diff --git a/sources/LevelAPI/Features/Commands/CommandDataBuilder.uc b/sources/LevelAPI/Features/Commands/CommandDataBuilder.uc index 8232917..03fd804 100644 --- a/sources/LevelAPI/Features/Commands/CommandDataBuilder.uc +++ b/sources/LevelAPI/Features/Commands/CommandDataBuilder.uc @@ -637,6 +637,10 @@ public final function ParamNumberList(BaseText name, optional BaseText variableN /// parameter's value. `none` means that parameter will be recorded as-is, any other value /// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will /// make values prefixed with "$" to be resolved as custom aliases. +/// In case auto-resolving is used, value will be recorded as a `HasTable` with two fields: +/// "alias" - value provided by user and (in case "$" prefix was used) "value" - actual resolved +/// value of an alias. +/// If alias has failed to be resolved, `none` will be stored as a value. public final function ParamText( BaseText name, optional BaseText variableName, @@ -672,6 +676,10 @@ public final function ParamText( /// parameter's value. `none` means that parameter will be recorded as-is, any other value /// (either "weapon", "color", "feature", "entity" or some kind of custom alias source name) will /// make values prefixed with "$" to be resolved as custom aliases. +/// In case auto-resolving is used, value will be recorded as a `HasTable` with two fields: +/// "alias" - value provided by user and (in case "$" prefix was used) "value" - actual resolved +/// value of an alias. +/// If alias has failed to be resolved, `none` will be stored as a value. public final function ParamTextList( BaseText name, optional BaseText variableName, diff --git a/sources/LevelAPI/Features/Commands/CommandParser.uc b/sources/LevelAPI/Features/Commands/CommandParser.uc index 614fa06..afb1c70 100644 --- a/sources/LevelAPI/Features/Commands/CommandParser.uc +++ b/sources/LevelAPI/Features/Commands/CommandParser.uc @@ -616,9 +616,10 @@ private final function bool ParseTextValue( HashTable parsedParameters, Command.Parameter expectedParameter) { - local bool failedParsing; - local MutableText textValue; - local Parser.ParserState initialState; + local bool failedParsing; + local MutableText textValue; + local Parser.ParserState initialState; + local HashTable resolvedPair; // (needs some work for reading formatting `string`s from `Text` objects) initialState = commandParser.Skip().GetCurrentState(); @@ -639,24 +640,35 @@ private final function bool ParseTextValue( commandParser.Fail(); return false; } - AutoResolveAlias(textValue, expectedParameter.aliasSourceName); - RecordParameter(parsedParameters, expectedParameter, textValue.IntoText()); + resolvedPair = AutoResolveAlias(textValue, expectedParameter.aliasSourceName); + if (resolvedPair != none) { + RecordParameter(parsedParameters, expectedParameter, resolvedPair); + _.memory.Free(textValue); + } else { + RecordParameter(parsedParameters, expectedParameter, textValue.IntoText()); + } return true; } -// Resolves alias with appropriate source, if parameter was specified to be -// auto-resolved. -// Resolved values is returned through first out-parameter. -private final function AutoResolveAlias( - out MutableText textValue, - Text aliasSourceName) -{ - local Text resolvedValue; +// Resolves alias and returns it, along with the resolved value, if parameter was specified to be +// auto-resolved. +// Returns `none` otherwise. +private final function HashTable AutoResolveAlias(MutableText textValue, Text aliasSourceName) { + local HashTable result; + local Text resolvedValue, immutableValue; - if (textValue == none) return; - if (aliasSourceName == none) return; - if (!textValue.StartsWithS("$")) return; + if (textValue == none) return none; + if (aliasSourceName == none) return none; + // Always create `HashTable` with at least "alias" key + result = _.collections.EmptyHashTable(); + immutableValue = textValue.Copy(); + result.SetItem(P("alias"), immutableValue); + _.memory.Free(immutableValue); + // Add "value" key only after we've checked for "$" prefix + if (!textValue.StartsWithS("$")) { + return result; + } if (aliasSourceName.Compare(P("weapon"))) { resolvedValue = _.alias.ResolveWeapon(textValue, true); } @@ -672,8 +684,9 @@ private final function AutoResolveAlias( else { resolvedValue = _.alias.ResolveCustom(aliasSourceName, textValue, true); } - textValue.FreeSelf(); - textValue = resolvedValue.IntoMutableText(); + result.SetItem(P("value"), resolvedValue); + _.memory.Free2(resolvedValue, immutableValue); + return result; } // Assumes `commandParser` and `parsedParameters` are not `none`.