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