@@ -10,7 +10,7 @@ namespace Discord | |||||
public Members(DiscordClient client, object writerLock) | public Members(DiscordClient client, object writerLock) | ||||
: base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } | : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } | ||||
private string GetKey(string userId, string serverId) | private string GetKey(string userId, string serverId) | ||||
=> (serverId ?? "Private") + '_' + userId; | |||||
=> User.GetId(userId, serverId); | |||||
public User this[string userId, string serverId] | public User this[string userId, string serverId] | ||||
=> this[GetKey(userId, serverId)]; | => this[GetKey(userId, serverId)]; | ||||
@@ -13,7 +13,10 @@ namespace Discord | |||||
private bool _isEnabled; | private bool _isEnabled; | ||||
public Messages(DiscordClient client, object writerLock, bool isEnabled) | public Messages(DiscordClient client, object writerLock, bool isEnabled) | ||||
: base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } | |||||
: base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) | |||||
{ | |||||
_isEnabled = isEnabled; | |||||
} | |||||
public Message GetOrAdd(string id, string channelId, string userId) | public Message GetOrAdd(string id, string channelId, string userId) | ||||
{ | { | ||||
@@ -9,9 +9,8 @@ namespace Discord | |||||
{ | { | ||||
internal sealed class GlobalUser : CachedObject | internal sealed class GlobalUser : CachedObject | ||||
{ | { | ||||
private readonly ConcurrentDictionary<string, bool> _servers; | |||||
private int _refCount; | |||||
private readonly ConcurrentDictionary<string, User> _users; | |||||
/// <summary> Returns the email for this user. </summary> | /// <summary> Returns the email for this user. </summary> | ||||
/// <remarks> This field is only ever populated for the current logged in user. </remarks> | /// <remarks> This field is only ever populated for the current logged in user. </remarks> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
@@ -27,15 +26,12 @@ namespace Discord | |||||
/// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary> | /// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public IEnumerable<User> Memberships => _servers.Select(x => _client.Members[Id, x.Key]); | |||||
/// <summary> Returns a collection of all servers this user is a member of. </summary> | |||||
[JsonIgnore] | |||||
public IEnumerable<Server> Servers => _servers.Select(x => _client.Servers[x.Key]); | |||||
public IEnumerable<User> Memberships => _users.Select(x => _client.Members[Id, x.Key]); | |||||
internal GlobalUser(DiscordClient client, string id) | internal GlobalUser(DiscordClient client, string id) | ||||
: base(client, id) | : base(client, id) | ||||
{ | { | ||||
_servers = new ConcurrentDictionary<string, bool>(); | |||||
_users = new ConcurrentDictionary<string, User>(); | |||||
} | } | ||||
internal override void OnCached() { } | internal override void OnCached() { } | ||||
internal override void OnUncached() { } | internal override void OnUncached() { } | ||||
@@ -48,24 +44,14 @@ namespace Discord | |||||
IsVerified = model.IsVerified; | IsVerified = model.IsVerified; | ||||
} | } | ||||
internal void AddServer(string serverId) | |||||
{ | |||||
_servers.TryAdd(serverId, true); | |||||
} | |||||
internal bool RemoveServer(string serverId) | |||||
{ | |||||
bool ignored; | |||||
return _servers.TryRemove(serverId, out ignored); | |||||
} | |||||
internal void AddRef() | |||||
{ | |||||
Interlocked.Increment(ref _refCount); | |||||
} | |||||
internal void RemoveRef() | |||||
internal void AddUser(User user) => _users.TryAdd(user.Id, user); | |||||
internal void RemoveUser(User user) | |||||
{ | { | ||||
if (Interlocked.Decrement(ref _refCount) == 0) | |||||
_client.Users.TryRemove(Id); | |||||
if (_users.TryRemove(user.Id, out user)) | |||||
{ | |||||
if (_users.Count == 0) | |||||
_client.Users.TryRemove(Id); | |||||
} | |||||
} | } | ||||
public override string ToString() => Id; | public override string ToString() => Id; | ||||
@@ -11,12 +11,15 @@ namespace Discord | |||||
{ | { | ||||
private static readonly string[] _initialRoleIds = new string[0]; | private static readonly string[] _initialRoleIds = new string[0]; | ||||
internal static string GetId(string userId, string serverId) => (serverId ?? "Private") + '_' + userId; | |||||
private ConcurrentDictionary<string, Channel> _channels; | private ConcurrentDictionary<string, Channel> _channels; | ||||
private ConcurrentDictionary<string, ChannelPermissions> _permissions; | private ConcurrentDictionary<string, ChannelPermissions> _permissions; | ||||
private ServerPermissions _serverPermissions; | private ServerPermissions _serverPermissions; | ||||
private bool _hasRef; | |||||
private string[] _roleIds; | private string[] _roleIds; | ||||
/// <summary> Returns a unique identifier combining this user's id with its server's. </summary> | |||||
internal string UniqueId => GetId(Id, ServerId); | |||||
/// <summary> Returns the name of this user on this server. </summary> | /// <summary> Returns the name of this user on this server. </summary> | ||||
public string Name { get; private set; } | public string Name { get; private set; } | ||||
/// <summary> Returns a by-name unique identifier separating this user from others with the same name. </summary> | /// <summary> Returns a by-name unique identifier separating this user from others with the same name. </summary> | ||||
@@ -81,20 +84,13 @@ namespace Discord | |||||
internal override void OnCached() | internal override void OnCached() | ||||
{ | { | ||||
var server = Server; | var server = Server; | ||||
if (server != null) | |||||
{ | |||||
server.AddMember(this); | |||||
if (Id == _client.CurrentUserId) | |||||
server.CurrentMember = this; | |||||
} | |||||
server.AddMember(this); | |||||
if (Id == _client.CurrentUserId) | |||||
server.CurrentMember = this; | |||||
var user = GlobalUser; | var user = GlobalUser; | ||||
if (user != null) | |||||
{ | |||||
if (server == null || !server.IsVirtual) | |||||
user.AddServer(ServerId); | |||||
user.AddRef(); | |||||
_hasRef = true; | |||||
} | |||||
if (server == null || !server.IsVirtual) | |||||
user.AddUser(this); | |||||
} | } | ||||
internal override void OnUncached() | internal override void OnUncached() | ||||
{ | { | ||||
@@ -105,14 +101,9 @@ namespace Discord | |||||
if (Id == _client.CurrentUserId) | if (Id == _client.CurrentUserId) | ||||
server.CurrentMember = null; | server.CurrentMember = null; | ||||
} | } | ||||
var user = GlobalUser; | |||||
if (user != null) | |||||
{ | |||||
user.RemoveServer(ServerId); | |||||
if (_hasRef) | |||||
user.RemoveRef(); | |||||
} | |||||
_hasRef = false; | |||||
var globalUser = GlobalUser; | |||||
if (globalUser != null) | |||||
globalUser.RemoveUser(this); | |||||
} | } | ||||
public override string ToString() => Id; | public override string ToString() => Id; | ||||