using Discord.Interactions.Builders; using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; namespace Discord.Interactions { /// /// Contains the information of a Interactions Module. /// public class ModuleInfo { internal ILookup GroupedPreconditions { get; } /// /// Gets the underlying command service. /// public InteractionService CommandService { get; } /// /// Gets the name of this module class. /// public string Name { get; } /// /// Gets the group name of this module, if the module is marked with a . /// public string SlashGroupName { get; } /// /// Gets if this module is marked with a . /// public bool IsSlashGroup => !string.IsNullOrEmpty(SlashGroupName); /// /// Gets the description of this module if is . /// public string Description { get; } /// /// Gets the default Permission of this module. /// [Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")] public bool DefaultPermission { get; } /// /// Gets whether this command can be used in DMs. /// public bool IsEnabledInDm { get; } /// /// Gets whether this command is age restricted. /// public bool IsNsfw { get; } /// /// Gets the default permissions needed for executing this command. /// public GuildPermission? DefaultMemberPermissions { get; } /// /// Gets the collection of Sub Modules of this module. /// public IReadOnlyList SubModules { get; } /// /// Gets the Slash Commands that are declared in this module. /// public IReadOnlyList SlashCommands { get; } /// /// Gets the Context Commands that are declared in this module. /// public IReadOnlyList ContextCommands { get; } /// /// Gets the Component Commands that are declared in this module. /// public IReadOnlyCollection ComponentCommands { get; } /// /// Gets the Autocomplete Commands that are declared in this module. /// public IReadOnlyCollection AutocompleteCommands { get; } public IReadOnlyCollection ModalCommands { get; } /// /// Gets the declaring type of this module, if is . /// public ModuleInfo Parent { get; } /// /// Gets if this module is declared by another . /// public bool IsSubModule => Parent != null; /// /// Gets a collection of the attributes of this module. /// public IReadOnlyCollection Attributes { get; } /// /// Gets a collection of the preconditions of this module. /// public IReadOnlyCollection Preconditions { get; } /// /// Gets if this module has a valid and has no parent with a . /// public bool IsTopLevelGroup { get; } /// /// Gets if this module will not be registered by /// or methods. /// public bool DontAutoRegister { get; } /// /// Gets the context types commands in this module can be executed in. /// public IReadOnlyCollection ContextTypes { get; } /// /// Gets the install method for commands in this module. /// public IReadOnlyCollection IntegrationTypes { get; } internal ModuleInfo(ModuleBuilder builder, InteractionService commandService, IServiceProvider services, ModuleInfo parent = null) { CommandService = commandService; Name = builder.Name; SlashGroupName = builder.SlashGroupName; Description = builder.Description; Parent = parent; #pragma warning disable CS0618 // Type or member is obsolete DefaultPermission = builder.DefaultPermission; #pragma warning restore CS0618 // Type or member is obsolete IsNsfw = builder.IsNsfw; #pragma warning disable CS0618 // Type or member is obsolete IsEnabledInDm = builder.IsEnabledInDm; #pragma warning restore CS0618 // Type or member is obsolete DefaultMemberPermissions = BuildDefaultMemberPermissions(builder); SlashCommands = BuildSlashCommands(builder).ToImmutableArray(); ContextCommands = BuildContextCommands(builder).ToImmutableArray(); ComponentCommands = BuildComponentCommands(builder).ToImmutableArray(); AutocompleteCommands = BuildAutocompleteCommands(builder).ToImmutableArray(); ModalCommands = BuildModalCommands(builder).ToImmutableArray(); SubModules = BuildSubModules(builder, commandService, services).ToImmutableArray(); Attributes = BuildAttributes(builder).ToImmutableArray(); Preconditions = BuildPreconditions(builder).ToImmutableArray(); IsTopLevelGroup = IsSlashGroup && CheckTopLevel(parent); DontAutoRegister = builder.DontAutoRegister; ContextTypes = builder.ContextTypes?.ToImmutableArray(); IntegrationTypes = builder.IntegrationTypes?.ToImmutableArray(); GroupedPreconditions = Preconditions.ToLookup(x => x.Group, x => x, StringComparer.Ordinal); } private IEnumerable BuildSubModules(ModuleBuilder builder, InteractionService commandService, IServiceProvider services) { var result = new List(); foreach (Builders.ModuleBuilder moduleBuilder in builder.SubModules) result.Add(moduleBuilder.Build(commandService, services, this)); return result; } private IEnumerable BuildSlashCommands(ModuleBuilder builder) { var result = new List(); foreach (Builders.SlashCommandBuilder commandBuilder in builder.SlashCommands) result.Add(commandBuilder.Build(this, CommandService)); return result; } private IEnumerable BuildContextCommands(ModuleBuilder builder) { var result = new List(); foreach (Builders.ContextCommandBuilder commandBuilder in builder.ContextCommands) result.Add(commandBuilder.Build(this, CommandService)); return result; } private IEnumerable BuildComponentCommands(ModuleBuilder builder) { var result = new List(); foreach (var interactionBuilder in builder.ComponentCommands) result.Add(interactionBuilder.Build(this, CommandService)); return result; } private IEnumerable BuildAutocompleteCommands(ModuleBuilder builder) { var result = new List(); foreach (var commandBuilder in builder.AutocompleteCommands) result.Add(commandBuilder.Build(this, CommandService)); return result; } private IEnumerable BuildModalCommands(ModuleBuilder builder) { var result = new List(); foreach (var commandBuilder in builder.ModalCommands) result.Add(commandBuilder.Build(this, CommandService)); return result; } private IEnumerable BuildAttributes(ModuleBuilder builder) { var result = new List(); var currentParent = builder; while (currentParent != null) { result.AddRange(currentParent.Attributes); currentParent = currentParent.Parent; } return result; } private static IEnumerable BuildPreconditions(ModuleBuilder builder) { var preconditions = new List(); var parent = builder; while (parent != null) { preconditions.AddRange(parent.Preconditions); parent = parent.Parent; } return preconditions; } private static bool CheckTopLevel(ModuleInfo parent) { var currentParent = parent; while (currentParent != null) { if (currentParent.IsSlashGroup) return false; currentParent = currentParent.Parent; } return true; } private static GuildPermission? BuildDefaultMemberPermissions(ModuleBuilder builder) { var permissions = builder.DefaultMemberPermissions; var parent = builder.Parent; while (parent != null) { permissions = (permissions ?? 0) | (parent.DefaultMemberPermissions ?? 0).SanitizeGuildPermissions(); parent = parent.Parent; } return permissions; } } }