Browse Source

Change built-in commands to support new `CommandAPI`

develop
Anton Tarasenko 1 year ago
parent
commit
7ff806b104
  1. 45
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandFakers.uc
  2. 227
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandHelp.uc
  3. 9
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandNotify.uc
  4. 10
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandSideEffects.uc
  5. 137
      sources/BaseAPI/API/Commands/BuiltInCommands/ACommandVote.uc

45
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandFakers.uc

@ -24,8 +24,12 @@ class ACommandFakers extends Command
var private array<UserID> fakers; var private array<UserID> fakers;
protected static function StaticFinalizer() {
__().memory.FreeMany(default.fakers);
default.fakers.length = 0;
}
protected function BuildData(CommandDataBuilder builder) { protected function BuildData(CommandDataBuilder builder) {
builder.Name(P("fakers"));
builder.Group(P("debug")); builder.Group(P("debug"));
builder.Summary(P("Adds fake voters for testing \"vote\" command.")); builder.Summary(P("Adds fake voters for testing \"vote\" command."));
builder.Describe(P("Displays current fake voters.")); builder.Describe(P("Displays current fake voters."));
@ -40,7 +44,11 @@ protected function BuildData(CommandDataBuilder builder) {
builder.ParamBoolean(P("vote_for")); builder.ParamBoolean(P("vote_for"));
} }
protected function Executed(CallData arguments, EPlayer instigator) { protected function Executed(
CallData arguments,
EPlayer instigator,
CommandPermissions permissions
) {
if (arguments.subCommandName.IsEmpty()) { if (arguments.subCommandName.IsEmpty()) {
DisplayCurrentFakers(); DisplayCurrentFakers();
} else if (arguments.subCommandName.Compare(P("amount"), SCASE_INSENSITIVE)) { } else if (arguments.subCommandName.Compare(P("amount"), SCASE_INSENSITIVE)) {
@ -52,14 +60,8 @@ protected function Executed(CallData arguments, EPlayer instigator) {
} }
} }
public final function UpdateFakersForVoting() { public final static function /*borrow*/ array<UserID> BorrowDebugVoters() {
local Voting currentVoting; return default.fakers;
currentVoting = GetCurrentVoting();
if (currentVoting != none) {
currentVoting.SetDebugVoters(fakers);
}
_.memory.Free(currentVoting);
} }
private final function CastVote(int fakerID, bool voteFor) { private final function CastVote(int fakerID, bool voteFor) {
@ -71,7 +73,7 @@ private final function CastVote(int fakerID, bool voteFor) {
.WriteLine(P("Faker number is out of bounds.")); .WriteLine(P("Faker number is out of bounds."));
return; return;
} }
currentVoting = GetCurrentVoting(); currentVoting = _.commands.GetCurrentVoting();
if (currentVoting == none) { if (currentVoting == none) {
callerConsole callerConsole
.UseColor(_.color.TextFailure) .UseColor(_.color.TextFailure)
@ -86,6 +88,7 @@ private final function ChangeAmount(int newAmount) {
local int i; local int i;
local Text nextIDName; local Text nextIDName;
local UserID nextID; local UserID nextID;
local Voting currentVoting;
if (newAmount < 0) { if (newAmount < 0) {
callerConsole callerConsole
@ -110,19 +113,12 @@ private final function ChangeAmount(int newAmount) {
} }
fakers.length = newAmount; fakers.length = newAmount;
} }
UpdateFakersForVoting(); default.fakers = fakers;
} currentVoting = _.commands.GetCurrentVoting();
if (currentVoting != none) {
private function Voting GetCurrentVoting() { currentVoting.SetDebugVoters(default.fakers);
local Commands_Feature feature; _.memory.Free(currentVoting);
local Voting result;
feature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance());
if (feature != none) {
result = feature.GetCurrentVoting();
feature.FreeSelf();
} }
return result;
} }
private function DisplayCurrentFakers() { private function DisplayCurrentFakers() {
@ -135,7 +131,7 @@ private function DisplayCurrentFakers() {
callerConsole.WriteLine(P("No fakers!")); callerConsole.WriteLine(P("No fakers!"));
return; return;
} }
currentVoting = GetCurrentVoting(); currentVoting =_.commands.GetCurrentVoting();
for (i = 0; i < fakers.length; i += 1) { for (i = 0; i < fakers.length; i += 1) {
nextNumber = _.text.FromIntM(i); nextNumber = _.text.FromIntM(i);
callerConsole callerConsole
@ -163,4 +159,5 @@ private function DisplayCurrentFakers() {
} }
defaultproperties { defaultproperties {
preferredName = "fakers"
} }

227
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandHelp.uc

@ -1,6 +1,6 @@
/** /**
* Command for displaying help information about registered Acedia's commands. * Command for displaying help information about registered Acedia's commands.
* Copyright 2021-2022 Anton Tarasenko * Copyright 2021-2023 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *
@ -18,7 +18,8 @@
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class ACommandHelp extends Command class ACommandHelp extends Command
dependson(LoggerAPI); dependson(LoggerAPI)
dependson(CommandAPI);
/** /**
* # `ACommandHelp` * # `ACommandHelp`
@ -72,6 +73,8 @@ class ACommandHelp extends Command
// that uses sub-command names as keys and returns `ArrayList` of aliases. // that uses sub-command names as keys and returns `ArrayList` of aliases.
var private HashTable commandToAliasesMap; var private HashTable commandToAliasesMap;
var private User callerUser;
var public const int TSPACE, TCOMMAND_NAME_FALLBACK, TPLUS; var public const int TSPACE, TCOMMAND_NAME_FALLBACK, TPLUS;
var public const int TOPEN_BRACKET, TCLOSE_BRACKET, TCOLON_SPACE; var public const int TOPEN_BRACKET, TCLOSE_BRACKET, TCOLON_SPACE;
var public const int TKEY, TDOUBLE_KEY, TCOMMA_SPACE, TBOOLEAN, TINDENT; var public const int TKEY, TDOUBLE_KEY, TCOMMA_SPACE, TBOOLEAN, TINDENT;
@ -79,7 +82,8 @@ var public const int TBOOLEAN_TRUE_FALSE, TBOOLEAN_ENABLE_DISABLE;
var public const int TBOOLEAN_ON_OFF, TBOOLEAN_YES_NO; 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 TOPTIONS, TCMD_WITH_TARGET, TCMD_WITHOUT_TARGET;
var public const int TSEPARATOR, TLIST_REGIRESTED_CMDS, TEMPTY_GROUP; var public const int TSEPARATOR, TLIST_REGIRESTED_CMDS, TEMPTY_GROUP;
var public const int TALIASES_FOR, TEMPTY, TDOT; var public const int TALIASES_FOR, TEMPTY, TDOT, TNO_COMMAND_BEGIN;
var public const int TNO_COMMAND_END, TEMPTY_GROUP_BEGIN, TEMPTY_GROUP_END;
protected function Constructor() protected function Constructor()
{ {
@ -96,13 +100,13 @@ protected function Constructor()
protected function Finalizer() protected function Finalizer()
{ {
super.Finalizer();
_.memory.Free(commandToAliasesMap); _.memory.Free(commandToAliasesMap);
commandToAliasesMap = none; commandToAliasesMap = none;
} }
protected function BuildData(CommandDataBuilder builder) protected function BuildData(CommandDataBuilder builder)
{ {
builder.Name(P("help"));
builder.Group(P("core")); builder.Group(P("core"));
builder.Summary(P("Displays detailed information about available commands.")); builder.Summary(P("Displays detailed information about available commands."));
builder.OptionalParams(); builder.OptionalParams();
@ -120,13 +124,18 @@ protected function BuildData(CommandDataBuilder builder)
builder.ParamTextList(P("groups")); builder.ParamTextList(P("groups"));
} }
protected function Executed(Command.CallData callData, EPlayer callerPlayer) protected function Executed(
{ Command.CallData callData,
EPlayer callerPlayer,
CommandPermissions permissions
) {
local bool printedSomething;
local HashTable parameters, options; local HashTable parameters, options;
local ArrayList commandsToDisplay, commandGroupsToDisplay; local ArrayList commandsToDisplay, commandGroupsToDisplay;
parameters = callData.parameters; callerUser = callerPlayer.GetIdentity();
options = callData.options; parameters = callData.parameters;
options = callData.options;
// Print command list if "--list" option was specified // Print command list if "--list" option was specified
if (options.HasKey(P("list"))) if (options.HasKey(P("list")))
{ {
@ -135,6 +144,7 @@ protected function Executed(Command.CallData callData, EPlayer callerPlayer)
commandGroupsToDisplay, commandGroupsToDisplay,
options.HasKey(P("aliases"))); options.HasKey(P("aliases")));
_.memory.Free(commandGroupsToDisplay); _.memory.Free(commandGroupsToDisplay);
printedSomething = true;
} }
// Help pages. // Help pages.
// Only need to print them if: // Only need to print them if:
@ -144,9 +154,11 @@ protected function Executed(Command.CallData callData, EPlayer callerPlayer)
if (!options.HasKey(P("list")) || parameters.HasKey(P("commands"))) if (!options.HasKey(P("list")) || parameters.HasKey(P("commands")))
{ {
commandsToDisplay = parameters.GetArrayList(P("commands")); commandsToDisplay = parameters.GetArrayList(P("commands"));
DisplayCommandHelpPages(commandsToDisplay); DisplayCommandHelpPages(commandsToDisplay, printedSomething);
_.memory.Free(commandsToDisplay); _.memory.Free(commandsToDisplay);
} }
_.memory.Free(callerUser);
callerUser = none;
} }
// If instance of the `Aliases_Feature` is passed as an argument (allowing this // If instance of the `Aliases_Feature` is passed as an argument (allowing this
@ -247,17 +259,11 @@ private final function DisplayCommandLists(
ArrayList commandGroupsToDisplay, ArrayList commandGroupsToDisplay,
bool displayAliases) bool displayAliases)
{ {
local int i; local int i;
local array<Text> commandNames, groupsNames; local array<Text> commandNames, groupsNames;
local Commands_Feature commandsFeature;
commandsFeature =
Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance());
if (commandsFeature == none) {
return;
}
if (commandGroupsToDisplay == none) { if (commandGroupsToDisplay == none) {
groupsNames = commandsFeature.GetGroupsNames(); groupsNames = _.commands.GetGroupsNames();
} }
else else
{ {
@ -271,7 +277,7 @@ private final function DisplayCommandLists(
if (groupsNames[i] == none) { if (groupsNames[i] == none) {
continue; continue;
} }
commandNames = commandsFeature.GetCommandNamesInGroup(groupsNames[i]); commandNames = _.commands.GetCommandNamesInGroup(groupsNames[i]);
if (commandNames.length > 0) if (commandNames.length > 0)
{ {
callerConsole.UseColorOnce(_.color.TextSubHeader); callerConsole.UseColorOnce(_.color.TextSubHeader);
@ -282,41 +288,45 @@ private final function DisplayCommandLists(
callerConsole.WriteLine(groupsNames[i]); callerConsole.WriteLine(groupsNames[i]);
} }
PrintCommandsNamesArray( PrintCommandsNamesArray(
commandsFeature,
commandNames, commandNames,
displayAliases); displayAliases);
_.memory.FreeMany(commandNames); _.memory.FreeMany(commandNames);
} else {
callerConsole.UseColor(_.color.TextFailure);
callerConsole.Write(T(TEMPTY_GROUP_BEGIN));
callerConsole.Write(groupsNames[i]);
callerConsole.WriteLine(T(TEMPTY_GROUP_END));
callerConsole.ResetColor();
} }
} }
_.memory.FreeMany(groupsNames); _.memory.FreeMany(groupsNames);
commandsFeature.FreeSelf();
} }
private final function PrintCommandsNamesArray( private final function PrintCommandsNamesArray(
Commands_Feature commandsFeature, array<Text> commandsNamesArray,
array<Text> commandsNamesArray, bool displayAliases
bool displayAliases) ) {
{ local int i;
local int i; local Command.Data nextData;
local Command nextCommand; local CommandAPI.CommandConfigInfo nextCommandPair;
local Command.Data nextData;
for (i = 0; i < commandsNamesArray.length; i += 1) for (i = 0; i < commandsNamesArray.length; i += 1)
{ {
nextCommand = commandsFeature.GetCommand(commandsNamesArray[i]); nextCommandPair = _.commands.ResolveCommandForUser(
if (nextCommand == none) { commandsNamesArray[i],
continue; callerUser);
} if (nextCommandPair.instance != none && !nextCommandPair.usageForbidden) {
nextData = nextCommand.BorrowData(); nextData = nextCommandPair.instance.BorrowData();
callerConsole callerConsole
.UseColorOnce(_.color.textEmphasis) .UseColorOnce(_.color.textEmphasis)
.Write(nextData.name) .Write(commandsNamesArray[i])
.Write(T(TCOLON_SPACE)) .Write(T(TCOLON_SPACE))
.WriteLine(nextData.summary); .WriteLine(nextData.summary);
if (displayAliases) { if (displayAliases) {
PrintCommandAliases(nextData.name); PrintCommandAliases(commandsNamesArray[i]);
}
} }
_.memory.Free(nextCommand); _.memory.Free(nextCommandPair.instance);
} }
} }
@ -397,46 +407,47 @@ private final function PrintAliasesArray(
callerConsole.WriteBlock(); callerConsole.WriteBlock();
} }
private final function DisplayCommandHelpPages(ArrayList commandList) private final function DisplayCommandHelpPages(ArrayList commandList, bool printedSomething) {
{ local int i;
local int i; local Text nextUserProvidedName;
local bool printedSomething; local MutableText referredSubcommand;
local Text nextUserProvidedName; local CommandAPI.CommandConfigInfo nextPair;
local MutableText referredSubcommand;
local Command nextCommand;
// If arguments were empty - at least display our own help page // If arguments were empty - at least display our own help page
if (commandList == none) if (commandList == none) {
{ nextPair.instance = self;
PrintHelpPageFor(BorrowData().name, none, BorrowData()); PrintHelpPageFor(usedName, none, nextPair);
return; return;
} }
// Otherwise - print help for specified commands // Otherwise - print help for specified commands
for (i = 0; i < commandList.GetLength(); i += 1) for (i = 0; i < commandList.GetLength(); i += 1) {
{
nextUserProvidedName = commandList.GetText(i); nextUserProvidedName = commandList.GetText(i);
nextCommand = GetCommandFromUserProvidedName( nextPair = GetCommandFromUserProvidedName(
nextUserProvidedName, nextUserProvidedName,
referredSubcommand); /*out*/ referredSubcommand);
if (nextCommand != none) if (nextPair.instance != none && !nextPair.usageForbidden) {
{
if (printedSomething) { if (printedSomething) {
callerConsole.WriteLine(T(TSEPARATOR)); callerConsole.WriteLine(T(TSEPARATOR));
} }
PrintHelpPageFor( PrintHelpPageFor(
nextUserProvidedName, nextUserProvidedName,
referredSubcommand, referredSubcommand,
nextCommand.BorrowData()); nextPair);
printedSomething = true; printedSomething = true;
} else if (nextPair.instance != none) {
callerConsole.UseColor(_.color.TextFailure);
callerConsole.Write(T(TNO_COMMAND_BEGIN));
callerConsole.Write(nextUserProvidedName);
callerConsole.WriteLine(T(TNO_COMMAND_END));
callerConsole.ResetColor();
} }
_.memory.Free(nextCommand); _.memory.Free(nextPair.instance);
_.memory.Free(nextUserProvidedName); _.memory.Free(nextUserProvidedName);
_.memory.Free(referredSubcommand); _.memory.Free(referredSubcommand);
// `referredSubcommand` is passed as an `out` parameter on // `referredSubcommand` is passed as an `out` parameter on
// every iteration, so we need to prevent the possibility of its value // every iteration, so we need to prevent the possibility of its value
// being used. // being used.
// NOTE: `nextCommand` and `nextUserProvidedName` are just // NOTE: `nextCommand` and `nextUserProvidedName` are just rewritten.
// rewritten.
referredSubcommand = none; referredSubcommand = none;
} }
} }
@ -446,56 +457,49 @@ private final function DisplayCommandHelpPages(ArrayList commandList)
// is passed) and is used to return name of the subcommand for returned // is passed) and is used to return name of the subcommand for returned
// `Command` that is specified by `nextUserProvidedName` (only relevant for // `Command` that is specified by `nextUserProvidedName` (only relevant for
// aliases that refer to a particular subcommand). // aliases that refer to a particular subcommand).
private final function Command GetCommandFromUserProvidedName( private final function CommandAPI.CommandConfigInfo GetCommandFromUserProvidedName(
BaseText nextUserProvidedName, BaseText nextUserProvidedName,
out MutableText referredSubcommand) out MutableText referredSubcommand)
{ {
local Command result; local CommandAPI.CommandConfigInfo result;
local Text commandAliasValue; local Text commandAliasValue;
local Commands_Feature commandsFeature; local MutableText parsedCommandName;
local MutableText parsedCommandName;
// Clear `out` parameter no matter what // Clear `out` parameter no matter what
if (referredSubcommand != none) if (referredSubcommand != none) {
{
referredSubcommand.FreeSelf(); referredSubcommand.FreeSelf();
referredSubcommand = none; referredSubcommand = none;
} }
// Try accessing (check availability of) `Commands_Feature`
commandsFeature =
Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance());
if (commandsFeature == none) {
return none;
}
// Try getting command using `nextUserProvidedName` as a literal name // Try getting command using `nextUserProvidedName` as a literal name
result = commandsFeature.GetCommand(nextUserProvidedName); result = _.commands.ResolveCommandForUser(nextUserProvidedName, callerUser);
if (result != none) if (result.instance != none) {
{
commandsFeature.FreeSelf();
return result; return result;
} }
// On failure - try resolving it as an alias // On failure - try resolving it as an alias
commandAliasValue = _.alias.ResolveCommand(nextUserProvidedName); commandAliasValue = _.alias.ResolveCommand(nextUserProvidedName);
ParseCommandNames(commandAliasValue, parsedCommandName, referredSubcommand); ParseCommandNames(commandAliasValue, parsedCommandName, referredSubcommand);
result = commandsFeature.GetCommand(parsedCommandName); result = _.commands.ResolveCommandForUser(parsedCommandName, callerUser);
if ( result.instance == none
|| !result.instance.IsSubCommandAllowed(referredSubcommand, result.config)) {
_.memory.Free(result.instance);
return result;
}
// Empty subcommand name from the alias is essentially no subcommand name // Empty subcommand name from the alias is essentially no subcommand name
if (referredSubcommand != none && referredSubcommand.IsEmpty()) if (referredSubcommand != none && referredSubcommand.IsEmpty()) {
{
referredSubcommand.FreeSelf(); referredSubcommand.FreeSelf();
referredSubcommand = none; referredSubcommand = none;
} }
_.memory.Free(commandAliasValue); _.memory.Free2(commandAliasValue, parsedCommandName);
_.memory.Free(parsedCommandName);
commandsFeature.FreeSelf();
return result; return result;
} }
private final function PrintHelpPageFor( private final function PrintHelpPageFor(
BaseText commandAlias, BaseText commandAlias,
BaseText referredSubcommand, BaseText referredSubcommand,
Command.Data commandData) CommandAPI.CommandConfigInfo commandPair
{ ) {
local Text commandNameLowerCase, commandNameUpperCase; local Text commandNameLowerCase, commandNameUpperCase;
// Get capitalized command name // Get capitalized command name
commandNameUpperCase = commandAlias.UpperCopy(); commandNameUpperCase = commandAlias.UpperCopy();
// Print header: name + basic info // Print header: name + basic info
@ -503,7 +507,7 @@ private final function PrintHelpPageFor(
.Write(commandNameUpperCase) .Write(commandNameUpperCase)
.UseColor(_.color.textDefault); .UseColor(_.color.textDefault);
commandNameUpperCase.FreeSelf(); commandNameUpperCase.FreeSelf();
if (commandData.requiresTarget) { if (commandPair.instance.BorrowData().requiresTarget) {
callerConsole.WriteLine(T(TCMD_WITH_TARGET)); callerConsole.WriteLine(T(TCMD_WITH_TARGET));
} }
else { else {
@ -511,31 +515,27 @@ private final function PrintHelpPageFor(
} }
// Print commands and options // Print commands and options
commandNameLowerCase = commandAlias.LowerCopy(); commandNameLowerCase = commandAlias.LowerCopy();
PrintCommands(commandData, commandNameLowerCase, referredSubcommand); PrintCommands(commandPair, commandNameLowerCase, referredSubcommand);
commandNameLowerCase.FreeSelf(); commandNameLowerCase.FreeSelf();
PrintOptions(commandData); PrintOptions(commandPair.instance.BorrowData());
// Clean up // Clean up
callerConsole.ResetColor().Flush(); callerConsole.ResetColor().Flush();
} }
private final function PrintCommands( private final function PrintCommands(
Command.Data data, CommandAPI.CommandConfigInfo commandPair,
BaseText commandName, BaseText commandName,
BaseText referredSubcommand) BaseText referredSubcommand
{ ) {
local int i; local int i;
local array<SubCommand> subCommands; local array<Command.SubCommand> subCommands;
subCommands = data.subCommands; subCommands = commandPair.instance.BorrowData().subCommands;
for (i = 0; i < subCommands.length; i += 1) for (i = 0; i < subCommands.length; i += 1) {
{ if (referredSubcommand == none || referredSubcommand.Compare(subCommands[i].name)) {
if ( referredSubcommand == none if (commandPair.instance.IsSubCommandAllowed(subCommands[i].name, commandPair.config)) {
|| referredSubcommand.Compare(subCommands[i].name)) PrintSubCommand(subCommands[i], commandName, referredSubcommand != none);
{ }
PrintSubCommand(
subCommands[i],
commandName,
referredSubcommand != none);
} }
} }
} }
@ -719,4 +719,13 @@ defaultproperties
stringConstants(21) = "" stringConstants(21) = ""
TDOT = 22 TDOT = 22
stringConstants(22) = "." stringConstants(22) = "."
TNO_COMMAND_BEGIN = 23
stringConstants(23) = "Command `"
TNO_COMMAND_END = 24
stringConstants(24) = "` not found!"
TEMPTY_GROUP_BEGIN = 25
stringConstants(25) = "No commands in group \""
TEMPTY_GROUP_END = 26
stringConstants(26) = "\"!"
preferredName = "help"
} }

9
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandNotify.uc

@ -23,7 +23,6 @@ class ACommandNotify extends Command
dependsOn(ChatApi); dependsOn(ChatApi);
protected function BuildData(CommandDataBuilder builder) { protected function BuildData(CommandDataBuilder builder) {
builder.Name(P("notify"));
builder.Group(P("core")); builder.Group(P("core"));
builder.Summary(P("Notifies players with provided message.")); builder.Summary(P("Notifies players with provided message."));
builder.ParamText(P("message")); builder.ParamText(P("message"));
@ -43,7 +42,12 @@ protected function BuildData(CommandDataBuilder builder) {
builder.ParamText(P("channel_name")); builder.ParamText(P("channel_name"));
} }
protected function ExecutedFor(EPlayer target, CallData arguments, EPlayer instigator) { protected function ExecutedFor(
EPlayer target,
CallData arguments,
EPlayer instigator,
CommandPermissions permissions
) {
local Text title, message, plainTitle, plainMessage; local Text title, message, plainTitle, plainMessage;
plainMessage = arguments.parameters.GetText(P("message")); plainMessage = arguments.parameters.GetText(P("message"));
@ -61,4 +65,5 @@ protected function ExecutedFor(EPlayer target, CallData arguments, EPlayer insti
} }
defaultproperties { defaultproperties {
preferredName = "notify"
} }

10
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandSideEffects.uc

@ -36,8 +36,7 @@ protected function Finalizer() {
} }
protected function BuildData(CommandDataBuilder builder) { protected function BuildData(CommandDataBuilder builder) {
builder.Name(P("sideeffects")); builder.Group(P("debug"));
builder.Group(P("core"));
builder.Summary(P("Displays information about current side effects.")); builder.Summary(P("Displays information about current side effects."));
builder.Describe(P("This command allows to display current side effects, optionally filtering" builder.Describe(P("This command allows to display current side effects, optionally filtering"
@ "them by specified package names.")); @ "them by specified package names."));
@ -54,7 +53,11 @@ protected function BuildData(CommandDataBuilder builder) {
builder.Describe(P("Display verbose information about each side effect.")); builder.Describe(P("Display verbose information about each side effect."));
} }
protected function Executed(CallData arguments, EPlayer instigator) { protected function Executed(
CallData arguments,
EPlayer instigator,
CommandPermissions permissions
) {
local UserID playerID; local UserID playerID;
local array<SideEffect> relevantSideEffects; local array<SideEffect> relevantSideEffects;
local ArrayList packagesList, storedSideEffectsList; local ArrayList packagesList, storedSideEffectsList;
@ -190,4 +193,5 @@ private function ShowInfoFor(UserID playerID, int sideEffectIndex) {
} }
defaultproperties { defaultproperties {
preferredName = "sideeffects"
} }

137
sources/BaseAPI/API/Commands/BuiltInCommands/ACommandVote.uc

@ -19,62 +19,93 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. * along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/ */
class ACommandVote extends Command; class ACommandVote extends Command
dependson(CommandAPI)
dependson(VotingModel);
var private CommandDataBuilder dataBuilder; var private CommandDataBuilder dataBuilder;
protected function Constructor() { protected function Constructor() {
ResetVotingInfo(); ResetVotingInfo();
_.commands.OnVotingAdded(self).connect = AddVotingInfo;
_.commands.OnVotingRemoved(self).connect = HandleRemovedVoting;
_.chat.OnVoiceMessage(self).connect = VoteWithVoice;
} }
protected function Finalizer() { protected function Finalizer() {
super.Finalizer(); super.Finalizer();
_.memory.Free(dataBuilder); _.memory.Free(dataBuilder);
dataBuilder = none; dataBuilder = none;
_.commands.OnVotingAdded(self).Disconnect();
_.commands.OnVotingRemoved(self).Disconnect();
_.chat.OnVoiceMessage(self).Disconnect();
} }
protected function BuildData(CommandDataBuilder builder) { protected function BuildData(CommandDataBuilder builder) {
builder.Name(P("vote"));
builder.Group(P("core")); builder.Group(P("core"));
builder.Summary(P("Allows players to initiate any available voting." builder.Summary(P("Allows players to initiate any available voting."
@ "Votings themselves are added as sub-commands.")); @ "Voting options themselves are specified as sub-commands."));
builder.Describe(P("Default command simply displaces information about current vote.")); builder.Describe(P("Default command simply displaces information about current vote."));
dataBuilder.SubCommand(P("yes")); dataBuilder.SubCommand(P("yes"));
builder.Describe(P("Vote `yes` on the current vote.")); builder.Describe(P("Vote `yes` on the current vote."));
dataBuilder.SubCommand(P("no")); dataBuilder.SubCommand(P("no"));
builder.Describe(P("Vote `no` on the current vote.")); builder.Describe(P("Vote `no` on the current vote."));
builder.Option(P("force"));
builder.Describe(P("Tries to force voting to end immediately with the desired result."));
} }
protected function Executed(CallData arguments, EPlayer instigator) { protected function Executed(
CallData arguments,
EPlayer instigator,
CommandPermissions permissions
) {
local bool forcingVoting;
local VotingModel.ForceEndingType forceType;
local Voting currentVoting; local Voting currentVoting;
local Commands_Feature feature;
feature = Commands_Feature(class'Commands_Feature'.static.GetEnabledInstance()); forcingVoting = arguments.options.HasKey(P("force"));
if (feature == none) { currentVoting = _.commands.GetCurrentVoting();
callerConsole
.UseColor(_.color.TextFailure)
.WriteLine(P("Feature responsible for commands and voting isn't enabled."
@ "This is unexpected, something broke terribly."));
return;
} else {
currentVoting = feature.GetCurrentVoting();
}
if (arguments.subCommandName.IsEmpty()) { if (arguments.subCommandName.IsEmpty()) {
DisplayInfoAboutVoting(instigator, currentVoting); DisplayInfoAboutVoting(instigator, currentVoting);
} else if (arguments.subCommandName.Compare(P("yes"), SCASE_INSENSITIVE)) { } else if (arguments.subCommandName.Compare(P("yes"), SCASE_INSENSITIVE)) {
CastVote(currentVoting, instigator, true); CastVote(currentVoting, instigator, true);
forceType = FET_Success;
} else if (arguments.subCommandName.Compare(P("no"), SCASE_INSENSITIVE)) { } else if (arguments.subCommandName.Compare(P("no"), SCASE_INSENSITIVE)) {
CastVote(currentVoting, instigator, false); CastVote(currentVoting, instigator, false);
forceType = FET_Failure;
} else if (StartVoting(arguments, currentVoting, instigator)) {
_.memory.Free(currentVoting);
currentVoting = _.commands.GetCurrentVoting();
forceType = FET_Success;
} else { } else {
StartVoting(arguments.subCommandName, feature, currentVoting, instigator); forcingVoting = false;
}
if (currentVoting != none && !currentVoting.HasEnded() && forcingVoting) {
if (currentVoting.ForceEnding(instigator, forceType) == FEO_Forbidden) {
callerConsole
.WriteLine(F("You {$TextNegative aren't allowed} to forcibly end current voting"));
}
}
_.memory.Free(currentVoting);
}
private final function VoteWithVoice(EPlayer sender, ChatApi.BuiltInVoiceMessage message) {
local Voting currentVoting;
currentVoting = _.commands.GetCurrentVoting();
if (message == BIVM_AckYes) {
CastVote(currentVoting, sender, true);
}
if (message == BIVM_AckNo) {
CastVote(currentVoting, sender, false);
} }
_.memory.Free(feature);
_.memory.Free(currentVoting); _.memory.Free(currentVoting);
} }
/// Adds sub-command information about given voting with a given name. /// Adds sub-command information about given voting with a given name.
public final function AddVotingInfo(BaseText processName, class<Voting> processClass) { public final function AddVotingInfo(class<Voting> processClass, Text processName) {
if (processName == none) return; if (processName == none) return;
if (processClass == none) return; if (processClass == none) return;
if (dataBuilder == none) return; if (dataBuilder == none) return;
@ -84,6 +115,19 @@ public final function AddVotingInfo(BaseText processName, class<Voting> processC
commandData = dataBuilder.BorrowData(); commandData = dataBuilder.BorrowData();
} }
public final function HandleRemovedVoting(class<Voting> votingClass) {
local int i;
local array<Text> votingsNames;
ResetVotingInfo();
// Rebuild the whole voting data
votingsNames = _.commands.GetAllVotingsNames();
for (i = 0; i < votingsNames.length; i += 1) {
AddVotingInfo(_.commands.GetVotingClass(votingsNames[i]), votingsNames[i]);
}
_.memory.FreeMany(votingsNames);
}
/// Clears all sub-command information added from [`Voting`]s. /// Clears all sub-command information added from [`Voting`]s.
public final function ResetVotingInfo() { public final function ResetVotingInfo() {
_.memory.Free(dataBuilder); _.memory.Free(dataBuilder);
@ -109,41 +153,54 @@ private final function CastVote(Voting currentVoting, EPlayer voter, bool voteFo
} }
// Assumes all arguments aren't `none`. // Assumes all arguments aren't `none`.
private final function StartVoting( private final function bool StartVoting(
BaseText votingName, CallData arguments,
Commands_Feature feature,
Voting currentVoting, Voting currentVoting,
EPlayer instigator EPlayer instigator
) { ) {
local Command fakersCommand;
local Voting newVoting; local Voting newVoting;
local Commands_Feature.StartVotingResult result; local User callerUser;
local CommandAPI.VotingConfigInfo pair;
local CommandAPI.StartVotingResult result;
result = feature.StartVoting(votingName); callerUser = instigator.GetIdentity();
// Handle errors pair = _.commands.ResolveVotingForUser(arguments.subCommandName, callerUser);
if (result == SVR_UnknownVoting) { _.memory.Free(callerUser);
if (pair.votingClass == none) {
callerConsole callerConsole
.UseColor(_.color.TextFailure) .UseColor(_.color.TextFailure)
.Write(P("Unknown voting option \"")) .Write(P("Unknown voting option \""))
.Write(votingName) .Write(arguments.subCommandName)
.WriteLine(P("\"")); .WriteLine(P("\""));
return; return false;
} else if (result == SVR_AlreadyInProgress) { }
if (pair.usageForbidden) {
callerConsole
.UseColor(_.color.TextFailure)
.Write(P("You aren't allowed to start \""))
.Write(arguments.subCommandName)
.WriteLine(P("\" voting"));
return false;
}
result = _.commands.StartVoting(pair, arguments.parameters);
Log("Result:" @ result);
// Handle errors.
// `SVR_UnknownVoting` is impossible, since we've already checked that
// `pair.votingClass != none`)
if (result == SVR_AlreadyInProgress) {
callerConsole callerConsole
.UseColor(_.color.TextWarning) .UseColor(_.color.TextWarning)
.WriteLine(P("Another voting is already in progress!")); .WriteLine(P("Another voting is already in progress!"));
return; return false;
} }
// Inform new voting about fake voters, in case we're debugging if (result == SVR_NoVoters) {
if (currentVoting == none && _.environment.IsDebugging()) { callerConsole
fakersCommand = feature.GetCommand(P("fakers")); .UseColor(_.color.TextWarning)
if (fakersCommand != none && fakersCommand.class == class'ACommandFakers') { .WriteLine(P("There are no players eligible for that voting."));
ACommandFakers(fakersCommand).UpdateFakersForVoting(); return false;
}
_.memory.Free(fakersCommand);
} }
// Cast a vote from instigator // Cast a vote from instigator
newVoting = feature.GetCurrentVoting(); newVoting = _.commands.GetCurrentVoting();
if (newVoting != none) { if (newVoting != none) {
newVoting.CastVote(instigator, true); newVoting.CastVote(instigator, true);
} else { } else {
@ -151,9 +208,13 @@ private final function StartVoting(
.UseColor(_.color.TextFailure) .UseColor(_.color.TextFailure)
.WriteLine(P("Voting should be available, but it isn't." .WriteLine(P("Voting should be available, but it isn't."
@ "This is unexpected, something broke terribly.")); @ "This is unexpected, something broke terribly."));
_.memory.Free(newVoting);
return false;
} }
_.memory.Free(newVoting); _.memory.Free(newVoting);
return true;
} }
defaultproperties { defaultproperties {
preferredName = "vote"
} }
Loading…
Cancel
Save