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">
|
<Compile Include="..\Discord.Net\Audio\VoiceBuffer.cs">
|
||||||
<Link>Audio\VoiceBuffer.cs</Link>
|
<Link>Audio\VoiceBuffer.cs</Link>
|
||||||
</Compile>
|
</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">
|
<Compile Include="..\Discord.Net\DiscordAPIClient.cs">
|
||||||
<Link>DiscordAPIClient.cs</Link>
|
<Link>DiscordAPIClient.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -250,6 +229,9 @@
|
|||||||
<Compile Include="..\Discord.Net\HttpException.cs">
|
<Compile Include="..\Discord.Net\HttpException.cs">
|
||||||
<Link>HttpException.cs</Link>
|
<Link>HttpException.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Models\AsyncCollection.cs">
|
||||||
|
<Link>Models\AsyncCollection.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Models\Channel.cs">
|
<Compile Include="..\Discord.Net\Models\Channel.cs">
|
||||||
<Link>Models\Channel.cs</Link>
|
<Link>Models\Channel.cs</Link>
|
||||||
</Compile>
|
</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
|
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 partial class DiscordClient
|
||||||
{
|
{
|
||||||
public event EventHandler<BanEventArgs> BanAdded;
|
public event EventHandler<BanEventArgs> BanAdded;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Discord.Collections;
|
|
||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -8,7 +7,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 Channel Channel { get; }
|
||||||
public string ChannelId => Channel.Id;
|
public string ChannelId => Channel.Id;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Discord.Collections;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -6,54 +5,66 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 Channel Channel { get; }
|
||||||
public string ChannelId => Channel.Id;
|
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;
|
Channel = channel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public class MemberIsSpeakingEventArgs : MemberChannelEventArgs
|
||||||
public sealed class MemberIsSpeakingEventArgs : EventArgs
|
|
||||||
{
|
{
|
||||||
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; }
|
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;
|
IsSpeaking = isSpeaking;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class DiscordClient
|
public partial class DiscordClient
|
||||||
{
|
{
|
||||||
public event EventHandler<MemberTypingEventArgs> UserIsTyping;
|
public event EventHandler<MemberChannelEventArgs> UserIsTyping;
|
||||||
private void RaiseUserIsTyping(Member member, Channel channel)
|
private void RaiseUserIsTyping(Member member, Channel channel)
|
||||||
{
|
{
|
||||||
if (UserIsTyping != null)
|
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;
|
public event EventHandler<MemberIsSpeakingEventArgs> UserIsSpeaking;
|
||||||
private void RaiseUserIsSpeaking(Member member, bool isSpeaking)
|
private void RaiseUserIsSpeaking(Member member, Channel channel, bool isSpeaking)
|
||||||
{
|
{
|
||||||
if (UserIsSpeaking != null)
|
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;
|
internal Members Members => _members;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Discord.Collections;
|
|
||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -9,6 +8,30 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 partial class DiscordClient
|
||||||
{
|
{
|
||||||
public const int MaxMessageSize = 2000;
|
public const int MaxMessageSize = 2000;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Discord.Collections;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -6,6 +5,25 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 partial class DiscordClient
|
||||||
{
|
{
|
||||||
public event EventHandler<RoleEventArgs> RoleCreated;
|
public event EventHandler<RoleEventArgs> RoleCreated;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Discord.Collections;
|
|
||||||
using Discord.Net;
|
using Discord.Net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -8,7 +7,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 Server Server { get; }
|
||||||
public string ServerId => Server.Id;
|
public string ServerId => Server.Id;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Discord.Collections;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -7,6 +6,14 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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 sealed class UserEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public User User { get; }
|
public User User { get; }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Discord.Audio;
|
using Discord.Audio;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Discord.Collections;
|
|
||||||
using Discord.Net.WebSockets;
|
using Discord.Net.WebSockets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
@@ -10,54 +9,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
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>
|
/// <summary> Provides a connection to the DiscordApp service. </summary>
|
||||||
public partial class DiscordClient : DiscordWSClient
|
public partial class DiscordClient : DiscordWSClient
|
||||||
{
|
{
|
||||||
@@ -106,7 +57,7 @@ namespace Discord
|
|||||||
if (member.ServerId == e.ServerId && member.IsSpeaking)
|
if (member.ServerId == e.ServerId && member.IsSpeaking)
|
||||||
{
|
{
|
||||||
member.IsSpeaking = false;
|
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}" +
|
$"Deleted Role: {e.Server?.Name ?? "[Private]"}/{e.Role.Name}" +
|
||||||
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.RoleId})." : ""));
|
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.RoleId})." : ""));
|
||||||
BanAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
|
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})." : ""));
|
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.UserId})." : ""));
|
||||||
BanRemoved += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
|
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})." : ""));
|
(showIDs ? $" ({e.ServerId ?? "[Private]"}/{e.UserId})." : ""));
|
||||||
UserAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
|
UserAdded += (s, e) => RaiseOnLog(LogMessageSeverity.Info, LogMessageSource.Client,
|
||||||
$"Added Member: {e.Server?.Name ?? "[Private]"}/{e.User.Name}" +
|
$"Added Member: {e.Server?.Name ?? "[Private]"}/{e.User.Name}" +
|
||||||
@@ -246,7 +197,8 @@ namespace Discord
|
|||||||
if (member.IsSpeaking != value)
|
if (member.IsSpeaking != value)
|
||||||
{
|
{
|
||||||
member.IsSpeaking = value;
|
member.IsSpeaking = value;
|
||||||
RaiseUserIsSpeaking(member, value);
|
var channel = _channels[_voiceSocket.CurrentChannelId];
|
||||||
|
RaiseUserIsSpeaking(member, channel, value);
|
||||||
if (Config.TrackActivity)
|
if (Config.TrackActivity)
|
||||||
member.UpdateActivity();
|
member.UpdateActivity();
|
||||||
}
|
}
|
||||||
@@ -665,7 +617,7 @@ namespace Discord
|
|||||||
if (data.ChannelId != member.VoiceChannelId && member.IsSpeaking)
|
if (data.ChannelId != member.VoiceChannelId && member.IsSpeaking)
|
||||||
{
|
{
|
||||||
member.IsSpeaking = false;
|
member.IsSpeaking = false;
|
||||||
RaiseUserIsSpeaking(member, false);
|
RaiseUserIsSpeaking(member, _channels[member.VoiceChannelId], false);
|
||||||
}
|
}
|
||||||
member.Update(data);
|
member.Update(data);
|
||||||
RaiseUserVoiceStateUpdated(member);
|
RaiseUserVoiceStateUpdated(member);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Discord.Collections
|
namespace Discord
|
||||||
{
|
{
|
||||||
internal abstract class AsyncCollection<TValue> : IEnumerable<TValue>
|
internal abstract class AsyncCollection<TValue> : IEnumerable<TValue>
|
||||||
where TValue : class
|
where TValue : class
|
||||||
@@ -52,12 +52,15 @@ namespace Discord.Collections
|
|||||||
|
|
||||||
protected readonly DiscordClient _client;
|
protected readonly DiscordClient _client;
|
||||||
protected readonly ConcurrentDictionary<string, TValue> _dictionary;
|
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;
|
_client = client;
|
||||||
_writerLock = writerLock;
|
_writerLock = writerLock;
|
||||||
_dictionary = new ConcurrentDictionary<string, TValue>();
|
_dictionary = new ConcurrentDictionary<string, TValue>();
|
||||||
|
_onCache = onCache;
|
||||||
|
_onUncache = onUncache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue this[string key]
|
public TValue this[string key]
|
||||||
@@ -85,7 +88,7 @@ namespace Discord.Collections
|
|||||||
result = _dictionary.GetOrAdd(key, newItem);
|
result = _dictionary.GetOrAdd(key, newItem);
|
||||||
if (result == newItem)
|
if (result == newItem)
|
||||||
{
|
{
|
||||||
OnCreated(newItem);
|
_onCache(result);
|
||||||
RaiseItemCreated(result);
|
RaiseItemCreated(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +103,7 @@ namespace Discord.Collections
|
|||||||
TValue result;
|
TValue result;
|
||||||
if (_dictionary.TryRemove(key, out 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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,16 +133,7 @@ namespace Discord.Collections
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnCreated(TValue item) { }
|
public IEnumerator<TValue> GetEnumerator() => _dictionary.Select(x => x.Value).GetEnumerator();
|
||||||
protected virtual void OnRemoved(TValue item) { }
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
public IEnumerator<TValue> GetEnumerator()
|
|
||||||
{
|
|
||||||
return _dictionary.Select(x => x.Value).GetEnumerator();
|
|
||||||
}
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -29,6 +30,7 @@ namespace Discord
|
|||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private readonly ConcurrentDictionary<string, bool> _messages;
|
private readonly ConcurrentDictionary<string, bool> _messages;
|
||||||
private bool _areMembersStale;
|
private bool _areMembersStale;
|
||||||
|
private bool _hasRef;
|
||||||
|
|
||||||
/// <summary> Returns the unique identifier for this channel. </summary>
|
/// <summary> Returns the unique identifier for this channel. </summary>
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
@@ -101,6 +103,39 @@ namespace Discord
|
|||||||
_permissionOverwrites = _initialPermissionsOverwrites;
|
_permissionOverwrites = _initialPermissionsOverwrites;
|
||||||
_areMembersStale = true;
|
_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)
|
internal void Update(ChannelReference model)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private ConcurrentDictionary<string, PackedChannelPermissions> _permissions;
|
private ConcurrentDictionary<string, PackedChannelPermissions> _permissions;
|
||||||
|
private bool _hasRef;
|
||||||
|
|
||||||
/// <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; }
|
||||||
@@ -77,6 +78,41 @@ namespace Discord
|
|||||||
RoleIds = _initialRoleIds;
|
RoleIds = _initialRoleIds;
|
||||||
_permissions = new ConcurrentDictionary<string, PackedChannelPermissions>();
|
_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;
|
public override string ToString() => UserId;
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ namespace Discord
|
|||||||
|
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private string _cleanText;
|
private string _cleanText;
|
||||||
|
private bool _gotRef;
|
||||||
|
|
||||||
/// <summary> Returns the global unique identifier for this message. </summary>
|
/// <summary> Returns the global unique identifier for this message. </summary>
|
||||||
public string Id { get; internal set; }
|
public string Id { get; internal set; }
|
||||||
@@ -154,16 +155,7 @@ namespace Discord
|
|||||||
public User User => _client.Users[UserId];
|
public User User => _client.Users[UserId];
|
||||||
/// <summary> Returns the author of this message. </summary>
|
/// <summary> Returns the author of this message. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Member Member
|
public Member Member => _client.Members[UserId, ServerId];
|
||||||
{
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Message(DiscordClient client, string id, string channelId, string userId)
|
internal Message(DiscordClient client, string id, string channelId, string userId)
|
||||||
{
|
{
|
||||||
@@ -175,6 +167,28 @@ namespace Discord
|
|||||||
Embeds = _initialEmbeds;
|
Embeds = _initialEmbeds;
|
||||||
MentionIds = _initialMentions;
|
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)
|
internal void Update(MessageInfo model)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ namespace Discord
|
|||||||
if (IsEveryone)
|
if (IsEveryone)
|
||||||
Position = int.MinValue;
|
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)
|
internal void Update(RoleInfo model)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,6 +104,23 @@ namespace Discord
|
|||||||
_members = new ConcurrentDictionary<string, bool>();
|
_members = new ConcurrentDictionary<string, bool>();
|
||||||
_roles = 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)
|
internal void Update(GuildInfo model)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,6 +81,12 @@ namespace Discord
|
|||||||
Id = id;
|
Id = id;
|
||||||
_servers = new ConcurrentDictionary<string, bool>();
|
_servers = new ConcurrentDictionary<string, bool>();
|
||||||
}
|
}
|
||||||
|
internal void OnCached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
internal void OnUncached()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
internal void Update(UserReference model)
|
internal void Update(UserReference model)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user