From d98b3cc495e9230346e38fbd3e7ff4f95c332ef1 Mon Sep 17 00:00:00 2001 From: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Thu, 28 Apr 2022 08:47:52 -0300 Subject: [PATCH] feature: V2 Permissions (#2222) * Initial V2 permissions * add perms-v2 attributes and properties, add deprecation messages * add perms-v2 properties to command info classes * add perms-v2 fields to Rest/SocketApplicationCommand entities and IApplicationCommand * fix json name of DmPermission field Co-authored-by: Cenngo --- .../ApplicationCommandProperties.cs | 10 +++++ .../ContextMenus/MessageCommandBuilder.cs | 36 +++++++++++++++++- .../ContextMenus/UserCommandBuilder.cs | 36 +++++++++++++++++- .../Interactions/IApplicationCommand.cs | 13 +++++++ .../SlashCommands/SlashCommandBuilder.cs | 34 +++++++++++++++++ .../DefaultMemberPermissionAttribute.cs | 25 ++++++++++++ .../Attributes/DefaultPermissionAttribute.cs | 1 + .../Attributes/EnabledInDmAttribute.cs | 25 ++++++++++++ .../Commands/ContextCommandBuilder.cs | 38 +++++++++++++++++++ .../Builders/Commands/SlashCommandBuilder.cs | 38 +++++++++++++++++++ .../Builders/ModuleBuilder.cs | 38 +++++++++++++++++++ .../Builders/ModuleClassBuilder.cs | 30 +++++++++++++++ .../ContextCommands/ContextCommandInfo.cs | 8 ++++ .../Info/Commands/SlashCommandInfo.cs | 8 ++++ .../Info/IApplicationCommandInfo.cs | 13 +++++++ .../Info/ModuleInfo.cs | 28 ++++++++++++++ .../Utilities/ApplicationCommandRestUtil.cs | 21 ++++++++-- .../API/Common/ApplicationCommand.cs | 7 ++++ .../Rest/CreateApplicationCommandParams.cs | 6 +++ .../Interactions/InteractionHelper.cs | 25 ++++++++++-- .../Interactions/RestApplicationCommand.cs | 10 +++++ .../SocketApplicationCommand.cs | 10 +++++ 22 files changed, 451 insertions(+), 9 deletions(-) create mode 100644 src/Discord.Net.Interactions/Attributes/DefaultMemberPermissionAttribute.cs create mode 100644 src/Discord.Net.Interactions/Attributes/EnabledInDmAttribute.cs diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs index 501a0e905..9b3ac8453 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandProperties.cs @@ -17,6 +17,16 @@ namespace Discord /// public Optional IsDefaultPermission { get; set; } + /// + /// Gets or sets whether or not this command can be used in DMs. + /// + public Optional IsDMEnabled { get; set; } + + /// + /// Gets or sets the default permissions required by a user to execute this application command. + /// + public Optional DefaultMemberPermissions { get; set; } + internal ApplicationCommandProperties() { } } } diff --git a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/MessageCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/MessageCommandBuilder.cs index c7a7cf741..59040dd4e 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/MessageCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/MessageCommandBuilder.cs @@ -31,6 +31,16 @@ namespace Discord /// public bool IsDefaultPermission { get; set; } = true; + /// + /// Gets or sets whether or not this command can be used in DMs. + /// + public bool IsDMEnabled { get; set; } = true; + + /// + /// Gets or sets the default permission required to use this slash command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } + private string _name; /// @@ -44,7 +54,9 @@ namespace Discord var props = new MessageCommandProperties { Name = Name, - IsDefaultPermission = IsDefaultPermission + IsDefaultPermission = IsDefaultPermission, + IsDMEnabled = IsDMEnabled, + DefaultMemberPermissions = DefaultMemberPermissions ?? Optional.Unspecified }; return props; @@ -73,5 +85,27 @@ namespace Discord IsDefaultPermission = isDefaultPermission; return this; } + + /// + /// Sets whether or not this command can be used in dms + /// + /// if the command is available in dms, otherwise . + /// The current builder. + public MessageCommandBuilder WithDMPermission(bool permission) + { + IsDMEnabled = permission; + return this; + } + + /// + /// Sets the default member permissions required to use this application command. + /// + /// The permissions required to use this command. + /// The current builder. + public MessageCommandBuilder WithDefaultMemberPermissions(GuildPermission? permissions) + { + DefaultMemberPermissions = permissions; + return this; + } } } diff --git a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/UserCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/UserCommandBuilder.cs index bd1078be3..7c82dce55 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/UserCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/UserCommandBuilder.cs @@ -31,6 +31,16 @@ namespace Discord /// public bool IsDefaultPermission { get; set; } = true; + /// + /// Gets or sets whether or not this command can be used in DMs. + /// + public bool IsDMEnabled { get; set; } = true; + + /// + /// Gets or sets the default permission required to use this slash command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } + private string _name; /// @@ -42,7 +52,9 @@ namespace Discord var props = new UserCommandProperties { Name = Name, - IsDefaultPermission = IsDefaultPermission + IsDefaultPermission = IsDefaultPermission, + IsDMEnabled = IsDMEnabled, + DefaultMemberPermissions = DefaultMemberPermissions ?? Optional.Unspecified }; return props; @@ -71,5 +83,27 @@ namespace Discord IsDefaultPermission = isDefaultPermission; return this; } + + /// + /// Sets whether or not this command can be used in dms + /// + /// if the command is available in dms, otherwise . + /// The current builder. + public UserCommandBuilder WithDMPermission(bool permission) + { + IsDMEnabled = permission; + return this; + } + + /// + /// Sets the default member permissions required to use this application command. + /// + /// The permissions required to use this command. + /// The current builder. + public UserCommandBuilder WithDefaultMemberPermissions(GuildPermission? permissions) + { + DefaultMemberPermissions = permissions; + return this; + } } } diff --git a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs index 72045a52a..58a002649 100644 --- a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs +++ b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommand.cs @@ -34,6 +34,19 @@ namespace Discord /// bool IsDefaultPermission { get; } + /// + /// Indicates whether the command is available in DMs with the app. + /// + /// + /// Only for globally-scoped commands. + /// + bool IsEnabledInDm { get; } + + /// + /// Set of default required to invoke the command. + /// + GuildPermissions DefaultMemberPermissions { get; } + /// /// Gets a collection of options for this application command. /// diff --git a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs index ccfb2da0a..ed815ca1a 100644 --- a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/SlashCommandBuilder.cs @@ -81,6 +81,16 @@ namespace Discord /// public bool IsDefaultPermission { get; set; } = true; + /// + /// Gets or sets whether or not this command can be used in DMs. + /// + public bool IsDMEnabled { get; set; } = true; + + /// + /// Gets or sets the default permission required to use this slash command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } + private string _name; private string _description; private List _options; @@ -96,6 +106,8 @@ namespace Discord Name = Name, Description = Description, IsDefaultPermission = IsDefaultPermission, + IsDMEnabled = IsDMEnabled, + DefaultMemberPermissions = DefaultMemberPermissions ?? Optional.Unspecified }; if (Options != null && Options.Any()) @@ -145,6 +157,28 @@ namespace Discord return this; } + /// + /// Sets whether or not this command can be used in dms + /// + /// if the command is available in dms, otherwise . + /// The current builder. + public SlashCommandBuilder WithDMPermission(bool permission) + { + IsDMEnabled = permission; + return this; + } + + /// + /// Sets the default member permissions required to use this application command. + /// + /// The permissions required to use this command. + /// The current builder. + public SlashCommandBuilder WithDefaultMemberPermissions(GuildPermission? permissions) + { + DefaultMemberPermissions = permissions; + return this; + } + /// /// Adds an option to the current slash command. /// diff --git a/src/Discord.Net.Interactions/Attributes/DefaultMemberPermissionAttribute.cs b/src/Discord.Net.Interactions/Attributes/DefaultMemberPermissionAttribute.cs new file mode 100644 index 000000000..ec79da1e3 --- /dev/null +++ b/src/Discord.Net.Interactions/Attributes/DefaultMemberPermissionAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Discord.Interactions +{ + /// + /// Sets the of an application command or module. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class DefaultMemberPermissionsAttribute : Attribute + { + /// + /// Gets the default permission required to use this command. + /// + public GuildPermission Permissions { get; } + + /// + /// Sets the of an application command or module. + /// + /// The default permission required to use this command. + public DefaultMemberPermissionsAttribute(GuildPermission permissions) + { + Permissions = permissions; + } + } +} diff --git a/src/Discord.Net.Interactions/Attributes/DefaultPermissionAttribute.cs b/src/Discord.Net.Interactions/Attributes/DefaultPermissionAttribute.cs index ed0a532be..2e03dfac6 100644 --- a/src/Discord.Net.Interactions/Attributes/DefaultPermissionAttribute.cs +++ b/src/Discord.Net.Interactions/Attributes/DefaultPermissionAttribute.cs @@ -6,6 +6,7 @@ namespace Discord.Interactions /// Set the "Default Permission" property of an Application Command. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + [Obsolete($"Soon to be deprecated, use Permissions-v2 attributes like {nameof(EnabledInDmAttribute)} and {nameof(DefaultMemberPermissionsAttribute)}")] public class DefaultPermissionAttribute : Attribute { /// diff --git a/src/Discord.Net.Interactions/Attributes/EnabledInDmAttribute.cs b/src/Discord.Net.Interactions/Attributes/EnabledInDmAttribute.cs new file mode 100644 index 000000000..a97f85a25 --- /dev/null +++ b/src/Discord.Net.Interactions/Attributes/EnabledInDmAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Discord.Interactions +{ + /// + /// Sets the property of an application command or module. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class EnabledInDmAttribute : Attribute + { + /// + /// Gets whether or not this command can be used in DMs. + /// + public bool IsEnabled { get; } + + /// + /// Sets the property of an application command or module. + /// + /// Whether or not this command can be used in DMs. + public EnabledInDmAttribute(bool isEnabled) + { + IsEnabled = isEnabled; + } + } +} diff --git a/src/Discord.Net.Interactions/Builders/Commands/ContextCommandBuilder.cs b/src/Discord.Net.Interactions/Builders/Commands/ContextCommandBuilder.cs index d40547b3c..be0e5eb70 100644 --- a/src/Discord.Net.Interactions/Builders/Commands/ContextCommandBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/Commands/ContextCommandBuilder.cs @@ -17,8 +17,19 @@ namespace Discord.Interactions.Builders /// /// Gets the default permission of this command. /// + [Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")] public bool DefaultPermission { get; set; } = true; + /// + /// Gets whether this command can be used in DMs. + /// + public bool IsEnabledInDm { get; set; } = true; + + /// + /// Gets the default permissions needed for executing this command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } = null; + internal ContextCommandBuilder (ModuleBuilder module) : base(module) { } /// @@ -49,6 +60,7 @@ namespace Discord.Interactions.Builders /// /// The builder instance. /// + [Obsolete($"To be deprecated soon, use {nameof(SetEnabledInDm)} and {nameof(WithDefaultMemberPermissions)} instead.")] public ContextCommandBuilder SetDefaultPermission (bool defaultPermision) { DefaultPermission = defaultPermision; @@ -70,6 +82,32 @@ namespace Discord.Interactions.Builders return this; } + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public ContextCommandBuilder SetEnabledInDm(bool isEnabled) + { + IsEnabledInDm = isEnabled; + return this; + } + + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public ContextCommandBuilder WithDefaultMemberPermissions(GuildPermission permissions) + { + DefaultMemberPermissions = permissions; + return this; + } + internal override ContextCommandInfo Build (ModuleInfo module, InteractionService commandService) => ContextCommandInfo.Create(this, module, commandService); } diff --git a/src/Discord.Net.Interactions/Builders/Commands/SlashCommandBuilder.cs b/src/Discord.Net.Interactions/Builders/Commands/SlashCommandBuilder.cs index d8e9b0658..cd9bdfc24 100644 --- a/src/Discord.Net.Interactions/Builders/Commands/SlashCommandBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/Commands/SlashCommandBuilder.cs @@ -17,8 +17,19 @@ namespace Discord.Interactions.Builders /// /// Gets and sets the default permission of this command. /// + [Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")] public bool DefaultPermission { get; set; } = true; + /// + /// Gets whether this command can be used in DMs. + /// + public bool IsEnabledInDm { get; set; } = true; + + /// + /// Gets the default permissions needed for executing this command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } = null; + internal SlashCommandBuilder (ModuleBuilder module) : base(module) { } /// @@ -49,6 +60,7 @@ namespace Discord.Interactions.Builders /// /// The builder instance. /// + [Obsolete($"To be deprecated soon, use {nameof(SetEnabledInDm)} and {nameof(WithDefaultMemberPermissions)} instead.")] public SlashCommandBuilder WithDefaultPermission (bool permission) { DefaultPermission = permission; @@ -70,6 +82,32 @@ namespace Discord.Interactions.Builders return this; } + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public SlashCommandBuilder SetEnabledInDm(bool isEnabled) + { + IsEnabledInDm = isEnabled; + return this; + } + + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public SlashCommandBuilder WithDefaultMemberPermissions(GuildPermission permissions) + { + DefaultMemberPermissions = permissions; + return this; + } + internal override SlashCommandInfo Build (ModuleInfo module, InteractionService commandService) => new SlashCommandInfo(this, module, commandService); } diff --git a/src/Discord.Net.Interactions/Builders/ModuleBuilder.cs b/src/Discord.Net.Interactions/Builders/ModuleBuilder.cs index 40c263643..b7f00025f 100644 --- a/src/Discord.Net.Interactions/Builders/ModuleBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/ModuleBuilder.cs @@ -51,8 +51,19 @@ namespace Discord.Interactions.Builders /// /// Gets and sets the default permission of this module. /// + [Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")] public bool DefaultPermission { get; set; } = true; + /// + /// Gets whether this command can be used in DMs. + /// + public bool IsEnabledInDm { get; set; } = true; + + /// + /// Gets the default permissions needed for executing this command. + /// + public GuildPermission? DefaultMemberPermissions { get; set; } = null; + /// /// Gets and sets whether this has a . /// @@ -159,12 +170,39 @@ namespace Discord.Interactions.Builders /// /// 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. + /// + public ModuleBuilder SetEnabledInDm(bool isEnabled) + { + IsEnabledInDm = isEnabled; + return this; + } + + /// + /// Sets . + /// + /// New value of the . + /// + /// The builder instance. + /// + public ModuleBuilder WithDefaultMemberPermissions(GuildPermission permissions) + { + DefaultMemberPermissions = permissions; + return this; + } + /// /// Adds attributes to . /// diff --git a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs index b2317d1f3..1bbdfcc4a 100644 --- a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs +++ b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs @@ -85,6 +85,16 @@ namespace Discord.Interactions.Builders builder.DefaultPermission = defPermission.IsDefaultPermission; } break; + case EnabledInDmAttribute enabledInDm: + { + builder.IsEnabledInDm = enabledInDm.IsEnabled; + } + break; + case DefaultMemberPermissionsAttribute memberPermission: + { + builder.DefaultMemberPermissions = memberPermission.Permissions; + } + break; case PreconditionAttribute precondition: builder.AddPreconditions(precondition); break; @@ -169,6 +179,16 @@ namespace Discord.Interactions.Builders builder.DefaultPermission = defaultPermission.IsDefaultPermission; } break; + case EnabledInDmAttribute enabledInDm: + { + builder.IsEnabledInDm = enabledInDm.IsEnabled; + } + break; + case DefaultMemberPermissionsAttribute memberPermission: + { + builder.DefaultMemberPermissions = memberPermission.Permissions; + } + break; case PreconditionAttribute precondition: builder.WithPreconditions(precondition); break; @@ -211,6 +231,16 @@ namespace Discord.Interactions.Builders builder.DefaultPermission = defaultPermission.IsDefaultPermission; } break; + case EnabledInDmAttribute enabledInDm: + { + builder.IsEnabledInDm = enabledInDm.IsEnabled; + } + break; + case DefaultMemberPermissionsAttribute memberPermission: + { + builder.DefaultMemberPermissions = memberPermission.Permissions; + } + break; case PreconditionAttribute precondition: builder.WithPreconditions(precondition); break; diff --git a/src/Discord.Net.Interactions/Info/Commands/ContextCommands/ContextCommandInfo.cs b/src/Discord.Net.Interactions/Info/Commands/ContextCommands/ContextCommandInfo.cs index 4c2e7af7d..2d6d748d4 100644 --- a/src/Discord.Net.Interactions/Info/Commands/ContextCommands/ContextCommandInfo.cs +++ b/src/Discord.Net.Interactions/Info/Commands/ContextCommands/ContextCommandInfo.cs @@ -17,6 +17,12 @@ namespace Discord.Interactions /// public bool DefaultPermission { get; } + /// + public bool IsEnabledInDm { get; } + + /// + public GuildPermission? DefaultMemberPermissions { get; } + /// public override IReadOnlyCollection Parameters { get; } @@ -31,6 +37,8 @@ namespace Discord.Interactions { CommandType = builder.CommandType; DefaultPermission = builder.DefaultPermission; + IsEnabledInDm = builder.IsEnabledInDm; + DefaultMemberPermissions = builder.DefaultMemberPermissions; Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); } diff --git a/src/Discord.Net.Interactions/Info/Commands/SlashCommandInfo.cs b/src/Discord.Net.Interactions/Info/Commands/SlashCommandInfo.cs index a123ac183..e428144c7 100644 --- a/src/Discord.Net.Interactions/Info/Commands/SlashCommandInfo.cs +++ b/src/Discord.Net.Interactions/Info/Commands/SlashCommandInfo.cs @@ -26,6 +26,12 @@ namespace Discord.Interactions /// public bool DefaultPermission { get; } + /// + public bool IsEnabledInDm { get; } + + /// + public GuildPermission? DefaultMemberPermissions { get; } + /// public override IReadOnlyCollection Parameters { get; } @@ -41,6 +47,8 @@ namespace Discord.Interactions { Description = builder.Description; DefaultPermission = builder.DefaultPermission; + IsEnabledInDm = builder.IsEnabledInDm; + DefaultMemberPermissions = builder.DefaultMemberPermissions; Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); FlattenedParameters = FlattenParameters(Parameters).ToImmutableArray(); diff --git a/src/Discord.Net.Interactions/Info/IApplicationCommandInfo.cs b/src/Discord.Net.Interactions/Info/IApplicationCommandInfo.cs index 1e0d532b0..dd1b97899 100644 --- a/src/Discord.Net.Interactions/Info/IApplicationCommandInfo.cs +++ b/src/Discord.Net.Interactions/Info/IApplicationCommandInfo.cs @@ -1,3 +1,5 @@ +using System; + namespace Discord.Interactions { /// @@ -18,6 +20,17 @@ namespace Discord.Interactions /// /// Gets the DefaultPermission of this command. /// + [Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")] bool DefaultPermission { get; } + + /// + /// Gets whether this command can be used in DMs. + /// + public bool IsEnabledInDm { get; } + + /// + /// Gets the default permissions needed for executing this command. + /// + public GuildPermission? DefaultMemberPermissions { get; } } } diff --git a/src/Discord.Net.Interactions/Info/ModuleInfo.cs b/src/Discord.Net.Interactions/Info/ModuleInfo.cs index 321e0bfa9..904d67410 100644 --- a/src/Discord.Net.Interactions/Info/ModuleInfo.cs +++ b/src/Discord.Net.Interactions/Info/ModuleInfo.cs @@ -41,8 +41,19 @@ namespace Discord.Interactions /// /// 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 the default permissions needed for executing this command. + /// + public GuildPermission? DefaultMemberPermissions { get; } + /// /// Gets the collection of Sub Modules of this module. /// @@ -110,6 +121,8 @@ namespace Discord.Interactions Description = builder.Description; Parent = parent; DefaultPermission = builder.DefaultPermission; + IsEnabledInDm = builder.IsEnabledInDm; + DefaultMemberPermissions = BuildDefaultMemberPermissions(builder); SlashCommands = BuildSlashCommands(builder).ToImmutableArray(); ContextCommands = BuildContextCommands(builder).ToImmutableArray(); ComponentCommands = BuildComponentCommands(builder).ToImmutableArray(); @@ -226,5 +239,20 @@ namespace Discord.Interactions } 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); + parent = parent.Parent; + } + + return permissions; + } } } diff --git a/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs b/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs index c2052b7c7..60980c065 100644 --- a/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs +++ b/src/Discord.Net.Interactions/Utilities/ApplicationCommandRestUtil.cs @@ -40,7 +40,8 @@ namespace Discord.Interactions { Name = commandInfo.Name, Description = commandInfo.Description, - IsDefaultPermission = commandInfo.DefaultPermission, + IsDMEnabled = commandInfo.IsEnabledInDm, + DefaultMemberPermissions = (commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0) }.Build(); if (commandInfo.Parameters.Count > SlashCommandBuilder.MaxOptionsCount) @@ -64,8 +65,20 @@ namespace Discord.Interactions public static ApplicationCommandProperties ToApplicationCommandProps(this ContextCommandInfo commandInfo) => commandInfo.CommandType switch { - ApplicationCommandType.Message => new MessageCommandBuilder { Name = commandInfo.Name, IsDefaultPermission = commandInfo.DefaultPermission}.Build(), - ApplicationCommandType.User => new UserCommandBuilder { Name = commandInfo.Name, IsDefaultPermission=commandInfo.DefaultPermission}.Build(), + ApplicationCommandType.Message => new MessageCommandBuilder + { + Name = commandInfo.Name, + IsDefaultPermission = commandInfo.DefaultPermission, + DefaultMemberPermissions = (commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0), + IsDMEnabled = commandInfo.IsEnabledInDm + }.Build(), + ApplicationCommandType.User => new UserCommandBuilder + { + Name = commandInfo.Name, + IsDefaultPermission = commandInfo.DefaultPermission, + DefaultMemberPermissions = (commandInfo.DefaultMemberPermissions ?? 0) | (commandInfo.Module.DefaultMemberPermissions ?? 0), + IsDMEnabled = commandInfo.IsEnabledInDm + }.Build(), _ => throw new InvalidOperationException($"{commandInfo.CommandType} isn't a supported command type.") }; #endregion @@ -113,6 +126,8 @@ namespace Discord.Interactions Name = moduleInfo.SlashGroupName, Description = moduleInfo.Description, IsDefaultPermission = moduleInfo.DefaultPermission, + IsDMEnabled = moduleInfo.IsEnabledInDm, + DefaultMemberPermissions = moduleInfo.DefaultMemberPermissions }.Build(); if (options.Count > SlashCommandBuilder.MaxOptionsCount) diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs index 81598b96e..8b84149dd 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommand.cs @@ -24,5 +24,12 @@ namespace Discord.API [JsonProperty("default_permission")] public Optional DefaultPermissions { get; set; } + + // V2 Permissions + [JsonProperty("dm_permission")] + public Optional DmPermission { get; set; } + + [JsonProperty("default_member_permissions")] + public Optional DefaultMemberPermission { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs b/src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs index 82f0befcd..7ae8718b6 100644 --- a/src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs +++ b/src/Discord.Net.Rest/API/Rest/CreateApplicationCommandParams.cs @@ -19,6 +19,12 @@ namespace Discord.API.Rest [JsonProperty("default_permission")] public Optional DefaultPermission { get; set; } + [JsonProperty("dm_permission")] + public Optional DmPermission { get; set; } + + [JsonProperty("default_member_permissions")] + public Optional DefaultMemberPermission { get; set; } + public CreateApplicationCommandParams() { } public CreateApplicationCommandParams(string name, string description, ApplicationCommandType type, ApplicationCommandOption[] options = null) { diff --git a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs index e345bfa94..74d7953ad 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs @@ -100,7 +100,12 @@ namespace Discord.Rest Type = arg.Type, DefaultPermission = arg.IsDefaultPermission.IsSpecified ? arg.IsDefaultPermission.Value - : Optional.Unspecified + : Optional.Unspecified, + + // TODO: better conversion to nullable optionals + DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(), + DmPermission = arg.IsDMEnabled.ToNullable() + }; if (arg is SlashCommandProperties slashProps) @@ -134,7 +139,11 @@ namespace Discord.Rest Type = arg.Type, DefaultPermission = arg.IsDefaultPermission.IsSpecified ? arg.IsDefaultPermission.Value - : Optional.Unspecified + : Optional.Unspecified, + + // TODO: better conversion to nullable optionals + DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(), + DmPermission = arg.IsDMEnabled.ToNullable() }; if (arg is SlashCommandProperties slashProps) @@ -171,7 +180,11 @@ namespace Discord.Rest Type = arg.Type, DefaultPermission = arg.IsDefaultPermission.IsSpecified ? arg.IsDefaultPermission.Value - : Optional.Unspecified + : Optional.Unspecified, + + // TODO: better conversion to nullable optionals + DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(), + DmPermission = arg.IsDMEnabled.ToNullable() }; if (arg is SlashCommandProperties slashProps) @@ -285,7 +298,11 @@ namespace Discord.Rest Type = arg.Type, DefaultPermission = arg.IsDefaultPermission.IsSpecified ? arg.IsDefaultPermission.Value - : Optional.Unspecified + : Optional.Unspecified, + + // TODO: better conversion to nullable optionals + DefaultMemberPermission = arg.DefaultMemberPermissions.ToNullable(), + DmPermission = arg.IsDMEnabled.ToNullable() }; if (arg is SlashCommandProperties slashProps) diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs index ea8d5bc42..9e2bab2c2 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommand.cs @@ -27,6 +27,12 @@ namespace Discord.Rest /// public bool IsDefaultPermission { get; private set; } + /// + public bool IsEnabledInDm { get; private set; } + + /// + public GuildPermissions DefaultMemberPermissions { get; private set; } + /// /// Gets a collection of options for this command. /// @@ -57,6 +63,10 @@ namespace Discord.Rest Options = model.Options.IsSpecified ? model.Options.Value.Select(RestApplicationCommandOption.Create).ToImmutableArray() : ImmutableArray.Create(); + + IsEnabledInDm = model.DmPermission.GetValueOrDefault(true).GetValueOrDefault(true); + DefaultMemberPermissions = model.DefaultMemberPermission.IsSpecified + ? new GuildPermissions((ulong)model.DefaultMemberPermission.Value) : GuildPermissions.None; } /// diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs index 36eba0cd1..40ec17f5b 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs @@ -36,6 +36,12 @@ namespace Discord.WebSocket /// public bool IsDefaultPermission { get; private set; } + /// + public bool IsEnabledInDm { get; private set; } + + /// + public GuildPermissions DefaultMemberPermissions { get; private set; } + /// /// Gets a collection of s for this command. /// @@ -86,6 +92,10 @@ namespace Discord.WebSocket Options = model.Options.IsSpecified ? model.Options.Value.Select(SocketApplicationCommandOption.Create).ToImmutableArray() : ImmutableArray.Create(); + + IsEnabledInDm = model.DmPermission.GetValueOrDefault(true).GetValueOrDefault(true); + DefaultMemberPermissions = model.DefaultMemberPermission.IsSpecified + ? new GuildPermissions((ulong)model.DefaultMemberPermission.Value) : GuildPermissions.None; } ///