Refactored project structure and API calls. Exposed DiscordAPIClient as public.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Discord.Commands
|
||||
{
|
||||
//TODO: Check support for escaping
|
||||
public static class CommandParser
|
||||
{
|
||||
private enum CommandParserPart
|
||||
|
||||
@@ -35,6 +35,17 @@
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</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>
|
||||
<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>
|
||||
@@ -57,6 +68,33 @@
|
||||
<None Include="packages.config" />
|
||||
</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">
|
||||
<Link>Audio\Opus.cs</Link>
|
||||
</Compile>
|
||||
@@ -84,6 +122,9 @@
|
||||
<Compile Include="..\Discord.Net\Collections\Users.cs">
|
||||
<Link>Collections\Users.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordAPIClient.cs">
|
||||
<Link>DiscordAPIClient.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\DiscordClient.API.cs">
|
||||
<Link>DiscordClient.API.cs</Link>
|
||||
</Compile>
|
||||
@@ -150,75 +191,45 @@
|
||||
<Compile Include="..\Discord.Net\Models\User.cs">
|
||||
<Link>Models\User.cs</Link>
|
||||
</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>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\DataWebSocket.cs">
|
||||
<Link>Net\WebSockets\DataWebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\DataWebSockets.Events.cs">
|
||||
<Link>Net\WebSockets\DataWebSockets.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\Events.cs">
|
||||
<Link>Net\WebSockets\Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\VoiceCommands.cs">
|
||||
<Link>Net\WebSockets\VoiceCommands.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\VoiceEvents.cs">
|
||||
<Link>Net\WebSockets\VoiceEvents.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\VoiceWebSocket.cs">
|
||||
<Link>Net\WebSockets\VoiceWebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\VoiceWebSocket.Events.cs">
|
||||
<Link>Net\WebSockets\VoiceWebSocket.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.BuiltIn.cs">
|
||||
<Link>Net\WebSockets\WebSocket.BuiltIn.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.cs">
|
||||
<Link>Net\WebSockets\WebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocket.Events.cs">
|
||||
<Link>Net\WebSockets\WebSocket.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\Net\WebSockets\WebSocketMessage.cs">
|
||||
<Link>Net\WebSockets\WebSocketMessage.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\TimeoutException.cs">
|
||||
<Link>TimeoutException.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Data\Commands.cs">
|
||||
<Link>WebSockets\Data\Commands.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Data\DataWebSocket.cs">
|
||||
<Link>WebSockets\Data\DataWebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Data\DataWebSockets.Events.cs">
|
||||
<Link>WebSockets\Data\DataWebSockets.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Data\Events.cs">
|
||||
<Link>WebSockets\Data\Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Voice\Commands.cs">
|
||||
<Link>WebSockets\Voice\Commands.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Voice\Events.cs">
|
||||
<Link>WebSockets\Voice\Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.cs">
|
||||
<Link>WebSockets\Voice\VoiceWebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.Events.cs">
|
||||
<Link>WebSockets\Voice\VoiceWebSocket.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.BuiltIn.cs">
|
||||
<Link>WebSockets\WebSocket.BuiltIn.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.cs">
|
||||
<Link>WebSockets\WebSocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.Events.cs">
|
||||
<Link>WebSockets\WebSocket.Events.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Discord.Net\WebSockets\WebSocketMessage.cs">
|
||||
<Link>WebSockets\WebSocketMessage.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
|
||||
295
src/Discord.Net/API/Common.cs
Normal file
295
src/Discord.Net/API/Common.cs
Normal file
@@ -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
|
||||
{
|
||||
@@ -45,5 +45,6 @@
|
||||
|
||||
public const string StatusActiveMaintenance = "scheduled-maintenances/active.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.Net;
|
||||
|
||||
namespace Discord.Net.API
|
||||
namespace Discord.API
|
||||
{
|
||||
public class HttpException : Exception
|
||||
{
|
||||
142
src/Discord.Net/API/Requests.cs
Normal file
142
src/Discord.Net/API/Requests.cs
Normal file
@@ -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.Net.Http;
|
||||
|
||||
namespace Discord.Net.API
|
||||
namespace Discord.API
|
||||
{
|
||||
internal partial class RestClient
|
||||
{
|
||||
@@ -6,7 +6,7 @@ using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.API
|
||||
namespace Discord.API
|
||||
{
|
||||
internal class RestSharpRestEngine : IRestEngine
|
||||
{
|
||||
@@ -6,7 +6,7 @@ using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.API
|
||||
namespace Discord.API
|
||||
{
|
||||
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.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -17,87 +16,7 @@ namespace Discord
|
||||
|
||||
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)
|
||||
{
|
||||
CheckReady();
|
||||
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> 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();
|
||||
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);
|
||||
}
|
||||
|
||||
//Channels
|
||||
/// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary>
|
||||
public Task<Channel> CreateChannel(Server server, string name, string type)
|
||||
=> CreateChannel(server?.Id, name, type);
|
||||
/// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary>
|
||||
public async Task<Channel> CreateChannel(string serverId, string name, string type)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
|
||||
var response = await _api.CreateChannel(serverId, name, type).ConfigureAwait(false);
|
||||
var channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id);
|
||||
channel.Update(response);
|
||||
return channel;
|
||||
}
|
||||
/// <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);
|
||||
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
||||
public Task<Channel> CreatePMChannel(User user) => CreatePMChannel(user, user?.Id);
|
||||
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
||||
public Task<Channel> CreatePMChannel(Member member) => CreatePMChannel(member.User, member.UserId);
|
||||
private async Task<Channel> CreatePMChannel(User user, string userId)
|
||||
{
|
||||
CheckReady();
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
Channel channel = null;
|
||||
if (user != null)
|
||||
channel = user.PrivateChannel;
|
||||
if (channel == null)
|
||||
{
|
||||
var response = await _api.CreatePMChannel(_currentUserId, userId).ConfigureAwait(false);
|
||||
channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id);
|
||||
channel.Update(response);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
/// <summary> Destroys the provided channel. </summary>
|
||||
public Task<Channel> DestroyChannel(Channel channel)
|
||||
=> DestroyChannel(channel?.Id);
|
||||
/// <summary> Destroys the provided channel. </summary>
|
||||
public async Task<Channel> DestroyChannel(string channelId)
|
||||
{
|
||||
CheckReady();
|
||||
if (channelId == null) throw new ArgumentNullException(nameof(channelId));
|
||||
|
||||
try { await _api.DestroyChannel(channelId).ConfigureAwait(false); }
|
||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
|
||||
return _channels.TryRemove(channelId);
|
||||
}
|
||||
public const int MaxMessageSize = 2000;
|
||||
|
||||
//Bans
|
||||
/// <summary> Bans a user from the provided server. </summary>
|
||||
@@ -144,6 +63,74 @@ namespace Discord
|
||||
try { await _api.Unban(serverId, userId).ConfigureAwait(false); }
|
||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
|
||||
}
|
||||
|
||||
//Channels
|
||||
/// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary>
|
||||
public Task<Channel> CreateChannel(Server server, string name, string type)
|
||||
=> CreateChannel(server?.Id, name, type);
|
||||
/// <summary> Creates a new channel with the provided name and type (see ChannelTypes). </summary>
|
||||
public async Task<Channel> CreateChannel(string serverId, string name, string type)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
|
||||
var response = await _api.CreateChannel(serverId, name, type).ConfigureAwait(false);
|
||||
var channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id);
|
||||
channel.Update(response);
|
||||
return channel;
|
||||
}
|
||||
|
||||
/// <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);
|
||||
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
||||
public Task<Channel> CreatePMChannel(User user) => CreatePMChannel(user, user?.Id);
|
||||
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
||||
public Task<Channel> CreatePMChannel(Member member) => CreatePMChannel(member.User, member.UserId);
|
||||
private async Task<Channel> CreatePMChannel(User user, string userId)
|
||||
{
|
||||
CheckReady();
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
Channel channel = null;
|
||||
if (user != null)
|
||||
channel = user.PrivateChannel;
|
||||
if (channel == null)
|
||||
{
|
||||
var response = await _api.CreatePMChannel(_currentUserId, userId).ConfigureAwait(false);
|
||||
channel = _channels.GetOrAdd(response.Id, response.GuildId, response.Recipient?.Id);
|
||||
channel.Update(response);
|
||||
}
|
||||
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>
|
||||
public Task<Channel> DestroyChannel(Channel channel)
|
||||
=> DestroyChannel(channel?.Id);
|
||||
/// <summary> Destroys the provided channel. </summary>
|
||||
public async Task<Channel> DestroyChannel(string channelId)
|
||||
{
|
||||
CheckReady();
|
||||
if (channelId == null) throw new ArgumentNullException(nameof(channelId));
|
||||
|
||||
try { await _api.DestroyChannel(channelId).ConfigureAwait(false); }
|
||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
|
||||
return _channels.TryRemove(channelId);
|
||||
}
|
||||
|
||||
//Invites
|
||||
/// <summary> Creates a new invite to the default channel of the provided server. </summary>
|
||||
@@ -178,14 +165,29 @@ namespace Discord
|
||||
return invite;
|
||||
}
|
||||
|
||||
/// <summary> Gets more info about the provided invite code. </summary>
|
||||
/// <remarks> Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode </remarks>
|
||||
public async Task<Invite> GetInvite(string id)
|
||||
/// <summary> Deletes the provided invite. </summary>
|
||||
public async Task DestroyInvite(string inviteId)
|
||||
{
|
||||
CheckReady();
|
||||
if (id == null) throw new ArgumentNullException(nameof(id));
|
||||
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>
|
||||
/// <remarks> Supported formats: inviteCode, xkcdCode, https://discord.gg/inviteCode, https://discord.gg/xkcdCode </remarks>
|
||||
public async Task<Invite> GetInvite(string inviteIdOrXkcd)
|
||||
{
|
||||
CheckReady();
|
||||
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);
|
||||
invite.Update(response);
|
||||
return invite;
|
||||
@@ -200,39 +202,42 @@ namespace Discord
|
||||
return _api.AcceptInvite(invite.Id);
|
||||
}
|
||||
/// <summary> Accepts the provided invite. </summary>
|
||||
public async Task AcceptInvite(string code)
|
||||
public async Task AcceptInvite(string inviteId)
|
||||
{
|
||||
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
|
||||
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)
|
||||
code = code.Substring(index + 1);
|
||||
inviteId = inviteId.Substring(index + 1);
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
/// <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();
|
||||
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>
|
||||
public Task<Message[]> SendMessage(Channel channel, string text)
|
||||
=> SendMessage(channel?.Id, text, new string[0]);
|
||||
@@ -252,18 +257,18 @@ namespace Discord
|
||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||
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];
|
||||
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));
|
||||
var nonce = GenerateNonce();
|
||||
if (_config.UseMessageQueue)
|
||||
{
|
||||
var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _currentUserId);
|
||||
var currentMember = _members[msg.UserId, channel.ServerId];
|
||||
msg.Update(new Net.API.Message
|
||||
msg.Update(new API.Message
|
||||
{
|
||||
Content = blockText,
|
||||
Timestamp = DateTime.UtcNow,
|
||||
@@ -302,35 +307,37 @@ namespace Discord
|
||||
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>
|
||||
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);
|
||||
/// <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>
|
||||
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);
|
||||
/// <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>
|
||||
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();
|
||||
if (channelId == null) throw new ArgumentNullException(nameof(channelId));
|
||||
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 msg = _messages[messageId];
|
||||
@@ -383,19 +390,6 @@ namespace Discord
|
||||
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>
|
||||
public Task<Message[]> DownloadMessages(Channel channel, int count, string beforeMessageId = null, bool cache = true)
|
||||
@@ -449,113 +443,6 @@ namespace Discord
|
||||
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
|
||||
public Task SetChannelUserPermissions(Channel channel, Member member, PackedPermissions allow, PackedPermissions deny)
|
||||
=> SetChannelPermissions(channel?.Id, member?.UserId, "member", allow, deny);
|
||||
@@ -585,7 +472,7 @@ namespace Discord
|
||||
if (channelId == null) throw new NullReferenceException(nameof(channelId));
|
||||
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
|
||||
}
|
||||
|
||||
@@ -625,128 +512,90 @@ namespace Discord
|
||||
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)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
return _api.Mute(serverId, userId);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
return _api.Unmute(serverId, userId);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
return _api.Deafen(serverId, userId);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||
|
||||
return _api.Undeafen(serverId, userId);
|
||||
}
|
||||
|
||||
//Profile
|
||||
/// <summary> Changes your username to newName. </summary>
|
||||
public async Task ChangeUsername(string newName, string currentEmail, string currentPassword)
|
||||
public Task<EditProfileResponse> EditProfile(string currentPassword,
|
||||
string username = null, string email = null, string password = null,
|
||||
AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CheckReady();
|
||||
var response = await _api.ChangeEmail(newEmail, currentPassword).ConfigureAwait(false);
|
||||
_currentUser.Update(response);
|
||||
}
|
||||
/// <summary> Changes your password to newPassword. </summary>
|
||||
public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword)
|
||||
{
|
||||
CheckReady();
|
||||
await _api.ChangePassword(newPassword, currentEmail, currentPassword).ConfigureAwait(false);
|
||||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword));
|
||||
|
||||
return _api.EditProfile(currentPassword, username: username, email: email, password: password,
|
||||
avatarType: avatarType, avatar: avatar);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
//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();
|
||||
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 NullReferenceException(nameof(serverId));
|
||||
|
||||
return _api.CreateRole(serverId);
|
||||
}
|
||||
|
||||
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();
|
||||
if (serverId == null) throw new NullReferenceException(nameof(serverId));
|
||||
if (roleId == null) throw new NullReferenceException(nameof(roleId));
|
||||
|
||||
return _api.EditRole(serverId, roleId, name: name, permissions: permissions?.RawValue);
|
||||
}
|
||||
|
||||
public Task DeleteRole(Role role)
|
||||
=> DeleteRole(role?.ServerId, role?.Id);
|
||||
public Task DeleteRole(string serverId, string roleId)
|
||||
{
|
||||
CheckReady();
|
||||
if (serverId == null) throw new NullReferenceException(nameof(serverId));
|
||||
if (roleId == null) throw new NullReferenceException(nameof(roleId));
|
||||
|
||||
return _api.DeleteRole(serverId, roleId);
|
||||
}
|
||||
|
||||
//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();
|
||||
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> 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();
|
||||
if (serverId == null) throw new ArgumentNullException(nameof(serverId));
|
||||
|
||||
return _api.EditServer(serverId, name: name, region: region);
|
||||
}
|
||||
|
||||
/// <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();
|
||||
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.WebSockets;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace Discord
|
||||
{
|
||||
CheckReady(checkVoice: true);
|
||||
|
||||
if (_voiceSocket.State != Net.WebSockets.WebSocketState.Disconnected)
|
||||
if (_voiceSocket.State != WebSocketState.Disconnected)
|
||||
{
|
||||
var serverId = _voiceSocket.CurrentVoiceServerId;
|
||||
if (serverId != null)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Discord.Collections;
|
||||
using Discord.API;
|
||||
using Discord.Collections;
|
||||
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 System;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -10,6 +10,7 @@ using System.Net;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
@@ -279,7 +280,7 @@ namespace Discord
|
||||
//Global
|
||||
case "READY": //Resync
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.Ready>(_serializer);
|
||||
var data = e.Payload.ToObject<ReadyEvent>(_serializer);
|
||||
_currentUserId = data.User.Id;
|
||||
_currentUser = _users.GetOrAdd(data.User.Id);
|
||||
_currentUser.Update(data.User);
|
||||
@@ -303,7 +304,7 @@ namespace Discord
|
||||
//Servers
|
||||
case "GUILD_CREATE":
|
||||
{
|
||||
var model = e.Payload.ToObject<Events.GuildCreate>(_serializer);
|
||||
var model = e.Payload.ToObject<GuildCreateEvent>(_serializer);
|
||||
var server = _servers.GetOrAdd(model.Id);
|
||||
server.Update(model);
|
||||
RaiseServerCreated(server);
|
||||
@@ -311,7 +312,7 @@ namespace Discord
|
||||
break;
|
||||
case "GUILD_UPDATE":
|
||||
{
|
||||
var model = e.Payload.ToObject<Events.GuildUpdate>(_serializer);
|
||||
var model = e.Payload.ToObject<GuildUpdateEvent>(_serializer);
|
||||
var server = _servers[model.Id];
|
||||
if (server != null)
|
||||
{
|
||||
@@ -322,7 +323,7 @@ namespace Discord
|
||||
break;
|
||||
case "GUILD_DELETE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.GuildDelete>(_serializer);
|
||||
var data = e.Payload.ToObject<GuildDeleteEvent>(_serializer);
|
||||
var server = _servers.TryRemove(data.Id);
|
||||
if (server != null)
|
||||
RaiseServerDestroyed(server);
|
||||
@@ -332,7 +333,7 @@ namespace Discord
|
||||
//Channels
|
||||
case "CHANNEL_CREATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.ChannelCreate>(_serializer);
|
||||
var data = e.Payload.ToObject<ChannelCreateEvent>(_serializer);
|
||||
Channel channel;
|
||||
if (data.IsPrivate)
|
||||
{
|
||||
@@ -348,7 +349,7 @@ namespace Discord
|
||||
break;
|
||||
case "CHANNEL_UPDATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.ChannelUpdate>(_serializer);
|
||||
var data = e.Payload.ToObject<ChannelUpdateEvent>(_serializer);
|
||||
var channel = _channels[data.Id];
|
||||
if (channel != null)
|
||||
{
|
||||
@@ -359,7 +360,7 @@ namespace Discord
|
||||
break;
|
||||
case "CHANNEL_DELETE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.ChannelDelete>(_serializer);
|
||||
var data = e.Payload.ToObject<ChannelDeleteEvent>(_serializer);
|
||||
var channel = _channels.TryRemove(data.Id);
|
||||
if (channel != null)
|
||||
RaiseChannelDestroyed(channel);
|
||||
@@ -369,7 +370,7 @@ namespace Discord
|
||||
//Members
|
||||
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 member = _members.GetOrAdd(data.User.Id, data.GuildId);
|
||||
user.Update(data.User);
|
||||
@@ -381,7 +382,7 @@ namespace Discord
|
||||
break;
|
||||
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];
|
||||
if (member != null)
|
||||
{
|
||||
@@ -392,7 +393,7 @@ namespace Discord
|
||||
break;
|
||||
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);
|
||||
if (member != null)
|
||||
RaiseUserRemoved(member);
|
||||
@@ -402,7 +403,7 @@ namespace Discord
|
||||
//Roles
|
||||
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);
|
||||
role.Update(data.Data);
|
||||
RaiseRoleUpdated(role);
|
||||
@@ -410,7 +411,7 @@ namespace Discord
|
||||
break;
|
||||
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];
|
||||
if (role != null)
|
||||
role.Update(data.Data);
|
||||
@@ -419,7 +420,7 @@ namespace Discord
|
||||
break;
|
||||
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);
|
||||
if (role != null)
|
||||
RaiseRoleDeleted(role);
|
||||
@@ -429,7 +430,7 @@ namespace Discord
|
||||
//Bans
|
||||
case "GUILD_BAN_ADD":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.GuildBanAdd>(_serializer);
|
||||
var data = e.Payload.ToObject<GuildBanAddEvent>(_serializer);
|
||||
var server = _servers[data.GuildId];
|
||||
if (server != null)
|
||||
{
|
||||
@@ -440,7 +441,7 @@ namespace Discord
|
||||
break;
|
||||
case "GUILD_BAN_REMOVE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.GuildBanRemove>(_serializer);
|
||||
var data = e.Payload.ToObject<GuildBanRemoveEvent>(_serializer);
|
||||
var server = _servers[data.GuildId];
|
||||
if (server != null && server.RemoveBan(data.UserId))
|
||||
RaiseBanRemoved(data.UserId, server);
|
||||
@@ -450,7 +451,7 @@ namespace Discord
|
||||
//Messages
|
||||
case "MESSAGE_CREATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.MessageCreate>(_serializer);
|
||||
var data = e.Payload.ToObject<MessageCreateEvent>(_serializer);
|
||||
Message msg = null;
|
||||
|
||||
bool wasLocal = _config.UseMessageQueue && data.Author.Id == _currentUserId && data.Nonce != null;
|
||||
@@ -490,7 +491,7 @@ namespace Discord
|
||||
break;
|
||||
case "MESSAGE_UPDATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.MessageUpdate>(_serializer);
|
||||
var data = e.Payload.ToObject<MessageUpdateEvent>(_serializer);
|
||||
var msg = _messages[data.Id];
|
||||
if (msg != null)
|
||||
{
|
||||
@@ -501,7 +502,7 @@ namespace Discord
|
||||
break;
|
||||
case "MESSAGE_DELETE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.MessageDelete>(_serializer);
|
||||
var data = e.Payload.ToObject<MessageDeleteEvent>(_serializer);
|
||||
var msg = _messages.TryRemove(data.Id);
|
||||
if (msg != null)
|
||||
RaiseMessageDeleted(msg);
|
||||
@@ -509,7 +510,7 @@ namespace Discord
|
||||
break;
|
||||
case "MESSAGE_ACK":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.MessageAck>(_serializer);
|
||||
var data = e.Payload.ToObject<MessageAckEvent>(_serializer);
|
||||
var msg = GetMessage(data.MessageId);
|
||||
if (msg != null)
|
||||
RaiseMessageReadRemotely(msg);
|
||||
@@ -519,7 +520,7 @@ namespace Discord
|
||||
//Statuses
|
||||
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];
|
||||
/*if (_config.TrackActivity)
|
||||
{
|
||||
@@ -536,7 +537,7 @@ namespace Discord
|
||||
break;
|
||||
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];
|
||||
/*if (_config.TrackActivity)
|
||||
{
|
||||
@@ -558,7 +559,7 @@ namespace Discord
|
||||
break;
|
||||
case "TYPING_START":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.TypingStart>(_serializer);
|
||||
var data = e.Payload.ToObject<TypingStartEvent>(_serializer);
|
||||
var channel = _channels[data.ChannelId];
|
||||
var user = _users[data.UserId];
|
||||
|
||||
@@ -587,7 +588,7 @@ namespace Discord
|
||||
//Voice
|
||||
case "VOICE_SERVER_UPDATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.VoiceServerUpdate>(_serializer);
|
||||
var data = e.Payload.ToObject<VoiceServerUpdateEvent>(_serializer);
|
||||
if (data.GuildId == _voiceSocket.CurrentVoiceServerId)
|
||||
{
|
||||
var server = _servers[data.GuildId];
|
||||
@@ -603,7 +604,7 @@ namespace Discord
|
||||
//Settings
|
||||
case "USER_UPDATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<Events.UserUpdate>(_serializer);
|
||||
var data = e.Payload.ToObject<UserUpdateEvent>(_serializer);
|
||||
var user = _users[data.Id];
|
||||
if (user != null)
|
||||
{
|
||||
@@ -670,8 +671,8 @@ namespace Discord
|
||||
_token = token;
|
||||
_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}");
|
||||
|
||||
_dataSocket.Host = url;
|
||||
@@ -838,7 +839,7 @@ namespace Discord
|
||||
while (_pendingMessages.TryDequeue(out msg))
|
||||
{
|
||||
bool hasFailed = false;
|
||||
Responses.SendMessage response = null;
|
||||
SendMessageResponse response = null;
|
||||
try
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -11,7 +10,7 @@ namespace Discord
|
||||
static Format()
|
||||
{
|
||||
_patterns = new string[] { "__", "_", "**", "*", "~~" };
|
||||
_builder = new StringBuilder(DiscordAPIClient.MaxMessageSize);
|
||||
_builder = new StringBuilder(DiscordClient.MaxMessageSize);
|
||||
}
|
||||
|
||||
/// <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
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Net.API;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -64,14 +63,14 @@ namespace Discord
|
||||
_messages = new ConcurrentDictionary<string, bool>();
|
||||
}
|
||||
|
||||
internal void Update(ChannelReference model)
|
||||
internal void Update(API.ChannelReference model)
|
||||
{
|
||||
Name = model.Name;
|
||||
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;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Net.API;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
@@ -24,7 +23,7 @@ namespace Discord
|
||||
public string XkcdPass { get; }
|
||||
|
||||
/// <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>
|
||||
public string InviterId { get; internal set; }
|
||||
@@ -54,16 +53,16 @@ namespace Discord
|
||||
|
||||
public override string ToString() => XkcdPass ?? Id;
|
||||
|
||||
internal void Update(Net.API.Invite model)
|
||||
internal void Update(API.Invite model)
|
||||
{
|
||||
ChannelId = model.Channel.Id;
|
||||
InviterId = model.Inviter?.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;
|
||||
IsTemporary = model.IsTemporary;
|
||||
MaxAge = model.MaxAge;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Net.API;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -17,7 +16,7 @@ namespace Discord
|
||||
/// <summary> Returns the unique identifier for this user's current avatar. </summary>
|
||||
public string AvatarId { get; internal set; }
|
||||
/// <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>
|
||||
public DateTime JoinedAt { get; internal set; }
|
||||
|
||||
@@ -70,7 +69,7 @@ namespace Discord
|
||||
|
||||
public override string ToString() => UserId;
|
||||
|
||||
internal void Update(UserReference model)
|
||||
internal void Update(API.UserReference model)
|
||||
{
|
||||
if (model.Avatar != null)
|
||||
AvatarId = model.Avatar;
|
||||
@@ -79,7 +78,7 @@ namespace Discord
|
||||
if (model.Username != null)
|
||||
Name = model.Username;
|
||||
}
|
||||
internal void Update(MemberInfo model)
|
||||
internal void Update(API.MemberInfo model)
|
||||
{
|
||||
if (model.User != null)
|
||||
Update(model.User);
|
||||
@@ -87,13 +86,13 @@ namespace Discord
|
||||
if (model.JoinedAt.HasValue)
|
||||
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;
|
||||
IsMuted = model.IsMuted;
|
||||
}
|
||||
internal void Update(PresenceMemberInfo model)
|
||||
internal void Update(API.PresenceMemberInfo model)
|
||||
{
|
||||
if (Status != model.Status)
|
||||
{
|
||||
@@ -103,7 +102,7 @@ namespace Discord
|
||||
}
|
||||
GameId = model.GameId;
|
||||
}
|
||||
internal void Update(VoiceMemberInfo model)
|
||||
internal void Update(API.VoiceMemberInfo model)
|
||||
{
|
||||
IsDeafened = model.IsDeafened;
|
||||
IsMuted = model.IsMuted;
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Discord
|
||||
UserId = userId;
|
||||
}
|
||||
|
||||
internal void Update(Net.API.Message model)
|
||||
internal void Update(API.Message model)
|
||||
{
|
||||
if (model.Attachments != null)
|
||||
{
|
||||
|
||||
@@ -71,8 +71,7 @@ namespace Discord
|
||||
else
|
||||
_rawValue &= ~(1U << (pos - 1));
|
||||
}
|
||||
|
||||
public static implicit operator uint (PackedPermissions perms) => perms._rawValue;
|
||||
|
||||
public PackedPermissions Copy() => new PackedPermissions(false, _rawValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Threading;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
@@ -29,7 +28,7 @@ namespace Discord
|
||||
Permissions = new PackedPermissions(true);
|
||||
}
|
||||
|
||||
internal void Update(Net.API.RoleInfo model)
|
||||
internal void Update(API.RoleInfo model)
|
||||
{
|
||||
Name = model.Name;
|
||||
Permissions.RawValue = (uint)model.Permissions;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Net.API;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -100,7 +99,7 @@ namespace Discord
|
||||
_roles = new ConcurrentDictionary<string, bool>();
|
||||
}
|
||||
|
||||
internal void Update(GuildInfo model)
|
||||
internal void Update(API.GuildInfo model)
|
||||
{
|
||||
AFKChannelId = model.AFKChannelId;
|
||||
AFKTimeout = model.AFKTimeout;
|
||||
@@ -117,9 +116,9 @@ namespace Discord
|
||||
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;
|
||||
foreach (var subModel in model.Channels)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Discord.Net.API;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@@ -24,7 +23,7 @@ namespace Discord
|
||||
/// <summary> Returns the unique identifier for this user's current avatar. </summary>
|
||||
public string AvatarId { get; internal set; }
|
||||
/// <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>
|
||||
/// <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>();
|
||||
}
|
||||
|
||||
internal void Update(UserReference model)
|
||||
internal void Update(API.UserReference model)
|
||||
{
|
||||
if (model.Avatar != null)
|
||||
AvatarId = model.Avatar;
|
||||
@@ -87,9 +86,9 @@ namespace Discord
|
||||
if (model.Username != null)
|
||||
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;
|
||||
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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord
|
||||
{
|
||||
|
||||
67
src/Discord.Net/WebSockets/Data/Commands.cs
Normal file
67
src/Discord.Net/WebSockets/Data/Commands.cs
Normal file
@@ -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.Linq;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets.Data
|
||||
{
|
||||
internal partial class DataWebSocket : WebSocket
|
||||
{
|
||||
@@ -22,7 +21,7 @@ namespace Discord.Net.WebSockets
|
||||
{
|
||||
await Connect().ConfigureAwait(false);
|
||||
|
||||
Commands.Login msg = new Commands.Login();
|
||||
LoginCommand msg = new LoginCommand();
|
||||
msg.Payload.Token = token;
|
||||
msg.Payload.Properties["$device"] = "Discord.Net";
|
||||
QueueMessage(msg);
|
||||
@@ -32,7 +31,7 @@ namespace Discord.Net.WebSockets
|
||||
await DisconnectInternal(isUnexpected: false).ConfigureAwait(false);
|
||||
await Connect().ConfigureAwait(false);
|
||||
|
||||
var resumeMsg = new Commands.Resume();
|
||||
var resumeMsg = new ResumeCommand();
|
||||
resumeMsg.Payload.SessionId = _sessionId;
|
||||
resumeMsg.Payload.Sequence = _lastSeq;
|
||||
QueueMessage(resumeMsg);
|
||||
@@ -75,16 +74,16 @@ namespace Discord.Net.WebSockets
|
||||
JToken token = msg.Payload as JToken;
|
||||
if (msg.Type == "READY")
|
||||
{
|
||||
var payload = token.ToObject<Events.Ready>();
|
||||
var payload = token.ToObject<ReadyEvent>();
|
||||
_sessionId = payload.SessionId;
|
||||
_heartbeatInterval = payload.HeartbeatInterval;
|
||||
QueueMessage(new Commands.UpdateStatus());
|
||||
QueueMessage(new UpdateStatusCommand());
|
||||
}
|
||||
else if (msg.Type == "RESUMED")
|
||||
{
|
||||
var payload = token.ToObject<Events.Resumed>();
|
||||
var payload = token.ToObject<ResumedEvent>();
|
||||
_heartbeatInterval = payload.HeartbeatInterval;
|
||||
QueueMessage(new Commands.UpdateStatus());
|
||||
QueueMessage(new UpdateStatusCommand());
|
||||
}
|
||||
RaiseReceivedEvent(msg.Type, token);
|
||||
if (msg.Type == "READY" || msg.Type == "RESUMED")
|
||||
@@ -93,7 +92,7 @@ namespace Discord.Net.WebSockets
|
||||
break;
|
||||
case 7: //Redirect
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<Events.Redirect>();
|
||||
var payload = (msg.Payload as JToken).ToObject<RedirectEvent>();
|
||||
Host = payload.Url;
|
||||
if (_logLevel >= LogMessageSeverity.Info)
|
||||
RaiseOnLog(LogMessageSeverity.Info, "Redirected to " + payload.Url);
|
||||
@@ -109,19 +108,19 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
protected override object GetKeepAlive()
|
||||
{
|
||||
return new Commands.KeepAlive();
|
||||
return new KeepAliveCommand();
|
||||
}
|
||||
|
||||
public void SendJoinVoice(string serverId, string channelId)
|
||||
{
|
||||
var joinVoice = new Commands.JoinVoice();
|
||||
var joinVoice = new JoinVoiceCommand();
|
||||
joinVoice.Payload.ServerId = serverId;
|
||||
joinVoice.Payload.ChannelId = channelId;
|
||||
QueueMessage(joinVoice);
|
||||
}
|
||||
public void SendLeaveVoice(string serverId)
|
||||
{
|
||||
var leaveVoice = new Commands.JoinVoice();
|
||||
var leaveVoice = new JoinVoiceCommand();
|
||||
leaveVoice.Payload.ServerId = serverId;
|
||||
QueueMessage(leaveVoice);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
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 JToken Payload;
|
||||
115
src/Discord.Net/WebSockets/Data/Events.cs
Normal file
115
src/Discord.Net/WebSockets/Data/Events.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
59
src/Discord.Net/WebSockets/Voice/Commands.cs
Normal file
59
src/Discord.Net/WebSockets/Voice/Commands.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
src/Discord.Net/WebSockets/Voice/Events.cs
Normal file
38
src/Discord.Net/WebSockets/Voice/Events.cs
Normal file
@@ -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;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets.Voice
|
||||
{
|
||||
public sealed class IsTalkingEventArgs : EventArgs
|
||||
{
|
||||
@@ -12,7 +12,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets.Voice
|
||||
{
|
||||
internal partial class VoiceWebSocket : WebSocket
|
||||
{
|
||||
@@ -106,7 +106,7 @@ namespace Discord.Net.WebSockets
|
||||
_udp.AllowNatTraversal(true);
|
||||
#endif
|
||||
|
||||
VoiceCommands.Login msg = new VoiceCommands.Login();
|
||||
LoginCommand msg = new LoginCommand();
|
||||
msg.Payload.ServerId = _serverId;
|
||||
msg.Payload.SessionId = _sessionId;
|
||||
msg.Payload.Token = _token;
|
||||
@@ -294,7 +294,7 @@ namespace Discord.Net.WebSockets
|
||||
{
|
||||
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;
|
||||
_ssrc = payload.SSRC;
|
||||
_endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port);
|
||||
@@ -319,7 +319,7 @@ namespace Discord.Net.WebSockets
|
||||
break;
|
||||
case 4: //SESSION_DESCRIPTION
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<VoiceEvents.JoinServer>();
|
||||
var payload = (msg.Payload as JToken).ToObject<JoinServerEvent>();
|
||||
_secretKey = payload.SecretKey;
|
||||
SendIsTalking(true);
|
||||
_connectWaitOnLogin.Set();
|
||||
@@ -327,7 +327,7 @@ namespace Discord.Net.WebSockets
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<VoiceEvents.IsTalking>();
|
||||
var payload = (msg.Payload as JToken).ToObject<IsTalkingEvent>();
|
||||
RaiseIsSpeaking(payload.UserId, payload.IsSpeaking);
|
||||
}
|
||||
break;
|
||||
@@ -358,7 +358,7 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
CompleteConnect();
|
||||
|
||||
var login2 = new VoiceCommands.Login2();
|
||||
var login2 = new Login2Command();
|
||||
login2.Payload.Protocol = "udp";
|
||||
login2.Payload.SocketData.Address = ip;
|
||||
login2.Payload.SocketData.Mode = _isEncrypted ? EncryptedMode : UnencryptedMode;
|
||||
@@ -503,7 +503,7 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
private void SendIsTalking(bool value)
|
||||
{
|
||||
var isTalking = new VoiceCommands.IsTalking();
|
||||
var isTalking = new IsTalkingCommand();
|
||||
isTalking.Payload.IsSpeaking = value;
|
||||
isTalking.Payload.Delay = 0;
|
||||
QueueMessage(isTalking);
|
||||
@@ -511,7 +511,7 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
protected override object GetKeepAlive()
|
||||
{
|
||||
return new VoiceCommands.KeepAlive();
|
||||
return new KeepAliveCommand();
|
||||
}
|
||||
|
||||
public void WaitForQueue()
|
||||
@@ -8,7 +8,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using State = System.Net.WebSockets.WebSocketState;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets
|
||||
{
|
||||
internal class BuiltInWebSocketEngine : IWebSocketEngine
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets
|
||||
{
|
||||
internal partial class WebSocket
|
||||
{
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets
|
||||
{
|
||||
public enum WebSocketState : byte
|
||||
{
|
||||
@@ -88,7 +88,7 @@ namespace Discord.Net.WebSockets
|
||||
_cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSource.Token, ParentCancelToken).Token;
|
||||
else
|
||||
_cancelToken = _cancelTokenSource.Token;
|
||||
|
||||
|
||||
await _engine.Connect(Host, _cancelToken).ConfigureAwait(false);
|
||||
_lastHeartbeat = DateTime.UtcNow;
|
||||
|
||||
@@ -107,8 +107,6 @@ namespace Discord.Net.WebSockets
|
||||
_connectedEvent.Set();
|
||||
RaiseConnected();
|
||||
}
|
||||
/*public Task Reconnect(CancellationToken cancelToken)
|
||||
=> Connect(_host, _cancelToken);*/
|
||||
|
||||
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)
|
||||
@@ -1,17 +1,17 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
namespace Discord.WebSockets
|
||||
{
|
||||
public class WebSocketMessage
|
||||
{
|
||||
[JsonProperty(PropertyName = "op")]
|
||||
[JsonProperty("op")]
|
||||
public int Operation;
|
||||
[JsonProperty(PropertyName = "d")]
|
||||
[JsonProperty("d")]
|
||||
public object Payload;
|
||||
[JsonProperty(PropertyName = "t", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Type;
|
||||
[JsonProperty(PropertyName = "s", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? Sequence;
|
||||
}
|
||||
internal abstract class WebSocketMessage<T> : WebSocketMessage
|
||||
Reference in New Issue
Block a user