From adec246b7d968a5cf5231d54cec22d7ba36e14cf Mon Sep 17 00:00:00 2001 From: "Sindre G. Langhus" Date: Thu, 25 May 2017 02:09:26 +0200 Subject: [PATCH] Adds PreconditionsMode to CommandAttribute --- .../Attributes/CommandAttribute.cs | 1 + .../Builders/CommandBuilder.cs | 6 ++ .../Builders/ModuleClassBuilder.cs | 80 +++++++++++-------- src/Discord.Net.Commands/CommandService.cs | 4 + .../CommandServiceConfig.cs | 3 + src/Discord.Net.Commands/Info/CommandInfo.cs | 22 ++++- src/Discord.Net.Commands/PreconditionsMode.cs | 9 +++ 7 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 src/Discord.Net.Commands/PreconditionsMode.cs diff --git a/src/Discord.Net.Commands/Attributes/CommandAttribute.cs b/src/Discord.Net.Commands/Attributes/CommandAttribute.cs index 5ae6092eb..7869e5e78 100644 --- a/src/Discord.Net.Commands/Attributes/CommandAttribute.cs +++ b/src/Discord.Net.Commands/Attributes/CommandAttribute.cs @@ -7,6 +7,7 @@ namespace Discord.Commands { public string Text { get; } public RunMode RunMode { get; set; } = RunMode.Default; + public PreconditionsMode PreconditionsMode { get; set; } = PreconditionsMode.Default; public CommandAttribute() { diff --git a/src/Discord.Net.Commands/Builders/CommandBuilder.cs b/src/Discord.Net.Commands/Builders/CommandBuilder.cs index ff89b7559..682073f6e 100644 --- a/src/Discord.Net.Commands/Builders/CommandBuilder.cs +++ b/src/Discord.Net.Commands/Builders/CommandBuilder.cs @@ -20,6 +20,7 @@ namespace Discord.Commands.Builders public string Remarks { get; set; } public string PrimaryAlias { get; set; } public RunMode RunMode { get; set; } + public PreconditionsMode PreconditionsMode { get; set; } public int Priority { get; set; } public IReadOnlyList Preconditions => _preconditions; @@ -67,6 +68,11 @@ namespace Discord.Commands.Builders RunMode = runMode; return this; } + public CommandBuilder WithPreconditionsMode(PreconditionsMode preconditionsMode) + { + PreconditionsMode = preconditionsMode; + return this; + } public CommandBuilder WithPriority(int priority) { Priority = priority; diff --git a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs index d8464ea72..cf1c4bab0 100644 --- a/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Commands/Builders/ModuleClassBuilder.cs @@ -128,26 +128,33 @@ namespace Discord.Commands foreach (var attribute in attributes) { - // TODO: C#7 type switch - if (attribute is CommandAttribute) + switch (attribute) { - var cmdAttr = attribute as CommandAttribute; - builder.AddAliases(cmdAttr.Text); - builder.RunMode = cmdAttr.RunMode; - builder.Name = builder.Name ?? cmdAttr.Text; + case CommandAttribute cmdAttr: + builder.AddAliases(cmdAttr.Text); + builder.RunMode = cmdAttr.RunMode; + builder.PreconditionsMode = cmdAttr.PreconditionsMode; + builder.Name = builder.Name ?? cmdAttr.Text; + break; + case NameAttribute nameAttr: + builder.Name = nameAttr.Text; + break; + case PriorityAttribute priorityAttr: + builder.Priority = priorityAttr.Priority; + break; + case SummaryAttribute summaryAttr: + builder.Summary = summaryAttr.Text; + break; + case RemarksAttribute remarksAttr: + builder.Remarks = remarksAttr.Text; + break; + case AliasAttribute aliasAttr: + builder.AddAliases(aliasAttr.Aliases); + break; + case PreconditionAttribute preconditionAttr: + builder.AddPrecondition(preconditionAttr); + break; } - else if (attribute is NameAttribute) - builder.Name = (attribute as NameAttribute).Text; - else if (attribute is PriorityAttribute) - builder.Priority = (attribute as PriorityAttribute).Priority; - else if (attribute is SummaryAttribute) - builder.Summary = (attribute as SummaryAttribute).Text; - else if (attribute is RemarksAttribute) - builder.Remarks = (attribute as RemarksAttribute).Text; - else if (attribute is AliasAttribute) - builder.AddAliases((attribute as AliasAttribute).Aliases); - else if (attribute is PreconditionAttribute) - builder.AddPrecondition(attribute as PreconditionAttribute); } if (builder.Name == null) @@ -195,24 +202,27 @@ namespace Discord.Commands foreach (var attribute in attributes) { - // TODO: C#7 type switch - if (attribute is SummaryAttribute) - builder.Summary = (attribute as SummaryAttribute).Text; - else if (attribute is OverrideTypeReaderAttribute) - builder.TypeReader = GetTypeReader(service, paramType, (attribute as OverrideTypeReaderAttribute).TypeReader); - else if (attribute is ParameterPreconditionAttribute) - builder.AddPrecondition(attribute as ParameterPreconditionAttribute); - else if (attribute is ParamArrayAttribute) - { - builder.IsMultiple = true; - paramType = paramType.GetElementType(); - } - else if (attribute is RemainderAttribute) + switch (attribute) { - if (position != count-1) - throw new InvalidOperationException("Remainder parameters must be the last parameter in a command."); - - builder.IsRemainder = true; + case SummaryAttribute summaryAttr: + builder.Summary = summaryAttr.Text; + break; + case OverrideTypeReaderAttribute overrideTypeReaderAttr: + builder.TypeReader = GetTypeReader(service, paramType, + overrideTypeReaderAttr.TypeReader); + break; + case ParameterPreconditionAttribute parameterPreconditionAttr: + builder.AddPrecondition(parameterPreconditionAttr); + break; + case ParamArrayAttribute paramArrayAttr: + builder.IsMultiple = true; + paramType = paramType.GetElementType(); + break; + case RemainderAttribute remainderAttr: + if (position != count - 1) + throw new InvalidOperationException("Remainder parameters must be the last parameter in a command."); + builder.IsRemainder = true; + break; } } diff --git a/src/Discord.Net.Commands/CommandService.cs b/src/Discord.Net.Commands/CommandService.cs index f526e8f3b..2081402b9 100644 --- a/src/Discord.Net.Commands/CommandService.cs +++ b/src/Discord.Net.Commands/CommandService.cs @@ -28,6 +28,7 @@ namespace Discord.Commands internal readonly bool _caseSensitive, _throwOnError; internal readonly char _separatorChar; internal readonly RunMode _defaultRunMode; + internal readonly PreconditionsMode _defaultPreconditionsMode; internal readonly Logger _cmdLogger; internal readonly LogManager _logManager; @@ -44,6 +45,9 @@ namespace Discord.Commands _defaultRunMode = config.DefaultRunMode; if (_defaultRunMode == RunMode.Default) throw new InvalidOperationException("The default run mode cannot be set to Default."); + _defaultPreconditionsMode = config.DefaultPreconditionsMode; + if (_defaultPreconditionsMode == PreconditionsMode.Default) + throw new InvalidOperationException("The default preconditions mode cannot be set to Default."); _logManager = new LogManager(config.LogLevel); _logManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false); diff --git a/src/Discord.Net.Commands/CommandServiceConfig.cs b/src/Discord.Net.Commands/CommandServiceConfig.cs index 5dcd50cd8..82ae0f999 100644 --- a/src/Discord.Net.Commands/CommandServiceConfig.cs +++ b/src/Discord.Net.Commands/CommandServiceConfig.cs @@ -5,6 +5,9 @@ /// The default RunMode commands should have, if one is not specified on the Command attribute or builder. public RunMode DefaultRunMode { get; set; } = RunMode.Sync; + /// The default PreconditionsMode commands should have, if one is not specified on the Command attribute or builder. + public PreconditionsMode DefaultPreconditionsMode { get; set; } = PreconditionsMode.RequireAll; + public char SeparatorChar { get; set; } = ' '; /// Should commands be case-sensitive? public bool CaseSensitiveCommands { get; set; } = false; diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index 5acd1f648..7d70298f0 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -27,6 +27,7 @@ namespace Discord.Commands public int Priority { get; } public bool HasVarArgs { get; } public RunMode RunMode { get; } + public PreconditionsMode PreconditionsMode { get; } public IReadOnlyList Aliases { get; } public IReadOnlyList Parameters { get; } @@ -41,6 +42,7 @@ namespace Discord.Commands Remarks = builder.Remarks; RunMode = (builder.RunMode == RunMode.Default ? service._defaultRunMode : builder.RunMode); + PreconditionsMode = (builder.PreconditionsMode == PreconditionsMode.Default ? service._defaultPreconditionsMode : builder.PreconditionsMode); Priority = builder.Priority; Aliases = module.Aliases @@ -75,11 +77,23 @@ namespace Discord.Commands return result; } - foreach (PreconditionAttribute precondition in Preconditions) + if (PreconditionsMode == PreconditionsMode.RequireAll) { - var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); - if (!result.IsSuccess) - return result; + foreach (PreconditionAttribute precondition in Preconditions) + { + var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); + if (!result.IsSuccess) + return result; + } + } + else + { + foreach (PreconditionAttribute precondition in Preconditions) + { + var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); + if (result.IsSuccess) + return result; + } } return PreconditionResult.FromSuccess(); diff --git a/src/Discord.Net.Commands/PreconditionsMode.cs b/src/Discord.Net.Commands/PreconditionsMode.cs new file mode 100644 index 000000000..4888123aa --- /dev/null +++ b/src/Discord.Net.Commands/PreconditionsMode.cs @@ -0,0 +1,9 @@ +namespace Discord.Commands +{ + public enum PreconditionsMode + { + Default, + RequireAny, + RequireAll + } +} \ No newline at end of file