Browse Source

Several permission cache fixes

tags/docs-0.9
RogueException 9 years ago
parent
commit
8e519d1925
4 changed files with 53 additions and 40 deletions
  1. +3
    -3
      src/Discord.Net/DiscordClient.cs
  2. +17
    -24
      src/Discord.Net/Models/Channel.cs
  3. +18
    -10
      src/Discord.Net/Models/Server.cs
  4. +15
    -3
      src/Discord.Net/Models/User.cs

+ 3
- 3
src/Discord.Net/DiscordClient.cs View File

@@ -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);
} }


+ 17
- 24
src/Discord.Net/Models/Channel.cs View File

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




+ 18
- 10
src/Discord.Net/Models/Server.cs View File

@@ -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;
} }


+ 15
- 3
src/Discord.Net/Models/User.cs View File

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


Loading…
Cancel
Save