using System; using System.Collections.Generic; using StardewModdingAPI.Events; using StardewModdingAPI.Framework; namespace StardewModdingAPI { /// A command that can be submitted through the SMAPI console to interact with SMAPI. [Obsolete("Use " + nameof(IModHelper) + "." + nameof(IModHelper.ConsoleCommands))] public class Command { /********* ** Properties *********/ /// The commands registered with SMAPI. private static readonly IDictionary LegacyCommands = new Dictionary(StringComparer.InvariantCultureIgnoreCase); /// Manages console commands. private static CommandManager CommandManager; /// Manages deprecation warnings. private static DeprecationManager DeprecationManager; /// Tracks the installed mods. private static ModRegistry ModRegistry; /********* ** Accessors *********/ /// The event raised when this command is submitted through the console. public event EventHandler CommandFired; /**** ** Command ****/ /// The name of the command. public string CommandName; /// A human-readable description of what the command does. public string CommandDesc; /// A human-readable list of accepted arguments. public string[] CommandArgs; /// The actual submitted argument values. public string[] CalledArgs; /********* ** Public methods *********/ /**** ** Command ****/ /// Injects types required for backwards compatibility. /// Manages console commands. /// Manages deprecation warnings. /// Tracks the installed mods. internal static void Shim(CommandManager commandManager, DeprecationManager deprecationManager, ModRegistry modRegistry) { Command.CommandManager = commandManager; Command.DeprecationManager = deprecationManager; Command.ModRegistry = modRegistry; } /// Construct an instance. /// The name of the command. /// A human-readable description of what the command does. /// A human-readable list of accepted arguments. public Command(string name, string description, string[] args = null) { this.CommandName = name; this.CommandDesc = description; if (args == null) args = new string[0]; this.CommandArgs = args; } /// Trigger this command. public void Fire() { if (this.CommandFired == null) throw new InvalidOperationException($"Can't run command '{this.CommandName}' because it has no registered handler."); this.CommandFired.Invoke(this, new EventArgsCommand(this)); } /**** ** SMAPI ****/ /// Parse a command string and invoke it if valid. /// The command to run, including the command name and any arguments. /// Encapsulates monitoring and logging. public static void CallCommand(string input, IMonitor monitor) { Command.DeprecationManager.Warn("Command.CallCommand", "1.9", DeprecationLevel.Info); Command.CommandManager.Trigger(input); } /// Register a command with SMAPI. /// The name of the command. /// A human-readable description of what the command does. /// A human-readable list of accepted arguments. public static Command RegisterCommand(string name, string description, string[] args = null) { name = name?.Trim().ToLower(); // raise deprecation warning Command.DeprecationManager.Warn("Command.RegisterCommand", "1.9", DeprecationLevel.Info); // validate if (Command.LegacyCommands.ContainsKey(name)) throw new InvalidOperationException($"The '{name}' command is already registered!"); // add command string modName = Command.ModRegistry.GetModFromStack() ?? ""; string documentation = args?.Length > 0 ? $"{description} - {string.Join(", ", args)}" : description; Command.CommandManager.Add(modName, name, documentation, Command.Fire); // add legacy command Command command = new Command(name, description, args); Command.LegacyCommands.Add(name, command); return command; } /// Find a command with the given name. /// The command name to find. public static Command FindCommand(string name) { Command.DeprecationManager.Warn("Command.FindCommand", "1.9", DeprecationLevel.Info); if (name == null) return null; Command command; Command.LegacyCommands.TryGetValue(name.Trim(), out command); return command; } /********* ** Private methods *********/ /// Trigger this command. /// The command name. /// The command arguments. private static void Fire(string name, string[] args) { Command command; if (!Command.LegacyCommands.TryGetValue(name, out command)) throw new InvalidOperationException($"Can't run command '{name}' because there's no such legacy command."); command.Fire(); } } }