Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace SampSharp.Entities.SAMP.Commands;

/// <summary>
/// Specifies metadata for a command parameter, such as its display name and optional parser type.
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class CommandParameterAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="CommandParameterAttribute"/> class.
/// </summary>
public CommandParameterAttribute()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="CommandParameterAttribute"/> class with a name and optional parser type.
/// </summary>
/// <param name="name">The display name of the command parameter or <see langword="null"/> to use the default name.</param>
/// <param name="parserType">The type used to parse the parameter value, or <see langword="null"/> to use the default parser.</param>
public CommandParameterAttribute(string? name, Type? parserType = null)
{
Name = name;
ParserType = parserType;
}

/// <summary>
/// Gets or sets the display name of the command parameter.
/// </summary>
public string? Name { get; set; }

/// <summary>
/// Gets or sets the type used to parse the command parameter.
/// </summary>
public Type? ParserType { get; set; }
}
10 changes: 8 additions & 2 deletions src/SampSharp.OpenMp.Entities.Commands/Core/CommandScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,16 @@ private static bool TryCollectParameters(ParameterInfo[] parameters, int prefixP
{
var param = parameters[i];

var paramName = param.Name ?? $"param{i}";
var paramAtribute = param.GetCustomAttribute<CommandParameterAttribute>();

var paramName = paramAtribute?.Name ?? param.Name ?? $"param{i}";

// Try to get a parser for this parameter
var parser = parserFactory.CreateParser(parameters, i);
var parserInstance = paramAtribute?.ParserType is not null
? Activator.CreateInstance(paramAtribute.ParserType)
: null;

var parser = parserInstance as ICommandParameterParser ?? parserFactory.CreateParser(parameters, i);

if (parser == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ private class CommandWithSuffixSystem : ISystem
public void HelpCommand(Player player) { }
}

private class CommandWithCustomNameSystem : ISystem
{
[PlayerCommand]
public void MessageCommand(Player player, [CommandParameter("custom")]string text) { }
}

private class InvalidReturnTypeSystem : ISystem
{
// int is not a valid return type for player commands
Expand Down Expand Up @@ -259,6 +265,21 @@ public void ScanPlayerCommands_StripsSuffixFromMethodName()
FindByName(registry, "help").ShouldNotBeNull();
}

[Fact]
public void ScanPlayerCommands_ProvidesCustomName()
{
var registry = CreateCommandRegistry();
var scanner = CreateScanner(typeof(CommandWithCustomNameSystem));

scanner.ScanPlayerCommands(registry, CreateParserFactory());

FindByName(registry, "message")
.ShouldNotBeNull()
.ParsedParameters[0]
.Name
.ShouldBe("custom");
}

[Fact]
public void ScanPlayerCommands_ExtractsParsedParameters()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,26 @@ public void AddCommand(int a, int b)
{
Console.WriteLine($"{a} + {b} = {a + b}");
}
}

[ConsoleCommand(Name = "double_number")]
public void DoubleValueCommand([CommandParameter("value", typeof(DoubleIntParser))] int v)
{
Console.WriteLine(v);
}

private class DoubleIntParser : ICommandParameterParser
{
private readonly IntParser _inner = new();

public bool TryParse(IServiceProvider services, ref StringSpan inputText, out object? result)
{
if (_inner.TryParse(services, ref inputText, out result) && result is int num)
{
result = num * 2;
return true;
}

return false;
}
}
}
Loading