using System; using System.Threading.Tasks; namespace Discord.Commands { /// /// Defines the type of command context (i.e. where the command is being executed). /// [Flags] public enum ContextType { /// /// Specifies the command to be executed within a guild. /// Guild = 0x01, /// /// Specifies the command to be executed within a DM. /// DM = 0x02, /// /// Specifies the command to be executed within a group. /// Group = 0x04 } /// /// Requires the command to be invoked in a specified context (e.g. in guild, DM). /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RequireContextAttribute : PreconditionAttribute { /// /// Gets the context required to execute the command. /// public ContextType Contexts { get; } /// public override string ErrorMessage { get; set; } /// Requires the command to be invoked in the specified context. /// The type of context the command can be invoked in. Multiple contexts can be specified by ORing the contexts together. /// /// /// [Command("secret")] /// [RequireContext(ContextType.DM | ContextType.Group)] /// public Task PrivateOnlyAsync() /// { /// return ReplyAsync("shh, this command is a secret"); /// } /// /// public RequireContextAttribute(ContextType contexts) { Contexts = contexts; } /// public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) { bool isValid = false; if ((Contexts & ContextType.Guild) != 0) isValid = context.Channel is IGuildChannel; if ((Contexts & ContextType.DM) != 0) isValid = isValid || context.Channel is IDMChannel; if ((Contexts & ContextType.Group) != 0) isValid = isValid || context.Channel is IGroupChannel; if (isValid) return Task.FromResult(PreconditionResult.FromSuccess()); else return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"Invalid context for command; accepted contexts: {Contexts}.")); } } }