@@ -13,6 +13,6 @@ using System.Runtime.InteropServices; | |||
[assembly: ComVisible(false)] | |||
[assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")] | |||
[assembly: AssemblyVersion("0.7.3.0")] | |||
[assembly: AssemblyFileVersion("0.7.3.0")] | |||
[assembly: AssemblyVersion("0.8.0.0")] | |||
[assembly: AssemblyFileVersion("0.8.0.0")] | |||
@@ -67,49 +67,50 @@ | |||
</Reference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Content Include="lib\libopus.so" /> | |||
<Content Include="lib\libsodium.dll" /> | |||
<Content Include="lib\opus.dll" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="..\Discord.Net\API\Common.cs"> | |||
<Link>API\Common.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Auth.cs"> | |||
<Link>API\Auth.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\Bans.cs"> | |||
<Link>API\Bans.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\Channels.cs"> | |||
<Link>API\Channels.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 Include="..\Discord.Net\API\Invites.cs"> | |||
<Link>API\Invites.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\Requests.cs"> | |||
<Link>API\Requests.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Maintenance.cs"> | |||
<Link>API\Maintenance.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\Responses.cs"> | |||
<Link>API\Responses.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Members.cs"> | |||
<Link>API\Members.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\RestClient.BuiltIn.cs"> | |||
<Link>API\RestClient.BuiltIn.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Messages.cs"> | |||
<Link>API\Messages.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\RestClient.cs"> | |||
<Link>API\RestClient.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Permissions.cs"> | |||
<Link>API\Permissions.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\RestClient.Events.cs"> | |||
<Link>API\RestClient.Events.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Presence.cs"> | |||
<Link>API\Presence.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\API\RestClient.SharpRest.cs"> | |||
<Link>API\RestClient.SharpRest.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Roles.cs"> | |||
<Link>API\Roles.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Audio\Opus.cs"> | |||
<Link>Audio\Opus.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Servers.cs"> | |||
<Link>API\Servers.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Audio\OpusDecoder.cs"> | |||
<Link>Audio\OpusDecoder.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Users.cs"> | |||
<Link>API\Users.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Audio\OpusEncoder.cs"> | |||
<Link>Audio\OpusEncoder.cs</Link> | |||
<Compile Include="..\Discord.Net\API\Voice.cs"> | |||
<Link>API\Voice.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Audio\Sodium.cs"> | |||
<Link>Audio\Sodium.cs</Link> | |||
<Compile Include="..\Discord.Net\API\WebSockets.cs"> | |||
<Link>API\WebSockets.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Collections\AsyncCollection.cs"> | |||
<Link>Collections\AsyncCollection.cs</Link> | |||
@@ -132,9 +133,6 @@ | |||
<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> | |||
@@ -174,26 +172,41 @@ | |||
<Compile Include="..\Discord.Net\Enums\UserStatus.cs"> | |||
<Link>Enums\UserStatus.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Format.cs"> | |||
<Link>Format.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\CollectionHelper.cs"> | |||
<Link>Helpers\CollectionHelper.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\EpochTime.cs"> | |||
<Link>Helpers\EpochTime.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\Extensions.cs"> | |||
<Link>Helpers\Extensions.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\Format.cs"> | |||
<Link>Helpers\Format.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\Mention.cs"> | |||
<Link>Helpers\Mention.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\MessageCleaner.cs"> | |||
<Link>Helpers\MessageCleaner.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\TaskExtensions.cs"> | |||
<Link>Helpers\TaskExtensions.cs</Link> | |||
<Compile Include="..\Discord.Net\Helpers\Shared\CollectionHelper.cs"> | |||
<Link>Helpers\Shared\CollectionHelper.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Helpers\Shared\TaskHelper.cs"> | |||
<Link>Helpers\Shared\TaskHelper.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Mention.cs"> | |||
<Link>Mention.cs</Link> | |||
<Compile Include="..\Discord.Net\Helpers\TimeoutException.cs"> | |||
<Link>Helpers\TimeoutException.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Interop\Opus.cs"> | |||
<Link>Interop\Opus.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Interop\OpusDecoder.cs"> | |||
<Link>Interop\OpusDecoder.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Interop\OpusEncoder.cs"> | |||
<Link>Interop\OpusEncoder.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Interop\Sodium.cs"> | |||
<Link>Interop\Sodium.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Models\Channel.cs"> | |||
<Link>Models\Channel.cs</Link> | |||
@@ -222,59 +235,61 @@ | |||
<Compile Include="..\Discord.Net\Models\User.cs"> | |||
<Link>Models\User.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\Shared\TaskHelper.cs"> | |||
<Link>Shared\TaskHelper.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\TimeoutException.cs"> | |||
<Link>TimeoutException.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\DataWebSocket.cs"> | |||
<Link>Net\DataWebSocket.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Data\Commands.cs"> | |||
<Link>WebSockets\Data\Commands.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\DataWebSockets.Events.cs"> | |||
<Link>Net\DataWebSockets.Events.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Data\DataWebSocket.cs"> | |||
<Link>WebSockets\Data\DataWebSocket.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\DiscordAPIClient.cs"> | |||
<Link>Net\DiscordAPIClient.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Data\DataWebSockets.Events.cs"> | |||
<Link>WebSockets\Data\DataWebSockets.Events.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\HttpException.cs"> | |||
<Link>Net\HttpException.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Data\Events.cs"> | |||
<Link>WebSockets\Data\Events.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\RestClient.cs"> | |||
<Link>Net\RestClient.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Voice\Commands.cs"> | |||
<Link>WebSockets\Voice\Commands.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\RestClient.Events.cs"> | |||
<Link>Net\RestClient.Events.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Voice\Events.cs"> | |||
<Link>WebSockets\Voice\Events.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\RestClient.SharpRest.cs"> | |||
<Link>Net\RestClient.SharpRest.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Voice\VoiceBuffer.cs"> | |||
<Link>WebSockets\Voice\VoiceBuffer.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\VoiceBuffer.cs"> | |||
<Link>Net\VoiceBuffer.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.cs"> | |||
<Link>WebSockets\Voice\VoiceWebSocket.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\VoiceWebSocket.cs"> | |||
<Link>Net\VoiceWebSocket.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\Voice\VoiceWebSocket.Events.cs"> | |||
<Link>WebSockets\Voice\VoiceWebSocket.Events.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\VoiceWebSocket.Events.cs"> | |||
<Link>Net\VoiceWebSocket.Events.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.BuiltIn.cs"> | |||
<Link>WebSockets\WebSocket.BuiltIn.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\WebSocket.cs"> | |||
<Link>Net\WebSocket.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.cs"> | |||
<Link>WebSockets\WebSocket.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\WebSocket.Events.cs"> | |||
<Link>Net\WebSocket.Events.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.Events.cs"> | |||
<Link>WebSockets\WebSocket.Events.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.WebSocketSharp.cs"> | |||
<Link>WebSockets\WebSocket.WebSocketSharp.cs</Link> | |||
</Compile> | |||
<Compile Include="..\Discord.Net\WebSockets\WebSocketMessage.cs"> | |||
<Link>WebSockets\WebSocketMessage.cs</Link> | |||
<Compile Include="..\Discord.Net\Net\WebSocket.WebSocketSharp.cs"> | |||
<Link>Net\WebSocket.WebSocketSharp.cs</Link> | |||
</Compile> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="..\Discord.Net\lib\libopus.so"> | |||
<Link>lib\libopus.so</Link> | |||
</None> | |||
<None Include="packages.config" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Content Include="..\Discord.Net\lib\libsodium.dll"> | |||
<Link>lib\libsodium.dll</Link> | |||
</Content> | |||
<Content Include="..\Discord.Net\lib\opus.dll"> | |||
<Link>lib\opus.dll</Link> | |||
</Content> | |||
</ItemGroup> | |||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
Other similar extension points exist, see Microsoft.Common.targets. | |||
@@ -0,0 +1,29 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
namespace Discord.API | |||
{ | |||
//Gateway | |||
public class GatewayResponse | |||
{ | |||
[JsonProperty("url")] | |||
public string Url; | |||
} | |||
//Login | |||
public sealed class LoginRequest | |||
{ | |||
[JsonProperty("email")] | |||
public string Email; | |||
[JsonProperty("password")] | |||
public string Password; | |||
} | |||
public sealed class LoginResponse | |||
{ | |||
[JsonProperty("token")] | |||
public string Token; | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
namespace Discord.API | |||
{ | |||
//Events | |||
internal sealed class BanAddEvent : MemberReference { } | |||
internal sealed class BanRemoveEvent : MemberReference { } | |||
} |
@@ -0,0 +1,100 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
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(PropertyName = "topic")] | |||
public string Topic; | |||
[JsonProperty("permission_overwrites")] | |||
public PermissionOverwrite[] PermissionOverwrites; | |||
[JsonProperty("recipient")] | |||
public UserReference Recipient; | |||
} | |||
//Create | |||
public class CreateChannelRequest | |||
{ | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("type")] | |||
public string Type; | |||
} | |||
public class CreatePMChannelRequest | |||
{ | |||
[JsonProperty("recipient_id")] | |||
public string RecipientId; | |||
} | |||
public class CreateChannelResponse : ChannelInfo { } | |||
//Edit | |||
public class EditChannelRequest | |||
{ | |||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Name; | |||
[JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Topic; | |||
} | |||
public class EditChannelResponse : ChannelInfo { } | |||
//Destroy | |||
public class DestroyChannelResponse : ChannelInfo { } | |||
//Reorder | |||
public class ReorderChannelsRequest : IEnumerable<ReorderChannelsRequest.Channel> | |||
{ | |||
public sealed class Channel | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("position")] | |||
public uint Position; | |||
} | |||
private IEnumerable<Channel> _channels; | |||
public ReorderChannelsRequest(IEnumerable<Channel> channels) { _channels = channels; } | |||
public IEnumerator<Channel> GetEnumerator() => _channels.GetEnumerator(); | |||
IEnumerator IEnumerable.GetEnumerator() => _channels.GetEnumerator(); | |||
} | |||
//Events | |||
internal sealed class ChannelCreateEvent : ChannelInfo { } | |||
internal sealed class ChannelDeleteEvent : ChannelInfo { } | |||
internal sealed class ChannelUpdateEvent : ChannelInfo { } | |||
} |
@@ -1,318 +0,0 @@ | |||
//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("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("user")] | |||
private UserReference _user; | |||
public UserReference User | |||
{ | |||
get { return _user; } | |||
set | |||
{ | |||
_user = value; | |||
UserId = User.Id; | |||
} | |||
} | |||
} | |||
public class MemberInfo : MemberReference | |||
{ | |||
[JsonProperty("joined_at")] | |||
public DateTime? JoinedAt; | |||
[JsonProperty("roles")] | |||
public string[] Roles; | |||
} | |||
public class ExtendedMemberInfo : MemberInfo | |||
{ | |||
[JsonProperty("mute")] | |||
public bool? IsServerMuted; | |||
[JsonProperty("deaf")] | |||
public bool? IsServerDeafened; | |||
} | |||
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("session_id")] | |||
public string SessionId; | |||
[JsonProperty("token")] | |||
public string Token; | |||
[JsonProperty("self_mute")] | |||
public bool? IsSelfMuted; | |||
[JsonProperty("self_deaf")] | |||
public bool? IsSelfDeafened; | |||
[JsonProperty("mute")] | |||
public bool? IsServerMuted; | |||
[JsonProperty("deaf")] | |||
public bool? IsServerDeafened; | |||
[JsonProperty("suppress")] | |||
public bool? IsServerSuppressed; | |||
} | |||
//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(PropertyName = "topic")] | |||
public string Topic; | |||
[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; | |||
[JsonProperty("unavailable")] | |||
public bool Unavailable; | |||
} | |||
//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 uint? Permissions; | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("position")] | |||
public int? Position; | |||
[JsonProperty("hoist")] | |||
public bool? Hoist; | |||
[JsonProperty("color")] | |||
public uint? Color; | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("managed")] | |||
public bool? Managed; | |||
} | |||
//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,9 +1,10 @@ | |||
namespace Discord.API | |||
{ | |||
internal static class Endpoints | |||
public static class Endpoints | |||
{ | |||
public const string BaseStatusApi = "https://status.discordapp.com/api/v2/"; | |||
public const string BaseApi = "https://discordapp.com/api/"; | |||
public const string Gateway = "gateway"; | |||
public const string Auth = "auth"; | |||
@@ -39,7 +40,7 @@ | |||
public const string Voice = "voice"; | |||
public const string VoiceRegions = "voice/regions"; | |||
public const string VoiceIce = "voice/ice"; | |||
//public const string VoiceIce = "voice/ice"; | |||
public const string StatusActiveMaintenance = "scheduled-maintenances/active.json"; | |||
public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json"; | |||
@@ -0,0 +1,59 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
public class InviteReference | |||
{ | |||
[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 InviteInfo : InviteReference | |||
{ | |||
[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; | |||
} | |||
//Create | |||
public class CreateInviteRequest | |||
{ | |||
[JsonProperty("max_age")] | |||
public int MaxAge; | |||
[JsonProperty("max_uses")] | |||
public int MaxUses; | |||
[JsonProperty("temporary")] | |||
public bool IsTemporary; | |||
[JsonProperty("xkcdpass")] | |||
public bool WithXkcdPass; | |||
} | |||
public class CreateInviteResponse : InviteInfo { } | |||
//Get | |||
public class GetInviteResponse : InviteReference { } | |||
//Accept | |||
public class AcceptInviteResponse : InviteReference { } | |||
} |
@@ -0,0 +1,33 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
namespace Discord.API | |||
{ | |||
public class GetIncidentsResponse | |||
{ | |||
[JsonProperty("page")] | |||
public PageData Page; | |||
[JsonProperty("scheduled_maintenances")] | |||
public MaintenanceData[] ScheduledMaintenances; | |||
public sealed class PageData | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("url")] | |||
public string Url; | |||
[JsonProperty("updated-at")] | |||
public DateTime? UpdatedAt; | |||
} | |||
public sealed class MaintenanceData | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
public class MemberReference | |||
{ | |||
[JsonProperty("user_id")] | |||
public string UserId; | |||
[JsonProperty("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("user")] | |||
private UserReference _user; | |||
public UserReference User | |||
{ | |||
get { return _user; } | |||
set | |||
{ | |||
_user = value; | |||
UserId = User.Id; | |||
} | |||
} | |||
} | |||
public class MemberInfo : MemberReference | |||
{ | |||
[JsonProperty("joined_at")] | |||
public DateTime? JoinedAt; | |||
[JsonProperty("roles")] | |||
public string[] Roles; | |||
} | |||
public class ExtendedMemberInfo : MemberInfo | |||
{ | |||
[JsonProperty("mute")] | |||
public bool? IsServerMuted; | |||
[JsonProperty("deaf")] | |||
public bool? IsServerDeafened; | |||
} | |||
public class PresenceInfo : MemberReference | |||
{ | |||
[JsonProperty("game_id")] | |||
public string GameId; | |||
[JsonProperty("status")] | |||
public string Status; | |||
} | |||
public class VoiceMemberInfo : MemberReference | |||
{ | |||
[JsonProperty("channel_id")] | |||
public string ChannelId; | |||
[JsonProperty("session_id")] | |||
public string SessionId; | |||
[JsonProperty("token")] | |||
public string Token; | |||
[JsonProperty("self_mute")] | |||
public bool? IsSelfMuted; | |||
[JsonProperty("self_deaf")] | |||
public bool? IsSelfDeafened; | |||
[JsonProperty("mute")] | |||
public bool? IsServerMuted; | |||
[JsonProperty("deaf")] | |||
public bool? IsServerDeafened; | |||
[JsonProperty("suppress")] | |||
public bool? IsServerSuppressed; | |||
} | |||
public 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 IEnumerable<string> Roles; | |||
} | |||
//Events | |||
internal sealed class MemberAddEvent : MemberInfo { } | |||
internal sealed class MemberUpdateEvent : MemberInfo { } | |||
internal sealed class MemberRemoveEvent : MemberInfo { } | |||
internal sealed class MemberVoiceStateUpdateEvent : VoiceMemberInfo { } | |||
} |
@@ -0,0 +1,133 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
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 MessageInfo : 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; | |||
} | |||
//Create | |||
internal sealed class SendMessageRequest | |||
{ | |||
[JsonProperty("content")] | |||
public string Content; | |||
[JsonProperty("mentions")] | |||
public IEnumerable<string> Mentions; | |||
[JsonProperty("nonce", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Nonce; | |||
[JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)] | |||
public bool IsTTS; | |||
} | |||
public sealed class SendMessageResponse : MessageInfo { } | |||
//Edit | |||
internal sealed class EditMessageRequest | |||
{ | |||
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Content; | |||
[JsonProperty("mentions", NullValueHandling = NullValueHandling.Ignore)] | |||
public IEnumerable<string> Mentions; | |||
} | |||
public sealed class EditMessageResponse : MessageInfo { } | |||
//Get | |||
public sealed class GetMessagesResponse : List<MessageInfo> { } | |||
//Events | |||
internal sealed class MessageCreateEvent : MessageInfo { } | |||
internal sealed class MessageUpdateEvent : MessageInfo { } | |||
internal sealed class MessageDeleteEvent : MessageReference { } | |||
internal sealed class MessageAckEvent : MessageReference { } | |||
} |
@@ -0,0 +1,21 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
namespace Discord.API | |||
{ | |||
//Create/Edit | |||
internal sealed class SetChannelPermissionsRequest | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("type")] | |||
public string Type; | |||
[JsonProperty("allow")] | |||
public uint Allow; | |||
[JsonProperty("deny")] | |||
public uint Deny; | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
namespace Discord.API | |||
{ | |||
//Commands | |||
internal sealed class UpdateStatusCommand : WebSocketMessage<UpdateStatusCommand.Data> | |||
{ | |||
public UpdateStatusCommand() : base(3) { } | |||
public class Data | |||
{ | |||
[JsonProperty("idle_since")] | |||
public ulong? IdleSince; | |||
[JsonProperty("game_id")] | |||
public int? GameId; | |||
} | |||
} | |||
//Events | |||
internal sealed class TypingStartEvent | |||
{ | |||
[JsonProperty("user_id")] | |||
public string UserId; | |||
[JsonProperty("channel_id")] | |||
public string ChannelId; | |||
[JsonProperty("timestamp")] | |||
public int Timestamp; | |||
} | |||
internal sealed class PresenceUpdateEvent : PresenceInfo { } | |||
} |
@@ -1,178 +0,0 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System.Collections.Generic; | |||
using System.Collections; | |||
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; | |||
} | |||
internal sealed class ReorderChannelsRequest : IEnumerable<ReorderChannelsRequest.Channel> | |||
{ | |||
public sealed class Channel | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("position")] | |||
public uint Position; | |||
} | |||
private IEnumerable<Channel> _channels; | |||
public ReorderChannelsRequest(IEnumerable<Channel> channels) { _channels = channels; } | |||
public IEnumerator<Channel> GetEnumerator() =>_channels.GetEnumerator(); | |||
IEnumerator IEnumerable.GetEnumerator() => _channels.GetEnumerator(); | |||
} | |||
//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 IEnumerable<string> Roles; | |||
} | |||
//Messages | |||
internal sealed class SendMessageRequest | |||
{ | |||
[JsonProperty("content")] | |||
public string Content; | |||
[JsonProperty("mentions")] | |||
public IEnumerable<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 IEnumerable<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")] | |||
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; | |||
[JsonProperty("hoist", NullValueHandling = NullValueHandling.Ignore)] | |||
public bool? Hoist; | |||
[JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] | |||
public uint? Color; | |||
} | |||
internal sealed class ReorderRolesRequest : IEnumerable<ReorderRolesRequest.Role> | |||
{ | |||
public sealed class Role | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("position")] | |||
public uint Position; | |||
} | |||
private IEnumerable<Role> _roles; | |||
public ReorderRolesRequest(IEnumerable<Role> roles) { _roles = roles; } | |||
public IEnumerator<Role> GetEnumerator() => _roles.GetEnumerator(); | |||
IEnumerator IEnumerable.GetEnumerator() => _roles.GetEnumerator(); | |||
} | |||
//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,106 +0,0 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Auth | |||
public sealed class GatewayResponse | |||
{ | |||
[JsonProperty("url")] | |||
public string Url; | |||
} | |||
public sealed class LoginResponse | |||
{ | |||
[JsonProperty("token")] | |||
public string Token; | |||
} | |||
//Channels | |||
public sealed class CreateChannelResponse : ChannelInfo { } | |||
public sealed class DestroyChannelResponse : ChannelInfo { } | |||
public sealed class EditChannelResponse : ChannelInfo { } | |||
//Invites | |||
public sealed class CreateInviteResponse : ExtendedInvite { } | |||
public sealed class GetInviteResponse : Invite { } | |||
public sealed class AcceptInviteResponse : Invite { } | |||
//Messages | |||
public sealed class SendMessageResponse : Message { } | |||
public sealed class EditMessageResponse : Message { } | |||
public sealed class GetMessagesResponse : List<Message> { } | |||
//Profile | |||
public sealed class EditProfileResponse : SelfUserInfo { } | |||
//Roles | |||
public sealed class CreateRoleResponse : RoleInfo { } | |||
public sealed class EditRoleResponse : RoleInfo { } | |||
//Servers | |||
public sealed class CreateServerResponse : GuildInfo { } | |||
public sealed class DeleteServerResponse : GuildInfo { } | |||
public sealed class EditServerResponse : GuildInfo { } | |||
//Voice | |||
public sealed class GetRegionsResponse : List<GetRegionsResponse.RegionData> | |||
{ | |||
public sealed class RegionData | |||
{ | |||
[JsonProperty("sample_hostname")] | |||
public string Hostname; | |||
[JsonProperty("sample_port")] | |||
public int Port; | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("name")] | |||
public string Name; | |||
} | |||
} | |||
public sealed class GetIceResponse | |||
{ | |||
[JsonProperty("ttl")] | |||
public string TTL; | |||
[JsonProperty("servers")] | |||
public ServerData[] Servers; | |||
public sealed class ServerData | |||
{ | |||
[JsonProperty("url")] | |||
public string URL; | |||
[JsonProperty("username")] | |||
public string Username; | |||
[JsonProperty("credential")] | |||
public string Credential; | |||
} | |||
} | |||
public sealed class GetIncidentsResponse | |||
{ | |||
[JsonProperty("page")] | |||
public PageData Page; | |||
[JsonProperty("scheduled_maintenances")] | |||
public MaintenanceData[] ScheduledMaintenances; | |||
public sealed class PageData | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("url")] | |||
public string Url; | |||
[JsonProperty("updated-at")] | |||
public DateTime? UpdatedAt; | |||
} | |||
public sealed class MaintenanceData | |||
{ | |||
} | |||
} | |||
} |
@@ -1,67 +0,0 @@ | |||
/* | |||
using Discord.API; | |||
using System; | |||
using System.Globalization; | |||
using System.IO; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord.API | |||
{ | |||
internal class BuiltInRestEngine : IRestEngine | |||
{ | |||
private readonly HttpClient _client; | |||
public BuiltInRestEngine(string userAgent, int timeout) | |||
{ | |||
_client = new HttpClient(new HttpClientHandler | |||
{ | |||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, | |||
UseCookies = false, | |||
PreAuthenticate = false //We do auth ourselves | |||
}); | |||
_client.DefaultRequestHeaders.Add("accept", "*\/*"); | |||
_client.DefaultRequestHeaders.Add("accept-encoding", "gzip,deflate"); | |||
_client.DefaultRequestHeaders.Add("user-agent", userAgent); | |||
_client.Timeout = TimeSpan.FromMilliseconds(timeout); | |||
} | |||
public void SetToken(string token) | |||
{ | |||
_client.DefaultRequestHeaders.Remove("authorization"); | |||
if (token != null) | |||
_client.DefaultRequestHeaders.Add("authorization", token); | |||
} | |||
public async Task<string> Send(HttpMethod method, string path, string json, CancellationToken cancelToken) | |||
{ | |||
using (var request = new HttpRequestMessage(method, Endpoints.BaseApi + path)) | |||
{ | |||
if (json != null) | |||
request.Content = new StringContent(json, Encoding.UTF8, "application/json"); | |||
return await Send(request, cancelToken); | |||
} | |||
} | |||
public async Task<string> SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken) | |||
{ | |||
using (var request = new HttpRequestMessage(method, Endpoints.BaseApi + path)) | |||
{ | |||
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); | |||
content.Add(new StreamContent(File.OpenRead(filePath)), "file", Path.GetFileName(filePath)); | |||
request.Content = content; | |||
return await Send(request, cancelToken); | |||
} | |||
} | |||
private async Task<string> Send(HttpRequestMessage request, CancellationToken cancelToken) | |||
{ | |||
var response = await _client.SendAsync(request, cancelToken).ConfigureAwait(false); | |||
if (!response.IsSuccessStatusCode) | |||
throw new HttpException(response.StatusCode); | |||
return await response.Content.ReadAsStringAsync().ConfigureAwait(false); | |||
} | |||
} | |||
} | |||
*/ |
@@ -0,0 +1,87 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
public class RoleReference | |||
{ | |||
[JsonProperty("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("role_id")] | |||
public string RoleId; | |||
} | |||
public class RoleInfo | |||
{ | |||
[JsonProperty("permissions")] | |||
public uint? Permissions; | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("position")] | |||
public int? Position; | |||
[JsonProperty("hoist")] | |||
public bool? Hoist; | |||
[JsonProperty("color")] | |||
public uint? Color; | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("managed")] | |||
public bool? Managed; | |||
} | |||
//Create | |||
public sealed class CreateRoleResponse : RoleInfo { } | |||
//Edit | |||
public sealed class EditRoleRequest | |||
{ | |||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Name; | |||
[JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)] | |||
public uint? Permissions; | |||
[JsonProperty("hoist", NullValueHandling = NullValueHandling.Ignore)] | |||
public bool? Hoist; | |||
[JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] | |||
public uint? Color; | |||
} | |||
public sealed class EditRoleResponse : RoleInfo { } | |||
//Reorder | |||
public sealed class ReorderRolesRequest : IEnumerable<ReorderRolesRequest.Role> | |||
{ | |||
public sealed class Role | |||
{ | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("position")] | |||
public uint Position; | |||
} | |||
private IEnumerable<Role> _roles; | |||
public ReorderRolesRequest(IEnumerable<Role> roles) { _roles = roles; } | |||
public IEnumerator<Role> GetEnumerator() => _roles.GetEnumerator(); | |||
IEnumerator IEnumerable.GetEnumerator() => _roles.GetEnumerator(); | |||
} | |||
//Events | |||
internal sealed class RoleCreateEvent | |||
{ | |||
[JsonProperty("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("role")] | |||
public RoleInfo Data; | |||
} | |||
internal sealed class RoleUpdateEvent | |||
{ | |||
[JsonProperty("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("role")] | |||
public RoleInfo Data; | |||
} | |||
internal sealed class RoleDeleteEvent : RoleReference { } | |||
} |
@@ -0,0 +1,80 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
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 PresenceInfo[] Presences; | |||
[JsonProperty("voice_states")] | |||
public VoiceMemberInfo[] VoiceStates; | |||
[JsonProperty("unavailable")] | |||
public bool Unavailable; | |||
} | |||
//Create | |||
internal sealed class CreateServerRequest | |||
{ | |||
[JsonProperty("name")] | |||
public string Name; | |||
[JsonProperty("region")] | |||
public string Region; | |||
} | |||
public sealed class CreateServerResponse : GuildInfo { } | |||
//Edit | |||
internal sealed class EditServerRequest | |||
{ | |||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Name; | |||
[JsonProperty("region", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Region; | |||
} | |||
public sealed class EditServerResponse : GuildInfo { } | |||
//Delete | |||
public sealed class DeleteServerResponse : GuildInfo { } | |||
//Events | |||
internal sealed class GuildCreateEvent : ExtendedGuildInfo { } | |||
internal sealed class GuildUpdateEvent : GuildInfo { } | |||
internal sealed class GuildDeleteEvent : ExtendedGuildInfo { } | |||
} |
@@ -0,0 +1,47 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
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 UserInfo : UserReference | |||
{ | |||
[JsonProperty("email")] | |||
public string Email; | |||
[JsonProperty("verified")] | |||
public bool? IsVerified; | |||
} | |||
//Edit | |||
internal sealed class EditUserRequest | |||
{ | |||
[JsonProperty(PropertyName = "password")] | |||
public string CurrentPassword; | |||
[JsonProperty(PropertyName = "email", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Email; | |||
[JsonProperty(PropertyName = "new_password")] | |||
public string Password; | |||
[JsonProperty(PropertyName = "username", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Username; | |||
[JsonProperty(PropertyName = "avatar", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Avatar; | |||
} | |||
public sealed class EditUserResponse : UserInfo { } | |||
//Events | |||
internal sealed class UserUpdateEvent : UserInfo { } | |||
} |
@@ -0,0 +1,153 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
public class GetRegionsResponse : List<GetRegionsResponse.RegionData> | |||
{ | |||
public sealed class RegionData | |||
{ | |||
[JsonProperty("sample_hostname")] | |||
public string Hostname; | |||
[JsonProperty("sample_port")] | |||
public int Port; | |||
[JsonProperty("id")] | |||
public string Id; | |||
[JsonProperty("name")] | |||
public string Name; | |||
} | |||
} | |||
public class GetIceResponse | |||
{ | |||
[JsonProperty("ttl")] | |||
public string TTL; | |||
[JsonProperty("servers")] | |||
public ServerData[] Servers; | |||
public sealed class ServerData | |||
{ | |||
[JsonProperty("url")] | |||
public string URL; | |||
[JsonProperty("username")] | |||
public string Username; | |||
[JsonProperty("credential")] | |||
public string Credential; | |||
} | |||
} | |||
//Commands | |||
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; | |||
} | |||
} | |||
//Events | |||
internal sealed class VoiceServerUpdateEvent | |||
{ | |||
[JsonProperty("guild_id")] | |||
public string GuildId; | |||
[JsonProperty("endpoint")] | |||
public string Endpoint; | |||
[JsonProperty("token")] | |||
public string Token; | |||
} | |||
//Commands (Voice) | |||
internal sealed class VoiceLoginCommand : WebSocketMessage<VoiceLoginCommand.Data> | |||
{ | |||
public VoiceLoginCommand() : 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 VoiceLogin2Command : WebSocketMessage<VoiceLogin2Command.Data> | |||
{ | |||
public VoiceLogin2Command() : 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 VoiceKeepAliveCommand : WebSocketMessage<object> | |||
{ | |||
public VoiceKeepAliveCommand() : 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; | |||
} | |||
} | |||
//Events (Voice) | |||
public class VoiceReadyEvent | |||
{ | |||
[JsonProperty("ssrc")] | |||
public uint SSRC; | |||
[JsonProperty("port")] | |||
public ushort Port; | |||
[JsonProperty("modes")] | |||
public string[] Modes; | |||
[JsonProperty("heartbeat_interval")] | |||
public int HeartbeatInterval; | |||
} | |||
public class JoinServerEvent | |||
{ | |||
[JsonProperty("secret_key")] | |||
public byte[] SecretKey; | |||
[JsonProperty("mode")] | |||
public string Mode; | |||
} | |||
public class IsTalkingEvent | |||
{ | |||
[JsonProperty("user_id")] | |||
public string UserId; | |||
[JsonProperty("ssrc")] | |||
public uint SSRC; | |||
[JsonProperty("speaking")] | |||
public bool IsSpeaking; | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using System.Collections.Generic; | |||
namespace Discord.API | |||
{ | |||
//Common | |||
public class WebSocketMessage | |||
{ | |||
[JsonProperty("op")] | |||
public int Operation; | |||
[JsonProperty("d")] | |||
public object Payload; | |||
[JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Type; | |||
[JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)] | |||
public int? Sequence; | |||
} | |||
internal abstract class WebSocketMessage<T> : WebSocketMessage | |||
where T : new() | |||
{ | |||
public WebSocketMessage() { Payload = new T(); } | |||
public WebSocketMessage(int op) { Operation = op; Payload = new T(); } | |||
public WebSocketMessage(int op, T payload) { Operation = op; Payload = payload; } | |||
[JsonIgnore] | |||
public new T Payload | |||
{ | |||
get | |||
{ | |||
if (base.Payload is JToken) | |||
base.Payload = (base.Payload as JToken).ToObject<T>(); | |||
return (T)base.Payload; | |||
} | |||
set { base.Payload = value; } | |||
} | |||
} | |||
//Commands | |||
internal sealed class KeepAliveCommand : WebSocketMessage<ulong> | |||
{ | |||
public KeepAliveCommand() : base(1, EpochTime.GetMilliseconds()) { } | |||
} | |||
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 ResumeCommand : WebSocketMessage<ResumeCommand.Data> | |||
{ | |||
public ResumeCommand() : base(6) { } | |||
public class Data | |||
{ | |||
[JsonProperty("session_id")] | |||
public string SessionId; | |||
[JsonProperty("seq")] | |||
public int Sequence; | |||
} | |||
} | |||
//Events | |||
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 UserInfo 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; | |||
} | |||
} |
@@ -1,4 +1,5 @@ | |||
using Discord.API; | |||
using Discord.Net; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -312,7 +313,7 @@ namespace Discord | |||
{ | |||
var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, CurrentUserId); | |||
var currentMember = _members[msg.UserId, channel.ServerId]; | |||
msg.Update(new API.Message | |||
msg.Update(new MessageInfo | |||
{ | |||
Content = blockText, | |||
Timestamp = DateTime.UtcNow, | |||
@@ -611,26 +612,20 @@ namespace Discord | |||
} | |||
//Profile | |||
public Task<EditProfileResponse> EditProfile(string currentPassword = "", | |||
public Task<EditUserResponse> EditProfile(string currentPassword = "", | |||
string username = null, string email = null, string password = null, | |||
AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) | |||
{ | |||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); | |||
return _api.EditProfile(currentPassword: currentPassword, username: username ?? _currentUser?.Name, email: email ?? _currentUser?.Email, password: password, | |||
return _api.EditUser(currentPassword: currentPassword, username: username ?? _currentUser?.Name, email: email ?? _currentUser?.Email, password: password, | |||
avatarType: avatarType, avatar: avatar); | |||
} | |||
public Task SetStatus(string status) | |||
{ | |||
switch (status) | |||
{ | |||
case UserStatus.Online: | |||
case UserStatus.Away: | |||
_status = status; | |||
break; | |||
default: | |||
throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Away}"); | |||
} | |||
if (status != UserStatus.Online && status != UserStatus.Idle) | |||
throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Idle}"); | |||
_status = status; | |||
return SendStatus(); | |||
} | |||
public Task SetGame(int? gameId) | |||
@@ -640,7 +635,7 @@ namespace Discord | |||
} | |||
private Task SendStatus() | |||
{ | |||
_dataSocket.SendStatus(_status == UserStatus.Away ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (ulong?)null, _gameId); | |||
_dataSocket.SendStatus(_status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (ulong?)null, _gameId); | |||
return TaskHelper.CompletedTask; | |||
} | |||
@@ -1,7 +1,6 @@ | |||
using Discord.API; | |||
using Discord.Collections; | |||
using Discord.WebSockets; | |||
using Discord.WebSockets.Data; | |||
using Discord.Net; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Concurrent; | |||
@@ -9,7 +8,6 @@ using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Threading.Tasks; | |||
using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket; | |||
namespace Discord | |||
{ | |||
@@ -474,7 +472,7 @@ namespace Discord | |||
//Members | |||
case "GUILD_MEMBER_ADD": | |||
{ | |||
var data = e.Payload.ToObject<GuildMemberAddEvent>(_serializer); | |||
var data = e.Payload.ToObject<MemberAddEvent>(_serializer); | |||
var user = _users.GetOrAdd(data.User.Id); | |||
user.Update(data.User); | |||
var member = _members.GetOrAdd(data.User.Id, data.GuildId); | |||
@@ -486,7 +484,7 @@ namespace Discord | |||
break; | |||
case "GUILD_MEMBER_UPDATE": | |||
{ | |||
var data = e.Payload.ToObject<GuildMemberUpdateEvent>(_serializer); | |||
var data = e.Payload.ToObject<MemberUpdateEvent>(_serializer); | |||
var member = _members[data.User.Id, data.GuildId]; | |||
if (member != null) | |||
{ | |||
@@ -497,7 +495,7 @@ namespace Discord | |||
break; | |||
case "GUILD_MEMBER_REMOVE": | |||
{ | |||
var data = e.Payload.ToObject<GuildMemberRemoveEvent>(_serializer); | |||
var data = e.Payload.ToObject<MemberRemoveEvent>(_serializer); | |||
var member = _members.TryRemove(data.UserId, data.GuildId); | |||
if (member != null) | |||
RaiseUserRemoved(member); | |||
@@ -507,7 +505,7 @@ namespace Discord | |||
//Roles | |||
case "GUILD_ROLE_CREATE": | |||
{ | |||
var data = e.Payload.ToObject<GuildRoleCreateEvent>(_serializer); | |||
var data = e.Payload.ToObject<RoleCreateEvent>(_serializer); | |||
var role = _roles.GetOrAdd(data.Data.Id, data.GuildId, false); | |||
role.Update(data.Data); | |||
var server = _servers[data.GuildId]; | |||
@@ -518,7 +516,7 @@ namespace Discord | |||
break; | |||
case "GUILD_ROLE_UPDATE": | |||
{ | |||
var data = e.Payload.ToObject<GuildRoleUpdateEvent>(_serializer); | |||
var data = e.Payload.ToObject<RoleUpdateEvent>(_serializer); | |||
var role = _roles[data.Data.Id]; | |||
if (role != null) | |||
role.Update(data.Data); | |||
@@ -527,7 +525,7 @@ namespace Discord | |||
break; | |||
case "GUILD_ROLE_DELETE": | |||
{ | |||
var data = e.Payload.ToObject<GuildRoleDeleteEvent>(_serializer); | |||
var data = e.Payload.ToObject<RoleDeleteEvent>(_serializer); | |||
var server = _servers[data.GuildId]; | |||
if (server != null) | |||
server.RemoveRole(data.RoleId); | |||
@@ -540,7 +538,7 @@ namespace Discord | |||
//Bans | |||
case "GUILD_BAN_ADD": | |||
{ | |||
var data = e.Payload.ToObject<GuildBanAddEvent>(_serializer); | |||
var data = e.Payload.ToObject<BanAddEvent>(_serializer); | |||
var server = _servers[data.GuildId]; | |||
if (server != null) | |||
{ | |||
@@ -551,7 +549,7 @@ namespace Discord | |||
break; | |||
case "GUILD_BAN_REMOVE": | |||
{ | |||
var data = e.Payload.ToObject<GuildBanRemoveEvent>(_serializer); | |||
var data = e.Payload.ToObject<BanRemoveEvent>(_serializer); | |||
var server = _servers[data.GuildId]; | |||
if (server != null && server.RemoveBan(data.User?.Id)) | |||
RaiseBanRemoved(data.User?.Id, server); | |||
@@ -682,7 +680,7 @@ namespace Discord | |||
//Voice | |||
case "VOICE_STATE_UPDATE": | |||
{ | |||
var data = e.Payload.ToObject<VoiceStateUpdateEvent>(_serializer); | |||
var data = e.Payload.ToObject<MemberVoiceStateUpdateEvent>(_serializer); | |||
var member = _members[data.UserId, data.GuildId]; | |||
if (member != null) | |||
{ | |||
@@ -1,11 +1,10 @@ | |||
using Discord.WebSockets.Data; | |||
using Discord.Net; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Runtime.ExceptionServices; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket; | |||
namespace Discord | |||
{ | |||
@@ -6,6 +6,53 @@ namespace Discord | |||
{ | |||
internal static class Extensions | |||
{ | |||
public static async Task Timeout(this Task self, int milliseconds) | |||
{ | |||
Task timeoutTask = Task.Delay(milliseconds); | |||
Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); | |||
if (finishedTask == timeoutTask) | |||
throw new TimeoutException(); | |||
else | |||
await self.ConfigureAwait(false); | |||
} | |||
public static async Task<T> Timeout<T>(this Task<T> self, int milliseconds) | |||
{ | |||
Task timeoutTask = Task.Delay(milliseconds); | |||
Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); | |||
if (finishedTask == timeoutTask) | |||
throw new TimeoutException(); | |||
else | |||
return await self.ConfigureAwait(false); | |||
} | |||
public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) | |||
{ | |||
try | |||
{ | |||
timeoutToken.CancelAfter(milliseconds); | |||
await self.ConfigureAwait(false); | |||
} | |||
catch (OperationCanceledException) | |||
{ | |||
if (timeoutToken.IsCancellationRequested) | |||
throw new TimeoutException(); | |||
throw; | |||
} | |||
} | |||
public static async Task<T> Timeout<T>(this Task<T> self, int milliseconds, CancellationTokenSource timeoutToken) | |||
{ | |||
try | |||
{ | |||
timeoutToken.CancelAfter(milliseconds); | |||
return await self.ConfigureAwait(false); | |||
} | |||
catch (OperationCanceledException) | |||
{ | |||
if (timeoutToken.IsCancellationRequested) | |||
throw new TimeoutException(); | |||
throw; | |||
} | |||
} | |||
public static async Task Wait(this CancellationTokenSource tokenSource) | |||
{ | |||
var token = tokenSource.Token; | |||
@@ -1,56 +0,0 @@ | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
public static class TaskExtensions | |||
{ | |||
public static async Task Timeout(this Task self, int milliseconds) | |||
{ | |||
Task timeoutTask = Task.Delay(milliseconds); | |||
Task finishedTask = await Task.WhenAny(self, timeoutTask); | |||
if (finishedTask == timeoutTask) | |||
throw new TimeoutException(); | |||
else | |||
await self; | |||
} | |||
public static async Task<T> Timeout<T>(this Task<T> self, int milliseconds) | |||
{ | |||
Task timeoutTask = Task.Delay(milliseconds); | |||
Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); | |||
if (finishedTask == timeoutTask) | |||
throw new TimeoutException(); | |||
else | |||
return await self.ConfigureAwait(false); | |||
} | |||
public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) | |||
{ | |||
try | |||
{ | |||
timeoutToken.CancelAfter(milliseconds); | |||
await self.ConfigureAwait(false); | |||
} | |||
catch (OperationCanceledException) | |||
{ | |||
if (timeoutToken.IsCancellationRequested) | |||
throw new TimeoutException(); | |||
throw; | |||
} | |||
} | |||
public static async Task<T> Timeout<T>(this Task<T> self, int milliseconds, CancellationTokenSource timeoutToken) | |||
{ | |||
try | |||
{ | |||
timeoutToken.CancelAfter(milliseconds); | |||
return await self.ConfigureAwait(false); | |||
} | |||
catch (OperationCanceledException) | |||
{ | |||
if (timeoutToken.IsCancellationRequested) | |||
throw new TimeoutException(); | |||
throw; | |||
} | |||
} | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Runtime.InteropServices; | |||
namespace Discord.Audio | |||
namespace Discord.Interop | |||
{ | |||
internal unsafe static class Opus | |||
{ |
@@ -1,6 +1,6 @@ | |||
using System; | |||
namespace Discord.Audio | |||
namespace Discord.Interop | |||
{ | |||
/// <summary> Opus codec wrapper. </summary> | |||
internal class OpusDecoder : IDisposable |
@@ -1,6 +1,6 @@ | |||
using System; | |||
namespace Discord.Audio | |||
namespace Discord.Interop | |||
{ | |||
/// <summary> Opus codec wrapper. </summary> | |||
internal class OpusEncoder : IDisposable |
@@ -1,6 +1,6 @@ | |||
using System.Runtime.InteropServices; | |||
namespace Discord.Audio | |||
namespace Discord.Interop | |||
{ | |||
internal unsafe static class Sodium | |||
{ |
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -99,16 +100,16 @@ namespace Discord | |||
_areMembersStale = true; | |||
} | |||
internal void Update(API.ChannelReference model) | |||
internal void Update(ChannelReference model) | |||
{ | |||
if (model.Name != null) | |||
Name = model.Name; | |||
if (model.Type != null) | |||
Type = model.Type; | |||
} | |||
internal void Update(API.ChannelInfo model) | |||
internal void Update(ChannelInfo model) | |||
{ | |||
Update(model as API.ChannelReference); | |||
Update(model as ChannelReference); | |||
if (model.Position != null) | |||
Position = model.Position.Value; | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
namespace Discord | |||
{ | |||
@@ -53,7 +54,7 @@ namespace Discord | |||
public override string ToString() => XkcdPass ?? Id; | |||
internal void Update(API.Invite model) | |||
internal void Update(InviteReference model) | |||
{ | |||
if (model.Channel != null) | |||
ChannelId = model.Channel.Id; | |||
@@ -61,9 +62,9 @@ namespace Discord | |||
InviterId = model.Inviter.Id; | |||
} | |||
internal void Update(API.ExtendedInvite model) | |||
internal void Update(InviteInfo model) | |||
{ | |||
Update(model as API.Invite); | |||
Update(model as InviteReference); | |||
if (model.IsRevoked != null) | |||
IsRevoked = model.IsRevoked.Value; | |||
if (model.IsTemporary != null) | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
@@ -77,7 +78,7 @@ namespace Discord | |||
public override string ToString() => UserId; | |||
internal void Update(API.UserReference model) | |||
internal void Update(UserReference model) | |||
{ | |||
if (model.Avatar != null) | |||
AvatarId = model.Avatar; | |||
@@ -86,7 +87,7 @@ namespace Discord | |||
if (model.Username != null) | |||
Name = model.Username; | |||
} | |||
internal void Update(API.MemberInfo model) | |||
internal void Update(MemberInfo model) | |||
{ | |||
if (model.User != null) | |||
Update(model.User); | |||
@@ -102,7 +103,7 @@ namespace Discord | |||
UpdatePermissions(); | |||
} | |||
internal void Update(API.ExtendedMemberInfo model) | |||
internal void Update(ExtendedMemberInfo model) | |||
{ | |||
Update(model as API.MemberInfo); | |||
if (model.IsServerDeafened != null) | |||
@@ -110,7 +111,7 @@ namespace Discord | |||
if (model.IsServerMuted != null) | |||
IsServerMuted = model.IsServerMuted.Value; | |||
} | |||
internal void Update(API.PresenceMemberInfo model) | |||
internal void Update(PresenceInfo model) | |||
{ | |||
//Allows null | |||
if (Status != model.Status) | |||
@@ -121,7 +122,7 @@ namespace Discord | |||
} | |||
GameId = model.GameId; | |||
} | |||
internal void Update(API.VoiceMemberInfo model) | |||
internal void Update(VoiceMemberInfo model) | |||
{ | |||
if (model.IsServerDeafened != null) | |||
IsServerDeafened = model.IsServerDeafened.Value; | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -175,7 +176,7 @@ namespace Discord | |||
MentionIds = _initialMentions; | |||
} | |||
internal void Update(API.Message model) | |||
internal void Update(MessageInfo model) | |||
{ | |||
if (model.Attachments != null) | |||
{ | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -52,7 +53,7 @@ namespace Discord | |||
Position = int.MinValue; | |||
} | |||
internal void Update(API.RoleInfo model) | |||
internal void Update(RoleInfo model) | |||
{ | |||
if (model.Name != null) | |||
Name = model.Name; | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
@@ -103,7 +104,7 @@ namespace Discord | |||
_roles = new ConcurrentDictionary<string, bool>(); | |||
} | |||
internal void Update(API.GuildInfo model) | |||
internal void Update(GuildInfo model) | |||
{ | |||
AFKChannelId = model.AFKChannelId; | |||
AFKTimeout = model.AFKTimeout; | |||
@@ -124,9 +125,9 @@ namespace Discord | |||
isEveryone = false; | |||
} | |||
} | |||
internal void Update(API.ExtendedGuildInfo model) | |||
internal void Update(ExtendedGuildInfo model) | |||
{ | |||
Update(model as API.GuildInfo); | |||
Update(model as GuildInfo); | |||
var channels = _client.Channels; | |||
foreach (var subModel in model.Channels) | |||
@@ -1,4 +1,5 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
@@ -77,7 +78,7 @@ namespace Discord | |||
_servers = new ConcurrentDictionary<string, bool>(); | |||
} | |||
internal void Update(API.UserReference model) | |||
internal void Update(UserReference model) | |||
{ | |||
if (model.Avatar != null) | |||
AvatarId = model.Avatar; | |||
@@ -86,11 +87,14 @@ namespace Discord | |||
if (model.Username != null) | |||
Name = model.Username; | |||
} | |||
internal void Update(API.SelfUserInfo model) | |||
internal void Update(UserInfo model) | |||
{ | |||
Update(model as API.UserReference); | |||
Email = model.Email; | |||
IsVerified = model.IsVerified; | |||
Update(model as UserReference); | |||
if (model.Email != null) | |||
Email = model.Email; | |||
if (model.IsVerified != null) | |||
IsVerified = model.IsVerified; | |||
} | |||
internal void UpdateActivity(DateTime? activity = null) | |||
{ | |||
@@ -1,9 +1,10 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord.WebSockets.Data | |||
namespace Discord.Net | |||
{ | |||
internal partial class DataWebSocket : WebSocket | |||
{ |
@@ -1,7 +1,7 @@ | |||
using Newtonsoft.Json.Linq; | |||
using System; | |||
namespace Discord.WebSockets.Data | |||
namespace Discord.Net | |||
{ | |||
internal sealed class WebSocketEventEventArgs : EventArgs | |||
{ |
@@ -5,7 +5,7 @@ using System.Linq; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
namespace Discord.Net | |||
{ | |||
/// <summary> A lightweight wrapper around the Discord API. </summary> | |||
public class DiscordAPIClient | |||
@@ -225,26 +225,6 @@ namespace Discord | |||
return _rest.Delete(Endpoints.ChannelPermission(channelId, userOrRoleId), null); | |||
} | |||
//Profile | |||
public Task<EditProfileResponse> EditProfile(string currentPassword = "", | |||
string username = null, string email = null, string password = null, | |||
AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) | |||
{ | |||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); | |||
string avatarBase64 = null; | |||
if (avatarType == AvatarImageType.None) | |||
avatarBase64 = ""; | |||
else if (avatar != null) | |||
{ | |||
string base64 = Convert.ToBase64String(avatar); | |||
string type = avatarType == AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | |||
avatarBase64 = $"data:{type},{base64}"; | |||
} | |||
var request = new EditProfileRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = avatarBase64 }; | |||
return _rest.Patch<EditProfileResponse>(Endpoints.UserMe, request); | |||
} | |||
//Roles | |||
public Task<RoleInfo> CreateRole(string serverId) | |||
{ | |||
@@ -302,10 +282,30 @@ namespace Discord | |||
return _rest.Patch<EditServerResponse>(Endpoints.Server(serverId), request); | |||
} | |||
//User | |||
public Task<EditUserResponse> EditUser(string currentPassword = "", | |||
string username = null, string email = null, string password = null, | |||
AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) | |||
{ | |||
if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); | |||
string avatarBase64 = null; | |||
if (avatarType == AvatarImageType.None) | |||
avatarBase64 = ""; | |||
else if (avatar != null) | |||
{ | |||
string base64 = Convert.ToBase64String(avatar); | |||
string type = avatarType == AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; | |||
avatarBase64 = $"data:{type},{base64}"; | |||
} | |||
var request = new EditUserRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = avatarBase64 }; | |||
return _rest.Patch<EditUserResponse>(Endpoints.UserMe, request); | |||
} | |||
//Voice | |||
public Task<GetRegionsResponse> GetVoiceRegions() | |||
=> _rest.Get<GetRegionsResponse>(Endpoints.VoiceRegions); | |||
public Task<GetIceResponse> GetVoiceIce() | |||
=> _rest.Get<GetIceResponse>(Endpoints.VoiceIce); | |||
/*public Task<GetIceResponse> GetVoiceIce() | |||
=> _rest.Get<GetIceResponse>(Endpoints.VoiceIce);*/ | |||
} | |||
} |
@@ -1,14 +1,14 @@ | |||
using System; | |||
using System.Net; | |||
namespace Discord.API | |||
namespace Discord.Net | |||
{ | |||
public class HttpException : Exception | |||
{ | |||
public HttpStatusCode StatusCode { get; } | |||
public HttpException(HttpStatusCode statusCode) | |||
: base($"The server responded with error {statusCode}") | |||
: base($"The server responded with error {(int)statusCode} ({statusCode})") | |||
{ | |||
StatusCode = statusCode; | |||
} |
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Net.Http; | |||
namespace Discord.API | |||
namespace Discord.Net | |||
{ | |||
internal partial class RestClient | |||
{ |
@@ -1,17 +1,17 @@ | |||
using RestSharp; | |||
using Discord.API; | |||
using RestSharp; | |||
using System; | |||
using System.IO; | |||
using System.Net.Http; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord.API | |||
namespace Discord.Net | |||
{ | |||
internal class RestSharpRestEngine : IRestEngine | |||
internal partial class RestClient | |||
{ | |||
private readonly RestSharp.RestClient _client; | |||
private RestSharp.RestClient _client; | |||
public RestSharpRestEngine(string userAgent, int timeout) | |||
partial void Initialize(string userAgent, int timeout) | |||
{ | |||
_client = new RestSharp.RestClient(Endpoints.BaseApi) | |||
{ | |||
@@ -24,20 +24,20 @@ namespace Discord.API | |||
_client.ReadWriteTimeout = timeout; | |||
} | |||
public void SetToken(string token) | |||
internal void SetToken(string token) | |||
{ | |||
_client.RemoveDefaultParameter("authorization"); | |||
if (token != null) | |||
_client.AddDefaultHeader("authorization", token); | |||
} | |||
public Task<string> Send(HttpMethod method, string path, string json, CancellationToken cancelToken) | |||
private Task<string> SendInternal(HttpMethod method, string path, string json, CancellationToken cancelToken) | |||
{ | |||
var request = new RestRequest(path, GetMethod(method)); | |||
request.AddParameter("application/json", json, ParameterType.RequestBody); | |||
return Send(request, cancelToken); | |||
} | |||
public Task<string> SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken) | |||
private Task<string> SendFileInternal(HttpMethod method, string path, string filePath, CancellationToken cancelToken) | |||
{ | |||
var request = new RestRequest(path, Method.POST); | |||
request.AddFile("file", filePath); |
@@ -1,32 +1,25 @@ | |||
using Newtonsoft.Json; | |||
using Discord.API; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Diagnostics; | |||
using System.Net.Http; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord.API | |||
namespace Discord.Net | |||
{ | |||
internal interface IRestEngine | |||
{ | |||
void SetToken(string token); | |||
Task<string> Send(HttpMethod method, string path, string json, CancellationToken cancelToken); | |||
Task<string> SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken); | |||
} | |||
internal partial class RestClient | |||
{ | |||
private readonly IRestEngine _engine; | |||
private readonly LogMessageSeverity _logLevel; | |||
private CancellationToken _cancelToken; | |||
public RestClient(LogMessageSeverity logLevel, string userAgent, int timeout) | |||
{ | |||
_logLevel = logLevel; | |||
_engine = new RestSharpRestEngine(userAgent, timeout); | |||
} | |||
partial void Initialize(string userAgent, int timeout); | |||
//DELETE | |||
private static readonly HttpMethod _delete = HttpMethod.Delete; | |||
internal Task<ResponseT> Delete<ResponseT>(string path, object data) where ResponseT : class | |||
=> Send<ResponseT>(_delete, path, data); | |||
@@ -37,12 +30,14 @@ namespace Discord.API | |||
internal Task Delete(string path) | |||
=> Send(_delete, path); | |||
//GET | |||
private static readonly HttpMethod _get = HttpMethod.Get; | |||
internal Task<ResponseT> Get<ResponseT>(string path) where ResponseT : class | |||
=> Send<ResponseT>(_get, path); | |||
internal Task Get(string path) | |||
=> Send(_get, path); | |||
//PATCH | |||
private static readonly HttpMethod _patch = new HttpMethod("PATCH"); | |||
internal Task<ResponseT> Patch<ResponseT>(string path, object data) where ResponseT : class | |||
=> Send<ResponseT>(_patch, path, data); | |||
@@ -97,7 +92,7 @@ namespace Discord.API | |||
if (_logLevel >= LogMessageSeverity.Verbose) | |||
stopwatch = Stopwatch.StartNew(); | |||
string responseJson = await _engine.Send(method, path, requestJson, _cancelToken).ConfigureAwait(false); | |||
string responseJson = await SendInternal(method, path, requestJson, _cancelToken).ConfigureAwait(false); | |||
#if TEST_RESPONSES | |||
if (!hasResponse && !string.IsNullOrEmpty(responseJson)) | |||
@@ -136,7 +131,7 @@ namespace Discord.API | |||
if (_logLevel >= LogMessageSeverity.Verbose) | |||
stopwatch = Stopwatch.StartNew(); | |||
string responseJson = await _engine.SendFile(method, path, filePath, _cancelToken).ConfigureAwait(false); | |||
string responseJson = await SendFileInternal(method, path, filePath, _cancelToken).ConfigureAwait(false); | |||
#if TEST_RESPONSES | |||
if (!hasResponse && !string.IsNullOrEmpty(responseJson)) | |||
@@ -173,7 +168,6 @@ namespace Discord.API | |||
#endif | |||
} | |||
internal void SetToken(string token) => _engine.SetToken(token); | |||
internal void SetCancelToken(CancellationToken token) => _cancelToken = token; | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Threading; | |||
namespace Discord.WebSockets.Voice | |||
namespace Discord.Net | |||
{ | |||
internal class VoiceBuffer : IDiscordVoiceBuffer | |||
{ | |||
@@ -46,7 +46,11 @@ namespace Discord.WebSockets.Voice | |||
if (_readCursor == nextPosition) | |||
{ | |||
_notOverflowEvent.Reset(); | |||
_notOverflowEvent.Wait(cancelToken); | |||
try | |||
{ | |||
_notOverflowEvent.Wait(cancelToken); | |||
} | |||
catch (OperationCanceledException) { return; } | |||
} | |||
if (i == wholeFrames) | |||
@@ -100,7 +104,11 @@ namespace Discord.WebSockets.Voice | |||
_isClearing = true; | |||
for (int i = 0; i < _frameCount; i++) | |||
Buffer.BlockCopy(_blankFrame, 0, _buffer, i * _frameCount, i++); | |||
_underflowEvent.Wait(cancelToken); | |||
try | |||
{ | |||
_underflowEvent.Wait(cancelToken); | |||
} | |||
catch (OperationCanceledException) { } | |||
_writeCursor = 0; | |||
_readCursor = 0; | |||
_isClearing = false; |
@@ -1,6 +1,6 @@ | |||
using System; | |||
namespace Discord.WebSockets.Voice | |||
namespace Discord.Net | |||
{ | |||
internal sealed class IsTalkingEventArgs : EventArgs | |||
{ |
@@ -1,5 +1,6 @@ | |||
#define USE_THREAD | |||
using Discord.Audio; | |||
using Discord.API; | |||
using Discord.Interop; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using System; | |||
@@ -13,7 +14,7 @@ using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord.WebSockets.Voice | |||
namespace Discord.Net | |||
{ | |||
internal partial class VoiceWebSocket : WebSocket | |||
{ | |||
@@ -109,8 +110,8 @@ namespace Discord.WebSockets.Voice | |||
#if !DNX451 && !__MonoCS__ | |||
_udp.AllowNatTraversal(true); | |||
#endif | |||
LoginCommand msg = new LoginCommand(); | |||
VoiceLoginCommand msg = new VoiceLoginCommand(); | |||
msg.Payload.ServerId = _serverId; | |||
msg.Payload.SessionId = _sessionId; | |||
msg.Payload.Token = _token; | |||
@@ -238,7 +239,7 @@ namespace Discord.WebSockets.Voice | |||
int port = packet[68] | packet[69] << 8; | |||
string ip = Encoding.ASCII.GetString(packet, 4, 70 - 6).TrimEnd('\0'); | |||
var login2 = new Login2Command(); | |||
var login2 = new VoiceLogin2Command(); | |||
login2.Payload.Protocol = "udp"; | |||
login2.Payload.SocketData.Address = ip; | |||
login2.Payload.SocketData.Mode = _encryptionMode; | |||
@@ -458,7 +459,7 @@ namespace Discord.WebSockets.Voice | |||
{ | |||
if (_state != (int)WebSocketState.Connected) | |||
{ | |||
var payload = (msg.Payload as JToken).ToObject<ReadyEvent>(); | |||
var payload = (msg.Payload as JToken).ToObject<VoiceReadyEvent>(); | |||
_heartbeatInterval = payload.HeartbeatInterval; | |||
_ssrc = payload.SSRC; | |||
_endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port); |
@@ -1,5 +1,4 @@ | |||
/* | |||
using Discord.Helpers; | |||
using Discord.Helpers; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
@@ -149,5 +148,4 @@ namespace Discord.WebSockets | |||
_sendQueue.Enqueue(message); | |||
} | |||
} | |||
} | |||
*/ | |||
} |
@@ -1,6 +1,6 @@ | |||
using System; | |||
namespace Discord.WebSockets | |||
namespace Discord.Net | |||
{ | |||
internal abstract partial class WebSocket | |||
{ |
@@ -5,7 +5,7 @@ using System.Threading; | |||
using System.Threading.Tasks; | |||
using WSSharpNWebSocket = WebSocketSharp.WebSocket; | |||
namespace Discord.WebSockets | |||
namespace Discord.Net | |||
{ | |||
internal class WSSharpWebSocketEngine : IWebSocketEngine | |||
{ |
@@ -6,7 +6,7 @@ using System.Runtime.ExceptionServices; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace Discord.WebSockets | |||
namespace Discord.Net | |||
{ | |||
public enum WebSocketState : byte | |||
{ |
@@ -1,64 +0,0 @@ | |||
//Ignore unused/unassigned variable warnings | |||
#pragma warning disable CS0649 | |||
#pragma warning disable CS0169 | |||
using Newtonsoft.Json; | |||
using System.Collections.Generic; | |||
namespace Discord.WebSockets.Data | |||
{ | |||
internal sealed class KeepAliveCommand : WebSocketMessage<ulong> | |||
{ | |||
public KeepAliveCommand() : base(1, EpochTime.GetMilliseconds()) { } | |||
} | |||
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 ulong? IdleSince; | |||
[JsonProperty("game_id")] | |||
public int? 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,115 +0,0 @@ | |||
//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; | |||
} | |||
} |
@@ -1,59 +0,0 @@ | |||
//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; | |||
} | |||
} | |||
} |
@@ -1,38 +0,0 @@ | |||
//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,31 +0,0 @@ | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
namespace Discord.WebSockets | |||
{ | |||
public class WebSocketMessage | |||
{ | |||
[JsonProperty("op")] | |||
public int Operation; | |||
[JsonProperty("d")] | |||
public object Payload; | |||
[JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)] | |||
public string Type; | |||
[JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)] | |||
public int? Sequence; | |||
} | |||
internal abstract class WebSocketMessage<T> : WebSocketMessage | |||
where T : new() | |||
{ | |||
public WebSocketMessage() { Payload = new T(); } | |||
public WebSocketMessage(int op) { Operation = op; Payload = new T(); } | |||
public WebSocketMessage(int op, T payload) { Operation = op; Payload = payload; } | |||
[JsonIgnore] | |||
public new T Payload | |||
{ | |||
get { if (base.Payload is JToken) { base.Payload = (base.Payload as JToken).ToObject<T>(); } return (T)base.Payload; } | |||
set { base.Payload = value; } | |||
} | |||
} | |||
} |
@@ -1,4 +0,0 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" /> | |||
</packages> |