| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
993e26d2be | Added alias types | 8 years ago |
| @@ -3,15 +3,24 @@ using System; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| /// <summary> Provides aliases for a command. </summary> | /// <summary> Provides aliases for a command. </summary> | ||||
| [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] | |||||
| [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple=true)] | |||||
| public class AliasAttribute : Attribute | public class AliasAttribute : Attribute | ||||
| { | { | ||||
| /// <summary> The type to be applied to this alias group <summary> | |||||
| public AliasType Type { get; } | |||||
| /// <summary> The aliases which have been defined for the command. </summary> | /// <summary> The aliases which have been defined for the command. </summary> | ||||
| public string[] Aliases { get; } | public string[] Aliases { get; } | ||||
| /// <summary> Creates a new <see cref="AliasAttribute"/> with the given aliases. </summary> | /// <summary> Creates a new <see cref="AliasAttribute"/> with the given aliases. </summary> | ||||
| public AliasAttribute(params string[] aliases) | public AliasAttribute(params string[] aliases) | ||||
| { | { | ||||
| Type = AliasType.Relative; | |||||
| Aliases = aliases; | |||||
| } | |||||
| /// <summary> Creates a new <see cref="AliasAttribute"/> with the given aliases. </summary> | |||||
| public AliasAttribute(AliasType type, params string[] aliases) | |||||
| { | |||||
| Type = type; | |||||
| Aliases = aliases; | Aliases = aliases; | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,8 @@ | |||||
| namespace Discord.Commands | |||||
| { | |||||
| public enum AliasType | |||||
| { | |||||
| Relative, | |||||
| Absolute | |||||
| } | |||||
| } | |||||
| @@ -1,9 +1,9 @@ | |||||
| using System; | using System; | ||||
| namespace Discord.Commands { | |||||
| [AttributeUsage(AttributeTargets.Property)] | |||||
| public class DontInjectAttribute : Attribute { | |||||
| } | |||||
| namespace Discord.Commands | |||||
| { | |||||
| [AttributeUsage(AttributeTargets.Property)] | |||||
| public class DontInjectAttribute : Attribute | |||||
| { | |||||
| } | |||||
| } | } | ||||
| @@ -9,7 +9,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| private readonly List<ParameterBuilder> _parameters; | private readonly List<ParameterBuilder> _parameters; | ||||
| private readonly List<string> _aliases; | |||||
| private readonly List<string> _relativeAliases, _absoluteAliases; | |||||
| public ModuleBuilder Module { get; } | public ModuleBuilder Module { get; } | ||||
| internal Func<ICommandContext, object[], IDependencyMap, Task> Callback { get; set; } | internal Func<ICommandContext, object[], IDependencyMap, Task> Callback { get; set; } | ||||
| @@ -22,7 +22,8 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | ||||
| public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | ||||
| public IReadOnlyList<string> Aliases => _aliases; | |||||
| public IReadOnlyList<string> RelativeAliases => _relativeAliases; | |||||
| public IReadOnlyList<string> AbsoluteAliases => _absoluteAliases; | |||||
| //Automatic | //Automatic | ||||
| internal CommandBuilder(ModuleBuilder module) | internal CommandBuilder(ModuleBuilder module) | ||||
| @@ -31,7 +32,8 @@ namespace Discord.Commands.Builders | |||||
| _preconditions = new List<PreconditionAttribute>(); | _preconditions = new List<PreconditionAttribute>(); | ||||
| _parameters = new List<ParameterBuilder>(); | _parameters = new List<ParameterBuilder>(); | ||||
| _aliases = new List<string>(); | |||||
| _relativeAliases = new List<string>(); | |||||
| _absoluteAliases = new List<string>(); | |||||
| } | } | ||||
| //User-defined | //User-defined | ||||
| internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IDependencyMap, Task> callback) | internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IDependencyMap, Task> callback) | ||||
| @@ -41,7 +43,7 @@ namespace Discord.Commands.Builders | |||||
| Discord.Preconditions.NotNull(callback, nameof(callback)); | Discord.Preconditions.NotNull(callback, nameof(callback)); | ||||
| Callback = callback; | Callback = callback; | ||||
| _aliases.Add(primaryAlias); | |||||
| _relativeAliases.Add(primaryAlias); | |||||
| } | } | ||||
| public CommandBuilder WithName(string name) | public CommandBuilder WithName(string name) | ||||
| @@ -70,13 +72,22 @@ namespace Discord.Commands.Builders | |||||
| return this; | return this; | ||||
| } | } | ||||
| public CommandBuilder AddAliases(params string[] aliases) | |||||
| public CommandBuilder AddAliases(AliasType type, params string[] aliases) | |||||
| { | { | ||||
| for (int i = 0; i < aliases.Length; i++) | for (int i = 0; i < aliases.Length; i++) | ||||
| { | { | ||||
| var alias = aliases[i] ?? ""; | var alias = aliases[i] ?? ""; | ||||
| if (!_aliases.Contains(alias)) | |||||
| _aliases.Add(alias); | |||||
| switch (type) | |||||
| { | |||||
| case AliasType.Relative: | |||||
| if (!_relativeAliases.Contains(alias)) | |||||
| _relativeAliases.Add(alias); | |||||
| break; | |||||
| case AliasType.Absolute: | |||||
| if (!_absoluteAliases.Contains(alias)) | |||||
| _absoluteAliases.Add(alias); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| return this; | return this; | ||||
| } | } | ||||
| @@ -111,7 +122,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| //Default name to first alias | //Default name to first alias | ||||
| if (Name == null) | if (Name == null) | ||||
| Name = _aliases[0]; | |||||
| Name = _relativeAliases[0]; | |||||
| if (_parameters.Count > 0) | if (_parameters.Count > 0) | ||||
| { | { | ||||
| @@ -9,7 +9,7 @@ namespace Discord.Commands.Builders | |||||
| private readonly List<CommandBuilder> _commands; | private readonly List<CommandBuilder> _commands; | ||||
| private readonly List<ModuleBuilder> _submodules; | private readonly List<ModuleBuilder> _submodules; | ||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| private readonly List<string> _aliases; | |||||
| private readonly List<string> _relativeAliases, _absoluteAliases; | |||||
| public CommandService Service { get; } | public CommandService Service { get; } | ||||
| public ModuleBuilder Parent { get; } | public ModuleBuilder Parent { get; } | ||||
| @@ -20,7 +20,8 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<CommandBuilder> Commands => _commands; | public IReadOnlyList<CommandBuilder> Commands => _commands; | ||||
| public IReadOnlyList<ModuleBuilder> Modules => _submodules; | public IReadOnlyList<ModuleBuilder> Modules => _submodules; | ||||
| public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | ||||
| public IReadOnlyList<string> Aliases => _aliases; | |||||
| public IReadOnlyList<string> RelativeAliases => _relativeAliases; | |||||
| public IReadOnlyList<string> AbsoluteAliases => _absoluteAliases; | |||||
| //Automatic | //Automatic | ||||
| internal ModuleBuilder(CommandService service, ModuleBuilder parent) | internal ModuleBuilder(CommandService service, ModuleBuilder parent) | ||||
| @@ -31,7 +32,8 @@ namespace Discord.Commands.Builders | |||||
| _commands = new List<CommandBuilder>(); | _commands = new List<CommandBuilder>(); | ||||
| _submodules = new List<ModuleBuilder>(); | _submodules = new List<ModuleBuilder>(); | ||||
| _preconditions = new List<PreconditionAttribute>(); | _preconditions = new List<PreconditionAttribute>(); | ||||
| _aliases = new List<string>(); | |||||
| _relativeAliases = new List<string>(); | |||||
| _absoluteAliases = new List<string>(); | |||||
| } | } | ||||
| //User-defined | //User-defined | ||||
| internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) | internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) | ||||
| @@ -39,7 +41,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| Discord.Preconditions.NotNull(primaryAlias, nameof(primaryAlias)); | Discord.Preconditions.NotNull(primaryAlias, nameof(primaryAlias)); | ||||
| _aliases = new List<string> { primaryAlias }; | |||||
| _relativeAliases = new List<string> { primaryAlias }; | |||||
| } | } | ||||
| public ModuleBuilder WithName(string name) | public ModuleBuilder WithName(string name) | ||||
| @@ -58,13 +60,22 @@ namespace Discord.Commands.Builders | |||||
| return this; | return this; | ||||
| } | } | ||||
| public ModuleBuilder AddAliases(params string[] aliases) | |||||
| public ModuleBuilder AddAliases(AliasType type, params string[] aliases) | |||||
| { | { | ||||
| for (int i = 0; i < aliases.Length; i++) | for (int i = 0; i < aliases.Length; i++) | ||||
| { | { | ||||
| var alias = aliases[i] ?? ""; | var alias = aliases[i] ?? ""; | ||||
| if (!_aliases.Contains(alias)) | |||||
| _aliases.Add(alias); | |||||
| switch (type) | |||||
| { | |||||
| case AliasType.Relative: | |||||
| if (!_relativeAliases.Contains(alias)) | |||||
| _relativeAliases.Add(alias); | |||||
| break; | |||||
| case AliasType.Absolute: | |||||
| if (!_absoluteAliases.Contains(alias)) | |||||
| _absoluteAliases.Add(alias); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| return this; | return this; | ||||
| } | } | ||||
| @@ -106,7 +117,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| //Default name to first alias | //Default name to first alias | ||||
| if (Name == null) | if (Name == null) | ||||
| Name = _aliases[0]; | |||||
| Name = _relativeAliases[0]; | |||||
| return new ModuleInfo(this, service, parent); | return new ModuleInfo(this, service, parent); | ||||
| } | } | ||||
| @@ -89,20 +89,23 @@ namespace Discord.Commands | |||||
| else if (attribute is RemarksAttribute) | else if (attribute is RemarksAttribute) | ||||
| builder.Remarks = (attribute as RemarksAttribute).Text; | builder.Remarks = (attribute as RemarksAttribute).Text; | ||||
| else if (attribute is AliasAttribute) | else if (attribute is AliasAttribute) | ||||
| builder.AddAliases((attribute as AliasAttribute).Aliases); | |||||
| { | |||||
| var aliasAttr = attribute as AliasAttribute; | |||||
| builder.AddAliases(aliasAttr.Type, aliasAttr.Aliases); | |||||
| } | |||||
| else if (attribute is GroupAttribute) | else if (attribute is GroupAttribute) | ||||
| { | { | ||||
| var groupAttr = attribute as GroupAttribute; | var groupAttr = attribute as GroupAttribute; | ||||
| builder.Name = builder.Name ?? groupAttr.Prefix; | builder.Name = builder.Name ?? groupAttr.Prefix; | ||||
| builder.AddAliases(groupAttr.Prefix); | |||||
| builder.AddAliases(AliasType.Relative, groupAttr.Prefix); | |||||
| } | } | ||||
| else if (attribute is PreconditionAttribute) | else if (attribute is PreconditionAttribute) | ||||
| builder.AddPrecondition(attribute as PreconditionAttribute); | builder.AddPrecondition(attribute as PreconditionAttribute); | ||||
| } | } | ||||
| //Check for unspecified info | //Check for unspecified info | ||||
| if (builder.Aliases.Count == 0) | |||||
| builder.AddAliases(""); | |||||
| if (builder.RelativeAliases.Count == 0) | |||||
| builder.AddAliases(AliasType.Relative, ""); | |||||
| if (builder.Name == null) | if (builder.Name == null) | ||||
| builder.Name = typeInfo.Name; | builder.Name = typeInfo.Name; | ||||
| @@ -127,7 +130,7 @@ namespace Discord.Commands | |||||
| if (attribute is CommandAttribute) | if (attribute is CommandAttribute) | ||||
| { | { | ||||
| var cmdAttr = attribute as CommandAttribute; | var cmdAttr = attribute as CommandAttribute; | ||||
| builder.AddAliases(cmdAttr.Text); | |||||
| builder.AddAliases(AliasType.Relative, cmdAttr.Text); | |||||
| builder.RunMode = cmdAttr.RunMode; | builder.RunMode = cmdAttr.RunMode; | ||||
| builder.Name = builder.Name ?? cmdAttr.Text; | builder.Name = builder.Name ?? cmdAttr.Text; | ||||
| } | } | ||||
| @@ -140,7 +143,10 @@ namespace Discord.Commands | |||||
| else if (attribute is RemarksAttribute) | else if (attribute is RemarksAttribute) | ||||
| builder.Remarks = (attribute as RemarksAttribute).Text; | builder.Remarks = (attribute as RemarksAttribute).Text; | ||||
| else if (attribute is AliasAttribute) | else if (attribute is AliasAttribute) | ||||
| builder.AddAliases((attribute as AliasAttribute).Aliases); | |||||
| { | |||||
| var aliasAttr = attribute as AliasAttribute; | |||||
| builder.AddAliases(aliasAttr.Type, aliasAttr.Aliases); | |||||
| } | |||||
| else if (attribute is PreconditionAttribute) | else if (attribute is PreconditionAttribute) | ||||
| builder.AddPrecondition(attribute as PreconditionAttribute); | builder.AddPrecondition(attribute as PreconditionAttribute); | ||||
| } | } | ||||
| @@ -43,7 +43,7 @@ namespace Discord.Commands | |||||
| Priority = builder.Priority; | Priority = builder.Priority; | ||||
| Aliases = module.Aliases | Aliases = module.Aliases | ||||
| .Permutate(builder.Aliases, (first, second) => | |||||
| .Permutate(builder.RelativeAliases, (first, second) => | |||||
| { | { | ||||
| if (first == "") | if (first == "") | ||||
| return second; | return second; | ||||
| @@ -52,6 +52,7 @@ namespace Discord.Commands | |||||
| else | else | ||||
| return first + service._separatorChar + second; | return first + service._separatorChar + second; | ||||
| }) | }) | ||||
| .Concat(builder.AbsoluteAliases) | |||||
| .Select(x => service._caseSensitive ? x : x.ToLowerInvariant()) | .Select(x => service._caseSensitive ? x : x.ToLowerInvariant()) | ||||
| .ToImmutableArray(); | .ToImmutableArray(); | ||||
| @@ -38,28 +38,33 @@ namespace Discord.Commands | |||||
| private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | private static IEnumerable<string> BuildAliases(ModuleBuilder builder, CommandService service) | ||||
| { | { | ||||
| var result = builder.Aliases.ToList(); | |||||
| var builderQueue = new Queue<ModuleBuilder>(); | |||||
| var result = builder.RelativeAliases.ToList(); | |||||
| var builderQueue = new Stack<ModuleBuilder>(); | |||||
| var parent = builder; | var parent = builder; | ||||
| while ((parent = parent.Parent) != null) | while ((parent = parent.Parent) != null) | ||||
| builderQueue.Enqueue(parent); | |||||
| builderQueue.Push(parent); | |||||
| while (builderQueue.Count > 0) | while (builderQueue.Count > 0) | ||||
| { | { | ||||
| var level = builderQueue.Dequeue(); | |||||
| var level = builderQueue.Pop(); | |||||
| // permute in reverse because we want to *prefix* our aliases | // permute in reverse because we want to *prefix* our aliases | ||||
| result = level.Aliases.Permutate(result, (first, second) => | |||||
| { | |||||
| if (first == "") | |||||
| return second; | |||||
| else if (second == "") | |||||
| return first; | |||||
| else | |||||
| return first + service._separatorChar + second; | |||||
| }).ToList(); | |||||
| result = result | |||||
| .Permutate(level.RelativeAliases, (first, second) => | |||||
| { | |||||
| if (first == "") | |||||
| return second; | |||||
| else if (second == "") | |||||
| return first; | |||||
| else | |||||
| return first + service._separatorChar + second; | |||||
| }) | |||||
| .Concat(level.AbsoluteAliases) | |||||
| .ToList(); | |||||
| } | } | ||||
| result = result.Concat(builder.AbsoluteAliases).ToList(); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -13,7 +13,6 @@ namespace Discord.WebSocket | |||||
| public override ushort DiscriminatorValue { get; internal set; } | public override ushort DiscriminatorValue { get; internal set; } | ||||
| public override string AvatarId { get; internal set; } | public override string AvatarId { get; internal set; } | ||||
| internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null); } set { } } | internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null); } set { } } | ||||
| internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } } | internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } } | ||||
| internal SocketSimpleUser(DiscordSocketClient discord, ulong id) | internal SocketSimpleUser(DiscordSocketClient discord, ulong id) | ||||