From 00358fd08d6234521a487f456a1291294142d9f0 Mon Sep 17 00:00:00 2001 From: ev chang Date: Mon, 6 Jan 2025 11:19:25 -0500 Subject: [PATCH] 2.0.2 add more try catches for crashgui crashes --- gradle.properties | 2 +- .../crashpatch/hooks/MinecraftHook.java | 1 + .../crashpatch/mixin/MixinMinecraft.java | 122 +++++++++++------- .../org/polyfrost/crashpatch/gui/CrashGui.kt | 12 +- .../crashpatch/utils/GuiDisconnectedHook.kt | 8 +- 5 files changed, 94 insertions(+), 51 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5c335ba..23b3c2b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ mod_id=crashpatch mod_name=CrashPatch -mod_version=2.0.1 +mod_version=2.0.2 mod_archives_name=CrashPatch # Gradle Configuration -- DO NOT TOUCH THESE VALUES. diff --git a/src/main/java/org/polyfrost/crashpatch/hooks/MinecraftHook.java b/src/main/java/org/polyfrost/crashpatch/hooks/MinecraftHook.java index 6be6ab8..4000a19 100644 --- a/src/main/java/org/polyfrost/crashpatch/hooks/MinecraftHook.java +++ b/src/main/java/org/polyfrost/crashpatch/hooks/MinecraftHook.java @@ -2,4 +2,5 @@ public interface MinecraftHook { boolean hasRecoveredFromCrash(); + void crashPatch$die(); } diff --git a/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java b/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java index 91b6d7f..86e89b6 100644 --- a/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java +++ b/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java @@ -54,6 +54,7 @@ import java.util.Objects; import java.util.Queue; import java.util.concurrent.FutureTask; +import java.util.function.Supplier; @Mixin(value = Minecraft.class, priority = -9000) public abstract class MixinMinecraft implements MinecraftHook { @@ -232,6 +233,7 @@ private void onGUIDisplay(GuiScreen i, CallbackInfo ci) { } catch (Throwable t) { // The crash screen has crashed. Report it normally instead. logger.error("An uncaught exception occured while displaying the crash screen, making normal report instead", t); + crashpatch$letDie = true; displayCrashReport(report); System.exit(report.getFile() != null ? -1 : -2); } @@ -330,7 +332,7 @@ private void onGUIDisplay(GuiScreen i, CallbackInfo ci) { GlStateManager.enableTexture2D(); } catch (Throwable ignored) { } - crashpatch$runGUILoop(new CrashGui(report, CrashGui.GuiType.INIT)); + crashpatch$runGUILoop(() -> new CrashGui(report, CrashGui.GuiType.INIT)); } catch (Throwable t) { if (!crashpatch$letDie) { logger.error("An uncaught exception occured while displaying the init error screen, making normal report instead", t); @@ -343,58 +345,80 @@ private void onGUIDisplay(GuiScreen i, CallbackInfo ci) { /** * @author Runemoro */ - private void crashpatch$runGUILoop(CrashGui screen) throws Throwable { - displayGuiScreen(screen); - while (running && currentScreen != null) { - if (Display.isCreated() && Display.isCloseRequested()) { - System.exit(0); - } - EventManager.INSTANCE.post(new RenderEvent(Stage.START, 0)); - leftClickCounter = 10000; - currentScreen.handleInput(); - currentScreen.updateScreen(); - - GlStateManager.pushMatrix(); - GlStateManager.clear(16640); - framebufferMc.bindFramebuffer(true); - GlStateManager.enableTexture2D(); - - GlStateManager.viewport(0, 0, displayWidth, displayHeight); - - ScaledResolution scaledResolution = new ScaledResolution(((Minecraft) (Object) this)); - GlStateManager.clear(256); - GlStateManager.matrixMode(5889); - GlStateManager.loadIdentity(); - GlStateManager.ortho(0.0D, scaledResolution.getScaledWidth_double(), scaledResolution.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D); - GlStateManager.matrixMode(5888); - GlStateManager.loadIdentity(); - GlStateManager.translate(0.0F, 0.0F, -2000.0F); - GlStateManager.clear(256); - - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); - int mouseX = Mouse.getX() * width / displayWidth; - int mouseY = height - Mouse.getY() * height / displayHeight - 1; - Gui.drawRect(0, 0, width, height, Color.WHITE.getRGB()); // DO NOT REMOVE THIS! FOR SOME REASON NANOVG DOESN'T RENDER WITHOUT IT - currentScreen.drawScreen(mouseX, mouseY, 0); - if (screen.getShouldCrash()) { + private void crashpatch$runGUILoop(Supplier guiSupplier) throws Throwable { + CrashGui screen = null; + try { + screen = guiSupplier.get(); + displayGuiScreen(screen); + } catch (Throwable t) { + if (!crashpatch$letDie) { + logger.error("An uncaught exception occured while displaying the crash screen, making normal report instead", t); crashpatch$letDie = true; - throw Objects.requireNonNull(screen.getThrowable()); } + if (screen != null && screen.getThrowable() != null) { + throw screen.getThrowable(); + } else { + displayCrashReport(new CrashReport("An uncaught exception occured while displaying the crash screen", t)); + return; + } + } + while (running && currentScreen != null) { + try { + if (Display.isCreated() && Display.isCloseRequested()) { + System.exit(0); + } + EventManager.INSTANCE.post(new RenderEvent(Stage.START, 0)); + leftClickCounter = 10000; + currentScreen.handleInput(); + currentScreen.updateScreen(); + + GlStateManager.pushMatrix(); + GlStateManager.clear(16640); + framebufferMc.bindFramebuffer(true); + GlStateManager.enableTexture2D(); - framebufferMc.unbindFramebuffer(); - GlStateManager.popMatrix(); + GlStateManager.viewport(0, 0, displayWidth, displayHeight); + + ScaledResolution scaledResolution = new ScaledResolution(((Minecraft) (Object) this)); + GlStateManager.clear(256); + GlStateManager.matrixMode(5889); + GlStateManager.loadIdentity(); + GlStateManager.ortho(0.0D, scaledResolution.getScaledWidth_double(), scaledResolution.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + GlStateManager.translate(0.0F, 0.0F, -2000.0F); + GlStateManager.clear(256); + + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + int mouseX = Mouse.getX() * width / displayWidth; + int mouseY = height - Mouse.getY() * height / displayHeight - 1; + Gui.drawRect(0, 0, width, height, Color.WHITE.getRGB()); // DO NOT REMOVE THIS! FOR SOME REASON NANOVG DOESN'T RENDER WITHOUT IT + currentScreen.drawScreen(mouseX, mouseY, 0); + if (screen.getShouldCrash()) { + crashpatch$letDie = true; + throw Objects.requireNonNull(screen.getThrowable()); + } - GlStateManager.pushMatrix(); - framebufferMc.framebufferRender(displayWidth, displayHeight); - GlStateManager.popMatrix(); + framebufferMc.unbindFramebuffer(); + GlStateManager.popMatrix(); - EventManager.INSTANCE.post(new RenderEvent(Stage.END, 0)); + GlStateManager.pushMatrix(); + framebufferMc.framebufferRender(displayWidth, displayHeight); + GlStateManager.popMatrix(); - updateDisplay(); - Thread.yield(); - Display.sync(60); - checkGLError("CrashPatch GUI Loop"); + EventManager.INSTANCE.post(new RenderEvent(Stage.END, 0)); + + updateDisplay(); + Thread.yield(); + Display.sync(60); + checkGLError("CrashPatch GUI Loop"); + } catch (Throwable t) { + // If the crash screen crashes, just give up lol + crashpatch$letDie = true; + logger.error("An uncaught exception occured while displaying the init error screen, making normal report instead", t); + throw screen.getThrowable() == null ? t : screen.getThrowable(); + } } } @@ -459,6 +483,10 @@ public void redirect(FMLCommonHandler instance, int code) { GL11.glDisable(GL11.GL_SCISSOR_TEST); } + @Override + public void crashPatch$die() { + crashpatch$letDie = true; + } } diff --git a/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashGui.kt b/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashGui.kt index 53708e9..01f2727 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashGui.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/gui/CrashGui.kt @@ -30,6 +30,8 @@ import org.polyfrost.crashpatch.CrashPatch import org.polyfrost.crashpatch.crashes.CrashHelper import org.polyfrost.crashpatch.crashes.CrashScan import org.polyfrost.crashpatch.hooks.CrashReportHook +import org.polyfrost.crashpatch.hooks.MinecraftHook +import org.polyfrost.crashpatch.logger import org.polyfrost.crashpatch.utils.InternetUtils import java.io.File import java.net.URI @@ -179,7 +181,15 @@ class CrashGui @JvmOverloads constructor( if (mc.theWorld == null && leaveWorldCrash) { drawDefaultBackground() } - NanoVGHelper.INSTANCE.setupAndDraw { draw(it, inputHandler) } + NanoVGHelper.INSTANCE.setupAndDraw { + try { + draw(it, inputHandler) + } catch (t: Throwable) { + (mc as MinecraftHook).`crashPatch$die`() + logger.error("An uncaught exception occured while displaying the init error screen, making normal report instead", t) + throw throwable ?: t + } + } } override fun onScreenClose() { diff --git a/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt b/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt index 7e9b395..746f9e2 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/utils/GuiDisconnectedHook.kt @@ -15,8 +15,12 @@ object GuiDisconnectedHook { val gui = i as AccessorGuiDisconnected val scan = scanReport(gui.message.formattedText, true) if (scan != null && scan.solutions.size > 1) { - ci.cancel() - mc.displayGuiScreen(CrashGui(gui.message.formattedText, null, gui.reason, CrashGui.GuiType.DISCONNECT)) + try { + mc.displayGuiScreen(CrashGui(gui.message.formattedText, null, gui.reason, CrashGui.GuiType.DISCONNECT)) + ci.cancel() + } catch (t: Throwable) { + t.printStackTrace() + } } } }