diff --git a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
index f2c8cbc5a6..0af63b48b5 100644
--- a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
+++ b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
@@ -6,6 +6,7 @@
false
false
IDE0003
+ enable
diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs
index 951050b336..fc5e96301b 100644
--- a/Dalamud.CorePlugin/PluginImpl.cs
+++ b/Dalamud.CorePlugin/PluginImpl.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using Dalamud.Configuration.Internal;
@@ -7,6 +8,7 @@
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+
using Serilog;
namespace Dalamud.CorePlugin
@@ -28,6 +30,7 @@ namespace Dalamud.CorePlugin
///
public sealed class PluginImpl : IDalamudPlugin
{
+ private readonly IChatGui chatGui;
#if !DEBUG
///
@@ -46,7 +49,6 @@ public void Dispose()
#else
private readonly WindowSystem windowSystem = new("Dalamud.CorePlugin");
- private Localization localization;
private IPluginLog pluginLog;
@@ -55,14 +57,17 @@ public void Dispose()
///
/// Dalamud plugin interface.
/// Logging service.
- public PluginImpl(IDalamudPluginInterface pluginInterface, IPluginLog log)
+ /// Command manager.
+ /// Chat GUI.
+ [Experimental("Dalamud001")]
+ public PluginImpl(IDalamudPluginInterface pluginInterface, IPluginLog log, ICommandManager commandManager, IChatGui chatGui)
{
+ this.chatGui = chatGui;
+ this.Interface = pluginInterface;
+ this.pluginLog = log;
+
try
{
- // this.InitLoc();
- this.Interface = pluginInterface;
- this.pluginLog = log;
-
this.windowSystem.AddWindow(new PluginWindow());
this.Interface.UiBuilder.Draw += this.OnDraw;
@@ -73,7 +78,8 @@ public PluginImpl(IDalamudPluginInterface pluginInterface, IPluginLog log)
Log.Information($"CorePlugin : DefaultFontHandle.ImFontChanged called {fc}");
};
- Service.Get().AddHandler("/coreplug", new CommandInfo(this.OnCommand) { HelpMessage = "Access the plugin." });
+ commandManager.AddHandler("/coreplug", new CommandInfo(this.OnCommand) { HelpMessage = "Access the plugin." });
+ commandManager.AddCommand("/coreplugnew", "Access the plugin.", this.OnCommandNew);
log.Information("CorePlugin ctor!");
}
@@ -98,25 +104,6 @@ public void Dispose()
this.windowSystem.RemoveAllWindows();
}
- ///
- /// CheapLoc needs to be reinitialized here because it tracks the setup by assembly name. New assembly, new setup.
- ///
- public void InitLoc()
- {
- var dalamud = Service.Get();
- var dalamudConfig = Service.Get();
-
- this.localization = new Localization(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "loc", "dalamud"), "dalamud_");
- if (!dalamudConfig.LanguageOverride.IsNullOrEmpty())
- {
- this.localization.SetupWithLangCode(dalamudConfig.LanguageOverride);
- }
- else
- {
- this.localization.SetupWithUiCulture();
- }
- }
-
///
/// Draw the window system.
///
@@ -134,11 +121,17 @@ private void OnDraw()
private void OnCommand(string command, string args)
{
- this.pluginLog.Information("Command called!");
+ this.chatGui.Print("Command called!");
// this.window.IsOpen = true;
}
+ private bool OnCommandNew(bool var1, int var2, string? var3)
+ {
+ this.chatGui.Print($"CorePlugin: Command called! var1: {var1}, var2: {var2}, var3: {var3}");
+ return true;
+ }
+
private void OnOpenConfigUi()
{
// this.window.IsOpen = true;
diff --git a/Dalamud/Console/ConsoleEntry.cs b/Dalamud/Console/ConsoleEntry.cs
index 93f250228f..23a00eb82e 100644
--- a/Dalamud/Console/ConsoleEntry.cs
+++ b/Dalamud/Console/ConsoleEntry.cs
@@ -11,13 +11,19 @@ public interface IConsoleEntry
/// Gets the name of the entry.
///
public string Name { get; }
-
+
///
/// Gets the description of the entry.
///
public string Description { get; }
+
+ ///
+ /// Get a string representation of the usage of this entry, detailing the expected arguments.
+ ///
+ /// The usage string.
+ public string GetUsageString();
}
-
+
///
/// Interface representing a command in the console.
///
diff --git a/Dalamud/Console/ConsoleManager.cs b/Dalamud/Console/ConsoleManager.cs
index 4112cde2a8..a961971a0c 100644
--- a/Dalamud/Console/ConsoleManager.cs
+++ b/Dalamud/Console/ConsoleManager.cs
@@ -18,9 +18,9 @@ namespace Dalamud.Console;
internal partial class ConsoleManager : IServiceType
{
private static readonly ModuleLog Log = new("CON");
-
+
private Dictionary entries = new();
-
+
///
/// Initializes a new instance of the class.
///
@@ -29,17 +29,53 @@ public ConsoleManager()
{
this.AddCommand("toggle", "Toggle a boolean variable.", this.OnToggleVariable);
}
-
+
///
- /// Event that is triggered when a command is processed. Return true to stop the command from being processed any further.
+ /// Possible results when processing a console command.
///
- public event Func? Invoke;
-
+ public enum CommandProcessResult
+ {
+ ///
+ /// The command was processed and executed correctly.
+ ///
+ Success,
+
+ ///
+ /// The input failed to parse. onDiagnosticEmitted will be called with further information.
+ ///
+ ParseFailure,
+
+ ///
+ /// The command did not indicate success.
+ ///
+ ExecutionFailure,
+
+ ///
+ /// The command was not found.
+ ///
+ NotFound,
+ }
+
///
/// Gets a read-only dictionary of console entries.
///
public IReadOnlyDictionary Entries => this.entries;
-
+
+ ///
+ /// Add an entry to the console.
+ ///
+ /// The entry to add.
+ /// Thrown if the entry already exists.
+ public void AddEntry(IConsoleEntry entry)
+ {
+ ArgumentNullException.ThrowIfNull(entry);
+
+ if (this.FindEntry(entry.Name) != null)
+ throw new InvalidOperationException($"Entry '{entry.Name}' already exists.");
+
+ this.entries.Add(entry.Name, entry);
+ }
+
///
/// Add a command to the console.
///
@@ -53,13 +89,10 @@ public IConsoleCommand AddCommand(string name, string description, Delegate func
ArgumentNullException.ThrowIfNull(name);
ArgumentNullException.ThrowIfNull(description);
ArgumentNullException.ThrowIfNull(func);
-
- if (this.FindEntry(name) != null)
- throw new InvalidOperationException($"Entry '{name}' already exists.");
var command = new ConsoleCommand(name, description, func);
- this.entries.Add(name, command);
-
+ this.AddEntry(command);
+
return command;
}
@@ -77,14 +110,13 @@ public IConsoleVariable AddVariable(string name, string description, T def
ArgumentNullException.ThrowIfNull(name);
ArgumentNullException.ThrowIfNull(description);
Traits.ThrowIfTIsNullableAndNull(defaultValue);
-
- if (this.FindEntry(name) != null)
- throw new InvalidOperationException($"Entry '{name}' already exists.");
-
- var variable = new ConsoleVariable(name, description);
- variable.Value = defaultValue;
- this.entries.Add(name, variable);
-
+
+ var variable = new ConsoleVariable(name, description)
+ {
+ Value = defaultValue,
+ };
+ this.AddEntry(variable);
+
return variable;
}
@@ -98,11 +130,11 @@ public IConsoleEntry AddAlias(string name, string alias)
{
ArgumentNullException.ThrowIfNull(name);
ArgumentNullException.ThrowIfNull(alias);
-
+
var target = this.FindEntry(name);
if (target == null)
throw new EntryNotFoundException(name);
-
+
if (this.FindEntry(alias) != null)
throw new InvalidOperationException($"Entry '{alias}' already exists.");
@@ -135,21 +167,21 @@ public void RemoveEntry(IConsoleEntry entry)
public T GetVariable(string name)
{
ArgumentNullException.ThrowIfNull(name);
-
+
var entry = this.FindEntry(name);
-
+
if (entry is ConsoleVariable variable)
return variable.Value;
-
+
if (entry is ConsoleVariable)
throw new InvalidOperationException($"Variable '{name}' is not of type {typeof(T).Name}.");
-
+
if (entry is null)
throw new EntryNotFoundException(name);
-
+
throw new InvalidOperationException($"Command '{name}' is not a variable.");
}
-
+
///
/// Set the value of a variable.
///
@@ -162,18 +194,18 @@ public void SetVariable(string name, T value)
{
ArgumentNullException.ThrowIfNull(name);
Traits.ThrowIfTIsNullableAndNull(value);
-
+
var entry = this.FindEntry(name);
-
+
if (entry is ConsoleVariable variable)
variable.Value = value;
-
+
if (entry is ConsoleVariable)
throw new InvalidOperationException($"Variable '{name}' is not of type {typeof(T).Name}.");
if (entry is null)
- throw new EntryNotFoundException(name);
-
+ throw new EntryNotFoundException(name);
+
throw new InvalidOperationException($"Command '{name}' is not a variable.");
}
@@ -181,30 +213,29 @@ public void SetVariable(string name, T value)
/// Process a console command.
///
/// The command to process.
- /// Whether or not the command was successfully processed.
- public bool ProcessCommand(string command)
+ /// Action to be invoked when an error during command parsing occurred.
+ /// Whether the command was successfully processed.
+ public CommandProcessResult ProcessCommand(string command, Action onDiagnosticEmitted)
{
- if (this.Invoke?.Invoke(command) == true)
- return true;
-
+ ArgumentNullException.ThrowIfNull(command);
+ ArgumentNullException.ThrowIfNull(onDiagnosticEmitted);
+
var matches = GetCommandParsingRegex().Matches(command);
if (matches.Count == 0)
- return false;
-
+ return CommandProcessResult.NotFound;
+
var entryName = matches[0].Value;
if (string.IsNullOrEmpty(entryName) || entryName.Any(char.IsWhiteSpace))
{
- Log.Error("No valid command specified");
- return false;
+ return CommandProcessResult.NotFound;
}
var entry = this.FindEntry(entryName);
if (entry == null)
{
- Log.Error("Command {CommandName} not found", entryName);
- return false;
+ return CommandProcessResult.NotFound;
}
-
+
var parsedArguments = new List