From 39fec52855fe81e2c39c4a1628542e6e30626df3 Mon Sep 17 00:00:00 2001 From: Deftu Date: Wed, 11 Dec 2024 04:52:05 +0200 Subject: [PATCH] Further cleanup, Mixins TBD --- .../org/polyfrost/crashpatch/CrashPatch.kt | 16 ++++- .../polyfrost/crashpatch/CrashPatchCommand.kt | 7 +-- .../{CrashHelper.kt => CrashScanStorage.kt} | 59 ++++++++++++------- .../org/polyfrost/crashpatch/gui/CrashUI.kt | 4 +- .../crashpatch/utils/GuiDisconnectedHook.kt | 2 +- 5 files changed, 57 insertions(+), 31 deletions(-) rename src/main/kotlin/org/polyfrost/crashpatch/crashes/{CrashHelper.kt => CrashScanStorage.kt} (76%) diff --git a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt index 53a77c8..364089d 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt @@ -10,8 +10,7 @@ import org.apache.logging.log4j.LogManager //#endif import java.io.File -import org.polyfrost.crashpatch.config.CrashPatchConfig -import org.polyfrost.crashpatch.crashes.CrashHelper +import org.polyfrost.crashpatch.crashes.CrashScanStorage import org.polyfrost.crashpatch.crashes.DeobfuscatingRewritePolicy import org.polyfrost.oneconfig.api.commands.v1.CommandManager import org.polyfrost.oneconfig.utils.v1.Multithreading @@ -35,6 +34,17 @@ object CrashPatch File(System.getProperty("user.dir")) } + val gameDir by lazy(LazyThreadSafetyMode.PUBLICATION) { + try { + if (mcDir.parentFile?.name?.let { name -> + name == ".minecraft" || name == "minecraft" + } == true) mcDir.parentFile else mcDir + } catch (e: Exception) { + e.printStackTrace() + mcDir + } + } + val isSkyclient by lazy(LazyThreadSafetyMode.PUBLICATION) { File(mcDir, "OneConfig/CrashPatch/SKYCLIENT").exists() || File(mcDir, "W-OVERFLOW/CrashPatch/SKYCLIENT").exists() } @@ -45,7 +55,7 @@ object CrashPatch DeobfuscatingRewritePolicy.install() Multithreading.submit { logger.info("Is SkyClient: $isSkyclient") - if (!CrashHelper.loadJson()) { + if (!CrashScanStorage.downloadJson()) { logger.error("CrashHelper failed to preload crash data JSON!") } } diff --git a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatchCommand.kt b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatchCommand.kt index b8a68e6..ccd0f0a 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatchCommand.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatchCommand.kt @@ -1,8 +1,7 @@ package org.polyfrost.crashpatch import net.minecraft.util.ChatComponentText -import org.polyfrost.crashpatch.config.CrashPatchConfig -import org.polyfrost.crashpatch.crashes.CrashHelper +import org.polyfrost.crashpatch.crashes.CrashScanStorage import org.polyfrost.oneconfig.api.commands.v1.factories.annotated.Command import org.polyfrost.universal.ChatColor import org.polyfrost.universal.UMinecraft @@ -18,8 +17,8 @@ object CrashPatchCommand { @Command fun reload() { - if (CrashHelper.loadJson()) { - CrashHelper.simpleCache.clear() + if (CrashScanStorage.downloadJson()) { + CrashScanStorage.simpleCache.clear() UMinecraft.getMinecraft().thePlayer.addChatMessage(ChatComponentText("${ChatColor.RED}[CrashPatch] Successfully reloaded JSON file!")) } else { UMinecraft.getMinecraft().thePlayer.addChatMessage(ChatComponentText("${ChatColor.RED}[CrashPatch] Failed to reload the JSON file!")) diff --git a/src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashHelper.kt b/src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashScanStorage.kt similarity index 76% rename from src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashHelper.kt rename to src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashScanStorage.kt index 82da599..0d139e7 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashHelper.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/crashes/CrashScanStorage.kt @@ -2,51 +2,63 @@ package org.polyfrost.crashpatch.crashes import org.polyfrost.universal.wrappers.message.UTextComponent import com.google.gson.JsonObject +import org.apache.logging.log4j.LogManager +import org.polyfrost.crashpatch.CrashPatch import org.polyfrost.oneconfig.utils.v1.JsonUtils import java.io.File import kotlin.collections.set -object CrashHelper { +object CrashScanStorage { - private var skyclientJson: JsonObject? = null - val simpleCache = hashMapOf() + private val logger = LogManager.getLogger() + + private val cacheFile by lazy(LazyThreadSafetyMode.PUBLICATION) { + File(CrashPatch.mcDir, "OneConfig/CrashPatch/cache.json") + } + + private val String.mappedPlaceholders: String + get() = this + .replace("%pathindicator%", "") + .replace("%gameroot%", CrashPatch.gameDir.absolutePath.removeSuffix(File.separator)) + .replace("%profileroot%", File(CrashPatch.mcDir, "OneConfig").parentFile.absolutePath.removeSuffix(File.separator)) + + private var skyclientData: JsonObject? = null @JvmStatic - fun loadJson(): Boolean { + fun downloadJson(): Boolean { return try { - skyclientJson = - JsonUtils.parseFromUrl("https://raw.githubusercontent.com/SkyblockClient/CrashData/main/crashes.json")?.asJsonObject ?: return false + skyclientData = JsonUtils.parseFromUrl("https://raw.githubusercontent.com/SkyblockClient/CrashData/main/crashes.json") + ?.asJsonObject ?: return false + cacheFile.writeText(skyclientData.toString()) true } catch (e: Exception) { - e.printStackTrace() - false + logger.error("Failed to download crash data JSON!", e) + cacheFile.takeIf { it.exists() }?.let { + logger.info("Attempting to load cached crash data JSON...") + skyclientData = JsonUtils.parseOrNull(it.readText())?.asJsonObject + + skyclientData != null + } ?: false } } @JvmStatic fun scanReport(report: String, serverCrash: Boolean = false): CrashScan? { return try { - if (simpleCache.containsKey(report)) { - return simpleCache[report] - } val responses = getResponses(report, serverCrash) CrashScan(responses.also { it[if (serverCrash) "Disconnect reason" else "Crash log"] = report.split("\\R".toRegex()) }.toSortedMap { o1, o2 -> if (o1 == "Crash log" || o1 == "Disconnect reason") { return@toSortedMap 1 } + if (o2 == "Crash log" || o2 == "Disconnect reason") { return@toSortedMap -1 } + return@toSortedMap o1.compareTo(o2) }.map { map -> - CrashScan.Solution("${map.key} (${map.value.size})", map.value.map { - it.replace("%pathindicator%", "").replace( - "%gameroot%", gameDir.absolutePath.removeSuffix( - File.separator - ) - ).replace("%profileroot%", File(mcDir, "OneConfig").parentFile.absolutePath.removeSuffix(File.separator)) - }, true) - }.toMutableList()).also { simpleCache[report] = it } + CrashScan.Solution("${map.key} (${map.value.size})", map.value.map { entry -> entry.mappedPlaceholders }, true) + }.toMutableList()) } catch (e: Throwable) { e.printStackTrace() null @@ -54,7 +66,7 @@ object CrashHelper { } private fun getResponses(report: String, serverCrash: Boolean): MutableMap> { - val issues = skyclientJson ?: return linkedMapOf() + val issues = skyclientData ?: return linkedMapOf() val responses = linkedMapOf>() val triggersToIgnore = arrayListOf() @@ -74,6 +86,7 @@ object CrashHelper { } else { triggersToIgnore.add(index) } + responses[type["name"].asString] = arrayListOf() } @@ -83,11 +96,13 @@ object CrashHelper { for (solution in fixes) { val solutionJson = solution.asJsonObject if (solutionJson.has("bot_only")) continue + val triggerNumber = if (solutionJson.has("fixtype")) solutionJson["fixtype"].asInt else issues["default_fix_type"].asInt if (triggersToIgnore.contains(triggerNumber)) { continue } + val causes = solutionJson["causes"].asJsonArray var trigger = false for (cause in causes) { @@ -96,6 +111,7 @@ object CrashHelper { if (causeJson.has("unformatted") && causeJson["unformatted"].asBoolean) { theReport = UTextComponent.stripFormatting(theReport) } + when (causeJson["method"].asString) { "contains" -> { if (theReport.contains(causeJson["value"].asString)) { @@ -134,11 +150,12 @@ object CrashHelper { } } } + if (trigger) { responses[responseCategories[triggerNumber]]?.add(solutionJson["fix"].asString) } - } + return responses.filterNot { it.value.isEmpty() }.toMutableMap() } } diff --git a/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashUI.kt b/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashUI.kt index cffc468..7030da0 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashUI.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashUI.kt @@ -4,7 +4,7 @@ import dev.deftu.clipboard.Clipboard import net.minecraft.client.gui.GuiScreen import net.minecraft.crash.CrashReport import org.polyfrost.crashpatch.CrashPatch -import org.polyfrost.crashpatch.crashes.CrashHelper +import org.polyfrost.crashpatch.crashes.CrashScanStorage import org.polyfrost.crashpatch.crashes.CrashScan import org.polyfrost.crashpatch.hooks.CrashReportHook import org.polyfrost.crashpatch.utils.UploadUtils @@ -53,7 +53,7 @@ class CrashUI @JvmOverloads constructor( } private val crashScan: CrashScan? by lazy { - return@lazy CrashHelper.scanReport(scanText, type == GuiType.DISCONNECT) + return@lazy CrashScanStorage.scanReport(scanText, type == GuiType.DISCONNECT) .let { return@let if (it != null && it.solutions.isNotEmpty()) it else null } } var shouldCrash = false diff --git a/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt b/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt index ade2a77..c89e5e9 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt @@ -1,6 +1,6 @@ package org.polyfrost.crashpatch.utils -import org.polyfrost.crashpatch.crashes.CrashHelper.scanReport +import org.polyfrost.crashpatch.crashes.CrashScanStorage.scanReport import org.polyfrost.crashpatch.mixin.AccessorGuiDisconnected import net.minecraft.client.gui.GuiDisconnected import net.minecraft.client.gui.GuiScreen