using System;
using System.Collections.Generic;
using System.Linq;
using StardewModdingAPI.Events;
using StardewModdingAPI.Framework;
namespace StardewModdingAPI
{
/// A command that can be submitted through the SMAPI console to interact with SMAPI.
public class Command
{
/*********
** Properties
*********/
/****
** SMAPI
****/
/// The commands registered with SMAPI.
internal static List RegisteredCommands = new List();
/// 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
****/
/// 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.
[Obsolete("Use the overload which passes in your mod's monitor")]
public static void CallCommand(string input)
{
Program.DeprecationManager.Warn($"an old version of {nameof(Command)}.{nameof(Command.CallCommand)}", "1.1", DeprecationLevel.Notice);
Command.CallCommand(input, Program.GetLegacyMonitorForMod());
}
/// 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)
{
// normalise input
input = input?.Trim();
if (string.IsNullOrWhiteSpace(input))
return;
// tokenise input
string[] args = input.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string commandName = args[0];
args = args.Skip(1).ToArray();
// get command
Command command = Command.FindCommand(commandName);
if (command == null)
{
monitor.Log("Unknown command", LogLevel.Error);
return;
}
// fire command
command.CalledArgs = args;
command.Fire();
}
/// 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)
{
var command = new Command(name, description, args);
if (Command.RegisteredCommands.Contains(command))
throw new InvalidOperationException($"The '{command.CommandName}' command is already registered!");
Command.RegisteredCommands.Add(command);
return command;
}
/// Find a command with the given name.
/// The command name to find.
public static Command FindCommand(string name)
{
return Command.RegisteredCommands.Find(x => x.CommandName.Equals(name));
}
}
}