diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs index 828847791..bf512e0ab 100644 --- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs +++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOption.cs @@ -66,6 +66,17 @@ namespace Discord /// Gets or sets whether or not this option supports autocomplete. /// public bool Autocomplete { get; set; } + + /// + /// Gets or sets the smallest number value the user can input. + /// + public double? MinValue { get; set; } + + /// + /// Gets or sets the largest number value the user can input. + /// + public double? MaxValue { get; set; } + /// /// Gets or sets the choices for string and int types for the user to pick from. /// diff --git a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs index a76abc68e..cef5b1af9 100644 --- a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs +++ b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandOption.cs @@ -32,6 +32,16 @@ namespace Discord /// bool? IsRequired { get; } + /// + /// The smallest number value the user can input. + /// + double? MinValue { get; } + + /// + /// The largest number value the user can input. + /// + double? MaxValue { get; } + /// /// Choices for string and int types for the user to pick from. /// diff --git a/src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs index c42934bcf..e6696bde4 100644 --- a/src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/Slash Commands/SlashCommandBuilder.cs @@ -155,10 +155,12 @@ namespace Discord /// The options of the option to add. /// The allowed channel types for this option. /// The choices of this option. + /// The smallest number value the user can input. + /// The largest number value the user can input. /// The current builder. public SlashCommandBuilder AddOption(string name, ApplicationCommandOptionType type, - string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, List options = null, - List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) + string description, bool? required = null, bool? isDefault = null, bool isAutocomplete = false, double? minValue = null, double? maxValue = null, + List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) { // Make sure the name matches the requirements from discord Preconditions.NotNullOrEmpty(name, nameof(name)); @@ -189,7 +191,9 @@ namespace Discord Type = type, Autocomplete = isAutocomplete, Choices = (choices ?? Array.Empty()).ToList(), - ChannelTypes = channelTypes + ChannelTypes = channelTypes, + MinValue = minValue, + MaxValue = maxValue, }; return AddOption(option); @@ -321,6 +325,16 @@ namespace Discord /// public bool Autocomplete { get; set; } + /// + /// Gets or sets the smallest number value the user can input. + /// + public double? MinValue { get; set; } + + /// + /// Gets or sets the largest number value the user can input. + /// + public double? MaxValue { get; set; } + /// /// Gets or sets the choices for string and int types for the user to pick from. /// @@ -343,6 +357,7 @@ namespace Discord public ApplicationCommandOptionProperties Build() { bool isSubType = Type == ApplicationCommandOptionType.SubCommandGroup; + bool isIntType = Type == ApplicationCommandOptionType.Integer; if (isSubType && (Options == null || !Options.Any())) throw new InvalidOperationException("SubCommands/SubCommandGroups must have at least one option"); @@ -350,6 +365,12 @@ namespace Discord if (!isSubType && Options != null && Options.Any() && Type != ApplicationCommandOptionType.SubCommand) throw new InvalidOperationException($"Cannot have options on {Type} type"); + if (isIntType && MinValue != null && MinValue % 1 != 0) + throw new InvalidOperationException("MinValue cannot have decimals on Integer command options."); + + if (isIntType && MaxValue != null && MaxValue % 1 != 0) + throw new InvalidOperationException("MaxValue cannot have decimals on Integer command options."); + return new ApplicationCommandOptionProperties { Name = Name, @@ -360,7 +381,9 @@ namespace Discord Options = Options?.Count > 0 ? Options.Select(x => x.Build()).ToList() : new List(), Choices = Choices, Autocomplete = Autocomplete, - ChannelTypes = ChannelTypes + ChannelTypes = ChannelTypes, + MinValue = MinValue, + MaxValue = MaxValue }; } @@ -376,10 +399,12 @@ namespace Discord /// The options of the option to add. /// The allowed channel types for this option. /// The choices of this option. + /// The smallest number value the user can input. + /// The largest number value the user can input. /// The current builder. public SlashCommandOptionBuilder AddOption(string name, ApplicationCommandOptionType type, - string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, List options = null, - List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) + string description, bool? required = null, bool isDefault = false, bool isAutocomplete = false, double? minValue = null, double? maxValue = null, + List options = null, List channelTypes = null, params ApplicationCommandOptionChoiceProperties[] choices) { // Make sure the name matches the requirements from discord Preconditions.NotNullOrEmpty(name, nameof(name)); @@ -407,6 +432,8 @@ namespace Discord Required = required, Default = isDefault, Autocomplete = isAutocomplete, + MinValue = minValue, + MaxValue = maxValue, Options = options, Type = type, Choices = (choices ?? Array.Empty()).ToList(), @@ -561,6 +588,28 @@ namespace Discord return this; } + /// + /// Sets the current builders min value field. + /// + /// The value to set. + /// The current builder. + public SlashCommandOptionBuilder WithMinValue(double value) + { + MinValue = value; + return this; + } + + /// + /// Sets the current builders max value field. + /// + /// The value to set. + /// The current builder. + public SlashCommandOptionBuilder WithMaxValue(double value) + { + MaxValue = value; + return this; + } + /// /// Sets the current type of this builder. /// diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs index 67fce2bb5..b282f71bb 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommandOption.cs @@ -29,6 +29,12 @@ namespace Discord.API [JsonProperty("autocomplete")] public Optional Autocomplete { get; set; } + [JsonProperty("min_value")] + public Optional MinValue { get; set; } + + [JsonProperty("max_value")] + public Optional MaxValue { get; set; } + [JsonProperty("channel_types")] public Optional ChannelTypes { get; set; } @@ -48,6 +54,8 @@ namespace Discord.API Required = cmd.IsRequired ?? Optional.Unspecified; Default = cmd.IsDefault ?? Optional.Unspecified; + MinValue = cmd.MinValue ?? Optional.Unspecified; + MaxValue = cmd.MaxValue ?? Optional.Unspecified; Name = cmd.Name; Type = cmd.Type; @@ -66,6 +74,8 @@ namespace Discord.API Required = option.Required ?? Optional.Unspecified; Default = option.Default ?? Optional.Unspecified; + MinValue = option.MinValue ?? Optional.Unspecified; + MaxValue = option.MaxValue ?? Optional.Unspecified; ChannelTypes = option.ChannelTypes?.ToArray() ?? Optional.Unspecified; diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs index 460ff872a..3aa377a27 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs @@ -26,6 +26,12 @@ namespace Discord.Rest /// public bool? IsRequired { get; private set; } + /// + public double? MinValue { get; private set; } + + /// + public double? MaxValue { get; private set; } + /// /// A collection of 's for this command. /// @@ -41,6 +47,7 @@ namespace Discord.Rest /// public IReadOnlyCollection ChannelTypes { get; private set; } + internal RestApplicationCommandOption() { } internal static RestApplicationCommandOption Create(Model model) @@ -62,6 +69,12 @@ namespace Discord.Rest if (model.Required.IsSpecified) IsRequired = model.Required.Value; + if (model.MinValue.IsSpecified) + MinValue = model.MinValue.Value; + + if (model.MaxValue.IsSpecified) + MaxValue = model.MaxValue.Value; + Options = model.Options.IsSpecified ? model.Options.Value.Select(Create).ToImmutableArray() : ImmutableArray.Create(); diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs index 8fd5f449c..a19068d48 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommandOption.cs @@ -25,6 +25,12 @@ namespace Discord.WebSocket /// public bool? IsRequired { get; private set; } + /// + public double? MinValue { get; private set; } + + /// + public double? MaxValue { get; private set; } + /// /// Choices for string and int types for the user to pick from. /// @@ -54,13 +60,13 @@ namespace Discord.WebSocket Type = model.Type; Description = model.Description; - IsDefault = model.Default.IsSpecified - ? model.Default.Value - : null; + IsDefault = model.Default.ToNullable(); + + IsRequired = model.Required.ToNullable(); + + MinValue = model.MinValue.ToNullable(); - IsRequired = model.Required.IsSpecified - ? model.Required.Value - : null; + MaxValue = model.MaxValue.ToNullable(); Choices = model.Choices.IsSpecified ? model.Choices.Value.Select(SocketApplicationCommandChoice.Create).ToImmutableArray()