diff --git a/src/Discord.Net.Commands/Attributes/AliasAttribute.cs b/src/Discord.Net.Commands/Attributes/AliasAttribute.cs new file mode 100644 index 000000000..9aa1371f6 --- /dev/null +++ b/src/Discord.Net.Commands/Attributes/AliasAttribute.cs @@ -0,0 +1,18 @@ +using System; + +namespace Discord.Commands +{ + /// Provides aliases for a command. + [AttributeUsage(AttributeTargets.Method)] + public class AliasAttribute : Attribute + { + /// The aliases which have been defined for the command. + public string[] Aliases { get; } + + /// Creates a new with the given aliases. + public AliasAttribute(params string[] aliases) + { + Aliases = aliases; + } + } +} diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index 3e8d596dd..f7bbc7d35 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -25,6 +25,7 @@ namespace Discord.Commands public string Summary { get; } public string Text { get; } public bool HasVarArgs { get; } + public IReadOnlyList Aliases { get; } public IReadOnlyList Parameters { get; } public IReadOnlyList Preconditions { get; } @@ -37,6 +38,16 @@ namespace Discord.Commands Name = source.Name; Text = groupPrefix + attribute.Text; + var aliasesBuilder = ImmutableArray.CreateBuilder(); + + aliasesBuilder.Add(Text); + + var aliasesAttr = source.GetCustomAttribute(); + if (aliasesAttr != null) + aliasesBuilder.AddRange(aliasesAttr.Aliases.Select(x => groupPrefix + x)); + + Aliases = aliasesBuilder.ToImmutable(); + var nameAttr = source.GetCustomAttribute(); if (nameAttr != null) Name = nameAttr.Text; @@ -81,7 +92,19 @@ namespace Discord.Commands if (preconditionResult != null && !preconditionResult.Value.IsSuccess) 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 Execute(IMessage msg, ParseResult parseResult) { diff --git a/src/Discord.Net.Commands/Map/CommandMap.cs b/src/Discord.Net.Commands/Map/CommandMap.cs index 98ff297b0..f75a0f12f 100644 --- a/src/Discord.Net.Commands/Map/CommandMap.cs +++ b/src/Discord.Net.Commands/Map/CommandMap.cs @@ -17,40 +17,44 @@ namespace Discord.Commands public void AddCommand(Command command) { - string text = command.Text; - int nextSpace = NextWhitespace(text); - string name; + 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); + 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); + lock (this) + { + var nextNode = _nodes.GetOrAdd(name, x => new CommandMapNode(x)); + nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); + } } } public void RemoveCommand(Command command) { - string text = command.Text; - int nextSpace = NextWhitespace(text); - string name; + 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); + if (nextSpace == -1) + name = command.Text; + else + name = command.Text.Substring(0, nextSpace); - lock (this) - { - CommandMapNode nextNode; - if (_nodes.TryGetValue(name, out nextNode)) + lock (this) { - nextNode.AddCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); - if (nextNode.IsEmpty) - _nodes.TryRemove(name, out nextNode); + CommandMapNode nextNode; + if (_nodes.TryGetValue(name, out nextNode)) + { + nextNode.RemoveCommand(nextSpace == -1 ? "" : text, nextSpace + 1, command); + if (nextNode.IsEmpty) + _nodes.TryRemove(name, out nextNode); + } } } }