Simplified caches, moved some eventargs, and made caching/uncaching objects more reliable.
This commit is contained in:
@@ -148,27 +148,6 @@
|
||||
<Compile Include="..\Discord.Net\Audio\VoiceBuffer.cs">
|
||||
<Link>Audio\VoiceBuffer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\AsyncCollection.cs">
|
||||
<Link>Collections\AsyncCollection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Channels.cs">
|
||||
<Link>Collections\Channels.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Members.cs">
|
||||
<Link>Collections\Members.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Messages.cs">
|
||||
<Link>Collections\Messages.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Roles.cs">
|
||||
<Link>Collections\Roles.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Servers.cs">
|
||||
<Link>Collections\Servers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Collections\Users.cs">
|
||||
<Link>Collections\Users.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordAPIClient.cs">
|
||||
<Link>DiscordAPIClient.cs</Link>
|
||||
</Compile>
|
||||
@@ -250,6 +229,9 @@
|
||||
<Compile Include="..\Discord.Net\HttpException.cs">
|
||||
<Link>HttpException.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Models\AsyncCollection.cs">
|
||||
<Link>Models\AsyncCollection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Models\Channel.cs">
|
||||
<Link>Models\Channel.cs</Link>
|
||||
</Compile>
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Channels : AsyncCollection<Channel>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Members : AsyncCollection<Member>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Messages : AsyncCollection<Message>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Roles : AsyncCollection<Role>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Servers : AsyncCollection<Server>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Discord.Collections
|
||||
{
|
||||
internal sealed class Users : AsyncCollection<User>
|
||||
{
|
||||
public Users(DiscordClient client, object writerLock)
|
||||
: base(client, writerLock) { }
|
||||
|
||||
public User GetOrAdd(string id) => GetOrAdd(id, () => new User(_client, id));
|
||||
}
|
||||
}
|
||||
@@ -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<BanEventArgs> BanAdded;
|
||||
|
||||
@@ -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<Channel>
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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<Member>
|
||||
{
|
||||
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 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; }
|
||||
}
|
||||
public class MemberChannelEventArgs : MemberEventArgs
|
||||
{
|
||||
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;
|
||||
|
||||
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<MemberTypingEventArgs> UserIsTyping;
|
||||
public event EventHandler<MemberChannelEventArgs> 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<MemberIsSpeakingEventArgs> 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;
|
||||
|
||||
@@ -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<Message>
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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<Role>
|
||||
{
|
||||
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<RoleEventArgs> RoleCreated;
|
||||
|
||||
@@ -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<Server>
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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<User>
|
||||
{
|
||||
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; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Discord.Audio;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
/// <summary> Provides a connection to the DiscordApp service. </summary>
|
||||
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);
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Discord.Collections
|
||||
namespace Discord
|
||||
{
|
||||
internal abstract class AsyncCollection<TValue> : IEnumerable<TValue>
|
||||
where TValue : class
|
||||
@@ -52,13 +52,16 @@ namespace Discord.Collections
|
||||
|
||||
protected readonly DiscordClient _client;
|
||||
protected readonly ConcurrentDictionary<string, TValue> _dictionary;
|
||||
private readonly Action<TValue> _onCache, _onUncache;
|
||||
|
||||
protected AsyncCollection(DiscordClient client, object writerLock)
|
||||
protected AsyncCollection(DiscordClient client, object writerLock, Action<TValue> onCache, Action<TValue> onUncache)
|
||||
{
|
||||
_client = client;
|
||||
_writerLock = writerLock;
|
||||
_dictionary = new ConcurrentDictionary<string, TValue>();
|
||||
}
|
||||
_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<TValue> GetEnumerator()
|
||||
{
|
||||
return _dictionary.Select(x => x.Value).GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
public IEnumerator<TValue> GetEnumerator() => _dictionary.Select(x => x.Value).GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
@@ -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<string, bool> _messages;
|
||||
private bool _areMembersStale;
|
||||
private bool _hasRef;
|
||||
|
||||
/// <summary> Returns the unique identifier for this channel. </summary>
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Discord
|
||||
{
|
||||
private readonly DiscordClient _client;
|
||||
private ConcurrentDictionary<string, PackedChannelPermissions> _permissions;
|
||||
private bool _hasRef;
|
||||
|
||||
/// <summary> Returns the name of this user on this server. </summary>
|
||||
public string Name { get; private set; }
|
||||
@@ -77,6 +78,41 @@ namespace Discord
|
||||
RoleIds = _initialRoleIds;
|
||||
_permissions = new ConcurrentDictionary<string, PackedChannelPermissions>();
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ namespace Discord
|
||||
|
||||
private readonly DiscordClient _client;
|
||||
private string _cleanText;
|
||||
private bool _gotRef;
|
||||
|
||||
/// <summary> Returns the global unique identifier for this message. </summary>
|
||||
public string Id { get; internal set; }
|
||||
@@ -154,16 +155,7 @@ namespace Discord
|
||||
public User User => _client.Users[UserId];
|
||||
/// <summary> Returns the author of this message. </summary>
|
||||
[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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,23 @@ namespace Discord
|
||||
_members = new ConcurrentDictionary<string, bool>();
|
||||
_roles = new ConcurrentDictionary<string, bool>();
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -80,7 +80,13 @@ namespace Discord
|
||||
_client = client;
|
||||
Id = id;
|
||||
_servers = new ConcurrentDictionary<string, bool>();
|
||||
}
|
||||
}
|
||||
internal void OnCached()
|
||||
{
|
||||
}
|
||||
internal void OnUncached()
|
||||
{
|
||||
}
|
||||
|
||||
internal void Update(UserReference model)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user