Add new reference system
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
68
src/Discord.Net/Helpers/Reference.cs
Normal file
68
src/Discord.Net/Helpers/Reference.cs
Normal file
@@ -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 LoadReferences();
|
||||||
internal abstract void OnUncached();
|
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; }
|
public Server Server => _server.Value;
|
||||||
private readonly string _serverId;
|
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; }
|
public User Recipient => _recipient.Value;
|
||||||
private readonly string _recipientId;
|
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;
|
_server = new Reference<Server>(serverId,
|
||||||
_recipientId = recipientId;
|
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)
|
||||||
{
|
_recipient.Load();
|
||||||
var recipient = _client.Users[_recipientId, null];
|
|
||||||
Name = "@" + recipient.Name;
|
|
||||||
recipient.GlobalUser.PrivateChannel = this;
|
|
||||||
Recipient = recipient;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
_server.Load();
|
||||||
var server = _client.Servers[_serverId];
|
|
||||||
server.AddChannel(this);
|
|
||||||
Server = server;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
var server = Server;
|
_server.Unload();
|
||||||
if (server != null)
|
_recipient.Unload();
|
||||||
server.RemoveChannel(this);
|
|
||||||
|
|
||||||
var recipient = Recipient;
|
|
||||||
if (recipient != null)
|
|
||||||
recipient.GlobalUser.PrivateChannel = null;
|
|
||||||
|
|
||||||
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 LoadReferences() { }
|
||||||
internal override void OnUncached()
|
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; }
|
public User Inviter => _inviter.Value;
|
||||||
[JsonProperty("InviterId")]
|
private readonly Reference<User> _inviter;
|
||||||
private readonly string _inviterId;
|
|
||||||
|
|
||||||
/// <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; }
|
public Server Server => _server.Value;
|
||||||
[JsonProperty("ServerId")]
|
private readonly Reference<Server> _server;
|
||||||
private readonly string _serverId;
|
|
||||||
|
|
||||||
/// <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; }
|
public Channel Channel => _channel.Value;
|
||||||
[JsonProperty("ChannelId")]
|
private readonly Reference<Channel> _channel;
|
||||||
private readonly string _channelId;
|
|
||||||
|
|
||||||
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;
|
_server = new Reference<Server>(serverId, x => _client.Servers[x] ?? new Server(client, x));
|
||||||
_inviterId = inviterId;
|
_inviter = new Reference<User>(serverId, x => _client.Users[x, _server.Id] ?? new User(client, x, _server.Id));
|
||||||
_channelId = channelId;
|
_channel = new Reference<Channel>(serverId, x => _client.Channels[x] ?? new Channel(client, x, _server.Id, null));
|
||||||
}
|
}
|
||||||
|
internal override void LoadReferences()
|
||||||
internal override void OnCached()
|
|
||||||
{
|
{
|
||||||
var server = _client.Servers[_serverId];
|
_server.Load();
|
||||||
if (server == null)
|
_inviter.Load();
|
||||||
server = new Server(_client, _serverId);
|
_channel.Load();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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; }
|
public Channel Channel => _channel.Value;
|
||||||
private readonly string _channelId;
|
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; }
|
public User User => _user.Value;
|
||||||
private readonly string _userId;
|
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;
|
_channel = new Reference<Channel>(channelId, x => _client.Channels[x], x => x.AddMessage(this), x => x.RemoveMessage(this));
|
||||||
_userId = userId;
|
_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
|
_channel.Load();
|
||||||
var channel = _client.Channels[_channelId];
|
_user.Load();
|
||||||
channel.AddMessage(this);
|
|
||||||
Channel = channel;
|
|
||||||
|
|
||||||
var user = _client.Users[_userId, channel.Server?.Id];
|
|
||||||
//user.AddMessage(this);
|
|
||||||
User = user;
|
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
//References
|
_channel.Unload();
|
||||||
var channel = Channel;
|
_user.Unload();
|
||||||
if (channel != null)
|
|
||||||
channel.RemoveMessage(this);
|
|
||||||
|
|
||||||
/*var user = User;
|
|
||||||
if (user != null)
|
|
||||||
user.RemoveMessage(this);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
_server.Load();
|
||||||
var server = _client.Servers[_serverId];
|
|
||||||
server.AddRole(this);
|
|
||||||
Server = server;
|
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void UnloadReferences()
|
||||||
{
|
{
|
||||||
//References
|
_server.Unload();
|
||||||
var server = Server;
|
|
||||||
if (server != null)
|
|
||||||
server.RemoveRole(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 LoadReferences() { }
|
||||||
internal override void OnUncached()
|
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);
|
if (_members.TryAdd(member.Id, member))
|
||||||
foreach (var channel in Channels)
|
|
||||||
{
|
{
|
||||||
member.AddChannel(channel);
|
if (member.Id == _ownerId)
|
||||||
channel.InvalidatePermissionsCache(member);
|
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);
|
if (member.Id == _ownerId)
|
||||||
channel.InvalidatePermissionsCache(member);
|
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; }
|
public Server Server => _server.Value;
|
||||||
private string _serverId;
|
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)
|
||||||
{
|
|
||||||
if (_serverId != null)
|
|
||||||
{
|
|
||||||
var server = _client.Servers[_serverId];
|
|
||||||
server.AddMember(this);
|
|
||||||
if (Id == _client.CurrentUserId)
|
|
||||||
server.CurrentMember = this;
|
|
||||||
Server = server;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UpdateRoles(null);
|
UpdateRoles(null);
|
||||||
|
|
||||||
var user = _client.GlobalUsers.GetOrAdd(Id);
|
|
||||||
user.AddUser(this);
|
|
||||||
GlobalUser = user;
|
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void LoadReferences()
|
||||||
{
|
{
|
||||||
//References
|
_globalUser.Load();
|
||||||
var server = Server;
|
_server.Load();
|
||||||
if (server != null)
|
}
|
||||||
{
|
internal override void UnloadReferences()
|
||||||
server.RemoveMember(this);
|
{
|
||||||
if (Id == _client.CurrentUserId)
|
_globalUser.Unload();
|
||||||
server.CurrentMember = null;
|
_server.Unload();
|
||||||
}
|
|
||||||
|
|
||||||
var globalUser = GlobalUser;
|
|
||||||
if (globalUser != null)
|
|
||||||
globalUser.RemoveUser(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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; //Allows null
|
||||||
GameId = model.GameId;
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user