using System; using System.Collections.Generic; using System.Text; using Brigadier.NET; using MinecraftClient.CommandHandler; using MinecraftClient.CommandHandler.Patch; 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; } /// /// Get the translated version of command description. /// /// Translated command description public string GetCmdDescTranslated() { char cmdChar = Settings.Config.Main.Advanced.InternalCmdChar.ToChar(); StringBuilder sb = new(); string s = (string.IsNullOrEmpty(CmdUsage) || string.IsNullOrEmpty(CmdDesc)) ? string.Empty : ": "; // If either one is empty, no colon : sb.Append("§e").Append(cmdChar).Append(CmdUsage).Append("§r").Append(s).AppendLine(CmdDesc); sb.Append(CmdResult.client!.dispatcher.GetAllUsageString(CmdName, false)); return sb.ToString(); } /// /// Usage message, eg: 'name [args]' /// public abstract string CmdUsage { get; } /// /// Register the command. /// public abstract void RegisterCommand(McClient handler, CommandDispatcher dispatcher); /// /// 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; } } }