using System; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; namespace Discord.Commands { /// Defines the type of command context. [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; } /// Requires that the command 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("private_only")] /// [RequireContext(ContextType.DM | ContextType.Group)] /// public async Task PrivateOnly() /// { /// } /// /// 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 = 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($"Invalid context for command; accepted contexts: {Contexts}")); } } }