diff --git a/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs index 168d15e5f..39457bbdb 100644 --- a/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs +++ b/src/Discord.Net.Commands/Attributes/ParameterPreconditionAttribute.cs @@ -6,6 +6,6 @@ namespace Discord.Commands [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)] public abstract class ParameterPreconditionAttribute : Attribute { - public abstract Task CheckPermissions(ICommandContext context, ParameterInfo parameter, object value, IDependencyMap map); + public abstract Task CheckPermissions(ICommandContext context, ParameterInfo parameter, T value, IDependencyMap map); } } \ No newline at end of file diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index 031d37581..63333f0d2 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -128,9 +128,11 @@ namespace Discord.Commands { object[] args = GenerateArgs(argList, paramList); - foreach (var parameter in Parameters) + for (int position = 0; position < Parameters.Count; position++) { - var result = await parameter.CheckPreconditionsAsync(context, args, map).ConfigureAwait(false); + var parameter = Parameters[position]; + var argument = args[position]; + var result = await parameter.CheckPreconditionsAsync(context, argument, map).ConfigureAwait(false); if (!result.IsSuccess) return ExecuteResult.FromError(result); } diff --git a/src/Discord.Net.Commands/Info/ParameterInfo.cs b/src/Discord.Net.Commands/Info/ParameterInfo.cs index a0cdf03d7..634e7b424 100644 --- a/src/Discord.Net.Commands/Info/ParameterInfo.cs +++ b/src/Discord.Net.Commands/Info/ParameterInfo.cs @@ -4,12 +4,18 @@ using System.Collections.Immutable; using System.Threading.Tasks; using Discord.Commands.Builders; +using System.Reflection; namespace Discord.Commands { public class ParameterInfo { + + private static MethodInfo _checkPermissionsMethod = typeof(ParameterPreconditionAttribute) + .GetTypeInfo().GetDeclaredMethod("CheckPermissions"); + private readonly TypeReader _reader; + private readonly MethodInfo _specializedCheckPermissionsMethod; public CommandInfo Command { get; } public string Name { get; } @@ -38,21 +44,20 @@ namespace Discord.Commands Preconditions = builder.Preconditions.ToImmutableArray(); _reader = builder.TypeReader; + + _specializedCheckPermissionsMethod = _checkPermissionsMethod.MakeGenericMethod(Type); } - public async Task CheckPreconditionsAsync(ICommandContext context, object[] args, IDependencyMap map = null) + public async Task CheckPreconditionsAsync(ICommandContext context, object arg, IDependencyMap map = null) { if (map == null) map = DependencyMap.Empty; - int position = 0; - for(position = 0; position < Command.Parameters.Count; position++) - if (Command.Parameters[position] == this) - break; - foreach (var precondition in Preconditions) { - var result = await precondition.CheckPermissions(context, this, args[position], map).ConfigureAwait(false); + object[] parameters = new []{ context, this, arg, map }; + var resultTask = (_specializedCheckPermissionsMethod.Invoke(precondition, parameters) as Task); + var result = await resultTask.ConfigureAwait(false); if (!result.IsSuccess) return result; }