using System; using System.Collections.Generic; using System.Reflection; namespace Discord.Interactions.Builders { /// /// Represents a builder for creating . /// public class ModuleBuilder { private readonly List _attributes; private readonly List _preconditions; private readonly List _subModules; private readonly List _slashCommands; private readonly List _contextCommands; private readonly List _componentCommands; private readonly List _autocompleteCommands; private readonly List _modalCommands; /// /// Gets the underlying Interaction Service. /// public InteractionService InteractionService { get; } /// /// Gets the parent module if this module is a sub-module. /// public ModuleBuilder Parent { get; } /// /// Gets the name of this module. /// public string Name { get; internal set; } /// /// Gets and sets the group name of this module. /// public string SlashGroupName { get; set; } /// /// Gets whether this has a . /// public bool IsSlashGroup => !string.IsNullOrEmpty(SlashGroupName); /// /// Gets and sets the description of this module. /// public string Description { get; set; } /// /// Gets and sets the default permission of this module. /// [Obsolete($"To be deprecated soon, use {nameof(ContextTypes)} and {nameof(DefaultMemberPermissions)} instead.")] public bool DefaultPermission { get; set; } = true; /// /// Gets whether this command can be used in DMs. /// [Obsolete("This property will be deprecated soon. Use ContextTypes instead.")] public bool IsEnabledInDm { get; set; } = true; /// /// Gets whether this command is age restricted. /// public bool IsNsfw { get; set; } = false; /// /// Gets the default permissions needed for executing this command. /// public GuildPermission? DefaultMemberPermissions { get; set; } = null; /// /// Gets and sets whether this has a . /// public bool DontAutoRegister { get; set; } = false; /// /// Gets a collection of the attributes of this module. /// public IReadOnlyList Attributes => _attributes; /// /// Gets a collection of the preconditions of this module. /// public IReadOnlyCollection Preconditions => _preconditions; /// /// Gets a collection of the sub-modules of this module. /// public IReadOnlyList SubModules => _subModules; /// /// Gets a collection of the Slash Commands of this module. /// public IReadOnlyList SlashCommands => _slashCommands; /// /// Gets a collection of the Context Commands of this module. /// public IReadOnlyList ContextCommands => _contextCommands; /// /// Gets a collection of the Component Commands of this module. /// public IReadOnlyList ComponentCommands => _componentCommands; /// /// Gets a collection of the Autocomplete Commands of this module. /// public IReadOnlyList AutocompleteCommands => _autocompleteCommands; /// /// Gets a collection of the Modal Commands of this module. /// public IReadOnlyList ModalCommands => _modalCommands; /// /// Gets or sets the install method for this command. /// public HashSet IntegrationTypes { get; set; } = null; /// /// Gets or sets the context types this command can be executed in. /// public HashSet ContextTypes { get; set; } = null; internal TypeInfo TypeInfo { get; set; } internal ModuleBuilder(InteractionService interactionService, ModuleBuilder parent = null) { InteractionService = interactionService; Parent = parent; _attributes = new List(); _subModules = new List(); _slashCommands = new List(); _contextCommands = new List(); _componentCommands = new List(); _autocompleteCommands = new List(); _modalCommands = new List(); _preconditions = new List(); } /// /// Initializes a new . /// /// The underlying Interaction Service. /// Name of this module. /// Parent module of this sub-module. public ModuleBuilder(InteractionService interactionService, string name, ModuleBuilder parent = null) : this(interactionService, parent) { Name = name; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// public ModuleBuilder WithGroupName(string name) { SlashGroupName = name; return this; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// public ModuleBuilder WithDescription(string description) { Description = description; return this; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// [Obsolete($"To be deprecated soon, use {nameof(SetEnabledInDm)} and {nameof(WithDefaultMemberPermissions)} instead.")] public ModuleBuilder WithDefaultPermission(bool permission) { DefaultPermission = permission; return this; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// [Obsolete("This method will be deprecated soon. Use WithContextTypes instead.")] public ModuleBuilder SetEnabledInDm(bool isEnabled) { IsEnabledInDm = isEnabled; return this; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// public ModuleBuilder SetNsfw(bool isNsfw) { IsNsfw = isNsfw; return this; } /// /// Sets . /// /// New value of the . /// /// The builder instance. /// public ModuleBuilder WithDefaultMemberPermissions(GuildPermission permissions) { DefaultMemberPermissions = permissions; return this; } /// /// Adds attributes to . /// /// New attributes to be added to . /// /// The builder instance. /// public ModuleBuilder AddAttributes(params Attribute[] attributes) { _attributes.AddRange(attributes); return this; } /// /// Adds preconditions to . /// /// New preconditions to be added to . /// /// The builder instance. /// public ModuleBuilder AddPreconditions(params PreconditionAttribute[] preconditions) { _preconditions.AddRange(preconditions); return this; } /// /// Adds slash command builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddSlashCommand(Action configure) { var command = new SlashCommandBuilder(this); configure(command); _slashCommands.Add(command); return this; } /// /// Adds slash command builder to . /// /// Name of the command. /// Command callback to be executed. /// factory. /// /// The builder instance. /// public ModuleBuilder AddSlashCommand(string name, ExecuteCallback callback, Action configure) { var command = new SlashCommandBuilder(this, name, callback); configure(command); _slashCommands.Add(command); return this; } /// /// Adds context command builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddContextCommand(Action configure) { var command = new ContextCommandBuilder(this); configure(command); _contextCommands.Add(command); return this; } /// /// Adds context command builder to . /// /// Name of the command. /// Command callback to be executed. /// factory. /// /// The builder instance. /// public ModuleBuilder AddContextCommand(string name, ExecuteCallback callback, Action configure) { var command = new ContextCommandBuilder(this, name, callback); configure(command); _contextCommands.Add(command); return this; } /// /// Adds component command builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddComponentCommand(Action configure) { var command = new ComponentCommandBuilder(this); configure(command); _componentCommands.Add(command); return this; } /// /// Adds component command builder to . /// /// Name of the command. /// Command callback to be executed. /// factory. /// /// The builder instance. /// public ModuleBuilder AddComponentCommand(string name, ExecuteCallback callback, Action configure) { var command = new ComponentCommandBuilder(this, name, callback); configure(command); _componentCommands.Add(command); return this; } /// /// Adds autocomplete command builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddAutocompleteCommand(Action configure) { var command = new AutocompleteCommandBuilder(this); configure(command); _autocompleteCommands.Add(command); return this; } /// /// Adds autocomplete command builder to . /// /// Name of the command. /// Command callback to be executed. /// factory. /// /// The builder instance. /// public ModuleBuilder AddSlashCommand(string name, ExecuteCallback callback, Action configure) { var command = new AutocompleteCommandBuilder(this, name, callback); configure(command); _autocompleteCommands.Add(command); return this; } /// /// Adds a modal command builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddModalCommand(Action configure) { var command = new ModalCommandBuilder(this); configure(command); _modalCommands.Add(command); return this; } /// /// Adds a modal command builder to . /// /// Name of the command. /// Command callback to be executed. /// factory. /// /// The builder instance. /// public ModuleBuilder AddModalCommand(string name, ExecuteCallback callback, Action configure) { var command = new ModalCommandBuilder(this, name, callback); configure(command); _modalCommands.Add(command); return this; } /// /// Adds sub-module builder to . /// /// factory. /// /// The builder instance. /// public ModuleBuilder AddModule(Action configure) { var subModule = new ModuleBuilder(InteractionService, this); configure(subModule); _subModules.Add(subModule); return this; } /// /// Sets the on this . /// /// Install types for this command. /// The builder instance. public ModuleBuilder WithIntegrationTypes(params ApplicationIntegrationType[] integrationTypes) { IntegrationTypes = new HashSet(integrationTypes); return this; } /// /// Sets the on this . /// /// Context types the command can be executed in. /// The builder instance. public ModuleBuilder WithContextTypes(params InteractionContextType[] contextTypes) { ContextTypes = new HashSet(contextTypes); return this; } internal ModuleInfo Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent = null) { if (TypeInfo is not null && ModuleClassBuilder.IsValidModuleDefinition(TypeInfo)) { var instance = ReflectionUtils.CreateObject(TypeInfo, interactionService, services); try { instance.Construct(this, interactionService); var moduleInfo = new ModuleInfo(this, interactionService, services, parent); instance.OnModuleBuilding(interactionService, moduleInfo); return moduleInfo; } finally { (instance as IDisposable)?.Dispose(); } } else return new(this, interactionService, services, parent); } } }