Describe chat commands in a machine readable way
Some checks failed
.NET Core / build (push) Has been cancelled
Some checks failed
.NET Core / build (push) Has been cancelled
The only description of a chat command was its usage string, which is meant to be read by a human. A user interface which wants to offer the commands to a player needs the parts separately: the command, what it does, and one entry per parameter. Add ChatCommandInfo and ChatCommandParameterInfo, built from the metadata which is already there - ChatCommandHelpAttribute for the command and its required character status, ArgumentAttribute for the short names and whether a parameter is required, ValidValuesAttribute for the accepted values. Name and description come from the display attribute, so they are returned in the language of the player. The description which is passed to ChatCommandHelpAttribute was never stored anywhere. Keep it as a fallback for commands which have no display attribute, instead of discarding it. The reset info command had its texts hard coded in English. It now refers to resources like every other chat command does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSpK6jkyF8ZS5nYXyGwYxA
This commit is contained in:
@@ -113,27 +113,46 @@ public static class CommandExtensions
|
||||
/// <param name="argumentsType">Type of the arguments.</param>
|
||||
/// <returns>A list of parameters with name, type, and valid values.</returns>
|
||||
public static IEnumerable<(string Name, string Type, string ValidValues)> GetParameters(Type argumentsType)
|
||||
{
|
||||
return GetParameterInfos(argumentsType)
|
||||
.Select(parameter => (Name: parameter.Name, Type: parameter.TypeName, ValidValues: string.Join('|', parameter.ValidValues)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the parameters of an argument class.
|
||||
/// </summary>
|
||||
/// <param name="argumentsType">Type of the arguments.</param>
|
||||
/// <returns>The described parameters, in the order in which they are expected when they are passed without their short names.</returns>
|
||||
public static IEnumerable<ChatCommandParameterInfo> GetParameterInfos(Type argumentsType)
|
||||
{
|
||||
var properties = argumentsType.GetProperties().Where(p => p.CanWrite);
|
||||
foreach (var property in properties)
|
||||
{
|
||||
string validValues = string.Empty;
|
||||
IReadOnlyList<string> validValues = [];
|
||||
|
||||
if (property.GetCustomAttribute<ValidValuesAttribute>() is { } validValuesAttribute)
|
||||
{
|
||||
validValues = string.Join('|', validValuesAttribute.ValidValues);
|
||||
validValues = validValuesAttribute.ValidValues.ToList();
|
||||
}
|
||||
else if (property.PropertyType == typeof(bool))
|
||||
{
|
||||
validValues = "0|1";
|
||||
validValues = ["0", "1"];
|
||||
}
|
||||
else if (property.PropertyType == typeof(byte) || property.PropertyType == typeof(ushort) || property.PropertyType == typeof(uint))
|
||||
{
|
||||
// todo: ranges in ParameterAttribute
|
||||
// validValues = "";
|
||||
}
|
||||
|
||||
yield return (property.Name, property.PropertyType.Name, validValues);
|
||||
// A parameter without an ArgumentAttribute can't be required - the parser
|
||||
// only counts the required arguments of the attributed properties.
|
||||
var argumentAttribute = property.GetCustomAttribute<ArgumentAttribute>(inherit: true);
|
||||
|
||||
yield return new ChatCommandParameterInfo(
|
||||
property.Name,
|
||||
argumentAttribute?.ShortName,
|
||||
property.PropertyType.Name,
|
||||
argumentAttribute?.IsRequired ?? false,
|
||||
validValues);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user