@@ -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) | |||
{ | |||