private async Task HeartbeatAsync() { await Task.Yield(); var token = Token; while (true) { try { token.ThrowIfCancellationRequested(); var dt = DateTime.Now; Discord.DebugLogger.LogMessage(LogLevel.Debug, "VoiceNext", "Sent heartbeat", dt); var hbd = new VoiceDispatch { OpCode = 3, Payload = UnixTimestamp(dt) }; var hbj = JsonConvert.SerializeObject(hbd); VoiceWs.SendMessage(hbj); LastHeartbeat = dt; await Task.Delay(HeartbeatInterval).ConfigureAwait(false); } catch (OperationCanceledException) { return; } } }
internal Task StartAsync() { // Let's announce our intentions to the server var vdp = new VoiceDispatch(); if (!Resume) { vdp.OpCode = 0; vdp.Payload = new VoiceIdentifyPayload { ServerId = ServerData.GuildId, UserId = StateData.UserId.Value, SessionId = StateData.SessionId, Token = ServerData.Token }; Resume = true; } else { vdp.OpCode = 7; vdp.Payload = new VoiceIdentifyPayload { ServerId = ServerData.GuildId, SessionId = StateData.SessionId, Token = ServerData.Token }; } var vdj = JsonConvert.SerializeObject(vdp, Formatting.None); VoiceWs.SendMessage(vdj); return(Task.Delay(0)); }
private async Task Stage1() { #if !NETSTANDARD1_1 // IP Discovery UdpClient.Setup(ConnectionEndpoint); var pck = new byte[70]; Array.Copy(BitConverter.GetBytes(SSRC), 0, pck, pck.Length - 4, 4); await UdpClient.SendAsync(pck, pck.Length).ConfigureAwait(false); var ipd = await UdpClient.ReceiveAsync().ConfigureAwait(false); var ipe = Array.IndexOf <byte>(ipd, 0, 4); var ip = new UTF8Encoding(false).GetString(ipd, 4, ipe - 4); var port = BitConverter.ToUInt16(ipd, ipd.Length - 2); DiscoveredEndpoint = new IpEndpoint { Address = System.Net.IPAddress.Parse(ip), Port = port }; #endif // Ready var vsp = new VoiceDispatch { OpCode = 1, Payload = new VoiceSelectProtocolPayload { Protocol = "udp", Data = new VoiceSelectProtocolPayloadData { #if !NETSTANDARD1_1 Address = DiscoveredEndpoint.Address.ToString(), Port = (ushort)DiscoveredEndpoint.Port, #else Address = "0.0.0.0", Port = 0, #endif Mode = VOICE_MODE } } }; var vsj = JsonConvert.SerializeObject(vsp, Formatting.None); VoiceWs.SendMessage(vsj); #if !NETSTANDARD1_1 if (Configuration.EnableIncoming) { ReceiverTokenSource = new CancellationTokenSource(); ReceiverTask = Task.Run(VoiceReceiverTask, ReceiverToken); } #endif }
/// <summary> /// Sends a speaking status to the connected voice channel. /// </summary> /// <param name="speaking">Whether the current user is speaking or not.</param> /// <returns>A task representing the sending operation.</returns> public async Task SendSpeakingAsync(bool speaking = true) { if (!IsInitialized) { throw new InvalidOperationException("The connection is not initialized"); } if (!speaking) { var nullpcm = new byte[3840]; for (var i = 0; i < 5; i++) { await SendAsync(nullpcm, 20).ConfigureAwait(false); } SynchronizerTicks = 0; if (PlayingWait != null) { PlayingWait.SetResult(true); } } else { if (PlayingWait == null || PlayingWait.Task.IsCompleted) { PlayingWait = new TaskCompletionSource <bool>(); } } var pld = new VoiceDispatch { OpCode = 5, Payload = new VoiceSpeakingPayload { Speaking = speaking, Delay = 0 } }; var plj = JsonConvert.SerializeObject(pld, Formatting.None); VoiceWs.SendMessage(plj); }
/// <summary> /// Sends a speaking status to the connected voice channel. /// </summary> /// <param name="speaking">Whether the current user is speaking or not.</param> /// <returns>A task representing the sending operation.</returns> public void SendSpeaking(bool speaking = true) { if (!IsInitialized) { throw new InvalidOperationException("The connection is not initialized"); } var pld = new VoiceDispatch { OpCode = 5, Payload = new VoiceSpeakingPayload { Speaking = speaking, Delay = 0 } }; var plj = JsonConvert.SerializeObject(pld, Formatting.None); VoiceWs.SendMessage(plj); }
private async Task Stage1(VoiceReadyPayload voiceReady) { // IP Discovery UdpClient.Setup(ConnectionEndpoint); var pck = new byte[70]; PreparePacket(pck); await UdpClient.SendAsync(pck, pck.Length).ConfigureAwait(false); var ipd = await UdpClient.ReceiveAsync().ConfigureAwait(false); ReadPacket(ipd, out var ip, out var port); DiscoveredEndpoint = new IPEndPoint(ip, port); Discord.DebugLogger.LogMessage(LogLevel.Debug, "VNext UDP", $"Endpoint discovery resulted in {ip}:{port}", DateTime.Now); void PreparePacket(byte[] packet) { var ssrc = SSRC; var packetSpan = packet.AsSpan(); MemoryMarshal.Write(packetSpan, ref ssrc); Helpers.ZeroFill(packetSpan); } void ReadPacket(byte[] packet, out System.Net.IPAddress decodedIp, out ushort decodedPort) { var packetSpan = packet.AsSpan(); var ipString = new UTF8Encoding(false).GetString(packet, 4, 64 /* 70 - 6 */).TrimEnd('\0'); decodedIp = System.Net.IPAddress.Parse(ipString); decodedPort = BinaryPrimitives.ReadUInt16LittleEndian(packetSpan.Slice(68 /* 70 - 2 */)); } // Select voice encryption mode var selectedEncryptionMode = Sodium.SelectMode(voiceReady.Modes); SelectedEncryptionMode = selectedEncryptionMode.Value; // Ready Discord.DebugLogger.LogMessage(LogLevel.Debug, "VoiceNext", $"Selected encryption mode: {selectedEncryptionMode.Key}", DateTime.Now); var vsp = new VoiceDispatch { OpCode = 1, Payload = new VoiceSelectProtocolPayload { Protocol = "udp", Data = new VoiceSelectProtocolPayloadData { Address = DiscoveredEndpoint.Address.ToString(), Port = (ushort)DiscoveredEndpoint.Port, Mode = selectedEncryptionMode.Key } } }; var vsj = JsonConvert.SerializeObject(vsp, Formatting.None); VoiceWs.SendMessage(vsj); SenderTokenSource = new CancellationTokenSource(); SenderTask = Task.Run(VoiceSenderTask, SenderToken); ReceiverTokenSource = new CancellationTokenSource(); ReceiverTask = Task.Run(UdpReceiverTask, ReceiverToken); }