/// <summary> /// Sends an VoiceUpdate to Lavalink for this Player /// </summary> /// <param name="sessionID">The SessionID of this VoiceUpdate</param> /// <param name="event">The VoiceServer event of this VoiceUpdate</param> /// <returns>Task</returns> public Task VoiceUpdateAsync(string sessionID, VoiceServerUpdatePayload @event) => Node.SendAsync(new VoiceUpdatePacket { OPCode = "voiceUpdate", GuildID = GuildID.ToString(), UpdateEvent = @event, SessionID = sessionID });
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { Discord = client; Guild = guild; Channel = channel; TransmittingSSRCs = new ConcurrentDictionary <uint, AudioSender>(); _userSpeaking = new AsyncEvent <UserSpeakingEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_SPEAKING"); _userJoined = new AsyncEvent <VoiceUserJoinEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_JOINED"); _userLeft = new AsyncEvent <VoiceUserLeaveEventArgs>(Discord.EventErrorHandler, "VNEXT_USER_LEFT"); _voiceReceived = new AsyncEvent <VoiceReceiveEventArgs>(Discord.EventErrorHandler, "VNEXT_VOICE_RECEIVED"); _voiceSocketError = new AsyncEvent <SocketErrorEventArgs>(Discord.EventErrorHandler, "VNEXT_WS_ERROR"); TokenSource = new CancellationTokenSource(); Configuration = config; Opus = new Opus(AudioFormat); //this.Sodium = new Sodium(); Rtp = new Rtp(); ServerData = server; StateData = state; var eps = ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 80; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } ConnectionEndpoint = new ConnectionEndpoint { Hostname = eph, Port = epp }; ReadyWait = new TaskCompletionSource <bool>(); IsInitialized = false; IsDisposed = false; PlayingWait = null; PacketQueue = new ConcurrentQueue <VoicePacket>(); KeepaliveTimestamps = new ConcurrentDictionary <ulong, long>(); UdpClient = Discord.Configuration.UdpClientFactory(); VoiceWs = Discord.Configuration.WebSocketClientFactory(Discord.Configuration.Proxy); VoiceWs.Disconnected += VoiceWS_SocketClosed; VoiceWs.MessageRecieved += VoiceWS_SocketMessage; VoiceWs.Connected += VoiceWS_SocketOpened; VoiceWs.Errored += VoiceWs_SocketErrored; }
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { Discord = client; Guild = guild; Channel = channel; SSRCMap = new ConcurrentDictionary <uint, ulong>(); _userSpeaking = new AsyncEvent <UserSpeakingEventArgs>(Discord.EventErrorHandler, "USER_SPEAKING"); _userLeft = new AsyncEvent <VoiceUserLeaveEventArgs>(Discord.EventErrorHandler, "USER_LEFT"); #if !NETSTANDARD1_1 _voiceReceived = new AsyncEvent <VoiceReceiveEventArgs>(Discord.EventErrorHandler, "VOICE_RECEIVED"); #endif _voiceSocketError = new AsyncEvent <SocketErrorEventArgs>(Discord.EventErrorHandler, "VOICE_WS_ERROR"); TokenSource = new CancellationTokenSource(); Configuration = config; Opus = new OpusCodec(48000, 2, Configuration.VoiceApplication); Sodium = new SodiumCodec(); Rtp = new RtpCodec(); ServerData = server; StateData = state; var eps = ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 80; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } ConnectionEndpoint = new ConnectionEndpoint { Hostname = eph, Port = epp }; ReadyWait = new TaskCompletionSource <bool>(); IsInitialized = false; IsDisposed = false; PlayingWait = null; PlaybackSemaphore = new SemaphoreSlim(1, 1); UdpClient = Discord.Configuration.UdpClientFactory(); VoiceWs = Discord.Configuration.WebSocketClientFactory(Discord.Configuration.Proxy); VoiceWs.OnDisconnect += VoiceWS_SocketClosed; VoiceWs.OnMessage += VoiceWS_SocketMessage; VoiceWs.OnConnect += VoiceWS_SocketOpened; VoiceWs.OnError += VoiceWs_SocketErrored; }
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { this.Discord = client; this.Guild = guild; this.TargetChannel = channel; this.TransmittingSSRCs = new ConcurrentDictionary <uint, AudioSender>(); this._userSpeaking = new AsyncEvent <VoiceNextConnection, UserSpeakingEventArgs>("VNEXT_USER_SPEAKING", TimeSpan.Zero, this.Discord.EventErrorHandler); this._userJoined = new AsyncEvent <VoiceNextConnection, VoiceUserJoinEventArgs>("VNEXT_USER_JOINED", TimeSpan.Zero, this.Discord.EventErrorHandler); this._userLeft = new AsyncEvent <VoiceNextConnection, VoiceUserLeaveEventArgs>("VNEXT_USER_LEFT", TimeSpan.Zero, this.Discord.EventErrorHandler); this._voiceReceived = new AsyncEvent <VoiceNextConnection, VoiceReceiveEventArgs>("VNEXT_VOICE_RECEIVED", TimeSpan.Zero, this.Discord.EventErrorHandler); this._voiceSocketError = new AsyncEvent <VoiceNextConnection, SocketErrorEventArgs>("VNEXT_WS_ERROR", TimeSpan.Zero, this.Discord.EventErrorHandler); this.TokenSource = new CancellationTokenSource(); this.Configuration = config; this.Opus = new Opus(this.AudioFormat); //this.Sodium = new Sodium(); this.Rtp = new Rtp(); this.ServerData = server; this.StateData = state; var eps = this.ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 443; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } this.WebSocketEndpoint = new ConnectionEndpoint { Hostname = eph, Port = epp }; this.ReadyWait = new TaskCompletionSource <bool>(); this.IsInitialized = false; this.IsDisposed = false; this.PlayingWait = null; this.TransmitChannel = Channel.CreateBounded <RawVoicePacket>(new BoundedChannelOptions(Configuration.PacketQueueSize)); this.KeepaliveTimestamps = new ConcurrentDictionary <ulong, long>(); this.PauseEvent = new AsyncManualResetEvent(true); this.UdpClient = this.Discord.Configuration.UdpClientFactory(); this.VoiceWs = this.Discord.Configuration.WebSocketClientFactory(this.Discord.Configuration.Proxy); this.VoiceWs.Disconnected += this.VoiceWS_SocketClosed; this.VoiceWs.MessageReceived += this.VoiceWS_SocketMessage; this.VoiceWs.Connected += this.VoiceWS_SocketOpened; this.VoiceWs.ExceptionThrown += this.VoiceWs_SocketException; }
/// <summary> /// Create a VoiceNext connection for the specified channel. /// </summary> /// <param name="channel">Channel to connect to.</param> /// <returns>VoiceNext connection for this channel.</returns> public async Task <VoiceNextConnection> ConnectAsync(DiscordChannel channel) { if (channel.Type != ChannelType.Voice) { throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be voice channel"); } if (channel.Guild == null) { throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be guild channel"); } if (!channel.PermissionsFor(channel.Guild.CurrentMember).HasPermission(Permissions.UseVoice)) { throw new InvalidOperationException("You need UseVoice permission to connect to this voice channel"); } var gld = channel.Guild; if (ActiveConnections.ContainsKey(gld.Id)) { throw new InvalidOperationException("This guild already has a voice connection"); } var vstut = new TaskCompletionSource <VoiceStateUpdateEventArgs>(); var vsrut = new TaskCompletionSource <VoiceServerUpdateEventArgs>(); this.VoiceStateUpdates[gld.Id] = vstut; this.VoiceServerUpdates[gld.Id] = vsrut; var vsd = new VoiceDispatch { OpCode = 4, Payload = new VoiceStateUpdatePayload { GuildId = gld.Id, ChannelId = channel.Id, Deafened = false, Muted = false } }; var vsj = JsonConvert.SerializeObject(vsd, Formatting.None); await(channel.Discord as DiscordClient)._webSocketClient.SendMessageAsync(vsj).ConfigureAwait(false); var vstu = await vstut.Task.ConfigureAwait(false); var vstup = new VoiceStateUpdatePayload { SessionId = vstu.SessionId, UserId = vstu.User.Id }; var vsru = await vsrut.Task.ConfigureAwait(false); var vsrup = new VoiceServerUpdatePayload { Endpoint = vsru.Endpoint, GuildId = vsru.Guild.Id, Token = vsru.VoiceToken }; var vnc = new VoiceNextConnection(this.Client, gld, channel, this.Configuration, vsrup, vstup); vnc.VoiceDisconnected += this.Vnc_VoiceDisconnected; await vnc.ConnectAsync().ConfigureAwait(false); await vnc.WaitForReadyAsync().ConfigureAwait(false); this.ActiveConnections[gld.Id] = vnc; return(vnc); }
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { this.Discord = client; this.Guild = guild; this.Channel = channel; this.Configuration = config; this.Opus = new OpusCodec(48000, 2, this.Configuration.VoiceApplication); this.Sodium = new SodiumCodec(); this.RTP = new RtpCodec(); this.Synchronizer = new Stopwatch(); this.UdpLatency = TimeSpan.FromMilliseconds(0.5); this.ServerData = server; this.StateData = state; var eps = this.ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 80; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } this.ConnectionEndpoint = new DnsEndPoint(eph, epp); this.ReadyWait = new TaskCompletionSource <bool>(); this.IsInitialized = false; this.IsDisposed = false; this.UdpClient = new UdpClient(); this.VoiceWs = WebSocketWrapper.Create($"wss://{this.ConnectionEndpoint.Host}"); this.VoiceWs.OnDisconnect += this.VoiceWS_SocketClosed; this.VoiceWs.OnMessage += this.VoiceWS_SocketMessage; this.VoiceWs.OnConnect += this.VoiceWS_SocketOpened; }
internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { this.Discord = client; this.Guild = guild; this.Channel = channel; this.SSRCMap = new ConcurrentDictionary <uint, ulong>(); this._user_speaking = new AsyncEvent <UserSpeakingEventArgs>(this.Discord.EventErrorHandler, "USER_SPEAKING"); #if !NETSTANDARD1_1 this._voice_received = new AsyncEvent <VoiceReceiveEventArgs>(this.Discord.EventErrorHandler, "VOICE_RECEIVED"); #endif this._voice_socket_error = new AsyncEvent <SocketErrorEventArgs>(this.Discord.EventErrorHandler, "VOICE_WS_ERROR"); this.TokenSource = new CancellationTokenSource(); this.Configuration = config; this.Opus = new OpusCodec(48000, 2, this.Configuration.VoiceApplication); this.Sodium = new SodiumCodec(); this.Rtp = new RtpCodec(); this.UdpLatency = TimeSpan.FromMilliseconds(0.1); this.ServerData = server; this.StateData = state; var eps = this.ServerData.Endpoint; var epi = eps.LastIndexOf(':'); var eph = string.Empty; var epp = 80; if (epi != -1) { eph = eps.Substring(0, epi); epp = int.Parse(eps.Substring(epi + 1)); } else { eph = eps; } this.ConnectionEndpoint = new ConnectionEndpoint { Hostname = eph, Port = epp }; this.ReadyWait = new TaskCompletionSource <bool>(); this.IsInitialized = false; this.IsDisposed = false; this.PlayingWait = null; this.PlaybackSemaphore = new SemaphoreSlim(1, 1); this.UdpClient = BaseUdpClient.Create(); this.VoiceWs = BaseWebSocketClient.Create(); this.VoiceWs.OnDisconnect += this.VoiceWS_SocketClosed; this.VoiceWs.OnMessage += this.VoiceWS_SocketMessage; this.VoiceWs.OnConnect += this.VoiceWS_SocketOpened; this.VoiceWs.OnError += this.VoiceWs_SocketErrored; }
// Token: 0x0600007E RID: 126 RVA: 0x000027F4 File Offset: 0x000009F4 internal VoiceNextConnection(DiscordClient client, DiscordGuild guild, DiscordChannel channel, VoiceNextConfiguration config, VoiceServerUpdatePayload server, VoiceStateUpdatePayload state) { this.Discord = client; this.Guild = guild; this.Channel = channel; this.TransmittingSSRCs = new ConcurrentDictionary <uint, AudioSender>(); this._userSpeaking = new AsyncEvent <UserSpeakingEventArgs>(new Action <string, Exception>(this.Discord.EventErrorHandler), "VNEXT_USER_SPEAKING"); this._userJoined = new AsyncEvent <VoiceUserJoinEventArgs>(new Action <string, Exception>(this.Discord.EventErrorHandler), "VNEXT_USER_JOINED"); this._userLeft = new AsyncEvent <VoiceUserLeaveEventArgs>(new Action <string, Exception>(this.Discord.EventErrorHandler), "VNEXT_USER_LEFT"); this._voiceReceived = new AsyncEvent <VoiceReceiveEventArgs>(new Action <string, Exception>(this.Discord.EventErrorHandler), "VNEXT_VOICE_RECEIVED"); this._voiceSocketError = new AsyncEvent <SocketErrorEventArgs>(new Action <string, Exception>(this.Discord.EventErrorHandler), "VNEXT_WS_ERROR"); this.TokenSource = new CancellationTokenSource(); this.Configuration = config; this.Opus = new Opus(this.AudioFormat); this.Rtp = new Rtp(); this.ServerData = server; this.StateData = state; string endpoint = this.ServerData.Endpoint; int num = endpoint.LastIndexOf(':'); string hostname = string.Empty; int port = 80; if (num != -1) { hostname = endpoint.Substring(0, num); port = int.Parse(endpoint.Substring(num + 1)); } else { hostname = endpoint; } ConnectionEndpoint webSocketEndpoint = default(ConnectionEndpoint); webSocketEndpoint.Hostname = hostname; webSocketEndpoint.Port = port; this.WebSocketEndpoint = webSocketEndpoint; this.ReadyWait = new TaskCompletionSource <bool>(); this.IsInitialized = false; this.IsDisposed = false; this.PlayingWait = null; this.PacketQueue = new ConcurrentQueue <VoicePacket>(); this.KeepaliveTimestamps = new ConcurrentDictionary <ulong, long>(); this.PauseEvent = new AsyncManualResetEvent(true); this.UdpClient = this.Discord.Configuration.UdpClientFactory.Invoke(); this.VoiceWs = this.Discord.Configuration.WebSocketClientFactory.Invoke(this.Discord.Configuration.Proxy); this.VoiceWs.Disconnected += new AsyncEventHandler <SocketCloseEventArgs>(this.VoiceWS_SocketClosed); this.VoiceWs.MessageReceived += new AsyncEventHandler <SocketMessageEventArgs>(this.VoiceWS_SocketMessage); this.VoiceWs.Connected += new AsyncEventHandler(this.VoiceWS_SocketOpened); this.VoiceWs.ExceptionThrown += new AsyncEventHandler <SocketErrorEventArgs>(this.VoiceWs_SocketException); }
/// <summary> /// Sends the VoiceServerUpdate to the corresponding Lavalink Node /// </summary> /// <param name="server">The updated VoiceServer payload</param> /// <returns>Task</returns> public Task VoiceServerUpdateAsync(VoiceServerUpdatePayload server) => GetNode(long.Parse(server.GuildId)).VoiceServerUpdateAsync(server);
/// <summary> /// Create a VoiceNext connection for the specified channel. /// </summary> /// <param name="channel">Channel to connect to.</param> /// <returns>VoiceNext connection for this channel.</returns> public async Task <VoiceNextConnection> ConnectAsync(DiscordChannel channel) { if (channel.Type != ChannelType.Voice) { throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be voice channel"); } if (channel.Parent == null) { throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be guild channel"); } var gld = channel.Parent; if (ActiveConnections.ContainsKey(gld.ID)) { throw new InvalidOperationException("This guild already has a voice connection"); } var vstut = new TaskCompletionSource <VoiceStateUpdateEventArgs>(); var vsrut = new TaskCompletionSource <VoiceServerUpdateEventArgs>(); this.VoiceStateUpdates[gld.ID] = vstut; this.VoiceServerUpdates[gld.ID] = vsrut; var vsd = new VoiceDispatch { OpCode = 4, Payload = new VoiceStateUpdatePayload { GuildId = gld.ID, ChannelId = channel.ID, Deafened = false, Muted = false } }; var vsj = JsonConvert.SerializeObject(vsd, Formatting.None); DiscordClient._websocketClient.SendMessage(vsj); var vstu = await vstut.Task; var vstup = new VoiceStateUpdatePayload { SessionId = vstu.SessionID, UserId = vstu.UserID }; var vsru = await vsrut.Task; var vsrup = new VoiceServerUpdatePayload { Endpoint = vsru.Endpoint, GuildId = vsru.GuildID, Token = vsru.VoiceToken }; var d1 = (TaskCompletionSource <VoiceStateUpdateEventArgs>)null; var d2 = (TaskCompletionSource <VoiceServerUpdateEventArgs>)null; this.VoiceStateUpdates.TryRemove(gld.ID, out d1); this.VoiceServerUpdates.TryRemove(gld.ID, out d2); var vnc = new VoiceNextConnection(this.Client, gld, channel, this.Configuration, vsrup, vstup); vnc.VoiceDisconnected += this.Vnc_VoiceDisconnected; await vnc.ConnectAsync(); await vnc.WaitForReady(); this.ActiveConnections[gld.ID] = vnc; return(vnc); }