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