Esempio n. 1
0
        public async Task Send(byte[] data, int offset, int count)
        {
            if (data == null)
            {
                throw new ArgumentException(nameof(data));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (VoiceSocket.Server == null)
            {
                return;                             //Has been closed
            }
            if (count == 0)
            {
                return;
            }

            await VoiceSocket.SendPCMFrames(data, offset, count);
        }
Esempio n. 2
0
        public async Task Join(Channel channel)
        {
            if (channel == null)
            {
                throw new ArgumentNullException(nameof(channel));
            }
            if (channel.Type != ChannelType.Voice)
            {
                throw new ArgumentException("Channel must be a voice channel.", nameof(channel));
            }
            if (channel == VoiceSocket.Channel)
            {
                return;
            }
            var server = channel.Server;

            if (server != VoiceSocket.Server)
            {
                throw new ArgumentException("This channel is not part of the current server.", nameof(channel));
            }
            if (VoiceSocket.Server == null)
            {
                throw new InvalidOperationException("This client has been closed.");
            }

            SendVoiceUpdate(channel.Server.Id, channel.Id);
            using (await _connectionLock.LockAsync().ConfigureAwait(false))
                await Task.Run(() => VoiceSocket.WaitForConnection(CancelToken)).ConfigureAwait(false);
        }
Esempio n. 3
0
        public AudioClient(DiscordClient client, Server server, int id
#if WINDOWS_UWP
                           , IWebSocketEngine customSocket = null
#endif
                           )
        {
            Id            = id;
            Service       = client.GetService <AudioService>();
            Config        = Service.Config;
            Serializer    = client.Serializer;
            _gatewayState = (int)ConnectionState.Disconnected;

            //Logging
            Logger = client.Log.CreateLogger($"AudioClient #{id}");

            //Async
            _taskManager    = new TaskManager(Cleanup, false);
            _connectionLock = new AsyncLock();
            CancelToken     = new CancellationToken(true);

            //Networking
            _config       = client.Config;
            GatewaySocket = client.GatewaySocket;
            GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e);
            VoiceSocket = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}")
#if WINDOWS_UWP
                                          , customSocket
#endif

                                          );
            VoiceSocket.Server = server;
            OutputStream       = new OutStream(this);
        }
Esempio n. 4
0
 public async Task Wait()
 {
     if (VoiceSocket.Server == null)
     {
         return;                             //Has been closed
     }
     await VoiceSocket.WaitForQueue();
 }
Esempio n. 5
0
 public async Task Clear()
 {
     if (VoiceSocket.Server == null)
     {
         return;                             //Has been closed
     }
     await VoiceSocket.ClearPCMFrames();
 }
Esempio n. 6
0
 public void Wait()
 {
     if (VoiceSocket.Server == null)
     {
         return;                             //Has been closed
     }
     VoiceSocket.WaitForQueue();
 }
Esempio n. 7
0
 public void Clear()
 {
     if (VoiceSocket.Server == null)
     {
         return;                             //Has been closed
     }
     VoiceSocket.ClearPCMFrames();
 }
Esempio n. 8
0
        public AudioClient(DiscordClient client, Server server, int id)
        {
            Id            = id;
            Service       = client.GetService <AudioService>();
            Config        = Service.Config;
            Serializer    = client.Serializer;
            _gatewayState = (int)ConnectionState.Disconnected;

            //Logging
            Logger = client.Log.CreateLogger($"AudioClient #{id}");

            //Async
            _taskManager    = new TaskManager(Cleanup, false);
            _connectionLock = new AsyncLock();
            CancelToken     = new CancellationToken(true);

            //Networking
            if (Config.EnableMultiserver)
            {
                //TODO: We can remove this hack when official API launches
                var baseConfig = client.Config;
                var builder    = new DiscordConfigBuilder
                {
                    AppName               = baseConfig.AppName,
                    AppUrl                = baseConfig.AppUrl,
                    AppVersion            = baseConfig.AppVersion,
                    CacheToken            = baseConfig.CacheDir != null,
                    ConnectionTimeout     = baseConfig.ConnectionTimeout,
                    EnablePreUpdateEvents = false,
                    FailedReconnectDelay  = baseConfig.FailedReconnectDelay,
                    LargeThreshold        = 1,
                    LogLevel              = baseConfig.LogLevel,
                    MessageCacheSize      = 0,
                    ReconnectDelay        = baseConfig.ReconnectDelay,
                    UsePermissionsCache   = false
                };
                _config = builder.Build();

                ClientAPI                = new JsonRestClient(_config, DiscordConfig.ClientAPIUrl, client.Log.CreateLogger($"ClientAPI #{id}"));
                GatewaySocket            = new GatewaySocket(_config, client.Serializer, client.Log.CreateLogger($"Gateway #{id}"));
                GatewaySocket.Connected += (s, e) =>
                {
                    if (_gatewayState == ConnectionState.Connecting)
                    {
                        EndGatewayConnect();
                    }
                };
            }
            else
            {
                _config       = client.Config;
                GatewaySocket = client.GatewaySocket;
            }
            GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e);
            VoiceSocket        = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}"));
            VoiceSocket.Server = server;
            OutputStream       = new OutStream(this);
        }
Esempio n. 9
0
        private async void OnReceivedEvent(WebSocketEventEventArgs e)
        {
            try
            {
                switch (e.Type)
                {
                case "VOICE_STATE_UPDATE":
                {
                    var data = e.Payload.ToObject <VoiceStateUpdateEvent>(Serializer);
                    if (data.GuildId == VoiceSocket.Server?.Id && data.UserId == Service.Client.CurrentUser?.Id)
                    {
                        if (data.ChannelId == null)
                        {
                            await Disconnect().ConfigureAwait(false);
                        }
                        else
                        {
                            var channel = Service.Client.GetChannel(data.ChannelId.Value);
                            if (channel != null)
                            {
                                VoiceSocket.Channel = channel;
                            }
                            else
                            {
                                Logger.Warning("VOICE_STATE_UPDATE referenced an unknown channel, disconnecting.");
                                await Disconnect().ConfigureAwait(false);
                            }
                        }
                    }
                }
                break;

                case "VOICE_SERVER_UPDATE":
                {
                    var data = e.Payload.ToObject <VoiceServerUpdateEvent>(Serializer);
                    if (data.GuildId == VoiceSocket.Server?.Id)
                    {
                        var client = Service.Client;
                        var id     = client.CurrentUser?.Id;
                        if (id != null)
                        {
                            var host = "wss://" + e.Payload.Value <string>("endpoint").Split(':')[0];
                            await VoiceSocket.Connect(host, data.Token, id.Value, GatewaySocket.SessionId, CancelToken).ConfigureAwait(false);
                        }
                    }
                }
                break;
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Error handling {e.Type} event", ex);
            }
        }
Esempio n. 10
0
        private async Task Cleanup()
        {
            var oldState = _gatewayState;

            _gatewayState = ConnectionState.Disconnecting;

            var server = VoiceSocket.Server;

            VoiceSocket.Server  = null;
            VoiceSocket.Channel = null;
            await Service.RemoveClient(server, this).ConfigureAwait(false);

            SendVoiceUpdate(server.Id, null);

            await VoiceSocket.Disconnect().ConfigureAwait(false);

            _gatewayState = (int)ConnectionState.Disconnected;
        }
Esempio n. 11
0
        public AudioClient(DiscordClient client, Server server, int id)
        {
            Id            = id;
            _config       = client.Config;
            Service       = client.Services.Get <AudioService>();
            Config        = Service.Config;
            Serializer    = client.Serializer;
            _gatewayState = (int)ConnectionState.Disconnected;

            //Logging
            Logger = client.Log.CreateLogger($"AudioClient #{id}");

            //Async
            _taskManager    = new TaskManager(Cleanup, false);
            _connectionLock = new AsyncLock();
            CancelToken     = new CancellationToken(true);

            //Networking
            if (Config.EnableMultiserver)
            {
                ClientAPI                = new JsonRestClient(_config, DiscordConfig.ClientAPIUrl, client.Log.CreateLogger($"ClientAPI #{id}"));
                GatewaySocket            = new GatewaySocket(_config, client.Serializer, client.Log.CreateLogger($"Gateway #{id}"));
                GatewaySocket.Connected += (s, e) =>
                {
                    if (_gatewayState == ConnectionState.Connecting)
                    {
                        EndGatewayConnect();
                    }
                };
            }
            else
            {
                GatewaySocket = client.GatewaySocket;
            }
            GatewaySocket.ReceivedDispatch += (s, e) => OnReceivedEvent(e);
            VoiceSocket        = new VoiceSocket(_config, Config, client.Serializer, client.Log.CreateLogger($"Voice #{id}"));
            VoiceSocket.Server = server;
            OutputStream       = new OutStream(this);
        }
Esempio n. 12
0
        private async Task Cleanup()
        {
            var oldState = _gatewayState;

            _gatewayState = ConnectionState.Disconnecting;

            if (Config.EnableMultiserver)
            {
                if (oldState == ConnectionState.Connected)
                {
                    try { await ClientAPI.Send(new LogoutRequest()).ConfigureAwait(false); }
                    catch (OperationCanceledException) { }
                }

                await GatewaySocket.Disconnect().ConfigureAwait(false);

                ClientAPI.Token = null;
            }

            var server = VoiceSocket.Server;

            VoiceSocket.Server  = null;
            VoiceSocket.Channel = null;
            if (Config.EnableMultiserver)
            {
                await Service.RemoveClient(server, this).ConfigureAwait(false);
            }
            SendVoiceUpdate(server.Id, null);

            await VoiceSocket.Disconnect().ConfigureAwait(false);

            if (Config.EnableMultiserver)
            {
                await GatewaySocket.Disconnect().ConfigureAwait(false);
            }

            _gatewayState = (int)ConnectionState.Disconnected;
        }