diff --git a/src/SMAPI/Framework/CommandManager.cs b/src/SMAPI/Framework/CommandManager.cs
index ceeb6f93..eaa91c86 100644
--- a/src/SMAPI/Framework/CommandManager.cs
+++ b/src/SMAPI/Framework/CommandManager.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using StardewModdingAPI.Framework.Commands;
namespace StardewModdingAPI.Framework
{
@@ -27,7 +28,7 @@ namespace StardewModdingAPI.Framework
/// The or is null or empty.
/// The is not a valid format.
/// There's already a command with that name.
- public void Add(IModMetadata mod, string name, string documentation, Action callback, bool allowNullCallback = false)
+ public CommandManager Add(IModMetadata mod, string name, string documentation, Action callback, bool allowNullCallback = false)
{
name = this.GetNormalizedName(name);
@@ -45,6 +46,16 @@ namespace StardewModdingAPI.Framework
// add command
this.Commands.Add(name, new Command(mod, name, documentation, callback));
+ return this;
+ }
+
+ /// Add a console command.
+ /// the SMAPI console command to add.
+ /// Writes messages to the console.
+ /// There's already a command with that name.
+ public CommandManager Add(IInternalCommand command, IMonitor monitor)
+ {
+ return this.Add(null, command.Name, command.Description, (name, args) => command.HandleCommand(args, monitor));
}
/// Get a command by its unique name.
diff --git a/src/SMAPI/Framework/Commands/HelpCommand.cs b/src/SMAPI/Framework/Commands/HelpCommand.cs
new file mode 100644
index 00000000..b8730a00
--- /dev/null
+++ b/src/SMAPI/Framework/Commands/HelpCommand.cs
@@ -0,0 +1,64 @@
+using System.Linq;
+
+namespace StardewModdingAPI.Framework.Commands
+{
+ /// The 'help' SMAPI console command.
+ internal class HelpCommand : IInternalCommand
+ {
+ /*********
+ ** Fields
+ *********/
+ /// Manages console commands.
+ private readonly CommandManager CommandManager;
+
+
+ /*********
+ ** Accessors
+ *********/
+ /// The command name, which the user must type to trigger it.
+ public string Name { get; } = "help";
+
+ /// The human-readable documentation shown when the player runs the built-in 'help' command.
+ public string Description { get; } = "Lists command documentation.\n\nUsage: help\nLists all available commands.\n\nUsage: help \n- cmd: The name of a command whose documentation to display.";
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// Construct an instance.
+ /// Manages console commands.
+ public HelpCommand(CommandManager commandManager)
+ {
+ this.CommandManager = commandManager;
+ }
+
+ /// Handle the console command when it's entered by the user.
+ /// The command arguments.
+ /// Writes messages to the console.
+ public void HandleCommand(string[] args, IMonitor monitor)
+ {
+ if (args.Any())
+ {
+ Command result = this.CommandManager.Get(args[0]);
+ if (result == null)
+ monitor.Log("There's no command with that name.", LogLevel.Error);
+ else
+ monitor.Log($"{result.Name}: {result.Documentation}{(result.Mod != null ? $"\n(Added by {result.Mod.DisplayName}.)" : "")}", LogLevel.Info);
+ }
+ else
+ {
+ string message = "The following commands are registered:\n";
+ IGrouping[] groups = (from command in this.CommandManager.GetAll() orderby command.Mod?.DisplayName, command.Name group command.Name by command.Mod?.DisplayName).ToArray();
+ foreach (var group in groups)
+ {
+ string modName = group.Key ?? "SMAPI";
+ string[] commandNames = group.ToArray();
+ message += $"{modName}:\n {string.Join("\n ", commandNames)}\n\n";
+ }
+ message += "For more information about a command, type 'help command_name'.";
+
+ monitor.Log(message, LogLevel.Info);
+ }
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/Commands/IInternalCommand.cs b/src/SMAPI/Framework/Commands/IInternalCommand.cs
new file mode 100644
index 00000000..abf105b6
--- /dev/null
+++ b/src/SMAPI/Framework/Commands/IInternalCommand.cs
@@ -0,0 +1,24 @@
+namespace StardewModdingAPI.Framework.Commands
+{
+ /// A core SMAPI console command.
+ interface IInternalCommand
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// The command name, which the user must type to trigger it.
+ string Name { get; }
+
+ /// The human-readable documentation shown when the player runs the built-in 'help' command.
+ string Description { get; }
+
+
+ /*********
+ ** Methods
+ *********/
+ /// Handle the console command when it's entered by the user.
+ /// The command arguments.
+ /// Writes messages to the console.
+ void HandleCommand(string[] args, IMonitor monitor);
+ }
+}
diff --git a/src/SMAPI/Framework/Commands/ReloadI18nCommand.cs b/src/SMAPI/Framework/Commands/ReloadI18nCommand.cs
new file mode 100644
index 00000000..12328bb6
--- /dev/null
+++ b/src/SMAPI/Framework/Commands/ReloadI18nCommand.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace StardewModdingAPI.Framework.Commands
+{
+ /// The 'reload_i18n' SMAPI console command.
+ internal class ReloadI18nCommand : IInternalCommand
+ {
+ /*********
+ ** Fields
+ *********/
+ /// Reload translations for all mods.
+ private readonly Action ReloadTranslations;
+
+
+ /*********
+ ** Accessors
+ *********/
+ /// The command name, which the user must type to trigger it.
+ public string Name { get; } = "reload_i18n";
+
+ /// The human-readable documentation shown when the player runs the built-in 'help' command.
+ public string Description { get; } = "Reloads translation files for all mods.\n\nUsage: reload_i18n";
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// Construct an instance.
+ /// Reload translations for all mods..
+ public ReloadI18nCommand(Action reloadTranslations)
+ {
+ this.ReloadTranslations = reloadTranslations;
+ }
+
+ /// Handle the console command when it's entered by the user.
+ /// The command arguments.
+ /// Writes messages to the console.
+ public void HandleCommand(string[] args, IMonitor monitor)
+ {
+ this.ReloadTranslations();
+ monitor.Log("Reloaded translation files for all mods. This only affects new translations the mods fetch; if they cached some text, it may not be updated.", LogLevel.Info);
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index cd292bfc..a89616a3 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -16,6 +16,7 @@ using System.Windows.Forms;
#endif
using Newtonsoft.Json;
using StardewModdingAPI.Events;
+using StardewModdingAPI.Framework.Commands;
using StardewModdingAPI.Framework.Events;
using StardewModdingAPI.Framework.Exceptions;
using StardewModdingAPI.Framework.Logging;
@@ -508,8 +509,9 @@ namespace StardewModdingAPI.Framework
{
// prepare console
this.Monitor.Log("Type 'help' for help, or 'help ' for a command's usage", LogLevel.Info);
- this.GameInstance.CommandManager.Add(null, "help", "Lists command documentation.\n\nUsage: help\nLists all available commands.\n\nUsage: help \n- cmd: The name of a command whose documentation to display.", this.HandleCommand);
- this.GameInstance.CommandManager.Add(null, "reload_i18n", "Reloads translation files for all mods.\n\nUsage: reload_i18n", this.HandleCommand);
+ this.GameInstance.CommandManager
+ .Add(new HelpCommand(this.GameInstance.CommandManager), this.Monitor)
+ .Add(new ReloadI18nCommand(this.ReloadTranslations), this.Monitor);
// start handling command line input
Thread inputThread = new Thread(() =>
@@ -1273,6 +1275,12 @@ namespace StardewModdingAPI.Framework
}
/// Reload translations for all mods.
+ private void ReloadTranslations()
+ {
+ this.ReloadTranslations(this.ModRegistry.GetAll(contentPacks: false));
+ }
+
+ /// Reload translations for the given mods.
/// The mods for which to reload translations.
private void ReloadTranslations(IEnumerable mods)
{
@@ -1357,48 +1365,6 @@ namespace StardewModdingAPI.Framework
return translations;
}
- /// The method called when the user submits a core SMAPI command in the console.
- /// The command name.
- /// The command arguments.
- private void HandleCommand(string name, string[] arguments)
- {
- switch (name)
- {
- case "help":
- if (arguments.Any())
- {
- Command result = this.GameInstance.CommandManager.Get(arguments[0]);
- if (result == null)
- this.Monitor.Log("There's no command with that name.", LogLevel.Error);
- else
- this.Monitor.Log($"{result.Name}: {result.Documentation}{(result.Mod != null ? $"\n(Added by {result.Mod.DisplayName}.)" : "")}", LogLevel.Info);
- }
- else
- {
- string message = "The following commands are registered:\n";
- IGrouping[] groups = (from command in this.GameInstance.CommandManager.GetAll() orderby command.Mod?.DisplayName, command.Name group command.Name by command.Mod?.DisplayName).ToArray();
- foreach (var group in groups)
- {
- string modName = group.Key ?? "SMAPI";
- string[] commandNames = group.ToArray();
- message += $"{modName}:\n {string.Join("\n ", commandNames)}\n\n";
- }
- message += "For more information about a command, type 'help command_name'.";
-
- this.Monitor.Log(message, LogLevel.Info);
- }
- break;
-
- case "reload_i18n":
- this.ReloadTranslations(this.ModRegistry.GetAll(contentPacks: false));
- this.Monitor.Log("Reloaded translation files for all mods. This only affects new translations the mods fetch; if they cached some text, it may not be updated.", LogLevel.Info);
- break;
-
- default:
- throw new NotSupportedException($"Unrecognized core SMAPI command '{name}'.");
- }
- }
-
/// Redirect messages logged directly to the console to the given monitor.
/// The monitor with which to log messages as the game.
/// The message to log.