@@ -223,6 +223,9 @@ | |||||
<Compile Include="..\Discord.Net\Helpers\Mention.cs"> | <Compile Include="..\Discord.Net\Helpers\Mention.cs"> | ||||
<Link>Helpers\Mention.cs</Link> | <Link>Helpers\Mention.cs</Link> | ||||
</Compile> | </Compile> | ||||
<Compile Include="..\Discord.Net\Helpers\Reference.cs"> | |||||
<Link>Helpers\Reference.cs</Link> | |||||
</Compile> | |||||
<Compile Include="..\Discord.Net\Helpers\TaskHelper.cs"> | <Compile Include="..\Discord.Net\Helpers\TaskHelper.cs"> | ||||
<Link>Helpers\TaskHelper.cs</Link> | <Link>Helpers\TaskHelper.cs</Link> | ||||
</Compile> | </Compile> | ||||
@@ -0,0 +1,68 @@ | |||||
using System; | |||||
namespace Discord | |||||
{ | |||||
internal class Reference<T> | |||||
where T : CachedObject | |||||
{ | |||||
private Action<T> _onCache, _onUncache; | |||||
private Func<string, T> _getItem; | |||||
private string _id; | |||||
public string Id | |||||
{ | |||||
get { return _id; } | |||||
set | |||||
{ | |||||
_id = value; | |||||
_value = null; | |||||
} | |||||
} | |||||
private T _value; | |||||
public T Value | |||||
{ | |||||
get | |||||
{ | |||||
var v = _value; //A little trickery to make this threadsafe | |||||
if (v != null && !_value.IsCached) | |||||
{ | |||||
v = null; | |||||
_value = null; | |||||
} | |||||
if (v == null && _id != null) | |||||
{ | |||||
v = _getItem(_id); | |||||
if (v != null) | |||||
_onCache(v); | |||||
_value = v; | |||||
} | |||||
return v; | |||||
} | |||||
} | |||||
public T Load() | |||||
{ | |||||
return Value; //Used for precaching | |||||
} | |||||
public void Unload() | |||||
{ | |||||
if (_onUncache != null) | |||||
{ | |||||
var v = _value; | |||||
if (v != null && _onUncache != null) | |||||
_onUncache(v); | |||||
} | |||||
} | |||||
public Reference(Func<string, T> onUpdate, Action<T> onCache = null, Action<T> onUncache = null) | |||||
: this(null, onUpdate, onCache, onUncache) { } | |||||
public Reference(string id, Func<string, T> getItem, Action<T> onCache = null, Action<T> onUncache = null) | |||||
{ | |||||
_id = id; | |||||
_getItem = getItem; | |||||
_onCache = onCache; | |||||
_onUncache = onUncache; | |||||
} | |||||
} | |||||
} |
@@ -5,6 +5,8 @@ | |||||
protected readonly DiscordClient _client; | protected readonly DiscordClient _client; | ||||
private bool _isCached; | private bool _isCached; | ||||
internal bool IsCached => _isCached; | |||||
internal CachedObject(DiscordClient client, string id) | internal CachedObject(DiscordClient client, string id) | ||||
{ | { | ||||
_client = client; | _client = client; | ||||
@@ -18,18 +20,18 @@ | |||||
internal void Cache() | internal void Cache() | ||||
{ | { | ||||
OnCached(); | |||||
LoadReferences(); | |||||
_isCached = true; | _isCached = true; | ||||
} | } | ||||
internal void Uncache() | internal void Uncache() | ||||
{ | { | ||||
if (_isCached) | if (_isCached) | ||||
{ | { | ||||
OnUncached(); | |||||
UnloadReferences(); | |||||
_isCached = false; | _isCached = false; | ||||
} | } | ||||
} | } | ||||
internal abstract void OnCached(); | |||||
internal abstract void OnUncached(); | |||||
internal abstract void LoadReferences(); | |||||
internal abstract void UnloadReferences(); | |||||
} | } | ||||
} | } |
@@ -33,19 +33,19 @@ namespace Discord | |||||
/// <summary> Returns the position of this channel in the channel list for this server. </summary> | /// <summary> Returns the position of this channel in the channel list for this server. </summary> | ||||
public int Position { get; private set; } | public int Position { get; private set; } | ||||
/// <summary> Returns false is this is a public chat and true if this is a private chat with another user (see Recipient). </summary> | /// <summary> Returns false is this is a public chat and true if this is a private chat with another user (see Recipient). </summary> | ||||
public bool IsPrivate => _recipientId != null; | |||||
public bool IsPrivate => _recipient.Id != null; | |||||
/// <summary> Returns the type of this channel (see ChannelTypes). </summary> | /// <summary> Returns the type of this channel (see ChannelTypes). </summary> | ||||
public string Type { get; private set; } | public string Type { get; private set; } | ||||
/// <summary> Returns the server containing this channel. </summary> | /// <summary> Returns the server containing this channel. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Server Server { get; private set; } | |||||
private readonly string _serverId; | |||||
public Server Server => _server.Value; | |||||
private readonly Reference<Server> _server; | |||||
/// For private chats, returns the target user, otherwise null. | /// For private chats, returns the target user, otherwise null. | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public User Recipient { get; private set; } | |||||
private readonly string _recipientId; | |||||
public User Recipient => _recipient.Value; | |||||
private readonly Reference<User> _recipient; | |||||
/// <summary> Returns a collection of all users with read access to this channel. </summary> | /// <summary> Returns a collection of all users with read access to this channel. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
@@ -74,39 +74,35 @@ namespace Discord | |||||
internal Channel(DiscordClient client, string id, string serverId, string recipientId) | internal Channel(DiscordClient client, string id, string serverId, string recipientId) | ||||
: base(client, id) | : base(client, id) | ||||
{ | { | ||||
_serverId = serverId; | |||||
_recipientId = recipientId; | |||||
_server = new Reference<Server>(serverId, | |||||
x => _client.Servers[x], | |||||
x => x.AddChannel(this), | |||||
x => x.RemoveChannel(this)); | |||||
_recipient = new Reference<User>(recipientId, | |||||
x => _client.Users[x, _server.Id], | |||||
x => | |||||
{ | |||||
Name = "@" + x.Name; | |||||
x.GlobalUser.PrivateChannel = this; | |||||
}, | |||||
x => x.GlobalUser.PrivateChannel = null); | |||||
_permissionOverwrites = _initialPermissionsOverwrites; | _permissionOverwrites = _initialPermissionsOverwrites; | ||||
_areMembersStale = true; | _areMembersStale = true; | ||||
//Local Cache | //Local Cache | ||||
_messages = new ConcurrentDictionary<string, Message>(); | _messages = new ConcurrentDictionary<string, Message>(); | ||||
} | } | ||||
internal override void OnCached() | |||||
internal override void LoadReferences() | |||||
{ | { | ||||
if (IsPrivate) | if (IsPrivate) | ||||
{ | |||||
var recipient = _client.Users[_recipientId, null]; | |||||
Name = "@" + recipient.Name; | |||||
recipient.GlobalUser.PrivateChannel = this; | |||||
Recipient = recipient; | |||||
} | |||||
_recipient.Load(); | |||||
else | else | ||||
{ | |||||
var server = _client.Servers[_serverId]; | |||||
server.AddChannel(this); | |||||
Server = server; | |||||
} | |||||
_server.Load(); | |||||
} | } | ||||
internal override void OnUncached() | |||||
internal override void UnloadReferences() | |||||
{ | { | ||||
var server = Server; | |||||
if (server != null) | |||||
server.RemoveChannel(this); | |||||
var recipient = Recipient; | |||||
if (recipient != null) | |||||
recipient.GlobalUser.PrivateChannel = null; | |||||
_server.Unload(); | |||||
_recipient.Unload(); | |||||
var globalMessages = _client.Messages; | var globalMessages = _client.Messages; | ||||
var messages = _messages; | var messages = _messages; | ||||
@@ -167,7 +163,10 @@ namespace Discord | |||||
} | } | ||||
private void UpdateMembersCache() | private void UpdateMembersCache() | ||||
{ | { | ||||
_members = Server.Members.Where(x => x.GetPermissions(this)?.ReadMessages ?? false).ToDictionary(x => x.Id, x => x); | |||||
if (_server.Id != null) | |||||
_members = Server.Members.Where(x => x.GetPermissions(this)?.ReadMessages ?? false).ToDictionary(x => x.Id, x => x); | |||||
else | |||||
_members = new Dictionary<string, User>(); | |||||
_areMembersStale = false; | _areMembersStale = false; | ||||
} | } | ||||
@@ -43,8 +43,8 @@ namespace Discord | |||||
{ | { | ||||
_users = new ConcurrentDictionary<string, User>(); | _users = new ConcurrentDictionary<string, User>(); | ||||
} | } | ||||
internal override void OnCached() { } | |||||
internal override void OnUncached() | |||||
internal override void LoadReferences() { } | |||||
internal override void UnloadReferences() | |||||
{ | { | ||||
//Don't need to clean _users - they're considered owned by server | //Don't need to clean _users - they're considered owned by server | ||||
} | } | ||||
@@ -21,58 +21,37 @@ namespace Discord | |||||
/// <summary> Returns a URL for this invite using XkcdCode if available or Id if not. </summary> | /// <summary> Returns a URL for this invite using XkcdCode if available or Id if not. </summary> | ||||
public string Url => API.Endpoints.InviteUrl(XkcdCode ?? Id); | public string Url => API.Endpoints.InviteUrl(XkcdCode ?? Id); | ||||
/// <summary> Returns the user that created this invite. </summary> | /// <summary> Returns the user that created this invite. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public User Inviter { get; private set; } | |||||
[JsonProperty("InviterId")] | |||||
private readonly string _inviterId; | |||||
public User Inviter => _inviter.Value; | |||||
private readonly Reference<User> _inviter; | |||||
/// <summary> Returns the server this invite is to. </summary> | /// <summary> Returns the server this invite is to. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Server Server { get; private set; } | |||||
[JsonProperty("ServerId")] | |||||
private readonly string _serverId; | |||||
public Server Server => _server.Value; | |||||
private readonly Reference<Server> _server; | |||||
/// <summary> Returns the channel this invite is to. </summary> | /// <summary> Returns the channel this invite is to. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Channel Channel { get; private set; } | |||||
[JsonProperty("ChannelId")] | |||||
private readonly string _channelId; | |||||
public Channel Channel => _channel.Value; | |||||
private readonly Reference<Channel> _channel; | |||||
internal Invite(DiscordClient client, string code, string xkcdPass, string serverId, string inviterId, string channelId) | internal Invite(DiscordClient client, string code, string xkcdPass, string serverId, string inviterId, string channelId) | ||||
: base(client, code) | : base(client, code) | ||||
{ | { | ||||
XkcdCode = xkcdPass; | XkcdCode = xkcdPass; | ||||
_serverId = serverId; | |||||
_inviterId = inviterId; | |||||
_channelId = channelId; | |||||
_server = new Reference<Server>(serverId, x => _client.Servers[x] ?? new Server(client, x)); | |||||
_inviter = new Reference<User>(serverId, x => _client.Users[x, _server.Id] ?? new User(client, x, _server.Id)); | |||||
_channel = new Reference<Channel>(serverId, x => _client.Channels[x] ?? new Channel(client, x, _server.Id, null)); | |||||
} | } | ||||
internal override void OnCached() | |||||
internal override void LoadReferences() | |||||
{ | { | ||||
var server = _client.Servers[_serverId]; | |||||
if (server == null) | |||||
server = new Server(_client, _serverId); | |||||
Server = server; | |||||
if (_inviterId != null) | |||||
{ | |||||
var inviter = _client.Users[_inviterId, _serverId]; | |||||
if (inviter == null) | |||||
inviter = new User(_client, _inviterId, _serverId); | |||||
Inviter = inviter; | |||||
} | |||||
if (_channelId != null) | |||||
{ | |||||
var channel = _client.Channels[_channelId]; | |||||
if (channel == null) | |||||
channel = new Channel(_client, _channelId, _serverId, null); | |||||
Channel = channel; | |||||
} | |||||
_server.Load(); | |||||
_inviter.Load(); | |||||
_channel.Load(); | |||||
} | } | ||||
internal override void OnUncached() { } | |||||
internal override void UnloadReferences() { } | |||||
public override string ToString() => XkcdCode ?? Id; | public override string ToString() => XkcdCode ?? Id; | ||||
@@ -129,48 +129,36 @@ namespace Discord | |||||
/// <summary> Returns the server containing the channel this message was sent to. </summary> | /// <summary> Returns the server containing the channel this message was sent to. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Server Server => Channel.Server; | |||||
public Server Server => _channel.Value.Server; | |||||
/// <summary> Returns the channel this message was sent to. </summary> | /// <summary> Returns the channel this message was sent to. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Channel Channel { get; private set; } | |||||
private readonly string _channelId; | |||||
public Channel Channel => _channel.Value; | |||||
private readonly Reference<Channel> _channel; | |||||
/// <summary> Returns true if the current user created this message. </summary> | /// <summary> Returns true if the current user created this message. </summary> | ||||
public bool IsAuthor => _client.CurrentUserId == _userId; | |||||
public bool IsAuthor => _client.CurrentUserId == _user.Id; | |||||
/// <summary> Returns the author of this message. </summary> | /// <summary> Returns the author of this message. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public User User { get; private set; } | |||||
private readonly string _userId; | |||||
public User User => _user.Value; | |||||
private readonly Reference<User> _user; | |||||
internal Message(DiscordClient client, string id, string channelId, string userId) | internal Message(DiscordClient client, string id, string channelId, string userId) | ||||
: base(client, id) | : base(client, id) | ||||
{ | { | ||||
_channelId = channelId; | |||||
_userId = userId; | |||||
_channel = new Reference<Channel>(channelId, x => _client.Channels[x], x => x.AddMessage(this), x => x.RemoveMessage(this)); | |||||
_user = new Reference<User>(userId, x => _client.Users[x]); | |||||
Attachments = _initialAttachments; | Attachments = _initialAttachments; | ||||
Embeds = _initialEmbeds; | Embeds = _initialEmbeds; | ||||
} | } | ||||
internal override void OnCached() | |||||
internal override void LoadReferences() | |||||
{ | { | ||||
//References | |||||
var channel = _client.Channels[_channelId]; | |||||
channel.AddMessage(this); | |||||
Channel = channel; | |||||
var user = _client.Users[_userId, channel.Server?.Id]; | |||||
//user.AddMessage(this); | |||||
User = user; | |||||
_channel.Load(); | |||||
_user.Load(); | |||||
} | } | ||||
internal override void OnUncached() | |||||
internal override void UnloadReferences() | |||||
{ | { | ||||
//References | |||||
var channel = Channel; | |||||
if (channel != null) | |||||
channel.RemoveMessage(this); | |||||
/*var user = User; | |||||
if (user != null) | |||||
user.RemoveMessage(this);*/ | |||||
_channel.Unload(); | |||||
_user.Unload(); | |||||
} | } | ||||
internal void Update(MessageInfo model) | internal void Update(MessageInfo model) | ||||
@@ -6,9 +6,7 @@ using System.Linq; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public sealed class Role : CachedObject | public sealed class Role : CachedObject | ||||
{ | |||||
private readonly string _serverId; | |||||
{ | |||||
/// <summary> Returns the name of this role. </summary> | /// <summary> Returns the name of this role. </summary> | ||||
public string Name { get; private set; } | public string Name { get; private set; } | ||||
/// <summary> If true, this role is displayed isolated from other users. </summary> | /// <summary> If true, this role is displayed isolated from other users. </summary> | ||||
@@ -22,40 +20,35 @@ namespace Discord | |||||
/// <summary> Returns the the permissions contained by this role. </summary> | /// <summary> Returns the the permissions contained by this role. </summary> | ||||
public ServerPermissions Permissions { get; } | public ServerPermissions Permissions { get; } | ||||
/// <summary> Returns the server this role is a member of. </summary> | /// <summary> Returns the server this role is a member of. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public Server Server { get; private set; } | |||||
public Server Server => _server.Value; | |||||
private readonly Reference<Server> _server; | |||||
/// <summary> Returns true if this is the role representing all users in a server. </summary> | /// <summary> Returns true if this is the role representing all users in a server. </summary> | ||||
public bool IsEveryone => _serverId == null || Id == _serverId; | |||||
public bool IsEveryone => _server.Id == null || Id == _server.Id; | |||||
/// <summary> Returns a list of all members in this role. </summary> | /// <summary> Returns a list of all members in this role. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public IEnumerable<User> Members => IsEveryone ? Server.Members : Server.Members.Where(x => x.HasRole(this)); | |||||
public IEnumerable<User> Members => _server.Id != null ? (IsEveryone ? Server.Members : Server.Members.Where(x => x.HasRole(this))) : new User[0]; | |||||
//TODO: Add local members cache | //TODO: Add local members cache | ||||
internal Role(DiscordClient client, string id, string serverId) | internal Role(DiscordClient client, string id, string serverId) | ||||
: base(client, id) | : base(client, id) | ||||
{ | { | ||||
_serverId = serverId; | |||||
_server = new Reference<Server>(serverId, x => _client.Servers[x], x => x.AddRole(this), x => x.RemoveRole(this)); | |||||
Permissions = new ServerPermissions(0); | Permissions = new ServerPermissions(0); | ||||
Permissions.Lock(); | Permissions.Lock(); | ||||
Color = new Color(0); | Color = new Color(0); | ||||
Color.Lock(); | Color.Lock(); | ||||
} | } | ||||
internal override void OnCached() | |||||
internal override void LoadReferences() | |||||
{ | { | ||||
//References | |||||
var server = _client.Servers[_serverId]; | |||||
server.AddRole(this); | |||||
Server = server; | |||||
_server.Load(); | |||||
} | } | ||||
internal override void OnUncached() | |||||
internal override void UnloadReferences() | |||||
{ | { | ||||
//References | |||||
var server = Server; | |||||
if (server != null) | |||||
server.RemoveRole(this); | |||||
_server.Unload(); | |||||
} | } | ||||
internal void Update(RoleInfo model) | internal void Update(RoleInfo model) | ||||
@@ -84,8 +84,8 @@ namespace Discord | |||||
_bans = new ConcurrentDictionary<string, bool>(); | _bans = new ConcurrentDictionary<string, bool>(); | ||||
_invites = new ConcurrentDictionary<string, Invite>(); | _invites = new ConcurrentDictionary<string, Invite>(); | ||||
} | } | ||||
internal override void OnCached() { } | |||||
internal override void OnUncached() | |||||
internal override void LoadReferences() { } | |||||
internal override void UnloadReferences() | |||||
{ | { | ||||
//Global Cache | //Global Cache | ||||
var globalChannels = _client.Channels; | var globalChannels = _client.Channels; | ||||
@@ -210,21 +210,31 @@ namespace Discord | |||||
internal void AddMember(User member) | internal void AddMember(User member) | ||||
{ | { | ||||
_members.TryAdd(member.Id, member); | |||||
foreach (var channel in Channels) | |||||
if (_members.TryAdd(member.Id, member)) | |||||
{ | { | ||||
member.AddChannel(channel); | |||||
channel.InvalidatePermissionsCache(member); | |||||
if (member.Id == _ownerId) | |||||
Owner = member; | |||||
foreach (var channel in Channels) | |||||
{ | |||||
member.AddChannel(channel); | |||||
channel.InvalidatePermissionsCache(member); | |||||
} | |||||
} | } | ||||
} | } | ||||
internal void RemoveMember(User member) | internal void RemoveMember(User member) | ||||
{ | { | ||||
foreach (var channel in Channels) | |||||
if (_members.TryRemove(member.Id, out member)) | |||||
{ | { | ||||
member.RemoveChannel(channel); | |||||
channel.InvalidatePermissionsCache(member); | |||||
if (member.Id == _ownerId) | |||||
Owner = null; | |||||
foreach (var channel in Channels) | |||||
{ | |||||
member.RemoveChannel(channel); | |||||
channel.InvalidatePermissionsCache(member); | |||||
} | |||||
} | } | ||||
_members.TryRemove(member.Id, out member); | |||||
} | } | ||||
internal void HasMember(User user) => _members.ContainsKey(user.Id); | internal void HasMember(User user) => _members.ContainsKey(user.Id); | ||||
@@ -16,7 +16,7 @@ namespace Discord | |||||
private ServerPermissions _serverPermissions; | private ServerPermissions _serverPermissions; | ||||
/// <summary> Returns a unique identifier combining this user's id with its server's. </summary> | /// <summary> Returns a unique identifier combining this user's id with its server's. </summary> | ||||
internal string UniqueId => GetId(Id, _serverId); | |||||
internal string UniqueId => GetId(Id, _server.Id); | |||||
/// <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> | ||||
@@ -49,11 +49,12 @@ namespace Discord | |||||
private DateTime _lastOnline; | private DateTime _lastOnline; | ||||
[JsonIgnore] | [JsonIgnore] | ||||
internal GlobalUser GlobalUser { get; private set; } | |||||
internal GlobalUser GlobalUser => _globalUser.Value; | |||||
private readonly Reference<GlobalUser> _globalUser; | |||||
[JsonIgnore] | [JsonIgnore] | ||||
public Server Server { get; private set; } | |||||
private string _serverId; | |||||
public Server Server => _server.Value; | |||||
private readonly Reference<Server> _server; | |||||
[JsonIgnore] | [JsonIgnore] | ||||
public Channel VoiceChannel { get; private set; } | public Channel VoiceChannel { get; private set; } | ||||
@@ -64,7 +65,7 @@ namespace Discord | |||||
/// <summary> Returns a collection of all messages this user has sent on this server that are still in cache. </summary> | /// <summary> Returns a collection of all messages this user has sent on this server that are still in cache. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.User.Id == Id && x.Server.Id == _serverId); | |||||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.User.Id == Id && x.Server.Id == _server.Id); | |||||
/// <summary> Returns a collection of all channels this user is a member of. </summary> | /// <summary> Returns a collection of all channels this user is a member of. </summary> | ||||
[JsonIgnore] | [JsonIgnore] | ||||
@@ -73,44 +74,41 @@ namespace Discord | |||||
internal User(DiscordClient client, string id, string serverId) | internal User(DiscordClient client, string id, string serverId) | ||||
: base(client, id) | : base(client, id) | ||||
{ | { | ||||
_serverId = serverId; | |||||
_globalUser = new Reference<GlobalUser>(id, | |||||
x => _client.GlobalUsers.GetOrAdd(x), | |||||
x => x.AddUser(this), | |||||
x => x.RemoveUser(this)); | |||||
_server = new Reference<Server>(serverId, | |||||
x => _client.Servers[x], | |||||
x => | |||||
{ | |||||
x.AddMember(this); | |||||
if (x.Id == _client.CurrentUserId) | |||||
x.CurrentMember = this; | |||||
}, | |||||
x => | |||||
{ | |||||
x.RemoveMember(this); | |||||
if (x.Id == _client.CurrentUserId) | |||||
x.CurrentMember = null; | |||||
}); | |||||
Status = UserStatus.Offline; | Status = UserStatus.Offline; | ||||
//_roles = new Dictionary<string, Role>(); | |||||
_channels = new ConcurrentDictionary<string, Channel>(); | _channels = new ConcurrentDictionary<string, Channel>(); | ||||
_permissions = new ConcurrentDictionary<string, ChannelPermissions>(); | _permissions = new ConcurrentDictionary<string, ChannelPermissions>(); | ||||
_serverPermissions = new ServerPermissions(); | _serverPermissions = new ServerPermissions(); | ||||
} | |||||
internal override void OnCached() | |||||
{ | |||||
if (_serverId != null) | |||||
{ | |||||
var server = _client.Servers[_serverId]; | |||||
server.AddMember(this); | |||||
if (Id == _client.CurrentUserId) | |||||
server.CurrentMember = this; | |||||
Server = server; | |||||
} | |||||
else | |||||
UpdateRoles(null); | |||||
var user = _client.GlobalUsers.GetOrAdd(Id); | |||||
user.AddUser(this); | |||||
GlobalUser = user; | |||||
if (serverId == null) | |||||
UpdateRoles(null); | |||||
} | } | ||||
internal override void OnUncached() | |||||
internal override void LoadReferences() | |||||
{ | { | ||||
//References | |||||
var server = Server; | |||||
if (server != null) | |||||
{ | |||||
server.RemoveMember(this); | |||||
if (Id == _client.CurrentUserId) | |||||
server.CurrentMember = null; | |||||
} | |||||
var globalUser = GlobalUser; | |||||
if (globalUser != null) | |||||
globalUser.RemoveUser(this); | |||||
_globalUser.Load(); | |||||
_server.Load(); | |||||
} | |||||
internal override void UnloadReferences() | |||||
{ | |||||
_globalUser.Unload(); | |||||
_server.Unload(); | |||||
} | } | ||||
public override string ToString() => Id; | public override string ToString() => Id; | ||||
@@ -128,6 +126,7 @@ namespace Discord | |||||
{ | { | ||||
if (model.User != null) | if (model.User != null) | ||||
Update(model.User); | Update(model.User); | ||||
if (model.JoinedAt.HasValue) | if (model.JoinedAt.HasValue) | ||||
JoinedAt = model.JoinedAt.Value; | JoinedAt = model.JoinedAt.Value; | ||||
if (model.Roles != null) | if (model.Roles != null) | ||||
@@ -138,6 +137,7 @@ namespace Discord | |||||
internal void Update(ExtendedMemberInfo model) | internal void Update(ExtendedMemberInfo model) | ||||
{ | { | ||||
Update(model as API.MemberInfo); | Update(model as API.MemberInfo); | ||||
if (model.IsServerDeafened != null) | if (model.IsServerDeafened != null) | ||||
IsServerDeafened = model.IsServerDeafened.Value; | IsServerDeafened = model.IsServerDeafened.Value; | ||||
if (model.IsServerMuted != null) | if (model.IsServerMuted != null) | ||||
@@ -156,9 +156,8 @@ namespace Discord | |||||
if (Status == UserStatus.Offline) | if (Status == UserStatus.Offline) | ||||
_lastOnline = DateTime.UtcNow; | _lastOnline = DateTime.UtcNow; | ||||
} | } | ||||
//Allows null | |||||
GameId = model.GameId; | |||||
GameId = model.GameId; //Allows null | |||||
} | } | ||||
internal void Update(VoiceMemberInfo model) | internal void Update(VoiceMemberInfo model) | ||||
{ | { | ||||
@@ -188,7 +187,7 @@ namespace Discord | |||||
else | else | ||||
newRoles = new Dictionary<string, Role>(); | newRoles = new Dictionary<string, Role>(); | ||||
Role everyone; | Role everyone; | ||||
if (_serverId != null) | |||||
if (_server.Id != null) | |||||
everyone = Server.EveryoneRole; | everyone = Server.EveryoneRole; | ||||
else | else | ||||
everyone = _client.Roles.VirtualEveryone; | everyone = _client.Roles.VirtualEveryone; | ||||