/** * 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; protected function BuildData(CommandDataBuilder builder) { builder.Name(P("help")) .Summary(P("Detailed information about available commands.")); builder.OptionalParams() .ParamTextList(P("commands")) .Describe(P("Display information about all specified commands.")); builder.Option(P("list")) .Describe(P("Display list of all available commands.")); } protected function Executed(Command.CallData callData, EPlayer callerPlayer) { local AssociativeArray parameters, options;; local DynamicArray commandsToDisplay; parameters = callData.parameters; options = callData.options; // Print command list if "--list" option was specified if (options.HasKey(P("list"))) { DisplayCommandList(callerPlayer); } // 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 = DynamicArray(parameters.GetItem(P("commands"))); DisplayCommandHelpPages(callerPlayer, commandsToDisplay); } } private final function DisplayCommandList(EPlayer player) { local int i; local ConsoleWriter console; local Command nextCommand; local Command.Data nextData; local array commandNames; 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) { nextCommand = commandsFeature.GetCommand(commandNames[i]); if (nextCommand == none) continue; nextData = nextCommand.GetData(); console.UseColor(_.color.textEmphasis) .Write(nextData.name) .ResetColor() .Write(T(TCOLUMN_SPACE)) .WriteLine(nextData.summary); } _.memory.FreeMany(commandNames); } private final function DisplayCommandHelpPages( EPlayer player, DynamicArray commandList) { local int i; local Command nextCommand; local Commands_Feature commandsFeature; if (player == none) return; 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(player.BorrowConsole(), GetData()); return; } // Otherwise - print help for specified commands for (i = 0; i < commandList.GetLength(); i += 1) { nextCommand = commandsFeature.GetCommand(Text(commandList.GetItem(i))); if (nextCommand == none) continue; PrintHelpPage(player.BorrowConsole(), nextCommand.GetData()); } } // Following methods are mostly self-explanatory, // all assume that passed `cout != none` private final function PrintHelpPage(ConsoleWriter cout, Command.Data data) { local Text commandNameUpperCase; // Get capitalized command name commandNameUpperCase = data.name.UpperCopy(); // Print header: name + basic info cout.UseColor(_.color.textHeader) .Write(commandNameUpperCase) .UseColor(_.color.textDefault); commandNameUpperCase.FreeSelf(); if (data.requiresTarget) { cout.WriteLine(T(TCMD_WITH_TARGET)); } else { cout.WriteLine(T(TCMD_WITHOUT_TARGET)); } // Print commands and options PrintCommands(cout, data); PrintOptions(cout, data); // Clean up cout.ResetColor().Flush(); } private final function PrintCommands(ConsoleWriter cout, 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); } } private final function PrintSubCommand( ConsoleWriter cout, SubCommand subCommand, BaseText commandName) { // Command + parameters // Command name + sub command name cout.UseColor(_.color.textEmphasis) .Write(commandName) .Write(T(TSPACE)); if (subCommand.name != none && !subCommand.name.IsEmpty()) { cout.Write(subCommand.name).Write(T(TSPACE)); } cout.UseColor(_.color.textDefault); // Parameters PrintParameters(cout, subCommand.required, subCommand.optional); cout.Flush(); // Description if (subCommand.description != none && !subCommand.description.IsEmpty()) { cout.WriteBlock(subCommand.description); } } private final function PrintOptions(ConsoleWriter cout, Command.Data data) { local int i; local array