diff --git a/libs/DSharpPlus b/libs/DSharpPlus index 14fc3c9..28e7641 160000 --- a/libs/DSharpPlus +++ b/libs/DSharpPlus @@ -1 +1 @@ -Subproject commit 14fc3c92befe72787f0fcfcb8e59604a3dbfca65 +Subproject commit 28e764148249a77135b98420acb008d070e78420 diff --git a/src/DSharpPlus.VoiceLink/VoiceLinkConnection.cs b/src/DSharpPlus.VoiceLink/VoiceLinkConnection.cs index 65f91a1..0ac2979 100644 --- a/src/DSharpPlus.VoiceLink/VoiceLinkConnection.cs +++ b/src/DSharpPlus.VoiceLink/VoiceLinkConnection.cs @@ -312,31 +312,38 @@ await _webSocket.SendAsync(new VoiceGatewayDispatch() private async Task ReceiveAudioLoopAsync() { - while (!_cancellationTokenSource.IsCancellationRequested) + try { - // HEY. YOU. THE PERSON WHO'S TOUCHING THIS CODE. - // This is a hotpath. Any modifications to this code should always - // lead to equal or better performance. If you're not sure, don't touch it. - UdpReceiveResult udpReceiveResult = await _udpClient.ReceiveAsync(_cancellationTokenSource.Token); - if (RtpUtilities.IsRtpHeader(udpReceiveResult.Buffer)) + while (!_cancellationTokenSource.IsCancellationRequested) { - // When the VoiceLinkUser is not null, this means that voice data was - // successfully decrypted and decoded and is ready to be consumed by the dev. - VoiceLinkUser? voiceLinkUser = HandleRtpVoicePacket(udpReceiveResult.Buffer); - if (voiceLinkUser is not null) + // HEY. YOU. THE PERSON WHO'S TOUCHING THIS CODE. + // This is a hotpath. Any modifications to this code should always + // lead to equal or better performance. If you're not sure, don't touch it. + UdpReceiveResult udpReceiveResult = await _udpClient.ReceiveAsync(_cancellationTokenSource.Token); + if (RtpUtilities.IsRtpHeader(udpReceiveResult.Buffer)) { - await voiceLinkUser._audioPipe.Writer.FlushAsync(_cancellationTokenSource.Token); + // When the VoiceLinkUser is not null, this means that voice data was + // successfully decrypted and decoded and is ready to be consumed by the dev. + VoiceLinkUser? voiceLinkUser = HandleRtpVoicePacket(udpReceiveResult.Buffer); + if (voiceLinkUser is not null) + { + await voiceLinkUser._audioPipe.Writer.FlushAsync(_cancellationTokenSource.Token); + } + } + else if (RtcpUtilities.IsRtcpReceiverReport(udpReceiveResult.Buffer)) + { + HandleRtcpReceiverReportPacket(udpReceiveResult.Buffer); + } + else + { + _logger.LogWarning("Connection {GuildId}: Received an unknown packet with a length of {Length} bytes. It is not an RTP Header or a keep alive packet. Skipping.", Guild.Id, udpReceiveResult.Buffer.Length); + _logger.LogDebug("Connection {GuildId}: Packet: {Packet}", Guild.Id, udpReceiveResult.Buffer.Select(x => x.ToString("X2", CultureInfo.InvariantCulture))); } } - else if (RtcpUtilities.IsRtcpReceiverReport(udpReceiveResult.Buffer)) - { - HandleRtcpReceiverReportPacket(udpReceiveResult.Buffer); - } - else - { - _logger.LogWarning("Connection {GuildId}: Received an unknown packet with a length of {Length} bytes. It is not an RTP Header or a keep alive packet. Skipping.", Guild.Id, udpReceiveResult.Buffer.Length); - _logger.LogDebug("Connection {GuildId}: Packet: {Packet}", Guild.Id, udpReceiveResult.Buffer.Select(x => x.ToString("X2", CultureInfo.InvariantCulture))); - } + } + catch (OperationCanceledException) + { + return; } } diff --git a/src/DSharpPlus.VoiceLink/VoiceLinkExtension.cs b/src/DSharpPlus.VoiceLink/VoiceLinkExtension.cs index c7b2e6d..8afa3fc 100644 --- a/src/DSharpPlus.VoiceLink/VoiceLinkExtension.cs +++ b/src/DSharpPlus.VoiceLink/VoiceLinkExtension.cs @@ -79,7 +79,7 @@ public async Task ConnectAsync(DiscordChannel channel, Voic { throw new ArgumentNullException(nameof(channel)); } - else if (channel.Type is not ChannelType.Voice or ChannelType.Stage) + else if (channel.Type is not DiscordChannelType.Voice or DiscordChannelType.Stage) { throw new ArgumentException("Channel must be a voice or stage channel.", nameof(channel)); } @@ -96,18 +96,18 @@ public async Task ConnectAsync(DiscordChannel channel, Voic throw new InvalidOperationException($"The bot is already connected to a voice channel in guild {channel.Guild.Id}. The bot may only be connected to one voice channel per guild."); } - Permissions botPermissions = channel.PermissionsFor(channel.Guild.CurrentMember); - if (!botPermissions.HasPermission(Permissions.AccessChannels | Permissions.UseVoice)) + DiscordPermissions botPermissions = channel.PermissionsFor(channel.Guild.CurrentMember); + if (!botPermissions.HasPermission(DiscordPermissions.AccessChannels | DiscordPermissions.UseVoice)) { - throw new InvalidOperationException($"The bot must have the {Permissions.AccessChannels} and {Permissions.UseVoice} permissions to connect to a channel."); + throw new InvalidOperationException($"The bot must have the {DiscordPermissions.AccessChannels} and {DiscordPermissions.UseVoice} permissions to connect to a channel."); } - else if (!botPermissions.HasPermission(Permissions.Speak) && !voiceState.HasFlag(VoiceState.UserMuted)) + else if (!botPermissions.HasPermission(DiscordPermissions.Speak) && !voiceState.HasFlag(VoiceState.UserMuted)) { - throw new InvalidOperationException($"The bot must have the {Permissions.Speak} permission to speak in a voice channel."); + throw new InvalidOperationException($"The bot must have the {DiscordPermissions.Speak} permission to speak in a voice channel."); } - else if (channel.UserLimit >= channel.Users.Count && !botPermissions.HasPermission(Permissions.ManageChannels)) + else if (channel.UserLimit >= channel.Users.Count && !botPermissions.HasPermission(DiscordPermissions.ManageChannels)) { - throw new InvalidOperationException($"The voice channel is full and the bot must have the {Permissions.ManageChannels} permission to connect to override the channel user limit."); + throw new InvalidOperationException($"The voice channel is full and the bot must have the {DiscordPermissions.ManageChannels} permission to connect to override the channel user limit."); } _logger.LogDebug("Connecting to voice channel {ChannelId} in guild {GuildId}.", channel.Id, channel.Guild.Id);