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 1819966b3..20c97bc98 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()