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