diff options
author | Brady <thatgravyboat@gmail.com> | 2024-04-30 14:49:15 -0230 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-30 19:19:15 +0200 |
commit | 8071da11713602d34cf93413e51da85a2a12530d (patch) | |
tree | 6c0f29c529f19d2023d185bda83ed94af4c4f157 | |
parent | ab49f89977c19cc8eba7911c073a9d74ede1eadf (diff) | |
download | skyhanni-8071da11713602d34cf93413e51da85a2a12530d.tar.gz skyhanni-8071da11713602d34cf93413e51da85a2a12530d.tar.bz2 skyhanni-8071da11713602d34cf93413e51da85a2a12530d.zip |
Improvements: Cleanup RPC (#1570)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
4 files changed, 80 insertions, 110 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 56751ad38..97360c3d9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,7 +80,7 @@ dependencies { forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") // Discord RPC client - shadowImpl("com.jagrosh:DiscordIPC:0.5") { + shadowImpl("com.jagrosh:DiscordIPC:0.5.2") { exclude(module = "log4j") because("Different version conflicts with Minecraft's Log4J") exclude(module = "gson") diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordLocationKey.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordLocationKey.kt index ef1bf0c12..baeb1df04 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordLocationKey.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordLocationKey.kt @@ -3,11 +3,8 @@ package at.hannibal2.skyhanni.features.misc.discordrpc import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.features.dungeon.DungeonAPI import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern -class DiscordLocationKey { - - private val rpcGroup = RepoPattern.group("misc.discordrpc") +object DiscordLocationKey { // normal keys follow a distinct pattern: lowercase the skyblock location and replace spaces with - private val normalRPC = setOf( diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt index 2f8b40212..8aa031b2d 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/discordrpc/DiscordRPCManager.kt @@ -2,9 +2,9 @@ package at.hannibal2.skyhanni.features.misc.discordrpc // This entire file was taken from SkyblockAddons code, ported to SkyHanni -import at.hannibal2.skyhanni.SkyHanniMod.Companion.consoleLog import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope import at.hannibal2.skyhanni.SkyHanniMod.Companion.feature +import at.hannibal2.skyhanni.SkyHanniMod.Companion.logger import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.LineEntry import at.hannibal2.skyhanni.config.features.misc.DiscordRPCConfig.PriorityEntry @@ -21,6 +21,7 @@ import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.ConditionalUtils import at.hannibal2.skyhanni.utils.ConfigUtils +import at.hannibal2.skyhanni.utils.DelayedRun import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.SimpleTimeMark import com.google.gson.JsonObject @@ -28,98 +29,82 @@ import com.jagrosh.discordipc.IPCClient import com.jagrosh.discordipc.IPCListener import com.jagrosh.discordipc.entities.RichPresence import com.jagrosh.discordipc.entities.RichPresenceButton +import com.jagrosh.discordipc.entities.pipe.PipeStatus import kotlinx.coroutines.launch import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.network.FMLNetworkEvent -import java.util.concurrent.Executors -import java.util.concurrent.ScheduledExecutorService -import java.util.concurrent.TimeUnit +import kotlin.time.Duration.Companion.seconds object DiscordRPCManager : IPCListener { - private const val applicationID = 1093298182735282176L + private const val APPLICATION_ID = 1093298182735282176L val config get() = feature.gui.discordRPC private var client: IPCClient? = null - private lateinit var secondLine: DiscordStatus - private lateinit var firstLine: DiscordStatus - private var startTimestamp: Long? = null - private var startOnce = false - - private var runTimer = false - private var connected = false - - private val DiscordLocationKey = DiscordLocationKey() + private var startTimestamp: Long = 0 + private var started = false + private var nextUpdate: SimpleTimeMark = SimpleTimeMark.farPast() var stackingEnchants: Map<String, StackingEnchantData> = emptyMap() fun start(fromCommand: Boolean = false) { coroutineScope.launch { try { - if (isActive()) { - return@launch - } - consoleLog("Starting Discord RPC...") - // TODO, change functionality to use enum rather than ordinals - firstLine = getStatusByConfigId(config.firstLine.get().ordinal) - secondLine = getStatusByConfigId(config.secondLine.get().ordinal) + if (isConnected()) return@launch + + logger.info("Starting Discord RPC...") startTimestamp = System.currentTimeMillis() - client = IPCClient(applicationID) - client?.setListener(this@DiscordRPCManager) - - try { - client?.connect() - if (fromCommand) ChatUtils.chat( - "Successfully started Rich Presence!", - prefixColor = "§a" - ) // confirm that /shrpcstart worked - } catch (ex: Exception) { - consoleLog("Warn: Failed to connect to RPC!") - consoleLog(ex.toString()) - ChatUtils.clickableChat( - "Discord Rich Presence was unable to start! " + - "This usually happens when you join SkyBlock when Discord is not started. " + - "Please run /shrpcstart to retry once you have launched Discord.", - onClick = { - startCommand() - } - ) - } + client = IPCClient(APPLICATION_ID) + client?.setup(fromCommand) } catch (ex: Throwable) { - consoleLog("Warn: Discord RPC has thrown an unexpected error while trying to start...") - consoleLog(ex.toString()) + logger.warn("Discord RPC has thrown an unexpected error while trying to start...", ex) } } } private fun stop() { coroutineScope.launch { - if (isActive()) { - connected = false + if (isConnected()) { client?.close() - startOnce = false + started = false } } } - private fun isActive() = client != null && connected + private fun IPCClient.setup(fromCommand: Boolean) { + setListener(DiscordRPCManager) + + try { + connect() + if (!fromCommand) return + + // confirm that /shrpcstart worked + ChatUtils.chat("Successfully started Rich Presence!", prefixColor = "§a") + } catch (ex: Exception) { + logger.warn("Failed to connect to RPC!", ex) + ChatUtils.clickableChat( + "Discord Rich Presence was unable to start! " + + "This usually happens when you join SkyBlock when Discord is not started. " + + "Please run /shrpcstart to retry once you have launched Discord.", + onClick = { + startCommand() + } + ) + } + } + + private fun isConnected() = client?.status == PipeStatus.CONNECTED @SubscribeEvent fun onConfigLoad(event: ConfigLoadEvent) { - ConditionalUtils.onToggle( - config.firstLine, - config.secondLine, - config.customText - ) { - if (isActive()) { + ConditionalUtils.onToggle(config.firstLine, config.secondLine, config.customText) { + if (isConnected()) { updatePresence() } } config.enabled.whenChanged { _, new -> - if (new) { -// start() - } else { + if (!new) { stop() } } @@ -133,82 +118,68 @@ object DiscordRPCManager : IPCListener { private fun updatePresence() { val location = DiscordStatus.LOCATION.getDisplayString() val discordIconKey = DiscordLocationKey.getDiscordIconKey(location) - // TODO, change functionality to use enum rather than ordinals - secondLine = getStatusByConfigId(config.secondLine.get().ordinal) - firstLine = getStatusByConfigId(config.firstLine.get().ordinal) - - var presence = RichPresence.Builder() - .setDetails(firstLine.getDisplayString()) - .setState(secondLine.getDisplayString()) - .setStartTimestamp(startTimestamp!!) - .setLargeImage(discordIconKey, location) - if (config.showSkyCryptButton.get()) { - val skyCryptUrl = "https://sky.shiiyu.moe/stats/${LorenzUtils.getPlayerName()}/${HypixelData.profileName}" - presence = presence.setButtons(arrayOf( - RichPresenceButton(skyCryptUrl, "Open SkyCrypt Profile") - )) - } - - client?.sendRichPresence(presence.build()) + client?.sendRichPresence(RichPresence.Builder().apply { + setDetails(getStatusByConfigId(config.firstLine.get()).getDisplayString()) + setState(getStatusByConfigId(config.secondLine.get()).getDisplayString()) + setStartTimestamp(startTimestamp) + setLargeImage(discordIconKey, location) + + if (config.showSkyCryptButton.get()) { + addButton(RichPresenceButton( + "https://sky.shiiyu.moe/stats/${LorenzUtils.getPlayerName()}/${HypixelData.profileName}", + "Open SkyCrypt Profile" + )) + } + }.build()) } override fun onReady(client: IPCClient) { - consoleLog("Discord RPC Started.") - connected = true - runTimer = true + logger.info("Discord RPC Ready.") } @SubscribeEvent fun onSecondPassed(event: SecondPassedEvent) { - if (!runTimer) return + if (!isConnected()) return if (event.repeatSeconds(5)) { updatePresence() } } override fun onClose(client: IPCClient, json: JsonObject?) { - consoleLog("Discord RPC closed.") + logger.info("Discord RPC closed.") this.client = null - connected = false - cancelTimer() } override fun onDisconnect(client: IPCClient?, t: Throwable?) { - consoleLog("Discord RPC disconnected.") + logger.info("Discord RPC disconnected.") this.client = null - connected = false - cancelTimer() } - private fun cancelTimer() { - runTimer = false - } - - private fun getStatusByConfigId(id: Int) = DiscordStatus.entries.getOrElse(id) { DiscordStatus.NONE } + private fun getStatusByConfigId(entry: LineEntry) = + DiscordStatus.entries.getOrElse(entry.ordinal) { DiscordStatus.NONE } private fun isEnabled() = config.enabled.get() @SubscribeEvent fun onTick(event: LorenzTickEvent) { - if (startOnce || !isEnabled()) return // the mod has already started the connection process. this variable is my way of running a function when the player joins SkyBlock but only running it again once they join and leave. + // the mod has already started the connection process. this variable is my way of running a function when + // the player joins SkyBlock but only running it again once they join and leave. + if (started || !isEnabled()) return if (LorenzUtils.inSkyBlock) { start() - startOnce = true + started = true } } @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { - val executor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() - executor.schedule( - { - if (!LorenzUtils.inSkyBlock) { - stop() - } - }, - 5, - TimeUnit.SECONDS - ) // wait 5 seconds to check if the new world is skyblock or not before stopping the function + if (nextUpdate.isInFuture()) return + // wait 5 seconds to check if the new world is skyblock or not before stopping the function + nextUpdate = DelayedRun.runDelayed(5.seconds) { + if (!LorenzUtils.inSkyBlock) { + stop() + } + } } @SubscribeEvent @@ -217,12 +188,12 @@ object DiscordRPCManager : IPCListener { } fun startCommand() { - if (!config.enabled.get()) { + if (!isEnabled()) { ChatUtils.userError("Discord Rich Presence is disabled. Enable it in the config §e/sh discord") return } - if (isActive()) { + if (isConnected()) { ChatUtils.userError("Discord Rich Presence is already active!") return } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt index 0b4c3adc9..eb83bce3a 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/DelayedRun.kt @@ -10,8 +10,10 @@ object DelayedRun { private val tasks = mutableListOf<Pair<() -> Any, SimpleTimeMark>>() private val futureTasks = ConcurrentLinkedQueue<Pair<() -> Any, SimpleTimeMark>>() - fun runDelayed(duration: Duration, run: () -> Unit) { - futureTasks.add(Pair(run, SimpleTimeMark.now() + duration)) + fun runDelayed(duration: Duration, run: () -> Unit): SimpleTimeMark { + val time = SimpleTimeMark.now() + duration + futureTasks.add(Pair(run, time)) + return time } /** Runs in the next full Tick so the delay is between 50ms to 100ms**/ |