using System;
using System.Collections.Generic;
using System.Text;
using Brigadier.NET;
using Microsoft.Extensions.Logging;
using MinecraftClient.Commands;
namespace MinecraftClient
{
///
/// Represents an internal MCC command: Command name, source code and usage message
/// To add a new command, inherit from this class while adding the command class to the folder "Commands".
/// If inheriting from the 'Command' class and placed in the 'Commands' namespace, the command will be
/// automatically loaded and available in main chat prompt, scripts, remote control and command help.
///
public abstract class Command
{
///
/// The command name
///
public abstract string CmdName { get; }
///
/// Command description with translation support. Please add your message in Translations.cs file and return mapping key in this property
///
public abstract string CmdDesc { get; }
public abstract void RegisterCommand(McClient handler, CommandDispatcher dispatcher);
///
/// Get the translated version of command description.
///
/// Translated command description
public string GetCmdDescTranslated()
{
string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? "" : ": "; // If either one is empty, no colon :
return CmdUsage + s + CmdDesc;
}
public void LogUsage(Logger.ILogger logger)
{
logger.Info($"{Translations.Get("error.usage")}: {Settings.Config.Main.Advanced.InternalCmdChar.ToChar()}{CmdUsage}");
}
public static int LogExecuteResult(Logger.ILogger logger, bool result)
{
logger.Info(Translations.Get(result ? "general.done" : "general.fail"));
return result ? 1 : 0;
}
public static int LogExecuteResult(Logger.ILogger logger, int result)
{
logger.Info(Translations.Get(result > 0 ? "general.done" : "general.fail"));
return result;
}
///
/// Usage message, eg: 'name [args]'
///
public abstract string CmdUsage { get; }
///
/// Perform the command
///
/// The full command, eg: 'mycommand arg1 arg2'
/// Local variables passed along with the command (may be null)
/// A confirmation/error message, or "" if no message
public abstract string Run(McClient handler, string command, Dictionary? localVars);
///
/// Return a list of aliases for this command.
/// Override this method if you wish to put aliases to the command
///
public virtual IEnumerable GetCMDAliases() { return Array.Empty(); }
///
/// Check if at least one argument has been passed to the command
///
public static bool HasArg(string command)
{
int first_space = command.IndexOf(' ');
return (first_space > 0 && first_space < command.Length - 1);
}
///
/// Extract the argument string from the command
///
/// Argument or "" if no argument
public static string GetArg(string command)
{
if (HasArg(command))
return command[(command.IndexOf(' ') + 1)..];
else
return string.Empty;
}
///
/// Extract the arguments as a string array from the command
///
/// Argument array or empty array if no arguments
public static string[] GetArgs(string command)
{
string[] args = GetArg(command).Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (args.Length == 1 && args[0] == string.Empty)
return Array.Empty();
else
return args;
}
///
/// Extract arguments from a given string. Allows quotines and escaping them.
/// Similar to command line arguments in regular terminals.
///
/// Provided arguments as a string
/// All extracted arguments in a string list
public static List ParseCommandLine(string cmdLine)
{
var args = new List();
if (string.IsNullOrWhiteSpace(cmdLine)) return args;
var currentArg = new StringBuilder();
bool inQuotedArg = false;
for (int i = 0; i < cmdLine.Length; i++)
{
if ((cmdLine[i] == '"' && i > 0 && cmdLine[i - 1] != '\\') || (cmdLine[i] == '"' && i == 0))
{
if (inQuotedArg)
{
args.Add(currentArg.ToString());
currentArg = new StringBuilder();
inQuotedArg = false;
}
else
{
inQuotedArg = true;
}
}
else if (cmdLine[i] == ' ')
{
if (inQuotedArg)
{
currentArg.Append(cmdLine[i]);
}
else if (currentArg.Length > 0)
{
args.Add(currentArg.ToString());
currentArg = new StringBuilder();
}
}
else
{
if (cmdLine[i] == '\\' && cmdLine[i + 1] == '\"')
{
currentArg.Append('"');
i += 1;
}
else
{
currentArg.Append(cmdLine[i]);
}
}
}
if (currentArg.Length > 0) args.Add(currentArg.ToString());
return args;
}
}
}