From be354f56142a3081ed512729710f8a68b1160d62 Mon Sep 17 00:00:00 2001 From: RogueException Date: Sun, 12 Jun 2016 17:02:23 -0300 Subject: [PATCH] Fixed errors when members haven't been downloaded. --- src/Discord.Net/DiscordSocketClient.cs | 8 +++ src/Discord.Net/Entities/Users/GuildUser.cs | 14 ++++- .../Entities/WebSocket/CachedGuild.cs | 57 ++++++++++++++----- .../Entities/WebSocket/CachedGuildUser.cs | 5 ++ 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/Discord.Net/DiscordSocketClient.cs b/src/Discord.Net/DiscordSocketClient.cs index 14038bdcc..13050fc96 100644 --- a/src/Discord.Net/DiscordSocketClient.cs +++ b/src/Discord.Net/DiscordSocketClient.cs @@ -825,6 +825,14 @@ namespace Discord else { guild.AddOrUpdatePresence(data); + if (data.Roles.IsSpecified) //Happens when a user we haven't seen before logs in + { + CachedGuildUser user = guild.GetUser(data.User.Id); + if (user == null) + guild.AddUser(data, DataStore); + else + user.Update(data, UpdateSource.WebSocket); + } } } else diff --git a/src/Discord.Net/Entities/Users/GuildUser.cs b/src/Discord.Net/Entities/Users/GuildUser.cs index 90e19614c..8351aa57b 100644 --- a/src/Discord.Net/Entities/Users/GuildUser.cs +++ b/src/Discord.Net/Entities/Users/GuildUser.cs @@ -37,11 +37,19 @@ namespace Discord public DiscordClient Discord => Guild.Discord; - public GuildUser(Guild guild, User user, Model model) + private GuildUser(Guild guild, User user) { Guild = guild; User = user; - + } + public GuildUser(Guild guild, User user, Model model) + : this(guild, user) + { + Update(model, UpdateSource.Creation); + } + public GuildUser(Guild guild, User user, PresenceModel model) + : this(guild, user) + { Update(model, UpdateSource.Creation); } public void Update(Model model, UpdateSource source) @@ -63,7 +71,7 @@ namespace Discord public void Update(PresenceModel model, UpdateSource source) { if (source == UpdateSource.Rest && IsAttached) return; - + if (model.Roles.IsSpecified) UpdateRoles(model.Roles.Value); } diff --git a/src/Discord.Net/Entities/WebSocket/CachedGuild.cs b/src/Discord.Net/Entities/WebSocket/CachedGuild.cs index 08c9b2d38..ed7af9e90 100644 --- a/src/Discord.Net/Entities/WebSocket/CachedGuild.cs +++ b/src/Discord.Net/Entities/WebSocket/CachedGuild.cs @@ -77,23 +77,28 @@ namespace Discord AddChannel(model.Channels[i], dataStore, channels); } _channels = channels; - - var presences = new ConcurrentDictionary(); + var members = new ConcurrentDictionary(); - if (model.Presences != null) - { - for (int i = 0; i < model.Presences.Length; i++) - AddOrUpdatePresence(model.Presences[i], presences, members); - } + var presences = new ConcurrentDictionary(); if (model.Members != null) { + DownloadedMemberCount = 0; for (int i = 0; i < model.Members.Length; i++) AddUser(model.Members[i], dataStore, members); - DownloadedMemberCount = model.Members.Length; _downloaderPromise = new TaskCompletionSource(); if (!model.Large) _downloaderPromise.SetResult(true); } + if (model.Presences != null) + { + for (int i = 0; i < model.Presences.Length; i++) + { + var presence = model.Presences[i]; + AddOrUpdatePresence(presence, presences); + if (presence.Roles.IsSpecified) + AddUser(presence, dataStore, members); //TODO: Does this ever happen? + } + } _presences = presences; _members = members; @@ -124,8 +129,7 @@ namespace Discord return Discord.DataStore.RemoveChannel(id) as ICachedGuildChannel; } - public Presence AddOrUpdatePresence(PresenceModel model, ConcurrentDictionary presences = null, - ConcurrentDictionary members = null) + public Presence AddOrUpdatePresence(PresenceModel model, ConcurrentDictionary presences = null) { var game = model.Game != null ? new Game(model.Game) : (Game?)null; var presence = new Presence(model.Status, game); @@ -194,10 +198,35 @@ namespace Discord public CachedGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary members = null) { var user = Discord.GetOrAddUser(model.User, dataStore); - var member = new CachedGuildUser(this, user, model); - (members ?? _members)[user.Id] = member; - user.AddRef(); - DownloadedMemberCount++; + members = members ?? _members; + + CachedGuildUser member; + if (members.TryGetValue(model.User.Id, out member)) + member.Update(model, UpdateSource.WebSocket); + else + { + member = new CachedGuildUser(this, user, model); + members[user.Id] = member; + user.AddRef(); + DownloadedMemberCount++; + } + return member; + } + public CachedGuildUser AddUser(PresenceModel model, DataStore dataStore, ConcurrentDictionary members = null) + { + var user = Discord.GetOrAddUser(model.User, dataStore); + members = members ?? _members; + + CachedGuildUser member; + if (members.TryGetValue(model.User.Id, out member)) + member.Update(model, UpdateSource.WebSocket); + else + { + member = new CachedGuildUser(this, user, model); + members[user.Id] = member; + user.AddRef(); + DownloadedMemberCount++; + } return member; } public CachedGuildUser GetUser(ulong id) diff --git a/src/Discord.Net/Entities/WebSocket/CachedGuildUser.cs b/src/Discord.Net/Entities/WebSocket/CachedGuildUser.cs index 104e6f1da..2a7f3326d 100644 --- a/src/Discord.Net/Entities/WebSocket/CachedGuildUser.cs +++ b/src/Discord.Net/Entities/WebSocket/CachedGuildUser.cs @@ -1,4 +1,5 @@ using Model = Discord.API.GuildMember; +using PresenceModel = Discord.API.Presence; namespace Discord { @@ -22,6 +23,10 @@ namespace Discord : base(guild, user, model) { } + public CachedGuildUser(CachedGuild guild, CachedPublicUser user, PresenceModel model) + : base(guild, user, model) + { + } public CachedGuildUser Clone() => MemberwiseClone() as CachedGuildUser; ICachedUser ICachedUser.Clone() => Clone();