From bafcfc20232a82fe21bfc9c64b0e98ac3e07a61c Mon Sep 17 00:00:00 2001 From: Freya Arbjerg Date: Mon, 9 Oct 2023 13:53:08 +0200 Subject: [PATCH] Recreate player on reconnect --- .../dev/schlaubi/lavakord/audio/Link.kt | 3 ++- .../audio/internal/AbstractLavakord.kt | 2 +- .../lavakord/audio/internal/AbstractLink.kt | 7 +++++- .../audio/internal/WebsocketPlayer.kt | 22 ++++++++++++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt index 737c1b10..bdb6966d 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt @@ -49,8 +49,9 @@ public interface Link { /** * Called internally when this link is connected or reconnected to a new node without resuming, thereby creating a * new session. + * @param node The node that was connected to, which may be potentially different from the previously connected node */ - public suspend fun onNewSession() + public suspend fun onNewSession(node: Node) /** * Destroys this link (will no longer be usable). diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt index d624c4d8..d573066d 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt @@ -185,7 +185,7 @@ public abstract class AbstractLavakord internal constructor( if (!options.link.autoReconnect) return linksMap.values.filter { it.node == node }.forEach { launch { - it.onNewSession() + it.onNewSession(node) } } } diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt index c7c2216e..5ff57577 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt @@ -6,6 +6,7 @@ import dev.arbjerg.lavalink.protocol.v4.toOmissible import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Node import dev.schlaubi.lavakord.audio.player.Player +import dev.schlaubi.lavakord.audio.player.node import dev.schlaubi.lavakord.rest.destroyPlayer import dev.schlaubi.lavakord.rest.updatePlayer @@ -29,10 +30,14 @@ public abstract class AbstractLink(node: Node, final override val guildId: ULong cachedVoiceState = null } - override suspend fun onNewSession() { + override suspend fun onNewSession(node: Node) { + this.node = node + player.node + cachedVoiceState?.let { node.updatePlayer(guildId, request = PlayerUpdate(voice = it.toOmissible())) } + (player as WebsocketPlayer).recreatePlayer(node as NodeImpl) } override suspend fun destroy() { diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt index 3d75fea8..6c038f76 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt @@ -20,7 +20,9 @@ import kotlinx.datetime.Instant import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds -internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId: ULong) : Player { +internal class WebsocketPlayer(node: NodeImpl, internal val guildId: ULong) : Player { + internal var node: NodeImpl = node + private set override var playingTrack: Track? = null override val coroutineScope: CoroutineScope get() = node.coroutineScope @@ -35,6 +37,7 @@ internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId return (lastPosition + elapsedSinceUpdate).coerceAtMost(trackLength) } + private var specifiedEndTime: Duration? = null override val volume: Int get() = ((filters.volume ?: 1.0f) * 100).toInt() @@ -81,6 +84,7 @@ internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId filters = options.filters?.toLavalink().toOmissible() ) ) + specifiedEndTime = options.end } private fun handleNewTrack(event: TrackStartEvent) { @@ -93,6 +97,7 @@ internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId private fun handleTrackEnd(@Suppress("UNUSED_PARAMETER") event: TrackEndEvent) { playingTrack = null lastPosition = 0.milliseconds + specifiedEndTime = null } override suspend fun stopTrack() { @@ -125,4 +130,19 @@ internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId updateTime = Instant.fromEpochMilliseconds(state.time) lastPosition = state.position.milliseconds } + + internal suspend fun recreatePlayer(node: NodeImpl) { + this.node = node + val position = if (playingTrack == null) Omissible.omitted() else positionDuration.inWholeMilliseconds.toOmissible() + node.updatePlayer(guildId, noReplace = false, PlayerUpdate( + encodedTrack = playingTrack?.encoded.toOmissible(), + identifier = Omissible.omitted(), + position = position, + endTime = specifiedEndTime?.inWholeMilliseconds.toOmissible(), + volume = volume.toOmissible(), + paused = paused.toOmissible(), + filters = filters.toLavalink().toOmissible() + ) + ) + } }