using Microsoft.Extensions.DependencyInjection;
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))
{
IServiceScope scope = null;
if (interactionService._autoServiceScopes)
{
scope = services?.CreateScope();
services = scope?.ServiceProvider ?? EmptyServiceProvider.Instance;
}
var instance = ReflectionUtils.CreateObject(TypeInfo, interactionService, services);
try
{
instance.Construct(this, interactionService);
var moduleInfo = new ModuleInfo(this, interactionService, services, parent);
instance.OnModuleBuilding(interactionService, moduleInfo);
scope?.Dispose();
return moduleInfo;
}
finally
{
scope?.Dispose();
(instance as IDisposable)?.Dispose();
}
}
else
return new(this, interactionService, services, parent);
}
}
}