From 1ae5ae2b9cc32a61ecf7ecf5b1f7af2cf91ea14a Mon Sep 17 00:00:00 2001 From: Joe4evr Date: Sat, 11 Apr 2020 13:38:55 +0200 Subject: [PATCH] Add cache purging methods --- .../Extensions/CollectionExtensions.cs | 4 ++-- src/Discord.Net.WebSocket/ClientState.cs | 23 +++++++++++++++++++ .../DiscordSocketClient.cs | 12 ++++++++++ .../Entities/Guilds/SocketGuild.cs | 22 ++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/Discord.Net.Core/Extensions/CollectionExtensions.cs b/src/Discord.Net.Core/Extensions/CollectionExtensions.cs index e5d6025c2..f6ba7624d 100644 --- a/src/Discord.Net.Core/Extensions/CollectionExtensions.cs +++ b/src/Discord.Net.Core/Extensions/CollectionExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -15,7 +15,7 @@ namespace Discord //public static IReadOnlyCollection ToReadOnlyCollection(this IReadOnlyDictionary source) // => new CollectionWrapper(source.Select(x => x.Value), () => source.Count); public static IReadOnlyCollection ToReadOnlyCollection(this IDictionary source) - => new CollectionWrapper(source.Select(x => x.Value), () => source.Count); + => new CollectionWrapper(source.Values, () => source.Count); public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable query, IReadOnlyCollection source) => new CollectionWrapper(query, () => source.Count); public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable query, Func countFunc) diff --git a/src/Discord.Net.WebSocket/ClientState.cs b/src/Discord.Net.WebSocket/ClientState.cs index dad185d66..f2e370d02 100644 --- a/src/Discord.Net.WebSocket/ClientState.cs +++ b/src/Discord.Net.WebSocket/ClientState.cs @@ -82,6 +82,20 @@ namespace Discord.WebSocket } return null; } + internal void PurgeAllChannels() + { + foreach (var guild in _guilds.Values) + guild.PurgeChannelCache(this); + + PurgeDMChannels(); + } + internal void PurgeDMChannels() + { + foreach (var channel in _dmChannels.Values) + _channels.TryRemove(channel.Id, out _); + + _dmChannels.Clear(); + } internal SocketGuild GetGuild(ulong id) { @@ -96,7 +110,11 @@ namespace Discord.WebSocket internal SocketGuild RemoveGuild(ulong id) { if (_guilds.TryRemove(id, out SocketGuild guild)) + { + guild.PurgeChannelCache(this); + guild.PurgeGuildUserCache(); return guild; + } return null; } @@ -116,5 +134,10 @@ namespace Discord.WebSocket return user; return null; } + internal void PurgeUsers() + { + foreach (var guild in _guilds.Values) + guild.PurgeGuildUserCache(); + } } } diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index ed142d001..8e18a92c4 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -306,6 +306,14 @@ namespace Discord.WebSocket /// public override SocketChannel GetChannel(ulong id) => State.GetChannel(id); + /// + /// Clears all cached channels from the client. + /// + public void PurgeChannelCache() => State.PurgeAllChannels(); + /// + /// Clears cached DM channels from the client. + /// + public void PurgeDMChannelCache() => State.PurgeDMChannels(); /// public override SocketUser GetUser(ulong id) @@ -313,6 +321,10 @@ namespace Discord.WebSocket /// public override SocketUser GetUser(string username, string discriminator) => State.Users.FirstOrDefault(x => x.Discriminator == discriminator && x.Username == username); + /// + /// Clears cached users from the client. + /// + public void PurgeUserCache() => State.PurgeUsers(); internal SocketGlobalUser GetOrCreateUser(ClientState state, Discord.API.User model) { return state.GetOrAddUser(model.Id, x => diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs index da9a316eb..fb0a56c24 100644 --- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -623,6 +623,13 @@ namespace Discord.WebSocket return state.RemoveChannel(id) as SocketGuildChannel; return null; } + internal void PurgeChannelCache(ClientState state) + { + foreach (var channelId in _channels) + state.RemoveChannel(channelId); + + _channels.Clear(); + } //Voice Regions /// @@ -797,6 +804,21 @@ namespace Discord.WebSocket } return null; } + internal void PurgeGuildUserCache() + { + var members = Users; + var self = CurrentUser; + _members.Clear(); + _members.TryAdd(self.Id, self); + + DownloadedMemberCount = _members.Count; + + foreach (var member in members) + { + if (member.Id != self.Id) + member.GlobalUser.RemoveRef(Discord); + } + } /// public async Task DownloadUsersAsync()