/// <summary> /// Connects this Lavalink node to specified Discord channel. /// </summary> /// <param name="channel">Voice channel to connect to.</param> /// <returns>Channel connection, which allows for playback control.</returns> public async Task <LavalinkGuildConnection> ConnectAsync(DiscordChannel channel) { if (this._connectedGuilds.ContainsKey(channel.Guild.Id)) { return(this._connectedGuilds[channel.Guild.Id]); } if (channel.Guild == null || channel.Type != ChannelType.Voice) { throw new ArgumentException("Invalid channel specified.", nameof(channel)); } var vstut = new TaskCompletionSource <VoiceStateUpdateEventArgs>(); var vsrut = new TaskCompletionSource <VoiceServerUpdateEventArgs>(); this.VoiceStateUpdates[channel.Guild.Id] = vstut; this.VoiceServerUpdates[channel.Guild.Id] = vsrut; var vsd = new VoiceDispatch { OpCode = 4, Payload = new VoiceStateUpdatePayload { GuildId = channel.Guild.Id, ChannelId = channel.Id, Deafened = false, Muted = false } }; var vsj = JsonConvert.SerializeObject(vsd, Formatting.None); await(channel.Discord as DiscordClient).WsSendAsync(vsj).ConfigureAwait(false); var vstu = await vstut.Task.ConfigureAwait(false); var vsru = await vsrut.Task.ConfigureAwait(false); await this.SendPayloadAsync(new LavalinkVoiceUpdate(vstu, vsru)).ConfigureAwait(false); var con = new LavalinkGuildConnection(this, channel, vstu); con.ChannelDisconnected += this.Con_ChannelDisconnected; con.PlayerUpdated += (s, e) => this._playerUpdated.InvokeAsync(s, e); con.PlaybackStarted += (s, e) => this._playbackStarted.InvokeAsync(s, e); con.PlaybackFinished += (s, e) => this._playbackFinished.InvokeAsync(s, e); con.TrackStuck += (s, e) => this._trackStuck.InvokeAsync(s, e); con.TrackException += (s, e) => this._trackException.InvokeAsync(s, e); this._connectedGuilds[channel.Guild.Id] = con; return(con); }
private void Con_ChannelDisconnected(LavalinkGuildConnection con) => this._connectedGuilds.TryRemove(con.GuildId, out _);