Ejemplo n.º 1
0
        public static Task <DiscordVoiceSession> JoinVoiceChannelAsync(this DiscordSocketClient client, VoiceStateProperties properties)
        {
            if (!properties.ChannelProperty.Set || !properties.ChannelId.HasValue)
            {
                throw new ArgumentNullException("ChannelId can not be null");
            }

            properties.Fill(client);

            ulong guildId = properties.GuildId ?? 0;

            if (client.VoiceSessions.TryGetValue(guildId, out var oldSession))
            {
                oldSession.Disconnect();
            }

            CancellationTokenSource source = new CancellationTokenSource();
            TaskCompletionSource <DiscordVoiceSession> task = new TaskCompletionSource <DiscordVoiceSession>();

            void serverHandler(DiscordMediaSession session, DiscordMediaServer server)
            {
                source.Cancel();

                if (server.Endpoint != null)
                {
                    session.OnServerUpdated -= serverHandler;

                    if (task.Task.Status != TaskStatus.Faulted)
                    {
                        task.SetResult((DiscordVoiceSession)session);
                    }
                }
            }

            void stateHandler(DiscordSocketClient c, DiscordVoiceState state)
            {
                if (state.Channel != null && state.Channel.Id == properties.ChannelId.Value)
                {
                    client.OnSessionVoiceState -= stateHandler;

                    DiscordVoiceSession session = client.VoiceSessions[guildId] = new DiscordVoiceSession(client, properties.GuildId, properties.ChannelId.Value, state.SessionId);
                    session.OnDisconnected  += (s, args) => client.VoiceSessions.Remove(guildId);
                    session.OnServerUpdated += serverHandler;
                }
            }

            client.OnSessionVoiceState += stateHandler;

            client.ChangeVoiceState(properties);

            if (client.Config.VoiceChannelConnectTimeout > 0)
            {
                Task.Run(async() =>
                {
                    await Task.Delay(client.Config.VoiceChannelConnectTimeout, source.Token);

                    if (!source.IsCancellationRequested)
                    {
                        task.SetException(new TimeoutException("Gateway did not respond with a server"));
                    }
                });
            }

            return(task.Task);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Changes a client's voice state
 /// </summary>
 public static void ChangeVoiceState(this DiscordSocketClient client, VoiceStateProperties properties)
 {
     client.Send(GatewayOpcode.VoiceStateUpdate, properties.Fill(client));
 }