/** * Author: dkanus * Home repo: https://www.insultplayers.ru/git/AcediaFramework/AcediaCore * License: GPL * Copyright 2023 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 ACommandSideEffects extends Command; // Maps `UserID` to `ArrayList` with side effects listed for that player last time var private HashTable displayedLists; protected function Constructor() { super.Constructor(); displayedLists = _.collections.EmptyHashTable(); } protected function Finalizer() { super.Finalizer(); _.memory.Free(displayedLists); displayedLists = none; } protected function BuildData(CommandDataBuilder builder) { builder.Group(P("debug")); builder.Summary(P("Displays information about current side effects.")); builder.Describe(P("This command allows to display current side effects, optionally filtering" @ "them by specified package names.")); builder.OptionalParams(); builder.ParamTextList(P("package_names")); builder.SubCommand(P("show")); builder.Describe(P("This sub-command is only usable after side effects have been shown" @ "at least once. It takes an index from the last displayed list and displays a verbose" @ "information about it.")); builder.ParamInteger(P("side_effect_number")); builder.Option(P("verbose")); builder.Describe(P("Display verbose information about each side effect.")); } protected function Executed( CallData arguments, EPlayer instigator, CommandPermissions permissions ) { local UserID playerID; local array relevantSideEffects; local ArrayList packagesList, storedSideEffectsList; playerID = instigator.GetUserID(); if (arguments.subCommandName.IsEmpty()) { relevantSideEffects = _.sideEffects.GetAll(); packagesList = arguments.parameters.GetArrayList(P("package_names")); FilterSideEffects(/*out*/ relevantSideEffects, packagesList); _.memory.Free(packagesList); DisplaySideEffects(relevantSideEffects, arguments.options.HasKey(P("verbose"))); // Store new side effect list storedSideEffectsList = _.collections.NewArrayList(relevantSideEffects); displayedLists.SetItem(playerID, storedSideEffectsList); _.memory.FreeMany(relevantSideEffects); _.memory.Free(storedSideEffectsList); } else { ShowInfoFor(playerID, arguments.parameters.GetInt(P("side_effect_number"))); } _.memory.Free(playerID); } private function FilterSideEffects(out array sideEffects, ArrayList allowedPackages) { local int i, j; local int packagesLength; local bool matchedPackage; local Text nextSideEffectPackage, nextAllowedPackage; if (allowedPackages == none) return; if (allowedPackages.GetLength() <= 0) return; packagesLength = allowedPackages.GetLength(); while (i < sideEffects.length) { nextSideEffectPackage = sideEffects[i].GetPackage(); matchedPackage = false; for (j = 0; j < packagesLength; j += 1) { nextAllowedPackage = allowedPackages.GetText(j); if (nextAllowedPackage.Compare(nextSideEffectPackage, SCASE_INSENSITIVE)) { matchedPackage = true; _.memory.Free(nextAllowedPackage); break; } _.memory.Free(nextAllowedPackage); } if (!matchedPackage) { sideEffects.Remove(i, 1); } else { i += 1; } _.memory.Free(nextSideEffectPackage); } } private function DisplaySideEffects(array toDisplay, bool verbose) { local int i; local MutableText nextPrefix; if (toDisplay.length <= 0) { callerConsole.Write(F("List of side effects is {$TextNeutral empty}.")); } for (i = 0; i < toDisplay.length; i += 1) { nextPrefix = _.text.FromIntM(i + 1); nextPrefix.Append(P(".")); DisplaySideEffect(toDisplay[i], nextPrefix, verbose); _.memory.Free(nextPrefix); } } private function DisplaySideEffect(SideEffect toDisplay, BaseText prefix, bool verbose) { local Text effectName, effectDescription, effectPackage, effectSource, effectStatus; if (toDisplay == none) { return; } if (prefix != none) { callerConsole.Write(prefix); callerConsole.Write(P(" ")); } effectName = toDisplay.GetName(); effectPackage = toDisplay.GetPackage(); effectSource = toDisplay.GetSource(); effectStatus = toDisplay.GetStatus(); callerConsole.UseColor(_.color.TextEmphasis); callerConsole.Write(P("[")); callerConsole.Write(effectPackage); callerConsole.Write(P(" \\ ")); callerConsole.Write(effectSource); callerConsole.Write(P("] ")); callerConsole.ResetColor(); callerConsole.Write(effectName); callerConsole.Write(P(" {")); callerConsole.Write(effectStatus); callerConsole.WriteLine(P("}")); if (verbose) { effectDescription = toDisplay.GetDescription(); callerConsole.WriteBlock(effectDescription); } _.memory.Free5(effectName, effectDescription, effectPackage, effectSource, effectStatus); } private function ShowInfoFor(UserID playerID, int sideEffectIndex) { local SideEffect toDisplay; local ArrayList sideEffectList; if (playerID == none) { return; } if (sideEffectIndex <= 0) { callerConsole.WriteLine(F("Specified side effect index {$TextNegative isn't positive}!")); return; } sideEffectList = displayedLists.GetArrayList(playerID); if (sideEffectList == none) { callerConsole.WriteLine(F("{$TextNegative Cannot display} side effect by index without" @ "first listing them. Call {$TextEmphasis sideeffects} command without" @ "{$TextEmphasis show} subcommand first.")); return; } if (sideEffectIndex > sideEffectList.GetLength()) { callerConsole.WriteLine(F("Specified side effect index is {$TextNegative out of bounds}.")); _.memory.Free(sideEffectList); return; } // Above we checked that `sideEffectIndex` lies within `[0; sideEffectList.GetLength()]` segment // This means that `sideEffectIndex - 1` points at non-`none` value toDisplay = SideEffect(sideEffectList.GetItem(sideEffectIndex - 1)); if (!_.sideEffects.IsRegistered(toDisplay)) { callerConsole.UseColorOnce(_.color.TextWarning); callerConsole.WriteLine(P("Selected side effect is no longer active!")); } DisplaySideEffect(toDisplay, none, true); _.memory.Free2(toDisplay, sideEffectList); } defaultproperties { preferredName = "sideeffects" }