diff --git a/src/Discord.Net.Commands/Attributes/FilterAttribute.cs b/src/Discord.Net.Commands/Attributes/PermissionAttribute.cs similarity index 51% rename from src/Discord.Net.Commands/Attributes/FilterAttribute.cs rename to src/Discord.Net.Commands/Attributes/PermissionAttribute.cs index a3a31dfbd..70825aec1 100644 --- a/src/Discord.Net.Commands/Attributes/FilterAttribute.cs +++ b/src/Discord.Net.Commands/Attributes/PermissionAttribute.cs @@ -5,8 +5,8 @@ using System.Threading.Tasks; namespace Discord.Commands { - public abstract class FilterAttribute : Attribute + public abstract class PermissionAttribute : Attribute { - public abstract void OnCommandExecuting(CommandExecutionContext context); + public abstract void CheckPermissions(PermissionsContext context); } } diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index 44be5de04..897106ac3 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -19,7 +19,7 @@ namespace Discord.Commands public string Text { get; } public Module Module { get; } public IReadOnlyList Parameters { get; } - public IReadOnlyList Filters { get; } + public IReadOnlyList Permissions { get; } internal Command(Module module, object instance, CommandAttribute attribute, MethodInfo methodInfo, string groupPrefix) { @@ -38,10 +38,24 @@ namespace Discord.Commands Synopsis = synopsis.Text; Parameters = BuildParameters(methodInfo); - Filters = BuildFilters(methodInfo); + Permissions = BuildPermissions(methodInfo); _action = BuildAction(methodInfo); } + public bool CanExecute(IMessage message) + { + var context = new PermissionsContext(this, message); + + foreach (PermissionAttribute permission in Permissions) + { + permission.CheckPermissions(context); + if (context.Handled) + return false; + } + + return true; + } + public async Task Parse(IMessage msg, SearchResult searchResult) { if (!searchResult.IsSuccess) @@ -54,13 +68,8 @@ 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"); - } + if (!CanExecute(msg)) // TODO: should we have to check this here, or leave it entirely to the bot dev? + return ExecuteResult.FromError(CommandError.InvalidPermissions, "Permissions check failed"); try { @@ -73,9 +82,9 @@ namespace Discord.Commands } } - private IReadOnlyList BuildFilters(MethodInfo methodInfo) + private IReadOnlyList BuildPermissions(MethodInfo methodInfo) { - return methodInfo.GetCustomAttributes().ToImmutableArray(); + return methodInfo.GetCustomAttributes().ToImmutableArray(); } private IReadOnlyList BuildParameters(MethodInfo methodInfo) diff --git a/src/Discord.Net.Commands/Context/CommandExecutionContext.cs b/src/Discord.Net.Commands/Context/PermissionsContext.cs similarity index 63% rename from src/Discord.Net.Commands/Context/CommandExecutionContext.cs rename to src/Discord.Net.Commands/Context/PermissionsContext.cs index 0eaac9fa7..8c9b79e22 100644 --- a/src/Discord.Net.Commands/Context/CommandExecutionContext.cs +++ b/src/Discord.Net.Commands/Context/PermissionsContext.cs @@ -5,18 +5,16 @@ using System.Threading.Tasks; namespace Discord.Commands { - public class CommandExecutionContext + public class PermissionsContext { 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) + internal PermissionsContext(Command command, IMessage message) { ExecutingCommand = command; - ParseResult = parseResult; Message = message; Handled = false;