Test-time reflected event checker

Server UI components work with new system
Events for loading and unloading TorchSessions
Commands report information again.
Catch, log, and rethrow errors that occur in Torch-handled SE events
This commit is contained in:
Westin Miller
2017-08-24 20:24:07 -07:00
parent 4b2fee7614
commit 140000df55
19 changed files with 230 additions and 73 deletions

View File

@@ -17,11 +17,27 @@ namespace Torch.API.Session
/// <returns>The manager that will live in the session, or null if none.</returns> /// <returns>The manager that will live in the session, or null if none.</returns>
public delegate IManager SessionManagerFactoryDel(ITorchSession session); public delegate IManager SessionManagerFactoryDel(ITorchSession session);
/// <summary>
/// Fired when the given session has been completely loaded or is unloading.
/// </summary>
/// <param name="session">The session</param>
public delegate void TorchSessionLoadDel(ITorchSession session);
/// <summary> /// <summary>
/// Manages the creation and destruction of <see cref="ITorchSession"/> instances for each <see cref="Sandbox.Game.World.MySession"/> created by Space Engineers. /// Manages the creation and destruction of <see cref="ITorchSession"/> instances for each <see cref="Sandbox.Game.World.MySession"/> created by Space Engineers.
/// </summary> /// </summary>
public interface ITorchSessionManager : IManager public interface ITorchSessionManager : IManager
{ {
/// <summary>
/// Fired when a <see cref="ITorchSession"/> has finished loading.
/// </summary>
event TorchSessionLoadDel SessionLoaded;
/// <summary>
/// Fired when a <see cref="ITorchSession"/> has begun unloading.
/// </summary>
event TorchSessionLoadDel SessionUnloading;
/// <summary> /// <summary>
/// The currently running session /// The currently running session
/// </summary> /// </summary>

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Torch.Client; using Torch.Client;
using Torch.Tests; using Torch.Tests;
using Torch.Utils; using Torch.Utils;
@@ -86,7 +87,7 @@ namespace Torch.Client.Tests
return; return;
Assert.True(ReflectedManager.Process(field.Field)); Assert.True(ReflectedManager.Process(field.Field));
if (field.Field.IsStatic) if (field.Field.IsStatic)
Assert.NotNull(field.Field.GetValue(null)); ((Func<ReflectedEventReplacer>)field.Field.GetValue(null)).Invoke();
} }
#endregion #endregion
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Torch.Tests; using Torch.Tests;
using Torch.Utils; using Torch.Utils;
using Xunit; using Xunit;
@@ -74,7 +75,7 @@ namespace Torch.Server.Tests
return; return;
Assert.True(ReflectedManager.Process(field.Field)); Assert.True(ReflectedManager.Process(field.Field));
if (field.Field.IsStatic) if (field.Field.IsStatic)
Assert.NotNull(field.Field.GetValue(null)); ((Func<ReflectedEventReplacer>)field.Field.GetValue(null)).Invoke();
} }
#endregion #endregion
} }

View File

@@ -16,6 +16,7 @@ using Torch.Utils;
using Torch.ViewModels; using Torch.ViewModels;
using VRage.GameServices; using VRage.GameServices;
using VRage.Network; using VRage.Network;
using VRage.Steam;
namespace Torch.Server.Managers namespace Torch.Server.Managers
{ {
@@ -73,9 +74,9 @@ namespace Torch.Server.Managers
#pragma warning disable 649 #pragma warning disable 649
[ReflectedEventReplace(typeof(IMyGameServer), nameof(IMyGameServer.ValidateAuthTicketResponse), typeof(MyDedicatedServerBase), "GameServer_ValidateAuthTicketResponse")] [ReflectedEventReplace(typeof(MySteamGameServer), nameof(MySteamGameServer.ValidateAuthTicketResponse), typeof(MyDedicatedServerBase), "GameServer_ValidateAuthTicketResponse")]
private static Func<ReflectedEventReplacer> _gameServerValidateAuthTicketFactory; private static Func<ReflectedEventReplacer> _gameServerValidateAuthTicketFactory;
[ReflectedEventReplace(typeof(IMyGameServer), nameof(IMyGameServer.UserGroupStatusResponse), typeof(MyDedicatedServerBase), "GameServer_UserGroupStatus")] [ReflectedEventReplace(typeof(MySteamGameServer), nameof(MySteamGameServer.UserGroupStatusResponse), typeof(MyDedicatedServerBase), "GameServer_UserGroupStatus")]
private static Func<ReflectedEventReplacer> _gameServerUserGroupStatusFactory; private static Func<ReflectedEventReplacer> _gameServerUserGroupStatusFactory;
private ReflectedEventReplacer _gameServerValidateAuthTicketReplacer; private ReflectedEventReplacer _gameServerValidateAuthTicketReplacer;
private ReflectedEventReplacer _gameServerUserGroupStatusReplacer; private ReflectedEventReplacer _gameServerUserGroupStatusReplacer;

View File

@@ -182,6 +182,9 @@
<HintPath>..\GameBinaries\VRage.Scripting.dll</HintPath> <HintPath>..\GameBinaries\VRage.Scripting.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="VRage.Steam">
<HintPath>..\GameBinaries\VRage.Steam.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />

View File

@@ -21,6 +21,7 @@ using Sandbox.Game.World;
using SteamSDK; using SteamSDK;
using Torch.API; using Torch.API;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.API.Session;
using Torch.Managers; using Torch.Managers;
using Torch.Server.Managers; using Torch.Server.Managers;
@@ -42,14 +43,29 @@ namespace Torch.Server
{ {
_server = (TorchBase)server; _server = (TorchBase)server;
ChatItems.Items.Clear(); ChatItems.Items.Clear();
server.SessionLoaded += () =>
var sessionManager = server.Managers.GetManager<ITorchSessionManager>();
sessionManager.SessionLoaded += BindSession;
sessionManager.SessionUnloading += UnbindSession;
}
private void BindSession(ITorchSession session)
{ {
var multiplayer = server.CurrentSession.Managers.GetManager<MultiplayerManagerDedicated>(); Dispatcher.Invoke(() =>
DataContext = multiplayer; {
// TODO var chatMgr = _server?.CurrentSession?.Managers.GetManager<IChatManagerClient>();
// if (multiplayer.ChatHistory is INotifyCollectionChanged ncc) if (chatMgr != null)
// ncc.CollectionChanged += ChatHistory_CollectionChanged; DataContext = new ChatManagerProxy(chatMgr);
}; });
}
private void UnbindSession(ITorchSession session)
{
Dispatcher.Invoke(() =>
{
(DataContext as ChatManagerProxy)?.Dispose();
DataContext = null;
});
} }
private void ChatHistory_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void ChatHistory_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -86,7 +102,7 @@ namespace Torch.Server
var commands = _server.CurrentSession?.Managers.GetManager<Torch.Commands.CommandManager>(); var commands = _server.CurrentSession?.Managers.GetManager<Torch.Commands.CommandManager>();
if (commands != null && commands.IsCommand(text)) if (commands != null && commands.IsCommand(text))
{ {
// TODO _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", text)); (DataContext as ChatManagerProxy)?.AddMessage(new TorchChatMessage() { Author = "Server", Message = text });
_server.Invoke(() => _server.Invoke(() =>
{ {
var response = commands.HandleCommandFromServer(text); var response = commands.HandleCommandFromServer(text);
@@ -102,8 +118,37 @@ namespace Torch.Server
private void OnMessageEntered_Callback(string response) private void OnMessageEntered_Callback(string response)
{ {
//if (!string.IsNullOrEmpty(response)) if (!string.IsNullOrEmpty(response))
// TODO _multiplayer.ChatHistory.Add(new ChatMessage(DateTime.Now, 0, "Server", response)); (DataContext as ChatManagerProxy)?.AddMessage(new TorchChatMessage() { Author = "Server", Message = response });
}
private class ChatManagerProxy : IDisposable
{
private readonly IChatManagerClient _chatMgr;
public ChatManagerProxy(IChatManagerClient chatMgr)
{
this._chatMgr = chatMgr;
this._chatMgr.MessageRecieved += ChatMgr_MessageRecieved; ;
}
public IList<IChatMessage> ChatHistory { get; } = new ObservableList<IChatMessage>();
/// <inheritdoc />
public void Dispose()
{
_chatMgr.MessageRecieved -= ChatMgr_MessageRecieved;
}
private void ChatMgr_MessageRecieved(TorchChatMessage msg, ref bool consumed)
{
AddMessage(msg);
}
internal void AddMessage(TorchChatMessage msg)
{
ChatHistory.Add(new ChatMessage(DateTime.Now, msg.AuthorSteamId ?? 0, msg.Author, msg.Message));
}
} }
} }
} }

View File

@@ -21,6 +21,7 @@ using Sandbox.ModAPI;
using SteamSDK; using SteamSDK;
using Torch.API; using Torch.API;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.API.Session;
using Torch.Managers; using Torch.Managers;
using Torch.Server.Managers; using Torch.Server.Managers;
using Torch.ViewModels; using Torch.ViewModels;
@@ -43,11 +44,20 @@ namespace Torch.Server
public void BindServer(ITorchServer server) public void BindServer(ITorchServer server)
{ {
_server = server; _server = server;
server.SessionLoaded += () =>
var sessionManager = server.Managers.GetManager<ITorchSessionManager>();
sessionManager.SessionLoaded += BindSession;
sessionManager.SessionUnloading += UnbindSession;
}
private void BindSession(ITorchSession session)
{ {
var multiplayer = server.CurrentSession?.Managers.GetManager<MultiplayerManagerDedicated>(); Dispatcher.Invoke(() => DataContext = _server?.CurrentSession?.Managers.GetManager<MultiplayerManagerDedicated>());
DataContext = multiplayer; }
};
private void UnbindSession(ITorchSession session)
{
Dispatcher.Invoke(() => DataContext = null);
} }
private void KickButton_Click(object sender, RoutedEventArgs e) private void KickButton_Click(object sender, RoutedEventArgs e)

View File

@@ -77,7 +77,7 @@ namespace Torch.Tests
return; return;
Assert.True(ReflectedManager.Process(field.Field)); Assert.True(ReflectedManager.Process(field.Field));
if (field.Field.IsStatic) if (field.Field.IsStatic)
Assert.NotNull(field.Field.GetValue(null)); ((Func<ReflectedEventReplacer>)field.Field.GetValue(null)).Invoke();
} }
#endregion #endregion

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Torch.Utils; using Torch.Utils;
using Xunit; using Xunit;
@@ -84,7 +85,7 @@ namespace Torch.Tests
return; return;
Assert.True(ReflectedManager.Process(field.Field)); Assert.True(ReflectedManager.Process(field.Field));
if (field.Field.IsStatic) if (field.Field.IsStatic)
Assert.NotNull(field.Field.GetValue(null)); ((Func<ReflectedEventReplacer>)field.Field.GetValue(null)).Invoke();
} }
#endregion #endregion
} }

View File

@@ -117,7 +117,7 @@ namespace Torch.Commands
catch (Exception e) catch (Exception e)
{ {
context.Respond(e.Message, "Error", MyFontEnum.Red); context.Respond(e.Message, "Error", MyFontEnum.Red);
Log.Error($"Command '{SyntaxHelp}' from '{Plugin.Name ?? "Torch"}' threw an exception. Args: {string.Join(", ", context.Args)}"); Log.Error($"Command '{SyntaxHelp}' from '{Plugin?.Name ?? "Torch"}' threw an exception. Args: {string.Join(", ", context.Args)}");
Log.Error(e); Log.Error(e);
return true; return true;
} }

View File

@@ -108,7 +108,7 @@ namespace Torch.Commands
consumed = true; consumed = true;
var player = Torch.GetManager<IMultiplayerManagerBase>().GetPlayerBySteamId(steamId); var player = Torch.CurrentSession.Managers.GetManager<IMultiplayerManagerBase>().GetPlayerBySteamId(steamId);
if (player == null) if (player == null)
{ {
_log.Error($"Command {message} invoked by nonexistant player"); _log.Error($"Command {message} invoked by nonexistant player");

View File

@@ -21,7 +21,12 @@ namespace Torch.Commands
[Permission(MyPromoteLevel.None)] [Permission(MyPromoteLevel.None)]
public void Help() public void Help()
{ {
var commandManager = ((TorchBase)Context.Torch).CurrentSession.Managers.GetManager<CommandManager>(); var commandManager = Context.Torch.CurrentSession?.Managers.GetManager<CommandManager>();
if (commandManager == null)
{
Context.Respond("Must have an attached session to list commands");
return;
}
commandManager.Commands.GetNode(Context.Args, out CommandTree.CommandNode node); commandManager.Commands.GetNode(Context.Args, out CommandTree.CommandNode node);
if (node != null) if (node != null)
@@ -51,7 +56,12 @@ namespace Torch.Commands
[Command("longhelp", "Get verbose help. Will send a long message, check the Comms tab.")] [Command("longhelp", "Get verbose help. Will send a long message, check the Comms tab.")]
public void LongHelp() public void LongHelp()
{ {
var commandManager = Context.Torch.Managers.GetManager<CommandManager>(); var commandManager = Context.Torch.CurrentSession?.Managers.GetManager<CommandManager>();
if (commandManager == null)
{
Context.Respond("Must have an attached session to list commands");
return;
}
commandManager.Commands.GetNode(Context.Args, out CommandTree.CommandNode node); commandManager.Commands.GetNode(Context.Args, out CommandTree.CommandNode node);
if (node != null) if (node != null)
@@ -96,7 +106,7 @@ namespace Torch.Commands
[Permission(MyPromoteLevel.None)] [Permission(MyPromoteLevel.None)]
public void Plugins() public void Plugins()
{ {
var plugins = Context.Torch.Plugins.Select(p => p.Name); var plugins = Context.Torch.Managers.GetManager<PluginManager>()?.Plugins.Select(p => p.Name) ?? Enumerable.Empty<string>();
Context.Respond($"Loaded plugins: {string.Join(", ", plugins)}"); Context.Respond($"Loaded plugins: {string.Join(", ", plugins)}");
} }
@@ -128,15 +138,13 @@ namespace Torch.Commands
{ {
if (i >= 60 && i % 60 == 0) if (i >= 60 && i % 60 == 0)
{ {
// TODO Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>().SendMessageAsSelf($"Restarting server in {i / 60} minute{Pluralize(i / 60)}.");
// Context.Torch.Multiplayer.SendMessage($"Restarting server in {i / 60} minute{Pluralize(i / 60)}."); yield return null;
// yield return null;
} }
else if (i > 0) else if (i > 0)
{ {
// TODO if (i < 11)
// if (i < 11) Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>().SendMessageAsSelf($"Restarting server in {i} second{Pluralize(i)}.");
// Context.Torch.Multiplayer.SendMessage($"Restarting server in {i} second{Pluralize(i)}.");
yield return null; yield return null;
} }
else else

View File

@@ -15,7 +15,6 @@ using Torch.API;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.Utils; using Torch.Utils;
using VRage.Game; using VRage.Game;
using Game = Sandbox.Engine.Platform.Game;
namespace Torch.Managers.ChatManager namespace Torch.Managers.ChatManager
{ {
@@ -37,7 +36,7 @@ namespace Torch.Managers.ChatManager
{ {
if (MyMultiplayer.Static != null) if (MyMultiplayer.Static != null)
{ {
if (Game.IsDedicated) if (Sandbox.Engine.Platform.Game.IsDedicated)
{ {
var scripted = new ScriptedChatMsg() var scripted = new ScriptedChatMsg()
{ {
@@ -51,14 +50,15 @@ namespace Torch.Managers.ChatManager
else else
MyMultiplayer.Static.SendChatMessage(message); MyMultiplayer.Static.SendChatMessage(message);
} }
else if (MyHud.Chat != null) else if (HasHud)
MyHud.Chat.ShowMessage(MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player", message); MyHud.Chat.ShowMessage(MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player", message);
} }
/// <inheritdoc /> /// <inheritdoc />
public void DisplayMessageOnSelf(string author, string message, string font) public void DisplayMessageOnSelf(string author, string message, string font)
{ {
MyHud.Chat.ShowMessage(author, message, font); if (HasHud)
MyHud.Chat?.ShowMessage(author, message, font);
MySession.Static.GlobalChatHistory.GlobalChatHistory.Chat.Enqueue(new MyGlobalChatItem() MySession.Static.GlobalChatHistory.GlobalChatHistory.Chat.Enqueue(new MyGlobalChatItem()
{ {
Author = author, Author = author,
@@ -91,9 +91,9 @@ namespace Torch.Managers.ChatManager
public override void Detach() public override void Detach()
{ {
MyAPIUtilities.Static.MessageEntered -= OnMessageEntered; MyAPIUtilities.Static.MessageEntered -= OnMessageEntered;
if (_chatMessageRecievedReplacer != null && _chatMessageRecievedReplacer.Replaced) if (_chatMessageRecievedReplacer != null && _chatMessageRecievedReplacer.Replaced && HasHud)
_chatMessageRecievedReplacer.Restore(MyHud.Chat); _chatMessageRecievedReplacer.Restore(MyHud.Chat);
if (_scriptedChatMessageRecievedReplacer != null && _scriptedChatMessageRecievedReplacer.Replaced) if (_scriptedChatMessageRecievedReplacer != null && _scriptedChatMessageRecievedReplacer.Replaced && HasHud)
_scriptedChatMessageRecievedReplacer.Restore(MyHud.Chat); _scriptedChatMessageRecievedReplacer.Restore(MyHud.Chat);
MyAPIUtilities.Static.MessageEntered -= OfflineMessageReciever; MyAPIUtilities.Static.MessageEntered -= OfflineMessageReciever;
base.Detach(); base.Detach();
@@ -148,11 +148,11 @@ namespace Torch.Managers.ChatManager
}; };
var consumed = false; var consumed = false;
MessageRecieved?.Invoke(torchMsg, ref consumed); MessageRecieved?.Invoke(torchMsg, ref consumed);
if (!consumed) if (!consumed && HasHud)
_hudChatMessageReceived.Invoke(MyHud.Chat, steamUserId, message); _hudChatMessageReceived.Invoke(MyHud.Chat, steamUserId, message);
} }
private void Multiplayer_ScriptedChatMessageReceived(string author, string message, string font) private void Multiplayer_ScriptedChatMessageReceived(string message, string author, string font)
{ {
var torchMsg = new TorchChatMessage() var torchMsg = new TorchChatMessage()
{ {
@@ -163,13 +163,15 @@ namespace Torch.Managers.ChatManager
}; };
var consumed = false; var consumed = false;
MessageRecieved?.Invoke(torchMsg, ref consumed); MessageRecieved?.Invoke(torchMsg, ref consumed);
if (!consumed) if (!consumed && HasHud)
_hudChatScriptedMessageReceived.Invoke(MyHud.Chat, author, message, font); _hudChatScriptedMessageReceived.Invoke(MyHud.Chat, author, message, font);
} }
private const string _hudChatMessageReceivedName = "Multiplayer_ChatMessageReceived"; private const string _hudChatMessageReceivedName = "Multiplayer_ChatMessageReceived";
private const string _hudChatScriptedMessageReceivedName = "multiplayer_ScriptedChatMessageReceived"; private const string _hudChatScriptedMessageReceivedName = "multiplayer_ScriptedChatMessageReceived";
protected static bool HasHud => !Sandbox.Engine.Platform.Game.IsDedicated;
[ReflectedMethod(Name = _hudChatMessageReceivedName)] [ReflectedMethod(Name = _hudChatMessageReceivedName)]
private static Action<MyHudChat, ulong, string> _hudChatMessageReceived; private static Action<MyHudChat, ulong, string> _hudChatMessageReceived;
[ReflectedMethod(Name = _hudChatScriptedMessageReceivedName)] [ReflectedMethod(Name = _hudChatScriptedMessageReceivedName)]

View File

@@ -43,7 +43,7 @@ namespace Torch.Managers.ChatManager
{ {
if (MyMultiplayer.Static == null) if (MyMultiplayer.Static == null)
{ {
if (targetSteamId == MyGameService.UserId || targetSteamId == 0) if ((targetSteamId == MyGameService.UserId || targetSteamId == 0) && HasHud)
MyHud.Chat?.ShowMessage(authorId == MyGameService.UserId ? MyHud.Chat?.ShowMessage(authorId == MyGameService.UserId ?
(MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player") : $"user_{authorId}", message); (MySession.Static.LocalHumanPlayer?.DisplayName ?? "Player") : $"user_{authorId}", message);
return; return;
@@ -73,7 +73,7 @@ namespace Torch.Managers.ChatManager
{ {
if (MyMultiplayer.Static == null) if (MyMultiplayer.Static == null)
{ {
if (targetSteamId == MyGameService.UserId || targetSteamId == 0) if ((targetSteamId == MyGameService.UserId || targetSteamId == 0) && HasHud)
MyHud.Chat?.ShowMessage(author, message, font); MyHud.Chat?.ShowMessage(author, message, font);
return; return;
} }
@@ -82,7 +82,7 @@ namespace Torch.Managers.ChatManager
Author = author, Author = author,
Text = message, Text = message,
Font = font, Font = font,
Target = (long)targetSteamId Target = Sync.Players.TryGetIdentityId(targetSteamId)
}; };
MyMultiplayerBase.SendScriptedChatMessage(ref scripted); MyMultiplayerBase.SendScriptedChatMessage(ref scripted);
} }
@@ -107,7 +107,12 @@ namespace Torch.Managers.ChatManager
if (MyMultiplayer.Static != null) if (MyMultiplayer.Static != null)
{ {
MyMultiplayer.Static.ChatMessageReceived += MpStaticChatMessageReceived; MyMultiplayer.Static.ChatMessageReceived += MpStaticChatMessageReceived;
_log.Warn("Failed to initialize network intercept, we can't discard chat messages! Falling back to another method."); _log.Warn(
"Failed to initialize network intercept, we can't discard chat messages! Falling back to another method.");
}
else
{
_log.Debug("Using offline message processor");
} }
} }

View File

@@ -115,7 +115,7 @@ namespace Torch.Managers
protected void RaiseClientJoined(ulong steamId) protected void RaiseClientJoined(ulong steamId)
{ {
var vm = new PlayerViewModel(steamId){State=ConnectionState.Connected}; var vm = new PlayerViewModel(steamId){State=ConnectionState.Connected};
_log.Info($"Plat {vm.Name} joined ({vm.SteamId}"); _log.Info($"Player {vm.Name} joined ({vm.SteamId}");
Players.Add(steamId, vm); Players.Add(steamId, vm);
PlayerJoined?.Invoke(vm); PlayerJoined?.Invoke(vm);
} }

View File

@@ -60,15 +60,9 @@ namespace Torch.Managers
throw; throw;
} }
} }
/// <summary>
/// Loads the network intercept system
/// </summary>
public override void Attach()
{
Torch.SessionLoaded += OnSessionLoaded;
}
private void OnSessionLoaded() /// <inheritdoc/>
public override void Attach()
{ {
if (_init) if (_init)
return; return;
@@ -105,6 +99,12 @@ namespace Torch.Managers
_log.Debug("Initialized network intercept"); _log.Debug("Initialized network intercept");
} }
/// <inheritdoc/>
public override void Detach()
{
// TODO reverse what was done in Attach
}
#region Network Intercept #region Network Intercept
/// <summary> /// <summary>

View File

@@ -10,6 +10,7 @@ using NLog;
using Torch.API; using Torch.API;
using Torch.API.Managers; using Torch.API.Managers;
using Torch.API.Plugins; using Torch.API.Plugins;
using Torch.API.Session;
using Torch.Commands; using Torch.Commands;
using VRage.Collections; using VRage.Collections;
@@ -22,8 +23,8 @@ namespace Torch.Managers
public readonly string PluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"); public readonly string PluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
[Dependency] [Dependency]
private UpdateManager _updateManager; private UpdateManager _updateManager;
[Dependency] [Dependency(Optional = true)]
private CommandManager _commandManager; private ITorchSessionManager _sessionManager;
/// <inheritdoc /> /// <inheritdoc />
public IList<ITorchPlugin> Plugins { get; } = new ObservableList<ITorchPlugin>(); public IList<ITorchPlugin> Plugins { get; } = new ObservableList<ITorchPlugin>();
@@ -41,6 +42,11 @@ namespace Torch.Managers
/// </summary> /// </summary>
public void UpdatePlugins() public void UpdatePlugins()
{ {
if (_sessionManager != null)
{
_sessionManager.SessionLoaded += AttachCommandsToSession;
_sessionManager.SessionUnloading += DetachCommandsFromSession;
}
foreach (var plugin in Plugins) foreach (var plugin in Plugins)
plugin.Update(); plugin.Update();
} }
@@ -50,12 +56,32 @@ namespace Torch.Managers
/// </summary> /// </summary>
public override void Detach() public override void Detach()
{ {
if (_sessionManager != null)
{
_sessionManager.SessionLoaded -= AttachCommandsToSession;
_sessionManager.SessionUnloading -= DetachCommandsFromSession;
}
foreach (var plugin in Plugins) foreach (var plugin in Plugins)
plugin.Dispose(); plugin.Dispose();
Plugins.Clear(); Plugins.Clear();
} }
private void AttachCommandsToSession(ITorchSession session)
{
var cmdMgr = session.Managers.GetManager<CommandManager>();
foreach (ITorchPlugin plugin in Plugins)
cmdMgr?.RegisterPluginCommands(plugin);
}
private void DetachCommandsFromSession(ITorchSession session)
{
var cmdMgr = session.Managers.GetManager<CommandManager>();
foreach (ITorchPlugin plugin in Plugins) {
// cmdMgr?.UnregisterPluginCommands(plugin);
}
}
private void DownloadPlugins() private void DownloadPlugins()
{ {
var folders = Directory.GetDirectories(PluginDir); var folders = Directory.GetDirectories(PluginDir);
@@ -80,7 +106,7 @@ namespace Torch.Managers
foreach (var repository in toDownload) foreach (var repository in toDownload)
{ {
var manifest = new PluginManifest {Repository = repository, Version = "0.0"}; var manifest = new PluginManifest { Repository = repository, Version = "0.0" };
taskList.Add(_updateManager.CheckAndUpdatePlugin(manifest)); taskList.Add(_updateManager.CheckAndUpdatePlugin(manifest));
} }
@@ -118,8 +144,6 @@ namespace Torch.Managers
_log.Info($"Loading plugin {plugin.Name} ({plugin.Version})"); _log.Info($"Loading plugin {plugin.Name} ({plugin.Version})");
plugin.StoragePath = Torch.Config.InstancePath; plugin.StoragePath = Torch.Config.InstancePath;
Plugins.Add(plugin); Plugins.Add(plugin);
_commandManager.RegisterPluginCommands(plugin);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@@ -21,6 +21,12 @@ namespace Torch.Session
private static readonly Logger _log = LogManager.GetCurrentClassLogger(); private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private TorchSession _currentSession; private TorchSession _currentSession;
/// <inheritdoc />
public event TorchSessionLoadDel SessionLoaded;
/// <inheritdoc />
public event TorchSessionLoadDel SessionUnloading;
/// <inheritdoc/> /// <inheritdoc/>
public ITorchSession CurrentSession => _currentSession; public ITorchSession CurrentSession => _currentSession;
@@ -46,7 +52,7 @@ namespace Torch.Session
return _factories.Remove(factory); return _factories.Remove(factory);
} }
private void SessionLoaded() private void LoadSession()
{ {
if (_currentSession != null) if (_currentSession != null)
{ {
@@ -63,12 +69,14 @@ namespace Torch.Session
CurrentSession.Managers.AddManager(manager); CurrentSession.Managers.AddManager(manager);
} }
(CurrentSession as TorchSession)?.Attach(); (CurrentSession as TorchSession)?.Attach();
SessionLoaded?.Invoke(_currentSession);
} }
private void SessionUnloaded() private void UnloadSession()
{ {
if (_currentSession == null) if (_currentSession == null)
return; return;
SessionUnloading?.Invoke(_currentSession);
_log.Info($"Unloading torch session for {_currentSession.KeenSession.Name}"); _log.Info($"Unloading torch session for {_currentSession.KeenSession.Name}");
_currentSession.Detach(); _currentSession.Detach();
_currentSession = null; _currentSession = null;
@@ -77,8 +85,8 @@ namespace Torch.Session
/// <inheritdoc/> /// <inheritdoc/>
public override void Attach() public override void Attach()
{ {
MySession.AfterLoading += SessionLoaded; MySession.AfterLoading += LoadSession;
MySession.OnUnloaded += SessionUnloaded; MySession.OnUnloaded += UnloadSession;
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -86,8 +94,8 @@ namespace Torch.Session
{ {
_currentSession?.Detach(); _currentSession?.Detach();
_currentSession = null; _currentSession = null;
MySession.AfterLoading -= SessionLoaded; MySession.AfterLoading -= LoadSession;
MySession.OnUnloaded -= SessionUnloaded; MySession.OnUnloaded -= UnloadSession;
} }
} }
} }

View File

@@ -273,26 +273,58 @@ namespace Torch
private void OnSessionLoading() private void OnSessionLoading()
{ {
Log.Debug("Session loading"); Log.Debug("Session loading");
try
{
SessionLoading?.Invoke(); SessionLoading?.Invoke();
} }
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnSessionLoaded() private void OnSessionLoaded()
{ {
Log.Debug("Session loaded"); Log.Debug("Session loaded");
try
{
SessionLoaded?.Invoke(); SessionLoaded?.Invoke();
} }
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnSessionUnloading() private void OnSessionUnloading()
{ {
Log.Debug("Session unloading"); Log.Debug("Session unloading");
try
{
SessionUnloading?.Invoke(); SessionUnloading?.Invoke();
} }
catch (Exception e)
{
Log.Error(e);
throw;
}
}
private void OnSessionUnloaded() private void OnSessionUnloaded()
{ {
Log.Debug("Session unloaded"); Log.Debug("Session unloaded");
try
{
SessionUnloaded?.Invoke(); SessionUnloaded?.Invoke();
} }
catch (Exception e)
{
Log.Error(e);
throw;
}
}
/// <summary> /// <summary>
/// Hook into the VRage plugin system for updates. /// Hook into the VRage plugin system for updates.