diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index ed500784c..9d6d82a6a 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -587,7 +587,7 @@ namespace Discord { var server = GetServer(data.GuildId.Value); if (server != null) - channel = server.AddChannel(data.Id); + channel = server.AddChannel(data.Id, true); else Logger.Warning("CHANNEL_CREATE referenced an unknown guild."); } @@ -637,7 +637,7 @@ namespace Discord var server = GetServer(data.GuildId.Value); if (server != null) { - var user = server.AddUser(data.User.Id); + var user = server.AddUser(data.User.Id, true); user.Update(data); user.UpdateActivity(); Logger.Debug($"GUILD_MEMBER_ADD: {user.Path}"); @@ -695,7 +695,7 @@ namespace Discord { foreach (var memberData in data.Members) { - var user = server.AddUser(memberData.User.Id); + var user = server.AddUser(memberData.User.Id, true); user.Update(memberData); //OnUserAdded(user); } diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index 79e908dd8..3023c76e3 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -80,18 +80,20 @@ namespace Discord { get { - if (IsPrivate) - return _users.Values.Select(x => x.User); if (Client.Config.UsePermissionsCache) { - if (Type == ChannelType.Text) + if (IsPrivate) + return new User[] { Client.PrivateUser, Recipient }; + else if (Type == ChannelType.Text) return _users.Values.Where(x => x.Permissions.ReadMessages == true).Select(x => x.User); else if (Type == ChannelType.Voice) return _users.Values.Select(x => x.User).Where(x => x.VoiceChannel == this); } else { - if (Type == ChannelType.Text) + if (IsPrivate) + return new User[] { Client.PrivateUser, Recipient }; + else if (Type == ChannelType.Text) { ChannelPermissions perms = new ChannelPermissions(); return Server.Users.Where(x => @@ -111,11 +113,6 @@ namespace Discord : this(client, id) { Server = server; - if (server != null && Client.Config.UsePermissionsCache) - { - foreach (var user in server.Users) - AddUser(user); - } if (client.Config.UsePermissionsCache) _users = new ConcurrentDictionary(2, (int)(server.UserCount * 1.05)); } @@ -123,11 +120,7 @@ namespace Discord : this(client, id) { Recipient = recipient; - AddUser(client.PrivateUser); - AddUser(recipient); Type = ChannelType.Text; //Discord doesn't give us a type for private channels - if (client.Config.UsePermissionsCache) - _users = new ConcurrentDictionary(2, 2); } private Channel(DiscordClient client, ulong id) { @@ -328,7 +321,7 @@ namespace Discord public IEnumerable FindUsers(string name, bool exactMatch = false) { if (name == null) throw new ArgumentNullException(nameof(name)); - return _users.Select(x => x.Value.User).Find(name, exactMatch: exactMatch); + return Users.Find(name, exactMatch: exactMatch); } public Task SendMessage(string text) => SendMessageInternal(text, false); @@ -370,8 +363,7 @@ namespace Discord #region Permissions internal void UpdatePermissions() { - if (!Client.Config.UsePermissionsCache) - return; + if (!Client.Config.UsePermissionsCache) return; foreach (var pair in _users) { @@ -383,8 +375,7 @@ namespace Discord } internal void UpdatePermissions(User user) { - if (!Client.Config.UsePermissionsCache) - return; + if (!Client.Config.UsePermissionsCache) return; Member member; if (_users.TryGetValue(user.Id, out member)) @@ -549,8 +540,7 @@ namespace Discord } internal void RemoveUser(ulong id) { - if (!Client.Config.UsePermissionsCache) - return; + if (!Client.Config.UsePermissionsCache) return; Member ignored; _users.TryRemove(id, out ignored); @@ -579,10 +569,13 @@ namespace Discord } return null; } - - Member result; - _users.TryGetValue(id, out result); - return result.User; + else + { + Member result; + if (_users.TryGetValue(id, out result)) + return result.User; + return null; + } } #endregion diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index 7db898804..17c90cc8a 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -161,21 +161,21 @@ namespace Discord } internal void Update(ExtendedGuild model) { + Update(model as Guild); //Needs channels if (model.Channels != null) { _channels = new ConcurrentDictionary(2, (int)(model.Channels.Length * 1.05)); foreach (var subModel in model.Channels) - AddChannel(subModel.Id).Update(subModel); + AddChannel(subModel.Id, false).Update(subModel); DefaultChannel = _channels[Id]; } - Update(model as Guild); //Needs channels - if (model.Members != null) { _users = new ConcurrentDictionary(2, (int)(model.Members.Length * 1.05)); foreach (var subModel in model.Members) - AddUser(subModel.User.Id).Update(subModel); + AddUser(subModel.User.Id, false).Update(subModel); } + if (model.VoiceStates != null) { foreach (var subModel in model.VoiceStates) @@ -248,9 +248,14 @@ namespace Discord #endregion #region Channels - internal Channel AddChannel(ulong id) + internal Channel AddChannel(ulong id, bool cachePerms) { var channel = new Channel(Client, id, this); + if (cachePerms && Client.Config.UsePermissionsCache) + { + foreach (var user in Users) + channel.AddUser(user); + } Client.AddChannel(channel); return _channels.GetOrAdd(id, x => channel); } @@ -287,7 +292,7 @@ namespace Discord var request = new CreateChannelRequest(Id) { Name = name, Type = type.Value }; var response = await Client.ClientAPI.Send(request).ConfigureAwait(false); - var channel = AddChannel(response.Id); + var channel = AddChannel(response.Id, true); channel.Update(response); return channel; } @@ -439,7 +444,7 @@ namespace Discord #endregion #region Users - internal User AddUser(ulong id) + internal User AddUser(ulong id, bool cachePerms) { _userCount++; Member member = new Member(new User(Client, id, this), ServerPermissions.None); @@ -448,11 +453,14 @@ namespace Discord member.User.CurrentGame = Client.CurrentGame; member.User.Status = Client.Status; } - + if (_users.TryGetOrAdd(id, member, out member)) { - foreach (var channel in _channels) - channel.Value.AddUser(member.User); + if (cachePerms && Client.Config.UsePermissionsCache) + { + foreach (var channel in _channels) + channel.Value.AddUser(member.User); + } } return member.User; } diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index dd381d014..8c45e5dcc 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -309,13 +309,20 @@ namespace Discord #region Roles private void UpdateRoles(IEnumerable roles) { + bool updated = false; var newRoles = new Dictionary(); + + var oldRoles = _roles; if (roles != null) { foreach (var r in roles) { if (r != null) + { newRoles[r.Id] = r; + if (!oldRoles.ContainsKey(r.Id)) + updated = true; //Check for adds + } } } @@ -324,10 +331,15 @@ namespace Discord var everyone = Server.EveryoneRole; newRoles[everyone.Id] = everyone; } - _roles = newRoles; + if (oldRoles.Count != newRoles.Count) + updated = true; //Check for removes - if (Server != null) - Server.UpdatePermissions(this); + if (updated) + { + _roles = newRoles; + if (Server != null) + Server.UpdatePermissions(this); + } } public bool HasRole(Role role) {