Implement Command Aliases
This implementation could probably be more efficient, but I opted for clarity and simplicity where possible.
This commit is contained in:
18
src/Discord.Net.Commands/Attributes/AliasAttribute.cs
Normal file
18
src/Discord.Net.Commands/Attributes/AliasAttribute.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Discord.Commands
|
||||||
|
{
|
||||||
|
/// <summary> Provides aliases for a command. </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class AliasAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary> The aliases which have been defined for the command. </summary>
|
||||||
|
public string[] Aliases { get; }
|
||||||
|
|
||||||
|
/// <summary> Creates a new <see cref="AliasAttribute"/> with the given aliases. </summary>
|
||||||
|
public AliasAttribute(params string[] aliases)
|
||||||
|
{
|
||||||
|
Aliases = aliases;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ namespace Discord.Commands
|
|||||||
public string Summary { get; }
|
public string Summary { get; }
|
||||||
public string Text { get; }
|
public string Text { get; }
|
||||||
public bool HasVarArgs { get; }
|
public bool HasVarArgs { get; }
|
||||||
|
public IReadOnlyList<string> Aliases { get; }
|
||||||
public IReadOnlyList<CommandParameter> Parameters { get; }
|
public IReadOnlyList<CommandParameter> Parameters { get; }
|
||||||
public IReadOnlyList<PreconditionAttribute> Preconditions { get; }
|
public IReadOnlyList<PreconditionAttribute> Preconditions { get; }
|
||||||
|
|
||||||
@@ -37,6 +38,16 @@ namespace Discord.Commands
|
|||||||
Name = source.Name;
|
Name = source.Name;
|
||||||
Text = groupPrefix + attribute.Text;
|
Text = groupPrefix + attribute.Text;
|
||||||
|
|
||||||
|
var aliasesBuilder = ImmutableArray.CreateBuilder<string>();
|
||||||
|
|
||||||
|
aliasesBuilder.Add(Text);
|
||||||
|
|
||||||
|
var aliasesAttr = source.GetCustomAttribute<AliasAttribute>();
|
||||||
|
if (aliasesAttr != null)
|
||||||
|
aliasesBuilder.AddRange(aliasesAttr.Aliases.Select(x => groupPrefix + x));
|
||||||
|
|
||||||
|
Aliases = aliasesBuilder.ToImmutable();
|
||||||
|
|
||||||
var nameAttr = source.GetCustomAttribute<NameAttribute>();
|
var nameAttr = source.GetCustomAttribute<NameAttribute>();
|
||||||
if (nameAttr != null)
|
if (nameAttr != null)
|
||||||
Name = nameAttr.Text;
|
Name = nameAttr.Text;
|
||||||
@@ -81,7 +92,19 @@ namespace Discord.Commands
|
|||||||
if (preconditionResult != null && !preconditionResult.Value.IsSuccess)
|
if (preconditionResult != null && !preconditionResult.Value.IsSuccess)
|
||||||
return ParseResult.FromError(preconditionResult.Value);
|
return ParseResult.FromError(preconditionResult.Value);
|
||||||
|
|
||||||
return await CommandParser.ParseArgs(this, msg, searchResult.Text.Substring(Text.Length), 0).ConfigureAwait(false);
|
string input = searchResult.Text;
|
||||||
|
var matchingAliases = Aliases.Where(alias => input.StartsWith(alias));
|
||||||
|
|
||||||
|
string matchingAlias = "";
|
||||||
|
foreach (string alias in matchingAliases)
|
||||||
|
{
|
||||||
|
if (alias.Length > matchingAlias.Length)
|
||||||
|
matchingAlias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
input = input.Substring(matchingAlias.Length);
|
||||||
|
|
||||||
|
return await CommandParser.ParseArgs(this, msg, input, 0).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
public Task<ExecuteResult> Execute(IMessage msg, ParseResult parseResult)
|
public Task<ExecuteResult> Execute(IMessage msg, ParseResult parseResult)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,19 +17,21 @@ namespace Discord.Commands
|
|||||||
|
|
||||||
public void AddCommand(Command command)
|
public void AddCommand(Command command)
|
||||||
{
|
{
|
||||||
string text = command.Text;
|
foreach (string text in command.Aliases)
|
||||||
int nextSpace = NextWhitespace(text);
|
|
||||||
string name;
|
|
||||||
|
|
||||||
if (nextSpace == -1)
|
|
||||||
name = command.Text;
|
|
||||||
else
|
|
||||||
name = command.Text.Substring(0, nextSpace);
|
|
||||||
|
|
||||||
lock (this)
|
|
||||||
{
|
{
|
||||||
var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x));
|
int nextSpace = NextWhitespace(text);
|
||||||
nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command);
|
string name;
|
||||||
|
|
||||||
|
if (nextSpace == -1)
|
||||||
|
name = command.Text;
|
||||||
|
else
|
||||||
|
name = command.Text.Substring(0, nextSpace);
|
||||||
|
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x));
|
||||||
|
nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void RemoveCommand(Command command)
|
public void RemoveCommand(Command command)
|
||||||
|
|||||||
Reference in New Issue
Block a user