diff --git a/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs b/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs
new file mode 100644
index 000000000..8fdb0808f
--- /dev/null
+++ b/src/Discord.Net.WebSocket/API/Voice/HelloEvent.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace Discord.API.Voice
+{
+ internal class HelloEvent
+ {
+ [JsonProperty("heartbeat_interval")]
+ public int HeartbeatInterval { get; set; }
+ }
+}
diff --git a/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs b/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
index 2a134ced1..7188cd8f7 100644
--- a/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
+++ b/src/Discord.Net.WebSocket/API/Voice/ReadyEvent.cs
@@ -1,5 +1,6 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
+using System;
namespace Discord.API.Voice
{
@@ -14,6 +15,7 @@ namespace Discord.API.Voice
[JsonProperty("modes")]
public string[] Modes { get; set; }
[JsonProperty("heartbeat_interval")]
+ [Obsolete("This field is errorneous and should not be used", true)]
public int HeartbeatInterval { get; set; }
}
}
diff --git a/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs b/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
index ae11a4c8f..67afe6173 100644
--- a/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
+++ b/src/Discord.Net.WebSocket/API/Voice/VoiceOpCode.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
namespace Discord.API.Voice
{
internal enum VoiceOpCode : byte
@@ -11,11 +11,19 @@ namespace Discord.API.Voice
Ready = 2,
/// C→S - Used to keep the connection alive and measure latency.
Heartbeat = 3,
- /// C←S - Used to reply to a client's heartbeat.
- HeartbeatAck = 3,
/// C←S - Used to provide an encryption key to the client.
SessionDescription = 4,
/// C↔S - Used to inform that a certain user is speaking.
- Speaking = 5
+ Speaking = 5,
+ /// C←S - Used to reply to a client's heartbeat.
+ HeartbeatAck = 6,
+ /// C→S - Used to resume a connection.
+ Resume = 7,
+ /// C←S - Used to inform the client the heartbeat interval.
+ Hello = 8,
+ /// C←S - Used to acknowledge a resumed connection.
+ Resumed = 9,
+ /// C←S - Used to notify that a client has disconnected.
+ ClientDisconnect = 13,
}
}
diff --git a/src/Discord.Net.WebSocket/Audio/AudioClient.cs b/src/Discord.Net.WebSocket/Audio/AudioClient.cs
index 1f33b3cc5..4e10d0c54 100644
--- a/src/Discord.Net.WebSocket/Audio/AudioClient.cs
+++ b/src/Discord.Net.WebSocket/Audio/AudioClient.cs
@@ -1,4 +1,4 @@
-using Discord.API.Voice;
+using Discord.API.Voice;
using Discord.Audio.Streams;
using Discord.Logging;
using Discord.Net.Converters;
@@ -107,7 +107,7 @@ namespace Discord.Audio
private async Task OnConnectingAsync()
{
await _audioLogger.DebugAsync("Connecting ApiClient").ConfigureAwait(false);
- await ApiClient.ConnectAsync("wss://" + _url).ConfigureAwait(false);
+ await ApiClient.ConnectAsync("wss://" + _url + "?v=3").ConfigureAwait(false);
await _audioLogger.DebugAsync("Listening on port " + ApiClient.UdpPort).ConfigureAwait(false);
await _audioLogger.DebugAsync("Sending Identity").ConfigureAwait(false);
await ApiClient.SendIdentityAsync(_userId, _sessionId, _token).ConfigureAwait(false);
@@ -216,6 +216,14 @@ namespace Discord.Audio
{
switch (opCode)
{
+ case VoiceOpCode.Hello:
+ {
+ await _audioLogger.DebugAsync("Received Hello").ConfigureAwait(false);
+ var data = (payload as JToken).ToObject(_serializer);
+
+ _heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _connection.CancelToken);
+ }
+ break;
case VoiceOpCode.Ready:
{
await _audioLogger.DebugAsync("Received Ready").ConfigureAwait(false);
@@ -225,8 +233,6 @@ namespace Discord.Audio
if (!data.Modes.Contains(DiscordVoiceAPIClient.Mode))
throw new InvalidOperationException($"Discord does not support {DiscordVoiceAPIClient.Mode}");
-
- _heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _connection.CancelToken);
ApiClient.SetUdpEndpoint(data.Ip, data.Port);
await ApiClient.SendDiscoveryAsync(_ssrc).ConfigureAwait(false);