diff --git a/src/Discord.Net.Commands/Attributes/FilterAttribute.cs b/src/Discord.Net.Commands/Attributes/FilterAttribute.cs new file mode 100644 index 000000000..6e1cfff1c --- /dev/null +++ b/src/Discord.Net.Commands/Attributes/FilterAttribute.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + public abstract class FilterAttribute : Attribute + { + public abstract void OnCommandExecuting(CommandExecutionContext context); + } +} diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index 5729e4c81..cd17b6916 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -19,6 +19,7 @@ namespace Discord.Commands public string Text { get; } public Module Module { get; } public IReadOnlyList Parameters { get; } + public IReadOnlyList Filters { get; } internal Command(Module module, object instance, CommandAttribute attribute, MethodInfo methodInfo, string groupPrefix) { @@ -37,6 +38,7 @@ namespace Discord.Commands Synopsis = synopsis.Text; Parameters = BuildParameters(methodInfo); + Filters = BuildFilters(methodInfo); _action = BuildAction(methodInfo); } @@ -52,6 +54,14 @@ namespace Discord.Commands if (!parseResult.IsSuccess) return ExecuteResult.FromError(parseResult); + var context = new CommandExecutionContext(this, parseResult, msg); + foreach (FilterAttribute filter in Filters) + { + filter.OnCommandExecuting(context); + if (context.Handled) + return ExecuteResult.FromError(CommandError.InvalidPermissions, $"Permission check for {filter.GetType().FullName} failed"); + } + try { await _action.Invoke(msg, parseResult.Values);//Note: This code may need context @@ -63,6 +73,11 @@ namespace Discord.Commands } } + private IReadOnlyList BuildFilters(MethodInfo methodInfo) + { + return methodInfo.GetCustomAttributes().ToImmutableArray(); + } + private IReadOnlyList BuildParameters(MethodInfo methodInfo) { var parameters = methodInfo.GetParameters(); diff --git a/src/Discord.Net.Commands/CommandError.cs b/src/Discord.Net.Commands/CommandError.cs index 135930dd9..c90d4be50 100644 --- a/src/Discord.Net.Commands/CommandError.cs +++ b/src/Discord.Net.Commands/CommandError.cs @@ -16,5 +16,6 @@ //Execute Exception, + InvalidPermissions } } diff --git a/src/Discord.Net.Commands/Context/CommandExecutionContext.cs b/src/Discord.Net.Commands/Context/CommandExecutionContext.cs new file mode 100644 index 000000000..bec8291cc --- /dev/null +++ b/src/Discord.Net.Commands/Context/CommandExecutionContext.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + public class CommandExecutionContext + { + public Command ExecutingCommand { get; internal set; } + public ParseResult ParseResult { get; internal set; } + public IMessage Message { get; internal set; } + + public bool Handled { get; set; } + + internal CommandExecutionContext(Command command, ParseResult parseResult, IMessage message) + { + ExecutingCommand = command; + ParseResult = parseResult; + Message = message; + + Handled = false; + } + } +}