Skip to content

Commit

Permalink
Reconnect voice session upon reconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
freyacodes committed Oct 5, 2023
1 parent e4f0769 commit f85a398
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public interface Link {
*/
public suspend fun onDisconnected()

/**
* Called internally when this link is connected or reconnected to a new node without resuming, thereby creating a
* new session.
*/
public suspend fun onNewSession()

/**
* Destroys this link (will no longer be usable).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,21 @@ public abstract class AbstractLavakord internal constructor(
guildId: ULong,
event: VoiceState
) {
link.node.updatePlayer(guildId, request = PlayerUpdate(voice = event.toOmissible()))
(link as AbstractLink).onVoiceServerUpdate(event)
}

/**
* Abstract function to create a new [Link] for this [guild][guildId] using this [node].
*/
protected abstract fun buildNewLink(guildId: ULong, node: Node): Link

/** Called on websocket connect without resuming */
internal suspend fun onNewSession(node: Node) {
if (!options.link.autoReconnect) return
linksMap.values.filter { it.node == node }.forEach {
launch {
it.onNewSession()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
package dev.schlaubi.lavakord.audio.internal

import dev.arbjerg.lavalink.protocol.v4.PlayerUpdate
import dev.arbjerg.lavalink.protocol.v4.VoiceState
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.rest.destroyPlayer
import dev.schlaubi.lavakord.rest.updatePlayer

/**
* Abstract implementation of [Link].
*/
public abstract class AbstractLink(final override val node: Node, final override val guildId: ULong) : Link {
public abstract class AbstractLink(node: Node, final override val guildId: ULong) : Link {

final override var node: Node = node
private set

override val player: Player = WebsocketPlayer(node as NodeImpl, guildId)
abstract override val lavakord: AbstractLavakord
override var lastChannelId: ULong? = null
override var state: Link.State = Link.State.NOT_CONNECTED
private var cachedVoiceState: VoiceState? = null

override suspend fun onDisconnected() {
state = Link.State.NOT_CONNECTED
node.destroyPlayer(guildId)
cachedVoiceState = null
}

override suspend fun onNewSession() {
cachedVoiceState?.let {
node.updatePlayer(guildId, request = PlayerUpdate(voice = it.toOmissible()))
}
}

override suspend fun destroy() {
Expand All @@ -29,4 +45,9 @@ public abstract class AbstractLink(final override val node: Node, final override
lavakord.removeDestroyedLink(this)
state = Link.State.DESTROYED
}

internal suspend fun onVoiceServerUpdate(update: VoiceState) {
cachedVoiceState = update
node.updatePlayer(guildId, request = PlayerUpdate(voice = update.toOmissible()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal class NodeImpl(

private suspend fun reconnect(e: Throwable? = null, resume: Boolean = false) {
if (retry.hasNext) {
LOG.error(e) { "Exception whilst trying to connect. Reconnecting" }
LOG.error { "Exception whilst trying to connect: '${e?.message}'. Reconnecting" }
retry.retry()
connect(resume)
} else {
Expand Down Expand Up @@ -181,6 +181,14 @@ internal class NodeImpl(
is Message.PlayerUpdateEvent -> (lavakord.getLink(event.guildId).player as WebsocketPlayer)
.provideState(event.state)

is Message.EmittedEvent.WebSocketClosedEvent -> {
// These codes represent an invalid session
// See https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes
if (event.code == 4004 || event.code == 4006 || event.code == 4009 || event.code == 4014) {
lavakord.getLink(event.guildId).onDisconnected()
}
}

is Message.StatsEvent -> {
LOG.debug { "Received node statistics for $name: $event" }
lastStatsEvent = event
Expand All @@ -193,6 +201,7 @@ internal class NodeImpl(
is Message.ReadyEvent -> {
available = true
sessionId = event.sessionId
lavakord.onNewSession(this)
updateSession(
SessionUpdate(
resuming = true.toOmissible(),
Expand Down

0 comments on commit f85a398

Please sign in to comment.