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); }
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); }
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); }
public async Task Wait() { if (VoiceSocket.Server == null) { return; //Has been closed } await VoiceSocket.WaitForQueue(); }
public async Task Clear() { if (VoiceSocket.Server == null) { return; //Has been closed } await VoiceSocket.ClearPCMFrames(); }
public void Wait() { if (VoiceSocket.Server == null) { return; //Has been closed } VoiceSocket.WaitForQueue(); }
public void Clear() { if (VoiceSocket.Server == null) { return; //Has been closed } VoiceSocket.ClearPCMFrames(); }
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); }
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); } }
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; }
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); }
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; }