| @@ -0,0 +1,11 @@ | |||||
| using System; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.Commands | |||||
| { | |||||
| [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] | |||||
| public abstract class PostActionAttribute : Attribute | |||||
| { | |||||
| public abstract Task ExecuteAsync(ICommandContext context, CommandInfo command, IResult result, IServiceProvider services); | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Linq; | using System.Linq; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -9,6 +9,7 @@ namespace Discord.Commands.Builders | |||||
| public class CommandBuilder | public class CommandBuilder | ||||
| { | { | ||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| private readonly List<PostActionAttribute> _postActions; | |||||
| private readonly List<ParameterBuilder> _parameters; | private readonly List<ParameterBuilder> _parameters; | ||||
| private readonly List<Attribute> _attributes; | private readonly List<Attribute> _attributes; | ||||
| private readonly List<string> _aliases; | private readonly List<string> _aliases; | ||||
| @@ -24,6 +25,7 @@ namespace Discord.Commands.Builders | |||||
| public int Priority { get; set; } | public int Priority { get; set; } | ||||
| public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | ||||
| public IReadOnlyList<PostActionAttribute> PostActions => _postActions; | |||||
| public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | ||||
| public IReadOnlyList<Attribute> Attributes => _attributes; | public IReadOnlyList<Attribute> Attributes => _attributes; | ||||
| public IReadOnlyList<string> Aliases => _aliases; | public IReadOnlyList<string> Aliases => _aliases; | ||||
| @@ -34,6 +36,7 @@ namespace Discord.Commands.Builders | |||||
| Module = module; | Module = module; | ||||
| _preconditions = new List<PreconditionAttribute>(); | _preconditions = new List<PreconditionAttribute>(); | ||||
| _postActions = new List<PostActionAttribute>(); | |||||
| _parameters = new List<ParameterBuilder>(); | _parameters = new List<ParameterBuilder>(); | ||||
| _attributes = new List<Attribute>(); | _attributes = new List<Attribute>(); | ||||
| _aliases = new List<string>(); | _aliases = new List<string>(); | ||||
| @@ -96,6 +99,11 @@ namespace Discord.Commands.Builders | |||||
| _preconditions.Add(precondition); | _preconditions.Add(precondition); | ||||
| return this; | return this; | ||||
| } | } | ||||
| public CommandBuilder AddPostAction(PostActionAttribute postAction) | |||||
| { | |||||
| _postActions.Add(postAction); | |||||
| return this; | |||||
| } | |||||
| public CommandBuilder AddParameter<T>(string name, Action<ParameterBuilder> createFunc) | public CommandBuilder AddParameter<T>(string name, Action<ParameterBuilder> createFunc) | ||||
| { | { | ||||
| var param = new ParameterBuilder(this, name, typeof(T)); | var param = new ParameterBuilder(this, name, typeof(T)); | ||||
| @@ -140,4 +148,4 @@ namespace Discord.Commands.Builders | |||||
| return new CommandInfo(this, info, service); | return new CommandInfo(this, info, service); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
| @@ -10,6 +10,7 @@ namespace Discord.Commands.Builders | |||||
| private readonly List<CommandBuilder> _commands; | private readonly List<CommandBuilder> _commands; | ||||
| private readonly List<ModuleBuilder> _submodules; | private readonly List<ModuleBuilder> _submodules; | ||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| private readonly List<PostActionAttribute> _postActions; | |||||
| private readonly List<Attribute> _attributes; | private readonly List<Attribute> _attributes; | ||||
| private readonly List<string> _aliases; | private readonly List<string> _aliases; | ||||
| @@ -22,6 +23,7 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<CommandBuilder> Commands => _commands; | public IReadOnlyList<CommandBuilder> Commands => _commands; | ||||
| public IReadOnlyList<ModuleBuilder> Modules => _submodules; | public IReadOnlyList<ModuleBuilder> Modules => _submodules; | ||||
| public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<PreconditionAttribute> Preconditions => _preconditions; | ||||
| public IReadOnlyList<PostActionAttribute> PostActions => _postActions; | |||||
| public IReadOnlyList<Attribute> Attributes => _attributes; | public IReadOnlyList<Attribute> Attributes => _attributes; | ||||
| public IReadOnlyList<string> Aliases => _aliases; | public IReadOnlyList<string> Aliases => _aliases; | ||||
| @@ -34,6 +36,7 @@ namespace Discord.Commands.Builders | |||||
| _commands = new List<CommandBuilder>(); | _commands = new List<CommandBuilder>(); | ||||
| _submodules = new List<ModuleBuilder>(); | _submodules = new List<ModuleBuilder>(); | ||||
| _preconditions = new List<PreconditionAttribute>(); | _preconditions = new List<PreconditionAttribute>(); | ||||
| _postActions = new List<PostActionAttribute>(); | |||||
| _attributes = new List<Attribute>(); | _attributes = new List<Attribute>(); | ||||
| _aliases = new List<string>(); | _aliases = new List<string>(); | ||||
| } | } | ||||
| @@ -82,6 +85,11 @@ namespace Discord.Commands.Builders | |||||
| _preconditions.Add(precondition); | _preconditions.Add(precondition); | ||||
| return this; | return this; | ||||
| } | } | ||||
| public ModuleBuilder AddPostAction(PostActionAttribute postAction) | |||||
| { | |||||
| _postActions.Add(postAction); | |||||
| return this; | |||||
| } | |||||
| public ModuleBuilder AddCommand(string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback, Action<CommandBuilder> createFunc) | public ModuleBuilder AddCommand(string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback, Action<CommandBuilder> createFunc) | ||||
| { | { | ||||
| var builder = new CommandBuilder(this, primaryAlias, callback); | var builder = new CommandBuilder(this, primaryAlias, callback); | ||||
| @@ -122,6 +122,9 @@ namespace Discord.Commands | |||||
| case PreconditionAttribute precondition: | case PreconditionAttribute precondition: | ||||
| builder.AddPrecondition(precondition); | builder.AddPrecondition(precondition); | ||||
| break; | break; | ||||
| case PostActionAttribute postAction: | |||||
| builder.AddPostAction(postAction); | |||||
| break; | |||||
| default: | default: | ||||
| builder.AddAttributes(attribute); | builder.AddAttributes(attribute); | ||||
| break; | break; | ||||
| @@ -176,6 +179,9 @@ namespace Discord.Commands | |||||
| case PreconditionAttribute precondition: | case PreconditionAttribute precondition: | ||||
| builder.AddPrecondition(precondition); | builder.AddPrecondition(precondition); | ||||
| break; | break; | ||||
| case PostActionAttribute postAction: | |||||
| builder.AddPostAction(postAction); | |||||
| break; | |||||
| default: | default: | ||||
| builder.AddAttributes(attribute); | builder.AddAttributes(attribute); | ||||
| break; | break; | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||
| @@ -18,6 +18,8 @@ namespace Discord.Commands | |||||
| public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IServiceProvider services = null) | ||||
| => Command.CheckPreconditionsAsync(context, services); | => Command.CheckPreconditionsAsync(context, services); | ||||
| public Task ExecutePostActionsAsync(ICommandContext context, IResult result, IServiceProvider services = null) | |||||
| => Command.ExecutePostActionsAsync(context, result, services); | |||||
| public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | ||||
| => Command.ParseAsync(context, Alias.Length, searchResult, preconditionResult, services); | => Command.ParseAsync(context, Alias.Length, searchResult, preconditionResult, services); | ||||
| public Task<IResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IServiceProvider services) | public Task<IResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IServiceProvider services) | ||||
| @@ -1,4 +1,4 @@ | |||||
| using Discord.Commands.Builders; | |||||
| using Discord.Commands.Builders; | |||||
| using Discord.Logging; | using Discord.Logging; | ||||
| using System; | using System; | ||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| @@ -362,7 +362,11 @@ namespace Discord.Commands | |||||
| //If we get this far, at least one parse was successful. Execute the most likely overload. | //If we get this far, at least one parse was successful. Execute the most likely overload. | ||||
| var chosenOverload = successfulParses[0]; | var chosenOverload = successfulParses[0]; | ||||
| return await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false); | |||||
| var result = await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false); | |||||
| await chosenOverload.Key.ExecutePostActionsAsync(context, result, services).ConfigureAwait(false); | |||||
| return result; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -32,6 +32,7 @@ namespace Discord.Commands | |||||
| public IReadOnlyList<string> Aliases { get; } | public IReadOnlyList<string> Aliases { get; } | ||||
| public IReadOnlyList<ParameterInfo> Parameters { get; } | public IReadOnlyList<ParameterInfo> Parameters { get; } | ||||
| public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | ||||
| public IReadOnlyList<PostActionAttribute> PostActions { get; } | |||||
| public IReadOnlyList<Attribute> Attributes { get; } | public IReadOnlyList<Attribute> Attributes { get; } | ||||
| internal CommandInfo(CommandBuilder builder, ModuleInfo module, CommandService service) | internal CommandInfo(CommandBuilder builder, ModuleInfo module, CommandService service) | ||||
| @@ -59,6 +60,7 @@ namespace Discord.Commands | |||||
| .ToImmutableArray(); | .ToImmutableArray(); | ||||
| Preconditions = builder.Preconditions.ToImmutableArray(); | Preconditions = builder.Preconditions.ToImmutableArray(); | ||||
| PostActions = builder.PostActions.ToImmutableArray(); | |||||
| Attributes = builder.Attributes.ToImmutableArray(); | Attributes = builder.Attributes.ToImmutableArray(); | ||||
| Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); | Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); | ||||
| @@ -109,6 +111,16 @@ namespace Discord.Commands | |||||
| return PreconditionResult.FromSuccess(); | return PreconditionResult.FromSuccess(); | ||||
| } | } | ||||
| public async Task ExecutePostActionsAsync(ICommandContext context, IResult result, IServiceProvider services = null) | |||||
| { | |||||
| services = services ?? EmptyServiceProvider.Instance; | |||||
| foreach (var postAction in Enumerable.Concat(PostActions, Module.PostActions)) | |||||
| { | |||||
| await postAction.ExecuteAsync(context, this, result, services).ConfigureAwait(false); | |||||
| } | |||||
| } | |||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null, IServiceProvider services = null) | ||||
| { | { | ||||
| services = services ?? EmptyServiceProvider.Instance; | services = services ?? EmptyServiceProvider.Instance; | ||||
| @@ -17,6 +17,7 @@ namespace Discord.Commands | |||||
| public IReadOnlyList<string> Aliases { get; } | public IReadOnlyList<string> Aliases { get; } | ||||
| public IReadOnlyList<CommandInfo> Commands { get; } | public IReadOnlyList<CommandInfo> Commands { get; } | ||||
| public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | ||||
| public IReadOnlyList<PostActionAttribute> PostActions { get; } | |||||
| public IReadOnlyList<Attribute> Attributes { get; } | public IReadOnlyList<Attribute> Attributes { get; } | ||||
| public IReadOnlyList<ModuleInfo> Submodules { get; } | public IReadOnlyList<ModuleInfo> Submodules { get; } | ||||
| public ModuleInfo Parent { get; } | public ModuleInfo Parent { get; } | ||||
| @@ -34,6 +35,7 @@ namespace Discord.Commands | |||||
| Aliases = BuildAliases(builder, service).ToImmutableArray(); | Aliases = BuildAliases(builder, service).ToImmutableArray(); | ||||
| Commands = builder.Commands.Select(x => x.Build(this, service)).ToImmutableArray(); | Commands = builder.Commands.Select(x => x.Build(this, service)).ToImmutableArray(); | ||||
| Preconditions = BuildPreconditions(builder).ToImmutableArray(); | Preconditions = BuildPreconditions(builder).ToImmutableArray(); | ||||
| PostActions = BuildPostActions(builder).ToImmutableArray(); | |||||
| Attributes = BuildAttributes(builder).ToImmutableArray(); | Attributes = BuildAttributes(builder).ToImmutableArray(); | ||||
| Submodules = BuildSubmodules(builder, service).ToImmutableArray(); | Submodules = BuildSubmodules(builder, service).ToImmutableArray(); | ||||
| @@ -90,6 +92,20 @@ namespace Discord.Commands | |||||
| return result; | return result; | ||||
| } | } | ||||
| private static List<PostActionAttribute> BuildPostActions(ModuleBuilder builder) | |||||
| { | |||||
| var result = new List<PostActionAttribute>(); | |||||
| ModuleBuilder parent = builder; | |||||
| while (parent != null) | |||||
| { | |||||
| result.AddRange(parent.PostActions); | |||||
| parent = parent.Parent; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| private static List<Attribute> BuildAttributes(ModuleBuilder builder) | private static List<Attribute> BuildAttributes(ModuleBuilder builder) | ||||
| { | { | ||||
| var result = new List<Attribute>(); | var result = new List<Attribute>(); | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System.Diagnostics; | |||||
| using System.Diagnostics; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||