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();