| @@ -10,7 +10,7 @@ namespace Discord | |||
| public Members(DiscordClient client, object writerLock) | |||
| : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } | |||
| private string GetKey(string userId, string serverId) | |||
| => (serverId ?? "Private") + '_' + userId; | |||
| => User.GetId(userId, serverId); | |||
| public User this[string userId, string serverId] | |||
| => this[GetKey(userId, serverId)]; | |||
| @@ -13,7 +13,10 @@ namespace Discord | |||
| private 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) | |||
| { | |||
| @@ -9,9 +9,8 @@ namespace Discord | |||
| { | |||
| 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> | |||
| /// <remarks> This field is only ever populated for the current logged in user. </remarks> | |||
| [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> | |||
| [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) | |||
| : base(client, id) | |||
| { | |||
| _servers = new ConcurrentDictionary<string, bool>(); | |||
| _users = new ConcurrentDictionary<string, User>(); | |||
| } | |||
| internal override void OnCached() { } | |||
| internal override void OnUncached() { } | |||
| @@ -48,24 +44,14 @@ namespace Discord | |||
| 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; | |||
| @@ -11,12 +11,15 @@ namespace Discord | |||
| { | |||
| 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, ChannelPermissions> _permissions; | |||
| private ServerPermissions _serverPermissions; | |||
| private bool _hasRef; | |||
| 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> | |||
| public string Name { get; private set; } | |||
| /// <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() | |||
| { | |||
| 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; | |||
| 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() | |||
| { | |||
| @@ -105,14 +101,9 @@ namespace Discord | |||
| if (Id == _client.CurrentUserId) | |||
| 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; | |||