diff --git a/Torch.API/Session/ITorchSessionManager.cs b/Torch.API/Session/ITorchSessionManager.cs index bfa3b88..1b13e95 100644 --- a/Torch.API/Session/ITorchSessionManager.cs +++ b/Torch.API/Session/ITorchSessionManager.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Torch.API.Managers; +using VRage.Game; namespace Torch.API.Session { @@ -47,5 +49,29 @@ namespace Torch.API.Session /// true if removed, false if not present /// If the factory is null bool RemoveFactory(SessionManagerFactoryDel factory); + + /// + /// Add a mod to be injected into client's world download. + /// + /// + /// + bool AddOverrideMod(ulong modId); + + /// + /// Removes a mod from the injected mod list. + /// + /// + /// + bool RemoveOverrideMod(ulong modId); + + /// + /// List over mods that will be injected into client world downloads. + /// + IReadOnlyCollection OverrideMods { get; } + + /// + /// Event raised when injected mod list changes. + /// + event Action OverrideModsChanged; } } diff --git a/Torch/Patches/SessionDownloadPatch.cs b/Torch/Patches/SessionDownloadPatch.cs index d7d8986..d739bcd 100644 --- a/Torch/Patches/SessionDownloadPatch.cs +++ b/Torch/Patches/SessionDownloadPatch.cs @@ -7,6 +7,8 @@ using System.Text; using System.Threading.Tasks; using NLog; using Sandbox.Game.World; +using Torch.API.Session; +using Torch.API.Managers; using Torch.Managers.PatchManager; using Torch.Mod; using VRage.Game; @@ -16,6 +18,10 @@ namespace Torch.Patches [PatchShim] internal static class SessionDownloadPatch { + private static ITorchSessionManager _sessionManager; + private static ITorchSessionManager SessionManager => _sessionManager ?? (_sessionManager = TorchBase.Instance.Managers.GetManager()); + + 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)); @@ -27,7 +33,7 @@ namespace Torch.Patches //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.Add(new MyObjectBuilder_Checkpoint.ModItem(TorchModCore.MOD_ID)); + __result.Checkpoint.Mods.AddRange(SessionManager.OverrideMods); } } } diff --git a/Torch/Session/TorchSessionManager.cs b/Torch/Session/TorchSessionManager.cs index 08ed019..b021772 100644 --- a/Torch/Session/TorchSessionManager.cs +++ b/Torch/Session/TorchSessionManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -9,7 +10,9 @@ using Torch.API; using Torch.API.Managers; using Torch.API.Session; using Torch.Managers; +using Torch.Mod; using Torch.Session; +using VRage.Game; namespace Torch.Session { @@ -21,6 +24,15 @@ namespace Torch.Session private static readonly Logger _log = LogManager.GetCurrentClassLogger(); private TorchSession _currentSession; + private readonly Dictionary _overrideMods; + + public event Action OverrideModsChanged; + + /// + /// List of mods that will be injected into client world downloads. + /// + public IReadOnlyCollection OverrideMods => _overrideMods.Values; + /// public event TorchSessionStateChangedDel SessionStateChanged; @@ -31,6 +43,8 @@ namespace Torch.Session public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance) { + _overrideMods = new Dictionary(); + _overrideMods.Add(TorchModCore.MOD_ID, new MyObjectBuilder_Checkpoint.ModItem(TorchModCore.MOD_ID)); } /// @@ -49,6 +63,27 @@ namespace Torch.Session return _factories.Remove(factory); } + /// + 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; + } + + /// + 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 private void SetState(TorchSessionState state)