From 38e2501e616f2e1a50f7be677cd73cad382dab46 Mon Sep 17 00:00:00 2001 From: RogueException Date: Wed, 23 Dec 2015 03:16:48 -0400 Subject: [PATCH] Fixed Audio compile errors --- src/Discord.Net.Audio/AudioExtensions.cs | 2 +- src/Discord.Net.Audio/AudioService.cs | 14 ++-- src/Discord.Net.Audio/DiscordAudioClient.cs | 80 ++++++++++--------- .../Net/WebSockets/VoiceWebSocket.cs | 74 ++++++++--------- src/Discord.Net/DiscordClient.cs | 4 +- src/Discord.Net/Net/WebSockets/WebSocket.cs | 2 +- 6 files changed, 89 insertions(+), 87 deletions(-) diff --git a/src/Discord.Net.Audio/AudioExtensions.cs b/src/Discord.Net.Audio/AudioExtensions.cs index cf5f256d8..68ef9b203 100644 --- a/src/Discord.Net.Audio/AudioExtensions.cs +++ b/src/Discord.Net.Audio/AudioExtensions.cs @@ -3,6 +3,6 @@ public static class AudioExtensions { public static AudioService Audio(this DiscordClient client, bool required = true) - => client.GetService(required); + => client.Services.Get(required); } } diff --git a/src/Discord.Net.Audio/AudioService.cs b/src/Discord.Net.Audio/AudioService.cs index 30511ffc5..c42db17ef 100644 --- a/src/Discord.Net.Audio/AudioService.cs +++ b/src/Discord.Net.Audio/AudioService.cs @@ -11,7 +11,7 @@ namespace Discord.Audio public readonly ulong ServerId; public VoiceDisconnectedEventArgs(ulong serverId, DisconnectedEventArgs e) - : base(e.WasUnexpected, e.Error) + : base(e.WasUnexpected, e.Exception) { ServerId = serverId; } @@ -45,8 +45,8 @@ namespace Discord.Audio } public class AudioService : IService - { - private DiscordAudioClient _defaultClient; + { + private DiscordAudioClient _defaultClient; private ConcurrentDictionary _voiceClients; private ConcurrentDictionary _talkingUsers; private int _nextClientId; @@ -94,8 +94,8 @@ namespace Discord.Audio _voiceClients = new ConcurrentDictionary(); else { - var logger = Client.Log().CreateLogger("Voice"); - _defaultClient = new DiscordAudioClient(this, 0, logger, _client.WebSocket); + var logger = Client.Log.CreateLogger("Voice"); + _defaultClient = new DiscordAudioClient(this, 0, logger, _client.GatewaySocket); } _talkingUsers = new ConcurrentDictionary(); @@ -147,7 +147,7 @@ namespace Discord.Audio var client = _voiceClients.GetOrAdd(server.Id, _ => { int id = unchecked(++_nextClientId); - var logger = Client.Log().CreateLogger($"Voice #{id}"); + var logger = Client.Log.CreateLogger($"Voice #{id}"); GatewaySocket gatewaySocket = null; var voiceClient = new DiscordAudioClient(this, id, logger, gatewaySocket); voiceClient.SetServerId(server.Id); @@ -158,7 +158,7 @@ namespace Discord.Audio }; voiceClient.VoiceSocket.IsSpeaking += (s, e) => { - var user = Client.GetUser(server, e.UserId); + var user = server.GetUser(e.UserId); RaiseUserIsSpeakingUpdated(user, e.IsSpeaking); }; diff --git a/src/Discord.Net.Audio/DiscordAudioClient.cs b/src/Discord.Net.Audio/DiscordAudioClient.cs index 535ce4078..56449433b 100644 --- a/src/Discord.Net.Audio/DiscordAudioClient.cs +++ b/src/Discord.Net.Audio/DiscordAudioClient.cs @@ -1,6 +1,8 @@ using Discord.API; using Discord.API.Client.GatewaySocket; +using Discord.Logging; using Discord.Net.WebSockets; +using Newtonsoft.Json; using System; using System.Threading.Tasks; @@ -8,31 +10,33 @@ namespace Discord.Audio { public partial class DiscordAudioClient { - private readonly int _id; - public int Id => _id; + private JsonSerializer _serializer; - private readonly AudioService _service; - private readonly Logger _logger; + internal AudioService Service { get; } + internal Logger Logger { get; } + public int Id { get; } + public GatewaySocket GatewaySocket { get; } + public VoiceWebSocket VoiceSocket { get; } - public GatewaySocket GatewaySocket => _gatewaySocket; - private readonly GatewaySocket _gatewaySocket; - - public VoiceWebSocket VoiceSocket => _voiceSocket; - private readonly VoiceWebSocket _voiceSocket; - - public string Token => _token; - private string _token; - - public ulong? ServerId => _voiceSocket.ServerId; - public ulong? ChannelId => _voiceSocket.ChannelId; + public ulong? ServerId => VoiceSocket.ServerId; + public ulong? ChannelId => VoiceSocket.ChannelId; public DiscordAudioClient(AudioService service, int id, Logger logger, GatewaySocket gatewaySocket) { - _service = service; - _id = id; - _logger = logger; - _gatewaySocket = gatewaySocket; - _voiceSocket = new VoiceWebSocket(service.Client, this, logger); + Service = service; + Id = id; + Logger = logger; + + _serializer = new JsonSerializer(); + _serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + _serializer.Error += (s, e) => + { + e.ErrorContext.Handled = true; + Logger.Error("Serialization Failed", e.ErrorContext.Error); + }; + + GatewaySocket = gatewaySocket; + VoiceSocket = new VoiceWebSocket(service.Client, this, _serializer, logger); /*_voiceSocket.Connected += (s, e) => RaiseVoiceConnected(); _voiceSocket.Disconnected += async (s, e) => @@ -68,7 +72,7 @@ namespace Discord.Audio _voiceSocket.ParentCancelToken = _cancelToken; };*/ - _gatewaySocket.ReceivedDispatch += async (s, e) => + GatewaySocket.ReceivedDispatch += async (s, e) => { try { @@ -76,15 +80,15 @@ namespace Discord.Audio { case "VOICE_SERVER_UPDATE": { - var data = e.Payload.ToObject(_gatewaySocket.Serializer); + var data = e.Payload.ToObject(_serializer); var serverId = data.GuildId; if (serverId == ServerId) { - var client = _service.Client; - _token = data.Token; - _voiceSocket.Host = "wss://" + e.Payload.Value("endpoint").Split(':')[0]; - await _voiceSocket.Connect().ConfigureAwait(false); + var client = Service.Client; + VoiceSocket.Token = data.Token; + VoiceSocket.Host = "wss://" + e.Payload.Value("endpoint").Split(':')[0]; + await VoiceSocket.Connect().ConfigureAwait(false); } } break; @@ -92,7 +96,7 @@ namespace Discord.Audio } catch (Exception ex) { - _gatewaySocket.Logger.Error($"Error handling {e.Type} event", ex); + Logger.Error($"Error handling {e.Type} event", ex); } }; } @@ -100,7 +104,7 @@ namespace Discord.Audio internal void SetServerId(ulong serverId) { - _voiceSocket.ServerId = serverId; + VoiceSocket.ServerId = serverId; } public async Task Join(Channel channel) { @@ -110,14 +114,14 @@ namespace Discord.Audio throw new InvalidOperationException("Cannot join a channel on a different server than this voice client."); //CheckReady(checkVoice: true); - await _voiceSocket.Disconnect().ConfigureAwait(false); - _voiceSocket.ChannelId = 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); + await VoiceSocket.Disconnect().ConfigureAwait(false); + VoiceSocket.ChannelId = 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(); + public Task Disconnect() => VoiceSocket.Disconnect(); /// Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. /// PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. @@ -129,7 +133,7 @@ namespace Discord.Audio //CheckReady(checkVoice: true); if (count != 0) - _voiceSocket.SendPCMFrames(data, count); + VoiceSocket.SendPCMFrames(data, count); } /// Clears the PCM buffer. @@ -137,7 +141,7 @@ namespace Discord.Audio { //CheckReady(checkVoice: true); - _voiceSocket.ClearPCMFrames(); + VoiceSocket.ClearPCMFrames(); } /// Returns a task that completes once the voice output buffer is empty. @@ -145,7 +149,7 @@ namespace Discord.Audio { //CheckReady(checkVoice: true); - _voiceSocket.WaitForQueue(); + VoiceSocket.WaitForQueue(); return TaskHelper.CompletedTask; } } diff --git a/src/Discord.Net.Audio/Net/WebSockets/VoiceWebSocket.cs b/src/Discord.Net.Audio/Net/WebSockets/VoiceWebSocket.cs index 476f1b131..84d990300 100644 --- a/src/Discord.Net.Audio/Net/WebSockets/VoiceWebSocket.cs +++ b/src/Discord.Net.Audio/Net/WebSockets/VoiceWebSocket.cs @@ -4,6 +4,7 @@ using Discord.API.Client.VoiceSocket; using Discord.Audio; using Discord.Audio.Opus; using Discord.Audio.Sodium; +using Discord.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -24,35 +25,33 @@ namespace Discord.Net.WebSockets private const int MaxOpusSize = 4000; private const string EncryptedMode = "xsalsa20_poly1305"; private const string UnencryptedMode = "plain"; - - //private readonly Random _rand; + private readonly int _targetAudioBufferLength; private readonly ConcurrentDictionary _decoders; private readonly DiscordAudioClient _audioClient; private readonly AudioServiceConfig _config; - private OpusEncoder _encoder; + private Thread _sendThread, _receiveThread; + private VoiceBuffer _sendBuffer; + private OpusEncoder _encoder; private uint _ssrc; private ConcurrentDictionary _ssrcMapping; - - private VoiceBuffer _sendBuffer; private UdpClient _udp; private IPEndPoint _endpoint; private bool _isEncrypted; private byte[] _secretKey, _encodingBuffer; private ushort _sequence; - private ulong? _serverId, _channelId; private string _encryptionMode; - private int _ping; - - private Thread _sendThread, _receiveThread; - - public ulong? ServerId { get { return _serverId; } internal set { _serverId = value; } } - public ulong? ChannelId { get { return _channelId; } internal set { _channelId = value; } } - public int Ping => _ping; + private int _ping; + + public string Token { get; internal set; } + public ulong? ServerId { get; internal set; } + public ulong? ChannelId { get; internal set; } + + public int Ping => _ping; internal VoiceBuffer OutputBuffer => _sendBuffer; - public VoiceWebSocket(DiscordClient client, DiscordAudioClient audioClient, Logger logger) - : base(client, logger) + public VoiceWebSocket(DiscordClient client, DiscordAudioClient audioClient, JsonSerializer serializer, Logger logger) + : base(client, serializer, logger) { _audioClient = audioClient; _config = client.Audio().Config; @@ -84,7 +83,7 @@ namespace Discord.Net.WebSockets catch (OperationCanceledException) { throw; } catch (Exception ex) { - _logger.Error("Reconnect failed", ex); + Logger.Error("Reconnect failed", ex); //Net is down? We can keep trying to reconnect until the user runs Disconnect() await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false); } @@ -101,14 +100,14 @@ namespace Discord.Net.WebSockets List tasks = new List(); if ((_config.Mode & AudioMode.Outgoing) != 0) { - _sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(_cancelToken))); + _sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(CancelToken))); _sendThread.IsBackground = true; _sendThread.Start(); } if ((_config.Mode & AudioMode.Incoming) != 0) { - _receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(_cancelToken))); - _receiveThread.IsBackground = true; + _receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(CancelToken))); + _receiveThread.IsBackground = true; _receiveThread.Start(); } @@ -117,8 +116,8 @@ namespace Discord.Net.WebSockets #if !DOTNET5_4 tasks.Add(WatcherAsync()); #endif - tasks.AddRange(_engine.GetTasks(_cancelToken)); - tasks.Add(HeartbeatAsync(_cancelToken)); + tasks.AddRange(_engine.GetTasks(CancelToken)); + tasks.Add(HeartbeatAsync(CancelToken)); await _taskManager.Start(tasks, _cancelTokenSource).ConfigureAwait(false); } protected override Task Cleanup() @@ -179,7 +178,7 @@ namespace Discord.Net.WebSockets if (packetLength > 0 && endpoint.Equals(_endpoint)) { - if (_state != ConnectionState.Connected) + if (State != ConnectionState.Connected) { if (packetLength != 70) return; @@ -235,7 +234,7 @@ namespace Discord.Net.WebSockets ulong userId; if (_ssrcMapping.TryGetValue(ssrc, out userId)) - RaiseOnPacket(userId, _channelId.Value, result, resultOffset, resultLength); + RaiseOnPacket(userId, ChannelId.Value, result, resultOffset, resultLength); } } } @@ -249,7 +248,7 @@ namespace Discord.Net.WebSockets { try { - while (!cancelToken.IsCancellationRequested && _state != ConnectionState.Connected) + while (!cancelToken.IsCancellationRequested && State != ConnectionState.Connected) Thread.Sleep(1); if (cancelToken.IsCancellationRequested) @@ -353,7 +352,7 @@ namespace Discord.Net.WebSockets } catch (SocketException ex) { - _logger.Error("Failed to send UDP packet.", ex); + Logger.Error("Failed to send UDP packet.", ex); } hasFrame = false; } @@ -385,11 +384,7 @@ namespace Discord.Net.WebSockets #if !DOTNET5_4 //Closes the UDP socket when _disconnectToken is triggered, since UDPClient doesn't allow passing a canceltoken private Task WatcherAsync() - { - var cancelToken = _cancelToken; - return cancelToken.Wait() - .ContinueWith(_ => _udp.Close()); - } + => CancelToken.Wait().ContinueWith(_ => _udp.Close()); #endif protected override async Task ProcessMessage(string json) @@ -401,7 +396,7 @@ namespace Discord.Net.WebSockets { case OpCodes.Ready: { - if (_state != ConnectionState.Connected) + if (State != ConnectionState.Connected) { var payload = (msg.Payload as JToken).ToObject(_serializer); _heartbeatInterval = payload.HeartbeatInterval; @@ -460,24 +455,23 @@ namespace Discord.Net.WebSockets } break; default: - if (_logger.Level >= LogSeverity.Warning) - _logger.Warning($"Unknown Opcode: {opCode}"); + Logger.Warning($"Unknown Opcode: {opCode}"); break; } } public void SendPCMFrames(byte[] data, int bytes) { - _sendBuffer.Push(data, bytes, _cancelToken); + _sendBuffer.Push(data, bytes, CancelToken); } public void ClearPCMFrames() { - _sendBuffer.Clear(_cancelToken); + _sendBuffer.Clear(CancelToken); } public void WaitForQueue() { - _sendBuffer.Wait(_cancelToken); + _sendBuffer.Wait(CancelToken); } public Task WaitForConnection(int timeout) { @@ -485,7 +479,7 @@ namespace Discord.Net.WebSockets { try { - if (!_connectedEvent.Wait(timeout, _cancelToken)) + if (!_connectedEvent.Wait(timeout, CancelToken)) throw new TimeoutException(); } catch (OperationCanceledException) @@ -498,9 +492,11 @@ namespace Discord.Net.WebSockets 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 }); + => QueueMessage(new IdentifyCommand { GuildId = ServerId.Value, UserId = _client.CurrentUser.Id, + SessionId = _client.SessionId, Token = Token }); public void SendSelectProtocol(string externalAddress, int externalPort) - => QueueMessage(new SelectProtocolCommand { Protocol = "udp", ExternalAddress = externalAddress, ExternalPort = externalPort, EncryptionMode = _encryptionMode }); + => QueueMessage(new SelectProtocolCommand { Protocol = "udp", ExternalAddress = externalAddress, + ExternalPort = externalPort, EncryptionMode = _encryptionMode }); public void SendSetSpeaking(bool value) => QueueMessage(new SetSpeakingCommand { IsSpeaking = value, Delay = 0 }); diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 8151773cd..3edd6a11b 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -56,6 +56,8 @@ namespace Discord internal User PrivateUser { get; private set; } /// Gets information about the current logged-in account. public Profile CurrentUser { get; private set; } + /// Gets the session id for the current connection. + public string SessionId { get; private set; } /// Gets the status of the current user. public UserStatus Status { get; private set; } /// Gets the game this current user is reported as playing. @@ -448,7 +450,7 @@ namespace Discord case "READY": //Resync { var data = e.Payload.ToObject(_serializer); - //SessionId = data.SessionId; + SessionId = data.SessionId; PrivateUser = new User(this, data.User.Id, null); PrivateUser.Update(data.User); CurrentUser.Update(data.User); diff --git a/src/Discord.Net/Net/WebSockets/WebSocket.cs b/src/Discord.Net/Net/WebSockets/WebSocket.cs index 494f8a162..9764220a6 100644 --- a/src/Discord.Net/Net/WebSockets/WebSocket.cs +++ b/src/Discord.Net/Net/WebSockets/WebSocket.cs @@ -22,7 +22,7 @@ namespace Discord.Net.WebSockets private DateTime _lastHeartbeat; /// Gets the logger used for this client. - internal Logger Logger { get; } + protected internal Logger Logger { get; } public CancellationToken CancelToken { get; private set; }