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();