Browse Source

Add parsing support for players command arguments

pull/8/head
Anton Tarasenko 2 years ago
parent
commit
0ee809194a
  1. 2
      sources/Commands/Command.uc
  2. 46
      sources/Commands/CommandParser.uc

2
sources/Commands/Command.uc

@ -348,7 +348,7 @@ public final function CallData ParseInputWith(
} }
// Parse parameters themselves // Parse parameters themselves
commandParser = CommandParser(_.memory.Allocate(class'CommandParser')); commandParser = CommandParser(_.memory.Allocate(class'CommandParser'));
callData = commandParser.ParseWith(parser, commandData); callData = commandParser.ParseWith(parser, commandData, callerPlayer);
callData.targetPlayers = targetPlayers; callData.targetPlayers = targetPlayers;
commandParser.FreeSelf(); commandParser.FreeSelf();
return callData; return callData;

46
sources/Commands/CommandParser.uc

@ -102,6 +102,8 @@ enum ParsingTarget
CPT_ExtraParameter, CPT_ExtraParameter,
}; };
// Parser for player parameters, setup with a caller for current parsing
var private PlayersParser currentPlayersParser;
// Current `ParsingTarget`, see it's enum description for more details // Current `ParsingTarget`, see it's enum description for more details
var private ParsingTarget currentTarget; var private ParsingTarget currentTarget;
// `true` means we are parsing parameters for a command's option and // `true` means we are parsing parameters for a command's option and
@ -131,6 +133,10 @@ protected function Finalizer()
private final function Reset() private final function Reset()
{ {
local Command.CallData blankCallData; local Command.CallData blankCallData;
_.memory.Free(currentPlayersParser);
currentPlayersParser = none;
// We didn't create this one and are not meant to free it either
commandParser = none; commandParser = none;
nextResult = blankCallData; nextResult = blankCallData;
currentTarget = CPT_NecessaryParameter; currentTarget = CPT_NecessaryParameter;
@ -197,18 +203,20 @@ private final function PickSubCommand(Command.Data commandData)
* Parses user's input given in `parser` using command's information given by * Parses user's input given in `parser` using command's information given by
* `commandData`. * `commandData`.
* *
* @param parser `Parser`, initialized with user's input that will need * @param parser `Parser`, initialized with user's input that will
* to be parsed as a command's call. * need to be parsed as a command's call.
* @param commandData Describes what parameters and options should be * @param commandData Describes what parameters and options should be
* expected in user's input. `Text` values from `commandData` can be used * expected in user's input. `Text` values from `commandData` can be used
* inside resulting `Command.CallData`, so deallocating them can * inside resulting `Command.CallData`, so deallocating them can
* invalidate returned value. * invalidate returned value.
* @param callerPlayer Player that called this command, if applicable.
* @return Results of parsing, described by `Command.CallData`. * @return Results of parsing, described by `Command.CallData`.
* Returned object is guaranteed to be not `none`. * Returned object is guaranteed to be not `none`.
*/ */
public final function Command.CallData ParseWith( public final function Command.CallData ParseWith(
Parser parser, Parser parser,
Command.Data commandData) Command.Data commandData,
optional EPlayer callerPlayer)
{ {
local HashTable commandParameters; local HashTable commandParameters;
// Temporary object to return `nextResult` while setting variable to `none` // Temporary object to return `nextResult` while setting variable to `none`
@ -231,6 +239,9 @@ public final function Command.CallData ParseWith(
} }
commandParser = parser; commandParser = parser;
availableOptions = commandData.options; availableOptions = commandData.options;
currentPlayersParser =
PlayersParser(_.memory.Allocate(class'PlayersParser'));
currentPlayersParser.SetSelf(callerPlayer);
// (subcommand) (parameters, possibly with options) and nothing else! // (subcommand) (parameters, possibly with options) and nothing else!
PickSubCommand(commandData); PickSubCommand(commandData);
nextResult.subCommandName = pickedSubCommand.name.Copy(); nextResult.subCommandName = pickedSubCommand.name.Copy();
@ -452,6 +463,9 @@ private final function bool ParseSingleValue(
else if (expectedParameter.type == CPT_JSON) { else if (expectedParameter.type == CPT_JSON) {
return ParseJSONValue(parsedParameters, expectedParameter); return ParseJSONValue(parsedParameters, expectedParameter);
} }
else if (expectedParameter.type == CPT_Players) {
return ParsePlayersValue(parsedParameters, expectedParameter);
}
return false; return false;
} }
@ -636,6 +650,28 @@ private final function bool ParseJSONValue(
return true; return true;
} }
// Assumes `commandParser` and `parsedParameters` are not `none`.
// Parses a single JSON value into given `parsedParameters`
// hash table.
private final function bool ParsePlayersValue(
HashTable parsedParameters,
Command.Parameter expectedParameter)
{
local ArrayList resultPlayerList;
local array<EPlayer> targetPlayers;
currentPlayersParser.ParseWith(commandParser);
if (commandParser.Ok()) {
targetPlayers = currentPlayersParser.GetPlayers();
}
else {
return false;
}
resultPlayerList = _.collections.NewArrayList(targetPlayers);
_.memory.FreeMany(targetPlayers);
RecordParameter(parsedParameters, expectedParameter, resultPlayerList);
return true;
}
// Assumes `parsedParameters` is not `none`. // Assumes `parsedParameters` is not `none`.
// Records `value` for a given `parameter` into a given `parametersArray`. // Records `value` for a given `parameter` into a given `parametersArray`.
// If parameter is not a list type - simply records `value` as value under // If parameter is not a list type - simply records `value` as value under

Loading…
Cancel
Save