| @@ -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); | |||
| } | |||
| @@ -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<ulong, Member>(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<ulong, Member>(2, 2); | |||
| } | |||
| private Channel(DiscordClient client, ulong id) | |||
| { | |||
| @@ -328,7 +321,7 @@ namespace Discord | |||
| public IEnumerable<User> 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<Message> 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 | |||
| @@ -161,21 +161,21 @@ namespace Discord | |||
| } | |||
| internal void Update(ExtendedGuild model) | |||
| { | |||
| Update(model as Guild); //Needs channels | |||
| if (model.Channels != null) | |||
| { | |||
| _channels = new ConcurrentDictionary<ulong, Channel>(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<ulong, Member>(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; | |||
| } | |||
| @@ -309,13 +309,20 @@ namespace Discord | |||
| #region Roles | |||
| private void UpdateRoles(IEnumerable<Role> roles) | |||
| { | |||
| bool updated = false; | |||
| var newRoles = new Dictionary<ulong, Role>(); | |||
| 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) | |||
| { | |||