From d7937f2df043b2adfd4b3a5f605f8911c5ea31f6 Mon Sep 17 00:00:00 2001 From: Adam Gauthier Date: Sun, 12 Sep 2021 02:08:45 -0400 Subject: [PATCH] Cache unknown thread channel on THREAD_UPDATE (#136) In the case where a thread is archived upon login, the thread channel is not cached by the client. When the thread channel is unarchived, the library simply outputs an unknown channel warning. When messages are sent in the unarchived thread, the library won't have it cached and will only output warnings. This change makes it so the channel is cached when unarchived and ThreadUpdated is invoked with an non specified "before" parameter. From that point, the channel will be available for future events. --- .../BaseSocketClient.Events.cs | 4 +-- .../DiscordSocketClient.cs | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs index 1cd35768d..fe13d327e 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs @@ -603,13 +603,13 @@ namespace Discord.WebSocket /// /// Fired when a thread is updated within a guild. /// - public event Func ThreadUpdated + public event Func, SocketThreadChannel, Task> ThreadUpdated { add { _threadUpdated.Add(value); } remove { _threadUpdated.Remove(value); } } - internal readonly AsyncEvent> _threadUpdated = new AsyncEvent>(); + internal readonly AsyncEvent, SocketThreadChannel, Task>> _threadUpdated = new(); /// /// Fired when a thread is deleted. diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index b79eeb099..007e9f68a 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -2243,16 +2243,25 @@ namespace Discord.WebSocket return; } - var channel = (SocketThreadChannel)guild.GetChannel(data.Id); + var threadChannel = guild.ThreadChannels.FirstOrDefault(x => x.Id == data.Id); + var before = threadChannel != null + ? new Cacheable(threadChannel.Clone(), data.Id, true, () => Task.FromResult((SocketThreadChannel)null)) + : new Cacheable(null, data.Id, false, () => Task.FromResult((SocketThreadChannel)null)); - if (channel == null) + if (threadChannel != null) { - await UnknownChannelAsync(type, data.Id); - return; - } + threadChannel.Update(State, data); - var before = channel.Clone(); - channel.Update(State, data); + if (data.ThreadMember.IsSpecified) + threadChannel.AddOrUpdateThreadMember(data.ThreadMember.Value, guild.CurrentUser); + } + else + { + // Thread is updated but was not cached, likely meaning the thread was unarchived. + threadChannel = (SocketThreadChannel)guild.AddChannel(State, data); + if (data.ThreadMember.IsSpecified) + threadChannel.AddOrUpdateThreadMember(data.ThreadMember.Value, guild.CurrentUser); + } if (!(guild?.IsSynced ?? true)) { @@ -2260,7 +2269,7 @@ namespace Discord.WebSocket return; } - await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, channel).ConfigureAwait(false); + await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, threadChannel).ConfigureAwait(false); } break; case "THREAD_DELETE":