| @@ -43,8 +43,11 @@ | |||||
| <Reference Include="System" /> | <Reference Include="System" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <Compile Include="..\Discord.Net.Audio\API\Voice.cs"> | |||||
| <Link>API\Voice.cs</Link> | |||||
| <Compile Include="..\Discord.Net.Audio\API\Messages\GatewaySocket.cs"> | |||||
| <Link>API\Messages\GatewaySocket.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net.Audio\API\Messages\VoiceSocket.cs"> | |||||
| <Link>API\Messages\VoiceSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net.Audio\AudioExtensions.cs"> | <Compile Include="..\Discord.Net.Audio\AudioExtensions.cs"> | ||||
| <Link>AudioExtensions.cs</Link> | <Link>AudioExtensions.cs</Link> | ||||
| @@ -58,11 +61,11 @@ | |||||
| <Compile Include="..\Discord.Net.Audio\DiscordAudioClient.cs"> | <Compile Include="..\Discord.Net.Audio\DiscordAudioClient.cs"> | ||||
| <Link>DiscordAudioClient.cs</Link> | <Link>DiscordAudioClient.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net.Audio\Net\VoiceWebSocket.cs"> | |||||
| <Link>Net\VoiceWebSocket.cs</Link> | |||||
| <Compile Include="..\Discord.Net.Audio\Net\WebSockets\VoiceWebSocket.cs"> | |||||
| <Link>Net\WebSockets\VoiceWebSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net.Audio\Net\VoiceWebSocket.Events.cs"> | |||||
| <Link>Net\VoiceWebSocket.Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net.Audio\Net\WebSockets\VoiceWebSocket.Events.cs"> | |||||
| <Link>Net\WebSockets\VoiceWebSocket.Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net.Audio\Opus.cs"> | <Compile Include="..\Discord.Net.Audio\Opus.cs"> | ||||
| <Link>Opus.cs</Link> | <Link>Opus.cs</Link> | ||||
| @@ -0,0 +1,20 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Discord.API.Converters; | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.Audio.API | |||||
| { | |||||
| internal sealed class VoiceServerUpdateEvent | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ServerId; | |||||
| [JsonProperty("endpoint")] | |||||
| public string Endpoint; | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| @@ -149,7 +149,7 @@ namespace Discord.Audio | |||||
| { | { | ||||
| int id = unchecked(++_nextClientId); | int id = unchecked(++_nextClientId); | ||||
| var logger = Client.Log().CreateLogger($"Voice #{id}"); | var logger = Client.Log().CreateLogger($"Voice #{id}"); | ||||
| GatewayWebSocket dataSocket = null; | |||||
| GatewayWebSocket gatewaySocket = null; | |||||
| var voiceSocket = new VoiceWebSocket(Client.Config, _config, logger); | var voiceSocket = new VoiceWebSocket(Client.Config, _config, logger); | ||||
| var voiceClient = new DiscordAudioClient(this, id, logger, gatewaySocket, voiceSocket); | var voiceClient = new DiscordAudioClient(this, id, logger, gatewaySocket, voiceSocket); | ||||
| voiceClient.SetServerId(server.Id); | voiceClient.SetServerId(server.Id); | ||||
| @@ -59,7 +59,7 @@ namespace Discord.Audio | |||||
| _voiceSocket.ParentCancelToken = _cancelToken; | _voiceSocket.ParentCancelToken = _cancelToken; | ||||
| };*/ | };*/ | ||||
| _gatewaySocket.ReceivedEvent += async (s, e) => | |||||
| _gatewaySocket.ReceivedDispatch += async (s, e) => | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| @@ -527,9 +527,9 @@ namespace Discord.Net.WebSockets | |||||
| QueueMessage(isTalking); | QueueMessage(isTalking); | ||||
| } | } | ||||
| protected override object GetKeepAlive() | |||||
| public override void SendHeartbeat() | |||||
| { | { | ||||
| return new VoiceKeepAliveCommand(); | |||||
| QueueMessage(new VoiceKeepAliveCommand()); | |||||
| } | } | ||||
| public void WaitForQueue() | public void WaitForQueue() | ||||
| @@ -68,15 +68,6 @@ | |||||
| </Reference> | </Reference> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <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\Converters\LongCollectionConverter.cs"> | <Compile Include="..\Discord.Net\API\Converters\LongCollectionConverter.cs"> | ||||
| <Link>API\Converters\LongCollectionConverter.cs</Link> | <Link>API\Converters\LongCollectionConverter.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -101,38 +92,38 @@ | |||||
| <Compile Include="..\Discord.Net\API\Enums\UserStatus.cs"> | <Compile Include="..\Discord.Net\API\Enums\UserStatus.cs"> | ||||
| <Link>API\Enums\UserStatus.cs</Link> | <Link>API\Enums\UserStatus.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Invites.cs"> | |||||
| <Link>API\Invites.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Auth.cs"> | |||||
| <Link>API\Messages\Auth.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Maintenance.cs"> | |||||
| <Link>API\Maintenance.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Channels.cs"> | |||||
| <Link>API\Messages\Channels.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Members.cs"> | |||||
| <Link>API\Members.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\GatewaySocket.cs"> | |||||
| <Link>API\Messages\GatewaySocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Messages.cs"> | |||||
| <Link>API\Messages.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Invites.cs"> | |||||
| <Link>API\Messages\Invites.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Permissions.cs"> | |||||
| <Link>API\Permissions.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Maintenance.cs"> | |||||
| <Link>API\Messages\Maintenance.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Presence.cs"> | |||||
| <Link>API\Presence.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Members.cs"> | |||||
| <Link>API\Messages\Members.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Roles.cs"> | |||||
| <Link>API\Roles.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Messages.cs"> | |||||
| <Link>API\Messages\Messages.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Servers.cs"> | |||||
| <Link>API\Servers.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Permissions.cs"> | |||||
| <Link>API\Messages\Permissions.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Users.cs"> | |||||
| <Link>API\Users.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Roles.cs"> | |||||
| <Link>API\Messages\Roles.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\Voice.cs"> | |||||
| <Link>API\Voice.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Servers.cs"> | |||||
| <Link>API\Messages\Servers.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\API\WebSockets.cs"> | |||||
| <Link>API\WebSockets.cs</Link> | |||||
| <Compile Include="..\Discord.Net\API\Messages\Users.cs"> | |||||
| <Link>API\Messages\Users.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\DiscordAPIClient.cs"> | <Compile Include="..\Discord.Net\DiscordAPIClient.cs"> | ||||
| <Link>DiscordAPIClient.cs</Link> | <Link>DiscordAPIClient.cs</Link> | ||||
| @@ -239,11 +230,11 @@ | |||||
| <Compile Include="..\Discord.Net\Net\Rest\SharpRestEngine.cs"> | <Compile Include="..\Discord.Net\Net\Rest\SharpRestEngine.cs"> | ||||
| <Link>Net\Rest\SharpRestEngine.cs</Link> | <Link>Net\Rest\SharpRestEngine.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\DataWebSocket.cs"> | |||||
| <Link>Net\WebSockets\DataWebSocket.cs</Link> | |||||
| <Compile Include="..\Discord.Net\Net\WebSockets\GatewayWebSocket.cs"> | |||||
| <Link>Net\WebSockets\GatewayWebSocket.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\DataWebSockets.Events.cs"> | |||||
| <Link>Net\WebSockets\DataWebSockets.Events.cs</Link> | |||||
| <Compile Include="..\Discord.Net\Net\WebSockets\GatewayWebSockets.Events.cs"> | |||||
| <Link>Net\WebSockets\GatewayWebSockets.Events.cs</Link> | |||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\IWebSocketEngine.cs"> | <Compile Include="..\Discord.Net\Net\WebSockets\IWebSocketEngine.cs"> | ||||
| <Link>Net\WebSockets\IWebSocketEngine.cs</Link> | <Link>Net\WebSockets\IWebSocketEngine.cs</Link> | ||||
| @@ -2,12 +2,26 @@ | |||||
| #pragma warning disable CS0649 | #pragma warning disable CS0649 | ||||
| #pragma warning disable CS0169 | #pragma warning disable CS0169 | ||||
| using Discord.API.Converters; | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| namespace Discord.API | namespace Discord.API | ||||
| { | { | ||||
| public enum GatewayOpCodes : byte | |||||
| { | |||||
| Dispatch = 0, | |||||
| Heartbeat = 1, | |||||
| Identify = 2, | |||||
| StatusUpdate = 3, | |||||
| VoiceStateUpdate = 4, | |||||
| //VoiceServerPing = 5, (Unused?) | |||||
| Resume = 6, | |||||
| Redirect = 7, | |||||
| RequestGuildMembers = 8 | |||||
| } | |||||
| //Common | //Common | ||||
| public class WebSocketMessage | public class WebSocketMessage | ||||
| { | { | ||||
| @@ -44,13 +58,13 @@ namespace Discord.API | |||||
| } | } | ||||
| //Commands | //Commands | ||||
| internal sealed class KeepAliveCommand : WebSocketMessage<long> | |||||
| internal sealed class HeartbeatCommand : WebSocketMessage<long> | |||||
| { | { | ||||
| public KeepAliveCommand() : base(1, EpochTime.GetMilliseconds()) { } | |||||
| public HeartbeatCommand() : base((int)GatewayOpCodes.Heartbeat, EpochTime.GetMilliseconds()) { } | |||||
| } | } | ||||
| internal sealed class LoginCommand : WebSocketMessage<LoginCommand.Data> | |||||
| internal sealed class IdentifyCommand : WebSocketMessage<IdentifyCommand.Data> | |||||
| { | { | ||||
| public LoginCommand() : base(2) { } | |||||
| public IdentifyCommand() : base((int)GatewayOpCodes.Identify) { } | |||||
| public class Data | public class Data | ||||
| { | { | ||||
| [JsonProperty("token")] | [JsonProperty("token")] | ||||
| @@ -65,9 +79,43 @@ namespace Discord.API | |||||
| public bool? Compress; | public bool? Compress; | ||||
| } | } | ||||
| } | } | ||||
| internal sealed class StatusUpdateCommand : WebSocketMessage<StatusUpdateCommand.Data> | |||||
| { | |||||
| public StatusUpdateCommand() : base((int)GatewayOpCodes.StatusUpdate) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("idle_since")] | |||||
| public long? IdleSince; | |||||
| [JsonProperty("game_id")] | |||||
| public int? GameId; | |||||
| } | |||||
| } | |||||
| //Commands | |||||
| internal sealed class JoinVoiceCommand : WebSocketMessage<JoinVoiceCommand.Data> | |||||
| { | |||||
| public JoinVoiceCommand() : base((int)GatewayOpCodes.VoiceStateUpdate) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ServerId; | |||||
| [JsonProperty("channel_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ChannelId; | |||||
| [JsonProperty("self_mute")] | |||||
| public string SelfMute; | |||||
| [JsonProperty("self_deaf")] | |||||
| public string SelfDeaf; | |||||
| } | |||||
| } | |||||
| //Events | |||||
| internal sealed class ResumeCommand : WebSocketMessage<ResumeCommand.Data> | internal sealed class ResumeCommand : WebSocketMessage<ResumeCommand.Data> | ||||
| { | { | ||||
| public ResumeCommand() : base(6) { } | |||||
| public ResumeCommand() : base((int)GatewayOpCodes.Resume) { } | |||||
| public class Data | public class Data | ||||
| { | { | ||||
| [JsonProperty("session_id")] | [JsonProperty("session_id")] | ||||
| @@ -105,15 +153,15 @@ namespace Discord.API | |||||
| [JsonProperty("heartbeat_interval")] | [JsonProperty("heartbeat_interval")] | ||||
| public int HeartbeatInterval; | public int HeartbeatInterval; | ||||
| } | } | ||||
| internal sealed class ResumedEvent | |||||
| { | |||||
| [JsonProperty("heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| internal sealed class RedirectEvent | internal sealed class RedirectEvent | ||||
| { | { | ||||
| [JsonProperty("url")] | [JsonProperty("url")] | ||||
| public string Url; | public string Url; | ||||
| } | } | ||||
| internal sealed class ResumeEvent | |||||
| { | |||||
| [JsonProperty("heartbeat_interval")] | |||||
| public int HeartbeatInterval; | |||||
| } | |||||
| } | } | ||||
| @@ -5,6 +5,7 @@ | |||||
| using Discord.API.Converters; | using Discord.API.Converters; | ||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System; | using System; | ||||
| using System.Collections.Generic; | |||||
| namespace Discord.API | namespace Discord.API | ||||
| { | { | ||||
| @@ -85,6 +86,21 @@ namespace Discord.API | |||||
| //Delete | //Delete | ||||
| public sealed class DeleteServerResponse : GuildInfo { } | public sealed class DeleteServerResponse : GuildInfo { } | ||||
| //GetRegions | |||||
| 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; | |||||
| } | |||||
| } | |||||
| //Events | //Events | ||||
| internal sealed class GuildCreateEvent : ExtendedGuildInfo { } | internal sealed class GuildCreateEvent : ExtendedGuildInfo { } | ||||
| internal sealed class GuildUpdateEvent : GuildInfo { } | internal sealed class GuildUpdateEvent : GuildInfo { } | ||||
| @@ -46,6 +46,18 @@ namespace Discord.API | |||||
| //Events | //Events | ||||
| internal sealed class UserUpdateEvent : UserInfo { } | internal sealed class UserUpdateEvent : UserInfo { } | ||||
| internal sealed class PresenceUpdateEvent : PresenceInfo { } | |||||
| internal sealed class TypingStartEvent | |||||
| { | |||||
| [JsonProperty("user_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long UserId; | |||||
| [JsonProperty("channel_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ChannelId; | |||||
| [JsonProperty("timestamp")] | |||||
| public int Timestamp; | |||||
| } | |||||
| internal sealed class BanAddEvent : MemberReference { } | internal sealed class BanAddEvent : MemberReference { } | ||||
| internal sealed class BanRemoveEvent : MemberReference { } | internal sealed class BanRemoveEvent : MemberReference { } | ||||
| } | } | ||||
| @@ -1,36 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Discord.API.Converters; | |||||
| 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 long? IdleSince; | |||||
| [JsonProperty("game_id")] | |||||
| public int? GameId; | |||||
| } | |||||
| } | |||||
| //Events | |||||
| internal sealed class TypingStartEvent | |||||
| { | |||||
| [JsonProperty("user_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long UserId; | |||||
| [JsonProperty("channel_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ChannelId; | |||||
| [JsonProperty("timestamp")] | |||||
| public int Timestamp; | |||||
| } | |||||
| internal sealed class PresenceUpdateEvent : PresenceInfo { } | |||||
| } | |||||
| @@ -1,56 +0,0 @@ | |||||
| //Ignore unused/unassigned variable warnings | |||||
| #pragma warning disable CS0649 | |||||
| #pragma warning disable CS0169 | |||||
| using Discord.API.Converters; | |||||
| 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; | |||||
| } | |||||
| } | |||||
| //Commands | |||||
| internal sealed class JoinVoiceCommand : WebSocketMessage<JoinVoiceCommand.Data> | |||||
| { | |||||
| public JoinVoiceCommand() : base(4) { } | |||||
| public class Data | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ServerId; | |||||
| [JsonProperty("channel_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ChannelId; | |||||
| [JsonProperty("self_mute")] | |||||
| public string SelfMute; | |||||
| [JsonProperty("self_deaf")] | |||||
| public string SelfDeaf; | |||||
| } | |||||
| } | |||||
| //Events | |||||
| internal sealed class VoiceServerUpdateEvent | |||||
| { | |||||
| [JsonProperty("guild_id")] | |||||
| [JsonConverter(typeof(LongStringConverter))] | |||||
| public long ServerId; | |||||
| [JsonProperty("endpoint")] | |||||
| public string Endpoint; | |||||
| [JsonProperty("token")] | |||||
| public string Token; | |||||
| } | |||||
| } | |||||
| @@ -302,7 +302,7 @@ namespace Discord | |||||
| } | } | ||||
| private Task SendStatus() | private Task SendStatus() | ||||
| { | { | ||||
| _webSocket.SendStatus(_status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (long?)null, _gameId); | |||||
| _webSocket.SendStatusUpdate(_status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (long?)null, _gameId); | |||||
| return TaskHelper.CompletedTask; | return TaskHelper.CompletedTask; | ||||
| } | } | ||||
| } | } | ||||
| @@ -273,7 +273,7 @@ namespace Discord | |||||
| await socket.Reconnect(_token).ConfigureAwait(false); | await socket.Reconnect(_token).ConfigureAwait(false); | ||||
| }; | }; | ||||
| socket.ReceivedEvent += async (s, e) => await OnReceivedEvent(e).ConfigureAwait(false); | |||||
| socket.ReceivedDispatch += async (s, e) => await OnReceivedEvent(e).ConfigureAwait(false); | |||||
| return socket; | return socket; | ||||
| } | } | ||||
| @@ -8,19 +8,6 @@ namespace Discord.Net.WebSockets | |||||
| { | { | ||||
| public partial class GatewayWebSocket : WebSocket | public partial class GatewayWebSocket : WebSocket | ||||
| { | { | ||||
| internal enum OpCodes : byte | |||||
| { | |||||
| Dispatch = 0, | |||||
| Heartbeat = 1, | |||||
| Identify = 2, | |||||
| StatusUpdate = 3, | |||||
| VoiceStateUpdate = 4, | |||||
| VoiceServerPing = 5, | |||||
| Resume = 6, | |||||
| Redirect = 7, | |||||
| RequestGuildMembers = 8 | |||||
| } | |||||
| private int _lastSeq; | private int _lastSeq; | ||||
| public string SessionId => _sessionId; | public string SessionId => _sessionId; | ||||
| @@ -35,14 +22,8 @@ namespace Discord.Net.WebSockets | |||||
| { | { | ||||
| await BeginConnect().ConfigureAwait(false); | await BeginConnect().ConfigureAwait(false); | ||||
| await Start().ConfigureAwait(false); | await Start().ConfigureAwait(false); | ||||
| LoginCommand msg = new LoginCommand(); | |||||
| msg.Payload.Token = token; | |||||
| msg.Payload.Properties["$device"] = "Discord.Net"; | |||||
| if (_config.UseLargeThreshold) | |||||
| msg.Payload.LargeThreshold = 100; | |||||
| msg.Payload.Compress = true; | |||||
| QueueMessage(msg); | |||||
| SendIdentify(token); | |||||
| } | } | ||||
| private async Task Redirect(string server) | private async Task Redirect(string server) | ||||
| { | { | ||||
| @@ -51,10 +32,7 @@ namespace Discord.Net.WebSockets | |||||
| await BeginConnect().ConfigureAwait(false); | await BeginConnect().ConfigureAwait(false); | ||||
| await Start().ConfigureAwait(false); | await Start().ConfigureAwait(false); | ||||
| var resumeMsg = new ResumeCommand(); | |||||
| resumeMsg.Payload.SessionId = _sessionId; | |||||
| resumeMsg.Payload.Sequence = _lastSeq; | |||||
| QueueMessage(resumeMsg); | |||||
| SendResume(); | |||||
| } | } | ||||
| public async Task Reconnect(string token) | public async Task Reconnect(string token) | ||||
| { | { | ||||
| @@ -88,10 +66,10 @@ namespace Discord.Net.WebSockets | |||||
| if (msg.Sequence.HasValue) | if (msg.Sequence.HasValue) | ||||
| _lastSeq = msg.Sequence.Value; | _lastSeq = msg.Sequence.Value; | ||||
| var opCode = (OpCodes)msg.Operation; | |||||
| var opCode = (GatewayOpCodes)msg.Operation; | |||||
| switch (opCode) | switch (opCode) | ||||
| { | { | ||||
| case OpCodes.Dispatch: | |||||
| case GatewayOpCodes.Dispatch: | |||||
| { | { | ||||
| JToken token = msg.Payload as JToken; | JToken token = msg.Payload as JToken; | ||||
| if (msg.Type == "READY") | if (msg.Type == "READY") | ||||
| @@ -102,15 +80,15 @@ namespace Discord.Net.WebSockets | |||||
| } | } | ||||
| else if (msg.Type == "RESUMED") | else if (msg.Type == "RESUMED") | ||||
| { | { | ||||
| var payload = token.ToObject<ResumedEvent>(_serializer); | |||||
| var payload = token.ToObject<ResumeEvent>(_serializer); | |||||
| _heartbeatInterval = payload.HeartbeatInterval; | _heartbeatInterval = payload.HeartbeatInterval; | ||||
| } | } | ||||
| RaiseReceivedEvent(msg.Type, token); | |||||
| RaiseReceivedDispatch(msg.Type, token); | |||||
| if (msg.Type == "READY" || msg.Type == "RESUMED") | if (msg.Type == "READY" || msg.Type == "RESUMED") | ||||
| EndConnect(); | EndConnect(); | ||||
| } | } | ||||
| break; | break; | ||||
| case OpCodes.Redirect: | |||||
| case GatewayOpCodes.Redirect: | |||||
| { | { | ||||
| var payload = (msg.Payload as JToken).ToObject<RedirectEvent>(_serializer); | var payload = (msg.Payload as JToken).ToObject<RedirectEvent>(_serializer); | ||||
| if (payload.Url != null) | if (payload.Url != null) | ||||
| @@ -129,14 +107,33 @@ namespace Discord.Net.WebSockets | |||||
| } | } | ||||
| } | } | ||||
| protected override object GetKeepAlive() | |||||
| public void SendIdentify(string token) | |||||
| { | { | ||||
| return new KeepAliveCommand(); | |||||
| IdentifyCommand msg = new IdentifyCommand(); | |||||
| msg.Payload.Token = token; | |||||
| msg.Payload.Properties["$device"] = "Discord.Net"; | |||||
| if (_config.UseLargeThreshold) | |||||
| msg.Payload.LargeThreshold = 100; | |||||
| msg.Payload.Compress = true; | |||||
| QueueMessage(msg); | |||||
| } | } | ||||
| public void SendStatus(long? idleSince, int? gameId) | |||||
| public void SendResume() | |||||
| { | { | ||||
| var updateStatus = new UpdateStatusCommand(); | |||||
| var resumeMsg = new ResumeCommand(); | |||||
| resumeMsg.Payload.SessionId = _sessionId; | |||||
| resumeMsg.Payload.Sequence = _lastSeq; | |||||
| QueueMessage(resumeMsg); | |||||
| } | |||||
| public override void SendHeartbeat() | |||||
| { | |||||
| QueueMessage(new HeartbeatCommand()); | |||||
| } | |||||
| public void SendStatusUpdate(long? idleSince, int? gameId) | |||||
| { | |||||
| var updateStatus = new StatusUpdateCommand(); | |||||
| updateStatus.Payload.IdleSince = idleSince; | updateStatus.Payload.IdleSince = idleSince; | ||||
| updateStatus.Payload.GameId = gameId; | updateStatus.Payload.GameId = gameId; | ||||
| QueueMessage(updateStatus); | QueueMessage(updateStatus); | ||||
| @@ -155,6 +152,7 @@ namespace Discord.Net.WebSockets | |||||
| leaveVoice.Payload.ServerId = serverId; | leaveVoice.Payload.ServerId = serverId; | ||||
| QueueMessage(leaveVoice); | QueueMessage(leaveVoice); | ||||
| } | } | ||||
| public void SendRequestUsers(long serverId, string query = "", int limit = 0) | public void SendRequestUsers(long serverId, string query = "", int limit = 0) | ||||
| { | { | ||||
| var getOfflineUsers = new GetUsersCommand(); | var getOfflineUsers = new GetUsersCommand(); | ||||
| @@ -16,11 +16,11 @@ namespace Discord.Net.WebSockets | |||||
| public partial class GatewayWebSocket | public partial class GatewayWebSocket | ||||
| { | { | ||||
| public event EventHandler<WebSocketEventEventArgs> ReceivedEvent; | |||||
| private void RaiseReceivedEvent(string type, JToken payload) | |||||
| public event EventHandler<WebSocketEventEventArgs> ReceivedDispatch; | |||||
| private void RaiseReceivedDispatch(string type, JToken payload) | |||||
| { | { | ||||
| if (ReceivedEvent != null) | |||||
| ReceivedEvent(this, new WebSocketEventEventArgs(type, payload)); | |||||
| if (ReceivedDispatch != null) | |||||
| ReceivedDispatch(this, new WebSocketEventEventArgs(type, payload)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -243,7 +243,6 @@ namespace Discord.Net.WebSockets | |||||
| _logger.Log(LogSeverity.Debug, $"In: {json}"); | _logger.Log(LogSeverity.Debug, $"In: {json}"); | ||||
| return TaskHelper.CompletedTask; | return TaskHelper.CompletedTask; | ||||
| } | } | ||||
| protected abstract object GetKeepAlive(); | |||||
| protected void QueueMessage(object message) | protected void QueueMessage(object message) | ||||
| { | { | ||||
| @@ -255,7 +254,7 @@ namespace Discord.Net.WebSockets | |||||
| private Task HeartbeatAsync(CancellationToken cancelToken) | private Task HeartbeatAsync(CancellationToken cancelToken) | ||||
| { | { | ||||
| return Task.Run(async () => | |||||
| return Task.Run((Func<Task>)(async () => | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| @@ -263,7 +262,7 @@ namespace Discord.Net.WebSockets | |||||
| { | { | ||||
| if (_state == (int)WebSocketState.Connected) | if (_state == (int)WebSocketState.Connected) | ||||
| { | { | ||||
| QueueMessage(GetKeepAlive()); | |||||
| SendHeartbeat(); | |||||
| await Task.Delay(_heartbeatInterval, cancelToken).ConfigureAwait(false); | await Task.Delay(_heartbeatInterval, cancelToken).ConfigureAwait(false); | ||||
| } | } | ||||
| else | else | ||||
| @@ -271,7 +270,7 @@ namespace Discord.Net.WebSockets | |||||
| } | } | ||||
| } | } | ||||
| catch (OperationCanceledException) { } | catch (OperationCanceledException) { } | ||||
| }); | |||||
| })); | |||||
| } | } | ||||
| protected internal void ThrowError() | protected internal void ThrowError() | ||||
| @@ -283,5 +282,7 @@ namespace Discord.Net.WebSockets | |||||
| reason.Throw(); | reason.Throw(); | ||||
| } | } | ||||
| } | } | ||||
| public abstract void SendHeartbeat(); | |||||
| } | } | ||||
| } | } | ||||