Add API for injecting client mods

This commit is contained in:
Brant Martin
2019-02-08 13:53:37 -05:00
parent f265f7e773
commit 0122f9e989
3 changed files with 68 additions and 1 deletions

View File

@@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Torch.API.Managers; using Torch.API.Managers;
using VRage.Game;
namespace Torch.API.Session namespace Torch.API.Session
{ {
@@ -47,5 +49,29 @@ namespace Torch.API.Session
/// <returns>true if removed, false if not present</returns> /// <returns>true if removed, false if not present</returns>
/// <exception cref="ArgumentNullException">If the factory is null</exception> /// <exception cref="ArgumentNullException">If the factory is null</exception>
bool RemoveFactory(SessionManagerFactoryDel factory); bool RemoveFactory(SessionManagerFactoryDel factory);
/// <summary>
/// Add a mod to be injected into client's world download.
/// </summary>
/// <param name="modId"></param>
/// <returns></returns>
bool AddOverrideMod(ulong modId);
/// <summary>
/// Removes a mod from the injected mod list.
/// </summary>
/// <param name="modId"></param>
/// <returns></returns>
bool RemoveOverrideMod(ulong modId);
/// <summary>
/// List over mods that will be injected into client world downloads.
/// </summary>
IReadOnlyCollection<MyObjectBuilder_Checkpoint.ModItem> OverrideMods { get; }
/// <summary>
/// Event raised when injected mod list changes.
/// </summary>
event Action<CollectionChangeEventArgs> OverrideModsChanged;
} }
} }

View File

@@ -7,6 +7,8 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using NLog; using NLog;
using Sandbox.Game.World; using Sandbox.Game.World;
using Torch.API.Session;
using Torch.API.Managers;
using Torch.Managers.PatchManager; using Torch.Managers.PatchManager;
using Torch.Mod; using Torch.Mod;
using VRage.Game; using VRage.Game;
@@ -16,6 +18,10 @@ namespace Torch.Patches
[PatchShim] [PatchShim]
internal static class SessionDownloadPatch internal static class SessionDownloadPatch
{ {
private static ITorchSessionManager _sessionManager;
private static ITorchSessionManager SessionManager => _sessionManager ?? (_sessionManager = TorchBase.Instance.Managers.GetManager<ITorchSessionManager>());
internal static void Patch(PatchContext context) internal static void Patch(PatchContext context)
{ {
context.GetPattern(typeof(MySession).GetMethod(nameof(MySession.GetWorld))).Suffixes.Add(typeof(SessionDownloadPatch).GetMethod(nameof(SuffixGetWorld), BindingFlags.Static | BindingFlags.NonPublic)); context.GetPattern(typeof(MySession).GetMethod(nameof(MySession.GetWorld))).Suffixes.Add(typeof(SessionDownloadPatch).GetMethod(nameof(SuffixGetWorld), BindingFlags.Static | BindingFlags.NonPublic));
@@ -27,7 +33,7 @@ namespace Torch.Patches
//copy this list so mods added here don't propagate up to the real session //copy this list so mods added here don't propagate up to the real session
__result.Checkpoint.Mods = __result.Checkpoint.Mods.ToList(); __result.Checkpoint.Mods = __result.Checkpoint.Mods.ToList();
__result.Checkpoint.Mods.Add(new MyObjectBuilder_Checkpoint.ModItem(TorchModCore.MOD_ID)); __result.Checkpoint.Mods.AddRange(SessionManager.OverrideMods);
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,7 +10,9 @@ using Torch.API;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.API.Session; using Torch.API.Session;
using Torch.Managers; using Torch.Managers;
using Torch.Mod;
using Torch.Session; using Torch.Session;
using VRage.Game;
namespace Torch.Session namespace Torch.Session
{ {
@@ -21,6 +24,15 @@ namespace Torch.Session
private static readonly Logger _log = LogManager.GetCurrentClassLogger(); private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private TorchSession _currentSession; private TorchSession _currentSession;
private readonly Dictionary<ulong, MyObjectBuilder_Checkpoint.ModItem> _overrideMods;
public event Action<CollectionChangeEventArgs> OverrideModsChanged;
/// <summary>
/// List of mods that will be injected into client world downloads.
/// </summary>
public IReadOnlyCollection<MyObjectBuilder_Checkpoint.ModItem> OverrideMods => _overrideMods.Values;
/// <inheritdoc /> /// <inheritdoc />
public event TorchSessionStateChangedDel SessionStateChanged; public event TorchSessionStateChangedDel SessionStateChanged;
@@ -31,6 +43,8 @@ namespace Torch.Session
public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance) public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance)
{ {
_overrideMods = new Dictionary<ulong, MyObjectBuilder_Checkpoint.ModItem>();
_overrideMods.Add(TorchModCore.MOD_ID, new MyObjectBuilder_Checkpoint.ModItem(TorchModCore.MOD_ID));
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -49,6 +63,27 @@ namespace Torch.Session
return _factories.Remove(factory); return _factories.Remove(factory);
} }
/// <inheritdoc/>
public bool AddOverrideMod(ulong modId)
{
if (_overrideMods.ContainsKey(modId))
return false;
var item = new MyObjectBuilder_Checkpoint.ModItem();
_overrideMods.Add(modId, item);
OverrideModsChanged?.Invoke(new CollectionChangeEventArgs(CollectionChangeAction.Add, item));
return true;
}
/// <inheritdoc/>
public bool RemoveOverrideMod(ulong modId)
{
if(_overrideMods.TryGetValue(modId, out var item))
OverrideModsChanged?.Invoke(new CollectionChangeEventArgs(CollectionChangeAction.Remove, item));
return _overrideMods.Remove(modId);
}
#region Session events #region Session events
private void SetState(TorchSessionState state) private void SetState(TorchSessionState state)