Updated to use the v2 API. Added Embeds, Channel Permissions and Voice State parsing. Moved Presence from User to Member.
This commit is contained in:
@@ -97,6 +97,9 @@
|
|||||||
<Compile Include="..\Discord.Net\Message.cs">
|
<Compile Include="..\Discord.Net\Message.cs">
|
||||||
<Link>Message.cs</Link>
|
<Link>Message.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\PackedPermissions.cs">
|
||||||
|
<Link>PackedPermissions.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Regions.cs">
|
<Compile Include="..\Discord.Net\Regions.cs">
|
||||||
<Link>Regions.cs</Link>
|
<Link>Regions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -51,13 +51,52 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "verified")]
|
[JsonProperty(PropertyName = "verified")]
|
||||||
public bool IsVerified;
|
public bool IsVerified;
|
||||||
}
|
}
|
||||||
internal class PresenceUserInfo : UserReference
|
internal class MemberInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "user_id")]
|
||||||
|
public string UserId;
|
||||||
|
[JsonProperty(PropertyName = "user")]
|
||||||
|
public UserReference User;
|
||||||
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
|
public string ServerId;
|
||||||
|
}
|
||||||
|
internal class PresenceMemberInfo : MemberInfo
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "game_id")]
|
[JsonProperty(PropertyName = "game_id")]
|
||||||
public string GameId;
|
public string GameId;
|
||||||
[JsonProperty(PropertyName = "status")]
|
[JsonProperty(PropertyName = "status")]
|
||||||
public string Status;
|
public string Status;
|
||||||
}
|
}
|
||||||
|
internal class VoiceMemberInfo : MemberInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "channel_id")]
|
||||||
|
public string ChannelId;
|
||||||
|
[JsonProperty(PropertyName = "suppress")]
|
||||||
|
public bool IsSuppressed;
|
||||||
|
[JsonProperty(PropertyName = "session_id")]
|
||||||
|
public string SessionId;
|
||||||
|
[JsonProperty(PropertyName = "self_mute")]
|
||||||
|
public bool IsSelfMuted;
|
||||||
|
[JsonProperty(PropertyName = "self_deaf")]
|
||||||
|
public bool IsSelfDeafened;
|
||||||
|
[JsonProperty(PropertyName = "mute")]
|
||||||
|
public bool IsMuted;
|
||||||
|
[JsonProperty(PropertyName = "deaf")]
|
||||||
|
public bool IsDeafened;
|
||||||
|
[JsonProperty(PropertyName = "token")]
|
||||||
|
public string Token;
|
||||||
|
}
|
||||||
|
internal class RoleMemberInfo : MemberInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "mute")]
|
||||||
|
public bool IsMuted;
|
||||||
|
[JsonProperty(PropertyName = "deaf")]
|
||||||
|
public bool IsDeafened;
|
||||||
|
[JsonProperty(PropertyName = "joined_at")]
|
||||||
|
public DateTime? JoinedAt;
|
||||||
|
[JsonProperty(PropertyName = "roles")]
|
||||||
|
public string[] Roles;
|
||||||
|
}
|
||||||
|
|
||||||
//Channels
|
//Channels
|
||||||
internal class ChannelReference
|
internal class ChannelReference
|
||||||
@@ -73,12 +112,26 @@ namespace Discord.API.Models
|
|||||||
}
|
}
|
||||||
internal class ChannelInfo : ChannelReference
|
internal class ChannelInfo : ChannelReference
|
||||||
{
|
{
|
||||||
|
public sealed class PermissionOverwrite
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "type")]
|
||||||
|
public string Type;
|
||||||
|
[JsonProperty(PropertyName = "id")]
|
||||||
|
public string Id;
|
||||||
|
[JsonProperty(PropertyName = "deny")]
|
||||||
|
public uint Deny;
|
||||||
|
[JsonProperty(PropertyName = "allow")]
|
||||||
|
public uint Allow;
|
||||||
|
}
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "last_message_id")]
|
[JsonProperty(PropertyName = "last_message_id")]
|
||||||
public string LastMessageId;
|
public string LastMessageId;
|
||||||
[JsonProperty(PropertyName = "is_private")]
|
[JsonProperty(PropertyName = "is_private")]
|
||||||
public bool IsPrivate;
|
public bool IsPrivate;
|
||||||
|
[JsonProperty(PropertyName = "position")]
|
||||||
|
public int Position;
|
||||||
[JsonProperty(PropertyName = "permission_overwrites")]
|
[JsonProperty(PropertyName = "permission_overwrites")]
|
||||||
public object[] PermissionOverwrites;
|
public PermissionOverwrite[] PermissionOverwrites;
|
||||||
[JsonProperty(PropertyName = "recipient")]
|
[JsonProperty(PropertyName = "recipient")]
|
||||||
public UserReference Recipient;
|
public UserReference Recipient;
|
||||||
}
|
}
|
||||||
@@ -114,28 +167,14 @@ namespace Discord.API.Models
|
|||||||
}
|
}
|
||||||
internal class ExtendedServerInfo : ServerInfo
|
internal class ExtendedServerInfo : ServerInfo
|
||||||
{
|
{
|
||||||
public class Membership
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "roles")]
|
|
||||||
public string[] Roles;
|
|
||||||
[JsonProperty(PropertyName = "mute")]
|
|
||||||
public bool IsMuted;
|
|
||||||
[JsonProperty(PropertyName = "deaf")]
|
|
||||||
public bool IsDeaf;
|
|
||||||
[JsonProperty(PropertyName = "joined_at")]
|
|
||||||
public DateTime JoinedAt;
|
|
||||||
[JsonProperty(PropertyName = "user")]
|
|
||||||
public UserReference User;
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "channels")]
|
[JsonProperty(PropertyName = "channels")]
|
||||||
public ChannelInfo[] Channels;
|
public ChannelInfo[] Channels;
|
||||||
[JsonProperty(PropertyName = "members")]
|
[JsonProperty(PropertyName = "members")]
|
||||||
public Membership[] Members;
|
public RoleMemberInfo[] Members;
|
||||||
[JsonProperty(PropertyName = "presence")]
|
[JsonProperty(PropertyName = "presences")]
|
||||||
public object[] Presence;
|
public PresenceMemberInfo[] Presences;
|
||||||
[JsonProperty(PropertyName = "voice_states")]
|
[JsonProperty(PropertyName = "voice_states")]
|
||||||
public object[] VoiceStates;
|
public VoiceMemberInfo[] VoiceStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Messages
|
//Messages
|
||||||
@@ -150,7 +189,7 @@ namespace Discord.API.Models
|
|||||||
}
|
}
|
||||||
internal class Message : MessageReference
|
internal class Message : MessageReference
|
||||||
{
|
{
|
||||||
public class Attachment
|
public sealed class Attachment
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "id")]
|
[JsonProperty(PropertyName = "id")]
|
||||||
public string Id;
|
public string Id;
|
||||||
@@ -167,6 +206,40 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "height")]
|
[JsonProperty(PropertyName = "height")]
|
||||||
public int Height;
|
public int Height;
|
||||||
}
|
}
|
||||||
|
public sealed class Embed
|
||||||
|
{
|
||||||
|
public sealed class ProviderInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string Url;
|
||||||
|
[JsonProperty(PropertyName = "name")]
|
||||||
|
public string Name;
|
||||||
|
}
|
||||||
|
public sealed class ThumbnailInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string Url;
|
||||||
|
[JsonProperty(PropertyName = "proxy_url")]
|
||||||
|
public string ProxyUrl;
|
||||||
|
[JsonProperty(PropertyName = "width")]
|
||||||
|
public int Width;
|
||||||
|
[JsonProperty(PropertyName = "height")]
|
||||||
|
public int Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string Url;
|
||||||
|
[JsonProperty(PropertyName = "type")]
|
||||||
|
public string Type;
|
||||||
|
[JsonProperty(PropertyName = "title")]
|
||||||
|
public string Title;
|
||||||
|
[JsonProperty(PropertyName = "description")]
|
||||||
|
public string Description;
|
||||||
|
[JsonProperty(PropertyName = "provider")]
|
||||||
|
public ProviderInfo Provider;
|
||||||
|
[JsonProperty(PropertyName = "thumbnail")]
|
||||||
|
public ThumbnailInfo Thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "tts")]
|
[JsonProperty(PropertyName = "tts")]
|
||||||
public bool IsTextToSpeech;
|
public bool IsTextToSpeech;
|
||||||
@@ -179,7 +252,7 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "mentions")]
|
[JsonProperty(PropertyName = "mentions")]
|
||||||
public UserReference[] Mentions;
|
public UserReference[] Mentions;
|
||||||
[JsonProperty(PropertyName = "embeds")]
|
[JsonProperty(PropertyName = "embeds")]
|
||||||
public object[] Embeds; //TODO: Parse this
|
public Embed[] Embeds; //TODO: Parse this
|
||||||
[JsonProperty(PropertyName = "attachments")]
|
[JsonProperty(PropertyName = "attachments")]
|
||||||
public Attachment[] Attachments;
|
public Attachment[] Attachments;
|
||||||
[JsonProperty(PropertyName = "content")]
|
[JsonProperty(PropertyName = "content")]
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ namespace Discord.API.Models
|
|||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "token")]
|
[JsonProperty(PropertyName = "token")]
|
||||||
public string Token;
|
public string Token;
|
||||||
|
[JsonProperty(PropertyName = "v")]
|
||||||
|
public int Version = 2;
|
||||||
[JsonProperty(PropertyName = "properties")]
|
[JsonProperty(PropertyName = "properties")]
|
||||||
public Dictionary<string, string> Properties = new Dictionary<string, string>();
|
public Dictionary<string, string> Properties = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,24 @@ namespace Discord.API.Models
|
|||||||
{
|
{
|
||||||
public sealed class Ready
|
public sealed class Ready
|
||||||
{
|
{
|
||||||
|
public sealed class ReadStateInfo
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "id")]
|
||||||
|
public string ChannelId;
|
||||||
|
[JsonProperty(PropertyName = "mention_count")]
|
||||||
|
public int MentionCount;
|
||||||
|
[JsonProperty(PropertyName = "last_message_id")]
|
||||||
|
public string LastMessageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonProperty(PropertyName = "v")]
|
||||||
|
public int Version;
|
||||||
[JsonProperty(PropertyName = "user")]
|
[JsonProperty(PropertyName = "user")]
|
||||||
public SelfUserInfo User;
|
public SelfUserInfo User;
|
||||||
[JsonProperty(PropertyName = "session_id")]
|
[JsonProperty(PropertyName = "session_id")]
|
||||||
public string SessionId;
|
public string SessionId;
|
||||||
[JsonProperty(PropertyName = "read_state")]
|
[JsonProperty(PropertyName = "read_state")]
|
||||||
public object[] ReadState;
|
public ReadStateInfo[] ReadState;
|
||||||
[JsonProperty(PropertyName = "guilds")]
|
[JsonProperty(PropertyName = "guilds")]
|
||||||
public ExtendedServerInfo[] Guilds;
|
public ExtendedServerInfo[] Guilds;
|
||||||
[JsonProperty(PropertyName = "private_channels")]
|
[JsonProperty(PropertyName = "private_channels")]
|
||||||
@@ -36,32 +48,15 @@ namespace Discord.API.Models
|
|||||||
public sealed class ChannelUpdate : ChannelInfo { }
|
public sealed class ChannelUpdate : ChannelInfo { }
|
||||||
|
|
||||||
//Memberships
|
//Memberships
|
||||||
public abstract class GuildMemberEvent
|
public sealed class GuildMemberAdd : RoleMemberInfo { }
|
||||||
{
|
public sealed class GuildMemberUpdate : RoleMemberInfo { }
|
||||||
[JsonProperty(PropertyName = "user")]
|
public sealed class GuildMemberRemove : MemberInfo { }
|
||||||
public UserReference User;
|
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
}
|
|
||||||
public sealed class GuildMemberAdd : GuildMemberEvent
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "joined_at")]
|
|
||||||
public DateTime JoinedAt;
|
|
||||||
[JsonProperty(PropertyName = "roles")]
|
|
||||||
public string[] Roles;
|
|
||||||
}
|
|
||||||
public sealed class GuildMemberUpdate : GuildMemberEvent
|
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "roles")]
|
|
||||||
public string[] Roles;
|
|
||||||
}
|
|
||||||
public sealed class GuildMemberRemove : GuildMemberEvent { }
|
|
||||||
|
|
||||||
//Roles
|
//Roles
|
||||||
public abstract class GuildRoleEvent
|
public abstract class GuildRoleEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
public string GuildId;
|
public string ServerId;
|
||||||
}
|
}
|
||||||
public sealed class GuildRoleCreateUpdate : GuildRoleEvent
|
public sealed class GuildRoleCreateUpdate : GuildRoleEvent
|
||||||
{
|
{
|
||||||
@@ -78,7 +73,7 @@ namespace Discord.API.Models
|
|||||||
public abstract class GuildBanEvent
|
public abstract class GuildBanEvent
|
||||||
{
|
{
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
[JsonProperty(PropertyName = "guild_id")]
|
||||||
public string GuildId;
|
public string ServerId;
|
||||||
}
|
}
|
||||||
public sealed class GuildBanAddRemove : GuildBanEvent
|
public sealed class GuildBanAddRemove : GuildBanEvent
|
||||||
{
|
{
|
||||||
@@ -93,28 +88,8 @@ namespace Discord.API.Models
|
|||||||
|
|
||||||
//User
|
//User
|
||||||
public sealed class UserUpdate : SelfUserInfo { }
|
public sealed class UserUpdate : SelfUserInfo { }
|
||||||
public sealed class PresenceUpdate : PresenceUserInfo { }
|
public sealed class PresenceUpdate : PresenceMemberInfo { }
|
||||||
public sealed class VoiceStateUpdate
|
public sealed class VoiceStateUpdate : VoiceMemberInfo { }
|
||||||
{
|
|
||||||
[JsonProperty(PropertyName = "user_id")]
|
|
||||||
public string UserId;
|
|
||||||
[JsonProperty(PropertyName = "guild_id")]
|
|
||||||
public string GuildId;
|
|
||||||
[JsonProperty(PropertyName = "channel_id")]
|
|
||||||
public string ChannelId;
|
|
||||||
[JsonProperty(PropertyName = "suppress")]
|
|
||||||
public bool IsSuppressed;
|
|
||||||
[JsonProperty(PropertyName = "session_id")]
|
|
||||||
public string SessionId;
|
|
||||||
[JsonProperty(PropertyName = "self_mute")]
|
|
||||||
public bool IsSelfMuted;
|
|
||||||
[JsonProperty(PropertyName = "self_deaf")]
|
|
||||||
public bool IsSelfDeafened;
|
|
||||||
[JsonProperty(PropertyName = "mute")]
|
|
||||||
public bool IsMuted;
|
|
||||||
[JsonProperty(PropertyName = "deaf")]
|
|
||||||
public bool IsDeafened;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Chat
|
//Chat
|
||||||
public sealed class MessageCreate : Message { }
|
public sealed class MessageCreate : Message { }
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public sealed class Channel
|
public sealed class Channel
|
||||||
{
|
{
|
||||||
|
public sealed class PermissionOverwrite
|
||||||
|
{
|
||||||
|
public string Type { get; internal set; }
|
||||||
|
public string Id { get; internal set; }
|
||||||
|
public PackedPermissions Deny { get; internal set; }
|
||||||
|
public PackedPermissions Allow { get; internal set; }
|
||||||
|
}
|
||||||
|
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
/// <summary> Returns the unique identifier for this channel. </summary>
|
/// <summary> Returns the unique identifier for this channel. </summary>
|
||||||
@@ -15,6 +23,8 @@ namespace Discord
|
|||||||
/// <summary> Returns the name of this channel. </summary>
|
/// <summary> Returns the name of this channel. </summary>
|
||||||
public string Name { get { return !IsPrivate ? $"#{_name}" : $"@{Recipient.Name}"; } internal set { _name = value; } }
|
public string Name { get { return !IsPrivate ? $"#{_name}" : $"@{Recipient.Name}"; } internal set { _name = value; } }
|
||||||
|
|
||||||
|
/// <summary> Returns the position of this channel in the channel list for this server. </summary>
|
||||||
|
public int Position { get; internal set; }
|
||||||
/// <summary> Returns false is this is a public chat and true if this is a private chat with another user (see Recipient). </summary>
|
/// <summary> Returns false is this is a public chat and true if this is a private chat with another user (see Recipient). </summary>
|
||||||
public bool IsPrivate { get; }
|
public bool IsPrivate { get; }
|
||||||
/// <summary> Returns the type of this channel (see ChannelTypes). </summary>
|
/// <summary> Returns the type of this channel (see ChannelTypes). </summary>
|
||||||
@@ -37,9 +47,8 @@ namespace Discord
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.ChannelId == Id);
|
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.ChannelId == Id);
|
||||||
|
|
||||||
//TODO: Not Implemented
|
/// <summary> Returns a collection of all custom permissions used for this channel. </summary>
|
||||||
/// <summary> Not implemented, stored for reference. </summary>
|
public PermissionOverwrite[] PermissionOverwrites { get; internal set; }
|
||||||
public object[] PermissionOverwrites { get; internal set; }
|
|
||||||
|
|
||||||
internal Channel(string id, string serverId, DiscordClient client)
|
internal Channel(string id, string serverId, DiscordClient client)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -187,19 +187,19 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<MemberEventArgs> MemberAdded;
|
public event EventHandler<MemberEventArgs> MemberAdded;
|
||||||
private void RaiseMemberAdded(Membership membership, Server server)
|
private void RaiseMemberAdded(Membership membership)
|
||||||
{
|
{
|
||||||
if (MemberAdded != null)
|
if (MemberAdded != null)
|
||||||
MemberAdded(this, new MemberEventArgs(membership));
|
MemberAdded(this, new MemberEventArgs(membership));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> MemberRemoved;
|
public event EventHandler<MemberEventArgs> MemberRemoved;
|
||||||
private void RaiseMemberRemoved(Membership membership, Server server)
|
private void RaiseMemberRemoved(Membership membership)
|
||||||
{
|
{
|
||||||
if (MemberRemoved != null)
|
if (MemberRemoved != null)
|
||||||
MemberRemoved(this, new MemberEventArgs(membership));
|
MemberRemoved(this, new MemberEventArgs(membership));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> MemberUpdated;
|
public event EventHandler<MemberEventArgs> MemberUpdated;
|
||||||
private void RaiseMemberUpdated(Membership membership, Server server)
|
private void RaiseMemberUpdated(Membership membership)
|
||||||
{
|
{
|
||||||
if (MemberUpdated != null)
|
if (MemberUpdated != null)
|
||||||
MemberUpdated(this, new MemberEventArgs(membership));
|
MemberUpdated(this, new MemberEventArgs(membership));
|
||||||
@@ -217,11 +217,11 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<UserEventArgs> PresenceUpdated;
|
public event EventHandler<MemberEventArgs> PresenceUpdated;
|
||||||
private void RaisePresenceUpdated(User user)
|
private void RaisePresenceUpdated(Membership member)
|
||||||
{
|
{
|
||||||
if (PresenceUpdated != null)
|
if (PresenceUpdated != null)
|
||||||
PresenceUpdated(this, new UserEventArgs(user));
|
PresenceUpdated(this, new MemberEventArgs(member));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> VoiceStateUpdated;
|
public event EventHandler<MemberEventArgs> VoiceStateUpdated;
|
||||||
private void RaiseVoiceStateUpdated(Membership member)
|
private void RaiseVoiceStateUpdated(Membership member)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Discord.API.Models;
|
using Discord.API.Models;
|
||||||
using Discord.Helpers;
|
using Discord.Helpers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -19,10 +20,13 @@ namespace Discord
|
|||||||
private ManualResetEventSlim _isStopping;
|
private ManualResetEventSlim _isStopping;
|
||||||
private readonly Regex _userRegex, _channelRegex;
|
private readonly Regex _userRegex, _channelRegex;
|
||||||
private readonly MatchEvaluator _userRegexEvaluator, _channelRegexEvaluator;
|
private readonly MatchEvaluator _userRegexEvaluator, _channelRegexEvaluator;
|
||||||
|
private readonly JsonSerializer _serializer;
|
||||||
|
|
||||||
/// <summary> Returns the User object for the current logged in user. </summary>
|
/// <summary> Returns the User object for the current logged in user. </summary>
|
||||||
public User User { get; private set; }
|
public User User { get; private set; }
|
||||||
|
/// <summary> Returns the id of the current logged in user. </summary>
|
||||||
public string UserId { get; private set; }
|
public string UserId { get; private set; }
|
||||||
|
public string SessionId { get; private set; }
|
||||||
|
|
||||||
/// <summary> Returns a collection of all users the client can see across all servers. </summary>
|
/// <summary> Returns a collection of all users the client can see across all servers. </summary>
|
||||||
/// <remarks> This collection does not guarantee any ordering. </remarks>
|
/// <remarks> This collection does not guarantee any ordering. </remarks>
|
||||||
@@ -64,6 +68,12 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
_isStopping = new ManualResetEventSlim(false);
|
_isStopping = new ManualResetEventSlim(false);
|
||||||
|
|
||||||
|
_serializer = new JsonSerializer();
|
||||||
|
#if TEST_RESPONSES
|
||||||
|
_serializer.CheckAdditionalContent = true;
|
||||||
|
_serializer.MissingMemberHandling = MissingMemberHandling.Error;
|
||||||
|
#endif
|
||||||
|
|
||||||
_userRegex = new Regex(@"<@\d+?>", RegexOptions.Compiled);
|
_userRegex = new Regex(@"<@\d+?>", RegexOptions.Compiled);
|
||||||
_channelRegex = new Regex(@"<#\d+?>", RegexOptions.Compiled);
|
_channelRegex = new Regex(@"<#\d+?>", RegexOptions.Compiled);
|
||||||
_userRegexEvaluator = new MatchEvaluator(e =>
|
_userRegexEvaluator = new MatchEvaluator(e =>
|
||||||
@@ -90,11 +100,7 @@ namespace Discord
|
|||||||
(server, model) =>
|
(server, model) =>
|
||||||
{
|
{
|
||||||
server.Name = model.Name;
|
server.Name = model.Name;
|
||||||
if (!server.Channels.Any()) //A default channel always exists with the same id as the server.
|
_channels.Update(server.DefaultChannelId, server.Id, null);
|
||||||
{
|
|
||||||
var defaultChannel = new ChannelReference() { Id = server.DefaultChannelId, GuildId = server.Id };
|
|
||||||
_channels.Update(defaultChannel.Id, defaultChannel.GuildId, defaultChannel);
|
|
||||||
}
|
|
||||||
if (model is ExtendedServerInfo)
|
if (model is ExtendedServerInfo)
|
||||||
{
|
{
|
||||||
var extendedModel = model as ExtendedServerInfo;
|
var extendedModel = model as ExtendedServerInfo;
|
||||||
@@ -102,9 +108,7 @@ namespace Discord
|
|||||||
server.AFKTimeout = extendedModel.AFKTimeout;
|
server.AFKTimeout = extendedModel.AFKTimeout;
|
||||||
server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue;
|
server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue;
|
||||||
server.OwnerId = extendedModel.OwnerId;
|
server.OwnerId = extendedModel.OwnerId;
|
||||||
server.Presence = extendedModel.Presence;
|
|
||||||
server.Region = extendedModel.Region;
|
server.Region = extendedModel.Region;
|
||||||
server.VoiceStates = extendedModel.VoiceStates;
|
|
||||||
|
|
||||||
foreach (var role in extendedModel.Roles)
|
foreach (var role in extendedModel.Roles)
|
||||||
_roles.Update(role.Id, model.Id, role);
|
_roles.Update(role.Id, model.Id, role);
|
||||||
@@ -113,10 +117,12 @@ namespace Discord
|
|||||||
foreach (var membership in extendedModel.Members)
|
foreach (var membership in extendedModel.Members)
|
||||||
{
|
{
|
||||||
_users.Update(membership.User.Id, membership.User);
|
_users.Update(membership.User.Id, membership.User);
|
||||||
var newMember = new Membership(server.Id, membership.User.Id, membership.JoinedAt, this);
|
server.UpdateMember(membership);
|
||||||
newMember.Update(membership);
|
|
||||||
server.AddMember(newMember);
|
|
||||||
}
|
}
|
||||||
|
foreach (var membership in extendedModel.VoiceStates)
|
||||||
|
server.UpdateMember(membership);
|
||||||
|
foreach (var membership in extendedModel.Presences)
|
||||||
|
server.UpdateMember(membership);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
server => { }
|
server => { }
|
||||||
@@ -131,13 +137,27 @@ namespace Discord
|
|||||||
if (model is ChannelInfo)
|
if (model is ChannelInfo)
|
||||||
{
|
{
|
||||||
var extendedModel = model as ChannelInfo;
|
var extendedModel = model as ChannelInfo;
|
||||||
channel.PermissionOverwrites = extendedModel.PermissionOverwrites;
|
channel.Position = extendedModel.Position;
|
||||||
|
|
||||||
if (extendedModel.IsPrivate)
|
if (extendedModel.IsPrivate)
|
||||||
{
|
{
|
||||||
var user = _users.Update(extendedModel.Recipient.Id, extendedModel.Recipient);
|
var user = _users.Update(extendedModel.Recipient.Id, extendedModel.Recipient);
|
||||||
channel.RecipientId = user.Id;
|
channel.RecipientId = user.Id;
|
||||||
user.PrivateChannelId = channel.Id;
|
user.PrivateChannelId = channel.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extendedModel.PermissionOverwrites != null)
|
||||||
|
{
|
||||||
|
channel.PermissionOverwrites = extendedModel.PermissionOverwrites.Select(x => new Channel.PermissionOverwrite
|
||||||
|
{
|
||||||
|
Type = x.Type,
|
||||||
|
Id = x.Id,
|
||||||
|
Deny = new PackedPermissions(x.Deny),
|
||||||
|
Allow = new PackedPermissions(x.Allow)
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
channel.PermissionOverwrites = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
channel =>
|
channel =>
|
||||||
@@ -170,8 +190,41 @@ namespace Discord
|
|||||||
}).ToArray();
|
}).ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
extendedModel.Attachments = null;
|
message.Attachments = new Message.Attachment[0];
|
||||||
message.Embeds = extendedModel.Embeds;
|
if (extendedModel.Embeds != null)
|
||||||
|
{
|
||||||
|
message.Embeds = extendedModel.Embeds.Select(x =>
|
||||||
|
{
|
||||||
|
var embed = new Message.Embed
|
||||||
|
{
|
||||||
|
Url = x.Url,
|
||||||
|
Type = x.Type,
|
||||||
|
Description = x.Description,
|
||||||
|
Title = x.Title
|
||||||
|
};
|
||||||
|
if (x.Provider != null)
|
||||||
|
{
|
||||||
|
embed.Provider = new Message.EmbedProvider
|
||||||
|
{
|
||||||
|
Url = x.Provider.Url,
|
||||||
|
Name = x.Provider.Name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (x.Thumbnail != null)
|
||||||
|
{
|
||||||
|
embed.Thumbnail = new Message.File
|
||||||
|
{
|
||||||
|
Url = x.Thumbnail.Url,
|
||||||
|
ProxyUrl = x.Thumbnail.ProxyUrl,
|
||||||
|
Width = x.Thumbnail.Width,
|
||||||
|
Height = x.Thumbnail.Height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return embed;
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
message.Embeds = new Message.Embed[0];
|
||||||
message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
|
message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
|
||||||
message.IsTTS = extendedModel.IsTextToSpeech;
|
message.IsTTS = extendedModel.IsTextToSpeech;
|
||||||
message.MentionIds = extendedModel.Mentions?.Select(x => x.Id)?.ToArray() ?? new string[0];
|
message.MentionIds = extendedModel.Mentions?.Select(x => x.Id)?.ToArray() ?? new string[0];
|
||||||
@@ -206,12 +259,6 @@ namespace Discord
|
|||||||
var extendedModel = model as SelfUserInfo;
|
var extendedModel = model as SelfUserInfo;
|
||||||
user.Email = extendedModel.Email;
|
user.Email = extendedModel.Email;
|
||||||
user.IsVerified = extendedModel.IsVerified;
|
user.IsVerified = extendedModel.IsVerified;
|
||||||
}
|
|
||||||
if (model is PresenceUserInfo)
|
|
||||||
{
|
|
||||||
var extendedModel = model as PresenceUserInfo;
|
|
||||||
user.GameId = extendedModel.GameId;
|
|
||||||
user.Status = extendedModel.Status;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
user => { }
|
user => { }
|
||||||
@@ -246,13 +293,14 @@ namespace Discord
|
|||||||
//Global
|
//Global
|
||||||
case "READY": //Resync
|
case "READY": //Resync
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.Ready>();
|
var data = e.Event.ToObject<WebSocketEvents.Ready>(_serializer);
|
||||||
|
|
||||||
_servers.Clear();
|
_servers.Clear();
|
||||||
_channels.Clear();
|
_channels.Clear();
|
||||||
_users.Clear();
|
_users.Clear();
|
||||||
|
|
||||||
UserId = data.User.Id;
|
UserId = data.User.Id;
|
||||||
|
SessionId = data.SessionId;
|
||||||
User = _users.Update(data.User.Id, data.User);
|
User = _users.Update(data.User.Id, data.User);
|
||||||
foreach (var server in data.Guilds)
|
foreach (var server in data.Guilds)
|
||||||
_servers.Update(server.Id, server);
|
_servers.Update(server.Id, server);
|
||||||
@@ -264,83 +312,85 @@ namespace Discord
|
|||||||
//Servers
|
//Servers
|
||||||
case "GUILD_CREATE":
|
case "GUILD_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildCreate>(_serializer);
|
||||||
var server = _servers.Update(data.Id, data);
|
var server = _servers.Update(data.Id, data);
|
||||||
RaiseServerCreated(server);
|
try { RaiseServerCreated(server); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_UPDATE":
|
case "GUILD_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildUpdate>(_serializer);
|
||||||
var server = _servers.Update(data.Id, data);
|
var server = _servers.Update(data.Id, data);
|
||||||
RaiseServerUpdated(server);
|
try { RaiseServerUpdated(server); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_DELETE":
|
case "GUILD_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildDelete>(_serializer);
|
||||||
var server = _servers.Remove(data.Id);
|
var server = _servers.Remove(data.Id);
|
||||||
if (server != null)
|
if (server != null)
|
||||||
RaiseServerDestroyed(server);
|
try { RaiseServerDestroyed(server); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Channels
|
//Channels
|
||||||
case "CHANNEL_CREATE":
|
case "CHANNEL_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.ChannelCreate>(_serializer);
|
||||||
var channel = _channels.Update(data.Id, data.GuildId, data);
|
var channel = _channels.Update(data.Id, data.GuildId, data);
|
||||||
RaiseChannelCreated(channel);
|
try { RaiseChannelCreated(channel); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CHANNEL_UPDATE":
|
case "CHANNEL_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.ChannelUpdate>(_serializer);
|
||||||
var channel = _channels.Update(data.Id, data.GuildId, data);
|
var channel = _channels.Update(data.Id, data.GuildId, data);
|
||||||
RaiseChannelUpdated(channel);
|
try { RaiseChannelUpdated(channel); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CHANNEL_DELETE":
|
case "CHANNEL_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.ChannelDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.ChannelDelete>(_serializer);
|
||||||
var channel = _channels.Remove(data.Id);
|
var channel = _channels.Remove(data.Id);
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
RaiseChannelDestroyed(channel);
|
try { RaiseChannelDestroyed(channel); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Members
|
//Members
|
||||||
case "GUILD_MEMBER_ADD":
|
case "GUILD_MEMBER_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberAdd>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberAdd>(_serializer);
|
||||||
var user = _users.Update(data.User.Id, data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.ServerId];
|
||||||
var membership = new Membership(server.Id, data.User.Id, data.JoinedAt, this) { RoleIds = data.Roles };
|
if (server != null)
|
||||||
server.AddMember(membership);
|
{
|
||||||
RaiseMemberAdded(membership, server);
|
var member = server.UpdateMember(data);
|
||||||
|
try { RaiseMemberAdded(member); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_MEMBER_UPDATE":
|
case "GUILD_MEMBER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberUpdate>(_serializer);
|
||||||
var user = _users.Update(data.User.Id, data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.ServerId];
|
||||||
var membership = server.GetMember(data.User.Id);
|
if (server != null)
|
||||||
if (membership != null)
|
{
|
||||||
membership.RoleIds = data.Roles;
|
var member = server.UpdateMember(data);
|
||||||
RaiseMemberUpdated(membership, server);
|
try { RaiseMemberUpdated(member); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_MEMBER_REMOVE":
|
case "GUILD_MEMBER_REMOVE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildMemberRemove>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildMemberRemove>(_serializer);
|
||||||
var user = _users.Update(data.User.Id, data.User);
|
var server = _servers[data.ServerId];
|
||||||
var server = _servers[data.GuildId];
|
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
var membership = server.RemoveMember(user.Id);
|
var member = server.RemoveMember(data.UserId);
|
||||||
if (membership != null)
|
if (member != null)
|
||||||
RaiseMemberRemoved(membership, server);
|
try { RaiseMemberRemoved(member); } catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -348,121 +398,138 @@ namespace Discord
|
|||||||
//Roles
|
//Roles
|
||||||
case "GUILD_ROLE_CREATE":
|
case "GUILD_ROLE_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>(_serializer);
|
||||||
var role = _roles.Update(data.Role.Id, data.GuildId, data.Role);
|
var role = _roles.Update(data.Role.Id, data.ServerId, data.Role);
|
||||||
RaiseRoleCreated(role);
|
try { RaiseRoleCreated(role); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_ROLE_UPDATE":
|
case "GUILD_ROLE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildRoleCreateUpdate>(_serializer);
|
||||||
var role = _roles.Update(data.Role.Id, data.GuildId, data.Role);
|
var role = _roles.Update(data.Role.Id, data.ServerId, data.Role);
|
||||||
RaiseRoleUpdated(role);
|
try { RaiseRoleUpdated(role); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_ROLE_DELETE":
|
case "GUILD_ROLE_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildRoleDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildRoleDelete>(_serializer);
|
||||||
var role = _roles.Remove(data.RoleId);
|
var role = _roles.Remove(data.RoleId);
|
||||||
if (role != null)
|
if (role != null)
|
||||||
RaiseRoleDeleted(role);
|
try { RaiseRoleDeleted(role); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Bans
|
//Bans
|
||||||
case "GUILD_BAN_ADD":
|
case "GUILD_BAN_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>(_serializer);
|
||||||
var user = _users.Update(data.User.Id, data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.ServerId];
|
||||||
RaiseBanAdded(user, server);
|
try { RaiseBanAdded(user, server); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "GUILD_BAN_REMOVE":
|
case "GUILD_BAN_REMOVE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>();
|
var data = e.Event.ToObject<WebSocketEvents.GuildBanAddRemove>(_serializer);
|
||||||
var user = _users.Update(data.User.Id, data.User);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
var server = _servers[data.GuildId];
|
var server = _servers[data.ServerId];
|
||||||
if (server != null && server.RemoveBan(user.Id))
|
if (server != null && server.RemoveBan(user.Id))
|
||||||
RaiseBanRemoved(user, server);
|
{
|
||||||
|
try { RaiseBanRemoved(user, server); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Messages
|
//Messages
|
||||||
case "MESSAGE_CREATE":
|
case "MESSAGE_CREATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageCreate>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageCreate>(_serializer);
|
||||||
var msg = _messages.Update(data.Id, data.ChannelId, data);
|
var msg = _messages.Update(data.Id, data.ChannelId, data);
|
||||||
msg.User.UpdateActivity(data.Timestamp);
|
msg.User.UpdateActivity(data.Timestamp);
|
||||||
RaiseMessageCreated(msg);
|
try { RaiseMessageCreated(msg); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MESSAGE_UPDATE":
|
case "MESSAGE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageUpdate>(_serializer);
|
||||||
var msg = _messages.Update(data.Id, data.ChannelId, data);
|
var msg = _messages.Update(data.Id, data.ChannelId, data);
|
||||||
RaiseMessageUpdated(msg);
|
try { RaiseMessageUpdated(msg); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MESSAGE_DELETE":
|
case "MESSAGE_DELETE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageDelete>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageDelete>(_serializer);
|
||||||
var msg = GetMessage(data.MessageId);
|
var msg = GetMessage(data.MessageId);
|
||||||
if (msg != null)
|
if (msg != null)
|
||||||
|
{
|
||||||
_messages.Remove(msg.Id);
|
_messages.Remove(msg.Id);
|
||||||
|
try { RaiseMessageDeleted(msg); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MESSAGE_ACK":
|
case "MESSAGE_ACK":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.MessageAck>();
|
var data = e.Event.ToObject<WebSocketEvents.MessageAck>(_serializer);
|
||||||
var msg = GetMessage(data.MessageId);
|
var msg = GetMessage(data.MessageId);
|
||||||
RaiseMessageAcknowledged(msg);
|
if (msg != null)
|
||||||
|
try { RaiseMessageAcknowledged(msg); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Statuses
|
//Statuses
|
||||||
case "PRESENCE_UPDATE":
|
case "PRESENCE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.PresenceUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.PresenceUpdate>(_serializer);
|
||||||
var user = _users.Update(data.Id, data);
|
var user = _users.Update(data.User.Id, data.User);
|
||||||
RaisePresenceUpdated(user);
|
var server = _servers[data.ServerId];
|
||||||
|
if (server != null)
|
||||||
|
{
|
||||||
|
var member = server.UpdateMember(data);
|
||||||
|
try { RaisePresenceUpdated(member); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "VOICE_STATE_UPDATE":
|
case "VOICE_STATE_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.VoiceStateUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.VoiceStateUpdate>(_serializer);
|
||||||
var member = GetMember(data.GuildId, data.UserId);
|
var server = _servers[data.ServerId];
|
||||||
if (member != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
member.Update(data);
|
var member = server.UpdateMember(data);
|
||||||
RaiseVoiceStateUpdated(member);
|
if (member != null)
|
||||||
|
try { RaiseVoiceStateUpdated(member); } catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "TYPING_START":
|
case "TYPING_START":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.TypingStart>();
|
var data = e.Event.ToObject<WebSocketEvents.TypingStart>(_serializer);
|
||||||
var channel = _channels[data.ChannelId];
|
var channel = _channels[data.ChannelId];
|
||||||
var user = _users[data.UserId];
|
var user = _users[data.UserId];
|
||||||
RaiseUserTyping(user, channel);
|
if (user != null)
|
||||||
|
{
|
||||||
|
user.UpdateActivity(DateTime.UtcNow);
|
||||||
|
if (channel != null)
|
||||||
|
try { RaiseUserTyping(user, channel); } catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Voice
|
//Voice
|
||||||
case "VOICE_SERVER_UPDATE":
|
case "VOICE_SERVER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.VoiceServerUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.VoiceServerUpdate>(_serializer);
|
||||||
var server = _servers[data.ServerId];
|
var server = _servers[data.ServerId];
|
||||||
RaiseVoiceServerUpdated(server, data.Endpoint);
|
try { RaiseVoiceServerUpdated(server, data.Endpoint); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Settings
|
//Settings
|
||||||
case "USER_UPDATE":
|
case "USER_UPDATE":
|
||||||
{
|
{
|
||||||
var data = e.Event.ToObject<WebSocketEvents.UserUpdate>();
|
var data = e.Event.ToObject<WebSocketEvents.UserUpdate>(_serializer);
|
||||||
var user = _users.Update(data.Id, data);
|
var user = _users.Update(data.Id, data);
|
||||||
RaiseUserUpdated(user);
|
try { RaiseUserUpdated(user); } catch { }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "USER_SETTINGS_UPDATE":
|
case "USER_SETTINGS_UPDATE":
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
throw new InvalidOperationException("Bad Token");
|
throw new InvalidOperationException("Bad Token");
|
||||||
}
|
}
|
||||||
_connectWaitOnLogin2.Wait(cancelToken); //Waiting on READY handler
|
try { _connectWaitOnLogin2.Wait(cancelToken); } //Waiting on READY handler
|
||||||
|
catch (OperationCanceledException) { return; }
|
||||||
|
|
||||||
_isConnected = true;
|
_isConnected = true;
|
||||||
RaiseConnected();
|
RaiseConnected();
|
||||||
@@ -150,11 +151,7 @@ namespace Discord
|
|||||||
QueueMessage(new WebSocketCommands.KeepAlive());
|
QueueMessage(new WebSocketCommands.KeepAlive());
|
||||||
_connectWaitOnLogin.Set(); //Pre-Event
|
_connectWaitOnLogin.Set(); //Pre-Event
|
||||||
}
|
}
|
||||||
try
|
|
||||||
{
|
|
||||||
RaiseGotEvent(msg.Type, msg.Payload as JToken);
|
RaiseGotEvent(msg.Type, msg.Payload as JToken);
|
||||||
}
|
|
||||||
catch { } //Don't allow user exceptions to affect our state
|
|
||||||
if (msg.Type == "READY")
|
if (msg.Type == "READY")
|
||||||
_connectWaitOnLogin2.Set(); //Post-Event
|
_connectWaitOnLogin2.Set(); //Post-Event
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Discord.Helpers
|
|||||||
private readonly Action<TValue, TModel> _onUpdate;
|
private readonly Action<TValue, TModel> _onUpdate;
|
||||||
private readonly Action<TValue> _onRemove;
|
private readonly Action<TValue> _onRemove;
|
||||||
|
|
||||||
public AsyncCache(Func<string, string, TValue> onCreate, Action<TValue, TModel> onUpdate, Action<TValue> onRemove)
|
public AsyncCache(Func<string, string, TValue> onCreate, Action<TValue, TModel> onUpdate, Action<TValue> onRemove = null)
|
||||||
{
|
{
|
||||||
_dictionary = new ConcurrentDictionary<string, TValue>();
|
_dictionary = new ConcurrentDictionary<string, TValue>();
|
||||||
_onCreate = onCreate;
|
_onCreate = onCreate;
|
||||||
@@ -49,6 +49,7 @@ namespace Discord.Helpers
|
|||||||
isNew = !_dictionary.TryGetValue(key, out value);
|
isNew = !_dictionary.TryGetValue(key, out value);
|
||||||
if (isNew)
|
if (isNew)
|
||||||
value = _onCreate(key, parentKey);
|
value = _onCreate(key, parentKey);
|
||||||
|
if (model != null)
|
||||||
_onUpdate(value, model);
|
_onUpdate(value, model);
|
||||||
if (isNew)
|
if (isNew)
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,11 @@ namespace Discord.Helpers
|
|||||||
{
|
{
|
||||||
TValue value = null;
|
TValue value = null;
|
||||||
if (_dictionary.TryRemove(key, out value))
|
if (_dictionary.TryRemove(key, out value))
|
||||||
|
{
|
||||||
|
if (_onRemove != null)
|
||||||
|
_onRemove(value);
|
||||||
return value;
|
return value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using System.Globalization;
|
|||||||
|
|
||||||
#if TEST_RESPONSES
|
#if TEST_RESPONSES
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using JsonErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Discord.Helpers
|
namespace Discord.Helpers
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ namespace Discord
|
|||||||
public bool IsSuppressed { get; internal set; }
|
public bool IsSuppressed { get; internal set; }
|
||||||
|
|
||||||
public string SessionId { get; internal set; }
|
public string SessionId { get; internal set; }
|
||||||
|
public string Token { get; internal set; }
|
||||||
|
/// <summary> Returns the id for the game this user is currently playing. </summary>
|
||||||
|
public string GameId { get; internal set; }
|
||||||
|
/// <summary> Returns the current status for this user. </summary>
|
||||||
|
public string Status { get; internal set; }
|
||||||
|
|
||||||
public string ServerId { get; }
|
public string ServerId { get; }
|
||||||
public Server Server => _client.GetServer(ServerId);
|
public Server Server => _client.GetServer(ServerId);
|
||||||
@@ -31,29 +36,11 @@ namespace Discord
|
|||||||
public string[] RoleIds { get; internal set; }
|
public string[] RoleIds { get; internal set; }
|
||||||
public IEnumerable<Role> Roles => RoleIds.Select(x => _client.GetRole(x));
|
public IEnumerable<Role> Roles => RoleIds.Select(x => _client.GetRole(x));
|
||||||
|
|
||||||
public Membership(string serverId, string userId, DateTime joinedAt, DiscordClient client)
|
public Membership(string serverId, string userId, DiscordClient client)
|
||||||
{
|
{
|
||||||
ServerId = serverId;
|
ServerId = serverId;
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
JoinedAt = joinedAt;
|
|
||||||
_client = client;
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update(ExtendedServerInfo.Membership data)
|
|
||||||
{
|
|
||||||
IsDeafened = data.IsDeaf;
|
|
||||||
IsMuted = data.IsMuted;
|
|
||||||
RoleIds = data.Roles;
|
|
||||||
}
|
|
||||||
internal void Update(WebSocketEvents.VoiceStateUpdate data)
|
|
||||||
{
|
|
||||||
VoiceChannelId = data.ChannelId;
|
|
||||||
IsDeafened = data.IsDeafened;
|
|
||||||
IsMuted = data.IsMuted;
|
|
||||||
IsSelfDeafened = data.IsSelfDeafened;
|
|
||||||
IsSelfMuted = data.IsSelfMuted;
|
|
||||||
IsSuppressed = data.IsSuppressed;
|
|
||||||
SessionId = data.SessionId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,39 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public sealed class Message
|
public sealed class Message
|
||||||
{
|
{
|
||||||
public class Attachment
|
public sealed class Attachment : File
|
||||||
{
|
{
|
||||||
/// <summary> Unique identifier for this file. </summary>
|
/// <summary> Unique identifier for this file. </summary>
|
||||||
public string Id { get; internal set; }
|
public string Id { get; internal set; }
|
||||||
|
/// <summary> Size, in bytes, of this file file. </summary>
|
||||||
|
public int Size { get; internal set; }
|
||||||
|
/// <summary> Filename of this file. </summary>
|
||||||
|
public string Filename { get; internal set; }
|
||||||
|
}
|
||||||
|
public sealed class Embed
|
||||||
|
{
|
||||||
|
/// <summary> URL of this embed. </summary>
|
||||||
|
public string Url { get; internal set; }
|
||||||
|
/// <summary> Type of this embed. </summary>
|
||||||
|
public string Type { get; internal set; }
|
||||||
|
/// <summary> Title for this embed. </summary>
|
||||||
|
public string Title { get; internal set; }
|
||||||
|
/// <summary> Summary of this embed. </summary>
|
||||||
|
public string Description { get; internal set; }
|
||||||
|
/// <summary> Returns information about the providing website of this embed. </summary>
|
||||||
|
public EmbedProvider Provider { get; internal set; }
|
||||||
|
/// <summary> Returns the thumbnail of this embed. </summary>
|
||||||
|
public File Thumbnail { get; internal set; }
|
||||||
|
}
|
||||||
|
public sealed class EmbedProvider
|
||||||
|
{
|
||||||
|
/// <summary> URL of this embed provider. </summary>
|
||||||
|
public string Url { get; internal set; }
|
||||||
|
/// <summary> Name of this embed provider. </summary>
|
||||||
|
public string Name { get; internal set; }
|
||||||
|
}
|
||||||
|
public class File
|
||||||
|
{
|
||||||
/// <summary> Download url for this file. </summary>
|
/// <summary> Download url for this file. </summary>
|
||||||
public string Url { get; internal set; }
|
public string Url { get; internal set; }
|
||||||
/// <summary> Preview url for this file. </summary>
|
/// <summary> Preview url for this file. </summary>
|
||||||
@@ -19,10 +48,6 @@ namespace Discord
|
|||||||
public int? Width { get; internal set; }
|
public int? Width { get; internal set; }
|
||||||
/// <summary> Height of this file, if it is an image. </summary>
|
/// <summary> Height of this file, if it is an image. </summary>
|
||||||
public int? Height { get; internal set; }
|
public int? Height { get; internal set; }
|
||||||
/// <summary> Size, in bytes, of this file file. </summary>
|
|
||||||
public int Size { get; internal set; }
|
|
||||||
/// <summary> Filename of this file. </summary>
|
|
||||||
public string Filename { get; internal set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
@@ -49,6 +74,9 @@ namespace Discord
|
|||||||
public DateTime? EditedTimestamp { get; internal set; }
|
public DateTime? EditedTimestamp { get; internal set; }
|
||||||
/// <summary> Returns the attachments included in this message. </summary>
|
/// <summary> Returns the attachments included in this message. </summary>
|
||||||
public Attachment[] Attachments { get; internal set; }
|
public Attachment[] Attachments { get; internal set; }
|
||||||
|
//TODO: Not Implemented
|
||||||
|
/// <summary> Returns a collection of all embeded content in this message. </summary>
|
||||||
|
public Embed[] Embeds { get; internal set; }
|
||||||
|
|
||||||
/// <summary> Returns a collection of all user ids mentioned in this message. </summary>
|
/// <summary> Returns a collection of all user ids mentioned in this message. </summary>
|
||||||
public string[] MentionIds { get; internal set; }
|
public string[] MentionIds { get; internal set; }
|
||||||
@@ -68,10 +96,6 @@ namespace Discord
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public User User => _client.GetUser(UserId);
|
public User User => _client.GetUser(UserId);
|
||||||
|
|
||||||
//TODO: Not Implemented
|
|
||||||
/// <summary> Not implemented, stored for reference. </summary>
|
|
||||||
public object[] Embeds { get; internal set; }
|
|
||||||
|
|
||||||
internal Message(string id, string channelId, DiscordClient client)
|
internal Message(string id, string channelId, DiscordClient client)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
|
|||||||
67
src/Discord.Net/PackedPermissions.cs
Normal file
67
src/Discord.Net/PackedPermissions.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
public sealed class PackedPermissions
|
||||||
|
{
|
||||||
|
private uint _rawValue;
|
||||||
|
internal uint RawValue { get { return _rawValue; } set { _rawValue = value; } }
|
||||||
|
|
||||||
|
internal PackedPermissions() { }
|
||||||
|
internal PackedPermissions(uint rawValue) { _rawValue = rawValue; }
|
||||||
|
|
||||||
|
/// <summary> If True, a user may create invites. </summary>
|
||||||
|
public bool General_CreateInstantInvite => ((_rawValue >> 0) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may ban users from the server. </summary>
|
||||||
|
public bool General_BanMembers => ((_rawValue >> 1) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may kick users from the server. </summary>
|
||||||
|
public bool General_KickMembers => ((_rawValue >> 2) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user adjust roles. </summary>
|
||||||
|
/// <remarks> Having this permission effectively gives all the others as a user may add them to themselves. </remarks>
|
||||||
|
public bool General_ManageRoles => ((_rawValue >> 3) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may create, delete and modify channels. </summary>
|
||||||
|
public bool General_ManageChannels => ((_rawValue >> 4) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may adjust server properties. </summary>
|
||||||
|
public bool General_ManageServer => ((_rawValue >> 5) & 0x1) == 1;
|
||||||
|
|
||||||
|
//4 Unused
|
||||||
|
|
||||||
|
/// <summary> If True, a user may join channels. </summary>
|
||||||
|
/// <remarks> Note that without this permission, a channel is not sent by the server. </remarks>
|
||||||
|
public bool Text_ReadMessages => ((_rawValue >> 10) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may send messages. </summary>
|
||||||
|
public bool Text_SendMessages => ((_rawValue >> 11) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may send text-to-speech messages. </summary>
|
||||||
|
public bool Text_SendTTSMessages => ((_rawValue >> 12) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may delete messages. </summary>
|
||||||
|
public bool Text_ManageMessages => ((_rawValue >> 13) & 0x1) == 1;
|
||||||
|
/// <summary> If True, Discord will auto-embed links sent by this user. </summary>
|
||||||
|
public bool Text_EmbedLinks => ((_rawValue >> 14) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may send files. </summary>
|
||||||
|
public bool Text_AttachFiles => ((_rawValue >> 15) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may read previous messages. </summary>
|
||||||
|
public bool Text_ReadMessageHistory => ((_rawValue >> 16) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may mention @everyone. </summary>
|
||||||
|
public bool Text_MentionEveryone => ((_rawValue >> 17) & 0x1) == 1;
|
||||||
|
|
||||||
|
//2 Unused
|
||||||
|
|
||||||
|
/// <summary> If True, a user may connect to a voice channel. </summary>
|
||||||
|
public bool Voice_Connect => ((_rawValue >> 20) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may speak in a voice channel. </summary>
|
||||||
|
public bool Voice_Speak => ((_rawValue >> 21) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may mute users. </summary>
|
||||||
|
public bool Voice_MuteMembers => ((_rawValue >> 22) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may deafen users. </summary>
|
||||||
|
public bool Voice_DeafenMembers => ((_rawValue >> 23) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may move other users between voice channels. </summary>
|
||||||
|
public bool Voice_MoveMembers => ((_rawValue >> 24) & 0x1) == 1;
|
||||||
|
/// <summary> If True, a user may use voice activation rather than push-to-talk. </summary>
|
||||||
|
public bool Voice_UseVoiceActivation => ((_rawValue >> 25) & 0x1) == 1;
|
||||||
|
|
||||||
|
//6 Unused
|
||||||
|
|
||||||
|
public static implicit operator uint (PackedPermissions perms)
|
||||||
|
{
|
||||||
|
return perms._rawValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,70 +4,6 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public sealed class Role
|
public sealed class Role
|
||||||
{
|
{
|
||||||
public sealed class PackedPermissions
|
|
||||||
{
|
|
||||||
private uint _rawValue;
|
|
||||||
internal uint RawValue { get { return _rawValue; } set { _rawValue = value; } }
|
|
||||||
|
|
||||||
internal PackedPermissions() { }
|
|
||||||
|
|
||||||
/// <summary> If True, a user may create invites. </summary>
|
|
||||||
public bool General_CreateInstantInvite => ((_rawValue >> 0) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may ban users from the server. </summary>
|
|
||||||
public bool General_BanMembers => ((_rawValue >> 1) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may kick users from the server. </summary>
|
|
||||||
public bool General_KickMembers => ((_rawValue >> 2) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user adjust roles. </summary>
|
|
||||||
/// <remarks> Having this permission effectively gives all the others as a user may add them to themselves. </remarks>
|
|
||||||
public bool General_ManageRoles => ((_rawValue >> 3) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may create, delete and modify channels. </summary>
|
|
||||||
public bool General_ManageChannels => ((_rawValue >> 4) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may adjust server properties. </summary>
|
|
||||||
public bool General_ManageServer => ((_rawValue >> 5) & 0x1) == 1;
|
|
||||||
|
|
||||||
//4 Unused
|
|
||||||
|
|
||||||
/// <summary> If True, a user may join channels. </summary>
|
|
||||||
/// <remarks> Note that without this permission, a channel is not sent by the server. </remarks>
|
|
||||||
public bool Text_ReadMessages => ((_rawValue >> 10) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may send messages. </summary>
|
|
||||||
public bool Text_SendMessages => ((_rawValue >> 11) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may send text-to-speech messages. </summary>
|
|
||||||
public bool Text_SendTTSMessages => ((_rawValue >> 12) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may delete messages. </summary>
|
|
||||||
public bool Text_ManageMessages => ((_rawValue >> 13) & 0x1) == 1;
|
|
||||||
/// <summary> If True, Discord will auto-embed links sent by this user. </summary>
|
|
||||||
public bool Text_EmbedLinks => ((_rawValue >> 14) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may send files. </summary>
|
|
||||||
public bool Text_AttachFiles => ((_rawValue >> 15) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may read previous messages. </summary>
|
|
||||||
public bool Text_ReadMessageHistory => ((_rawValue >> 16) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may mention @everyone. </summary>
|
|
||||||
public bool Text_MentionEveryone => ((_rawValue >> 17) & 0x1) == 1;
|
|
||||||
|
|
||||||
//2 Unused
|
|
||||||
|
|
||||||
/// <summary> If True, a user may connect to a voice channel. </summary>
|
|
||||||
public bool Voice_Connect => ((_rawValue >> 20) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may speak in a voice channel. </summary>
|
|
||||||
public bool Voice_Speak => ((_rawValue >> 21) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may mute users. </summary>
|
|
||||||
public bool Voice_MuteMembers => ((_rawValue >> 22) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may deafen users. </summary>
|
|
||||||
public bool Voice_DeafenMembers => ((_rawValue >> 23) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may move other users between voice channels. </summary>
|
|
||||||
public bool Voice_MoveMembers => ((_rawValue >> 24) & 0x1) == 1;
|
|
||||||
/// <summary> If True, a user may use voice activation rather than push-to-talk. </summary>
|
|
||||||
public bool Voice_UseVoiceActivation => ((_rawValue >> 25) & 0x1) == 1;
|
|
||||||
|
|
||||||
//6 Unused
|
|
||||||
|
|
||||||
public static implicit operator uint(PackedPermissions perms)
|
|
||||||
{
|
|
||||||
return perms._rawValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
/// <summary> Returns the unique identifier for this role. </summary>
|
/// <summary> Returns the unique identifier for this role. </summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Discord.Helpers;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -38,9 +39,9 @@ namespace Discord
|
|||||||
/// <summary> Returns the default channel for this server. </summary>
|
/// <summary> Returns the default channel for this server. </summary>
|
||||||
public Channel DefaultChannel =>_client.GetChannel(DefaultChannelId);
|
public Channel DefaultChannel =>_client.GetChannel(DefaultChannelId);
|
||||||
|
|
||||||
internal ConcurrentDictionary<string, Membership> _members;
|
internal AsyncCache<Membership, API.Models.MemberInfo> _members;
|
||||||
/// <summary> Returns a collection of all channels within this server. </summary>
|
/// <summary> Returns a collection of all channels within this server. </summary>
|
||||||
public IEnumerable<Membership> Members => _members.Values;
|
public IEnumerable<Membership> Members => _members;
|
||||||
|
|
||||||
internal ConcurrentDictionary<string, bool> _bans;
|
internal ConcurrentDictionary<string, bool> _bans;
|
||||||
/// <summary> Returns a collection of all users banned on this server. </summary>
|
/// <summary> Returns a collection of all users banned on this server. </summary>
|
||||||
@@ -54,38 +55,59 @@ namespace Discord
|
|||||||
/// <summary> Returns a collection of all roles within this server. </summary>
|
/// <summary> Returns a collection of all roles within this server. </summary>
|
||||||
public IEnumerable<Role> Roles => _client.Roles.Where(x => x.ServerId == Id);
|
public IEnumerable<Role> Roles => _client.Roles.Where(x => x.ServerId == Id);
|
||||||
|
|
||||||
//TODO: Not Implemented
|
|
||||||
/// <summary> Not implemented, stored for reference. </summary>
|
|
||||||
public object Presence { get; internal set; }
|
|
||||||
//TODO: Not Implemented
|
|
||||||
/// <summary> Not implemented, stored for reference. </summary>
|
|
||||||
public object[] VoiceStates { get; internal set; }
|
|
||||||
|
|
||||||
internal Server(string id, DiscordClient client)
|
internal Server(string id, DiscordClient client)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
_client = client;
|
_client = client;
|
||||||
_members = new ConcurrentDictionary<string, Membership>();
|
|
||||||
_bans = new ConcurrentDictionary<string, bool>();
|
_bans = new ConcurrentDictionary<string, bool>();
|
||||||
|
_members = new AsyncCache<Membership, API.Models.MemberInfo>(
|
||||||
|
(key, parentKey) => new Membership(parentKey, key, _client),
|
||||||
|
(member, model) =>
|
||||||
|
{
|
||||||
|
if (model is API.Models.PresenceMemberInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as API.Models.PresenceMemberInfo;
|
||||||
|
member.Status = extendedModel.Status;
|
||||||
|
member.GameId = extendedModel.GameId;
|
||||||
|
}
|
||||||
|
if (model is API.Models.VoiceMemberInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as API.Models.VoiceMemberInfo;
|
||||||
|
member.VoiceChannelId = extendedModel.ChannelId;
|
||||||
|
member.IsDeafened = extendedModel.IsDeafened;
|
||||||
|
member.IsMuted = extendedModel.IsMuted;
|
||||||
|
member.IsSelfDeafened = extendedModel.IsSelfDeafened;
|
||||||
|
member.IsSelfMuted = extendedModel.IsSelfMuted;
|
||||||
|
member.IsSuppressed = extendedModel.IsSuppressed;
|
||||||
|
member.SessionId = extendedModel.SessionId;
|
||||||
|
member.Token = extendedModel.Token;
|
||||||
|
}
|
||||||
|
if (model is API.Models.RoleMemberInfo)
|
||||||
|
{
|
||||||
|
var extendedModel = model as API.Models.RoleMemberInfo;
|
||||||
|
member.IsDeafened = extendedModel.IsDeafened;
|
||||||
|
member.IsMuted = extendedModel.IsMuted;
|
||||||
|
member.RoleIds = extendedModel.Roles;
|
||||||
|
if (extendedModel.JoinedAt.HasValue)
|
||||||
|
member.JoinedAt = extendedModel.JoinedAt.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddMember(Membership membership)
|
internal Membership UpdateMember(API.Models.MemberInfo membership)
|
||||||
{
|
{
|
||||||
_members[membership.UserId] = membership;
|
return _members.Update(membership.User?.Id ?? membership.UserId, Id, membership);
|
||||||
}
|
}
|
||||||
internal Membership RemoveMember(string userId)
|
internal Membership RemoveMember(string userId)
|
||||||
{
|
{
|
||||||
Membership result = null;
|
return _members.Remove(userId);
|
||||||
_members.TryRemove(userId, out result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
public Membership GetMembership(User user)
|
public Membership GetMembership(User user)
|
||||||
=> GetMember(user.Id);
|
=> GetMember(user.Id);
|
||||||
public Membership GetMember(string userId)
|
public Membership GetMember(string userId)
|
||||||
{
|
{
|
||||||
Membership result = null;
|
return _members[userId];
|
||||||
_members.TryGetValue(userId, out result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddBan(string banId)
|
internal void AddBan(string banId)
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ namespace Discord
|
|||||||
/// <summary> Returns if the email for this user has been verified. </summary>
|
/// <summary> Returns if the email for this user has been verified. </summary>
|
||||||
/// <remarks> This field is only ever populated for the current logged in user. </remarks>
|
/// <remarks> This field is only ever populated for the current logged in user. </remarks>
|
||||||
public bool IsVerified { get; internal set; }
|
public bool IsVerified { get; internal set; }
|
||||||
/// <summary> Returns the id for the game this user is currently playing. </summary>
|
|
||||||
public string GameId { get; internal set; }
|
|
||||||
/// <summary> Returns the current status for this user. </summary>
|
|
||||||
public string Status { get; internal set; }
|
|
||||||
|
|
||||||
/// <summary> Returns the string "<@Id>" to be used as a shortcut when including mentions in text. </summary>
|
/// <summary> Returns the string "<@Id>" to be used as a shortcut when including mentions in text. </summary>
|
||||||
public string Mention { get { return $"<@{Id}>"; } }
|
public string Mention { get { return $"<@{Id}>"; } }
|
||||||
|
|||||||
Reference in New Issue
Block a user