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