/** * Command for displaying help information about registered Acedia's commands. * Copyright 2021 - 2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * * Acedia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * (at your option) any later version. * * Acedia is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ class ACommandHelp extends Command dependson(LoggerAPI); var LoggerAPI.Definition testMsg; var public const int TSPACE, TCOMMAND_NAME_FALLBACK, TPLUS; var public const int TOPEN_BRACKET, TCLOSE_BRACKET, TCOLUMN_SPACE; 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")).Group(P("core")) .Summary(P("Displays detailed information about available commands.")); builder.OptionalParams() .ParamTextList(P("commands")) .Describe(P("Displays information about all specified commands.")); builder.Option(P("list")) .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, commandGroupsToDisplay; parameters = callData.parameters; options = callData.options; // Print command list if "--list" option was specified if (options.HasKey(P("list"))) { commandGroupsToDisplay = options.GetArrayListBy(P("/list/groups")); DisplayCommandLists(commandGroupsToDisplay); _.memory.Free(commandGroupsToDisplay); } // Help pages. // Only need to print them if: // 1. Any commands are specified as parameters; // 2. No commands or "--list" option was specified, then we want to // print a help page for this command. if (!options.HasKey(P("list")) || parameters.HasKey(P("commands"))) { commandsToDisplay = parameters.GetArrayList(P("commands")); DisplayCommandHelpPages(commandsToDisplay); _.memory.Free(commandsToDisplay); } } private final function DisplayCommandLists(ArrayList commandGroupsToDisplay) { local int i; local array commandNames, groupsNames; local Commands_Feature commandsFeature; commandsFeature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance()); if (commandsFeature == none) { return; } if (commandGroupsToDisplay == none) { 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(); callerConsole.UseColor(_.color.textEmphasis) .Write(nextData.name) .ResetColor() .Write(T(TCOLUMN_SPACE)) .WriteLine(nextData.summary); _.memory.Free(nextCommand); } } private final function DisplayCommandHelpPages(ArrayList commandList) { local int i; local Text nextCommandName; local Command nextCommand; local Commands_Feature commandsFeature; commandsFeature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance()); if (commandsFeature == none) { return; } // If arguments were empty - at least display our own help page if (commandList == none) { PrintHelpPage(BorrowData()); return; } // Otherwise - print help for specified commands for (i = 0; i < commandList.GetLength(); i += 1) { nextCommandName = commandList.GetText(i); nextCommand = commandsFeature.GetCommand(nextCommandName); _.memory.Free(nextCommandName); if (nextCommand == none) { continue; } if (i > 0) { callerConsole.WriteLine(T(TSEPARATOR)); } PrintHelpPage(nextCommand.BorrowData()); _.memory.Free(nextCommand); } } // 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 callerConsole.UseColor(_.color.textHeader) .Write(commandNameUpperCase) .UseColor(_.color.textDefault); commandNameUpperCase.FreeSelf(); if (data.requiresTarget) { callerConsole.WriteLine(T(TCMD_WITH_TARGET)); } else { callerConsole.WriteLine(T(TCMD_WITHOUT_TARGET)); } // Print commands and options PrintCommands(data); PrintOptions(data); // Clean up callerConsole.ResetColor().Flush(); } 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(subCommands[i], data.name); } } private final function PrintSubCommand( SubCommand subCommand, BaseText commandName) { // Command + parameters // Command name + sub command name callerConsole.UseColor(_.color.textEmphasis) .Write(commandName) .Write(T(TSPACE)); if (subCommand.name != none && !subCommand.name.IsEmpty()) { callerConsole.Write(subCommand.name).Write(T(TSPACE)); } callerConsole.UseColor(_.color.textDefault); // Parameters PrintParameters(subCommand.required, subCommand.optional); callerConsole.Flush(); // Description if (subCommand.description != none && !subCommand.description.IsEmpty()) { callerConsole.WriteBlock(subCommand.description); } } private final function PrintOptions(Command.Data data) { local int i; local array