diff --git a/src/main/kotlin/com/lambda/module/modules/client/Discord.kt b/src/main/kotlin/com/lambda/module/modules/client/Discord.kt index 254a0eea4..05f2a9de7 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/Discord.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/Discord.kt @@ -38,13 +38,13 @@ import dev.cbyrne.kdiscordipc.core.packet.inbound.impl.AuthenticatePacket import dev.cbyrne.kdiscordipc.data.activity.largeImage import dev.cbyrne.kdiscordipc.data.activity.smallImage import dev.cbyrne.kdiscordipc.data.activity.timestamps +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.delay object Discord : Module( name = "Discord", description = "Discord Rich Presence configuration", - tag = ModuleTag.CLIENT, - enabledByDefault = true, + tag = ModuleTag.CLIENT ) { private val delay by setting("Update Delay", 5000L, 5000L..30000L, 100L, unit = "ms") private val showTime by setting("Show Time", true, description = "Show how long you have been playing for.") @@ -53,7 +53,7 @@ object Discord : Module( private val line2Left by setting("Line 2 Left", LineInfo.Version) private val line2Right by setting("Line 2 Right", LineInfo.Fps) - val rpc = KDiscordIPC(Lambda.APP_ID, scope = EventFlow.lambdaScope) + var rpc: KDiscordIPC? = null private var startup = System.currentTimeMillis() @@ -67,36 +67,58 @@ object Discord : Module( return@listenOnce true } - onEnable { runConcurrent { start(); handleLoop() } } - runConcurrent { start() } + onEnable { + runConcurrent { + if (start()) handleLoop() + } + } onDisable { stop() } } - private suspend fun start() { - if (rpc.connected) return - - rpc.connect() + private suspend fun start(): Boolean { + if (rpc == null) { + rpc = KDiscordIPC(Lambda.APP_ID, scope = EventFlow.lambdaScope) + } + if (rpc!!.connected) return true + + try { + rpc!!.connect() + } catch (t: Throwable) { + if (t is CancellationException) throw t + LOG.warn(t) + warn("Failed to connect to Discord. Make sure Discord is open and can access temporary files.") + return false + } - val auth = rpc.applicationManager.authenticate() + val auth = try { + rpc!!.applicationManager.authenticate() + } catch (t: Throwable) { + if (t is CancellationException) throw t + LOG.warn(t) + warn("Connected to Discord but authentication failed.") + return false + } linkDiscord(discordToken = auth.accessToken) .onSuccess { updateToken(it); discordAuth = auth } .onFailure { LOG.error(it); warn("Failed to link your discord account") } + + return true } private fun stop() { - if (rpc.connected) rpc.disconnect() + if (rpc?.connected == true) rpc?.disconnect() } private suspend fun SafeContext.handleLoop() { - while (rpc.connected) { + while (rpc?.connected == true) { update() delay(delay) } } private suspend fun SafeContext.update() { - rpc.activityManager.setActivity { + rpc?.activityManager?.setActivity { details = "${line1Left.value(this@update)} | ${line1Right.value(this@update)}".take(128) state = "${line2Left.value(this@update)} | ${line2Right.value(this@update)}".take(128)