You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

DiscordAudioClient.cs 4.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using Discord.Net.WebSockets;
  2. using System;
  3. using System.Threading.Tasks;
  4. namespace Discord.Audio
  5. {
  6. public partial class DiscordAudioClient
  7. {
  8. private readonly int _id;
  9. public int Id => _id;
  10. private readonly AudioService _service;
  11. private readonly GatewaySocket _gatewaySocket;
  12. private readonly VoiceWebSocket _voiceSocket;
  13. private readonly Logger _logger;
  14. public long? ServerId => _voiceSocket.ServerId;
  15. public long? ChannelId => _voiceSocket.ChannelId;
  16. public DiscordAudioClient(AudioService service, int id, Logger logger, GatewaySocket gatewaySocket, VoiceWebSocket voiceSocket)
  17. {
  18. _service = service;
  19. _id = id;
  20. _logger = logger;
  21. _gatewaySocket = gatewaySocket;
  22. _voiceSocket = voiceSocket;
  23. /*_voiceSocket.Connected += (s, e) => RaiseVoiceConnected();
  24. _voiceSocket.Disconnected += async (s, e) =>
  25. {
  26. _voiceSocket.CurrentServerId;
  27. if (voiceServerId != null)
  28. _gatewaySocket.SendLeaveVoice(voiceServerId.Value);
  29. await _voiceSocket.Disconnect().ConfigureAwait(false);
  30. RaiseVoiceDisconnected(socket.CurrentServerId.Value, e);
  31. if (e.WasUnexpected)
  32. await socket.Reconnect().ConfigureAwait(false);
  33. };*/
  34. /*_voiceSocket.IsSpeaking += (s, e) =>
  35. {
  36. if (_voiceSocket.State == WebSocketState.Connected)
  37. {
  38. var user = _users[e.UserId, socket.CurrentServerId];
  39. bool value = e.IsSpeaking;
  40. if (user.IsSpeaking != value)
  41. {
  42. user.IsSpeaking = value;
  43. var channel = _channels[_voiceSocket.CurrentChannelId];
  44. RaiseUserIsSpeaking(user, channel, value);
  45. if (Config.TrackActivity)
  46. user.UpdateActivity();
  47. }
  48. }
  49. };*/
  50. /*this.Connected += (s, e) =>
  51. {
  52. _voiceSocket.ParentCancelToken = _cancelToken;
  53. };*/
  54. _gatewaySocket.ReceivedDispatch += async (s, e) =>
  55. {
  56. try
  57. {
  58. switch (e.Type)
  59. {
  60. case "VOICE_SERVER_UPDATE":
  61. {
  62. long serverId = IdConvert.ToLong(e.Payload.Value<string>("guild_id"));
  63. if (serverId == ServerId)
  64. {
  65. var client = _service.Client;
  66. string token = e.Payload.Value<string>("token");
  67. _voiceSocket.Host = "wss://" + e.Payload.Value<string>("endpoint").Split(':')[0];
  68. await _voiceSocket.Connect(client.CurrentUser.Id, _gatewaySocket.SessionId, token/*, client.CancelToken*/).ConfigureAwait(false);
  69. }
  70. }
  71. break;
  72. }
  73. }
  74. catch (Exception ex)
  75. {
  76. _gatewaySocket.Logger.Log(LogSeverity.Error, $"Error handling {e.Type} event", ex);
  77. }
  78. };
  79. }
  80. public Task Disconnect()
  81. {
  82. return _voiceSocket.Disconnect();
  83. }
  84. internal void SetServerId(long serverId)
  85. {
  86. _voiceSocket.ServerId = serverId;
  87. }
  88. public async Task Join(Channel channel)
  89. {
  90. if (channel == null) throw new ArgumentNullException(nameof(channel));
  91. long? serverId = channel.Server?.Id;
  92. if (serverId != ServerId)
  93. throw new InvalidOperationException("Cannot join a channel on a different server than this voice client.");
  94. //CheckReady(checkVoice: true);
  95. await _voiceSocket.Disconnect().ConfigureAwait(false);
  96. _voiceSocket.ChannelId = channel.Id;
  97. _gatewaySocket.SendJoinVoice(channel.Server.Id, channel.Id);
  98. await _voiceSocket.WaitForConnection(_service.Config.ConnectionTimeout).ConfigureAwait(false);
  99. }
  100. /// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
  101. /// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
  102. /// <param name="count">Number of bytes in this frame. </param>
  103. public void Send(byte[] data, int count)
  104. {
  105. if (data == null) throw new ArgumentException(nameof(data));
  106. if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
  107. //CheckReady(checkVoice: true);
  108. if (count != 0)
  109. _voiceSocket.SendPCMFrames(data, count);
  110. }
  111. /// <summary> Clears the PCM buffer. </summary>
  112. public void Clear()
  113. {
  114. //CheckReady(checkVoice: true);
  115. _voiceSocket.ClearPCMFrames();
  116. }
  117. /// <summary> Returns a task that completes once the voice output buffer is empty. </summary>
  118. public Task Wait()
  119. {
  120. //CheckReady(checkVoice: true);
  121. _voiceSocket.WaitForQueue();
  122. return TaskHelper.CompletedTask;
  123. }
  124. }
  125. }