You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
3.7 KiB

using System;
using System.Threading.Tasks;
namespace Discord.Commands
{
/// <summary>
/// Requires the user invoking the command to have a specified permission.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireUserPermissionAttribute : PreconditionAttribute
{
/// <summary>
/// Gets the specified <see cref="Discord.GuildPermission" /> of the precondition.
/// </summary>
public GuildPermission? GuildPermission { get; }
/// <summary>
/// Gets the specified <see cref="Discord.ChannelPermission" /> of the precondition.
/// </summary>
public ChannelPermission? ChannelPermission { get; }
/// <inheritdoc />
public override string ErrorMessage { get; set; }
/// <summary>
/// Gets or sets the error message if the precondition
/// fails due to being run outside of a Guild channel.
/// </summary>
public string NotAGuildErrorMessage { get; set; }
/// <summary>
/// Requires that the user invoking the command to have a specific <see cref="Discord.GuildPermission"/>.
/// </summary>
/// <remarks>
/// This precondition will always fail if the command is being invoked in a <see cref="IPrivateChannel"/>.
/// </remarks>
/// <param name="permission">
/// The <see cref="Discord.GuildPermission" /> that the user must have. Multiple permissions can be
/// specified by ORing the permissions together.
/// </param>
public RequireUserPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
/// <summary>
/// Requires that the user invoking the command to have a specific <see cref="Discord.ChannelPermission"/>.
/// </summary>
/// <param name="permission">
/// The <see cref="Discord.ChannelPermission"/> that the user must have. Multiple permissions can be
/// specified by ORing the permissions together.
/// </param>
public RequireUserPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}
/// <inheritdoc />
public override Task<PreconditionResult> CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
var guildUser = context.User as IGuildUser;
if (GuildPermission.HasValue)
{
if (guildUser == null)
return Task.FromResult(PreconditionResult.FromError(NotAGuildErrorMessage ?? "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());
}
}
}