From 7b83e3ce051986db4d3413d2b924def3a97b6e50 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Sun, 30 Apr 2023 17:22:47 +0200 Subject: reverted "Removed Discord Rich Presence since jitpack links are broken" and using a commit id for DiscordIPC import --- build.gradle.kts | 12 +- src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 3 +- .../features/misc/discordrpc/DiscordRPCManager.kt | 370 ++++++++++----------- 3 files changed, 193 insertions(+), 192 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 21038aaa7..b4816e042 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -55,12 +55,12 @@ dependencies { forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") // Discord RPC client -// shadowImpl("com.github.ILikePlayingGames:DiscordIPC:-SNAPSHOT") { -// exclude(module = "log4j") -// because("Different version conflicts with Minecraft's Log4J") -// exclude(module = "gson") -// because("Different version conflicts with Minecraft's Log4j") -// } + shadowImpl("com.github.ILikePlayingGames:DiscordIPC:f91ed4b") { + exclude(module = "log4j") + because("Different version conflicts with Minecraft's Log4J") + exclude(module = "gson") + because("Different version conflicts with Minecraft's Log4j") + } shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") { diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 57b0afa49..2d0bc3fb7 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -46,6 +46,7 @@ import at.hannibal2.skyhanni.features.itemabilities.abilitycooldown.ItemAbilityC import at.hannibal2.skyhanni.features.minion.MinionCollectLogic import at.hannibal2.skyhanni.features.minion.MinionFeatures import at.hannibal2.skyhanni.features.misc.* +import at.hannibal2.skyhanni.features.misc.discordrpc.DiscordRPCManager import at.hannibal2.skyhanni.features.misc.tiarelay.TiaRelayHelper import at.hannibal2.skyhanni.features.misc.tiarelay.TiaRelayWaypoints import at.hannibal2.skyhanni.features.misc.update.UpdateManager @@ -255,7 +256,7 @@ class SkyHanniMod { loadModule(AshfangMinisNametagHider()) loadModule(GardenTeleportPadInventoryNumber()) loadModule(ComposterOverlay()) -// loadModule(DiscordRPCManager()) + loadModule(DiscordRPCManager()) loadModule(GardenCropMilestoneFix()) loadModule(GardenBurrowingSporesNotifier()) loadModule(WildStrawberryDyeNotification()) 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 ec52288d0..7b4ded2a2 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 @@ -1,185 +1,185 @@ -//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.events.ConfigLoadEvent -//import at.hannibal2.skyhanni.utils.LorenzUtils -//import com.google.gson.JsonObject -//import com.jagrosh.discordipc.IPCClient -//import com.jagrosh.discordipc.IPCListener -//import com.jagrosh.discordipc.entities.RichPresence -//import io.github.moulberry.moulconfig.observer.Property -//import kotlinx.coroutines.launch -//import net.minecraftforge.event.world.WorldEvent -//import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -//import net.minecraftforge.fml.common.gameevent.TickEvent -//import net.minecraftforge.fml.common.network.FMLNetworkEvent -//import java.util.* -//import java.util.concurrent.Executors -//import java.util.concurrent.ScheduledExecutorService -//import java.util.concurrent.TimeUnit -// -//class DiscordRPCManager : IPCListener { -// private val applicationID = 653443797182578707L -// private val updatePeriod = 4200L -// -// private val config get() = feature.misc.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 updateTimer: Timer? = null -// private var connected = false -// -// private val DiscordLocationKey = DiscordLocationKey() -// -// private fun start() { -// coroutineScope.launch { -// try { -// if (isActive()) { -// return@launch -// } -// consoleLog("Starting Discord RPC...") -// -// firstLine = getStatusByConfigId(config.firstLine.get()) -// secondLine = getStatusByConfigId(config.secondLine.get()) -// startTimestamp = System.currentTimeMillis() -// client = IPCClient(applicationID) -// client?.setListener(this@DiscordRPCManager) // why must kotlin be this way -// -// try { -// client?.connect() -// } catch (ex: Exception) { -// consoleLog("Warn: Failed to connect to RPC!") -// consoleLog(ex.toString()) -// } -// } catch (ex: Throwable) { -// consoleLog("Warn: Discord RPC has thrown an unexpected error while trying to start...") -// consoleLog(ex.toString()) -// } -// } -// } -// -// private fun stop() { -// coroutineScope.launch { -// if (isActive()) { -// connected = false -// client?.close() -// startOnce = false -// } -// } -// } -// -// private fun isActive() = client != null && connected -// -// @SubscribeEvent -// fun onConfigLoad(event: ConfigLoadEvent) { -// for (property in listOf( -// config.firstLine, -// config.secondLine, -// config.customText, -// )) { -// property.whenChangedWithDifference { -// if (isActive()) { -// updatePresence() -// } -// } -// } -// config.enabled.whenChanged { _, new -> -// if (new) { -//// start() -// } else { -// stop() -// } -// } -// } -// -// fun Property<*>.whenChangedWithDifference(run: () -> (Unit)) { -// whenChanged { old, new -> if (old != new) run() } -// } -// -// fun updatePresence() { -// val location = LorenzUtils.skyBlockArea -// val discordIconKey = DiscordLocationKey.getDiscordIconKey(location) -// -// secondLine = getStatusByConfigId(config.secondLine.get()) -// firstLine = getStatusByConfigId(config.firstLine.get()) -// val presence: RichPresence = RichPresence.Builder() -// .setDetails(firstLine.getDisplayString()) -// .setState(secondLine.getDisplayString()) -// .setStartTimestamp(startTimestamp!!) -// .setLargeImage(discordIconKey, location) -// .build() -// client?.sendRichPresence(presence) -// } -// -// override fun onReady(client: IPCClient) { -// consoleLog("Discord RPC Started.") -// connected = true -// updateTimer = Timer() -// updateTimer?.schedule(object : TimerTask() { -// override fun run() { -// updatePresence() -// } -// }, 0, updatePeriod) -// } -// -// override fun onClose(client: IPCClient, json: JsonObject) { -// consoleLog("Discord RPC closed.") -// this.client = null -// connected = false -// cancelTimer() -// } -// -// override fun onDisconnect(client: IPCClient?, t: Throwable?) { -// consoleLog("Discord RPC disconnected.") -// this.client = null -// connected = false -// cancelTimer() -// } -// -// private fun cancelTimer() { -// updateTimer?.let { -// it.cancel() -// updateTimer = null -// } -// } -// -// private fun getStatusByConfigId(id: Int) = DiscordStatus.values().getOrElse(id) { DiscordStatus.NONE } -// -// private fun isEnabled() = config.enabled.get() -// -// @SubscribeEvent -// fun onTick(event: TickEvent.ClientTickEvent) { -// 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. -// if (LorenzUtils.inSkyBlock) { -// start() -// startOnce = true -// } -// } -// -// @SubscribeEvent -// fun onWorldChange(event: WorldEvent.Load) { -// 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 -// } -// -// @SubscribeEvent -// fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { -// stop() -// } -//} +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.events.ConfigLoadEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import com.google.gson.JsonObject +import com.jagrosh.discordipc.IPCClient +import com.jagrosh.discordipc.IPCListener +import com.jagrosh.discordipc.entities.RichPresence +import io.github.moulberry.moulconfig.observer.Property +import kotlinx.coroutines.launch +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import net.minecraftforge.fml.common.network.FMLNetworkEvent +import java.util.* +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.TimeUnit + +class DiscordRPCManager : IPCListener { + private val applicationID = 653443797182578707L + private val updatePeriod = 4200L + + private val config get() = feature.misc.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 updateTimer: Timer? = null + private var connected = false + + private val DiscordLocationKey = DiscordLocationKey() + + private fun start() { + coroutineScope.launch { + try { + if (isActive()) { + return@launch + } + consoleLog("Starting Discord RPC...") + + firstLine = getStatusByConfigId(config.firstLine.get()) + secondLine = getStatusByConfigId(config.secondLine.get()) + startTimestamp = System.currentTimeMillis() + client = IPCClient(applicationID) + client?.setListener(this@DiscordRPCManager) // why must kotlin be this way + + try { + client?.connect() + } catch (ex: Exception) { + consoleLog("Warn: Failed to connect to RPC!") + consoleLog(ex.toString()) + } + } catch (ex: Throwable) { + consoleLog("Warn: Discord RPC has thrown an unexpected error while trying to start...") + consoleLog(ex.toString()) + } + } + } + + private fun stop() { + coroutineScope.launch { + if (isActive()) { + connected = false + client?.close() + startOnce = false + } + } + } + + private fun isActive() = client != null && connected + + @SubscribeEvent + fun onConfigLoad(event: ConfigLoadEvent) { + for (property in listOf( + config.firstLine, + config.secondLine, + config.customText, + )) { + property.whenChangedWithDifference { + if (isActive()) { + updatePresence() + } + } + } + config.enabled.whenChanged { _, new -> + if (new) { +// start() + } else { + stop() + } + } + } + + fun Property<*>.whenChangedWithDifference(run: () -> (Unit)) { + whenChanged { old, new -> if (old != new) run() } + } + + fun updatePresence() { + val location = LorenzUtils.skyBlockArea + val discordIconKey = DiscordLocationKey.getDiscordIconKey(location) + + secondLine = getStatusByConfigId(config.secondLine.get()) + firstLine = getStatusByConfigId(config.firstLine.get()) + val presence: RichPresence = RichPresence.Builder() + .setDetails(firstLine.getDisplayString()) + .setState(secondLine.getDisplayString()) + .setStartTimestamp(startTimestamp!!) + .setLargeImage(discordIconKey, location) + .build() + client?.sendRichPresence(presence) + } + + override fun onReady(client: IPCClient) { + consoleLog("Discord RPC Started.") + connected = true + updateTimer = Timer() + updateTimer?.schedule(object : TimerTask() { + override fun run() { + updatePresence() + } + }, 0, updatePeriod) + } + + override fun onClose(client: IPCClient, json: JsonObject) { + consoleLog("Discord RPC closed.") + this.client = null + connected = false + cancelTimer() + } + + override fun onDisconnect(client: IPCClient?, t: Throwable?) { + consoleLog("Discord RPC disconnected.") + this.client = null + connected = false + cancelTimer() + } + + private fun cancelTimer() { + updateTimer?.let { + it.cancel() + updateTimer = null + } + } + + private fun getStatusByConfigId(id: Int) = DiscordStatus.values().getOrElse(id) { DiscordStatus.NONE } + + private fun isEnabled() = config.enabled.get() + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + 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. + if (LorenzUtils.inSkyBlock) { + start() + startOnce = true + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + 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 + } + + @SubscribeEvent + fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { + stop() + } +} -- cgit