From 8e19bd77ea510b7ae777f462ae832ab6d96aee95 Mon Sep 17 00:00:00 2001 From: quin lynch Date: Sat, 21 Aug 2021 00:54:06 -0300 Subject: [PATCH] Code cleanup and simplification --- .../ApplicationCommandInteractionData.cs | 4 +- src/Discord.Net.Rest/API/Net/IResolvable.cs | 14 ++ .../Discord.Net.WebSocket.xml | 56 ++++---- .../Message Commands/SocketMessageCommand.cs | 2 +- .../SocketMessageCommandData.cs | 128 ++--------------- .../User Commands/SocketUserCommand.cs | 2 +- .../User Commands/SocketUserCommandData.cs | 98 ++----------- .../Slash Commands/SocketSlashCommand.cs | 2 +- .../Slash Commands/SocketSlashCommandData.cs | 94 +----------- .../SocketSlashCommandDataOption.cs | 22 +-- .../SocketBaseCommand/SocketCommandBase.cs | 2 +- .../SocketCommandBaseData.cs | 127 +++-------------- .../SocketCommandBaseDataOption.cs | 134 ------------------ .../SocketBaseCommand/SocketResolvableData.cs | 113 +++++++++++++++ 14 files changed, 216 insertions(+), 582 deletions(-) create mode 100644 src/Discord.Net.Rest/API/Net/IResolvable.cs delete mode 100644 src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseDataOption.cs create mode 100644 src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionData.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionData.cs index ed86b0b4a..bb395df13 100644 --- a/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionData.cs +++ b/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionData.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Discord.API { - internal class ApplicationCommandInteractionData : IDiscordInteractionData + internal class ApplicationCommandInteractionData : IResolvable, IDiscordInteractionData { [JsonProperty("id")] public ulong Id { get; set; } @@ -18,7 +18,7 @@ namespace Discord.API public Optional Resolved { get; set; } [JsonProperty("type")] - public Optional Type { get; set; } + public ApplicationCommandType Type { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Net/IResolvable.cs b/src/Discord.Net.Rest/API/Net/IResolvable.cs new file mode 100644 index 000000000..fe31cd75e --- /dev/null +++ b/src/Discord.Net.Rest/API/Net/IResolvable.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord.API +{ + internal interface IResolvable + { + Optional Resolved { get; } + + } +} diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml index 485a83a61..f7137c90c 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml @@ -3617,8 +3617,16 @@ Represents the data tied with the interaction. - + + + Gets the messagte associated with this message command. + + + + + Note Not implemented for + @@ -3635,8 +3643,16 @@ Represents the data tied with the interaction. - + + + The user used to run the command + + + + + Note Not implemented for + @@ -3715,14 +3731,6 @@ Represents the data tied with the interaction. - - - - - - The 's received with this interaction. - - Represents a Websocket-based recieved by the gateway @@ -3821,7 +3829,7 @@ - Base class for User, Message, and Slash command interactions + Base class for User, Message, and Slash command interactions @@ -3843,36 +3851,22 @@ A task that represents the asynchronous operation of acknowledging the interaction. - + Represents the base data tied with the interaction. - + - + - The 's received with this interaction. + The received with this interaction. - - - Represents the base Websocket-based recieved by the gateway - - - - - - - - - - - - + - The sub command options received for this sub command group. + Represents the base data tied with the interaction. diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommand.cs index 5d8b0af43..72f040cc6 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommand.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommand.cs @@ -15,7 +15,7 @@ namespace Discord.WebSocket /// /// The data associated with this interaction. /// - new public SocketMessageCommandData Data { get; } + public new SocketMessageCommandData Data { get; } internal SocketMessageCommand(DiscordSocketClient client, Model model, ISocketMessageChannel channel) : base(client, model, channel) diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommandData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommandData.cs index 9c925c4ce..e78da223d 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommandData.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/Message Commands/SocketMessageCommandData.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; using Model = Discord.API.ApplicationCommandInteractionData; @@ -8,132 +7,29 @@ namespace Discord.WebSocket /// /// Represents the data tied with the interaction. /// - public class SocketMessageCommandData : SocketEntity, IApplicationCommandInteractionData + public class SocketMessageCommandData : SocketCommandBaseData { - /// - public string Name { get; private set; } /// - /// The message selected to run the command + /// Gets the messagte associated with this message command. /// - public SocketMessage Message { get; private set; } - - internal Dictionary guildMembers { get; private set; } - = new Dictionary(); - internal Dictionary users { get; private set; } - = new Dictionary(); - internal Dictionary channels { get; private set; } - = new Dictionary(); - internal Dictionary roles { get; private set; } - = new Dictionary(); - - IReadOnlyCollection IApplicationCommandInteractionData.Options => throw new System.NotImplementedException(); + public SocketMessage Message + => ResolvableData?.Messages.FirstOrDefault().Value; - private ulong? guildId; + /// + /// + /// Note Not implemented for + /// + public override IReadOnlyCollection Options + => throw new System.NotImplementedException(); internal SocketMessageCommandData(DiscordSocketClient client, Model model, ulong? guildId) - : base(client, model.Id) - { - this.guildId = guildId; - - if (model.Resolved.IsSpecified) - { - var guild = this.guildId.HasValue ? Discord.GetGuild(this.guildId.Value) : null; - - var resolved = model.Resolved.Value; - - if (resolved.Users.IsSpecified) - { - foreach (var user in resolved.Users.Value) - { - var socketUser = Discord.GetOrCreateUser(this.Discord.State, user.Value); - - this.users.Add(ulong.Parse(user.Key), socketUser); - } - } - - if (resolved.Channels.IsSpecified) - { - foreach (var channel in resolved.Channels.Value) - { - SocketChannel socketChannel = guild != null - ? guild.GetChannel(channel.Value.Id) - : Discord.GetChannel(channel.Value.Id); - - if (socketChannel == null) - { - var channelModel = guild != null - ? Discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() - : Discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); + : base(client, model, guildId) { } - socketChannel = guild != null - ? SocketGuildChannel.Create(guild, Discord.State, channelModel) - : (SocketChannel)SocketChannel.CreatePrivate(Discord, Discord.State, channelModel); - } - - Discord.State.AddChannel(socketChannel); - this.channels.Add(ulong.Parse(channel.Key), socketChannel); - } - } - - if (resolved.Members.IsSpecified) - { - foreach (var member in resolved.Members.Value) - { - member.Value.User = resolved.Users.Value[member.Key]; - var user = guild.AddOrUpdateUser(member.Value); - this.guildMembers.Add(ulong.Parse(member.Key), user); - } - } - - if (resolved.Roles.IsSpecified) - { - foreach (var role in resolved.Roles.Value) - { - var socketRole = guild.AddOrUpdateRole(role.Value); - this.roles.Add(ulong.Parse(role.Key), socketRole); - } - } - - if (resolved.Messages.IsSpecified) - { - foreach (var msg in resolved.Messages.Value) - { - var channel = client.GetChannel(msg.Value.ChannelId) as ISocketMessageChannel; - - SocketUser author; - if (guild != null) - { - if (msg.Value.WebhookId.IsSpecified) - author = SocketWebhookUser.Create(guild, client.State, msg.Value.Author.Value, msg.Value.WebhookId.Value); - else - author = guild.GetUser(msg.Value.Author.Value.Id); - } - else - author = (channel as SocketChannel).GetUser(msg.Value.Author.Value.Id); - - if (channel == null) - { - if (!msg.Value.GuildId.IsSpecified) // assume it is a DM - { - channel = client.CreateDMChannel(msg.Value.ChannelId, msg.Value.Author.Value, client.State); - } - } - - this.Message = SocketMessage.Create(client, client.State, author, channel, msg.Value); - } - } - } - } - - internal static SocketMessageCommandData Create(DiscordSocketClient client, Model model, ulong id, ulong? guildId) + internal new static SocketMessageCommandData Create(DiscordSocketClient client, Model model, ulong id, ulong? guildId) { var entity = new SocketMessageCommandData(client, model, guildId); entity.Update(model); return entity; } - internal void Update(Model model) - { - this.Name = model.Name; - } } } diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommand.cs index f4c3a8b7b..5345c08f7 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommand.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommand.cs @@ -15,7 +15,7 @@ namespace Discord.WebSocket /// /// The data associated with this interaction. /// - new public SocketUserCommandData Data { get; } + public new SocketUserCommandData Data { get; } internal SocketUserCommand(DiscordSocketClient client, Model model, ISocketMessageChannel channel) : base(client, model, channel) diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommandData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommandData.cs index 1cdfed097..70eb4adff 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommandData.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Context Menu Commands/User Commands/SocketUserCommandData.cs @@ -1,6 +1,4 @@ using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; using Model = Discord.API.ApplicationCommandInteractionData; namespace Discord.WebSocket @@ -8,104 +6,28 @@ namespace Discord.WebSocket /// /// Represents the data tied with the interaction. /// - public class SocketUserCommandData : SocketEntity, IApplicationCommandInteractionData + public class SocketUserCommandData : SocketCommandBaseData { - /// - public string Name { get; private set; } /// - /// The user used to run the command + /// The user used to run the command /// public SocketUser Member { get; private set; } - internal Dictionary guildMembers { get; private set; } - = new Dictionary(); - internal Dictionary users { get; private set; } - = new Dictionary(); - internal Dictionary channels { get; private set; } - = new Dictionary(); - internal Dictionary roles { get; private set; } - = new Dictionary(); - - IReadOnlyCollection IApplicationCommandInteractionData.Options => throw new System.NotImplementedException(); - - private ulong? guildId; + /// + /// + /// Note Not implemented for + /// + public override IReadOnlyCollection Options + => throw new System.NotImplementedException(); internal SocketUserCommandData(DiscordSocketClient client, Model model, ulong? guildId) - : base(client, model.Id) - { - this.guildId = guildId; - - if (model.Resolved.IsSpecified) - { - var guild = this.guildId.HasValue ? Discord.GetGuild(this.guildId.Value) : null; - - var resolved = model.Resolved.Value; - - if (resolved.Users.IsSpecified) - { - foreach (var user in resolved.Users.Value) - { - var socketUser = Discord.GetOrCreateUser(this.Discord.State, user.Value); - - this.users.Add(ulong.Parse(user.Key), socketUser); - } - } + : base(client, model, guildId) { } - if (resolved.Channels.IsSpecified) - { - foreach (var channel in resolved.Channels.Value) - { - SocketChannel socketChannel = guild != null - ? guild.GetChannel(channel.Value.Id) - : Discord.GetChannel(channel.Value.Id); - - if (socketChannel == null) - { - var channelModel = guild != null - ? Discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() - : Discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); - - socketChannel = guild != null - ? SocketGuildChannel.Create(guild, Discord.State, channelModel) - : (SocketChannel)SocketChannel.CreatePrivate(Discord, Discord.State, channelModel); - } - - Discord.State.AddChannel(socketChannel); - this.channels.Add(ulong.Parse(channel.Key), socketChannel); - } - } - - if (resolved.Members.IsSpecified) - { - foreach (var member in resolved.Members.Value) - { - member.Value.User = resolved.Users.Value[member.Key]; - var user = guild.AddOrUpdateUser(member.Value); - this.guildMembers.Add(ulong.Parse(member.Key), user); - this.Member = user; - } - } - - if (resolved.Roles.IsSpecified) - { - foreach (var role in resolved.Roles.Value) - { - var socketRole = guild.AddOrUpdateRole(role.Value); - this.roles.Add(ulong.Parse(role.Key), socketRole); - } - } - } - } - - internal static SocketUserCommandData Create(DiscordSocketClient client, Model model, ulong id, ulong? guildId) + internal new static SocketUserCommandData Create(DiscordSocketClient client, Model model, ulong id, ulong? guildId) { var entity = new SocketUserCommandData(client, model, guildId); entity.Update(model); return entity; } - internal void Update(Model model) - { - this.Name = model.Name; - } } } diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs index 36542f15a..05c051f12 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs @@ -28,7 +28,7 @@ namespace Discord.WebSocket if (this.Channel is SocketGuildChannel guildChannel) guildId = guildChannel.Guild.Id; - Data = SocketSlashCommandData.Create(client, dataModel, model.Id, guildId); + Data = SocketSlashCommandData.Create(client, dataModel, guildId); } new internal static SocketInteraction Create(DiscordSocketClient client, Model model, ISocketMessageChannel channel) diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandData.cs index 6ed77b997..4b6764bf7 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandData.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandData.cs @@ -8,108 +8,24 @@ namespace Discord.WebSocket /// /// Represents the data tied with the interaction. /// - public class SocketSlashCommandData : SocketEntity, IApplicationCommandInteractionData + public class SocketSlashCommandData : SocketCommandBaseData { - /// - public string Name { get; private set; } - - /// - /// The 's received with this interaction. - /// - public IReadOnlyCollection Options { get; private set; } - - internal Dictionary guildMembers { get; private set; } - = new Dictionary(); - internal Dictionary users { get; private set; } - = new Dictionary(); - internal Dictionary channels { get; private set; } - = new Dictionary(); - internal Dictionary roles { get; private set; } - = new Dictionary(); - - private ulong? guildId; - internal SocketSlashCommandData(DiscordSocketClient client, Model model, ulong? guildId) - : base(client, model.Id) - { - this.guildId = guildId; - - if (model.Resolved.IsSpecified) - { - var guild = this.guildId.HasValue ? Discord.GetGuild(this.guildId.Value) : null; - - var resolved = model.Resolved.Value; - - if (resolved.Users.IsSpecified) - { - foreach (var user in resolved.Users.Value) - { - var socketUser = Discord.GetOrCreateUser(this.Discord.State, user.Value); - - this.users.Add(ulong.Parse(user.Key), socketUser); - } - } + : base(client, model, guildId) { } - if (resolved.Channels.IsSpecified) - { - foreach (var channel in resolved.Channels.Value) - { - SocketChannel socketChannel = guild != null - ? guild.GetChannel(channel.Value.Id) - : Discord.GetChannel(channel.Value.Id); - - if (socketChannel == null) - { - var channelModel = guild != null - ? Discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() - : Discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); - - socketChannel = guild != null - ? SocketGuildChannel.Create(guild, Discord.State, channelModel) - : (SocketChannel)SocketChannel.CreatePrivate(Discord, Discord.State, channelModel); - } - - Discord.State.AddChannel(socketChannel); - this.channels.Add(ulong.Parse(channel.Key), socketChannel); - } - } - - if (resolved.Members.IsSpecified) - { - foreach (var member in resolved.Members.Value) - { - member.Value.User = resolved.Users.Value[member.Key]; - var user = guild.AddOrUpdateUser(member.Value); - this.guildMembers.Add(ulong.Parse(member.Key), user); - } - } - - if (resolved.Roles.IsSpecified) - { - foreach (var role in resolved.Roles.Value) - { - var socketRole = guild.AddOrUpdateRole(role.Value); - this.roles.Add(ulong.Parse(role.Key), socketRole); - } - } - } - } - - internal static SocketSlashCommandData Create(DiscordSocketClient client, Model model, ulong id, ulong? guildId) + internal static SocketSlashCommandData Create(DiscordSocketClient client, Model model, ulong? guildId) { var entity = new SocketSlashCommandData(client, model, guildId); entity.Update(model); return entity; } - internal void Update(Model model) + internal override void Update(Model model) { - this.Name = model.Name; + base.Update(model); this.Options = model.Options.IsSpecified ? model.Options.Value.Select(x => new SocketSlashCommandDataOption(this, x)).ToImmutableArray() : null; } - - IReadOnlyCollection IApplicationCommandInteractionData.Options => Options; } } diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs index f9c12257e..a79a9724c 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs @@ -44,34 +44,34 @@ namespace Discord.WebSocket { case ApplicationCommandOptionType.User: { - var guildUser = data.guildMembers.FirstOrDefault(x => x.Key == valueId).Value; + var guildUser = data.ResolvableData.GuildMembers.FirstOrDefault(x => x.Key == valueId).Value; if (guildUser != null) this.Value = guildUser; else - this.Value = data.users.FirstOrDefault(x => x.Key == valueId).Value; + this.Value = data.ResolvableData.Users.FirstOrDefault(x => x.Key == valueId).Value; } break; case ApplicationCommandOptionType.Channel: - this.Value = data.channels.FirstOrDefault(x => x.Key == valueId).Value; + this.Value = data.ResolvableData.Channels.FirstOrDefault(x => x.Key == valueId).Value; break; case ApplicationCommandOptionType.Role: - this.Value = data.roles.FirstOrDefault(x => x.Key == valueId).Value; + this.Value = data.ResolvableData.Roles.FirstOrDefault(x => x.Key == valueId).Value; break; case ApplicationCommandOptionType.Mentionable: { - if(data.guildMembers.Any(x => x.Key == valueId) || data.users.Any(x => x.Key == valueId)) + if(data.ResolvableData.GuildMembers.Any(x => x.Key == valueId) || data.ResolvableData.Users.Any(x => x.Key == valueId)) { - var guildUser = data.guildMembers.FirstOrDefault(x => x.Key == valueId).Value; + var guildUser = data.ResolvableData.GuildMembers.FirstOrDefault(x => x.Key == valueId).Value; if (guildUser != null) this.Value = guildUser; else - this.Value = data.users.FirstOrDefault(x => x.Key == valueId).Value; + this.Value = data.ResolvableData.Users.FirstOrDefault(x => x.Key == valueId).Value; } - else if(data.roles.Any(x => x.Key == valueId)) + else if(data.ResolvableData.Roles.Any(x => x.Key == valueId)) { - this.Value = data.roles.FirstOrDefault(x => x.Key == valueId).Value; + this.Value = data.ResolvableData.Roles.FirstOrDefault(x => x.Key == valueId).Value; } } break; @@ -125,6 +125,8 @@ namespace Discord.WebSocket public static explicit operator string(SocketSlashCommandDataOption option) => option.Value.ToString(); - IReadOnlyCollection IApplicationCommandInteractionDataOption.Options => this.Options; + // IApplicationCommandInteractionDataOption + IReadOnlyCollection IApplicationCommandInteractionDataOption.Options + => this.Options; } } diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs index 6ba9ba05a..7c8e2422e 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs @@ -10,7 +10,7 @@ using Model = Discord.API.Interaction; namespace Discord.WebSocket { /// - /// Base class for User, Message, and Slash command interactions + /// Base class for User, Message, and Slash command interactions /// public class SocketCommandBase : SocketInteraction { diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseData.cs index dde981eb9..64aeb5d24 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseData.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseData.cs @@ -8,123 +8,28 @@ namespace Discord.WebSocket /// /// Represents the base data tied with the interaction. /// - public class SocketCommandBaseData : SocketEntity, IApplicationCommandInteractionData + public class SocketCommandBaseData : SocketEntity, IApplicationCommandInteractionData where TOption : IApplicationCommandInteractionDataOption { /// public string Name { get; private set; } + /// - /// The 's received with this interaction. + /// The received with this interaction. /// - public IReadOnlyCollection Options { get; private set; } - internal Dictionary guildMembers { get; private set; } - = new Dictionary(); - internal Dictionary users { get; private set; } - = new Dictionary(); - internal Dictionary channels { get; private set; } - = new Dictionary(); - internal Dictionary roles { get; private set; } - = new Dictionary(); - - private ulong? guildId; + public virtual IReadOnlyCollection Options { get; internal set; } - internal SocketMessage Message { get; private set; } + internal readonly SocketResolvableData ResolvableData; private ApplicationCommandType Type { get; set; } internal SocketCommandBaseData(DiscordSocketClient client, Model model, ulong? guildId) : base(client, model.Id) { - this.guildId = guildId; - - this.Type = (ApplicationCommandType)model.Type; + this.Type = model.Type; if (model.Resolved.IsSpecified) { - var guild = this.guildId.HasValue ? Discord.GetGuild(this.guildId.Value) : null; - - var resolved = model.Resolved.Value; - - if (resolved.Users.IsSpecified) - { - foreach (var user in resolved.Users.Value) - { - var socketUser = Discord.GetOrCreateUser(this.Discord.State, user.Value); - - this.users.Add(ulong.Parse(user.Key), socketUser); - } - } - - if (resolved.Channels.IsSpecified) - { - foreach (var channel in resolved.Channels.Value) - { - SocketChannel socketChannel = guild != null - ? guild.GetChannel(channel.Value.Id) - : Discord.GetChannel(channel.Value.Id); - - if (socketChannel == null) - { - var channelModel = guild != null - ? Discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() - : Discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); - - socketChannel = guild != null - ? SocketGuildChannel.Create(guild, Discord.State, channelModel) - : (SocketChannel)SocketChannel.CreatePrivate(Discord, Discord.State, channelModel); - } - - Discord.State.AddChannel(socketChannel); - this.channels.Add(ulong.Parse(channel.Key), socketChannel); - } - } - - if (resolved.Members.IsSpecified) - { - foreach (var member in resolved.Members.Value) - { - member.Value.User = resolved.Users.Value[member.Key]; - var user = guild.AddOrUpdateUser(member.Value); - this.guildMembers.Add(ulong.Parse(member.Key), user); - } - } - - if (resolved.Roles.IsSpecified) - { - foreach (var role in resolved.Roles.Value) - { - var socketRole = guild.AddOrUpdateRole(role.Value); - this.roles.Add(ulong.Parse(role.Key), socketRole); - } - } - - if (resolved.Messages.IsSpecified) - { - foreach (var msg in resolved.Messages.Value) - { - var channel = client.GetChannel(msg.Value.ChannelId) as ISocketMessageChannel; - - SocketUser author; - if (guild != null) - { - if (msg.Value.WebhookId.IsSpecified) - author = SocketWebhookUser.Create(guild, client.State, msg.Value.Author.Value, msg.Value.WebhookId.Value); - else - author = guild.GetUser(msg.Value.Author.Value.Id); - } - else - author = (channel as SocketChannel).GetUser(msg.Value.Author.Value.Id); - - if (channel == null) - { - if (!msg.Value.GuildId.IsSpecified) // assume it is a DM - { - channel = client.CreateDMChannel(msg.Value.ChannelId, msg.Value.Author.Value, client.State); - } - } - - this.Message = SocketMessage.Create(client, client.State, author, channel, msg.Value); - } - } + ResolvableData = new SocketResolvableData(client, guildId, model); } } @@ -135,15 +40,21 @@ namespace Discord.WebSocket return entity; } - internal void Update(Model model) + internal virtual void Update(Model model) { this.Name = model.Name; - - this.Options = model.Options.IsSpecified - ? model.Options.Value.Select(x => new SocketCommandBaseDataOption(this, x)).ToImmutableArray() - : null; } - IReadOnlyCollection IApplicationCommandInteractionData.Options => Options; + IReadOnlyCollection IApplicationCommandInteractionData.Options + => (IReadOnlyCollection)Options; + } + + /// + /// Represents the base data tied with the interaction. + /// + public class SocketCommandBaseData : SocketCommandBaseData + { + internal SocketCommandBaseData(DiscordSocketClient client, Model model, ulong? guildId) + : base(client, model, guildId) { } } } diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseDataOption.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseDataOption.cs deleted file mode 100644 index 6aa15978e..000000000 --- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBaseDataOption.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Model = Discord.API.ApplicationCommandInteractionDataOption; - -namespace Discord.WebSocket -{ - /// - /// Represents the base Websocket-based recieved by the gateway - /// - public class SocketCommandBaseDataOption : IApplicationCommandInteractionDataOption - { - /// - public string Name { get; private set; } - - /// - public object Value { get; private set; } - - /// - public ApplicationCommandOptionType Type { get; private set; } - - /// - /// The sub command options received for this sub command group. - /// - public IReadOnlyCollection Options { get; private set; } - - internal SocketCommandBaseDataOption() { } - internal SocketCommandBaseDataOption(SocketCommandBaseData data, Model model) - { - this.Name = model.Name; - this.Type = model.Type; - - if (model.Value.IsSpecified) - { - switch (Type) - { - case ApplicationCommandOptionType.User: - case ApplicationCommandOptionType.Role: - case ApplicationCommandOptionType.Channel: - case ApplicationCommandOptionType.Mentionable: - 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; - case ApplicationCommandOptionType.Mentionable: - { - if (data.guildMembers.Any(x => x.Key == valueId) || data.users.Any(x => x.Key == valueId)) - { - 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; - } - else if (data.roles.Any(x => x.Key == valueId)) - { - this.Value = data.roles.FirstOrDefault(x => x.Key == valueId).Value; - } - } - break; - default: - this.Value = model.Value.Value; - break; - } - } - break; - case ApplicationCommandOptionType.String: - this.Value = model.Value.ToString(); - break; - case ApplicationCommandOptionType.Integer: - { - if (model.Value.Value is int val) - this.Value = val; - else if (int.TryParse(model.Value.Value.ToString(), out int res)) - this.Value = res; - } - break; - case ApplicationCommandOptionType.Boolean: - { - if (model.Value.Value is bool val) - this.Value = val; - else if (bool.TryParse(model.Value.Value.ToString(), out bool res)) - this.Value = res; - } - break; - case ApplicationCommandOptionType.Number: - { - if (model.Value.Value is int val) - this.Value = val; - else if (double.TryParse(model.Value.Value.ToString(), out double res)) - this.Value = res; - } - break; - } - - } - - this.Options = model.Options.IsSpecified - ? model.Options.Value.Select(x => new SocketCommandBaseDataOption(data, x)).ToImmutableArray() - : null; - } - - // Converters - public static explicit operator bool(SocketCommandBaseDataOption option) - => (bool)option.Value; - public static explicit operator int(SocketCommandBaseDataOption option) - => (int)option.Value; - public static explicit operator string(SocketCommandBaseDataOption option) - => option.Value.ToString(); - - IReadOnlyCollection IApplicationCommandInteractionDataOption.Options => this.Options; - } -} diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs new file mode 100644 index 000000000..17c96724c --- /dev/null +++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord.WebSocket +{ + internal class SocketResolvableData where T : API.IResolvable + { + internal readonly Dictionary GuildMembers + = new Dictionary(); + internal readonly Dictionary Users + = new Dictionary(); + internal readonly Dictionary Channels + = new Dictionary(); + internal readonly Dictionary Roles + = new Dictionary(); + + internal readonly Dictionary Messages + = new Dictionary(); + + internal SocketResolvableData(DiscordSocketClient discord, ulong? guildId, T model) + { + var guild = guildId.HasValue ? discord.GetGuild(guildId.Value) : null; + + var resolved = model.Resolved.Value; + + if (resolved.Users.IsSpecified) + { + foreach (var user in resolved.Users.Value) + { + var socketUser = discord.GetOrCreateUser(discord.State, user.Value); + + this.Users.Add(ulong.Parse(user.Key), socketUser); + } + } + + if (resolved.Channels.IsSpecified) + { + foreach (var channel in resolved.Channels.Value) + { + SocketChannel socketChannel = guild != null + ? guild.GetChannel(channel.Value.Id) + : discord.GetChannel(channel.Value.Id); + + if (socketChannel == null) + { + var channelModel = guild != null + ? discord.Rest.ApiClient.GetChannelAsync(guild.Id, channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult() + : discord.Rest.ApiClient.GetChannelAsync(channel.Value.Id).ConfigureAwait(false).GetAwaiter().GetResult(); + + socketChannel = guild != null + ? SocketGuildChannel.Create(guild, discord.State, channelModel) + : (SocketChannel)SocketChannel.CreatePrivate(discord, discord.State, channelModel); + } + + discord.State.AddChannel(socketChannel); + this.Channels.Add(ulong.Parse(channel.Key), socketChannel); + } + } + + if (resolved.Members.IsSpecified) + { + foreach (var member in resolved.Members.Value) + { + member.Value.User = resolved.Users.Value[member.Key]; + var user = guild.AddOrUpdateUser(member.Value); + this.GuildMembers.Add(ulong.Parse(member.Key), user); + } + } + + if (resolved.Roles.IsSpecified) + { + foreach (var role in resolved.Roles.Value) + { + var socketRole = guild.AddOrUpdateRole(role.Value); + this.Roles.Add(ulong.Parse(role.Key), socketRole); + } + } + + if (resolved.Messages.IsSpecified) + { + foreach (var msg in resolved.Messages.Value) + { + var channel = discord.GetChannel(msg.Value.ChannelId) as ISocketMessageChannel; + + SocketUser author; + if (guild != null) + { + if (msg.Value.WebhookId.IsSpecified) + author = SocketWebhookUser.Create(guild, discord.State, msg.Value.Author.Value, msg.Value.WebhookId.Value); + else + author = guild.GetUser(msg.Value.Author.Value.Id); + } + else + author = (channel as SocketChannel).GetUser(msg.Value.Author.Value.Id); + + if (channel == null) + { + if (!msg.Value.GuildId.IsSpecified) // assume it is a DM + { + channel = discord.CreateDMChannel(msg.Value.ChannelId, msg.Value.Author.Value, discord.State); + } + } + + var message = SocketMessage.Create(discord, discord.State, author, channel, msg.Value); + this.Messages.Add(message.Id, message); + } + } + } + } +}