diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj
index 68ed60e20..960a597f9 100644
--- a/src/Discord.Net.Net45/Discord.Net.csproj
+++ b/src/Discord.Net.Net45/Discord.Net.csproj
@@ -148,27 +148,6 @@
Audio\VoiceBuffer.cs
-
- Collections\AsyncCollection.cs
-
-
- Collections\Channels.cs
-
-
- Collections\Members.cs
-
-
- Collections\Messages.cs
-
-
- Collections\Roles.cs
-
-
- Collections\Servers.cs
-
-
- Collections\Users.cs
-
DiscordAPIClient.cs
@@ -250,6 +229,9 @@
HttpException.cs
+
+ Models\AsyncCollection.cs
+
Models\Channel.cs
diff --git a/src/Discord.Net/Collections/Channels.cs b/src/Discord.Net/Collections/Channels.cs
deleted file mode 100644
index ec9d28c1c..000000000
--- a/src/Discord.Net/Collections/Channels.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using System;
-
-namespace Discord.Collections
-{
- internal sealed class Channels : AsyncCollection
- {
- public Channels(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
-
- public Channel GetOrAdd(string id, string serverId, string recipientId = null)
- => GetOrAdd(id, () => new Channel(_client, id, serverId, recipientId));
-
- protected override void OnCreated(Channel item)
- {
- if (!item.IsPrivate)
- item.Server.AddChannel(item.Id);
- if (item.RecipientId != null)
- {
- var user = item.Recipient;
- if (user.PrivateChannelId != null)
- throw new Exception("User already has a private channel.");
- user.PrivateChannelId = item.Id;
- user.AddRef();
- }
- }
- protected override void OnRemoved(Channel item)
- {
- if (!item.IsPrivate)
- {
- var server = item.Server;
- if (server != null)
- item.Server.RemoveChannel(item.Id);
- }
- if (item.RecipientId != null)
- {
- var user = item.Recipient;
- if (user != null)
- {
- if (user.PrivateChannelId != item.Id)
- throw new Exception("User has a different private channel.");
- user.PrivateChannelId = null;
- user.RemoveRef();
- }
- }
- }
- }
-}
diff --git a/src/Discord.Net/Collections/Members.cs b/src/Discord.Net/Collections/Members.cs
deleted file mode 100644
index 7801b8aa3..000000000
--- a/src/Discord.Net/Collections/Members.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-namespace Discord.Collections
-{
- internal sealed class Members : AsyncCollection
- {
- public Members(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
- private string GetKey(string userId, string serverId)
- => serverId + '_' + userId;
-
- public Member this[string userId, string serverId]
- => this[GetKey(userId, serverId)];
- public Member GetOrAdd(string userId, string serverId)
- => GetOrAdd(GetKey(userId, serverId), () => new Member(_client, userId, serverId));
- public Member TryRemove(string userId, string serverId)
- => TryRemove(GetKey(userId, serverId));
-
- protected override void OnCreated(Member item)
- {
- item.Server.AddMember(item);
- item.User.AddServer(item.ServerId);
- item.User.AddRef();
- if (item.UserId == _client.CurrentUserId)
- item.Server.CurrentMember = item;
- }
- protected override void OnRemoved(Member item)
- {
- var server = item.Server;
- if (server != null)
- {
- server.RemoveMember(item);
- if (item.UserId == _client.CurrentUserId)
- server.CurrentMember = null;
- }
- var user = item.User;
- if (user != null)
- {
- user.RemoveServer(item.ServerId);
- user.RemoveRef();
- }
- }
- }
-}
diff --git a/src/Discord.Net/Collections/Messages.cs b/src/Discord.Net/Collections/Messages.cs
deleted file mode 100644
index 5e2b38ce3..000000000
--- a/src/Discord.Net/Collections/Messages.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace Discord.Collections
-{
- internal sealed class Messages : AsyncCollection
- {
- public Messages(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
-
- public Message GetOrAdd(string id, string channelId, string userId)
- => GetOrAdd(id, () => new Message(_client, id, channelId, userId));
-
- protected override void OnCreated(Message item)
- {
- item.Channel.AddMessage(item.Id);
- item.User.AddRef();
- }
- protected override void OnRemoved(Message item)
- {
- var channel = item.Channel;
- if (channel != null)
- channel.RemoveMessage(item.Id);
- var user = item.User;
- if (user != null)
- user.RemoveRef();
- }
- }
-}
diff --git a/src/Discord.Net/Collections/Roles.cs b/src/Discord.Net/Collections/Roles.cs
deleted file mode 100644
index 4bc4bd1d8..000000000
--- a/src/Discord.Net/Collections/Roles.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace Discord.Collections
-{
- internal sealed class Roles : AsyncCollection
- {
- public Roles(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
-
- public Role GetOrAdd(string id, string serverId)
- => GetOrAdd(id, () => new Role(_client, id, serverId));
-
- protected override void OnCreated(Role item)
- {
- item.Server.AddRole(item.Id);
- }
- protected override void OnRemoved(Role item)
- {
- var server = item.Server;
- if (server != null)
- item.Server.RemoveRole(item.Id);
- }
- }
-}
diff --git a/src/Discord.Net/Collections/Servers.cs b/src/Discord.Net/Collections/Servers.cs
deleted file mode 100644
index 977c3b99f..000000000
--- a/src/Discord.Net/Collections/Servers.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Discord.Collections
-{
- internal sealed class Servers : AsyncCollection
- {
- public Servers(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
-
- public Server GetOrAdd(string id)
- => base.GetOrAdd(id, () => new Server(_client, id));
-
- protected override void OnRemoved(Server item)
- {
- var channels = _client.Channels;
- foreach (var channelId in item.ChannelIds)
- channels.TryRemove(channelId);
-
- var members = _client.Members;
- foreach (var userId in item.UserIds)
- members.TryRemove(userId, item.Id);
-
- var roles = _client.Roles;
- foreach (var roleId in item.RoleIds)
- roles.TryRemove(roleId);
- }
- }
-}
diff --git a/src/Discord.Net/Collections/Users.cs b/src/Discord.Net/Collections/Users.cs
deleted file mode 100644
index 31d12c1e2..000000000
--- a/src/Discord.Net/Collections/Users.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Discord.Collections
-{
- internal sealed class Users : AsyncCollection
- {
- public Users(DiscordClient client, object writerLock)
- : base(client, writerLock) { }
-
- public User GetOrAdd(string id) => GetOrAdd(id, () => new User(_client, id));
- }
-}
diff --git a/src/Discord.Net/DiscordClient.Bans.cs b/src/Discord.Net/DiscordClient.Bans.cs
index 2c0d98ad0..4c7563447 100644
--- a/src/Discord.Net/DiscordClient.Bans.cs
+++ b/src/Discord.Net/DiscordClient.Bans.cs
@@ -5,6 +5,21 @@ using System.Threading.Tasks;
namespace Discord
{
+ public class BanEventArgs : EventArgs
+ {
+ public User User { get; }
+ public string UserId { get; }
+ public Server Server { get; }
+ public string ServerId => Server.Id;
+
+ internal BanEventArgs(User user, string userId, Server server)
+ {
+ User = user;
+ UserId = userId;
+ Server = server;
+ }
+ }
+
public partial class DiscordClient
{
public event EventHandler BanAdded;
diff --git a/src/Discord.Net/DiscordClient.Channels.cs b/src/Discord.Net/DiscordClient.Channels.cs
index 8b98cc395..5ab562943 100644
--- a/src/Discord.Net/DiscordClient.Channels.cs
+++ b/src/Discord.Net/DiscordClient.Channels.cs
@@ -1,4 +1,3 @@
-using Discord.Collections;
using Discord.Net;
using System;
using System.Collections.Generic;
@@ -8,7 +7,16 @@ using System.Threading.Tasks;
namespace Discord
{
- public sealed class ChannelEventArgs : EventArgs
+ internal sealed class Channels : AsyncCollection
+ {
+ public Channels(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+
+ public Channel GetOrAdd(string id, string serverId, string recipientId = null)
+ => GetOrAdd(id, () => new Channel(_client, id, serverId, recipientId));
+ }
+
+ public class ChannelEventArgs : EventArgs
{
public Channel Channel { get; }
public string ChannelId => Channel.Id;
diff --git a/src/Discord.Net/DiscordClient.Members.cs b/src/Discord.Net/DiscordClient.Members.cs
index 235eb704f..980841bb3 100644
--- a/src/Discord.Net/DiscordClient.Members.cs
+++ b/src/Discord.Net/DiscordClient.Members.cs
@@ -1,4 +1,3 @@
-using Discord.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -6,54 +5,66 @@ using System.Threading.Tasks;
namespace Discord
{
- public sealed class MemberTypingEventArgs : EventArgs
+ internal sealed class Members : AsyncCollection
+ {
+ public Members(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+ private string GetKey(string userId, string serverId)
+ => serverId + '_' + userId;
+
+ public Member this[string userId, string serverId]
+ => this[GetKey(userId, serverId)];
+ public Member GetOrAdd(string userId, string serverId)
+ => GetOrAdd(GetKey(userId, serverId), () => new Member(_client, userId, serverId));
+ public Member TryRemove(string userId, string serverId)
+ => TryRemove(GetKey(userId, serverId));
+ }
+
+ public class MemberEventArgs : EventArgs
{
- public Channel Channel { get; }
- public string ChannelId => Channel.Id;
- public Server Server => Channel.Server;
- public string ServerId => Channel.ServerId;
public Member Member { get; }
- public string UserId => User.Id;
public User User => Member.User;
+ public string UserId => Member.UserId;
+ public Server Server => Member.Server;
+ public string ServerId => Member.ServerId;
+
+ internal MemberEventArgs(Member member) { Member = member; }
+ }
+ public class MemberChannelEventArgs : MemberEventArgs
+ {
+ public Channel Channel { get; }
+ public string ChannelId => Channel.Id;
- internal MemberTypingEventArgs(Member member, Channel channel)
+ internal MemberChannelEventArgs(Member member, Channel channel)
+ : base(member)
{
- Member = member;
Channel = channel;
}
}
-
- public sealed class MemberIsSpeakingEventArgs : EventArgs
+ public class MemberIsSpeakingEventArgs : MemberChannelEventArgs
{
- public Channel Channel => Member.VoiceChannel;
- public string ChannelId => Member.VoiceChannelId;
- public Server Server => Member.Server;
- public string ServerId => Member.ServerId;
- public User User => Member.User;
- public string UserId => Member.UserId;
- public Member Member { get; }
public bool IsSpeaking { get; }
- internal MemberIsSpeakingEventArgs(Member member, bool isSpeaking)
+ internal MemberIsSpeakingEventArgs(Member member, Channel channel, bool isSpeaking)
+ : base(member, channel)
{
- Member = member;
IsSpeaking = isSpeaking;
}
}
public partial class DiscordClient
{
- public event EventHandler UserIsTyping;
+ public event EventHandler UserIsTyping;
private void RaiseUserIsTyping(Member member, Channel channel)
{
if (UserIsTyping != null)
- RaiseEvent(nameof(UserIsTyping), () => UserIsTyping(this, new MemberTypingEventArgs(member, channel)));
+ RaiseEvent(nameof(UserIsTyping), () => UserIsTyping(this, new MemberChannelEventArgs(member, channel)));
}
public event EventHandler UserIsSpeaking;
- private void RaiseUserIsSpeaking(Member member, bool isSpeaking)
+ private void RaiseUserIsSpeaking(Member member, Channel channel, bool isSpeaking)
{
if (UserIsSpeaking != null)
- RaiseEvent(nameof(UserIsSpeaking), () => UserIsSpeaking(this, new MemberIsSpeakingEventArgs(member, isSpeaking)));
+ RaiseEvent(nameof(UserIsSpeaking), () => UserIsSpeaking(this, new MemberIsSpeakingEventArgs(member, channel, isSpeaking)));
}
internal Members Members => _members;
diff --git a/src/Discord.Net/DiscordClient.Messages.cs b/src/Discord.Net/DiscordClient.Messages.cs
index fe71dc233..59e4301e4 100644
--- a/src/Discord.Net/DiscordClient.Messages.cs
+++ b/src/Discord.Net/DiscordClient.Messages.cs
@@ -1,5 +1,4 @@
using Discord.API;
-using Discord.Collections;
using Discord.Net;
using System;
using System.Collections.Generic;
@@ -9,6 +8,30 @@ using System.Threading.Tasks;
namespace Discord
{
+ internal sealed class Messages : AsyncCollection
+ {
+ public Messages(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+
+ public Message GetOrAdd(string id, string channelId, string userId)
+ => GetOrAdd(id, () => new Message(_client, id, channelId, userId));
+ }
+
+ public class MessageEventArgs : EventArgs
+ {
+ public Message Message { get; }
+ public string MessageId => Message.Id;
+ public Member Member => Message.Member;
+ public Channel Channel => Message.Channel;
+ public string ChannelId => Message.ChannelId;
+ public Server Server => Message.Server;
+ public string ServerId => Message.ServerId;
+ public User User => Member.User;
+ public string UserId => Message.UserId;
+
+ internal MessageEventArgs(Message msg) { Message = msg; }
+ }
+
public partial class DiscordClient
{
public const int MaxMessageSize = 2000;
diff --git a/src/Discord.Net/DiscordClient.Roles.cs b/src/Discord.Net/DiscordClient.Roles.cs
index 35802fb6d..24e316401 100644
--- a/src/Discord.Net/DiscordClient.Roles.cs
+++ b/src/Discord.Net/DiscordClient.Roles.cs
@@ -1,4 +1,3 @@
-using Discord.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -6,6 +5,25 @@ using System.Threading.Tasks;
namespace Discord
{
+ internal sealed class Roles : AsyncCollection
+ {
+ public Roles(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+
+ public Role GetOrAdd(string id, string serverId)
+ => GetOrAdd(id, () => new Role(_client, id, serverId));
+ }
+
+ public class RoleEventArgs : EventArgs
+ {
+ public Role Role { get; }
+ public string RoleId => Role.Id;
+ public Server Server => Role.Server;
+ public string ServerId => Role.ServerId;
+
+ internal RoleEventArgs(Role role) { Role = role; }
+ }
+
public partial class DiscordClient
{
public event EventHandler RoleCreated;
diff --git a/src/Discord.Net/DiscordClient.Servers.cs b/src/Discord.Net/DiscordClient.Servers.cs
index c52be5c42..dbdcc9338 100644
--- a/src/Discord.Net/DiscordClient.Servers.cs
+++ b/src/Discord.Net/DiscordClient.Servers.cs
@@ -1,4 +1,3 @@
-using Discord.Collections;
using Discord.Net;
using System;
using System.Collections.Generic;
@@ -8,7 +7,16 @@ using System.Threading.Tasks;
namespace Discord
{
- public sealed class ServerEventArgs : EventArgs
+ internal sealed class Servers : AsyncCollection
+ {
+ public Servers(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+
+ public Server GetOrAdd(string id)
+ => base.GetOrAdd(id, () => new Server(_client, id));
+ }
+
+ public class ServerEventArgs : EventArgs
{
public Server Server { get; }
public string ServerId => Server.Id;
diff --git a/src/Discord.Net/DiscordClient.Users.cs b/src/Discord.Net/DiscordClient.Users.cs
index 29b9a3bb5..21b432beb 100644
--- a/src/Discord.Net/DiscordClient.Users.cs
+++ b/src/Discord.Net/DiscordClient.Users.cs
@@ -1,5 +1,4 @@
using Discord.API;
-using Discord.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -7,6 +6,14 @@ using System.Threading.Tasks;
namespace Discord
{
+ internal sealed class Users : AsyncCollection
+ {
+ public Users(DiscordClient client, object writerLock)
+ : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
+
+ public User GetOrAdd(string id) => GetOrAdd(id, () => new User(_client, id));
+ }
+
public sealed class UserEventArgs : EventArgs
{
public User User { get; }
diff --git a/src/Discord.Net/DiscordClient.Voice.cs b/src/Discord.Net/DiscordClient.Voice.cs
index 247977e59..56f4e2635 100644
--- a/src/Discord.Net/DiscordClient.Voice.cs
+++ b/src/Discord.Net/DiscordClient.Voice.cs
@@ -1,5 +1,6 @@
using Discord.Audio;
using System;
+using System.Threading.Tasks;
namespace Discord
{
diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs
index c8c5b7e60..6cc5fc0e9 100644
--- a/src/Discord.Net/DiscordClient.cs
+++ b/src/Discord.Net/DiscordClient.cs
@@ -1,5 +1,4 @@
using Discord.API;
-using Discord.Collections;
using Discord.Net.WebSockets;
using Newtonsoft.Json;
using System;
@@ -10,54 +9,6 @@ using System.Threading.Tasks;
namespace Discord
{
- public sealed class MessageEventArgs : EventArgs
- {
- public Message Message { get; }
- public string MessageId => Message.Id;
- public Member Member => Message.Member;
- public Channel Channel => Message.Channel;
- public string ChannelId => Message.ChannelId;
- public Server Server => Message.Server;
- public string ServerId => Message.ServerId;
- public User User => Member.User;
- public string UserId => Message.UserId;
-
- internal MessageEventArgs(Message msg) { Message = msg; }
- }
- public sealed class RoleEventArgs : EventArgs
- {
- public Role Role { get; }
- public string RoleId => Role.Id;
- public Server Server => Role.Server;
- public string ServerId => Role.ServerId;
-
- internal RoleEventArgs(Role role) { Role = role; }
- }
- public sealed class BanEventArgs : EventArgs
- {
- public User User { get; }
- public string UserId { get; }
- public Server Server { get; }
- public string ServerId => Server.Id;
-
- internal BanEventArgs(User user, string userId, Server server)
- {
- User = user;
- UserId = userId;
- Server = server;
- }
- }
- public sealed class MemberEventArgs : EventArgs
- {
- public Member Member { get; }
- public User User => Member.User;
- public string UserId => Member.UserId;
- public Server Server => Member.Server;
- public string ServerId => Member.ServerId;
-
- internal MemberEventArgs(Member member) { Member = member; }
- }
-
/// Provides a connection to the DiscordApp service.
public partial class DiscordClient : DiscordWSClient
{
@@ -106,7 +57,7 @@ namespace Discord
if (member.ServerId == e.ServerId && member.IsSpeaking)
{
member.IsSpeaking = false;
- RaiseUserIsSpeaking(member, false);
+ RaiseUserIsSpeaking(member, _channels[_voiceSocket.CurrentChannelId], false);
}
}
};
@@ -157,10 +108,10 @@ namespace Discord
$"Deleted Role: {e.Server?.Name ?? "[Private]"}/{e.Role.Name}" +
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.RoleId})." : ""));
BanAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
- $"Added Ban: {e.Server?.Name ?? "[Private]"}/{e.User?.Name ?? "Unknown"}" +
+ $"Added Ban: {e.Server?.Name ?? "[Private]"}/{e.User?.Name ?? e.UserId}" +
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.UserId})." : ""));
BanRemoved += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
- $"Removed Ban: {e.Server?.Name ?? "[Private]"}/{e.User?.Name ?? "Unknown"}" +
+ $"Removed Ban: {e.Server?.Name ?? "[Private]"}/{e.User?.Name ?? e.UserId}" +
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.UserId})." : ""));
UserAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
$"Added Member: {e.Server?.Name ?? "[Private]"}/{e.User.Name}" +
@@ -246,7 +197,8 @@ namespace Discord
if (member.IsSpeaking != value)
{
member.IsSpeaking = value;
- RaiseUserIsSpeaking(member, value);
+ var channel = _channels[_voiceSocket.CurrentChannelId];
+ RaiseUserIsSpeaking(member, channel, value);
if (Config.TrackActivity)
member.UpdateActivity();
}
@@ -665,7 +617,7 @@ namespace Discord
if (data.ChannelId != member.VoiceChannelId && member.IsSpeaking)
{
member.IsSpeaking = false;
- RaiseUserIsSpeaking(member, false);
+ RaiseUserIsSpeaking(member, _channels[member.VoiceChannelId], false);
}
member.Update(data);
RaiseUserVoiceStateUpdated(member);
diff --git a/src/Discord.Net/Collections/AsyncCollection.cs b/src/Discord.Net/Models/AsyncCollection.cs
similarity index 85%
rename from src/Discord.Net/Collections/AsyncCollection.cs
rename to src/Discord.Net/Models/AsyncCollection.cs
index f206011e0..d7533e58b 100644
--- a/src/Discord.Net/Collections/AsyncCollection.cs
+++ b/src/Discord.Net/Models/AsyncCollection.cs
@@ -4,7 +4,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
-namespace Discord.Collections
+namespace Discord
{
internal abstract class AsyncCollection : IEnumerable
where TValue : class
@@ -52,13 +52,16 @@ namespace Discord.Collections
protected readonly DiscordClient _client;
protected readonly ConcurrentDictionary _dictionary;
+ private readonly Action _onCache, _onUncache;
- protected AsyncCollection(DiscordClient client, object writerLock)
+ protected AsyncCollection(DiscordClient client, object writerLock, Action onCache, Action onUncache)
{
_client = client;
_writerLock = writerLock;
_dictionary = new ConcurrentDictionary();
- }
+ _onCache = onCache;
+ _onUncache = onUncache;
+ }
public TValue this[string key]
{
@@ -85,7 +88,7 @@ namespace Discord.Collections
result = _dictionary.GetOrAdd(key, newItem);
if (result == newItem)
{
- OnCreated(newItem);
+ _onCache(result);
RaiseItemCreated(result);
}
}
@@ -100,7 +103,7 @@ namespace Discord.Collections
TValue result;
if (_dictionary.TryRemove(key, out result))
{
- OnRemoved(result); //TODO: If this object is accessed before OnRemoved finished firing, properties such as Server.Channels will have null elements
+ _onUncache(result); //TODO: If this object is accessed before OnRemoved finished firing, properties such as Server.Channels will have null elements
return result;
}
}
@@ -130,16 +133,7 @@ namespace Discord.Collections
}
}
- protected virtual void OnCreated(TValue item) { }
- protected virtual void OnRemoved(TValue item) { }
-
- public IEnumerator GetEnumerator()
- {
- return _dictionary.Select(x => x.Value).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
+ public IEnumerator GetEnumerator() => _dictionary.Select(x => x.Value).GetEnumerator();
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs
index 1a4c8bf77..0b6a2bf07 100644
--- a/src/Discord.Net/Models/Channel.cs
+++ b/src/Discord.Net/Models/Channel.cs
@@ -1,5 +1,6 @@
using Discord.API;
using Newtonsoft.Json;
+using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
@@ -29,6 +30,7 @@ namespace Discord
private readonly DiscordClient _client;
private readonly ConcurrentDictionary _messages;
private bool _areMembersStale;
+ private bool _hasRef;
/// Returns the unique identifier for this channel.
public string Id { get; }
@@ -101,6 +103,39 @@ namespace Discord
_permissionOverwrites = _initialPermissionsOverwrites;
_areMembersStale = true;
}
+ internal void OnCached()
+ {
+ var server = Server;
+ if (server != null)
+ server.AddChannel(Id);
+ if (RecipientId != null)
+ {
+ var user = Recipient;
+ if (user != null)
+ {
+ user.PrivateChannelId = Id;
+ user.AddRef();
+ _hasRef = true;
+ }
+ }
+ }
+ internal void OnUncached()
+ {
+ var server = Server;
+ if (server != null)
+ server.RemoveChannel(Id);
+ if (RecipientId != null)
+ {
+ var user = Recipient;
+ if (user != null)
+ {
+ user.PrivateChannelId = null;
+ if (_hasRef)
+ user.RemoveRef();
+ }
+ }
+ _hasRef = false;
+ }
internal void Update(ChannelReference model)
{
diff --git a/src/Discord.Net/Models/Member.cs b/src/Discord.Net/Models/Member.cs
index ec48c2375..3012de7d9 100644
--- a/src/Discord.Net/Models/Member.cs
+++ b/src/Discord.Net/Models/Member.cs
@@ -11,6 +11,7 @@ namespace Discord
{
private readonly DiscordClient _client;
private ConcurrentDictionary _permissions;
+ private bool _hasRef;
/// Returns the name of this user on this server.
public string Name { get; private set; }
@@ -77,6 +78,41 @@ namespace Discord
RoleIds = _initialRoleIds;
_permissions = new ConcurrentDictionary();
}
+ internal void OnCached()
+ {
+ var server = Server;
+ if (server != null)
+ {
+ server.AddMember(this);
+ if (UserId == _client.CurrentUserId)
+ server.CurrentMember = this;
+ }
+ var user = User;
+ if (user != null)
+ {
+ user.AddServer(ServerId);
+ user.AddRef();
+ _hasRef = true;
+ }
+ }
+ internal void OnUncached()
+ {
+ var server = Server;
+ if (server != null)
+ {
+ server.RemoveMember(this);
+ if (UserId == _client.CurrentUserId)
+ server.CurrentMember = null;
+ }
+ var user = User;
+ if (user != null)
+ {
+ user.RemoveServer(ServerId);
+ if (_hasRef)
+ user.RemoveRef();
+ }
+ _hasRef = false;
+ }
public override string ToString() => UserId;
diff --git a/src/Discord.Net/Models/Message.cs b/src/Discord.Net/Models/Message.cs
index a23644448..a7370ac16 100644
--- a/src/Discord.Net/Models/Message.cs
+++ b/src/Discord.Net/Models/Message.cs
@@ -93,6 +93,7 @@ namespace Discord
private readonly DiscordClient _client;
private string _cleanText;
+ private bool _gotRef;
/// Returns the global unique identifier for this message.
public string Id { get; internal set; }
@@ -154,16 +155,7 @@ namespace Discord
public User User => _client.Users[UserId];
/// Returns the author of this message.
[JsonIgnore]
- public Member Member
- {
- get
- {
- if (!Channel.IsPrivate)
- return _client.Members[UserId, ServerId];
- else
- throw new InvalidOperationException("Unable to access Member in a private channel. Use User instead or check for Channel.IsPrivate.");
- }
- }
+ public Member Member => _client.Members[UserId, ServerId];
internal Message(DiscordClient client, string id, string channelId, string userId)
{
@@ -174,6 +166,28 @@ namespace Discord
Attachments = _initialAttachments;
Embeds = _initialEmbeds;
MentionIds = _initialMentions;
+ }
+ internal void OnCached()
+ {
+ var channel = Channel;
+ if (channel != null)
+ channel.AddMessage(Id);
+ var user = User;
+ if (user != null)
+ {
+ user.AddRef();
+ _gotRef = true;
+ }
+ }
+ internal void OnUncached()
+ {
+ var channel = Channel;
+ if (channel != null)
+ channel.RemoveMessage(Id);
+ var user = User;
+ if (user != null && _gotRef)
+ user.RemoveRef();
+ _gotRef = false;
}
internal void Update(MessageInfo model)
diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs
index 43215b8f8..399fa5d4b 100644
--- a/src/Discord.Net/Models/Role.cs
+++ b/src/Discord.Net/Models/Role.cs
@@ -52,7 +52,19 @@ namespace Discord
if (IsEveryone)
Position = int.MinValue;
- }
+ }
+ internal void OnCached()
+ {
+ var server = Server;
+ if (server != null)
+ server.AddRole(Id);
+ }
+ internal void OnUncached()
+ {
+ var server = Server;
+ if (server != null)
+ server.RemoveRole(Id);
+ }
internal void Update(RoleInfo model)
{
diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs
index aada16b20..b99cc8d48 100644
--- a/src/Discord.Net/Models/Server.cs
+++ b/src/Discord.Net/Models/Server.cs
@@ -104,6 +104,23 @@ namespace Discord
_members = new ConcurrentDictionary();
_roles = new ConcurrentDictionary();
}
+ internal void OnCached()
+ {
+ }
+ internal void OnUncached()
+ {
+ var channels = _client.Channels;
+ foreach (var channelId in ChannelIds)
+ channels.TryRemove(channelId);
+
+ var members = _client.Members;
+ foreach (var userId in UserIds)
+ members.TryRemove(userId, Id);
+
+ var roles = _client.Roles;
+ foreach (var roleId in RoleIds)
+ roles.TryRemove(roleId);
+ }
internal void Update(GuildInfo model)
{
diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs
index baa80c69b..0598ff33d 100644
--- a/src/Discord.Net/Models/User.cs
+++ b/src/Discord.Net/Models/User.cs
@@ -80,7 +80,13 @@ namespace Discord
_client = client;
Id = id;
_servers = new ConcurrentDictionary();
- }
+ }
+ internal void OnCached()
+ {
+ }
+ internal void OnUncached()
+ {
+ }
internal void Update(UserReference model)
{