Reworked Rest system
This commit is contained in:
@@ -1,20 +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
|
||||
{
|
||||
internal sealed class VoiceServerUpdateEvent
|
||||
{
|
||||
[JsonProperty("guild_id")]
|
||||
[JsonConverter(typeof(LongStringConverter))]
|
||||
public ulong ServerId;
|
||||
[JsonProperty("endpoint")]
|
||||
public string Endpoint;
|
||||
[JsonProperty("token")]
|
||||
public string Token;
|
||||
}
|
||||
}
|
||||
@@ -1,111 +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
|
||||
{
|
||||
public enum VoiceOpCodes : byte
|
||||
{
|
||||
/// <summary> Client --> Server - Used to associate a connection with a token. </summary>
|
||||
Identify = 0,
|
||||
/// <summary> Client --> Server - Used to specify configuration. </summary>
|
||||
SelectProtocol = 1,
|
||||
/// <summary> Client <-- Server - Used to notify that the voice connection was successful and informs the client of available protocols. </summary>
|
||||
Ready = 2,
|
||||
/// <summary> Client <-> Server - Used to keep the connection alive and measure latency. </summary>
|
||||
Heartbeat = 3,
|
||||
/// <summary> Client <-- Server - Used to provide an encryption key to the client. </summary>
|
||||
SessionDescription = 4,
|
||||
/// <summary> Client <-> Server - Used to inform that a certain user is speaking. </summary>
|
||||
Speaking = 5
|
||||
}
|
||||
|
||||
//Commands
|
||||
internal sealed class IdentifyCommand : WebSocketMessage<IdentifyCommand.Data>
|
||||
{
|
||||
public IdentifyCommand() : base((int)VoiceOpCodes.Identify) { }
|
||||
public class Data
|
||||
{
|
||||
[JsonProperty("server_id")]
|
||||
[JsonConverter(typeof(LongStringConverter))]
|
||||
public ulong ServerId;
|
||||
[JsonProperty("user_id")]
|
||||
[JsonConverter(typeof(LongStringConverter))]
|
||||
public ulong UserId;
|
||||
[JsonProperty("session_id")]
|
||||
public string SessionId;
|
||||
[JsonProperty("token")]
|
||||
public string Token;
|
||||
}
|
||||
}
|
||||
internal sealed class SelectProtocolCommand : WebSocketMessage<SelectProtocolCommand.Data>
|
||||
{
|
||||
public SelectProtocolCommand() : base((int)VoiceOpCodes.SelectProtocol) { }
|
||||
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 HeartbeatCommand : WebSocketMessage<long>
|
||||
{
|
||||
public HeartbeatCommand() : base((int)VoiceOpCodes.Heartbeat, EpochTime.GetMilliseconds()) { }
|
||||
}
|
||||
internal sealed class SpeakingCommand : WebSocketMessage<SpeakingCommand.Data>
|
||||
{
|
||||
public SpeakingCommand() : base((int)VoiceOpCodes.Speaking) { }
|
||||
public class Data
|
||||
{
|
||||
[JsonProperty("delay")]
|
||||
public int Delay;
|
||||
[JsonProperty("speaking")]
|
||||
public bool IsSpeaking;
|
||||
}
|
||||
}
|
||||
|
||||
//Events
|
||||
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")]
|
||||
[JsonConverter(typeof(LongStringConverter))]
|
||||
public ulong UserId;
|
||||
[JsonProperty("ssrc")]
|
||||
public uint SSRC;
|
||||
[JsonProperty("speaking")]
|
||||
public bool IsSpeaking;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>dff7afe3-ca77-4109-bade-b4b49a4f6648</ProjectGuid>
|
||||
<RootNamespace>Discord.Audio</RootNamespace>
|
||||
<RootNamespace>Discord</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Discord.API;
|
||||
using Discord.API.Client.GatewaySocket;
|
||||
using Discord.Net.WebSockets;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
@@ -76,7 +77,7 @@ namespace Discord.Audio
|
||||
case "VOICE_SERVER_UPDATE":
|
||||
{
|
||||
var data = e.Payload.ToObject<VoiceServerUpdateEvent>(_gatewaySocket.Serializer);
|
||||
var serverId = data.ServerId;
|
||||
var serverId = data.GuildId;
|
||||
|
||||
if (serverId == ServerId)
|
||||
{
|
||||
@@ -96,10 +97,6 @@ namespace Discord.Audio
|
||||
};
|
||||
}
|
||||
|
||||
public Task Disconnect()
|
||||
{
|
||||
return _voiceSocket.Disconnect();
|
||||
}
|
||||
|
||||
internal void SetServerId(ulong serverId)
|
||||
{
|
||||
@@ -115,14 +112,17 @@ namespace Discord.Audio
|
||||
|
||||
await _voiceSocket.Disconnect().ConfigureAwait(false);
|
||||
_voiceSocket.ChannelId = channel.Id;
|
||||
_gatewaySocket.SendJoinVoice(channel.Server.Id, channel.Id);
|
||||
_gatewaySocket.SendUpdateVoice(channel.Server.Id, channel.Id,
|
||||
(_service.Config.Mode | AudioMode.Outgoing) == 0,
|
||||
(_service.Config.Mode | AudioMode.Incoming) == 0);
|
||||
await _voiceSocket.WaitForConnection(_service.Config.ConnectionTimeout).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
public Task Disconnect() => _voiceSocket.Disconnect();
|
||||
|
||||
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
|
||||
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
|
||||
/// <param name="count">Number of bytes in this frame. </param>
|
||||
public void Send(byte[] data, int count)
|
||||
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
|
||||
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
|
||||
/// <param name="count">Number of bytes in this frame. </param>
|
||||
public void Send(byte[] data, int count)
|
||||
{
|
||||
if (data == null) throw new ArgumentException(nameof(data));
|
||||
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Discord.API;
|
||||
using Discord.API.Client;
|
||||
using Discord.API.Client.VoiceSocket;
|
||||
using Discord.Audio;
|
||||
using Discord.Audio.Opus;
|
||||
using Discord.Audio.Sodium;
|
||||
@@ -394,14 +396,14 @@ namespace Discord.Net.WebSockets
|
||||
{
|
||||
await base.ProcessMessage(json).ConfigureAwait(false);
|
||||
var msg = JsonConvert.DeserializeObject<WebSocketMessage>(json);
|
||||
var opCode = (VoiceOpCodes)msg.Operation;
|
||||
var opCode = (OpCodes)msg.Operation;
|
||||
switch (opCode)
|
||||
{
|
||||
case VoiceOpCodes.Ready:
|
||||
case OpCodes.Ready:
|
||||
{
|
||||
if (_state != ConnectionState.Connected)
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<VoiceReadyEvent>(_serializer);
|
||||
var payload = (msg.Payload as JToken).ToObject<ReadyEvent>(_serializer);
|
||||
_heartbeatInterval = payload.HeartbeatInterval;
|
||||
_ssrc = payload.SSRC;
|
||||
var address = (await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault();
|
||||
@@ -435,7 +437,7 @@ namespace Discord.Net.WebSockets
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VoiceOpCodes.Heartbeat:
|
||||
case OpCodes.Heartbeat:
|
||||
{
|
||||
long time = EpochTime.GetMilliseconds();
|
||||
var payload = (long)msg.Payload;
|
||||
@@ -443,17 +445,17 @@ namespace Discord.Net.WebSockets
|
||||
//TODO: Use this to estimate latency
|
||||
}
|
||||
break;
|
||||
case VoiceOpCodes.SessionDescription:
|
||||
case OpCodes.SessionDescription:
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<JoinServerEvent>(_serializer);
|
||||
var payload = (msg.Payload as JToken).ToObject<SessionDescriptionEvent>(_serializer);
|
||||
_secretKey = payload.SecretKey;
|
||||
SendIsTalking(true);
|
||||
SendSetSpeaking(true);
|
||||
EndConnect();
|
||||
}
|
||||
break;
|
||||
case VoiceOpCodes.Speaking:
|
||||
case OpCodes.Speaking:
|
||||
{
|
||||
var payload = (msg.Payload as JToken).ToObject<IsTalkingEvent>(_serializer);
|
||||
var payload = (msg.Payload as JToken).ToObject<SpeakingEvent>(_serializer);
|
||||
RaiseIsSpeaking(payload.UserId, payload.IsSpeaking);
|
||||
}
|
||||
break;
|
||||
@@ -493,37 +495,14 @@ namespace Discord.Net.WebSockets
|
||||
});
|
||||
}
|
||||
|
||||
public void SendIdentify()
|
||||
{
|
||||
var msg = new IdentifyCommand();
|
||||
msg.Payload.ServerId = _serverId.Value;
|
||||
msg.Payload.SessionId = _client.SessionId;
|
||||
msg.Payload.Token = _audioClient.Token;
|
||||
msg.Payload.UserId = _client.UserId.Value;
|
||||
QueueMessage(msg);
|
||||
}
|
||||
public override void SendHeartbeat()
|
||||
=> QueueMessage(new HeartbeatCommand());
|
||||
public void SendIdentify()
|
||||
=> QueueMessage(new IdentifyCommand { GuildId = _serverId.Value, UserId = _client.UserId.Value, SessionId = _client.SessionId, Token = _audioClient.Token });
|
||||
public void SendSelectProtocol(string externalAddress, int externalPort)
|
||||
=> QueueMessage(new SelectProtocolCommand { Protocol = "udp", ExternalAddress = externalAddress, ExternalPort = externalPort, EncryptionMode = _encryptionMode });
|
||||
public void SendSetSpeaking(bool value)
|
||||
=> QueueMessage(new SetSpeakingCommand { IsSpeaking = value, Delay = 0 });
|
||||
|
||||
public void SendSelectProtocol(string externalIp, int externalPort)
|
||||
{
|
||||
var msg = new SelectProtocolCommand();
|
||||
msg.Payload.Protocol = "udp";
|
||||
msg.Payload.SocketData.Address = externalIp;
|
||||
msg.Payload.SocketData.Mode = _encryptionMode;
|
||||
msg.Payload.SocketData.Port = externalPort;
|
||||
QueueMessage(msg);
|
||||
}
|
||||
|
||||
public void SendIsTalking(bool value)
|
||||
{
|
||||
var isTalking = new SpeakingCommand();
|
||||
isTalking.Payload.IsSpeaking = value;
|
||||
isTalking.Payload.Delay = 0;
|
||||
QueueMessage(isTalking);
|
||||
}
|
||||
|
||||
public override void SendHeartbeat()
|
||||
{
|
||||
QueueMessage(new HeartbeatCommand());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user