diff --git a/src/Discord.Net.Commands/Attributes/Preconditions/RequireRoleAttribute.cs b/src/Discord.Net.Commands/Attributes/Preconditions/RequireRoleAttribute.cs new file mode 100644 index 00000000..112f5697 --- /dev/null +++ b/src/Discord.Net.Commands/Attributes/Preconditions/RequireRoleAttribute.cs @@ -0,0 +1,74 @@ +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Discord.Commands +{ + /// + /// Requires the user invoking the command to have a specified role. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class RequireRoleAttribute : PreconditionAttribute + { + /// + /// Gets the specified Role name of the precondition. + /// + public string RoleName { get; } + + /// + /// Gets the specified Role ID of the precondition. + /// + public ulong? RoleId { get; } + + /// + /// Gets or sets the error message if the precondition + /// fails due to being run outside of a Guild channel. + /// + public string NotAGuildErrorMessage { get; set; } + + /// + /// Requires that the user invoking the command to have a specific Role. + /// + /// Id of the role that the user must have. + public RequireRoleAttribute(ulong roleId) + { + RoleId = roleId; + } + + /// + /// Requires that the user invoking the command to have a specific Role. + /// + /// Name of the role that the user must have. + public RequireRoleAttribute(string roleName) + { + RoleName = roleName; + } + + + public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) + { + if (context.User is not IGuildUser guildUser) + return Task.FromResult(PreconditionResult.FromError(NotAGuildErrorMessage ?? "Command must be used in a guild channel.")); + + if (RoleId.HasValue) + { + if (guildUser.RoleIds.Contains(RoleId.Value)) + return Task.FromResult(PreconditionResult.FromSuccess()); + else + return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires guild role {context.Guild.GetRole(RoleId.Value).Name}.")); + } + + if (!string.IsNullOrEmpty(RoleName)) + { + var roleNames = guildUser.RoleIds.Select(x => guildUser.Guild.GetRole(x).Name); + + if (roleNames.Contains(RoleName)) + return Task.FromResult(PreconditionResult.FromSuccess()); + else + return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires guild role {RoleName}.")); + } + + return Task.FromResult(PreconditionResult.FromSuccess()); + } + } +}