| @@ -8,7 +8,7 @@ | |||
| <TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks> | |||
| <TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks> | |||
| <PackageId>Discord.Net.Labs.Core</PackageId> | |||
| <Version>2.3.9-dev</Version> | |||
| <Version>2.4.0</Version> | |||
| <Product>Discord.Net.Labs.Core</Product> | |||
| <RepositoryUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</RepositoryUrl> | |||
| <PackageIcon>Temporary.png</PackageIcon> | |||
| @@ -5023,30 +5023,30 @@ | |||
| <summary> | |||
| Adds a choice to the current option. | |||
| </summary> | |||
| <param name="Name">The name of the choice.</param> | |||
| <param name="Value">The value of the choice.</param> | |||
| <param name="name">The name of the choice.</param> | |||
| <param name="value">The value of the choice.</param> | |||
| <returns>The current builder.</returns> | |||
| </member> | |||
| <member name="M:Discord.SlashCommandOptionBuilder.AddChoice(System.String,System.String)"> | |||
| <summary> | |||
| Adds a choice to the current option. | |||
| </summary> | |||
| <param name="Name">The name of the choice.</param> | |||
| <param name="Value">The value of the choice.</param> | |||
| <param name="name">The name of the choice.</param> | |||
| <param name="value">The value of the choice.</param> | |||
| <returns>The current builder.</returns> | |||
| </member> | |||
| <member name="M:Discord.SlashCommandOptionBuilder.WithName(System.String)"> | |||
| <summary> | |||
| Sets the current builders name. | |||
| </summary> | |||
| <param name="Name">The name to set the current option builder.</param> | |||
| <param name="name">The name to set the current option builder.</param> | |||
| <returns>The current builder.</returns> | |||
| </member> | |||
| <member name="M:Discord.SlashCommandOptionBuilder.WithDescription(System.String)"> | |||
| <summary> | |||
| Sets the current builders description. | |||
| </summary> | |||
| <param name="Description">The description to set.</param> | |||
| <param name="description">The description to set.</param> | |||
| <returns>The current builder.</returns> | |||
| </member> | |||
| <member name="M:Discord.SlashCommandOptionBuilder.WithRequired(System.Boolean)"> | |||
| @@ -5067,7 +5067,7 @@ | |||
| <summary> | |||
| Sets the current type of this builder. | |||
| </summary> | |||
| <param name="Type">The type to set.</param> | |||
| <param name="type">The type to set.</param> | |||
| <returns>The current builder.</returns> | |||
| </member> | |||
| <member name="T:Discord.SlashCommandCreationProperties"> | |||
| @@ -8,6 +8,9 @@ namespace Discord.API | |||
| [JsonProperty("name")] | |||
| public string Name { get; set; } | |||
| [JsonProperty("type")] | |||
| public ApplicationCommandOptionType Type { get; set; } | |||
| [JsonProperty("value")] | |||
| public Optional<object> Value { get; set; } | |||
| @@ -1,4 +1,4 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <Import Project="../../Discord.Net.targets" /> | |||
| <Import Project="../../StyleAnalyzer.targets" /> | |||
| <PropertyGroup> | |||
| @@ -8,7 +8,7 @@ | |||
| <TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">net461;netstandard2.0;netstandard2.1</TargetFrameworks> | |||
| <TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;netstandard2.1</TargetFrameworks> | |||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
| <Version>2.3.9-dev</Version> | |||
| <Version>2.3.10</Version> | |||
| <RepositoryUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</RepositoryUrl> | |||
| <PackageProjectUrl>https://github.com/Discord-Net-Labs/Discord.Net-Labs</PackageProjectUrl> | |||
| <PackageIcon>Temporary.png</PackageIcon> | |||
| @@ -3383,6 +3383,9 @@ | |||
| The version of this interaction. | |||
| </summary> | |||
| </member> | |||
| <member name="P:Discord.WebSocket.SocketInteraction.CreatedAt"> | |||
| <inheritdoc/> | |||
| </member> | |||
| <member name="P:Discord.WebSocket.SocketInteraction.IsValidToken"> | |||
| <summary> | |||
| <see langword="true"/> if the token is valid for replying to, otherwise <see langword="false"/>. | |||
| @@ -3393,7 +3396,7 @@ | |||
| Responds to an Interaction. | |||
| <para> | |||
| If you have <see cref="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use | |||
| <see cref="!:FollowupAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/> instead. | |||
| <see cref="M:Discord.WebSocket.SocketInteraction.FollowupAsync(System.String,System.Boolean,Discord.Embed,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)"/> instead. | |||
| </para> | |||
| </summary> | |||
| <param name="text">The text of the message to be sent.</param> | |||
| @@ -18,10 +18,14 @@ namespace Discord.WebSocket | |||
| /// </summary> | |||
| public IReadOnlyCollection<SocketSlashCommandDataOption> Options { get; private set; } | |||
| internal Dictionary<ulong, SocketGuildUser> guildMembers { get; private set; } = new(); | |||
| internal Dictionary<ulong, SocketGlobalUser> users { get; private set; } = new(); | |||
| internal Dictionary<ulong, SocketChannel> channels { get; private set; } = new(); | |||
| internal Dictionary<ulong, SocketRole> roles { get; private set; } = new(); | |||
| internal Dictionary<ulong, SocketGuildUser> guildMembers { get; private set; } | |||
| = new Dictionary<ulong, SocketGuildUser>(); | |||
| internal Dictionary<ulong, SocketGlobalUser> users { get; private set; } | |||
| = new Dictionary<ulong, SocketGlobalUser>(); | |||
| internal Dictionary<ulong, SocketChannel> channels { get; private set; } | |||
| = new Dictionary<ulong, SocketChannel>(); | |||
| internal Dictionary<ulong, SocketRole> roles { get; private set; } | |||
| = new Dictionary<ulong, SocketRole>(); | |||
| private ulong? guildId; | |||
| @@ -24,14 +24,41 @@ namespace Discord.WebSocket | |||
| /// </summary> | |||
| public IReadOnlyCollection<SocketSlashCommandDataOption> Options { get; private set; } | |||
| private SocketSlashCommandData data; | |||
| internal SocketSlashCommandDataOption() { } | |||
| internal SocketSlashCommandDataOption(SocketSlashCommandData data, Model model) | |||
| { | |||
| this.Name = model.Name; | |||
| this.Value = model.Value.IsSpecified ? model.Value.Value : null; | |||
| this.Type = model.Type; | |||
| if (model.Value.IsSpecified) | |||
| { | |||
| if (ulong.TryParse($"{model.Value.Value}", out var valueId)) | |||
| { | |||
| switch (this.Type) | |||
| { | |||
| case ApplicationCommandOptionType.User: | |||
| var guildUser = data.guildMembers.FirstOrDefault(x => x.Key == valueId).Value; | |||
| if (guildUser != null) | |||
| this.Value = guildUser; | |||
| else | |||
| this.Value = data.users.FirstOrDefault(x => x.Key == valueId).Value; | |||
| break; | |||
| case ApplicationCommandOptionType.Channel: | |||
| this.Value = data.channels.FirstOrDefault(x => x.Key == valueId).Value; | |||
| break; | |||
| case ApplicationCommandOptionType.Role: | |||
| this.Value = data.roles.FirstOrDefault(x => x.Key == valueId).Value; | |||
| break; | |||
| default: | |||
| this.Value = model.Value.Value; | |||
| break; | |||
| } | |||
| } | |||
| else | |||
| this.Value = model.Value.Value; | |||
| } | |||
| this.Options = model.Options.Any() | |||
| ? model.Options.Select(x => new SocketSlashCommandDataOption(data, x)).ToImmutableArray() | |||
| @@ -46,48 +73,6 @@ namespace Discord.WebSocket | |||
| public static explicit operator string(SocketSlashCommandDataOption option) | |||
| => option.Value.ToString(); | |||
| public static explicit operator SocketChannel(SocketSlashCommandDataOption option) | |||
| { | |||
| if(ulong.TryParse(option.Value.ToString(), out ulong id)) | |||
| { | |||
| if (option.data.channels.TryGetValue(id, out var channel)) | |||
| return channel; | |||
| } | |||
| return null; | |||
| } | |||
| public static explicit operator SocketRole(SocketSlashCommandDataOption option) | |||
| { | |||
| if (ulong.TryParse(option.Value.ToString(), out ulong id)) | |||
| { | |||
| if (option.data.roles.TryGetValue(id, out var role)) | |||
| return role; | |||
| } | |||
| return null; | |||
| } | |||
| public static explicit operator SocketUser(SocketSlashCommandDataOption option) | |||
| { | |||
| if (ulong.TryParse(option.Value.ToString(), out ulong id)) | |||
| { | |||
| if (option.data.users.TryGetValue(id, out var user)) | |||
| return user; | |||
| } | |||
| return null; | |||
| } | |||
| public static explicit operator SocketGuildUser(SocketSlashCommandDataOption option) | |||
| { | |||
| if (option.Value as SocketUser is SocketGuildUser guildUser) | |||
| return guildUser; | |||
| return null; | |||
| } | |||
| IReadOnlyCollection<IApplicationCommandInteractionDataOption> IApplicationCommandInteractionDataOption.Options => this.Options; | |||
| } | |||
| } | |||
| @@ -43,7 +43,9 @@ namespace Discord.WebSocket | |||
| /// </summary> | |||
| public int Version { get; private set; } | |||
| public DateTimeOffset CreatedAt { get; } | |||
| /// <inheritdoc/> | |||
| public DateTimeOffset CreatedAt | |||
| => SnowflakeUtils.FromSnowflake(this.Id); | |||
| /// <summary> | |||
| /// <see langword="true"/> if the token is valid for replying to, otherwise <see langword="false"/>. | |||
| @@ -52,7 +54,6 @@ namespace Discord.WebSocket | |||
| => CheckToken(); | |||
| private ulong? GuildId { get; set; } | |||
| private ulong? ChannelId { get; set; } | |||
| internal SocketInteraction(DiscordSocketClient client, ulong id, ISocketMessageChannel channel) | |||
| : base(client, id) | |||
| @@ -77,7 +78,6 @@ namespace Discord.WebSocket | |||
| : null; | |||
| this.GuildId = model.GuildId.ToNullable(); | |||
| this.ChannelId = model.ChannelId.ToNullable(); | |||
| this.Token = model.Token; | |||
| this.Version = model.Version; | |||
| this.Type = model.Type; | |||
| @@ -99,7 +99,7 @@ namespace Discord.WebSocket | |||
| /// Responds to an Interaction. | |||
| /// <para> | |||
| /// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use | |||
| /// <see cref="FollowupAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/> instead. | |||
| /// <see cref="FollowupAsync(string, bool, Embed, bool, InteractionResponseType, AllowedMentions, RequestOptions, MessageComponent)"/> instead. | |||
| /// </para> | |||
| /// </summary> | |||
| /// <param name="text">The text of the message to be sent.</param> | |||
| @@ -163,7 +163,7 @@ namespace Discord.WebSocket | |||
| private bool CheckToken() | |||
| { | |||
| // Tokens last for 15 minutes according to https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction | |||
| return (DateTime.UtcNow - this.CreatedAt.UtcDateTime).TotalMinutes >= 15d; | |||
| return (DateTime.UtcNow - this.CreatedAt.UtcDateTime).TotalMinutes <= 15d; | |||
| } | |||
| } | |||
| } | |||