@@ -0,0 +1,75 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> | |||
/// This attribute requires that the bot has a speicifed permission in the channel a command is invoked in. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |||
public class RequireBotPermissionAttribute : PreconditionAttribute | |||
{ | |||
public GuildPermission? GuildPermission { get; } | |||
public ChannelPermission? ChannelPermission { get; } | |||
/// <summary> | |||
/// Require that the bot account has a specified GuildPermission | |||
/// </summary> | |||
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks> | |||
/// <param name="permission">The GuildPermission that the bot must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param> | |||
public RequireBotPermissionAttribute(GuildPermission permission) | |||
{ | |||
GuildPermission = permission; | |||
ChannelPermission = null; | |||
} | |||
/// <summary> | |||
/// Require that the bot account has a specified ChannelPermission. | |||
/// </summary> | |||
/// <param name="permission">The ChannelPermission that the bot must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// [Command("permission")] | |||
/// [RequireBotPermission(ChannelPermission.ManageMessages)] | |||
/// public async Task Purge() | |||
/// { | |||
/// } | |||
/// </code> | |||
/// </example> | |||
public RequireBotPermissionAttribute(ChannelPermission permission) | |||
{ | |||
ChannelPermission = permission; | |||
GuildPermission = null; | |||
} | |||
public override async Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map) | |||
{ | |||
var guildUser = await context.Guild.GetCurrentUserAsync(); | |||
if (GuildPermission.HasValue) | |||
{ | |||
if (guildUser == null) | |||
return PreconditionResult.FromError("Command must be used in a guild channel"); | |||
if (!guildUser.GuildPermissions.Has(GuildPermission.Value)) | |||
return PreconditionResult.FromError($"Command requires guild permission {GuildPermission.Value}"); | |||
} | |||
if (ChannelPermission.HasValue) | |||
{ | |||
var guildChannel = context.Channel as IGuildChannel; | |||
ChannelPermissions perms; | |||
if (guildChannel != null) | |||
perms = guildUser.GetPermissions(guildChannel); | |||
else | |||
perms = ChannelPermissions.All(guildChannel); | |||
if (!perms.Has(ChannelPermission.Value)) | |||
return PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}"); | |||
} | |||
return PreconditionResult.FromSuccess(); | |||
} | |||
} | |||
} |
@@ -11,11 +11,27 @@ namespace Discord.Commands | |||
Group = 0x04 | |||
} | |||
/// <summary> | |||
/// Require that the command be invoked in a specified context. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |||
public class RequireContextAttribute : PreconditionAttribute | |||
{ | |||
public ContextType Contexts { get; } | |||
/// <summary> | |||
/// Require that the command be invoked in a specified context. | |||
/// </summary> | |||
/// <param name="contexts">The type of context the command can be invoked in. Multiple contexts can be speicifed by ORing the contexts together.</param> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// [Command("private_only")] | |||
/// [RequireContext(ContextType.DM | ContextType.Group)] | |||
/// public async Task PrivateOnly() | |||
/// { | |||
/// } | |||
/// </code> | |||
/// </example> | |||
public RequireContextAttribute(ContextType contexts) | |||
{ | |||
Contexts = contexts; | |||
@@ -0,0 +1,23 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Discord; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> | |||
/// Require that the command is invoked by the owner of the bot. | |||
/// </summary> | |||
/// <remarks>This precondition will only work if the bot is a bot account.</remarks> | |||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |||
public class RequireOwnerAttribute : PreconditionAttribute | |||
{ | |||
public override async Task<PreconditionResult> CheckPermissions(CommandContext context, CommandInfo command, IDependencyMap map) | |||
{ | |||
var application = await context.Client.GetApplicationInfoAsync(); | |||
if (context.User.Id == application.Owner.Id) return PreconditionResult.FromSuccess(); | |||
return PreconditionResult.FromError("Command can only be run by the owner of the bot"); | |||
} | |||
} | |||
} |
@@ -3,18 +3,40 @@ using System.Threading.Tasks; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> | |||
/// This attribute requires that the user invoking the command has a specified permission. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] | |||
public class RequirePermissionAttribute : PreconditionAttribute | |||
public class RequireUserPermissionAttribute : PreconditionAttribute | |||
{ | |||
public GuildPermission? GuildPermission { get; } | |||
public ChannelPermission? ChannelPermission { get; } | |||
public RequirePermissionAttribute(GuildPermission permission) | |||
/// <summary> | |||
/// Require that the user invoking the command has a specified GuildPermission | |||
/// </summary> | |||
/// <remarks>This precondition will always fail if the command is being invoked in a private channel.</remarks> | |||
/// <param name="permission">The GuildPermission that the user must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param> | |||
public RequireUserPermissionAttribute(GuildPermission permission) | |||
{ | |||
GuildPermission = permission; | |||
ChannelPermission = null; | |||
} | |||
public RequirePermissionAttribute(ChannelPermission permission) | |||
/// <summary> | |||
/// Require that the user invoking the command has a specified ChannelPermission. | |||
/// </summary> | |||
/// <param name="permission">The ChannelPermission that the user must have. Multiple permissions can be specified by ORing or ANDing the permissions together.</param> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// [Command("permission")] | |||
/// [RequireUserPermission(ChannelPermission.ReadMessageHistory & ChannelPermission.ReadMessages)] | |||
/// public async Task HasPermission() | |||
/// { | |||
/// await ReplyAsync("You can read messages and the message history!"); | |||
/// } | |||
/// </code> | |||
/// </example> | |||
public RequireUserPermissionAttribute(ChannelPermission permission) | |||
{ | |||
ChannelPermission = permission; | |||
GuildPermission = null; |
@@ -38,6 +38,7 @@ namespace Discord.WebSocket | |||
private int _nextAudioId; | |||
private bool _canReconnect; | |||
private DateTimeOffset? _statusSince; | |||
private RestApplication _application; | |||
/// <summary> Gets the shard of of this client. </summary> | |||
public int ShardId { get; } | |||
@@ -333,8 +334,10 @@ namespace Discord.WebSocket | |||
} | |||
/// <inheritdoc /> | |||
public Task<RestApplication> GetApplicationInfoAsync() | |||
=> ClientHelper.GetApplicationInfoAsync(this); | |||
public async Task<RestApplication> GetApplicationInfoAsync() | |||
{ | |||
return _application ?? (_application = await ClientHelper.GetApplicationInfoAsync(this)); | |||
} | |||
/// <inheritdoc /> | |||
public SocketGuild GetGuild(ulong id) | |||