diff --git a/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs new file mode 100644 index 000000000..3df215649 --- /dev/null +++ b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs @@ -0,0 +1,11 @@ +using System; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)] + public abstract class ParameterPreconditionAttribute : Attribute + { + public abstract Task CheckPermissions(CommandContext context, CommandParameter parameter, IDependencyMap map); + } +} diff --git a/src/Discord.Net.Commands/CommandInfo.cs b/src/Discord.Net.Commands/CommandInfo.cs index 47aae1ae2..fb9c48e72 100644 --- a/src/Discord.Net.Commands/CommandInfo.cs +++ b/src/Discord.Net.Commands/CommandInfo.cs @@ -104,6 +104,13 @@ namespace Discord.Commands return result; } + foreach (CommandParameter parameter in Parameters) + { + var result = await parameter.CheckPreconditions(context, map).ConfigureAwait(false); + if (!result.IsSuccess) + return result; + } + return PreconditionResult.FromSuccess(); } diff --git a/src/Discord.Net.Commands/CommandParameter.cs b/src/Discord.Net.Commands/CommandParameter.cs index 1edf42bf1..3a652cd5c 100644 --- a/src/Discord.Net.Commands/CommandParameter.cs +++ b/src/Discord.Net.Commands/CommandParameter.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.Reflection; using System.Threading.Tasks; @@ -18,6 +20,7 @@ namespace Discord.Commands public bool IsMultiple { get; } public Type ElementType { get; } public object DefaultValue { get; } + public IReadOnlyList Preconditions { get; } public CommandParameter(ParameterInfo source, string name, string summary, Type type, TypeReader reader, bool isOptional, bool isRemainder, bool isMultiple, object defaultValue) { @@ -30,6 +33,7 @@ namespace Discord.Commands IsRemainder = isRemainder; IsMultiple = isMultiple; DefaultValue = defaultValue; + Preconditions = BuildPreconditions(source); } public async Task Parse(CommandContext context, string input) @@ -37,6 +41,23 @@ namespace Discord.Commands return await _reader.Read(context, input).ConfigureAwait(false); } + public async Task CheckPreconditions(CommandContext context, IDependencyMap map = null) + { + foreach (ParameterPreconditionAttribute precondition in Preconditions) + { + var result = await precondition.CheckPermissions(context, this, map).ConfigureAwait(false); + if (!result.IsSuccess) + return result; + } + + return PreconditionResult.FromSuccess(); + } + + private IReadOnlyList BuildPreconditions(ParameterInfo paramInfo) + { + return paramInfo.GetCustomAttributes().ToImmutableArray(); + } + public override string ToString() => Name; private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}"; }