From 3f45423dc84e7769414b1f0d97b0d1f7d35a94e3 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Tue, 5 Jul 2022 16:12:26 +0700 Subject: [PATCH] Add command groups support --- .../Commands/BuiltInCommands/ACommandHelp.uc | 216 +++++++++++------- sources/Commands/Command.uc | 16 ++ sources/Commands/CommandDataBuilder.uc | 30 ++- sources/Commands/Commands_Feature.uc | 118 +++++++++- 4 files changed, 288 insertions(+), 92 deletions(-) diff --git a/sources/Commands/BuiltInCommands/ACommandHelp.uc b/sources/Commands/BuiltInCommands/ACommandHelp.uc index 81c5ff0..7de2d6a 100644 --- a/sources/Commands/BuiltInCommands/ACommandHelp.uc +++ b/sources/Commands/BuiltInCommands/ACommandHelp.uc @@ -28,27 +28,35 @@ var public const int TKEY, TDOUBLE_KEY, TCOMMA_SPACE, TBOOLEAN, TINDENT; var public const int TBOOLEAN_TRUE_FALSE, TBOOLEAN_ENABLE_DISABLE; var public const int TBOOLEAN_ON_OFF, TBOOLEAN_YES_NO; var public const int TOPTIONS, TCMD_WITH_TARGET, TCMD_WITHOUT_TARGET; +var public const int TSEPARATOR, TLIST_REGIRESTED_CMDS, TEMPTY_GROUP; protected function BuildData(CommandDataBuilder builder) { - builder.Name(P("help")) - .Summary(P("Detailed information about available commands.")); + builder.Name(P("help")).Group(P("core")) + .Summary(P("Displays detailed information about available commands.")); builder.OptionalParams() .ParamTextList(P("commands")) - .Describe(P("Display information about all specified commands.")); + .Describe(P("Displays information about all specified commands.")); builder.Option(P("list")) - .Describe(P("Display list of all available commands.")); + .Describe(P("Display available commands. Optionally command groups can" + @ "be specified and then only commands from such groups will be" + @ "listed. Otherwise all commands will be displayed.")) + .OptionalParams() + .ParamTextList(P("groups")); } protected function Executed(Command.CallData callData, EPlayer callerPlayer) { local HashTable parameters, options;; - local ArrayList commandsToDisplay; + local ArrayList commandsToDisplay, commandGroupsToDisplay; parameters = callData.parameters; options = callData.options; // Print command list if "--list" option was specified - if (options.HasKey(P("list"))) { - DisplayCommandList(callerPlayer); + if (options.HasKey(P("list"))) + { + commandGroupsToDisplay = options.GetArrayListBy(P("/list/groups")); + DisplayCommandLists(commandGroupsToDisplay); + _.memory.Free(commandGroupsToDisplay); } // Help pages. // Only need to print them if: @@ -58,58 +66,95 @@ protected function Executed(Command.CallData callData, EPlayer callerPlayer) if (!options.HasKey(P("list")) || parameters.HasKey(P("commands"))) { commandsToDisplay = parameters.GetArrayList(P("commands")); - DisplayCommandHelpPages(callerPlayer, commandsToDisplay); + DisplayCommandHelpPages(commandsToDisplay); _.memory.Free(commandsToDisplay); } } -private final function DisplayCommandList(EPlayer player) +private final function DisplayCommandLists(ArrayList commandGroupsToDisplay) { local int i; - local ConsoleWriter console; - local Command nextCommand; - local Command.Data nextData; - local array commandNames; + local array commandNames, groupsNames; local Commands_Feature commandsFeature; - if (player == none) return; + commandsFeature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance()); - if (commandsFeature == none) return; - - console = player.BorrowConsole(); - commandNames = commandsFeature.GetCommandNames(); - for (i = 0; i < commandNames.length; i += 1) + if (commandsFeature == none) { + return; + } + if (commandGroupsToDisplay == none) { - nextCommand = commandsFeature.GetCommand(commandNames[i]); - if (nextCommand == none) continue; + groupsNames = commandsFeature.GetGroupsNames(); + DisplayCommandsNamesArray(commandsFeature, commandNames); + } + else + { + for (i = 0; i < commandGroupsToDisplay.GetLength(); i += 1) { + groupsNames[groupsNames.length] = commandGroupsToDisplay.GetText(i); + } + } + callerConsole.WriteLine(T(TLIST_REGIRESTED_CMDS)); + for (i = 0; i < groupsNames.length; i += 1) + { + if (groupsNames[i] == none) { + continue; + } + commandNames = commandsFeature.GetCommandNamesInGroup(groupsNames[i]); + if (commandNames.length > 0) + { + callerConsole.UseColorOnce(_.color.TextSubHeader); + if (groupsNames[i].IsEmpty()) { + callerConsole.WriteLine(T(TEMPTY_GROUP)); + } + else { + callerConsole.WriteLine(groupsNames[i]); + } + DisplayCommandsNamesArray(commandsFeature, commandNames); + _.memory.FreeMany(commandNames); + } + } + _.memory.FreeMany(groupsNames); +} +private final function DisplayCommandsNamesArray( + Commands_Feature commandsFeature, + array commandsNamesArray) +{ + local int i; + local Command nextCommand; + local Command.Data nextData; + + for (i = 0; i < commandsNamesArray.length; i += 1) + { + nextCommand = commandsFeature.GetCommand(commandsNamesArray[i]); + if (nextCommand == none) { + continue; + } nextData = nextCommand.BorrowData(); - console.UseColor(_.color.textEmphasis) + callerConsole.UseColor(_.color.textEmphasis) .Write(nextData.name) .ResetColor() .Write(T(TCOLUMN_SPACE)) .WriteLine(nextData.summary); + _.memory.Free(nextCommand); } - _.memory.FreeMany(commandNames); } -private final function DisplayCommandHelpPages( - EPlayer player, - ArrayList commandList) +private final function DisplayCommandHelpPages(ArrayList commandList) { local int i; local Text nextCommandName; local Command nextCommand; local Commands_Feature commandsFeature; - if (player == none) return; commandsFeature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance()); - if (commandsFeature == none) return; - + if (commandsFeature == none) { + return; + } // If arguments were empty - at least display our own help page if (commandList == none) { - PrintHelpPage(player.BorrowConsole(), BorrowData()); + PrintHelpPage(BorrowData()); return; } // Otherwise - print help for specified commands @@ -118,70 +163,74 @@ private final function DisplayCommandHelpPages( nextCommandName = commandList.GetText(i); nextCommand = commandsFeature.GetCommand(nextCommandName); _.memory.Free(nextCommandName); - if (nextCommand == none) continue; - PrintHelpPage(player.BorrowConsole(), nextCommand.BorrowData()); + if (nextCommand == none) { + continue; + } + if (i > 0) { + callerConsole.WriteLine(T(TSEPARATOR)); + } + PrintHelpPage(nextCommand.BorrowData()); + _.memory.Free(nextCommand); } } -// Following methods are mostly self-explanatory, -// all assume that passed `cout != none` -private final function PrintHelpPage(ConsoleWriter cout, Command.Data data) +// Following methods are mostly self-explanatory +private final function PrintHelpPage(Command.Data data) { local Text commandNameUpperCase; // Get capitalized command name commandNameUpperCase = data.name.UpperCopy(); // Print header: name + basic info - cout.UseColor(_.color.textHeader) + callerConsole.UseColor(_.color.textHeader) .Write(commandNameUpperCase) .UseColor(_.color.textDefault); commandNameUpperCase.FreeSelf(); if (data.requiresTarget) { - cout.WriteLine(T(TCMD_WITH_TARGET)); + callerConsole.WriteLine(T(TCMD_WITH_TARGET)); } else { - cout.WriteLine(T(TCMD_WITHOUT_TARGET)); + callerConsole.WriteLine(T(TCMD_WITHOUT_TARGET)); } // Print commands and options - PrintCommands(cout, data); - PrintOptions(cout, data); + PrintCommands(data); + PrintOptions(data); // Clean up - cout.ResetColor().Flush(); + callerConsole.ResetColor().Flush(); } -private final function PrintCommands(ConsoleWriter cout, Command.Data data) +private final function PrintCommands(Command.Data data) { local int i; local array subCommands; subCommands = data.subCommands; for (i = 0; i < subCommands.length; i += 1) { - PrintSubCommand(cout, subCommands[i], data.name); + PrintSubCommand(subCommands[i], data.name); } } private final function PrintSubCommand( - ConsoleWriter cout, - SubCommand subCommand, - BaseText commandName) + SubCommand subCommand, + BaseText commandName) { // Command + parameters // Command name + sub command name - cout.UseColor(_.color.textEmphasis) + callerConsole.UseColor(_.color.textEmphasis) .Write(commandName) .Write(T(TSPACE)); if (subCommand.name != none && !subCommand.name.IsEmpty()) { - cout.Write(subCommand.name).Write(T(TSPACE)); + callerConsole.Write(subCommand.name).Write(T(TSPACE)); } - cout.UseColor(_.color.textDefault); + callerConsole.UseColor(_.color.textDefault); // Parameters - PrintParameters(cout, subCommand.required, subCommand.optional); - cout.Flush(); + PrintParameters(subCommand.required, subCommand.optional); + callerConsole.Flush(); // Description if (subCommand.description != none && !subCommand.description.IsEmpty()) { - cout.WriteBlock(subCommand.description); + callerConsole.WriteBlock(subCommand.description); } } -private final function PrintOptions(ConsoleWriter cout, Command.Data data) +private final function PrintOptions(Command.Data data) { local int i; local array