Implement Command Aliasestags/1.0-rc
| @@ -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,40 +17,44 @@ namespace Discord.Commands | |||||
| public void AddCommand(Command command) | 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) | 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); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||