diff --git a/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs b/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs index e099380f6..38672f071 100644 --- a/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs +++ b/src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs @@ -6,6 +6,16 @@ namespace Discord.Commands [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public abstract class PreconditionAttribute : Attribute { + /// + /// Specify a group that this precondition belongs to. + /// Preconditions of the same group require only one + /// of the preconditions to pass in order to be + /// successful (A || B). Specifying = 0 + /// or not at all will require *all* preconditions + /// to pass, just like normal (A && B). + /// + public int Group { get; set; } = 0; + public abstract Task CheckPermissions(ICommandContext context, CommandInfo command, IServiceProvider services); } } diff --git a/src/Discord.Net.Commands/Info/CommandInfo.cs b/src/Discord.Net.Commands/Info/CommandInfo.cs index 5acd1f648..360dcf1fb 100644 --- a/src/Discord.Net.Commands/Info/CommandInfo.cs +++ b/src/Discord.Net.Commands/Info/CommandInfo.cs @@ -68,18 +68,48 @@ namespace Discord.Commands { services = services ?? EmptyServiceProvider.Instance; - foreach (PreconditionAttribute precondition in Module.Preconditions) + foreach (IGrouping preconditionGroup in Module.Preconditions.GroupBy(p => p.Group)) { - var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); - if (!result.IsSuccess) - return result; + if (preconditionGroup.Key == 0) + { + foreach (PreconditionAttribute precondition in preconditionGroup) + { + var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); + if (!result.IsSuccess) + return result; + } + } + else + { + var results = new List(); + foreach (PreconditionAttribute precondition in preconditionGroup) + results.Add(await precondition.CheckPermissions(context, this, services).ConfigureAwait(false)); + + if (!results.Any(p => p.IsSuccess)) + return results[0]; + } } - foreach (PreconditionAttribute precondition in Preconditions) + foreach (IGrouping preconditionGroup in Module.Preconditions.GroupBy(p => p.Group)) { - var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); - if (!result.IsSuccess) - return result; + if (preconditionGroup.Key == 0) + { + foreach (PreconditionAttribute precondition in Preconditions) + { + var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false); + if (!result.IsSuccess) + return result; + } + } + else + { + var results = new List(); + foreach (PreconditionAttribute precondition in preconditionGroup) + results.Add(await precondition.CheckPermissions(context, this, services).ConfigureAwait(false)); + + if (!results.Any(p => p.IsSuccess)) + return results[0]; + } } return PreconditionResult.FromSuccess();