Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recreate player on reconnect #30

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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) {
Expand All @@ -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() {
Expand Down Expand Up @@ -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()
)
)
}
}