| @@ -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> | |||