@@ -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; | |||||
} | } | ||||
} | } | ||||
} | } |