using System; using System.Threading.Tasks; namespace Discord.Commands { /// /// This attribute requires that the user invoking the command has a specified permission. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RequireUserPermissionAttribute : PreconditionAttribute { public GuildPermission? GuildPermission { get; } public ChannelPermission? ChannelPermission { get; } public override string ErrorMessage { get; set; } public string NotAGuild { get; set; } /// /// Require that the user invoking the command has a specified GuildPermission /// /// This precondition will always fail if the command is being invoked in a private channel. /// The GuildPermission that the user must have. Multiple permissions can be specified by ORing the permissions together. public RequireUserPermissionAttribute(GuildPermission permission) { GuildPermission = permission; ChannelPermission = null; } /// /// Require that the user invoking the command has a specified ChannelPermission. /// /// The ChannelPermission that the user must have. Multiple permissions can be specified by ORing the permissions together. /// /// /// [Command("permission")] /// [RequireUserPermission(ChannelPermission.ReadMessageHistory | ChannelPermission.ReadMessages)] /// public async Task HasPermission() /// { /// await ReplyAsync("You can read messages and the message history!"); /// } /// /// public RequireUserPermissionAttribute(ChannelPermission permission) { ChannelPermission = permission; GuildPermission = null; } public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) { var guildUser = context.User as IGuildUser; if (GuildPermission.HasValue) { if (guildUser == null) return Task.FromResult(PreconditionResult.FromError(NotAGuild ?? "Command must be used in a guild channel")); if (!guildUser.GuildPermissions.Has(GuildPermission.Value)) return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires guild permission {GuildPermission.Value}")); } if (ChannelPermission.HasValue) { ChannelPermissions perms; if (context.Channel is IGuildChannel guildChannel) perms = guildUser.GetPermissions(guildChannel); else perms = ChannelPermissions.All(context.Channel); if (!perms.Has(ChannelPermission.Value)) return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires channel permission {ChannelPermission.Value}")); } return Task.FromResult(PreconditionResult.FromSuccess()); } } }