| @@ -2,6 +2,7 @@ | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| //TODO: Check support for escaping | |||||
| public static class CommandParser | public static class CommandParser | ||||
| { | { | ||||
| private enum CommandParserPart | private enum CommandParserPart | ||||
| @@ -35,6 +35,17 @@ | |||||
| <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FullDebug|AnyCPU'"> | |||||
| <DebugSymbols>true</DebugSymbols> | |||||
| <OutputPath>bin\FullDebug\</OutputPath> | |||||
| <DefineConstants>TRACE;DEBUG;NET45,TEST_RESPONSES</DefineConstants> | |||||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||||
| <WarningLevel>2</WarningLevel> | |||||
| <DebugType>full</DebugType> | |||||
| <PlatformTarget>AnyCPU</PlatformTarget> | |||||
| <ErrorReport>prompt</ErrorReport> | |||||
| <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | <ItemGroup> | ||||
| <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | ||||
| <HintPath>..\..\..\DiscordBot\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> | <HintPath>..\..\..\DiscordBot\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> | ||||
| @@ -57,6 +68,33 @@ | |||||
| <None Include="packages.config" /> | <None Include="packages.config" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Compile Include="..\Discord.Net\API\Common.cs"> | |||||
| <Link>API\Common.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\Endpoints.cs"> | |||||
| <Link>API\Endpoints.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\HttpException.cs"> | |||||
| <Link>API\HttpException.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\Requests.cs"> | |||||
| <Link>API\Requests.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\Responses.cs"> | |||||
| <Link>API\Responses.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\RestClient.BuiltIn.cs"> | |||||
| <Link>API\RestClient.BuiltIn.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\RestClient.cs"> | |||||
| <Link>API\RestClient.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\RestClient.Events.cs"> | |||||
| <Link>API\RestClient.Events.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\API\RestClient.SharpRest.cs"> | |||||
| <Link>API\RestClient.SharpRest.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Audio\Opus.cs"> | <Compile Include="..\Discord.Net\Audio\Opus.cs"> | ||||
| <Link>Audio\Opus.cs</Link> | <Link>Audio\Opus.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -84,6 +122,9 @@ | |||||
| <Compile Include="..\Discord.Net\Collections\Users.cs"> | <Compile Include="..\Discord.Net\Collections\Users.cs"> | ||||
| <Link>Collections\Users.cs</Link> | <Link>Collections\Users.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\DiscordAPIClient.cs"> | |||||
| <Link>DiscordAPIClient.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\DiscordClient.API.cs"> | <Compile Include="..\Discord.Net\DiscordClient.API.cs"> | ||||
| <Link>DiscordClient.API.cs</Link> | <Link>DiscordClient.API.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -150,74 +191,44 @@ | |||||
| <Compile Include="..\Discord.Net\Models\User.cs"> | <Compile Include="..\Discord.Net\Models\User.cs"> | ||||
| <Link>Models\User.cs</Link> | <Link>Models\User.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\API\Common.cs"> | |||||
| <Link>Net\API\Common.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\DiscordAPIClient.cs"> | |||||
| <Link>Net\API\DiscordAPIClient.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\Endpoints.cs"> | |||||
| <Link>Net\API\Endpoints.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\HttpException.cs"> | |||||
| <Link>Net\API\HttpException.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\Requests.cs"> | |||||
| <Link>Net\API\Requests.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\Responses.cs"> | |||||
| <Link>Net\API\Responses.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\RestClient.BuiltIn.cs"> | |||||
| <Link>Net\API\RestClient.BuiltIn.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\RestClient.cs"> | |||||
| <Link>Net\API\RestClient.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\RestClient.Events.cs"> | |||||
| <Link>Net\API\RestClient.Events.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\API\RestClient.SharpRest.cs"> | |||||
| <Link>Net\API\RestClient.SharpRest.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Net\WebSockets\Commands.cs"> | |||||
| <Link>Net\WebSockets\Commands.cs</Link> | |||||
| <Compile Include="..\Discord.Net\TimeoutException.cs"> | |||||
| <Link>TimeoutException.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\DataWebSocket.cs"> | |||||
| <Link>Net\WebSockets\DataWebSocket.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Data\Commands.cs"> | |||||
| <Link>WebSockets\Data\Commands.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\DataWebSockets.Events.cs"> | |||||
| <Link>Net\WebSockets\DataWebSockets.Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Data\DataWebSocket.cs"> | |||||
| <Link>WebSockets\Data\DataWebSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\Events.cs"> | |||||
| <Link>Net\WebSockets\Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Data\DataWebSockets.Events.cs"> | |||||
| <Link>WebSockets\Data\DataWebSockets.Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\VoiceCommands.cs"> | |||||
| <Link>Net\WebSockets\VoiceCommands.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Data\Events.cs"> | |||||
| <Link>WebSockets\Data\Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\VoiceEvents.cs"> | |||||
| <Link>Net\WebSockets\VoiceEvents.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Voice\Commands.cs"> | |||||
| <Link>WebSockets\Voice\Commands.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\VoiceWebSocket.cs"> | |||||
| <Link>Net\WebSockets\VoiceWebSocket.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Voice\Events.cs"> | |||||
| <Link>WebSockets\Voice\Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\VoiceWebSocket.Events.cs"> | |||||
| <Link>Net\WebSockets\VoiceWebSocket.Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.cs"> | |||||
| <Link>WebSockets\Voice\VoiceWebSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.BuiltIn.cs"> | |||||
| <Link>Net\WebSockets\WebSocket.BuiltIn.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.Events.cs"> | |||||
| <Link>WebSockets\Voice\VoiceWebSocket.Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.cs"> | |||||
| <Link>Net\WebSockets\WebSocket.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\WebSocket.BuiltIn.cs"> | |||||
| <Link>WebSockets\WebSocket.BuiltIn.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.Events.cs"> | |||||
| <Link>Net\WebSockets\WebSocket.Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\WebSocket.cs"> | |||||
| <Link>WebSockets\WebSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WebSocketMessage.cs"> | |||||
| <Link>Net\WebSockets\WebSocketMessage.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\WebSocket.Events.cs"> | |||||
| <Link>WebSockets\WebSocket.Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\TimeoutException.cs"> | |||||
| <Link>TimeoutException.cs</Link> | |||||
| <Compile Include="..\Discord.Net\WebSockets\WebSocketMessage.cs"> | |||||
| <Link>WebSockets\WebSocketMessage.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="Properties\AssemblyInfo.cs" /> | <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| @@ -0,0 +1,295 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| namespace Discord.API | |||||
| { | |||||
| //User | |||||
| public class UserReference | |||||
| { | |||||
| [JsonProperty("username")] | |||||
| public string Username; | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("discriminator")] | |||||
| public string Discriminator; | |||||
| [JsonProperty("avatar")] | |||||
| public string Avatar; | |||||
| } | |||||
| public class SelfUserInfo : UserReference | |||||
| { | |||||
| [JsonProperty("email")] | |||||
| public string Email; | |||||
| [JsonProperty("verified")] | |||||
| public bool IsVerified; | |||||
| } | |||||
| //Members | |||||
| public class MemberReference | |||||
| { | |||||
| [JsonProperty("user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty("user")] | |||||
| public UserReference User; | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| } | |||||
| public class MemberInfo : MemberReference | |||||
| { | |||||
| [JsonProperty("joined_at")] | |||||
| public DateTime? JoinedAt; | |||||
| [JsonProperty("roles")] | |||||
| public string[] Roles; | |||||
| } | |||||
| public class ExtendedMemberInfo : MemberInfo | |||||
| { | |||||
| [JsonProperty("mute")] | |||||
| public bool IsMuted; | |||||
| [JsonProperty("deaf")] | |||||
| public bool IsDeafened; | |||||
| } | |||||
| public class PresenceMemberInfo : MemberReference | |||||
| { | |||||
| [JsonProperty("game_id")] | |||||
| public string GameId; | |||||
| [JsonProperty("status")] | |||||
| public string Status; | |||||
| } | |||||
| public class VoiceMemberInfo : MemberReference | |||||
| { | |||||
| [JsonProperty("channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty("suppress")] | |||||
| public bool? IsSuppressed; | |||||
| [JsonProperty("session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty("self_mute")] | |||||
| public bool? IsSelfMuted; | |||||
| [JsonProperty("self_deaf")] | |||||
| public bool? IsSelfDeafened; | |||||
| [JsonProperty("mute")] | |||||
| public bool IsMuted; | |||||
| [JsonProperty("deaf")] | |||||
| public bool IsDeafened; | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| } | |||||
| //Channels | |||||
| public class ChannelReference | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| [JsonProperty("type")] | |||||
| public string Type; | |||||
| } | |||||
| public class ChannelInfo : ChannelReference | |||||
| { | |||||
| public sealed class PermissionOverwrite | |||||
| { | |||||
| [JsonProperty("type")] | |||||
| public string Type; | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("deny")] | |||||
| public uint Deny; | |||||
| [JsonProperty("allow")] | |||||
| public uint Allow; | |||||
| } | |||||
| [JsonProperty("last_message_id")] | |||||
| public string LastMessageId; | |||||
| [JsonProperty("is_private")] | |||||
| public bool IsPrivate; | |||||
| [JsonProperty("position")] | |||||
| public int Position; | |||||
| [JsonProperty("permission_overwrites")] | |||||
| public PermissionOverwrite[] PermissionOverwrites; | |||||
| [JsonProperty("recipient")] | |||||
| public UserReference Recipient; | |||||
| } | |||||
| //Guilds (Servers) | |||||
| public class GuildReference | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| } | |||||
| public class GuildInfo : GuildReference | |||||
| { | |||||
| [JsonProperty("afk_channel_id")] | |||||
| public string AFKChannelId; | |||||
| [JsonProperty("afk_timeout")] | |||||
| public int AFKTimeout; | |||||
| [JsonProperty("embed_channel_id")] | |||||
| public string EmbedChannelId; | |||||
| [JsonProperty("embed_enabled")] | |||||
| public bool EmbedEnabled; | |||||
| [JsonProperty("icon")] | |||||
| public string Icon; | |||||
| [JsonProperty("joined_at")] | |||||
| public DateTime? JoinedAt; | |||||
| [JsonProperty("owner_id")] | |||||
| public string OwnerId; | |||||
| [JsonProperty("region")] | |||||
| public string Region; | |||||
| [JsonProperty("roles")] | |||||
| public RoleInfo[] Roles; | |||||
| } | |||||
| public class ExtendedGuildInfo : GuildInfo | |||||
| { | |||||
| [JsonProperty("channels")] | |||||
| public ChannelInfo[] Channels; | |||||
| [JsonProperty("members")] | |||||
| public ExtendedMemberInfo[] Members; | |||||
| [JsonProperty("presences")] | |||||
| public PresenceMemberInfo[] Presences; | |||||
| [JsonProperty("voice_states")] | |||||
| public VoiceMemberInfo[] VoiceStates; | |||||
| } | |||||
| //Messages | |||||
| public class MessageReference | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty("message_id")] | |||||
| public string MessageId { get { return Id; } set { Id = value; } } | |||||
| } | |||||
| public class Message : MessageReference | |||||
| { | |||||
| public sealed class Attachment | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("url")] | |||||
| public string Url; | |||||
| [JsonProperty("proxy_url")] | |||||
| public string ProxyUrl; | |||||
| [JsonProperty("size")] | |||||
| public int Size; | |||||
| [JsonProperty("filename")] | |||||
| public string Filename; | |||||
| [JsonProperty("width")] | |||||
| public int Width; | |||||
| [JsonProperty("height")] | |||||
| public int Height; | |||||
| } | |||||
| public sealed class Embed | |||||
| { | |||||
| public sealed class Reference | |||||
| { | |||||
| [JsonProperty("url")] | |||||
| public string Url; | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| } | |||||
| public sealed class ThumbnailInfo | |||||
| { | |||||
| [JsonProperty("url")] | |||||
| public string Url; | |||||
| [JsonProperty("proxy_url")] | |||||
| public string ProxyUrl; | |||||
| [JsonProperty("width")] | |||||
| public int Width; | |||||
| [JsonProperty("height")] | |||||
| public int Height; | |||||
| } | |||||
| [JsonProperty("url")] | |||||
| public string Url; | |||||
| [JsonProperty("type")] | |||||
| public string Type; | |||||
| [JsonProperty("title")] | |||||
| public string Title; | |||||
| [JsonProperty("description")] | |||||
| public string Description; | |||||
| [JsonProperty("author")] | |||||
| public Reference Author; | |||||
| [JsonProperty("provider")] | |||||
| public Reference Provider; | |||||
| [JsonProperty("thumbnail")] | |||||
| public ThumbnailInfo Thumbnail; | |||||
| } | |||||
| [JsonProperty("tts")] | |||||
| public bool IsTextToSpeech; | |||||
| [JsonProperty("mention_everyone")] | |||||
| public bool IsMentioningEveryone; | |||||
| [JsonProperty("timestamp")] | |||||
| public DateTime Timestamp; | |||||
| [JsonProperty("edited_timestamp")] | |||||
| public DateTime? EditedTimestamp; | |||||
| [JsonProperty("mentions")] | |||||
| public UserReference[] Mentions; | |||||
| [JsonProperty("embeds")] | |||||
| public Embed[] Embeds; //TODO: Parse this | |||||
| [JsonProperty("attachments")] | |||||
| public Attachment[] Attachments; | |||||
| [JsonProperty("content")] | |||||
| public string Content; | |||||
| [JsonProperty("author")] | |||||
| public UserReference Author; | |||||
| [JsonProperty("nonce")] | |||||
| public string Nonce; | |||||
| } | |||||
| //Roles | |||||
| public class RoleReference | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty("role_id")] | |||||
| public string RoleId; | |||||
| } | |||||
| public class RoleInfo | |||||
| { | |||||
| [JsonProperty("permissions")] | |||||
| public int Permissions; | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| } | |||||
| //Invites | |||||
| public class Invite | |||||
| { | |||||
| [JsonProperty("inviter")] | |||||
| public UserReference Inviter; | |||||
| [JsonProperty("guild")] | |||||
| public GuildReference Guild; | |||||
| [JsonProperty("channel")] | |||||
| public ChannelReference Channel; | |||||
| [JsonProperty("code")] | |||||
| public string Code; | |||||
| [JsonProperty("xkcdpass")] | |||||
| public string XkcdPass; | |||||
| } | |||||
| public class ExtendedInvite : Invite | |||||
| { | |||||
| [JsonProperty("max_age")] | |||||
| public int MaxAge; | |||||
| [JsonProperty("max_uses")] | |||||
| public int MaxUses; | |||||
| [JsonProperty("revoked")] | |||||
| public bool IsRevoked; | |||||
| [JsonProperty("temporary")] | |||||
| public bool IsTemporary; | |||||
| [JsonProperty("uses")] | |||||
| public int Uses; | |||||
| [JsonProperty("created_at")] | |||||
| public DateTime CreatedAt; | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| namespace Discord.Net.API | |||||
| namespace Discord.API | |||||
| { | { | ||||
| internal static class Endpoints | internal static class Endpoints | ||||
| { | { | ||||
| @@ -45,5 +45,6 @@ | |||||
| public const string StatusActiveMaintenance = "scheduled-maintenances/active.json"; | public const string StatusActiveMaintenance = "scheduled-maintenances/active.json"; | ||||
| public const string StatusUnresolvedMaintenance = "scheduled-maintenances/unresolved.json"; | public const string StatusUnresolvedMaintenance = "scheduled-maintenances/unresolved.json"; | ||||
| public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json"; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,7 +1,7 @@ | |||||
| using System; | using System; | ||||
| using System.Net; | using System.Net; | ||||
| namespace Discord.Net.API | |||||
| namespace Discord.API | |||||
| { | { | ||||
| public class HttpException : Exception | public class HttpException : Exception | ||||
| { | { | ||||
| @@ -0,0 +1,142 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API | |||||
| { | |||||
| //Auth | |||||
| internal sealed class RegisterRequest | |||||
| { | |||||
| [JsonProperty("fingerprint")] | |||||
| public string Fingerprint; | |||||
| [JsonProperty("username")] | |||||
| public string Username; | |||||
| } | |||||
| internal sealed class LoginRequest | |||||
| { | |||||
| [JsonProperty("email")] | |||||
| public string Email; | |||||
| [JsonProperty("password")] | |||||
| public string Password; | |||||
| } | |||||
| //Channels | |||||
| internal sealed class CreateChannelRequest | |||||
| { | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| [JsonProperty("type")] | |||||
| public string Type; | |||||
| } | |||||
| internal sealed class CreatePMChannelRequest | |||||
| { | |||||
| [JsonProperty("recipient_id")] | |||||
| public string RecipientId; | |||||
| } | |||||
| internal sealed class EditChannelRequest | |||||
| { | |||||
| [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Name; | |||||
| [JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Topic; | |||||
| } | |||||
| //Invites | |||||
| internal sealed class CreateInviteRequest | |||||
| { | |||||
| [JsonProperty("max_age")] | |||||
| public int MaxAge; | |||||
| [JsonProperty("max_uses")] | |||||
| public int MaxUses; | |||||
| [JsonProperty("temporary")] | |||||
| public bool IsTemporary; | |||||
| [JsonProperty("xkcdpass")] | |||||
| public bool WithXkcdPass; | |||||
| } | |||||
| //Members | |||||
| internal sealed class EditMemberRequest | |||||
| { | |||||
| [JsonProperty(PropertyName = "mute", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public bool? Mute; | |||||
| [JsonProperty(PropertyName = "deaf", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public bool? Deaf; | |||||
| [JsonProperty(PropertyName = "roles", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string[] Roles; | |||||
| } | |||||
| //Messages | |||||
| internal sealed class SendMessageRequest | |||||
| { | |||||
| [JsonProperty("content")] | |||||
| public string Content; | |||||
| [JsonProperty("mentions")] | |||||
| public string[] Mentions; | |||||
| [JsonProperty("nonce", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Nonce; | |||||
| [JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public bool IsTTS; | |||||
| } | |||||
| internal sealed class EditMessageRequest | |||||
| { | |||||
| [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Content; | |||||
| [JsonProperty("mentions", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string[] Mentions; | |||||
| } | |||||
| //Permissions | |||||
| internal sealed class SetChannelPermissionsRequest //Both creates and modifies | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id; | |||||
| [JsonProperty("type")] | |||||
| public string Type; | |||||
| [JsonProperty("allow")] | |||||
| public uint Allow; | |||||
| [JsonProperty("deny")] | |||||
| public uint Deny; | |||||
| } | |||||
| //Profile | |||||
| internal sealed class EditProfileRequest | |||||
| { | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string CurrentPassword; | |||||
| [JsonProperty(PropertyName = "email", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Email; | |||||
| [JsonProperty(PropertyName = "new_password", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Password; | |||||
| [JsonProperty(PropertyName = "username", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Username; | |||||
| [JsonProperty(PropertyName = "avatar", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Avatar; | |||||
| } | |||||
| //Roles | |||||
| internal sealed class EditRoleRequest | |||||
| { | |||||
| [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Name; | |||||
| [JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public uint? Permissions; | |||||
| } | |||||
| //Servers | |||||
| internal sealed class CreateServerRequest | |||||
| { | |||||
| [JsonProperty("name")] | |||||
| public string Name; | |||||
| [JsonProperty("region")] | |||||
| public string Region; | |||||
| } | |||||
| internal sealed class EditServerRequest | |||||
| { | |||||
| [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Name; | |||||
| [JsonProperty("region", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Region; | |||||
| } | |||||
| } | |||||
| @@ -1,7 +1,7 @@ | |||||
| using System; | using System; | ||||
| using System.Net.Http; | using System.Net.Http; | ||||
| namespace Discord.Net.API | |||||
| namespace Discord.API | |||||
| { | { | ||||
| internal partial class RestClient | internal partial class RestClient | ||||
| { | { | ||||
| @@ -6,7 +6,7 @@ using System.Net.Http; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Net.API | |||||
| namespace Discord.API | |||||
| { | { | ||||
| internal class RestSharpRestEngine : IRestEngine | internal class RestSharpRestEngine : IRestEngine | ||||
| { | { | ||||
| @@ -6,7 +6,7 @@ using System.Reflection; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Net.API | |||||
| namespace Discord.API | |||||
| { | { | ||||
| internal interface IRestEngine | internal interface IRestEngine | ||||
| { | { | ||||
| @@ -1,6 +1,5 @@ | |||||
| using Discord.Helpers; | |||||
| using Discord.Net; | |||||
| using Discord.Net.API; | |||||
| using Discord.API; | |||||
| using Discord.Helpers; | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| @@ -17,34 +16,54 @@ namespace Discord | |||||
| public partial class DiscordClient | public partial class DiscordClient | ||||
| { | { | ||||
| //Servers | |||||
| /// <summary> Creates a new server with the provided name and region (see Regions). </summary> | |||||
| public async Task<Server> CreateServer(string name, string region) | |||||
| public const int MaxMessageSize = 2000; | |||||
| //Bans | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Member member) | |||||
| => Ban(member?.ServerId, member?.UserId); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Server server, User user) | |||||
| => Ban(server?.Id, user?.Id); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Server server, string userId) | |||||
| => Ban(server?.Id, userId); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(string server, User user) | |||||
| => Ban(server, user?.Id); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(string serverId, string userId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (name == null) throw new ArgumentNullException(nameof(name)); | |||||
| if (region == null) throw new ArgumentNullException(nameof(region)); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| var response = await _api.CreateServer(name, region).ConfigureAwait(false); | |||||
| var server = _servers.GetOrAdd(response.Id); | |||||
| server.Update(response); | |||||
| return server; | |||||
| return _api.Ban(serverId, userId); | |||||
| } | } | ||||
| /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | |||||
| public Task<Server> LeaveServer(Server server) | |||||
| => LeaveServer(server?.Id); | |||||
| /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | |||||
| public async Task<Server> LeaveServer(string serverId) | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Member member) | |||||
| => Unban(member?.ServerId, member?.UserId); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Server server, User user) | |||||
| => Unban(server?.Id, user?.Id); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Server server, string userId) | |||||
| => Unban(server?.Id, userId); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(string server, User user) | |||||
| => Unban(server, user?.Id); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public async Task Unban(string serverId, string userId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | ||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| try { await _api.LeaveServer(serverId).ConfigureAwait(false); } | |||||
| try { await _api.Unban(serverId, userId).ConfigureAwait(false); } | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| return _servers.TryRemove(serverId); | |||||
| } | } | ||||
| //Channels | //Channels | ||||
| /// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary> | /// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary> | ||||
| public Task<Channel> CreateChannel(Server server, string name, string type) | public Task<Channel> CreateChannel(Server server, string name, string type) | ||||
| @@ -62,6 +81,7 @@ namespace Discord | |||||
| channel.Update(response); | channel.Update(response); | ||||
| return channel; | return channel; | ||||
| } | } | ||||
| /// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary> | /// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary> | ||||
| public Task<Channel> CreatePMChannel(string userId) => CreatePMChannel(_users[userId], userId); | public Task<Channel> CreatePMChannel(string userId) => CreatePMChannel(_users[userId], userId); | ||||
| /// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary> | /// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary> | ||||
| @@ -70,7 +90,7 @@ namespace Discord | |||||
| public Task<Channel> CreatePMChannel(Member member) => CreatePMChannel(member.User, member.UserId); | public Task<Channel> CreatePMChannel(Member member) => CreatePMChannel(member.User, member.UserId); | ||||
| private async Task<Channel> CreatePMChannel(User user, string userId) | private async Task<Channel> CreatePMChannel(User user, string userId) | ||||
| { | { | ||||
| CheckReady(); | |||||
| CheckReady(); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | if (userId == null) throw new ArgumentNullException(nameof(userId)); | ||||
| Channel channel = null; | Channel channel = null; | ||||
| @@ -85,6 +105,19 @@ namespace Discord | |||||
| return channel; | return channel; | ||||
| } | } | ||||
| /// <summary> Edits the provided channel, changing only non-null attributes. </summary> | |||||
| public Task EditChannel(Channel channel) | |||||
| => EditChannel(channel?.Id); | |||||
| /// <summary> Edits the provided channel, changing only non-null attributes. </summary> | |||||
| public Task EditChannel(string channelId, string name = null, string topic = null) | |||||
| { | |||||
| CheckReady(); | |||||
| if (channelId == null) throw new ArgumentNullException(nameof(channelId)); | |||||
| if (topic == null) throw new ArgumentNullException(nameof(topic)); | |||||
| return _api.EditChannel(channelId, name: name, topic: topic); | |||||
| } | |||||
| /// <summary> Destroys the provided channel. </summary> | /// <summary> Destroys the provided channel. </summary> | ||||
| public Task<Channel> DestroyChannel(Channel channel) | public Task<Channel> DestroyChannel(Channel channel) | ||||
| => DestroyChannel(channel?.Id); | => DestroyChannel(channel?.Id); | ||||
| @@ -99,52 +132,6 @@ namespace Discord | |||||
| return _channels.TryRemove(channelId); | return _channels.TryRemove(channelId); | ||||
| } | } | ||||
| //Bans | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Member member) | |||||
| => Ban(member?.ServerId, member?.UserId); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Server server, User user) | |||||
| => Ban(server?.Id, user?.Id); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(Server server, string userId) | |||||
| => Ban(server?.Id, userId); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(string server, User user) | |||||
| => Ban(server, user?.Id); | |||||
| /// <summary> Bans a user from the provided server. </summary> | |||||
| public Task Ban(string serverId, string userId) | |||||
| { | |||||
| CheckReady(); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| return _api.Ban(serverId, userId); | |||||
| } | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Member member) | |||||
| => Unban(member?.ServerId, member?.UserId); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Server server, User user) | |||||
| => Unban(server?.Id, user?.Id); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(Server server, string userId) | |||||
| => Unban(server?.Id, userId); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public Task Unban(string server, User user) | |||||
| => Unban(server, user?.Id); | |||||
| /// <summary> Unbans a user from the provided server. </summary> | |||||
| public async Task Unban(string serverId, string userId) | |||||
| { | |||||
| CheckReady(); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| try { await _api.Unban(serverId, userId).ConfigureAwait(false); } | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | |||||
| } | |||||
| //Invites | //Invites | ||||
| /// <summary> Creates a new invite to the default channel of the provided server. </summary> | /// <summary> Creates a new invite to the default channel of the provided server. </summary> | ||||
| /// <param name="maxAge"> Time (in seconds) until the invite expires. Set to 0 to never expire. </param> | /// <param name="maxAge"> Time (in seconds) until the invite expires. Set to 0 to never expire. </param> | ||||
| @@ -178,14 +165,29 @@ namespace Discord | |||||
| return invite; | return invite; | ||||
| } | } | ||||
| /// <summary> Deletes the provided invite. </summary> | |||||
| public async Task DestroyInvite(string inviteId) | |||||
| { | |||||
| CheckReady(); | |||||
| if (inviteId == null) throw new ArgumentNullException(nameof(inviteId)); | |||||
| try | |||||
| { | |||||
| //Check if this is a human-readable link and get its ID | |||||
| var response = await _api.GetInvite(inviteId).ConfigureAwait(false); | |||||
| await _api.DeleteInvite(response.Code).ConfigureAwait(false); | |||||
| } | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | |||||
| } | |||||
| /// <summary> Gets more info about the provided invite code. </summary> | /// <summary> Gets more info about the provided invite code. </summary> | ||||
| /// <remarks> Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode </remarks> | /// <remarks> Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode </remarks> | ||||
| public async Task<Invite> GetInvite(string id) | |||||
| public async Task<Invite> GetInvite(string inviteIdOrXkcd) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (id == null) throw new ArgumentNullException(nameof(id)); | |||||
| if (inviteIdOrXkcd == null) throw new ArgumentNullException(nameof(inviteIdOrXkcd)); | |||||
| var response = await _api.GetInvite(id).ConfigureAwait(false); | |||||
| var response = await _api.GetInvite(inviteIdOrXkcd).ConfigureAwait(false); | |||||
| var invite = new Invite(this, response.Code, response.XkcdPass, response.Guild.Id); | var invite = new Invite(this, response.Code, response.XkcdPass, response.Guild.Id); | ||||
| invite.Update(response); | invite.Update(response); | ||||
| return invite; | return invite; | ||||
| @@ -200,39 +202,42 @@ namespace Discord | |||||
| return _api.AcceptInvite(invite.Id); | return _api.AcceptInvite(invite.Id); | ||||
| } | } | ||||
| /// <summary> Accepts the provided invite. </summary> | /// <summary> Accepts the provided invite. </summary> | ||||
| public async Task AcceptInvite(string code) | |||||
| public async Task AcceptInvite(string inviteId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (code == null) throw new ArgumentNullException(nameof(code)); | |||||
| if (inviteId == null) throw new ArgumentNullException(nameof(inviteId)); | |||||
| //Remove trailing slash and any non-code url parts | //Remove trailing slash and any non-code url parts | ||||
| if (code.Length > 0 && code[code.Length - 1] == '/') | |||||
| code = code.Substring(0, code.Length - 1); | |||||
| int index = code.LastIndexOf('/'); | |||||
| if (inviteId.Length > 0 && inviteId[inviteId.Length - 1] == '/') | |||||
| inviteId = inviteId.Substring(0, inviteId.Length - 1); | |||||
| int index = inviteId.LastIndexOf('/'); | |||||
| if (index >= 0) | if (index >= 0) | ||||
| code = code.Substring(index + 1); | |||||
| inviteId = inviteId.Substring(index + 1); | |||||
| //Check if this is a human-readable link and get its ID | //Check if this is a human-readable link and get its ID | ||||
| var invite = await GetInvite(code).ConfigureAwait(false); | |||||
| var invite = await GetInvite(inviteId).ConfigureAwait(false); | |||||
| await _api.AcceptInvite(invite.Id).ConfigureAwait(false); | await _api.AcceptInvite(invite.Id).ConfigureAwait(false); | ||||
| } | } | ||||
| /// <summary> Deletes the provided invite. </summary> | |||||
| public async Task DeleteInvite(string code) | |||||
| //Members | |||||
| public Task EditMember(Member member, bool? mute = null, bool? deaf = null, string[] roles = null) | |||||
| => EditMember(member?.ServerId, member?.UserId, mute, deaf, roles); | |||||
| public Task EditMember(Server server, User user, bool? mute = null, bool? deaf = null, string[] roles = null) | |||||
| => EditMember(server?.Id, user?.Id, mute, deaf, roles); | |||||
| public Task EditMember(Server server, string userId, bool? mute = null, bool? deaf = null, string[] roles = null) | |||||
| => EditMember(server?.Id, userId, mute, deaf, roles); | |||||
| public Task EditMember(string serverId, User user, bool? mute = null, bool? deaf = null, string[] roles = null) | |||||
| => EditMember(serverId, user?.Id, mute, deaf, roles); | |||||
| public Task EditMember(string serverId, string userId, bool? mute = null, bool? deaf = null, string[] roles = null) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (code == null) throw new ArgumentNullException(nameof(code)); | |||||
| if (serverId == null) throw new NullReferenceException(nameof(serverId)); | |||||
| if (userId == null) throw new NullReferenceException(nameof(userId)); | |||||
| try | |||||
| { | |||||
| //Check if this is a human-readable link and get its ID | |||||
| var response = await _api.GetInvite(code).ConfigureAwait(false); | |||||
| await _api.DeleteInvite(response.Code).ConfigureAwait(false); | |||||
| } | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | |||||
| return _api.EditMember(serverId, userId, mute, deaf, roles); | |||||
| } | } | ||||
| //Chat | |||||
| //Messages | |||||
| /// <summary> Sends a message to the provided channel. </summary> | /// <summary> Sends a message to the provided channel. </summary> | ||||
| public Task<Message[]> SendMessage(Channel channel, string text) | public Task<Message[]> SendMessage(Channel channel, string text) | ||||
| => SendMessage(channel?.Id, text, new string[0]); | => SendMessage(channel?.Id, text, new string[0]); | ||||
| @@ -252,18 +257,18 @@ namespace Discord | |||||
| if (text == null) throw new ArgumentNullException(nameof(text)); | if (text == null) throw new ArgumentNullException(nameof(text)); | ||||
| if (mentions == null) throw new ArgumentNullException(nameof(mentions)); | if (mentions == null) throw new ArgumentNullException(nameof(mentions)); | ||||
| int blockCount = (int)Math.Ceiling(text.Length / (double)DiscordAPIClient.MaxMessageSize); | |||||
| int blockCount = (int)Math.Ceiling(text.Length / (double)MaxMessageSize); | |||||
| Message[] result = new Message[blockCount]; | Message[] result = new Message[blockCount]; | ||||
| for (int i = 0; i < blockCount; i++) | for (int i = 0; i < blockCount; i++) | ||||
| { | { | ||||
| int index = i * DiscordAPIClient.MaxMessageSize; | |||||
| int index = i * MaxMessageSize; | |||||
| string blockText = text.Substring(index, Math.Min(2000, text.Length - index)); | string blockText = text.Substring(index, Math.Min(2000, text.Length - index)); | ||||
| var nonce = GenerateNonce(); | var nonce = GenerateNonce(); | ||||
| if (_config.UseMessageQueue) | if (_config.UseMessageQueue) | ||||
| { | { | ||||
| var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _currentUserId); | var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _currentUserId); | ||||
| var currentMember = _members[msg.UserId, channel.ServerId]; | var currentMember = _members[msg.UserId, channel.ServerId]; | ||||
| msg.Update(new Net.API.Message | |||||
| msg.Update(new API.Message | |||||
| { | { | ||||
| Content = blockText, | Content = blockText, | ||||
| Timestamp = DateTime.UtcNow, | Timestamp = DateTime.UtcNow, | ||||
| @@ -302,35 +307,37 @@ namespace Discord | |||||
| return await SendMessage(channel, text, new string[0]).ConfigureAwait(false); | return await SendMessage(channel, text, new string[0]).ConfigureAwait(false); | ||||
| } | } | ||||
| /// <summary> Edits a message the provided message. </summary> | |||||
| public Task EditMessage(Message message, string text) | |||||
| => EditMessage(message?.ChannelId, message?.Id, text, new string[0]); | |||||
| /// <summary> Edits a message the provided message. </summary> | |||||
| public Task EditMessage(Channel channel, string messageId, string text) | |||||
| => EditMessage(channel?.Id, messageId, text, new string[0]); | |||||
| /// <summary> Edits a message the provided message. </summary> | |||||
| public Task EditMessage(string channelId, string messageId, string text) | |||||
| => EditMessage(channelId, messageId, text, new string[0]); | |||||
| /// <summary> Edits a message the provided message, mentioning certain users. </summary> | |||||
| /// <summary> Sends a file to the provided channel. </summary> | |||||
| public Task SendFile(Channel channel, string filePath) | |||||
| => SendFile(channel?.Id, filePath); | |||||
| /// <summary> Sends a file to the provided channel. </summary> | |||||
| public Task SendFile(string channelId, string filePath) | |||||
| { | |||||
| CheckReady(); | |||||
| if (channelId == null) throw new ArgumentNullException(nameof(channelId)); | |||||
| if (filePath == null) throw new ArgumentNullException(nameof(filePath)); | |||||
| return _api.SendFile(channelId, filePath); | |||||
| } | |||||
| /// <summary> Edits the provided message, changing only non-null attributes. </summary> | |||||
| /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | ||||
| public Task EditMessage(Message message, string text, string[] mentions) | |||||
| public Task EditMessage(Message message, string text = null, string[] mentions = null) | |||||
| => EditMessage(message?.ChannelId, message?.Id, text, mentions); | => EditMessage(message?.ChannelId, message?.Id, text, mentions); | ||||
| /// <summary> Edits a message the provided message, mentioning certain users. </summary> | |||||
| /// <summary> Edits the provided message, changing only non-null attributes. </summary> | |||||
| /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | ||||
| public Task EditMessage(Channel channel, string messageId, string text, string[] mentions) | |||||
| public Task EditMessage(Channel channel, string messageId, string text = null, string[] mentions = null) | |||||
| => EditMessage(channel?.Id, messageId, text, mentions); | => EditMessage(channel?.Id, messageId, text, mentions); | ||||
| /// <summary> Edits a message the provided message, mentioning certain users. </summary> | |||||
| /// <summary> Edits the provided message, changing only non-null attributes. </summary> | |||||
| /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | /// <remarks> While not required, it is recommended to include a mention reference in the text (see Mention.User). </remarks> | ||||
| public async Task EditMessage(string channelId, string messageId, string text, string[] mentions) | |||||
| public async Task EditMessage(string channelId, string messageId, string text = null, string[] mentions = null) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (channelId == null) throw new ArgumentNullException(nameof(channelId)); | if (channelId == null) throw new ArgumentNullException(nameof(channelId)); | ||||
| if (messageId == null) throw new ArgumentNullException(nameof(messageId)); | if (messageId == null) throw new ArgumentNullException(nameof(messageId)); | ||||
| if (text == null) throw new ArgumentNullException(nameof(text)); | |||||
| if (mentions == null) throw new ArgumentNullException(nameof(mentions)); | |||||
| if (text.Length > DiscordAPIClient.MaxMessageSize) | |||||
| text = text.Substring(0, DiscordAPIClient.MaxMessageSize); | |||||
| if (text != null && text.Length > MaxMessageSize) | |||||
| text = text.Substring(0, MaxMessageSize); | |||||
| var model = await _api.EditMessage(messageId, channelId, text, mentions).ConfigureAwait(false); | var model = await _api.EditMessage(messageId, channelId, text, mentions).ConfigureAwait(false); | ||||
| var msg = _messages[messageId]; | var msg = _messages[messageId]; | ||||
| @@ -383,19 +390,6 @@ namespace Discord | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| } | } | ||||
| } | } | ||||
| /// <summary> Sends a file to the provided channel. </summary> | |||||
| public Task SendFile(Channel channel, string filePath) | |||||
| => SendFile(channel?.Id, filePath); | |||||
| /// <summary> Sends a file to the provided channel. </summary> | |||||
| public Task SendFile(string channelId, string filePath) | |||||
| { | |||||
| CheckReady(); | |||||
| if (channelId == null) throw new ArgumentNullException(nameof(channelId)); | |||||
| if (filePath == null) throw new ArgumentNullException(nameof(filePath)); | |||||
| return _api.SendFile(channelId, filePath); | |||||
| } | |||||
| /// <summary> Downloads last count messages from the server, starting at beforeMessageId if it's provided. </summary> | /// <summary> Downloads last count messages from the server, starting at beforeMessageId if it's provided. </summary> | ||||
| public Task<Message[]> DownloadMessages(Channel channel, int count, string beforeMessageId = null, bool cache = true) | public Task<Message[]> DownloadMessages(Channel channel, int count, string beforeMessageId = null, bool cache = true) | ||||
| @@ -449,113 +443,6 @@ namespace Discord | |||||
| return null; | return null; | ||||
| } | } | ||||
| //Roles | |||||
| /// <summary>Note: due to current API limitations, the created role cannot be returned. </summary> | |||||
| public Task CreateRole(Server server) | |||||
| => CreateRole(server?.Id); | |||||
| /// <summary>Note: due to current API limitations, the created role cannot be returned. </summary> | |||||
| public Task CreateRole(string serverId) | |||||
| { | |||||
| CheckReady(); | |||||
| if (serverId == null) throw new NullReferenceException(nameof(serverId)); | |||||
| return _api.CreateRole(serverId); | |||||
| } | |||||
| public Task RenameRole(Role role, string newName) | |||||
| => RenameRole(role?.ServerId, role?.Id, newName); | |||||
| public Task RenameRole(string serverId, string roleId, string newName) | |||||
| { | |||||
| CheckReady(); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| if (newName == null) throw new NullReferenceException(nameof(newName)); | |||||
| return _api.RenameRole(serverId, roleId, newName); | |||||
| } | |||||
| public Task DeleteRole(Role role) | |||||
| => DeleteRole(role?.ServerId, role?.Id); | |||||
| public Task DeleteRole(string serverId, string roleId) | |||||
| { | |||||
| CheckReady(); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| return _api.DeleteRole(serverId, roleId); | |||||
| } | |||||
| public Task AddRoleMember(Role role, string serverId, string userId) | |||||
| => AddRoleMember(role?.Id, GetMember(serverId, userId)); | |||||
| public Task AddRoleMember(Role role, string serverId, User user) | |||||
| => AddRoleMember(role?.Id, GetMember(serverId, user)); | |||||
| public Task AddRoleMember(Role role, Server server, string userId) | |||||
| => AddRoleMember(role?.Id, GetMember(server, userId)); | |||||
| public Task AddRoleMember(Role role, Server server, User user) | |||||
| => AddRoleMember(role?.Id, GetMember(server, user)); | |||||
| public Task AddRoleMember(Role role, Member member) | |||||
| => AddRoleMember(role?.Id, member); | |||||
| public Task AddRoleMember(string roleId, string serverId, string userId) | |||||
| => AddRoleMember(roleId, GetMember(serverId, userId)); | |||||
| public Task AddRoleMember(string roleId, string serverId, User user) | |||||
| => AddRoleMember(roleId, GetMember(serverId, user)); | |||||
| public Task AddRoleMember(string roleId, Server server, string userId) | |||||
| => AddRoleMember(roleId, GetMember(server, userId)); | |||||
| public Task AddRoleMember(string roleId, Server server, User user) | |||||
| => AddRoleMember(roleId, GetMember(server, user)); | |||||
| public Task AddRoleMember(string roleId, Member member) | |||||
| { | |||||
| CheckReady(); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| if (member == null) throw new NullReferenceException(nameof(member)); | |||||
| if (!member.RoleIds.Contains(roleId)) | |||||
| { | |||||
| var oldRoles = member.RoleIds; | |||||
| string[] newRoles = new string[oldRoles.Length + 1]; | |||||
| for (int i = 0; i < oldRoles.Length; i++) | |||||
| newRoles[i] = oldRoles[i]; | |||||
| return _api.SetMemberRoles(member.ServerId, member.UserId, newRoles); | |||||
| } | |||||
| return TaskHelper.CompletedTask; | |||||
| } | |||||
| public Task RemoveRoleMember(Role role, string serverId, string userId) | |||||
| => RemoveRoleMember(role?.Id, GetMember(serverId, userId)); | |||||
| public Task RemoveRoleMember(Role role, string serverId, User user) | |||||
| => RemoveRoleMember(role?.Id, GetMember(serverId, user)); | |||||
| public Task RemoveRoleMember(Role role, Server server, string userId) | |||||
| => RemoveRoleMember(role?.Id, GetMember(server, userId)); | |||||
| public Task RemoveRoleMember(Role role, Server server, User user) | |||||
| => RemoveRoleMember(role?.Id, GetMember(server, user)); | |||||
| public Task RemoveRoleMember(Role role, Member member) | |||||
| => RemoveRoleMember(role?.Id, member); | |||||
| public Task RemoveRoleMember(string roleId, string serverId, string userId) | |||||
| => RemoveRoleMember(roleId, GetMember(serverId, userId)); | |||||
| public Task RemoveRoleMember(string roleId, string serverId, User user) | |||||
| => RemoveRoleMember(roleId, GetMember(serverId, user)); | |||||
| public Task RemoveRoleMember(string roleId, Server server, string userId) | |||||
| => RemoveRoleMember(roleId, GetMember(server, userId)); | |||||
| public Task RemoveRoleMember(string roleId, Server server, User user) | |||||
| => RemoveRoleMember(roleId, GetMember(server, user)); | |||||
| public Task RemoveRoleMember(string roleId, Member member) | |||||
| { | |||||
| CheckReady(); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| if (member == null) throw new NullReferenceException(nameof(member)); | |||||
| if (member.RoleIds.Contains(roleId)) | |||||
| { | |||||
| var oldRoles = member.RoleIds; | |||||
| string[] newRoles = new string[oldRoles.Length - 1]; | |||||
| for (int i = 0, j = 0; i < oldRoles.Length; i++) | |||||
| { | |||||
| if (oldRoles[i] != roleId) | |||||
| newRoles[j++] = oldRoles[i]; | |||||
| } | |||||
| return _api.SetMemberRoles(member.ServerId, member.UserId, newRoles); | |||||
| } | |||||
| return TaskHelper.CompletedTask; | |||||
| } | |||||
| //Permissions | //Permissions | ||||
| public Task SetChannelUserPermissions(Channel channel, Member member, PackedPermissions allow, PackedPermissions deny) | public Task SetChannelUserPermissions(Channel channel, Member member, PackedPermissions allow, PackedPermissions deny) | ||||
| => SetChannelPermissions(channel?.Id, member?.UserId, "member", allow, deny); | => SetChannelPermissions(channel?.Id, member?.UserId, "member", allow, deny); | ||||
| @@ -585,7 +472,7 @@ namespace Discord | |||||
| if (channelId == null) throw new NullReferenceException(nameof(channelId)); | if (channelId == null) throw new NullReferenceException(nameof(channelId)); | ||||
| if (userOrRoleId == null) throw new NullReferenceException(nameof(userOrRoleId)); | if (userOrRoleId == null) throw new NullReferenceException(nameof(userOrRoleId)); | ||||
| return _api.SetChannelPermissions(channelId, userOrRoleId, idType, allow, deny); | |||||
| return _api.SetChannelPermissions(channelId, userOrRoleId, idType, allow.RawValue, deny.RawValue); | |||||
| //TODO: Remove permission from cache | //TODO: Remove permission from cache | ||||
| } | } | ||||
| @@ -625,128 +512,90 @@ namespace Discord | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | ||||
| } | } | ||||
| //Voice | |||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Mute(Member member) | |||||
| => Mute(member?.ServerId, member?.UserId); | |||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Mute(Server server, User user) | |||||
| => Mute(server?.Id, user?.Id); | |||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Mute(Server server, string userId) | |||||
| => Mute(server?.Id, userId); | |||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Mute(string server, User user) | |||||
| => Mute(server, user?.Id); | |||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Mute(string serverId, string userId) | |||||
| //Profile | |||||
| public Task<EditProfileResponse> EditProfile(string currentPassword, | |||||
| string username = null, string email = null, string password = null, | |||||
| AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) | |||||
| { | { | ||||
| CheckReady(); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); | |||||
| return _api.Mute(serverId, userId); | |||||
| return _api.EditProfile(currentPassword, username: username, email: email, password: password, | |||||
| avatarType: avatarType, avatar: avatar); | |||||
| } | } | ||||
| /// <summary> Mutes a user on the provided server. </summary> | |||||
| public Task Unmute(Member member) | |||||
| => Unmute(member?.ServerId, member?.UserId); | |||||
| /// <summary> Unmutes a user on the provided server. </summary> | |||||
| public Task Unmute(Server server, User user) | |||||
| => Unmute(server?.Id, user?.Id); | |||||
| /// <summary> Unmutes a user on the provided server. </summary> | |||||
| public Task Unmute(Server server, string userId) | |||||
| => Unmute(server?.Id, userId); | |||||
| /// <summary> Unmutes a user on the provided server. </summary> | |||||
| public Task Unmute(string server, User user) | |||||
| => Unmute(server, user?.Id); | |||||
| /// <summary> Unmutes a user on the provided server. </summary> | |||||
| public Task Unmute(string serverId, string userId) | |||||
| //Roles | |||||
| /// <summary> Note: due to current API limitations, the created role cannot be returned. </summary> | |||||
| public Task CreateRole(Server server) | |||||
| => CreateRole(server?.Id); | |||||
| /// <summary> Note: due to current API limitations, the created role cannot be returned. </summary> | |||||
| public Task CreateRole(string serverId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| if (serverId == null) throw new NullReferenceException(nameof(serverId)); | |||||
| return _api.Unmute(serverId, userId); | |||||
| return _api.CreateRole(serverId); | |||||
| } | } | ||||
| /// <summary> Deafens a user on the provided server. </summary> | |||||
| public Task Deafen(Member member) | |||||
| => Deafen(member?.ServerId, member?.UserId); | |||||
| /// <summary> Deafens a user on the provided server. </summary> | |||||
| public Task Deafen(Server server, User user) | |||||
| => Deafen(server?.Id, user?.Id); | |||||
| /// <summary> Deafens a user on the provided server. </summary> | |||||
| public Task Deafen(Server server, string userId) | |||||
| => Deafen(server?.Id, userId); | |||||
| /// <summary> Deafens a user on the provided server. </summary> | |||||
| public Task Deafen(string server, User user) | |||||
| => Deafen(server, user?.Id); | |||||
| /// <summary> Deafens a user on the provided server. </summary> | |||||
| public Task Deafen(string serverId, string userId) | |||||
| public Task EditRole(Role role, string newName) | |||||
| => EditRole(role?.ServerId, role?.Id, newName); | |||||
| public Task EditRole(string serverId, string roleId, string name = null, PackedPermissions permissions = null) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| if (serverId == null) throw new NullReferenceException(nameof(serverId)); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| return _api.Deafen(serverId, userId); | |||||
| return _api.EditRole(serverId, roleId, name: name, permissions: permissions?.RawValue); | |||||
| } | } | ||||
| /// <summary> Undeafens a user on the provided server. </summary> | |||||
| public Task Undeafen(Member member) | |||||
| => Undeafen(member?.ServerId, member?.UserId); | |||||
| /// <summary> Undeafens a user on the provided server. </summary> | |||||
| public Task Undeafen(Server server, User user) | |||||
| => Undeafen(server?.Id, user?.Id); | |||||
| /// <summary> Undeafens a user on the provided server. </summary> | |||||
| public Task Undeafen(Server server, string userId) | |||||
| => Undeafen(server?.Id, userId); | |||||
| /// <summary> Undeafens a user on the provided server. </summary> | |||||
| public Task Undeafen(string server, User user) | |||||
| => Undeafen(server, user?.Id); | |||||
| /// <summary> Undeafens a user on the provided server. </summary> | |||||
| public Task Undeafen(string serverId, string userId) | |||||
| public Task DeleteRole(Role role) | |||||
| => DeleteRole(role?.ServerId, role?.Id); | |||||
| public Task DeleteRole(string serverId, string roleId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| if (userId == null) throw new ArgumentNullException(nameof(userId)); | |||||
| if (serverId == null) throw new NullReferenceException(nameof(serverId)); | |||||
| if (roleId == null) throw new NullReferenceException(nameof(roleId)); | |||||
| return _api.Undeafen(serverId, userId); | |||||
| return _api.DeleteRole(serverId, roleId); | |||||
| } | } | ||||
| //Profile | |||||
| /// <summary> Changes your username to newName. </summary> | |||||
| public async Task ChangeUsername(string newName, string currentEmail, string currentPassword) | |||||
| { | |||||
| CheckReady(); | |||||
| var response = await _api.ChangeUsername(newName, currentEmail, currentPassword).ConfigureAwait(false); | |||||
| _currentUser.Update(response); | |||||
| foreach (var membership in _currentUser.Memberships) | |||||
| membership.Update(response); | |||||
| } | |||||
| /// <summary> Changes your email to newEmail. </summary> | |||||
| public async Task ChangeEmail(string newEmail, string currentPassword) | |||||
| //Servers | |||||
| /// <summary> Creates a new server with the provided name and region (see Regions). </summary> | |||||
| public async Task<Server> CreateServer(string name, string region) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await _api.ChangeEmail(newEmail, currentPassword).ConfigureAwait(false); | |||||
| _currentUser.Update(response); | |||||
| if (name == null) throw new ArgumentNullException(nameof(name)); | |||||
| if (region == null) throw new ArgumentNullException(nameof(region)); | |||||
| var response = await _api.CreateServer(name, region).ConfigureAwait(false); | |||||
| var server = _servers.GetOrAdd(response.Id); | |||||
| server.Update(response); | |||||
| return server; | |||||
| } | } | ||||
| /// <summary> Changes your password to newPassword. </summary> | |||||
| public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword) | |||||
| /// <summary> Edits the provided server, changing only non-null attributes. </summary> | |||||
| public Task EditServer(Server server) | |||||
| => EditServer(server?.Id); | |||||
| /// <summary> Edits the provided server, changing only non-null attributes. </summary> | |||||
| public Task EditServer(string serverId, string name = null, string region = null) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| await _api.ChangePassword(newPassword, currentEmail, currentPassword).ConfigureAwait(false); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| return _api.EditServer(serverId, name: name, region: region); | |||||
| } | } | ||||
| /// <summary> Changes your avatar. </summary> | |||||
| /// <remarks>Only supports PNG and JPEG (see AvatarImageType)</remarks> | |||||
| public async Task ChangeAvatar(AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||||
| /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | |||||
| public Task<Server> LeaveServer(Server server) | |||||
| => LeaveServer(server?.Id); | |||||
| /// <summary> Leaves the provided server, destroying it if you are the owner. </summary> | |||||
| public async Task<Server> LeaveServer(string serverId) | |||||
| { | { | ||||
| CheckReady(); | CheckReady(); | ||||
| var response = await _api.ChangeAvatar(imageType, bytes, currentEmail, currentPassword).ConfigureAwait(false); | |||||
| _currentUser.Update(response); | |||||
| foreach (var membership in _currentUser.Memberships) | |||||
| membership.Update(response); | |||||
| if (serverId == null) throw new ArgumentNullException(nameof(serverId)); | |||||
| try { await _api.LeaveServer(serverId).ConfigureAwait(false); } | |||||
| catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } | |||||
| return _servers.TryRemove(serverId); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,5 @@ | |||||
| using Discord.Helpers; | using Discord.Helpers; | ||||
| using Discord.WebSockets; | |||||
| using System; | using System; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| @@ -36,7 +37,7 @@ namespace Discord | |||||
| { | { | ||||
| CheckReady(checkVoice: true); | CheckReady(checkVoice: true); | ||||
| if (_voiceSocket.State != Net.WebSockets.WebSocketState.Disconnected) | |||||
| if (_voiceSocket.State != WebSocketState.Disconnected) | |||||
| { | { | ||||
| var serverId = _voiceSocket.CurrentVoiceServerId; | var serverId = _voiceSocket.CurrentVoiceServerId; | ||||
| if (serverId != null) | if (serverId != null) | ||||
| @@ -1,8 +1,8 @@ | |||||
| using Discord.Collections; | |||||
| using Discord.API; | |||||
| using Discord.Collections; | |||||
| using Discord.Helpers; | using Discord.Helpers; | ||||
| using Discord.Net; | |||||
| using Discord.Net.API; | |||||
| using Discord.Net.WebSockets; | |||||
| using Discord.WebSockets; | |||||
| using Discord.WebSockets.Data; | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System; | using System; | ||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| @@ -10,6 +10,7 @@ using System.Net; | |||||
| using System.Runtime.ExceptionServices; | using System.Runtime.ExceptionServices; | ||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -279,7 +280,7 @@ namespace Discord | |||||
| //Global | //Global | ||||
| case "READY": //Resync | case "READY": //Resync | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.Ready>(_serializer); | |||||
| var data = e.Payload.ToObject<ReadyEvent>(_serializer); | |||||
| _currentUserId = data.User.Id; | _currentUserId = data.User.Id; | ||||
| _currentUser = _users.GetOrAdd(data.User.Id); | _currentUser = _users.GetOrAdd(data.User.Id); | ||||
| _currentUser.Update(data.User); | _currentUser.Update(data.User); | ||||
| @@ -303,7 +304,7 @@ namespace Discord | |||||
| //Servers | //Servers | ||||
| case "GUILD_CREATE": | case "GUILD_CREATE": | ||||
| { | { | ||||
| var model = e.Payload.ToObject<Events.GuildCreate>(_serializer); | |||||
| var model = e.Payload.ToObject<GuildCreateEvent>(_serializer); | |||||
| var server = _servers.GetOrAdd(model.Id); | var server = _servers.GetOrAdd(model.Id); | ||||
| server.Update(model); | server.Update(model); | ||||
| RaiseServerCreated(server); | RaiseServerCreated(server); | ||||
| @@ -311,7 +312,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_UPDATE": | case "GUILD_UPDATE": | ||||
| { | { | ||||
| var model = e.Payload.ToObject<Events.GuildUpdate>(_serializer); | |||||
| var model = e.Payload.ToObject<GuildUpdateEvent>(_serializer); | |||||
| var server = _servers[model.Id]; | var server = _servers[model.Id]; | ||||
| if (server != null) | if (server != null) | ||||
| { | { | ||||
| @@ -322,7 +323,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_DELETE": | case "GUILD_DELETE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildDelete>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildDeleteEvent>(_serializer); | |||||
| var server = _servers.TryRemove(data.Id); | var server = _servers.TryRemove(data.Id); | ||||
| if (server != null) | if (server != null) | ||||
| RaiseServerDestroyed(server); | RaiseServerDestroyed(server); | ||||
| @@ -332,7 +333,7 @@ namespace Discord | |||||
| //Channels | //Channels | ||||
| case "CHANNEL_CREATE": | case "CHANNEL_CREATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.ChannelCreate>(_serializer); | |||||
| var data = e.Payload.ToObject<ChannelCreateEvent>(_serializer); | |||||
| Channel channel; | Channel channel; | ||||
| if (data.IsPrivate) | if (data.IsPrivate) | ||||
| { | { | ||||
| @@ -348,7 +349,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "CHANNEL_UPDATE": | case "CHANNEL_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.ChannelUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<ChannelUpdateEvent>(_serializer); | |||||
| var channel = _channels[data.Id]; | var channel = _channels[data.Id]; | ||||
| if (channel != null) | if (channel != null) | ||||
| { | { | ||||
| @@ -359,7 +360,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "CHANNEL_DELETE": | case "CHANNEL_DELETE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.ChannelDelete>(_serializer); | |||||
| var data = e.Payload.ToObject<ChannelDeleteEvent>(_serializer); | |||||
| var channel = _channels.TryRemove(data.Id); | var channel = _channels.TryRemove(data.Id); | ||||
| if (channel != null) | if (channel != null) | ||||
| RaiseChannelDestroyed(channel); | RaiseChannelDestroyed(channel); | ||||
| @@ -369,7 +370,7 @@ namespace Discord | |||||
| //Members | //Members | ||||
| case "GUILD_MEMBER_ADD": | case "GUILD_MEMBER_ADD": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildMemberAdd>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildMemberAddEvent>(_serializer); | |||||
| var user = _users.GetOrAdd(data.User.Id); | var user = _users.GetOrAdd(data.User.Id); | ||||
| var member = _members.GetOrAdd(data.User.Id, data.GuildId); | var member = _members.GetOrAdd(data.User.Id, data.GuildId); | ||||
| user.Update(data.User); | user.Update(data.User); | ||||
| @@ -381,7 +382,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_MEMBER_UPDATE": | case "GUILD_MEMBER_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildMemberUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildMemberUpdateEvent>(_serializer); | |||||
| var member = _members[data.User.Id, data.GuildId]; | var member = _members[data.User.Id, data.GuildId]; | ||||
| if (member != null) | if (member != null) | ||||
| { | { | ||||
| @@ -392,7 +393,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_MEMBER_REMOVE": | case "GUILD_MEMBER_REMOVE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildMemberRemove>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildMemberRemoveEvent>(_serializer); | |||||
| var member = _members.TryRemove(data.UserId, data.GuildId); | var member = _members.TryRemove(data.UserId, data.GuildId); | ||||
| if (member != null) | if (member != null) | ||||
| RaiseUserRemoved(member); | RaiseUserRemoved(member); | ||||
| @@ -402,7 +403,7 @@ namespace Discord | |||||
| //Roles | //Roles | ||||
| case "GUILD_ROLE_CREATE": | case "GUILD_ROLE_CREATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildRoleCreate>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildRoleCreateEvent>(_serializer); | |||||
| var role = _roles.GetOrAdd(data.Data.Id, data.GuildId); | var role = _roles.GetOrAdd(data.Data.Id, data.GuildId); | ||||
| role.Update(data.Data); | role.Update(data.Data); | ||||
| RaiseRoleUpdated(role); | RaiseRoleUpdated(role); | ||||
| @@ -410,7 +411,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_ROLE_UPDATE": | case "GUILD_ROLE_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildRoleUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildRoleUpdateEvent>(_serializer); | |||||
| var role = _roles[data.Data.Id]; | var role = _roles[data.Data.Id]; | ||||
| if (role != null) | if (role != null) | ||||
| role.Update(data.Data); | role.Update(data.Data); | ||||
| @@ -419,7 +420,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_ROLE_DELETE": | case "GUILD_ROLE_DELETE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildRoleDelete>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildRoleDeleteEvent>(_serializer); | |||||
| var role = _roles.TryRemove(data.RoleId); | var role = _roles.TryRemove(data.RoleId); | ||||
| if (role != null) | if (role != null) | ||||
| RaiseRoleDeleted(role); | RaiseRoleDeleted(role); | ||||
| @@ -429,7 +430,7 @@ namespace Discord | |||||
| //Bans | //Bans | ||||
| case "GUILD_BAN_ADD": | case "GUILD_BAN_ADD": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildBanAdd>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildBanAddEvent>(_serializer); | |||||
| var server = _servers[data.GuildId]; | var server = _servers[data.GuildId]; | ||||
| if (server != null) | if (server != null) | ||||
| { | { | ||||
| @@ -440,7 +441,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "GUILD_BAN_REMOVE": | case "GUILD_BAN_REMOVE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.GuildBanRemove>(_serializer); | |||||
| var data = e.Payload.ToObject<GuildBanRemoveEvent>(_serializer); | |||||
| var server = _servers[data.GuildId]; | var server = _servers[data.GuildId]; | ||||
| if (server != null && server.RemoveBan(data.UserId)) | if (server != null && server.RemoveBan(data.UserId)) | ||||
| RaiseBanRemoved(data.UserId, server); | RaiseBanRemoved(data.UserId, server); | ||||
| @@ -450,7 +451,7 @@ namespace Discord | |||||
| //Messages | //Messages | ||||
| case "MESSAGE_CREATE": | case "MESSAGE_CREATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.MessageCreate>(_serializer); | |||||
| var data = e.Payload.ToObject<MessageCreateEvent>(_serializer); | |||||
| Message msg = null; | Message msg = null; | ||||
| bool wasLocal = _config.UseMessageQueue && data.Author.Id == _currentUserId && data.Nonce != null; | bool wasLocal = _config.UseMessageQueue && data.Author.Id == _currentUserId && data.Nonce != null; | ||||
| @@ -490,7 +491,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "MESSAGE_UPDATE": | case "MESSAGE_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.MessageUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<MessageUpdateEvent>(_serializer); | |||||
| var msg = _messages[data.Id]; | var msg = _messages[data.Id]; | ||||
| if (msg != null) | if (msg != null) | ||||
| { | { | ||||
| @@ -501,7 +502,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "MESSAGE_DELETE": | case "MESSAGE_DELETE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.MessageDelete>(_serializer); | |||||
| var data = e.Payload.ToObject<MessageDeleteEvent>(_serializer); | |||||
| var msg = _messages.TryRemove(data.Id); | var msg = _messages.TryRemove(data.Id); | ||||
| if (msg != null) | if (msg != null) | ||||
| RaiseMessageDeleted(msg); | RaiseMessageDeleted(msg); | ||||
| @@ -509,7 +510,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "MESSAGE_ACK": | case "MESSAGE_ACK": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.MessageAck>(_serializer); | |||||
| var data = e.Payload.ToObject<MessageAckEvent>(_serializer); | |||||
| var msg = GetMessage(data.MessageId); | var msg = GetMessage(data.MessageId); | ||||
| if (msg != null) | if (msg != null) | ||||
| RaiseMessageReadRemotely(msg); | RaiseMessageReadRemotely(msg); | ||||
| @@ -519,7 +520,7 @@ namespace Discord | |||||
| //Statuses | //Statuses | ||||
| case "PRESENCE_UPDATE": | case "PRESENCE_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.PresenceUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<PresenceUpdateEvent>(_serializer); | |||||
| var member = _members[data.User.Id, data.GuildId]; | var member = _members[data.User.Id, data.GuildId]; | ||||
| /*if (_config.TrackActivity) | /*if (_config.TrackActivity) | ||||
| { | { | ||||
| @@ -536,7 +537,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "VOICE_STATE_UPDATE": | case "VOICE_STATE_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.VoiceStateUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<VoiceStateUpdateEvent>(_serializer); | |||||
| var member = _members[data.UserId, data.GuildId]; | var member = _members[data.UserId, data.GuildId]; | ||||
| /*if (_config.TrackActivity) | /*if (_config.TrackActivity) | ||||
| { | { | ||||
| @@ -558,7 +559,7 @@ namespace Discord | |||||
| break; | break; | ||||
| case "TYPING_START": | case "TYPING_START": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.TypingStart>(_serializer); | |||||
| var data = e.Payload.ToObject<TypingStartEvent>(_serializer); | |||||
| var channel = _channels[data.ChannelId]; | var channel = _channels[data.ChannelId]; | ||||
| var user = _users[data.UserId]; | var user = _users[data.UserId]; | ||||
| @@ -587,7 +588,7 @@ namespace Discord | |||||
| //Voice | //Voice | ||||
| case "VOICE_SERVER_UPDATE": | case "VOICE_SERVER_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.VoiceServerUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<VoiceServerUpdateEvent>(_serializer); | |||||
| if (data.GuildId == _voiceSocket.CurrentVoiceServerId) | if (data.GuildId == _voiceSocket.CurrentVoiceServerId) | ||||
| { | { | ||||
| var server = _servers[data.GuildId]; | var server = _servers[data.GuildId]; | ||||
| @@ -603,7 +604,7 @@ namespace Discord | |||||
| //Settings | //Settings | ||||
| case "USER_UPDATE": | case "USER_UPDATE": | ||||
| { | { | ||||
| var data = e.Payload.ToObject<Events.UserUpdate>(_serializer); | |||||
| var data = e.Payload.ToObject<UserUpdateEvent>(_serializer); | |||||
| var user = _users[data.Id]; | var user = _users[data.Id]; | ||||
| if (user != null) | if (user != null) | ||||
| { | { | ||||
| @@ -670,8 +671,8 @@ namespace Discord | |||||
| _token = token; | _token = token; | ||||
| _state = (int)DiscordClientState.Connecting; | _state = (int)DiscordClientState.Connecting; | ||||
| string url = (await _api.GetWebSocketEndpoint().ConfigureAwait(false)).Url; | |||||
| if (_config.LogLevel >= LogMessageSeverity.Verbose) | |||||
| string url = (await _api.Gateway().ConfigureAwait(false)).Url; | |||||
| if (_config.LogLevel >= LogMessageSeverity.Verbose) | |||||
| RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client, $"Websocket endpoint: {url}"); | RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Client, $"Websocket endpoint: {url}"); | ||||
| _dataSocket.Host = url; | _dataSocket.Host = url; | ||||
| @@ -838,7 +839,7 @@ namespace Discord | |||||
| while (_pendingMessages.TryDequeue(out msg)) | while (_pendingMessages.TryDequeue(out msg)) | ||||
| { | { | ||||
| bool hasFailed = false; | bool hasFailed = false; | ||||
| Responses.SendMessage response = null; | |||||
| SendMessageResponse response = null; | |||||
| try | try | ||||
| { | { | ||||
| response = await _api.SendMessage(msg.ChannelId, msg.RawText, msg.MentionIds, msg.Nonce, msg.IsTTS).ConfigureAwait(false); | response = await _api.SendMessage(msg.ChannelId, msg.RawText, msg.MentionIds, msg.Nonce, msg.IsTTS).ConfigureAwait(false); | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using System.Text; | |||||
| using System.Text; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -11,7 +10,7 @@ namespace Discord | |||||
| static Format() | static Format() | ||||
| { | { | ||||
| _patterns = new string[] { "__", "_", "**", "*", "~~" }; | _patterns = new string[] { "__", "_", "**", "*", "~~" }; | ||||
| _builder = new StringBuilder(DiscordAPIClient.MaxMessageSize); | |||||
| _builder = new StringBuilder(DiscordClient.MaxMessageSize); | |||||
| } | } | ||||
| /// <summary> Removes all special formatting characters from the provided text. </summary> | /// <summary> Removes all special formatting characters from the provided text. </summary> | ||||
| @@ -1,9 +1,4 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord | |||||
| namespace Discord | |||||
| { | { | ||||
| public static class Mention | public static class Mention | ||||
| { | { | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json; | |||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| @@ -64,14 +63,14 @@ namespace Discord | |||||
| _messages = new ConcurrentDictionary<string, bool>(); | _messages = new ConcurrentDictionary<string, bool>(); | ||||
| } | } | ||||
| internal void Update(ChannelReference model) | |||||
| internal void Update(API.ChannelReference model) | |||||
| { | { | ||||
| Name = model.Name; | Name = model.Name; | ||||
| Type = model.Type; | Type = model.Type; | ||||
| } | } | ||||
| internal void Update(ChannelInfo model) | |||||
| internal void Update(API.ChannelInfo model) | |||||
| { | { | ||||
| Update(model as ChannelReference); | |||||
| Update(model as API.ChannelReference); | |||||
| Position = model.Position; | Position = model.Position; | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -24,7 +23,7 @@ namespace Discord | |||||
| public string XkcdPass { get; } | public string XkcdPass { get; } | ||||
| /// <summary> Returns a URL for this invite using XkcdPass if available or Id if not. </summary> | /// <summary> Returns a URL for this invite using XkcdPass if available or Id if not. </summary> | ||||
| public string Url => Endpoints.InviteUrl(XkcdPass ?? Id); | |||||
| public string Url => API.Endpoints.InviteUrl(XkcdPass ?? Id); | |||||
| /// <summary> Returns the id of the user that created this invite. </summary> | /// <summary> Returns the id of the user that created this invite. </summary> | ||||
| public string InviterId { get; internal set; } | public string InviterId { get; internal set; } | ||||
| @@ -54,16 +53,16 @@ namespace Discord | |||||
| public override string ToString() => XkcdPass ?? Id; | public override string ToString() => XkcdPass ?? Id; | ||||
| internal void Update(Net.API.Invite model) | |||||
| internal void Update(API.Invite model) | |||||
| { | { | ||||
| ChannelId = model.Channel.Id; | ChannelId = model.Channel.Id; | ||||
| InviterId = model.Inviter?.Id; | InviterId = model.Inviter?.Id; | ||||
| ServerId = model.Guild.Id; | ServerId = model.Guild.Id; | ||||
| } | } | ||||
| internal void Update(Net.API.ExtendedInvite model) | |||||
| internal void Update(API.ExtendedInvite model) | |||||
| { | { | ||||
| Update(model as Net.API.Invite); | |||||
| Update(model as API.Invite); | |||||
| IsRevoked = model.IsRevoked; | IsRevoked = model.IsRevoked; | ||||
| IsTemporary = model.IsTemporary; | IsTemporary = model.IsTemporary; | ||||
| MaxAge = model.MaxAge; | MaxAge = model.MaxAge; | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json; | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| @@ -17,7 +16,7 @@ namespace Discord | |||||
| /// <summary> Returns the unique identifier for this user's current avatar. </summary> | /// <summary> Returns the unique identifier for this user's current avatar. </summary> | ||||
| public string AvatarId { get; internal set; } | public string AvatarId { get; internal set; } | ||||
| /// <summary> Returns the URL to this user's current avatar. </summary> | /// <summary> Returns the URL to this user's current avatar. </summary> | ||||
| public string AvatarUrl => Endpoints.UserAvatar(UserId, AvatarId); | |||||
| public string AvatarUrl => API.Endpoints.UserAvatar(UserId, AvatarId); | |||||
| /// <summary> Returns the datetime that this user joined this server. </summary> | /// <summary> Returns the datetime that this user joined this server. </summary> | ||||
| public DateTime JoinedAt { get; internal set; } | public DateTime JoinedAt { get; internal set; } | ||||
| @@ -70,7 +69,7 @@ namespace Discord | |||||
| public override string ToString() => UserId; | public override string ToString() => UserId; | ||||
| internal void Update(UserReference model) | |||||
| internal void Update(API.UserReference model) | |||||
| { | { | ||||
| if (model.Avatar != null) | if (model.Avatar != null) | ||||
| AvatarId = model.Avatar; | AvatarId = model.Avatar; | ||||
| @@ -79,7 +78,7 @@ namespace Discord | |||||
| if (model.Username != null) | if (model.Username != null) | ||||
| Name = model.Username; | Name = model.Username; | ||||
| } | } | ||||
| internal void Update(MemberInfo model) | |||||
| internal void Update(API.MemberInfo model) | |||||
| { | { | ||||
| if (model.User != null) | if (model.User != null) | ||||
| Update(model.User); | Update(model.User); | ||||
| @@ -87,13 +86,13 @@ namespace Discord | |||||
| if (model.JoinedAt.HasValue) | if (model.JoinedAt.HasValue) | ||||
| JoinedAt = model.JoinedAt.Value; | JoinedAt = model.JoinedAt.Value; | ||||
| } | } | ||||
| internal void Update(ExtendedMemberInfo model) | |||||
| internal void Update(API.ExtendedMemberInfo model) | |||||
| { | { | ||||
| Update(model as MemberInfo); | |||||
| Update(model as API.MemberInfo); | |||||
| IsDeafened = model.IsDeafened; | IsDeafened = model.IsDeafened; | ||||
| IsMuted = model.IsMuted; | IsMuted = model.IsMuted; | ||||
| } | } | ||||
| internal void Update(PresenceMemberInfo model) | |||||
| internal void Update(API.PresenceMemberInfo model) | |||||
| { | { | ||||
| if (Status != model.Status) | if (Status != model.Status) | ||||
| { | { | ||||
| @@ -103,7 +102,7 @@ namespace Discord | |||||
| } | } | ||||
| GameId = model.GameId; | GameId = model.GameId; | ||||
| } | } | ||||
| internal void Update(VoiceMemberInfo model) | |||||
| internal void Update(API.VoiceMemberInfo model) | |||||
| { | { | ||||
| IsDeafened = model.IsDeafened; | IsDeafened = model.IsDeafened; | ||||
| IsMuted = model.IsMuted; | IsMuted = model.IsMuted; | ||||
| @@ -122,7 +122,7 @@ namespace Discord | |||||
| UserId = userId; | UserId = userId; | ||||
| } | } | ||||
| internal void Update(Net.API.Message model) | |||||
| internal void Update(API.Message model) | |||||
| { | { | ||||
| if (model.Attachments != null) | if (model.Attachments != null) | ||||
| { | { | ||||
| @@ -71,8 +71,7 @@ namespace Discord | |||||
| else | else | ||||
| _rawValue &= ~(1U << (pos - 1)); | _rawValue &= ~(1U << (pos - 1)); | ||||
| } | } | ||||
| public static implicit operator uint (PackedPermissions perms) => perms._rawValue; | |||||
| public PackedPermissions Copy() => new PackedPermissions(false, _rawValue); | public PackedPermissions Copy() => new PackedPermissions(false, _rawValue); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System.Threading; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -29,7 +28,7 @@ namespace Discord | |||||
| Permissions = new PackedPermissions(true); | Permissions = new PackedPermissions(true); | ||||
| } | } | ||||
| internal void Update(Net.API.RoleInfo model) | |||||
| internal void Update(API.RoleInfo model) | |||||
| { | { | ||||
| Name = model.Name; | Name = model.Name; | ||||
| Permissions.RawValue = (uint)model.Permissions; | Permissions.RawValue = (uint)model.Permissions; | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json; | |||||
| using System; | using System; | ||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -100,7 +99,7 @@ namespace Discord | |||||
| _roles = new ConcurrentDictionary<string, bool>(); | _roles = new ConcurrentDictionary<string, bool>(); | ||||
| } | } | ||||
| internal void Update(GuildInfo model) | |||||
| internal void Update(API.GuildInfo model) | |||||
| { | { | ||||
| AFKChannelId = model.AFKChannelId; | AFKChannelId = model.AFKChannelId; | ||||
| AFKTimeout = model.AFKTimeout; | AFKTimeout = model.AFKTimeout; | ||||
| @@ -117,9 +116,9 @@ namespace Discord | |||||
| role.Update(subModel); | role.Update(subModel); | ||||
| } | } | ||||
| } | } | ||||
| internal void Update(ExtendedGuildInfo model) | |||||
| internal void Update(API.ExtendedGuildInfo model) | |||||
| { | { | ||||
| Update(model as GuildInfo); | |||||
| Update(model as API.GuildInfo); | |||||
| var channels = _client.Channels; | var channels = _client.Channels; | ||||
| foreach (var subModel in model.Channels) | foreach (var subModel in model.Channels) | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json; | |||||
| using System; | using System; | ||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -24,7 +23,7 @@ namespace Discord | |||||
| /// <summary> Returns the unique identifier for this user's current avatar. </summary> | /// <summary> Returns the unique identifier for this user's current avatar. </summary> | ||||
| public string AvatarId { get; internal set; } | public string AvatarId { get; internal set; } | ||||
| /// <summary> Returns the URL to this user's current avatar. </summary> | /// <summary> Returns the URL to this user's current avatar. </summary> | ||||
| public string AvatarUrl => Endpoints.UserAvatar(Id, AvatarId); | |||||
| public string AvatarUrl => API.Endpoints.UserAvatar(Id, AvatarId); | |||||
| /// <summary> Returns the email for this user. </summary> | /// <summary> Returns the email for this user. </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> | ||||
| @@ -78,7 +77,7 @@ namespace Discord | |||||
| _servers = new ConcurrentDictionary<string, bool>(); | _servers = new ConcurrentDictionary<string, bool>(); | ||||
| } | } | ||||
| internal void Update(UserReference model) | |||||
| internal void Update(API.UserReference model) | |||||
| { | { | ||||
| if (model.Avatar != null) | if (model.Avatar != null) | ||||
| AvatarId = model.Avatar; | AvatarId = model.Avatar; | ||||
| @@ -87,9 +86,9 @@ namespace Discord | |||||
| if (model.Username != null) | if (model.Username != null) | ||||
| Name = model.Username; | Name = model.Username; | ||||
| } | } | ||||
| internal void Update(SelfUserInfo model) | |||||
| internal void Update(API.SelfUserInfo model) | |||||
| { | { | ||||
| Update(model as UserReference); | |||||
| Update(model as API.UserReference); | |||||
| Email = model.Email; | Email = model.Email; | ||||
| IsVerified = model.IsVerified; | IsVerified = model.IsVerified; | ||||
| } | } | ||||
| @@ -1,295 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| namespace Discord.Net.API | |||||
| { | |||||
| //User | |||||
| internal class UserReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "username")] | |||||
| public string Username; | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "discriminator")] | |||||
| public string Discriminator; | |||||
| [JsonProperty(PropertyName = "avatar")] | |||||
| public string Avatar; | |||||
| } | |||||
| internal class SelfUserInfo : UserReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string Email; | |||||
| [JsonProperty(PropertyName = "verified")] | |||||
| public bool IsVerified; | |||||
| } | |||||
| //Members | |||||
| internal class MemberReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty(PropertyName = "user")] | |||||
| public UserReference User; | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| } | |||||
| internal class MemberInfo : MemberReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "joined_at")] | |||||
| public DateTime? JoinedAt; | |||||
| [JsonProperty(PropertyName = "roles")] | |||||
| public string[] Roles; | |||||
| } | |||||
| internal class ExtendedMemberInfo : MemberInfo | |||||
| { | |||||
| [JsonProperty(PropertyName = "mute")] | |||||
| public bool IsMuted; | |||||
| [JsonProperty(PropertyName = "deaf")] | |||||
| public bool IsDeafened; | |||||
| } | |||||
| internal class PresenceMemberInfo : MemberReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "game_id")] | |||||
| public string GameId; | |||||
| [JsonProperty(PropertyName = "status")] | |||||
| public string Status; | |||||
| } | |||||
| internal class VoiceMemberInfo : MemberReference | |||||
| { | |||||
| [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; | |||||
| } | |||||
| //Channels | |||||
| internal class ChannelReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| [JsonProperty(PropertyName = "type")] | |||||
| public string Type; | |||||
| } | |||||
| 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")] | |||||
| public string LastMessageId; | |||||
| [JsonProperty(PropertyName = "is_private")] | |||||
| public bool IsPrivate; | |||||
| [JsonProperty(PropertyName = "position")] | |||||
| public int Position; | |||||
| [JsonProperty(PropertyName = "permission_overwrites")] | |||||
| public PermissionOverwrite[] PermissionOverwrites; | |||||
| [JsonProperty(PropertyName = "recipient")] | |||||
| public UserReference Recipient; | |||||
| } | |||||
| //Guilds (Servers) | |||||
| internal class GuildReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| } | |||||
| internal class GuildInfo : GuildReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "afk_channel_id")] | |||||
| public string AFKChannelId; | |||||
| [JsonProperty(PropertyName = "afk_timeout")] | |||||
| public int AFKTimeout; | |||||
| [JsonProperty(PropertyName = "embed_channel_id")] | |||||
| public string EmbedChannelId; | |||||
| [JsonProperty(PropertyName = "embed_enabled")] | |||||
| public bool EmbedEnabled; | |||||
| [JsonProperty(PropertyName = "icon")] | |||||
| public string Icon; | |||||
| [JsonProperty(PropertyName = "joined_at")] | |||||
| public DateTime? JoinedAt; | |||||
| [JsonProperty(PropertyName = "owner_id")] | |||||
| public string OwnerId; | |||||
| [JsonProperty(PropertyName = "region")] | |||||
| public string Region; | |||||
| [JsonProperty(PropertyName = "roles")] | |||||
| public RoleInfo[] Roles; | |||||
| } | |||||
| internal class ExtendedGuildInfo : GuildInfo | |||||
| { | |||||
| [JsonProperty(PropertyName = "channels")] | |||||
| public ChannelInfo[] Channels; | |||||
| [JsonProperty(PropertyName = "members")] | |||||
| public ExtendedMemberInfo[] Members; | |||||
| [JsonProperty(PropertyName = "presences")] | |||||
| public PresenceMemberInfo[] Presences; | |||||
| [JsonProperty(PropertyName = "voice_states")] | |||||
| public VoiceMemberInfo[] VoiceStates; | |||||
| } | |||||
| //Messages | |||||
| internal class MessageReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty(PropertyName = "message_id")] | |||||
| public string MessageId { get { return Id; } set { Id = value; } } | |||||
| } | |||||
| internal class Message : MessageReference | |||||
| { | |||||
| public sealed class Attachment | |||||
| { | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "url")] | |||||
| public string Url; | |||||
| [JsonProperty(PropertyName = "proxy_url")] | |||||
| public string ProxyUrl; | |||||
| [JsonProperty(PropertyName = "size")] | |||||
| public int Size; | |||||
| [JsonProperty(PropertyName = "filename")] | |||||
| public string Filename; | |||||
| [JsonProperty(PropertyName = "width")] | |||||
| public int Width; | |||||
| [JsonProperty(PropertyName = "height")] | |||||
| public int Height; | |||||
| } | |||||
| public sealed class Embed | |||||
| { | |||||
| public sealed class Reference | |||||
| { | |||||
| [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 = "author")] | |||||
| public Reference Author; | |||||
| [JsonProperty(PropertyName = "provider")] | |||||
| public Reference Provider; | |||||
| [JsonProperty(PropertyName = "thumbnail")] | |||||
| public ThumbnailInfo Thumbnail; | |||||
| } | |||||
| [JsonProperty(PropertyName = "tts")] | |||||
| public bool IsTextToSpeech; | |||||
| [JsonProperty(PropertyName = "mention_everyone")] | |||||
| public bool IsMentioningEveryone; | |||||
| [JsonProperty(PropertyName = "timestamp")] | |||||
| public DateTime Timestamp; | |||||
| [JsonProperty(PropertyName = "edited_timestamp")] | |||||
| public DateTime? EditedTimestamp; | |||||
| [JsonProperty(PropertyName = "mentions")] | |||||
| public UserReference[] Mentions; | |||||
| [JsonProperty(PropertyName = "embeds")] | |||||
| public Embed[] Embeds; //TODO: Parse this | |||||
| [JsonProperty(PropertyName = "attachments")] | |||||
| public Attachment[] Attachments; | |||||
| [JsonProperty(PropertyName = "content")] | |||||
| public string Content; | |||||
| [JsonProperty(PropertyName = "author")] | |||||
| public UserReference Author; | |||||
| [JsonProperty(PropertyName = "nonce")] | |||||
| public string Nonce; | |||||
| } | |||||
| //Roles | |||||
| internal class RoleReference | |||||
| { | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty(PropertyName = "role_id")] | |||||
| public string RoleId; | |||||
| } | |||||
| internal class RoleInfo | |||||
| { | |||||
| [JsonProperty(PropertyName = "permissions")] | |||||
| public int Permissions; | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| } | |||||
| //Invites | |||||
| internal class Invite | |||||
| { | |||||
| [JsonProperty(PropertyName = "inviter")] | |||||
| public UserReference Inviter; | |||||
| [JsonProperty(PropertyName = "guild")] | |||||
| public GuildReference Guild; | |||||
| [JsonProperty(PropertyName = "channel")] | |||||
| public ChannelReference Channel; | |||||
| [JsonProperty(PropertyName = "code")] | |||||
| public string Code; | |||||
| [JsonProperty(PropertyName = "xkcdpass")] | |||||
| public string XkcdPass; | |||||
| } | |||||
| internal class ExtendedInvite : Invite | |||||
| { | |||||
| [JsonProperty(PropertyName = "max_age")] | |||||
| public int MaxAge; | |||||
| [JsonProperty(PropertyName = "max_uses")] | |||||
| public int MaxUses; | |||||
| [JsonProperty(PropertyName = "revoked")] | |||||
| public bool IsRevoked; | |||||
| [JsonProperty(PropertyName = "temporary")] | |||||
| public bool IsTemporary; | |||||
| [JsonProperty(PropertyName = "uses")] | |||||
| public int Uses; | |||||
| [JsonProperty(PropertyName = "created_at")] | |||||
| public DateTime CreatedAt; | |||||
| } | |||||
| } | |||||
| @@ -1,212 +0,0 @@ | |||||
| using System; | |||||
| using System.Threading; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord.Net.API | |||||
| { | |||||
| internal class DiscordAPIClient | |||||
| { | |||||
| public const int MaxMessageSize = 2000; | |||||
| public RestClient RestClient => _rest; | |||||
| private readonly RestClient _rest; | |||||
| public DiscordAPIClient(LogMessageSeverity logLevel, int timeout) | |||||
| { | |||||
| _rest = new RestClient(logLevel, timeout); | |||||
| } | |||||
| private string _token; | |||||
| public string Token | |||||
| { | |||||
| get { return _token; } | |||||
| set { _token = value; _rest.SetToken(value); } | |||||
| } | |||||
| private CancellationToken _cancelToken; | |||||
| public CancellationToken CancelToken | |||||
| { | |||||
| get { return _cancelToken; } | |||||
| set { _cancelToken = value; _rest.SetCancelToken(value); } | |||||
| } | |||||
| //Auth | |||||
| public Task<Responses.Gateway> GetWebSocketEndpoint() | |||||
| => _rest.Get<Responses.Gateway>(Endpoints.Gateway); | |||||
| public async Task<Responses.AuthRegister> LoginAnonymous(string username) | |||||
| { | |||||
| var fingerprintResponse = await _rest.Post<Responses.AuthFingerprint>(Endpoints.AuthFingerprint).ConfigureAwait(false); | |||||
| var registerRequest = new Requests.AuthRegister { Fingerprint = fingerprintResponse.Fingerprint, Username = username }; | |||||
| var registerResponse = await _rest.Post<Responses.AuthRegister>(Endpoints.AuthRegister, registerRequest).ConfigureAwait(false); | |||||
| return registerResponse; | |||||
| } | |||||
| public async Task<Responses.AuthLogin> Login(string email, string password) | |||||
| { | |||||
| var request = new Requests.AuthLogin { Email = email, Password = password }; | |||||
| var response = await _rest.Post<Responses.AuthLogin>(Endpoints.AuthLogin, request).ConfigureAwait(false); | |||||
| return response; | |||||
| } | |||||
| public Task Logout() | |||||
| => _rest.Post(Endpoints.AuthLogout); | |||||
| //Servers | |||||
| public Task<Responses.CreateServer> CreateServer(string name, string region) | |||||
| { | |||||
| var request = new Requests.CreateServer { Name = name, Region = region }; | |||||
| return _rest.Post<Responses.CreateServer>(Endpoints.Servers, request); | |||||
| } | |||||
| public Task LeaveServer(string id) | |||||
| => _rest.Delete<Responses.DeleteServer>(Endpoints.Server(id)); | |||||
| //Channels | |||||
| public Task<Responses.CreateChannel> CreateChannel(string serverId, string name, string channelType) | |||||
| { | |||||
| var request = new Requests.CreateChannel { Name = name, Type = channelType }; | |||||
| return _rest.Post<Responses.CreateChannel>(Endpoints.ServerChannels(serverId), request); | |||||
| } | |||||
| public Task<Responses.CreateChannel> CreatePMChannel(string myId, string recipientId) | |||||
| { | |||||
| var request = new Requests.CreatePMChannel { RecipientId = recipientId }; | |||||
| return _rest.Post<Responses.CreateChannel>(Endpoints.UserChannels(myId), request); | |||||
| } | |||||
| public Task<Responses.DestroyChannel> DestroyChannel(string channelId) | |||||
| => _rest.Delete<Responses.DestroyChannel>(Endpoints.Channel(channelId)); | |||||
| public Task<Responses.GetMessages[]> GetMessages(string channelId, int count) | |||||
| => _rest.Get<Responses.GetMessages[]>(Endpoints.ChannelMessages(channelId, count)); | |||||
| //Members | |||||
| public Task Kick(string serverId, string userId) | |||||
| => _rest.Delete(Endpoints.ServerMember(serverId, userId)); | |||||
| public Task Ban(string serverId, string userId) | |||||
| => _rest.Put(Endpoints.ServerBan(serverId, userId)); | |||||
| public Task Unban(string serverId, string userId) | |||||
| => _rest.Delete(Endpoints.ServerBan(serverId, userId)); | |||||
| public Task SetMemberRoles(string serverId, string userId, string[] roles) | |||||
| { | |||||
| var request = new Requests.ModifyMember { Roles = roles }; | |||||
| return _rest.Patch(Endpoints.ServerMember(serverId, userId)); | |||||
| } | |||||
| //Invites | |||||
| public Task<Responses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool withXkcdPass) | |||||
| { | |||||
| var request = new Requests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, WithXkcdPass = withXkcdPass }; | |||||
| return _rest.Post<Responses.CreateInvite>(Endpoints.ChannelInvites(channelId), request); | |||||
| } | |||||
| public Task<Responses.GetInvite> GetInvite(string id) | |||||
| => _rest.Get<Responses.GetInvite>(Endpoints.Invite(id)); | |||||
| public Task AcceptInvite(string id) | |||||
| => _rest.Post<Responses.AcceptInvite>(Endpoints.Invite(id)); | |||||
| public Task DeleteInvite(string id) | |||||
| => _rest.Delete(Endpoints.Invite(id)); | |||||
| //Roles | |||||
| public Task CreateRole(string serverId) | |||||
| { | |||||
| //TODO: Return a result when Discord starts giving us one | |||||
| return _rest.Post(Endpoints.ServerRoles(serverId)); | |||||
| } | |||||
| public Task RenameRole(string serverId, string roleId, string newName) | |||||
| { | |||||
| var request = new Requests.ModifyRole { Name = newName }; | |||||
| return _rest.Patch(Endpoints.ServerRole(serverId, roleId), request); | |||||
| } | |||||
| public Task SetRolePermissions(string serverId, string roleId, PackedPermissions permissions) | |||||
| { | |||||
| var request = new Requests.ModifyRole { Permissions = permissions.RawValue }; | |||||
| return _rest.Patch(Endpoints.ServerRole(serverId, roleId), request); | |||||
| } | |||||
| public Task DeleteRole(string serverId, string roleId) | |||||
| { | |||||
| return _rest.Delete(Endpoints.ServerRole(serverId, roleId)); | |||||
| } | |||||
| //Permissions | |||||
| public Task SetChannelPermissions(string channelId, string userOrRoleId, string idType, PackedPermissions allow, PackedPermissions deny) | |||||
| { | |||||
| var request = new Requests.SetChannelPermissions { Id = userOrRoleId, Type = idType, Allow = allow.RawValue, Deny = deny.RawValue }; | |||||
| return _rest.Put(Endpoints.ChannelPermission(channelId, userOrRoleId), request); | |||||
| } | |||||
| public Task DeleteChannelPermissions(string channelId, string userOrRoleId) | |||||
| { | |||||
| return _rest.Delete(Endpoints.ChannelPermission(channelId, userOrRoleId), null); | |||||
| } | |||||
| //Chat | |||||
| public Task<Responses.SendMessage> SendMessage(string channelId, string message, string[] mentions, string nonce, bool isTTS) | |||||
| { | |||||
| var request = new Requests.SendMessage { Content = message, Mentions = mentions, Nonce = nonce, IsTTS = isTTS }; | |||||
| return _rest.Post<Responses.SendMessage>(Endpoints.ChannelMessages(channelId), request); | |||||
| } | |||||
| public Task<Responses.EditMessage> EditMessage(string messageId, string channelId, string message, string[] mentions) | |||||
| { | |||||
| var request = new Requests.EditMessage { Content = message, Mentions = mentions }; | |||||
| return _rest.Patch<Responses.EditMessage>(Endpoints.ChannelMessage(channelId, messageId), request); | |||||
| } | |||||
| public Task SendIsTyping(string channelId) | |||||
| => _rest.Post(Endpoints.ChannelTyping(channelId)); | |||||
| public Task DeleteMessage(string channelId, string msgId) | |||||
| => _rest.Delete(Endpoints.ChannelMessage(channelId, msgId)); | |||||
| public Task SendFile(string channelId, string filePath) | |||||
| => _rest.PostFile<Responses.SendMessage>(Endpoints.ChannelMessages(channelId), filePath); | |||||
| //Voice | |||||
| public Task<Responses.GetRegions[]> GetVoiceRegions() | |||||
| => _rest.Get<Responses.GetRegions[]>(Endpoints.VoiceRegions); | |||||
| public Task<Responses.GetIce> GetVoiceIce() | |||||
| => _rest.Get<Responses.GetIce>(Endpoints.VoiceIce); | |||||
| public Task Mute(string serverId, string memberId) | |||||
| { | |||||
| var request = new Requests.SetMemberMute { Value = true }; | |||||
| return _rest.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | |||||
| public Task Unmute(string serverId, string memberId) | |||||
| { | |||||
| var request = new Requests.SetMemberMute { Value = false }; | |||||
| return _rest.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | |||||
| public Task Deafen(string serverId, string memberId) | |||||
| { | |||||
| var request = new Requests.SetMemberDeaf { Value = true }; | |||||
| return _rest.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | |||||
| public Task Undeafen(string serverId, string memberId) | |||||
| { | |||||
| var request = new Requests.SetMemberDeaf { Value = false }; | |||||
| return _rest.Patch(Endpoints.ServerMember(serverId, memberId)); | |||||
| } | |||||
| //Profile | |||||
| public Task<Responses.ChangeProfile> ChangeUsername(string newUsername, string currentEmail, string currentPassword) | |||||
| { | |||||
| var request = new Requests.ChangeUsername { Username = newUsername, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | |||||
| return _rest.Patch<Responses.ChangeProfile>(Endpoints.UserMe, request); | |||||
| } | |||||
| public Task<Responses.ChangeProfile> ChangeEmail(string newEmail, string currentPassword) | |||||
| { | |||||
| var request = new Requests.ChangeEmail { NewEmail = newEmail, CurrentPassword = currentPassword }; | |||||
| return _rest.Patch<Responses.ChangeProfile>(Endpoints.UserMe, request); | |||||
| } | |||||
| public Task<Responses.ChangeProfile> ChangePassword(string newPassword, string currentEmail, string currentPassword) | |||||
| { | |||||
| var request = new Requests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | |||||
| return _rest.Patch<Responses.ChangeProfile>(Endpoints.UserMe, request); | |||||
| } | |||||
| public Task<Responses.ChangeProfile> ChangeAvatar(AvatarImageType imageType, byte[] bytes, string currentEmail, string currentPassword) | |||||
| { | |||||
| string base64 = Convert.ToBase64String(bytes); | |||||
| string type = imageType == AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | |||||
| var request = new Requests.ChangeAvatar { Avatar = $"data:{type},/9j/{base64}", CurrentEmail = currentEmail, CurrentPassword = currentPassword }; | |||||
| return _rest.Patch<Responses.ChangeProfile>(Endpoints.UserMe, request); | |||||
| } | |||||
| //Other | |||||
| /*public Task<Responses.Status> GetUnresolvedIncidents() | |||||
| { | |||||
| return _rest.Get<Responses.Status>(Endpoints.StatusUnresolvedMaintenance); | |||||
| } | |||||
| public Task<Responses.Status> GetActiveIncidents() | |||||
| { | |||||
| return _rest.Get<Responses.Status>(Endpoints.StatusActiveMaintenance); | |||||
| }*/ | |||||
| } | |||||
| } | |||||
| @@ -1,158 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.Net.API | |||||
| { | |||||
| internal static class Requests | |||||
| { | |||||
| //Auth | |||||
| public sealed class AuthRegister | |||||
| { | |||||
| [JsonProperty(PropertyName = "fingerprint")] | |||||
| public string Fingerprint; | |||||
| [JsonProperty(PropertyName = "username")] | |||||
| public string Username; | |||||
| } | |||||
| public sealed class AuthLogin | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string Email; | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string Password; | |||||
| } | |||||
| //Servers | |||||
| public sealed class CreateServer | |||||
| { | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| [JsonProperty(PropertyName = "region")] | |||||
| public string Region; | |||||
| } | |||||
| //Channels | |||||
| public sealed class CreateChannel | |||||
| { | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| [JsonProperty(PropertyName = "type")] | |||||
| public string Type; | |||||
| } | |||||
| public sealed class CreatePMChannel | |||||
| { | |||||
| [JsonProperty(PropertyName = "recipient_id")] | |||||
| public string RecipientId; | |||||
| } | |||||
| //Invites | |||||
| public sealed class CreateInvite | |||||
| { | |||||
| [JsonProperty(PropertyName = "max_age")] | |||||
| public int MaxAge; | |||||
| [JsonProperty(PropertyName = "max_uses")] | |||||
| public int MaxUses; | |||||
| [JsonProperty(PropertyName = "temporary")] | |||||
| public bool IsTemporary; | |||||
| [JsonProperty(PropertyName = "xkcdpass")] | |||||
| public bool WithXkcdPass; | |||||
| } | |||||
| //Messages | |||||
| public sealed class SendMessage | |||||
| { | |||||
| [JsonProperty(PropertyName = "content")] | |||||
| public string Content; | |||||
| [JsonProperty(PropertyName = "mentions")] | |||||
| public string[] Mentions; | |||||
| [JsonProperty(PropertyName = "nonce")] | |||||
| public string Nonce; | |||||
| [JsonProperty(PropertyName = "tts")] | |||||
| public bool IsTTS; | |||||
| } | |||||
| public sealed class EditMessage | |||||
| { | |||||
| [JsonProperty(PropertyName = "content")] | |||||
| public string Content; | |||||
| [JsonProperty(PropertyName = "mentions")] | |||||
| public string[] Mentions; | |||||
| } | |||||
| //Members | |||||
| public sealed class SetMemberMute | |||||
| { | |||||
| [JsonProperty(PropertyName = "mute")] | |||||
| public bool Value; | |||||
| } | |||||
| public sealed class SetMemberDeaf | |||||
| { | |||||
| [JsonProperty(PropertyName = "deaf")] | |||||
| public bool Value; | |||||
| } | |||||
| public sealed class ModifyMember | |||||
| { | |||||
| [JsonProperty(PropertyName = "roles")] | |||||
| public string[] Roles; | |||||
| } | |||||
| //Profile | |||||
| public sealed class ChangeUsername | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string CurrentEmail; | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string CurrentPassword; | |||||
| [JsonProperty(PropertyName = "username")] | |||||
| public string Username; | |||||
| } | |||||
| public sealed class ChangeEmail | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string NewEmail; | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string CurrentPassword; | |||||
| } | |||||
| public sealed class ChangePassword | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string CurrentEmail; | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string CurrentPassword; | |||||
| [JsonProperty(PropertyName = "new_password")] | |||||
| public string NewPassword; | |||||
| } | |||||
| public sealed class ChangeAvatar | |||||
| { | |||||
| [JsonProperty(PropertyName = "email")] | |||||
| public string CurrentEmail; | |||||
| [JsonProperty(PropertyName = "password")] | |||||
| public string CurrentPassword; | |||||
| [JsonProperty(PropertyName = "avatar")] | |||||
| public string Avatar; | |||||
| } | |||||
| //Roles | |||||
| public sealed class ModifyRole | |||||
| { | |||||
| [JsonProperty(PropertyName = "name", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Name; | |||||
| [JsonProperty(PropertyName = "permissions", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public uint Permissions; | |||||
| } | |||||
| //Permissions | |||||
| public sealed class SetChannelPermissions | |||||
| { | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "type")] | |||||
| public string Type; | |||||
| [JsonProperty(PropertyName = "allow")] | |||||
| public uint Allow; | |||||
| [JsonProperty(PropertyName = "deny")] | |||||
| public uint Deny; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,85 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| namespace Discord.Net.API | |||||
| { | |||||
| internal static class Responses | |||||
| { | |||||
| //Auth | |||||
| public sealed class Gateway | |||||
| { | |||||
| [JsonProperty(PropertyName = "url")] | |||||
| public string Url; | |||||
| } | |||||
| public sealed class AuthFingerprint | |||||
| { | |||||
| [JsonProperty(PropertyName = "fingerprint")] | |||||
| public string Fingerprint; | |||||
| } | |||||
| public sealed class AuthRegister | |||||
| { | |||||
| [JsonProperty(PropertyName = "token")] | |||||
| public string Token; | |||||
| } | |||||
| public sealed class AuthLogin | |||||
| { | |||||
| [JsonProperty(PropertyName = "token")] | |||||
| public string Token; | |||||
| } | |||||
| //Users | |||||
| public sealed class ChangeProfile : SelfUserInfo { } | |||||
| //Servers | |||||
| public sealed class CreateServer : GuildInfo { } | |||||
| public sealed class DeleteServer : GuildInfo { } | |||||
| //Channels | |||||
| public sealed class CreateChannel : ChannelInfo { } | |||||
| public sealed class DestroyChannel : ChannelInfo { } | |||||
| //Invites | |||||
| public sealed class CreateInvite : ExtendedInvite { } | |||||
| public sealed class GetInvite : Invite { } | |||||
| public sealed class AcceptInvite : Invite { } | |||||
| //Messages | |||||
| public sealed class SendMessage : Message { } | |||||
| public sealed class EditMessage : Message { } | |||||
| public sealed class GetMessages : Message { } | |||||
| //Voice | |||||
| public sealed class GetRegions | |||||
| { | |||||
| [JsonProperty(PropertyName = "sample_hostname")] | |||||
| public string Hostname; | |||||
| [JsonProperty(PropertyName = "sample_port")] | |||||
| public int Port; | |||||
| [JsonProperty(PropertyName = "id")] | |||||
| public string Id; | |||||
| [JsonProperty(PropertyName = "name")] | |||||
| public string Name; | |||||
| } | |||||
| public sealed class GetIce | |||||
| { | |||||
| [JsonProperty(PropertyName = "ttl")] | |||||
| public string TTL; | |||||
| [JsonProperty(PropertyName = "servers")] | |||||
| public Server[] Servers; | |||||
| public sealed class Server | |||||
| { | |||||
| [JsonProperty(PropertyName = "url")] | |||||
| public string URL; | |||||
| [JsonProperty(PropertyName = "username")] | |||||
| public string Username; | |||||
| [JsonProperty(PropertyName = "credential")] | |||||
| public string Credential; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,71 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| using Newtonsoft.Json.Linq; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| namespace Discord.Net.WebSockets | |||||
| { | |||||
| internal static class Commands | |||||
| { | |||||
| public sealed class KeepAlive : WebSocketMessage<ulong> | |||||
| { | |||||
| public KeepAlive() : base(1, GetTimestamp()) { } | |||||
| private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); | |||||
| private static ulong GetTimestamp() => (ulong)(DateTime.UtcNow - epoch).TotalMilliseconds; | |||||
| } | |||||
| public sealed class Login : WebSocketMessage<Login.Data> | |||||
| { | |||||
| public Login() : base(2) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "token")] | |||||
| public string Token; | |||||
| [JsonProperty(PropertyName = "v")] | |||||
| public int Version = 3; | |||||
| [JsonProperty(PropertyName = "properties")] | |||||
| public Dictionary<string, string> Properties = new Dictionary<string, string>(); | |||||
| } | |||||
| } | |||||
| public sealed class UpdateStatus : WebSocketMessage<UpdateStatus.Data> | |||||
| { | |||||
| public UpdateStatus() : base(3) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "idle_since")] | |||||
| public string IdleSince; | |||||
| [JsonProperty(PropertyName = "game_id")] | |||||
| public string GameId; | |||||
| } | |||||
| } | |||||
| public sealed class JoinVoice : WebSocketMessage<JoinVoice.Data> | |||||
| { | |||||
| public JoinVoice() : base(4) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string ServerId; | |||||
| [JsonProperty(PropertyName = "channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty(PropertyName = "self_mute")] | |||||
| public string SelfMute; | |||||
| [JsonProperty(PropertyName = "self_deaf")] | |||||
| public string SelfDeaf; | |||||
| } | |||||
| } | |||||
| public sealed class Resume : WebSocketMessage<Resume.Data> | |||||
| { | |||||
| public Resume() : base(6) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty(PropertyName = "seq")] | |||||
| public int Sequence; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,118 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Discord.Net.API; | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.Net.WebSockets | |||||
| { | |||||
| internal static class Events | |||||
| { | |||||
| 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")] | |||||
| public SelfUserInfo User; | |||||
| [JsonProperty(PropertyName = "session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty(PropertyName = "read_state")] | |||||
| public ReadStateInfo[] ReadState; | |||||
| [JsonProperty(PropertyName = "guilds")] | |||||
| public ExtendedGuildInfo[] Guilds; | |||||
| [JsonProperty(PropertyName = "private_channels")] | |||||
| public ChannelInfo[] PrivateChannels; | |||||
| [JsonProperty(PropertyName = "heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| public sealed class Resumed | |||||
| { | |||||
| [JsonProperty(PropertyName = "heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| public sealed class Redirect | |||||
| { | |||||
| [JsonProperty(PropertyName = "url")] | |||||
| public string Url; | |||||
| } | |||||
| //Servers | |||||
| public sealed class GuildCreate : ExtendedGuildInfo { } | |||||
| public sealed class GuildUpdate : GuildInfo { } | |||||
| public sealed class GuildDelete : ExtendedGuildInfo { } | |||||
| //Channels | |||||
| public sealed class ChannelCreate : ChannelInfo { } | |||||
| public sealed class ChannelDelete : ChannelInfo { } | |||||
| public sealed class ChannelUpdate : ChannelInfo { } | |||||
| //Memberships | |||||
| public sealed class GuildMemberAdd : MemberInfo { } | |||||
| public sealed class GuildMemberUpdate : MemberInfo { } | |||||
| public sealed class GuildMemberRemove : MemberInfo { } | |||||
| //Roles | |||||
| public sealed class GuildRoleCreate | |||||
| { | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty(PropertyName = "role")] | |||||
| public RoleInfo Data; | |||||
| } | |||||
| public sealed class GuildRoleUpdate | |||||
| { | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty(PropertyName = "role")] | |||||
| public RoleInfo Data; | |||||
| } | |||||
| public sealed class GuildRoleDelete : RoleReference { } | |||||
| //Bans | |||||
| public sealed class GuildBanAdd : MemberReference { } | |||||
| public sealed class GuildBanRemove : MemberReference { } | |||||
| //User | |||||
| public sealed class UserUpdate : SelfUserInfo { } | |||||
| public sealed class PresenceUpdate : PresenceMemberInfo { } | |||||
| public sealed class VoiceStateUpdate : VoiceMemberInfo { } | |||||
| //Chat | |||||
| public sealed class MessageCreate : API.Message { } | |||||
| public sealed class MessageUpdate : API.Message { } | |||||
| public sealed class MessageDelete : MessageReference { } | |||||
| public sealed class MessageAck : MessageReference { } | |||||
| public sealed class TypingStart | |||||
| { | |||||
| [JsonProperty(PropertyName = "user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty(PropertyName = "channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty(PropertyName = "timestamp")] | |||||
| public int Timestamp; | |||||
| } | |||||
| //Voice | |||||
| public sealed class VoiceServerUpdate | |||||
| { | |||||
| [JsonProperty(PropertyName = "guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty(PropertyName = "endpoint")] | |||||
| public string Endpoint; | |||||
| [JsonProperty(PropertyName = "token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,62 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.Net.WebSockets | |||||
| { | |||||
| internal static class VoiceCommands | |||||
| { | |||||
| public sealed class Login : WebSocketMessage<Login.Data> | |||||
| { | |||||
| public Login() : base(0) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "server_id")] | |||||
| public string ServerId; | |||||
| [JsonProperty(PropertyName = "user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty(PropertyName = "session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty(PropertyName = "token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| public sealed class Login2 : WebSocketMessage<Login2.Data> | |||||
| { | |||||
| public Login2() : base(1) { } | |||||
| public class Data | |||||
| { | |||||
| public class SocketInfo | |||||
| { | |||||
| [JsonProperty(PropertyName = "address")] | |||||
| public string Address; | |||||
| [JsonProperty(PropertyName = "port")] | |||||
| public int Port; | |||||
| [JsonProperty(PropertyName = "mode")] | |||||
| public string Mode = "xsalsa20_poly1305"; | |||||
| } | |||||
| [JsonProperty(PropertyName = "protocol")] | |||||
| public string Protocol = "udp"; | |||||
| [JsonProperty(PropertyName = "data")] | |||||
| public SocketInfo SocketData = new SocketInfo(); | |||||
| } | |||||
| } | |||||
| public sealed class KeepAlive : WebSocketMessage<object> | |||||
| { | |||||
| public KeepAlive() : base(3, null) { } | |||||
| } | |||||
| public sealed class IsTalking : WebSocketMessage<IsTalking.Data> | |||||
| { | |||||
| public IsTalking() : base(5) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty(PropertyName = "delay")] | |||||
| public int Delay; | |||||
| [JsonProperty(PropertyName = "speaking")] | |||||
| public bool IsSpeaking; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,41 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.Net.WebSockets | |||||
| { | |||||
| internal static class VoiceEvents | |||||
| { | |||||
| public sealed class Ready | |||||
| { | |||||
| [JsonProperty(PropertyName = "ssrc")] | |||||
| public uint SSRC; | |||||
| [JsonProperty(PropertyName = "port")] | |||||
| public ushort Port; | |||||
| [JsonProperty(PropertyName = "modes")] | |||||
| public string[] Modes; | |||||
| [JsonProperty(PropertyName = "heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| public sealed class JoinServer | |||||
| { | |||||
| [JsonProperty(PropertyName = "secret_key")] | |||||
| public byte[] SecretKey; | |||||
| [JsonProperty(PropertyName = "mode")] | |||||
| public string Mode; | |||||
| } | |||||
| public sealed class IsTalking | |||||
| { | |||||
| [JsonProperty(PropertyName = "user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty(PropertyName = "ssrc")] | |||||
| public uint SSRC; | |||||
| [JsonProperty(PropertyName = "speaking")] | |||||
| public bool IsSpeaking; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,8 +1,4 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -0,0 +1,67 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| namespace Discord.WebSockets.Data | |||||
| { | |||||
| internal sealed class KeepAliveCommand : WebSocketMessage<ulong> | |||||
| { | |||||
| public KeepAliveCommand() : base(1, GetTimestamp()) { } | |||||
| private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); | |||||
| private static ulong GetTimestamp() => (ulong)(DateTime.UtcNow - epoch).TotalMilliseconds; | |||||
| } | |||||
| internal sealed class LoginCommand : WebSocketMessage<LoginCommand.Data> | |||||
| { | |||||
| public LoginCommand() : base(2) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| [JsonProperty("v")] | |||||
| public int Version = 3; | |||||
| [JsonProperty("properties")] | |||||
| public Dictionary<string, string> Properties = new Dictionary<string, string>(); | |||||
| } | |||||
| } | |||||
| internal sealed class UpdateStatusCommand : WebSocketMessage<UpdateStatusCommand.Data> | |||||
| { | |||||
| public UpdateStatusCommand() : base(3) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("idle_since")] | |||||
| public string IdleSince; | |||||
| [JsonProperty("game_id")] | |||||
| public string GameId; | |||||
| } | |||||
| } | |||||
| internal sealed class JoinVoiceCommand : WebSocketMessage<JoinVoiceCommand.Data> | |||||
| { | |||||
| public JoinVoiceCommand() : base(4) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| public string ServerId; | |||||
| [JsonProperty("channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty("self_mute")] | |||||
| public string SelfMute; | |||||
| [JsonProperty("self_deaf")] | |||||
| public string SelfDeaf; | |||||
| } | |||||
| } | |||||
| internal sealed class ResumeCommand : WebSocketMessage<ResumeCommand.Data> | |||||
| { | |||||
| public ResumeCommand() : base(6) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty("seq")] | |||||
| public int Sequence; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,10 +1,9 @@ | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||
| using System; | using System; | ||||
| using System.Threading; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets.Data | |||||
| { | { | ||||
| internal partial class DataWebSocket : WebSocket | internal partial class DataWebSocket : WebSocket | ||||
| { | { | ||||
| @@ -22,7 +21,7 @@ namespace Discord.Net.WebSockets | |||||
| { | { | ||||
| await Connect().ConfigureAwait(false); | await Connect().ConfigureAwait(false); | ||||
| Commands.Login msg = new Commands.Login(); | |||||
| LoginCommand msg = new LoginCommand(); | |||||
| msg.Payload.Token = token; | msg.Payload.Token = token; | ||||
| msg.Payload.Properties["$device"] = "Discord.Net"; | msg.Payload.Properties["$device"] = "Discord.Net"; | ||||
| QueueMessage(msg); | QueueMessage(msg); | ||||
| @@ -32,7 +31,7 @@ namespace Discord.Net.WebSockets | |||||
| await DisconnectInternal(isUnexpected: false).ConfigureAwait(false); | await DisconnectInternal(isUnexpected: false).ConfigureAwait(false); | ||||
| await Connect().ConfigureAwait(false); | await Connect().ConfigureAwait(false); | ||||
| var resumeMsg = new Commands.Resume(); | |||||
| var resumeMsg = new ResumeCommand(); | |||||
| resumeMsg.Payload.SessionId = _sessionId; | resumeMsg.Payload.SessionId = _sessionId; | ||||
| resumeMsg.Payload.Sequence = _lastSeq; | resumeMsg.Payload.Sequence = _lastSeq; | ||||
| QueueMessage(resumeMsg); | QueueMessage(resumeMsg); | ||||
| @@ -75,16 +74,16 @@ namespace Discord.Net.WebSockets | |||||
| JToken token = msg.Payload as JToken; | JToken token = msg.Payload as JToken; | ||||
| if (msg.Type == "READY") | if (msg.Type == "READY") | ||||
| { | { | ||||
| var payload = token.ToObject<Events.Ready>(); | |||||
| var payload = token.ToObject<ReadyEvent>(); | |||||
| _sessionId = payload.SessionId; | _sessionId = payload.SessionId; | ||||
| _heartbeatInterval = payload.HeartbeatInterval; | _heartbeatInterval = payload.HeartbeatInterval; | ||||
| QueueMessage(new Commands.UpdateStatus()); | |||||
| QueueMessage(new UpdateStatusCommand()); | |||||
| } | } | ||||
| else if (msg.Type == "RESUMED") | else if (msg.Type == "RESUMED") | ||||
| { | { | ||||
| var payload = token.ToObject<Events.Resumed>(); | |||||
| var payload = token.ToObject<ResumedEvent>(); | |||||
| _heartbeatInterval = payload.HeartbeatInterval; | _heartbeatInterval = payload.HeartbeatInterval; | ||||
| QueueMessage(new Commands.UpdateStatus()); | |||||
| QueueMessage(new UpdateStatusCommand()); | |||||
| } | } | ||||
| RaiseReceivedEvent(msg.Type, token); | RaiseReceivedEvent(msg.Type, token); | ||||
| if (msg.Type == "READY" || msg.Type == "RESUMED") | if (msg.Type == "READY" || msg.Type == "RESUMED") | ||||
| @@ -93,7 +92,7 @@ namespace Discord.Net.WebSockets | |||||
| break; | break; | ||||
| case 7: //Redirect | case 7: //Redirect | ||||
| { | { | ||||
| var payload = (msg.Payload as JToken).ToObject<Events.Redirect>(); | |||||
| var payload = (msg.Payload as JToken).ToObject<RedirectEvent>(); | |||||
| Host = payload.Url; | Host = payload.Url; | ||||
| if (_logLevel >= LogMessageSeverity.Info) | if (_logLevel >= LogMessageSeverity.Info) | ||||
| RaiseOnLog(LogMessageSeverity.Info, "Redirected to " + payload.Url); | RaiseOnLog(LogMessageSeverity.Info, "Redirected to " + payload.Url); | ||||
| @@ -109,19 +108,19 @@ namespace Discord.Net.WebSockets | |||||
| protected override object GetKeepAlive() | protected override object GetKeepAlive() | ||||
| { | { | ||||
| return new Commands.KeepAlive(); | |||||
| return new KeepAliveCommand(); | |||||
| } | } | ||||
| public void SendJoinVoice(string serverId, string channelId) | public void SendJoinVoice(string serverId, string channelId) | ||||
| { | { | ||||
| var joinVoice = new Commands.JoinVoice(); | |||||
| var joinVoice = new JoinVoiceCommand(); | |||||
| joinVoice.Payload.ServerId = serverId; | joinVoice.Payload.ServerId = serverId; | ||||
| joinVoice.Payload.ChannelId = channelId; | joinVoice.Payload.ChannelId = channelId; | ||||
| QueueMessage(joinVoice); | QueueMessage(joinVoice); | ||||
| } | } | ||||
| public void SendLeaveVoice(string serverId) | public void SendLeaveVoice(string serverId) | ||||
| { | { | ||||
| var leaveVoice = new Commands.JoinVoice(); | |||||
| var leaveVoice = new JoinVoiceCommand(); | |||||
| leaveVoice.Payload.ServerId = serverId; | leaveVoice.Payload.ServerId = serverId; | ||||
| QueueMessage(leaveVoice); | QueueMessage(leaveVoice); | ||||
| } | } | ||||
| @@ -1,9 +1,9 @@ | |||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||
| using System; | using System; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets.Data | |||||
| { | { | ||||
| public sealed class WebSocketEventEventArgs : EventArgs | |||||
| internal sealed class WebSocketEventEventArgs : EventArgs | |||||
| { | { | ||||
| public readonly string Type; | public readonly string Type; | ||||
| public readonly JToken Payload; | public readonly JToken Payload; | ||||
| @@ -0,0 +1,115 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Discord.API; | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.WebSockets.Data | |||||
| { | |||||
| internal sealed class ReadyEvent | |||||
| { | |||||
| public sealed class ReadStateInfo | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty("mention_count")] | |||||
| public int MentionCount; | |||||
| [JsonProperty("last_message_id")] | |||||
| public string LastMessageId; | |||||
| } | |||||
| [JsonProperty("v")] | |||||
| public int Version; | |||||
| [JsonProperty("user")] | |||||
| public SelfUserInfo User; | |||||
| [JsonProperty("session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty("read_state")] | |||||
| public ReadStateInfo[] ReadState; | |||||
| [JsonProperty("guilds")] | |||||
| public ExtendedGuildInfo[] Guilds; | |||||
| [JsonProperty("private_channels")] | |||||
| public ChannelInfo[] PrivateChannels; | |||||
| [JsonProperty("heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| internal sealed class ResumedEvent | |||||
| { | |||||
| [JsonProperty("heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| internal sealed class RedirectEvent | |||||
| { | |||||
| [JsonProperty("url")] | |||||
| public string Url; | |||||
| } | |||||
| //Servers | |||||
| internal sealed class GuildCreateEvent : ExtendedGuildInfo { } | |||||
| internal sealed class GuildUpdateEvent : GuildInfo { } | |||||
| internal sealed class GuildDeleteEvent : ExtendedGuildInfo { } | |||||
| //Channels | |||||
| internal sealed class ChannelCreateEvent : ChannelInfo { } | |||||
| internal sealed class ChannelDeleteEvent : ChannelInfo { } | |||||
| internal sealed class ChannelUpdateEvent : ChannelInfo { } | |||||
| //Memberships | |||||
| internal sealed class GuildMemberAddEvent : MemberInfo { } | |||||
| internal sealed class GuildMemberUpdateEvent : MemberInfo { } | |||||
| internal sealed class GuildMemberRemoveEvent : MemberInfo { } | |||||
| //Roles | |||||
| internal sealed class GuildRoleCreateEvent | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty("role")] | |||||
| public RoleInfo Data; | |||||
| } | |||||
| internal sealed class GuildRoleUpdateEvent | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty("role")] | |||||
| public RoleInfo Data; | |||||
| } | |||||
| internal sealed class GuildRoleDeleteEvent : RoleReference { } | |||||
| //Bans | |||||
| internal sealed class GuildBanAddEvent : MemberReference { } | |||||
| internal sealed class GuildBanRemoveEvent : MemberReference { } | |||||
| //User | |||||
| internal sealed class UserUpdateEvent : SelfUserInfo { } | |||||
| internal sealed class PresenceUpdateEvent : PresenceMemberInfo { } | |||||
| internal sealed class VoiceStateUpdateEvent : VoiceMemberInfo { } | |||||
| //Chat | |||||
| internal sealed class MessageCreateEvent : API.Message { } | |||||
| internal sealed class MessageUpdateEvent : API.Message { } | |||||
| internal sealed class MessageDeleteEvent : MessageReference { } | |||||
| internal sealed class MessageAckEvent : MessageReference { } | |||||
| internal sealed class TypingStartEvent | |||||
| { | |||||
| [JsonProperty("user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty("channel_id")] | |||||
| public string ChannelId; | |||||
| [JsonProperty("timestamp")] | |||||
| public int Timestamp; | |||||
| } | |||||
| //Voice | |||||
| internal sealed class VoiceServerUpdateEvent | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| public string GuildId; | |||||
| [JsonProperty("endpoint")] | |||||
| public string Endpoint; | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.WebSockets.Voice | |||||
| { | |||||
| internal sealed class LoginCommand : WebSocketMessage<LoginCommand.Data> | |||||
| { | |||||
| public LoginCommand() : base(0) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("server_id")] | |||||
| public string ServerId; | |||||
| [JsonProperty("user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty("session_id")] | |||||
| public string SessionId; | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| internal sealed class Login2Command : WebSocketMessage<Login2Command.Data> | |||||
| { | |||||
| public Login2Command() : base(1) { } | |||||
| public class Data | |||||
| { | |||||
| public class SocketInfo | |||||
| { | |||||
| [JsonProperty("address")] | |||||
| public string Address; | |||||
| [JsonProperty("port")] | |||||
| public int Port; | |||||
| [JsonProperty("mode")] | |||||
| public string Mode = "xsalsa20_poly1305"; | |||||
| } | |||||
| [JsonProperty("protocol")] | |||||
| public string Protocol = "udp"; | |||||
| [JsonProperty("data")] | |||||
| public SocketInfo SocketData = new SocketInfo(); | |||||
| } | |||||
| } | |||||
| internal sealed class KeepAliveCommand : WebSocketMessage<object> | |||||
| { | |||||
| public KeepAliveCommand() : base(3, null) { } | |||||
| } | |||||
| internal sealed class IsTalkingCommand : WebSocketMessage<IsTalkingCommand.Data> | |||||
| { | |||||
| public IsTalkingCommand() : base(5) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("delay")] | |||||
| public int Delay; | |||||
| [JsonProperty("speaking")] | |||||
| public bool IsSpeaking; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.WebSockets.Voice | |||||
| { | |||||
| internal sealed class ReadyEvent | |||||
| { | |||||
| [JsonProperty("ssrc")] | |||||
| public uint SSRC; | |||||
| [JsonProperty("port")] | |||||
| public ushort Port; | |||||
| [JsonProperty("modes")] | |||||
| public string[] Modes; | |||||
| [JsonProperty("heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| internal sealed class JoinServerEvent | |||||
| { | |||||
| [JsonProperty("secret_key")] | |||||
| public byte[] SecretKey; | |||||
| [JsonProperty("mode")] | |||||
| public string Mode; | |||||
| } | |||||
| internal sealed class IsTalkingEvent | |||||
| { | |||||
| [JsonProperty("user_id")] | |||||
| public string UserId; | |||||
| [JsonProperty("ssrc")] | |||||
| public uint SSRC; | |||||
| [JsonProperty("speaking")] | |||||
| public bool IsSpeaking; | |||||
| } | |||||
| } | |||||
| @@ -1,6 +1,6 @@ | |||||
| using System; | using System; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets.Voice | |||||
| { | { | ||||
| public sealed class IsTalkingEventArgs : EventArgs | public sealed class IsTalkingEventArgs : EventArgs | ||||
| { | { | ||||
| @@ -12,7 +12,7 @@ using System.Text; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets.Voice | |||||
| { | { | ||||
| internal partial class VoiceWebSocket : WebSocket | internal partial class VoiceWebSocket : WebSocket | ||||
| { | { | ||||
| @@ -106,7 +106,7 @@ namespace Discord.Net.WebSockets | |||||
| _udp.AllowNatTraversal(true); | _udp.AllowNatTraversal(true); | ||||
| #endif | #endif | ||||
| VoiceCommands.Login msg = new VoiceCommands.Login(); | |||||
| LoginCommand msg = new LoginCommand(); | |||||
| msg.Payload.ServerId = _serverId; | msg.Payload.ServerId = _serverId; | ||||
| msg.Payload.SessionId = _sessionId; | msg.Payload.SessionId = _sessionId; | ||||
| msg.Payload.Token = _token; | msg.Payload.Token = _token; | ||||
| @@ -294,7 +294,7 @@ namespace Discord.Net.WebSockets | |||||
| { | { | ||||
| if (_state != (int)WebSocketState.Connected) | if (_state != (int)WebSocketState.Connected) | ||||
| { | { | ||||
| var payload = (msg.Payload as JToken).ToObject<VoiceEvents.Ready>(); | |||||
| var payload = (msg.Payload as JToken).ToObject<ReadyEvent>(); | |||||
| _heartbeatInterval = payload.HeartbeatInterval; | _heartbeatInterval = payload.HeartbeatInterval; | ||||
| _ssrc = payload.SSRC; | _ssrc = payload.SSRC; | ||||
| _endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port); | _endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port); | ||||
| @@ -319,7 +319,7 @@ namespace Discord.Net.WebSockets | |||||
| break; | break; | ||||
| case 4: //SESSION_DESCRIPTION | case 4: //SESSION_DESCRIPTION | ||||
| { | { | ||||
| var payload = (msg.Payload as JToken).ToObject<VoiceEvents.JoinServer>(); | |||||
| var payload = (msg.Payload as JToken).ToObject<JoinServerEvent>(); | |||||
| _secretKey = payload.SecretKey; | _secretKey = payload.SecretKey; | ||||
| SendIsTalking(true); | SendIsTalking(true); | ||||
| _connectWaitOnLogin.Set(); | _connectWaitOnLogin.Set(); | ||||
| @@ -327,7 +327,7 @@ namespace Discord.Net.WebSockets | |||||
| break; | break; | ||||
| case 5: | case 5: | ||||
| { | { | ||||
| var payload = (msg.Payload as JToken).ToObject<VoiceEvents.IsTalking>(); | |||||
| var payload = (msg.Payload as JToken).ToObject<IsTalkingEvent>(); | |||||
| RaiseIsSpeaking(payload.UserId, payload.IsSpeaking); | RaiseIsSpeaking(payload.UserId, payload.IsSpeaking); | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -358,7 +358,7 @@ namespace Discord.Net.WebSockets | |||||
| CompleteConnect(); | CompleteConnect(); | ||||
| var login2 = new VoiceCommands.Login2(); | |||||
| var login2 = new Login2Command(); | |||||
| login2.Payload.Protocol = "udp"; | login2.Payload.Protocol = "udp"; | ||||
| login2.Payload.SocketData.Address = ip; | login2.Payload.SocketData.Address = ip; | ||||
| login2.Payload.SocketData.Mode = _isEncrypted ? EncryptedMode : UnencryptedMode; | login2.Payload.SocketData.Mode = _isEncrypted ? EncryptedMode : UnencryptedMode; | ||||
| @@ -503,7 +503,7 @@ namespace Discord.Net.WebSockets | |||||
| private void SendIsTalking(bool value) | private void SendIsTalking(bool value) | ||||
| { | { | ||||
| var isTalking = new VoiceCommands.IsTalking(); | |||||
| var isTalking = new IsTalkingCommand(); | |||||
| isTalking.Payload.IsSpeaking = value; | isTalking.Payload.IsSpeaking = value; | ||||
| isTalking.Payload.Delay = 0; | isTalking.Payload.Delay = 0; | ||||
| QueueMessage(isTalking); | QueueMessage(isTalking); | ||||
| @@ -511,7 +511,7 @@ namespace Discord.Net.WebSockets | |||||
| protected override object GetKeepAlive() | protected override object GetKeepAlive() | ||||
| { | { | ||||
| return new VoiceCommands.KeepAlive(); | |||||
| return new KeepAliveCommand(); | |||||
| } | } | ||||
| public void WaitForQueue() | public void WaitForQueue() | ||||
| @@ -8,7 +8,7 @@ using System.Threading; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using State = System.Net.WebSockets.WebSocketState; | using State = System.Net.WebSockets.WebSocketState; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets | |||||
| { | { | ||||
| internal class BuiltInWebSocketEngine : IWebSocketEngine | internal class BuiltInWebSocketEngine : IWebSocketEngine | ||||
| { | { | ||||
| @@ -1,6 +1,6 @@ | |||||
| using System; | using System; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets | |||||
| { | { | ||||
| internal partial class WebSocket | internal partial class WebSocket | ||||
| { | { | ||||
| @@ -7,7 +7,7 @@ using System.Text; | |||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets | |||||
| { | { | ||||
| public enum WebSocketState : byte | public enum WebSocketState : byte | ||||
| { | { | ||||
| @@ -88,7 +88,7 @@ namespace Discord.Net.WebSockets | |||||
| _cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSource.Token, ParentCancelToken).Token; | _cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSource.Token, ParentCancelToken).Token; | ||||
| else | else | ||||
| _cancelToken = _cancelTokenSource.Token; | _cancelToken = _cancelTokenSource.Token; | ||||
| await _engine.Connect(Host, _cancelToken).ConfigureAwait(false); | await _engine.Connect(Host, _cancelToken).ConfigureAwait(false); | ||||
| _lastHeartbeat = DateTime.UtcNow; | _lastHeartbeat = DateTime.UtcNow; | ||||
| @@ -107,8 +107,6 @@ namespace Discord.Net.WebSockets | |||||
| _connectedEvent.Set(); | _connectedEvent.Set(); | ||||
| RaiseConnected(); | RaiseConnected(); | ||||
| } | } | ||||
| /*public Task Reconnect(CancellationToken cancelToken) | |||||
| => Connect(_host, _cancelToken);*/ | |||||
| public Task Disconnect() => DisconnectInternal(new Exception("Disconnect was requested by user."), isUnexpected: false); | public Task Disconnect() => DisconnectInternal(new Exception("Disconnect was requested by user."), isUnexpected: false); | ||||
| protected async Task DisconnectInternal(Exception ex = null, bool isUnexpected = true, bool skipAwait = false) | protected async Task DisconnectInternal(Exception ex = null, bool isUnexpected = true, bool skipAwait = false) | ||||
| @@ -1,17 +1,17 @@ | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||
| namespace Discord.Net.WebSockets | |||||
| namespace Discord.WebSockets | |||||
| { | { | ||||
| public class WebSocketMessage | public class WebSocketMessage | ||||
| { | { | ||||
| [JsonProperty(PropertyName = "op")] | |||||
| [JsonProperty("op")] | |||||
| public int Operation; | public int Operation; | ||||
| [JsonProperty(PropertyName = "d")] | |||||
| [JsonProperty("d")] | |||||
| public object Payload; | public object Payload; | ||||
| [JsonProperty(PropertyName = "t", NullValueHandling = NullValueHandling.Ignore)] | |||||
| [JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public string Type; | public string Type; | ||||
| [JsonProperty(PropertyName = "s", NullValueHandling = NullValueHandling.Ignore)] | |||||
| [JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)] | |||||
| public int? Sequence; | public int? Sequence; | ||||
| } | } | ||||
| internal abstract class WebSocketMessage<T> : WebSocketMessage | internal abstract class WebSocketMessage<T> : WebSocketMessage | ||||