* omg it kinda works somehow * more things added * a bit of xmldocs * added interaction framework support * working? IF * more builder stuff * space * rename attribute to prevent conflict with `ContextType` enum * context type * moar features * remove integration types * trigger workflow * modelzzzz * `InteractionContextType` * allow setting custom status with `SetGameAsync` * bugzzz * app permissions * message interaction context * hm * push for cd * structs lets goooo * whoops forgot to change types * whoops x2 * tweak some things * xmldocs + missing prop + fix enabled in dm * moar validations * deprecate a bunch of stuffz * disable moar obsolete warnings * add IF sample * Apply suggestions from code review Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * Update src/Discord.Net.Rest/Entities/RestApplication.cs Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> --------- Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
281 lines
10 KiB
C#
281 lines
10 KiB
C#
using Discord.Interactions.Builders;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
|
|
namespace Discord.Interactions
|
|
{
|
|
/// <summary>
|
|
/// Contains the information of a Interactions Module.
|
|
/// </summary>
|
|
public class ModuleInfo
|
|
{
|
|
internal ILookup<string, PreconditionAttribute> GroupedPreconditions { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the underlying command service.
|
|
/// </summary>
|
|
public InteractionService CommandService { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the name of this module class.
|
|
/// </summary>
|
|
public string Name { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the group name of this module, if the module is marked with a <see cref="GroupAttribute"/>.
|
|
/// </summary>
|
|
public string SlashGroupName { get; }
|
|
|
|
/// <summary>
|
|
/// Gets <see langword="true"/> if this module is marked with a <see cref="GroupAttribute"/>.
|
|
/// </summary>
|
|
public bool IsSlashGroup => !string.IsNullOrEmpty(SlashGroupName);
|
|
|
|
/// <summary>
|
|
/// Gets the description of this module if <see cref="IsSlashGroup"/> is <see langword="true"/>.
|
|
/// </summary>
|
|
public string Description { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the default Permission of this module.
|
|
/// </summary>
|
|
[Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")]
|
|
public bool DefaultPermission { get; }
|
|
|
|
/// <summary>
|
|
/// Gets whether this command can be used in DMs.
|
|
/// </summary>
|
|
public bool IsEnabledInDm { get; }
|
|
|
|
/// <summary>
|
|
/// Gets whether this command is age restricted.
|
|
/// </summary>
|
|
public bool IsNsfw { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the default permissions needed for executing this command.
|
|
/// </summary>
|
|
public GuildPermission? DefaultMemberPermissions { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the collection of Sub Modules of this module.
|
|
/// </summary>
|
|
public IReadOnlyList<ModuleInfo> SubModules { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the Slash Commands that are declared in this module.
|
|
/// </summary>
|
|
public IReadOnlyList<SlashCommandInfo> SlashCommands { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the Context Commands that are declared in this module.
|
|
/// </summary>
|
|
public IReadOnlyList<ContextCommandInfo> ContextCommands { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the Component Commands that are declared in this module.
|
|
/// </summary>
|
|
public IReadOnlyCollection<ComponentCommandInfo> ComponentCommands { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the Autocomplete Commands that are declared in this module.
|
|
/// </summary>
|
|
public IReadOnlyCollection<AutocompleteCommandInfo> AutocompleteCommands { get; }
|
|
|
|
public IReadOnlyCollection<ModalCommandInfo> ModalCommands { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the declaring type of this module, if <see cref="IsSubModule"/> is <see langword="true"/>.
|
|
/// </summary>
|
|
public ModuleInfo Parent { get; }
|
|
|
|
/// <summary>
|
|
/// Gets <see langword="true"/> if this module is declared by another <see cref="InteractionModuleBase{T}"/>.
|
|
/// </summary>
|
|
public bool IsSubModule => Parent != null;
|
|
|
|
/// <summary>
|
|
/// Gets a collection of the attributes of this module.
|
|
/// </summary>
|
|
public IReadOnlyCollection<Attribute> Attributes { get; }
|
|
|
|
/// <summary>
|
|
/// Gets a collection of the preconditions of this module.
|
|
/// </summary>
|
|
public IReadOnlyCollection<PreconditionAttribute> Preconditions { get; }
|
|
|
|
/// <summary>
|
|
/// Gets <see langword="true"/> if this module has a valid <see cref="GroupAttribute"/> and has no parent with a <see cref="GroupAttribute"/>.
|
|
/// </summary>
|
|
public bool IsTopLevelGroup { get; }
|
|
|
|
/// <summary>
|
|
/// Gets <see langword="true"/> if this module will not be registered by <see cref="InteractionService.RegisterCommandsGloballyAsync(bool)"/>
|
|
/// or <see cref="InteractionService.RegisterCommandsToGuildAsync(ulong, bool)"/> methods.
|
|
/// </summary>
|
|
public bool DontAutoRegister { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the context types commands in this module can be executed in.
|
|
/// </summary>
|
|
public IReadOnlyCollection<InteractionContextType> ContextTypes { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the install method for commands in this module.
|
|
/// </summary>
|
|
public IReadOnlyCollection<ApplicationIntegrationType> 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<ModuleInfo> BuildSubModules(ModuleBuilder builder, InteractionService commandService, IServiceProvider services)
|
|
{
|
|
var result = new List<ModuleInfo>();
|
|
|
|
foreach (Builders.ModuleBuilder moduleBuilder in builder.SubModules)
|
|
result.Add(moduleBuilder.Build(commandService, services, this));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<SlashCommandInfo> BuildSlashCommands(ModuleBuilder builder)
|
|
{
|
|
var result = new List<SlashCommandInfo>();
|
|
|
|
foreach (Builders.SlashCommandBuilder commandBuilder in builder.SlashCommands)
|
|
result.Add(commandBuilder.Build(this, CommandService));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<ContextCommandInfo> BuildContextCommands(ModuleBuilder builder)
|
|
{
|
|
var result = new List<ContextCommandInfo>();
|
|
|
|
foreach (Builders.ContextCommandBuilder commandBuilder in builder.ContextCommands)
|
|
result.Add(commandBuilder.Build(this, CommandService));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<ComponentCommandInfo> BuildComponentCommands(ModuleBuilder builder)
|
|
{
|
|
var result = new List<ComponentCommandInfo>();
|
|
|
|
foreach (var interactionBuilder in builder.ComponentCommands)
|
|
result.Add(interactionBuilder.Build(this, CommandService));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<AutocompleteCommandInfo> BuildAutocompleteCommands(ModuleBuilder builder)
|
|
{
|
|
var result = new List<AutocompleteCommandInfo>();
|
|
|
|
foreach (var commandBuilder in builder.AutocompleteCommands)
|
|
result.Add(commandBuilder.Build(this, CommandService));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<ModalCommandInfo> BuildModalCommands(ModuleBuilder builder)
|
|
{
|
|
var result = new List<ModalCommandInfo>();
|
|
|
|
foreach (var commandBuilder in builder.ModalCommands)
|
|
result.Add(commandBuilder.Build(this, CommandService));
|
|
|
|
return result;
|
|
}
|
|
|
|
private IEnumerable<Attribute> BuildAttributes(ModuleBuilder builder)
|
|
{
|
|
var result = new List<Attribute>();
|
|
var currentParent = builder;
|
|
|
|
while (currentParent != null)
|
|
{
|
|
result.AddRange(currentParent.Attributes);
|
|
currentParent = currentParent.Parent;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static IEnumerable<PreconditionAttribute> BuildPreconditions(ModuleBuilder builder)
|
|
{
|
|
var preconditions = new List<PreconditionAttribute>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|