コード例 #1
0
ファイル: Player.cs プロジェクト: lavalibs/Lavalink.NET
		/// <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
			});
コード例 #2
0
        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;
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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;
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        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;
        }
コード例 #7
0
        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;
        }
コード例 #8
0
        // 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);
        }
コード例 #9
0
 /// <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);
コード例 #10
0
        /// <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);
        }