From 3e8be33a5cfb916bf28633521fe228b6e570a609 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:45:42 -0700 Subject: [PATCH 1/3] Add CommandManagerPluginScoped --- Dalamud/Game/Command/CommandManager.cs | 76 ++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs index 6a8651b41..56630a5ad 100644 --- a/Dalamud/Game/Command/CommandManager.cs +++ b/Dalamud/Game/Command/CommandManager.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -17,12 +16,8 @@ namespace Dalamud.Game.Command; /// /// This class manages registered in-game slash commands. /// -[PluginInterface] [InterfaceVersion("1.0")] [ServiceManager.BlockingEarlyLoadedService] -#pragma warning disable SA1015 -[ResolveVia] -#pragma warning restore SA1015 internal sealed class CommandManager : IServiceType, IDisposable, ICommandManager { private readonly ConcurrentDictionary commandMap = new(); @@ -84,7 +79,7 @@ internal sealed class CommandManager : IServiceType, IDisposable, ICommandManage // => command: 0-12 (12 chars) // => argument: 13-17 (4 chars) // => content.IndexOf(' ') == 12 - command = content.Substring(0, separatorPosition); + command = content[..separatorPosition]; var argStart = separatorPosition + 1; argument = content[argStart..]; @@ -162,3 +157,72 @@ internal sealed class CommandManager : IServiceType, IDisposable, ICommandManage } } } + +/// +/// Plugin-scoped version of a AddonLifecycle service. +/// +[PluginInterface] +[InterfaceVersion("1.0")] +[ServiceManager.ScopedService] +#pragma warning disable SA1015 +[ResolveVia] +#pragma warning restore SA1015 +internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandManager +{ + [ServiceManager.ServiceDependency] + private readonly CommandManager commandManagerService = Service.Get(); + + private readonly List pluginRegisteredCommands = new(); + + /// + public ReadOnlyDictionary Commands => this.commandManagerService.Commands; + + /// + public void Dispose() + { + foreach (var command in this.pluginRegisteredCommands) + { + this.commandManagerService.RemoveHandler(command); + } + + this.pluginRegisteredCommands.Clear(); + } + + /// + public bool ProcessCommand(string content) + => this.commandManagerService.ProcessCommand(content); + + /// + public void DispatchCommand(string command, string argument, CommandInfo info) + => this.commandManagerService.DispatchCommand(command, argument, info); + + /// + public bool AddHandler(string command, CommandInfo info) + { + if (!this.pluginRegisteredCommands.Contains(command)) + { + if (this.commandManagerService.AddHandler(command, info)) + { + this.pluginRegisteredCommands.Add(command); + return true; + } + } + + return false; + } + + /// + public bool RemoveHandler(string command) + { + if (this.pluginRegisteredCommands.Contains(command)) + { + if (this.commandManagerService.RemoveHandler(command)) + { + this.pluginRegisteredCommands.Remove(command); + return true; + } + } + + return false; + } +} From 34617cf377b7805b0fa60296fcfccb3af73c6ca1 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Mon, 18 Sep 2023 10:50:05 -0700 Subject: [PATCH 2/3] Add error logging --- Dalamud/Game/Command/CommandManager.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs index 56630a5ad..118d210e2 100644 --- a/Dalamud/Game/Command/CommandManager.cs +++ b/Dalamud/Game/Command/CommandManager.cs @@ -8,8 +8,8 @@ using Dalamud.Game.Text; using Dalamud.Game.Text.SeStringHandling; using Dalamud.IoC; using Dalamud.IoC.Internal; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Services; -using Serilog; namespace Dalamud.Game.Command; @@ -20,6 +20,8 @@ namespace Dalamud.Game.Command; [ServiceManager.BlockingEarlyLoadedService] internal sealed class CommandManager : IServiceType, IDisposable, ICommandManager { + private static readonly ModuleLog Log = new("Command"); + private readonly ConcurrentDictionary commandMap = new(); private readonly Regex commandRegexEn = new(@"^The command (?.+) does not exist\.$", RegexOptions.Compiled); private readonly Regex commandRegexJp = new(@"^そのコマンドはありません。: (?.+)$", RegexOptions.Compiled); @@ -169,6 +171,8 @@ internal sealed class CommandManager : IServiceType, IDisposable, ICommandManage #pragma warning restore SA1015 internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandManager { + private static readonly ModuleLog Log = new("Command"); + [ServiceManager.ServiceDependency] private readonly CommandManager commandManagerService = Service.Get(); @@ -207,6 +211,10 @@ internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandM return true; } } + else + { + Log.Error($"Command {command} is already registered."); + } return false; } @@ -222,6 +230,10 @@ internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandM return true; } } + else + { + Log.Error($"Command {command} not found."); + } return false; } From 5d0694918572281ba0ac2a00915691406bf5f2ef Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Mon, 18 Sep 2023 12:00:49 -0700 Subject: [PATCH 3/3] Set CommandInfo InternalName when adding to CommandManager via PluginScopedService --- Dalamud/Game/Command/CommandInfo.cs | 1 - Dalamud/Game/Command/CommandManager.cs | 12 ++++++++++++ .../Windows/PluginInstaller/PluginInstallerWindow.cs | 4 +--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Dalamud/Game/Command/CommandInfo.cs b/Dalamud/Game/Command/CommandInfo.cs index 9b559599a..bc0250a66 100644 --- a/Dalamud/Game/Command/CommandInfo.cs +++ b/Dalamud/Game/Command/CommandInfo.cs @@ -15,7 +15,6 @@ public sealed class CommandInfo public CommandInfo(HandlerDelegate handler) { this.Handler = handler; - this.LoaderAssemblyName = Assembly.GetCallingAssembly()?.GetName()?.Name; } /// diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs index 118d210e2..218b89676 100644 --- a/Dalamud/Game/Command/CommandManager.cs +++ b/Dalamud/Game/Command/CommandManager.cs @@ -9,6 +9,7 @@ using Dalamud.Game.Text.SeStringHandling; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Logging.Internal; +using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Services; namespace Dalamud.Game.Command; @@ -177,7 +178,17 @@ internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandM private readonly CommandManager commandManagerService = Service.Get(); private readonly List pluginRegisteredCommands = new(); + private readonly LocalPlugin pluginInfo; + /// + /// Initializes a new instance of the class. + /// + /// Info for the plugin that requests this service. + public CommandManagerPluginScoped(LocalPlugin localPlugin) + { + this.pluginInfo = localPlugin; + } + /// public ReadOnlyDictionary Commands => this.commandManagerService.Commands; @@ -205,6 +216,7 @@ internal class CommandManagerPluginScoped : IDisposable, IServiceType, ICommandM { if (!this.pluginRegisteredCommands.Contains(command)) { + info.LoaderAssemblyName = this.pluginInfo.InternalName; if (this.commandManagerService.AddHandler(command, info)) { this.pluginRegisteredCommands.Add(command); diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index e5d3c147b..dcbdced28 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -15,7 +15,6 @@ using Dalamud.Game.Command; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; using Dalamud.Interface.Internal.Notifications; -using Dalamud.Interface.Style; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; @@ -2227,8 +2226,7 @@ internal class PluginInstallerWindow : Window, IDisposable { var commands = commandManager.Commands .Where(cInfo => - cInfo.Value != null && - cInfo.Value.ShowInHelp && + cInfo.Value is { ShowInHelp: true } && cInfo.Value.LoaderAssemblyName == plugin.Manifest.InternalName) .ToArray();