diff --git a/build.gradle b/build.gradle index 166069a..0e4577d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { maven { url = 'https://maven.fabricmc.net/' } } dependencies { - classpath "net.fabricmc:fabric-loom:0.2.0-SNAPSHOT" + classpath "net.fabricmc:fabric-loom:0.2.5-SNAPSHOT" } } @@ -15,16 +15,16 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { - minecraft "com.mojang:minecraft:19w02a" - mappings "net.fabricmc:yarn:19w02a.20" - modCompile "net.fabricmc:fabric-loader:0.3.2.93" - modCompile "net.fabricmc:fabric:0.1.4.71" + minecraft "com.mojang:minecraft:19w35a" + mappings "net.fabricmc:yarn:19w35a+build.1" + modCompile "net.fabricmc:fabric-loader:0.6.1+build.164" +// modCompile "net.fabricmc.fabric-api:fabric-api:0.3.2+build.217-1.15" } def travisBuildNumber = System.getenv("TRAVIS_BUILD_NUMBER") def versionSuffix = travisBuildNumber != null ? travisBuildNumber : "SNAPSHOT" -version "1.0" +version "1.0.1" group "org.dimdev.toomanycrashes" archivesBaseName = "TooManyCrashes" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1948b90..5c2d1cf 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d2c45a4..ef9a9e0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d..83f2acf 100644 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -109,8 +125,8 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` diff --git a/gradlew.bat b/gradlew.bat index f955316..9618d8d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/src/main/java/org/dimdev/toomanycrashes/CrashScreen.java b/src/main/java/org/dimdev/toomanycrashes/CrashScreen.java new file mode 100644 index 0000000..db1c938 --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/CrashScreen.java @@ -0,0 +1,64 @@ +package org.dimdev.toomanycrashes; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.util.SystemUtil; +import net.minecraft.util.crash.CrashReport; +import net.minecraft.util.math.Box; + +import java.io.File; + +@Environment(EnvType.CLIENT) +public class CrashScreen extends ProblemScreen { + + public CrashScreen(CrashReport report) { + super(report); + } + + @Override + public void init() { + super.init(); + ButtonWidget mainMenuButton = new ButtonWidget(width / 2 - 155, height / 4 + 120 + 12, 150, 20, I18n.translate("gui.toTitle"), + button -> minecraft.openScreen(new TitleScreen())); + + if (ModConfig.instance().disableReturnToMainMenu) { + mainMenuButton.active = false; + mainMenuButton.setMessage(I18n.translate("toomanycrashes.gui.disabledByConfig")); + } + + addButton(mainMenuButton); + } + + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { // TODO: localize number of lines + renderBackground(); + drawCenteredString(font, I18n.translate("toomanycrashes.crashscreen.title"), width / 2, height / 4 - 40, 0xFFFFFF); + + int textColor = 0xD0D0D0; + int x = width / 2 - 155; + int y = height / 4; + + drawString(font, I18n.translate("toomanycrashes.crashscreen.summary"), x, y, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph1.line1"), x, y += 18, textColor); + + drawCenteredString(font, getModListString(), width / 2, y += 11, 0xE0E000); + + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph2.line1"), x, y += 11, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph2.line2"), x, y += 9, textColor); + + drawFileNameString(y); + y += 11; + + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph3.line1"), x, y += 12, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph3.line2"), x, y += 9, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph3.line3"), x, y += 9, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph3.line4"), x, y + 9, textColor); + + super.render(mouseX, mouseY, partialTicks); + } +} diff --git a/src/main/java/org/dimdev/toomanycrashes/CrashScreenGui.java b/src/main/java/org/dimdev/toomanycrashes/CrashScreenGui.java deleted file mode 100644 index f3c8c51..0000000 --- a/src/main/java/org/dimdev/toomanycrashes/CrashScreenGui.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.dimdev.toomanycrashes; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.MainMenuGui; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.util.crash.CrashReport; - -@Environment(EnvType.CLIENT) -public class CrashScreenGui extends ProblemScreenGui { - public CrashScreenGui(CrashReport report) { - super(report); - } - - @Override - public void onInitialized() { - super.onInitialized(); - ButtonWidget mainMenuButton = new ButtonWidget(0, width / 2 - 155, height / 4 + 120 + 12, 150, 20, I18n.translate("gui.toTitle")) { - @Override - public void onPressed(double x, double y) { - client.openGui(new MainMenuGui()); - } - }; - - if (ModConfig.instance().disableReturnToMainMenu) { - mainMenuButton.enabled = false; - mainMenuButton.text = I18n.translate("toomanycrashes.gui.disabledByConfig"); - } - - addButton(mainMenuButton); - } - - @Override - public void draw(int mouseX, int mouseY, float partialTicks) { // TODO: localize number of lines - drawBackground(); - drawStringCentered(fontRenderer, I18n.translate("toomanycrashes.crashscreen.title"), width / 2, height / 4 - 40, 0xFFFFFF); - - int textColor = 0xD0D0D0; - int x = width / 2 - 155; - int y = height / 4; - - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.summary"), x, y, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph1.line1"), x, y += 18, textColor); - - drawStringCentered(fontRenderer, getModListString(), width / 2, y += 11, 0xE0E000); - - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph2.line1"), x, y += 11, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph2.line2"), x, y += 9, textColor); - - String fileNameString = report.getFile() != null ? "\u00A7n" + report.getFile().getName() : I18n.translate("toomanycrashes.crashscreen.reportSaveFailed"); - drawStringCentered(fontRenderer, fileNameString, width / 2, y += 11, 0x00FF00); - - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph3.line1"), x, y += 12, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph3.line2"), x, y += 9, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph3.line3"), x, y += 9, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph3.line4"), x, y + 9, textColor); - - super.draw(mouseX, mouseY, partialTicks); - } -} diff --git a/src/main/java/org/dimdev/toomanycrashes/CrashUtils.java b/src/main/java/org/dimdev/toomanycrashes/CrashUtils.java index d829519..2311096 100644 --- a/src/main/java/org/dimdev/toomanycrashes/CrashUtils.java +++ b/src/main/java/org/dimdev/toomanycrashes/CrashUtils.java @@ -1,5 +1,6 @@ package org.dimdev.toomanycrashes; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.util.crash.CrashReport; import org.apache.logging.log4j.LogManager; @@ -10,6 +11,7 @@ import java.util.Date; public final class CrashUtils { + private static final Logger LOGGER = LogManager.getLogger("TMC"); private static boolean isClient; @@ -26,10 +28,10 @@ public static void outputReport(CrashReport report) { if (report.getFile() == null) { String reportName = "crash-"; reportName += new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()); - reportName += MinecraftClient.getInstance().isMainThread() ? "-client" : "-server"; + reportName += isClient && MinecraftClient.getInstance().isOnThread() ? "-client" : "-server"; reportName += ".txt"; - File reportsDir = isClient ? new File(MinecraftClient.getInstance().runDirectory, "crash-reports") : new File("crash-reports"); + File reportsDir = new File(FabricLoader.getInstance().getGameDirectory(), "crash-reports"); File reportFile = new File(reportsDir, reportName); report.writeToFile(reportFile); @@ -38,7 +40,8 @@ public static void outputReport(CrashReport report) { LOGGER.fatal("Failed saving report", e); } - LOGGER.fatal("Minecraft ran into a problem! " + (report.getFile() != null ? "Report saved to: " + report.getFile() : "Crash report could not be saved.") + "\n" + - report.asString()); + LOGGER.fatal("Minecraft ran into a problem! " + (report.getFile() != null ? "Report saved to: " + report.getFile() : + "Crash report could not be saved.") + "\n" + + report.asString()); } } diff --git a/src/main/java/org/dimdev/toomanycrashes/DeobfuscatingRewritePolicy.java b/src/main/java/org/dimdev/toomanycrashes/DeobfuscatingRewritePolicy.java index 12322b2..b3fb627 100644 --- a/src/main/java/org/dimdev/toomanycrashes/DeobfuscatingRewritePolicy.java +++ b/src/main/java/org/dimdev/toomanycrashes/DeobfuscatingRewritePolicy.java @@ -12,11 +12,6 @@ import java.util.List; public class DeobfuscatingRewritePolicy implements RewritePolicy { - @Override - public LogEvent rewrite(LogEvent source) { - if (source.getThrown() != null) StacktraceDeobfuscator.deobfuscateThrowable(source.getThrown()); - return source; - } /** Modifies the log4j config to add the policy **/ public static void install() { @@ -43,4 +38,12 @@ public static void install() { // Add the new appender loggerConfig.addAppender(rewriteAppender, null, null); } + + @Override + public LogEvent rewrite(LogEvent source) { + if (source.getThrown() != null) { + StacktraceDeobfuscator.deobfuscateThrowable(source.getThrown()); + } + return source; + } } diff --git a/src/main/java/org/dimdev/toomanycrashes/InitErrorScreen.java b/src/main/java/org/dimdev/toomanycrashes/InitErrorScreen.java new file mode 100644 index 0000000..11cd81a --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/InitErrorScreen.java @@ -0,0 +1,52 @@ +package org.dimdev.toomanycrashes; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.widget.AbstractButtonWidget; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.util.crash.CrashReport; + +@Environment(EnvType.CLIENT) +public class InitErrorScreen extends ProblemScreen { + + public InitErrorScreen(CrashReport report) { + super(report); + } + + @Override + public void init() { + super.init(); + AbstractButtonWidget getLinkButton = buttons.get(0); + getLinkButton.x = width / 2 - 155; + getLinkButton.y = height / 4 + 120 + 12; + getLinkButton.setWidth(310); + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { // TODO: localize number of lines + renderBackground(); + drawCenteredString(font, I18n.translate("toomanycrashes.initerrorscreen.title"), width / 2, height / 4 - 40, 0xFFFFFF); + + int textColor = 0xD0D0D0; + int x = width / 2 - 155; + int y = height / 4; + + drawString(font, I18n.translate("toomanycrashes.initerrorscreen.summary"), x, y, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph1.line1"), x, y += 18, textColor); + + drawCenteredString(font, getModListString(), width / 2, y += 11, 0xE0E000); + + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph2.line1"), x, y += 11, textColor); + drawString(font, I18n.translate("toomanycrashes.crashscreen.paragraph2.line2"), x, y += 9, textColor); + + drawFileNameString(y); + y += 11; + + drawString(font, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line1"), x, y += 12, textColor); + drawString(font, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line2"), x, y += 9, textColor); + drawString(font, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line3"), x, y += 9, textColor); + drawString(font, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line4"), x, y + 9, textColor); + + super.render(mouseX, mouseY, partialTicks); + } +} diff --git a/src/main/java/org/dimdev/toomanycrashes/InitErrorScreenGui.java b/src/main/java/org/dimdev/toomanycrashes/InitErrorScreenGui.java deleted file mode 100644 index 5d919e2..0000000 --- a/src/main/java/org/dimdev/toomanycrashes/InitErrorScreenGui.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.dimdev.toomanycrashes; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.util.crash.CrashReport; - -@Environment(EnvType.CLIENT) -public class InitErrorScreenGui extends ProblemScreenGui { - - public InitErrorScreenGui(CrashReport report) { - super(report); - } - - @Override - public void onInitialized() { - super.onInitialized(); - ButtonWidget getLinkButton = buttons.get(0); - getLinkButton.x = width / 2 - 155; - getLinkButton.y = height / 4 + 120 + 12; - getLinkButton.setWidth(310); - } - - @Override - public void draw(int mouseX, int mouseY, float partialTicks) { // TODO: localize number of lines - drawBackground(); - drawStringCentered(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.title"), width / 2, height / 4 - 40, 0xFFFFFF); - - int textColor = 0xD0D0D0; - int x = width / 2 - 155; - int y = height / 4; - - drawString(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.summary"), x, y, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph1.line1"), x, y += 18, textColor); - - drawStringCentered(fontRenderer, getModListString(), width / 2, y += 11, 0xE0E000); - - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph2.line1"), x, y += 11, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.crashscreen.paragraph2.line2"), x, y += 9, textColor); - - drawStringCentered(fontRenderer, report.getFile() != null ? "\u00A7n" + report.getFile().getName() : I18n.translate("toomanycrashes.crashscreen.reportSaveFailed"), width / 2, y += 11, 0x00FF00); - - drawString(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line1"), x, y += 12, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line2"), x, y += 9, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line3"), x, y += 9, textColor); - drawString(fontRenderer, I18n.translate("toomanycrashes.initerrorscreen.paragraph3.line4"), x, y + 9, textColor); - - super.draw(mouseX, mouseY, partialTicks); - } -} diff --git a/src/main/java/org/dimdev/toomanycrashes/ModConfig.java b/src/main/java/org/dimdev/toomanycrashes/ModConfig.java index 9f303ec..a4c3c1b 100644 --- a/src/main/java/org/dimdev/toomanycrashes/ModConfig.java +++ b/src/main/java/org/dimdev/toomanycrashes/ModConfig.java @@ -2,12 +2,17 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import net.fabricmc.loader.FabricLoader; +import net.fabricmc.loader.api.FabricLoader; -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; public class ModConfig { - private static final File CONFIG_FILE = new File(FabricLoader.INSTANCE.getConfigDirectory(), "toomanycrashes.json"); + + private static final File CONFIG_FILE = new File(FabricLoader.getInstance().getConfigDirectory(), "toomanycrashes.json"); private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static ModConfig instance = null; diff --git a/src/main/java/org/dimdev/toomanycrashes/PatchedClient.java b/src/main/java/org/dimdev/toomanycrashes/PatchedClient.java new file mode 100644 index 0000000..0c0d51c --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/PatchedClient.java @@ -0,0 +1,8 @@ +package org.dimdev.toomanycrashes; + +import net.minecraft.util.crash.CrashReport; + +public interface PatchedClient { + + void displayInitErrorScreen(CrashReport report); +} diff --git a/src/main/java/org/dimdev/toomanycrashes/PatchedCrashReport.java b/src/main/java/org/dimdev/toomanycrashes/PatchedCrashReport.java index b466e0d..a4c7f5a 100644 --- a/src/main/java/org/dimdev/toomanycrashes/PatchedCrashReport.java +++ b/src/main/java/org/dimdev/toomanycrashes/PatchedCrashReport.java @@ -1,13 +1,15 @@ package org.dimdev.toomanycrashes; -import net.fabricmc.loader.ModInfo; +import net.fabricmc.loader.api.metadata.ModMetadata; import java.util.Set; public interface PatchedCrashReport { - Set getSuspectedMods(); + + Set getSuspectedMods(); interface Element { + String invokeGetName(); String invokeGetDetail(); diff --git a/src/main/java/org/dimdev/toomanycrashes/PatchedIntegratedServer.java b/src/main/java/org/dimdev/toomanycrashes/PatchedIntegratedServer.java index e94a014..89484e1 100644 --- a/src/main/java/org/dimdev/toomanycrashes/PatchedIntegratedServer.java +++ b/src/main/java/org/dimdev/toomanycrashes/PatchedIntegratedServer.java @@ -1,5 +1,6 @@ package org.dimdev.toomanycrashes; public interface PatchedIntegratedServer { + void setCrashNextTick(); } diff --git a/src/main/java/org/dimdev/toomanycrashes/ProblemScreen.java b/src/main/java/org/dimdev/toomanycrashes/ProblemScreen.java new file mode 100644 index 0000000..78a2bdf --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/ProblemScreen.java @@ -0,0 +1,116 @@ +package org.dimdev.toomanycrashes; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.metadata.ModMetadata; +import net.minecraft.client.gui.screen.ConfirmChatLinkScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.text.LiteralText; +import net.minecraft.util.SystemUtil; +import net.minecraft.util.crash.CrashReport; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.dimdev.utils.HasteUpload; + +import java.io.File; +import java.lang.reflect.Field; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Environment(EnvType.CLIENT) +public abstract class ProblemScreen extends Screen { + + private static final Logger LOGGER = LogManager.getLogger(); + + protected final CrashReport report; + private String hasteLink = null; + private String modListString = null; + protected int xLeft = Integer.MAX_VALUE; + protected int xRight = Integer.MIN_VALUE; + protected int yTop = Integer.MAX_VALUE; + protected int yBottom = Integer.MIN_VALUE; + + protected ProblemScreen(CrashReport report) { + super(new LiteralText("")); + this.report = report; + } + + @Override + public void init() { + addButton(new ButtonWidget(width / 2 - 155 + 160, height / 4 + 120 + 12, 150, 20, I18n.translate("toomanycrashes.gui.getLink"), + buttonWidget -> { + try { + if (hasteLink == null) { + hasteLink = HasteUpload.uploadToHaste(ModConfig.instance().hasteURL, "mccrash", report.asString()); + } + Field uriField; + //noinspection JavaReflectionMemberAccess + uriField = Screen.class.getDeclaredField("clickedLink"); + uriField.setAccessible(true); + uriField.set(ProblemScreen.this, new URI(hasteLink)); + minecraft.openScreen(new ConfirmChatLinkScreen(b -> { + if (b) { + SystemUtil.getOperatingSystem().open(hasteLink); + } + + this.minecraft.openScreen(this); + }, hasteLink, false)); + } catch (Throwable e) { + LOGGER.error("Exception when crash menu button clicked:", e); + buttonWidget.setMessage(I18n.translate("toomanycrashes.gui.failed")); + buttonWidget.active = false; + } + })); + } + + @Override + public boolean mouseClicked(double x, double y, int int_1) { + if (x >= xLeft && x <= xRight && y >= yTop && y <= yBottom) { + File file = report.getFile(); + if (file != null) { + SystemUtil.getOperatingSystem().open(file); + } + } + return super.mouseClicked(x, y, int_1); + } + + @Override + public boolean shouldCloseOnEsc() { + return false; + } + + protected String getModListString() { + if (modListString == null) { + Set suspectedMods = ((PatchedCrashReport) report).getSuspectedMods(); + if (suspectedMods == null) { + return modListString = I18n.translate("toomanycrashes.crashscreen.identificationErrored"); + } + List modNames = new ArrayList<>(); + for (ModMetadata mod : suspectedMods) { + modNames.add(mod.getName()); + } + if (modNames.isEmpty()) { + modListString = I18n.translate("toomanycrashes.crashscreen.unknownCause"); + } else { + modListString = StringUtils.join(modNames, ", "); + } + } + return modListString; + } + + protected void drawFileNameString(int y) { + String fileNameString = + report.getFile() != null ? "\u00A7n" + report.getFile().getName() : I18n.translate("toomanycrashes.crashscreen.reportSaveFailed"); + int stLen = font.getStringWidth(fileNameString); + xLeft = width / 2 - stLen / 2; + xRight = width / 2 + stLen / 2; + drawString(font, fileNameString, xLeft, y += 11, 0x00FF00); + yTop = y; + yBottom = y + 10; + } +} diff --git a/src/main/java/org/dimdev/toomanycrashes/ProblemScreenGui.java b/src/main/java/org/dimdev/toomanycrashes/ProblemScreenGui.java deleted file mode 100644 index 103d2dd..0000000 --- a/src/main/java/org/dimdev/toomanycrashes/ProblemScreenGui.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.dimdev.toomanycrashes; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.loader.ModInfo; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.ingame.ConfirmChatLinkGui; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.util.crash.CrashReport; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.dimdev.utils.HasteUpload; - -import java.lang.reflect.Field; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -@Environment(EnvType.CLIENT) -public abstract class ProblemScreenGui extends Gui { - private static final Logger LOGGER = LogManager.getLogger(); - - protected final CrashReport report; - private String hasteLink = null; - private String modListString = null; - - protected ProblemScreenGui(CrashReport report) { - this.report = report; - } - - @Override - public void onInitialized() { - addButton(new ButtonWidget(1, width / 2 - 155 + 160, height / 4 + 120 + 12, 150, 20, I18n.translate("toomanycrashes.gui.getLink", new Object[0])) { - @Override - public void onPressed(double x, double y) { - try { - if (hasteLink == null) { - hasteLink = HasteUpload.uploadToHaste(ModConfig.instance().hasteURL, "mccrash", report.asString()); - } - Field uriField; - try { - //noinspection JavaReflectionMemberAccess - uriField = Gui.class.getDeclaredField("field_2562"); - } catch (NoSuchFieldException e) { - uriField = Gui.class.getDeclaredField("uri"); - } - uriField.setAccessible(true); - uriField.set(ProblemScreenGui.this, new URI(hasteLink)); - client.openGui(new ConfirmChatLinkGui(ProblemScreenGui.this, hasteLink, 31102009, false)); - } catch (Throwable e) { - LOGGER.error("Exception when crash menu button clicked:", e); - text = I18n.translate("toomanycrashes.gui.failed"); - enabled = false; - } - } - }); - } - - @Override - public boolean doesEscapeKeyClose() { - return false; - } - - protected String getModListString() { - if (modListString == null) { - Set suspectedMods = ((PatchedCrashReport) report).getSuspectedMods(); - if (suspectedMods == null) { - return modListString = I18n.translate("toomanycrashes.crashscreen.identificationErrored"); - } - List modNames = new ArrayList<>(); - for (ModInfo mod : suspectedMods) { - modNames.add(mod.getName()); - } - if (modNames.isEmpty()) { - modListString = I18n.translate("toomanycrashes.crashscreen.unknownCause"); - } else { - modListString = StringUtils.join(modNames, ", "); - } - } - return modListString; - } -} diff --git a/src/main/java/org/dimdev/toomanycrashes/StacktraceDeobfuscator.java b/src/main/java/org/dimdev/toomanycrashes/StacktraceDeobfuscator.java index 227c71c..99dadce 100644 --- a/src/main/java/org/dimdev/toomanycrashes/StacktraceDeobfuscator.java +++ b/src/main/java/org/dimdev/toomanycrashes/StacktraceDeobfuscator.java @@ -1,27 +1,31 @@ package org.dimdev.toomanycrashes; -import net.fabricmc.tinyremapper.TinyUtils; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.*; +import java.util.ArrayDeque; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.Map; public final class StacktraceDeobfuscator { + public static final String MAPPINGS = "mappings/mappings.tiny"; private static Map mappings = null; public static void init() { Map mappings = new HashMap<>(); - try (BufferedReader mappingReader = new BufferedReader(new InputStreamReader(StacktraceDeobfuscator.class.getClassLoader().getResourceAsStream(MAPPINGS)))) { - TinyUtils.read( - mappingReader, - "intermediary", - "named", - (key, value) -> mappings.put(key.replace('/', '.'), value.replace('/', '.')), - (intermediary, named) -> mappings.put(intermediary.name, named.name), - (intermediary, named) -> mappings.put(intermediary.name, named.name) - ); + try (BufferedReader mappingReader = new BufferedReader( + new InputStreamReader(StacktraceDeobfuscator.class.getClassLoader().getResourceAsStream(MAPPINGS)))) { + // TinyUtils.read( + // mappingReader, + // "intermediary", + // "named", + // (key, value) -> mappings.put(key.replace('/', '.'), value.replace('/', '.')), + // (intermediary, named) -> mappings.put(intermediary.name, named.name), + // (intermediary, named) -> mappings.put(intermediary.name, named.name) + // ); todo no more named } catch (IOException e) { throw new RuntimeException(e); } @@ -35,7 +39,9 @@ public static void deobfuscateThrowable(Throwable t) { while (!queue.isEmpty()) { t = queue.remove(); t.setStackTrace(deobfuscateStacktrace(t.getStackTrace())); - if (t.getCause() != null) queue.add(t.getCause()); + if (t.getCause() != null) { + queue.add(t.getCause()); + } Collections.addAll(queue, t.getSuppressed()); } } diff --git a/src/main/java/org/dimdev/toomanycrashes/StateManager.java b/src/main/java/org/dimdev/toomanycrashes/StateManager.java index 3acd7f6..b21e607 100644 --- a/src/main/java/org/dimdev/toomanycrashes/StateManager.java +++ b/src/main/java/org/dimdev/toomanycrashes/StateManager.java @@ -11,13 +11,6 @@ * registered here. */ public class StateManager { - public interface IResettable { - default void register() { - resettableRefs.add(new WeakReference<>(this)); - } - - void resetState(); - } // Use WeakReference to allow garbage collection, preventing memory leaks private static Set> resettableRefs = new HashSet<>(); @@ -33,4 +26,13 @@ public static void resetStates() { } } } + + public interface IResettable { + + default void register() { + resettableRefs.add(new WeakReference<>(this)); + } + + void resetState(); + } } diff --git a/src/main/java/org/dimdev/toomanycrashes/TooManyCrashes.java b/src/main/java/org/dimdev/toomanycrashes/TooManyCrashes.java index 0d1f427..2399c50 100644 --- a/src/main/java/org/dimdev/toomanycrashes/TooManyCrashes.java +++ b/src/main/java/org/dimdev/toomanycrashes/TooManyCrashes.java @@ -1,5 +1,6 @@ package org.dimdev.toomanycrashes; +import net.fabricmc.api.ModInitializer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dimdev.utils.SSLUtils; @@ -11,16 +12,18 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; -public class TooManyCrashes { +public class TooManyCrashes implements ModInitializer { + private static final Logger LOGGER = LogManager.getLogger("TooManyCrashes"); - public static void init() { + @Override + public void onInitialize() { ModConfig.instance(); trustIdenTrust(); - initStacktraceDeobfuscator(); + //initStacktraceDeobfuscator(); } - private static void trustIdenTrust() { + private void trustIdenTrust() { // Trust the "IdenTrust DST Root CA X3" certificate (used by Let's Encrypt, which is used by paste.dimdev.org) try (InputStream keyStoreInputStream = TooManyCrashes.class.getResourceAsStream("/dst_root_ca_x3.jks")) { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); @@ -31,7 +34,7 @@ private static void trustIdenTrust() { } } - private static void initStacktraceDeobfuscator() { + private void initStacktraceDeobfuscator() { LOGGER.info("Initializing StacktraceDeobfuscator"); try { StacktraceDeobfuscator.init(); diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/CrashReportSectionElementMixin.java b/src/main/java/org/dimdev/toomanycrashes/mixins/CrashReportSectionElementMixin.java new file mode 100644 index 0000000..0bf9d54 --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/CrashReportSectionElementMixin.java @@ -0,0 +1,25 @@ +package org.dimdev.toomanycrashes.mixins; + +import org.dimdev.toomanycrashes.PatchedCrashReport; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(targets = "net.minecraft.util.crash.CrashReportSection$Element") +public abstract class CrashReportSectionElementMixin implements PatchedCrashReport.Element { + + @Shadow + public abstract String getName(); + + @Shadow + public abstract String getDetail(); + + @Override + public String invokeGetName() { + return getName(); + } + + @Override + public String invokeGetDetail() { + return getDetail(); + } +} diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReport.java b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReport.java index 4a87081..0d546fb 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReport.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReport.java @@ -1,6 +1,6 @@ package org.dimdev.toomanycrashes.mixins; -import net.fabricmc.loader.ModInfo; +import net.fabricmc.loader.api.metadata.ModMetadata; import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReportSection; import org.apache.commons.lang3.StringUtils; @@ -26,17 +26,26 @@ @Mixin(value = CrashReport.class, priority = 500) public abstract class MixinCrashReport implements PatchedCrashReport { + + private static final boolean ANNOYING_EASTER_EGG_DISABLED = true; @Shadow @Final private CrashReportSection systemDetailsSection; @Shadow @Final private List otherSections; @Shadow @Final private Throwable cause; @Shadow @Final private String message; - @Shadow private static String generateWittyComment() { return null; } + private Set suspectedMods = null; - private static final boolean ANNOYING_EASTER_EGG_DISABLED = true; - private Set suspectedMods = null; + @Shadow private static String generateWittyComment() { + return null; + } + + private static String stacktraceToString(Throwable cause) { + StringWriter writer = new StringWriter(); + cause.printStackTrace(new PrintWriter(writer)); + return writer.toString(); + } @Override - public Set getSuspectedMods() { + public Set getSuspectedMods() { return suspectedMods; } @@ -59,7 +68,7 @@ private void afterFillSystemDetails(CallbackInfo ci) { String modListString = "Unknown"; List modNames = new ArrayList<>(); - for (ModInfo mod : suspectedMods) { + for (ModMetadata mod : suspectedMods) { modNames.add(mod.getName() + " (" + mod.getId() + ")"); } @@ -81,13 +90,14 @@ public String asString() { StringBuilder builder = new StringBuilder(); builder.append("---- Minecraft Crash Report ----\n") - .append("// ").append(ANNOYING_EASTER_EGG_DISABLED ? generateWittyComment() : generateEasterEggComment()) - .append("\n\n") - .append("Time: ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())).append("\n") - .append("Description: ").append(message) - .append("\n\n") - .append(stacktraceToString(cause).replace("\t", " ")) // Vanilla's getCauseStackTraceOrString doesn't print causes and suppressed exceptions - .append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n"); + .append("// ").append(ANNOYING_EASTER_EGG_DISABLED ? generateWittyComment() : generateEasterEggComment()) + .append("\n\n") + .append("Time: ").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new Date())).append("\n") + .append("Description: ").append(message) + .append("\n\n") + .append(stacktraceToString(cause) + .replace("\t", " ")) // Vanilla's getCauseStackTraceOrString doesn't print causes and suppressed exceptions + .append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n"); for (int i = 0; i < 87; i++) { builder.append("-"); @@ -98,12 +108,6 @@ public String asString() { return builder.toString().replace("\t", " "); } - private static String stacktraceToString(Throwable cause) { - StringWriter writer = new StringWriter(); - cause.printStackTrace(new PrintWriter(writer)); - return writer.toString(); - } - /** * @reason Improve report formatting */ @@ -122,13 +126,16 @@ private String generateEasterEggComment() { String comment = generateWittyComment(); if (comment.contains("Dinnerbone")) { - ModInfo mod = suspectedMods.iterator().next(); - String author = mod.getAuthors().get(0).getName(); - comment = comment.replace("Dinnerbone", author); + ModMetadata mod = suspectedMods.iterator().next(); + if (!mod.getAuthors().isEmpty()) { + String author = mod.getAuthors().iterator().next().getName(); + comment = comment.replace("Dinnerbone", author); + } } return comment; - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } return generateWittyComment(); } diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReportSection.java b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReportSection.java index 2b6dab8..e230c59 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReportSection.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinCrashReportSection.java @@ -12,40 +12,23 @@ @Mixin(CrashReportSection.class) public class MixinCrashReportSection { + @Shadow @Final private String title; @Shadow @Final private List elements; @Shadow private StackTraceElement[] stackTrace; - @Mixin(targets = "net.minecraft.util.crash.CrashReportSection$Element") - public static abstract class MixinElement implements PatchedCrashReport.Element { - @Shadow - public abstract String getName(); - - @Shadow - public abstract String getDetail(); - - @Override - public String invokeGetName() { - return getName(); - } - - @Override - public String invokeGetDetail() { - return getDetail(); - } - } - /** * @reason Disable stack trace pruning */ @Overwrite - public void method_580(int size) {} + public void method_580(int size) { + } /** * @reason Disable stack trace pruning, deobfuscate stack trace */ @Overwrite - public int method_579(int prune) { + public int trimStackTrace(int prune) { stackTrace = StacktraceDeobfuscator.deobfuscateStacktrace(Thread.currentThread().getStackTrace()); return stackTrace.length; } @@ -62,8 +45,8 @@ public void addStackTrace(StringBuilder builder) { String sectionIndent = " "; builder.append(sectionIndent) - .append(element.invokeGetName()) - .append(": "); + .append(element.invokeGetName()) + .append(": "); StringBuilder indent = new StringBuilder(sectionIndent + " "); for (char ignored : element.invokeGetName().toCharArray()) { @@ -72,9 +55,13 @@ public void addStackTrace(StringBuilder builder) { boolean first = true; for (String line : element.invokeGetDetail().trim().split("\n")) { - if (!first) builder.append("\n").append(indent); + if (!first) { + builder.append("\n").append(indent); + } first = false; - if (line.startsWith("\t")) line = line.substring(1); + if (line.startsWith("\t")) { + line = line.substring(1); + } builder.append(line.replace("\t", "")); } diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinEntity.java b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinEntity.java index 6914082..cb2c95c 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinEntity.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinEntity.java @@ -10,6 +10,7 @@ @Mixin(value = Entity.class, priority = 10000) public class MixinEntity { + private boolean noNBT = false; @Inject(method = "populateCrashReport", at = @At("TAIL")) diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinIntegratedServer.java b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinIntegratedServer.java index 651c485..2d38cbb 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinIntegratedServer.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinIntegratedServer.java @@ -11,6 +11,7 @@ @Mixin(IntegratedServer.class) public class MixinIntegratedServer implements PatchedIntegratedServer { + private boolean crashNextTick = false; @Override @@ -18,7 +19,7 @@ public void setCrashNextTick() { crashNextTick = true; } - @Inject(method = "method_3748", at = @At("HEAD")) + @Inject(method = "tick(Ljava/util/function/BooleanSupplier;)V", at = @At("HEAD")) private void beforeTick(CallbackInfo ci) { if (crashNextTick) { throw new CrashException(new CrashReport("Manually triggered server-side debug crash", new Throwable())); diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinTileEntity.java b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinTileEntity.java index ee5831a..8180e52 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/MixinTileEntity.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/MixinTileEntity.java @@ -10,6 +10,7 @@ @Mixin(value = BlockEntity.class, priority = 10000) public class MixinTileEntity { + private boolean noNBT = false; @Inject(method = "populateCrashReport", at = @At("TAIL")) diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/client/ClientMainMixin.java b/src/main/java/org/dimdev/toomanycrashes/mixins/client/ClientMainMixin.java new file mode 100644 index 0000000..13cf03d --- /dev/null +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/client/ClientMainMixin.java @@ -0,0 +1,19 @@ +package org.dimdev.toomanycrashes.mixins.client; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.main.Main; +import net.minecraft.util.crash.CrashReport; +import org.dimdev.toomanycrashes.PatchedClient; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(Main.class) +public class ClientMainMixin { + + @Redirect(method = "main([Ljava/lang/String;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V")) + private static void redirectPrintCrash(MinecraftClient client, CrashReport crashReport) { + ((PatchedClient) client).displayInitErrorScreen(crashReport); + } +} diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinBufferBuilder.java b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinBufferBuilder.java index 721cc0f..0fb0b1f 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinBufferBuilder.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinBufferBuilder.java @@ -10,7 +10,9 @@ @Mixin(BufferBuilder.class) public abstract class MixinBufferBuilder implements StateManager.IResettable { + @Shadow private boolean building; + @Shadow public abstract void end(); @Inject(method = "", at = @At("RETURN")) diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinKeyboard.java b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinKeyboard.java index 37d7c9a..f7956f8 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinKeyboard.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinKeyboard.java @@ -3,7 +3,7 @@ import com.google.common.util.concurrent.ListenableFutureTask; import net.minecraft.client.Keyboard; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.util.GlfwUtil; import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashReport; @@ -15,6 +15,7 @@ @Mixin(Keyboard.class) public abstract class MixinKeyboard { + @Shadow @Final private MinecraftClient client; @Shadow private long debugCrashStartTime; @@ -38,11 +39,11 @@ public void pollDebugCrash() { // a world. debugCrashStartTime = -1; - if (Gui.isControlPressed()) { + if (Screen.hasControlDown()) { GlfwUtil.method_15973(); - } else if (Gui.isShiftPressed()) { - if (Gui.isAltPressed()) { - if (client.method_1496()) { + } else if (Screen.hasShiftDown()) { + if (Screen.hasAltDown()) { + if (client.isIntegratedServerRunning()) { client.getServer().execute(() -> { throw new CrashException(new CrashReport("Manually triggered server-side scheduled task exception", new Throwable())); }); @@ -53,8 +54,8 @@ public void pollDebugCrash() { })); } } else { - if (Gui.isAltPressed()) { - if (client.method_1496()) { + if (Screen.hasAltDown()) { + if (client.isIntegratedServerRunning()) { ((PatchedIntegratedServer) client.getServer()).setCrashNextTick(); } } else { diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMain.java b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMain.java deleted file mode 100644 index 9695993..0000000 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMain.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.dimdev.toomanycrashes.mixins.client; - -import net.minecraft.client.main.Main; -import org.dimdev.toomanycrashes.TooManyCrashes; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Main.class) -public class MixinMain { - static { - TooManyCrashes.init(); - } -} diff --git a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMinecraftClient.java b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMinecraftClient.java index 45ea96d..1a5d574 100644 --- a/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMinecraftClient.java +++ b/src/main/java/org/dimdev/toomanycrashes/mixins/client/MixinMinecraftClient.java @@ -1,37 +1,37 @@ package org.dimdev.toomanycrashes.mixins.client; import com.mojang.blaze3d.platform.GLX; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Keyboard; import net.minecraft.client.MinecraftClient; import net.minecraft.client.Mouse; -import net.minecraft.client.audio.SoundLoader; -import net.minecraft.client.font.FontRenderer; -import net.minecraft.client.font.FontRendererManager; +import net.minecraft.client.font.FontManager; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gl.GlFramebuffer; -import net.minecraft.client.gui.CloseWorldGui; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.MainMenuGui; import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.gui.screen.SaveLevelScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.options.GameOptions; import net.minecraft.client.resource.ClientResourcePackContainer; -import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.LanguageManager; +import net.minecraft.client.sound.SoundManager; import net.minecraft.client.texture.TextureManager; import net.minecraft.client.util.Window; -import net.minecraft.client.world.ClientWorld; import net.minecraft.resource.ReloadableResourceManager; import net.minecraft.resource.ResourcePackContainerManager; -import net.minecraft.text.StringTextComponent; +import net.minecraft.text.LiteralText; +import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; -import net.minecraft.util.ThreadTaskQueue; +import net.minecraft.util.NonBlockingThreadExecutor; import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashReport; import org.apache.logging.log4j.Logger; -import org.dimdev.toomanycrashes.CrashScreenGui; +import org.dimdev.toomanycrashes.CrashScreen; import org.dimdev.toomanycrashes.CrashUtils; -import org.dimdev.toomanycrashes.InitErrorScreenGui; +import org.dimdev.toomanycrashes.InitErrorScreen; +import org.dimdev.toomanycrashes.PatchedClient; import org.dimdev.toomanycrashes.StateManager; import org.dimdev.utils.GlUtil; import org.spongepowered.asm.mixin.Final; @@ -40,101 +40,104 @@ import org.spongepowered.asm.mixin.Shadow; import java.io.File; +import java.util.Queue; +import java.util.concurrent.CompletableFuture; @Mixin(MinecraftClient.class) @SuppressWarnings("StaticVariableMayNotBeInitialized") -public abstract class MixinMinecraftClient extends ThreadTaskQueue { +public abstract class MixinMinecraftClient extends NonBlockingThreadExecutor implements PatchedClient { + + @Shadow public static byte[] memoryReservedForCrash; + @Shadow @Final public static Identifier DEFAULT_TEXT_RENDERER_ID; + @Shadow @Final public static boolean IS_SYSTEM_MAC; // @formatter:off @Shadow @Final private static Logger LOGGER; + @Shadow public GameOptions options; + @Shadow public InGameHud inGameHud; + @Shadow public Screen currentScreen; + @Shadow public TextureManager textureManager; + @Shadow public TextRenderer textRenderer; +// @Shadow public abstract void method_1550(ClientWorld world, Gui loadingGui); + @Shadow public Window window; + @Shadow public Mouse mouse; + @Shadow @Final public File runDirectory; + @Shadow public Keyboard keyboard; @Shadow volatile boolean isRunning; @Shadow private boolean crashed; @Shadow private CrashReport crashReport; - @Shadow public static byte[] memoryReservedForCrash; - @Shadow public GameOptions options; - @Shadow public InGameHud hudInGame; - @Shadow public Gui currentGui; - @Shadow public TextureManager textureManager; - @Shadow public FontRenderer fontRenderer; @Shadow private int attackCooldown; @Shadow private GlFramebuffer framebuffer; @Shadow private ReloadableResourceManager resourceManager; - @Shadow private SoundLoader soundLoader; + @Shadow private SoundManager soundManager; @Shadow private LanguageManager languageManager; + @Shadow private FontManager fontManager; + @Shadow @Final private ResourcePackContainerManager resourcePackContainerManager; + @Shadow @Final private Queue renderTaskQueue; + private int clientCrashCount = 0; + private int serverCrashCount = 0; + public MixinMinecraftClient(String string_1) { + super(string_1); + } + @Shadow private void init() {} - @Shadow public void openGui(Gui gui) {} + + @Shadow public void openScreen(Screen gui) {} + // @formatter:on + @Shadow public CrashReport populateCrashReport(CrashReport report) { return null; } - @Shadow public void stop() {} + + @Shadow public void close() {} + @Shadow public abstract ClientPlayNetworkHandler getNetworkHandler(); + @Shadow public abstract void updateDisplay(boolean respectFramerateLimit); + @Shadow protected abstract void render(boolean boolean_1); - @Shadow public abstract void method_1550(ClientWorld world, Gui loadingGui); - @Shadow public Window window; - @Shadow private FontRendererManager fontManager; - @Shadow public abstract void reloadResources(); - @Shadow public Mouse mouse; + + @Shadow public abstract CompletableFuture reloadResources(); + @Shadow public abstract boolean forcesUnicodeFont(); - @Shadow @Final public static Identifier defaultFontRendererId; - @Shadow public abstract void stopThread(); - // @formatter:on - @Shadow @Final public static boolean isSystemMac; - @Shadow @Final public File runDirectory; - @Shadow public Keyboard keyboard; - @Shadow @Final private ResourcePackContainerManager resourcePackContainerManager; - private int clientCrashCount = 0; - private int serverCrashCount = 0; + @Shadow public abstract void stop(); + + @Shadow public abstract void disconnect(Screen screen); /** + * @author runemoro * @reason Allows the player to choose to return to the title screen after a crash, or get * a pasteable link to the crash report on paste.dimdev.org. */ @Overwrite public void start() { - isRunning = true; - - try { - init(); - } catch (Throwable throwable) { - // TODO: Error screen for crashes during Bootstrap.initialize() too - CrashReport report = CrashReport.create(throwable, "Initializing game"); - report.addElement("Initialization"); - displayInitErrorScreen(populateCrashReport(report)); - return; - } - - try { - while (isRunning) { - if (!crashed || crashReport == null) { - try { - render(true); - } catch (CrashException e) { - clientCrashCount++; - populateCrashReport(e.getReport()); - addInfoToCrash(e.getReport()); - resetGameState(); - LOGGER.fatal("Reported exception thrown!", e); - displayCrashScreen(e.getReport()); - } catch (Throwable e) { - clientCrashCount++; - CrashReport report = new CrashReport("Unexpected error", e); - - populateCrashReport(report); - addInfoToCrash(report); - resetGameState(); - LOGGER.fatal("Unreported exception thrown!", e); - displayCrashScreen(report); - } - } else { - serverCrashCount++; - addInfoToCrash(crashReport); + while (isRunning) { + if (!crashed || crashReport == null) { + try { + render(true); + } catch (CrashException e) { + clientCrashCount++; + populateCrashReport(e.getReport()); + addInfoToCrash(e.getReport()); + resetGameState(); + LOGGER.fatal("Reported exception thrown!", e); + displayCrashScreen(e.getReport()); + } catch (Throwable e) { + clientCrashCount++; + CrashReport report = new CrashReport("Unexpected error", e); + + populateCrashReport(report); + addInfoToCrash(report); resetGameState(); - displayCrashScreen(crashReport); - crashed = false; - crashReport = null; + LOGGER.fatal("Unreported exception thrown!", e); + displayCrashScreen(report); } + } else { + serverCrashCount++; + addInfoToCrash(crashReport); + resetGameState(); + displayCrashScreen(crashReport); + crashed = false; + crashReport = null; } - } finally { - stop(); } } @@ -143,13 +146,14 @@ public void addInfoToCrash(CrashReport report) { report.getSystemDetailsSection().add("Integrated Server Crashes Since Restart", () -> String.valueOf(serverCrashCount)); } + @Override public void displayInitErrorScreen(CrashReport report) { CrashUtils.outputReport(report); try { GlUtil.resetState(); isRunning = true; - runGUILoop(new InitErrorScreenGui(report)); + runGUILoop(new InitErrorScreen(report)); } catch (Throwable t) { LOGGER.error("An uncaught exception occured while displaying the init error screen, making normal report instead", t); printCrashReport(report); @@ -157,48 +161,48 @@ public void displayInitErrorScreen(CrashReport report) { } } - private void runGUILoop(Gui screen) { - openGui(screen); + private void runGUILoop(Screen screen) { + openScreen(screen); - while (isRunning && currentGui != null && !(currentGui instanceof MainMenuGui)) { + while (isRunning && currentScreen != null && !(currentScreen instanceof TitleScreen)) { window.setPhase("TooManyCrashes GUI Loop"); - if (GLX.shouldClose(window)) { - stopThread(); + if (GLX._shouldClose(window)) { + stop(); } attackCooldown = 10000; - currentGui.update(); + currentScreen.tick(); mouse.updateMouse(); - GLX.pollEvents(); + GLX._pollEvents(); - GlStateManager.pushMatrix(); - GlStateManager.clear(16640, isSystemMac); + RenderSystem.pushMatrix(); + RenderSystem.clear(16640, IS_SYSTEM_MAC); framebuffer.beginWrite(true); - GlStateManager.enableTexture(); - - GlStateManager.viewport(0, 0, window.getWindowWidth(), window.getWindowHeight()); - GlStateManager.matrixMode(5889); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(5888); - GlStateManager.loadIdentity(); - window.method_4493(isSystemMac); - - GlStateManager.clear(256, isSystemMac); - currentGui.draw( - (int) (mouse.getX() * window.getScaledWidth() / window.method_4480()), - (int) (mouse.getY() * window.getScaledHeight() / window.method_4507()), + RenderSystem.enableTexture(); + + RenderSystem.viewport(0, 0, window.getWidth(), window.getHeight()); + RenderSystem.matrixMode(5889); + RenderSystem.loadIdentity(); + RenderSystem.matrixMode(5888); + RenderSystem.loadIdentity(); + window.method_4493(IS_SYSTEM_MAC); + + RenderSystem.clear(256, IS_SYSTEM_MAC); + currentScreen.render( + (int) (mouse.getX() * window.getScaledWidth() / window.getWidth()), + (int) (mouse.getY() * window.getScaledHeight() / window.getHeight()), 0 ); framebuffer.endWrite(); - GlStateManager.popMatrix(); - GlStateManager.pushMatrix(); - framebuffer.draw(window.getWindowWidth(), window.getWindowHeight()); - GlStateManager.popMatrix(); - GlStateManager.pushMatrix(); - window.method_4493(isSystemMac); - GlStateManager.popMatrix(); + RenderSystem.popMatrix(); + RenderSystem.pushMatrix(); + framebuffer.draw(window.getWidth(), window.getHeight()); + RenderSystem.popMatrix(); + RenderSystem.pushMatrix(); + window.method_4493(IS_SYSTEM_MAC); + RenderSystem.popMatrix(); updateDisplay(true); Thread.yield(); } @@ -214,10 +218,10 @@ public void displayCrashScreen(CrashReport report) { // Vanilla does this when switching to main menu but not our custom crash screen // nor the out of memory screen (see https://bugs.mojang.com/browse/MC-128953) options.debugEnabled = false; - hudInGame.getHudChat().clear(true); + inGameHud.getChatHud().clear(true); // Display the crash screen - runGUILoop(new CrashScreenGui(report)); + runGUILoop(new CrashScreen(report)); } 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); @@ -226,6 +230,10 @@ public void displayCrashScreen(CrashReport report) { } } + /** + * @author Runemoro + * @reason Substitute + */ @Overwrite public void printCrashReport(CrashReport report) { CrashUtils.outputReport(report); @@ -240,7 +248,8 @@ public void resetGameState() { originalReservedMemorySize = memoryReservedForCrash.length; memoryReservedForCrash = new byte[0]; } - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } // Reset registered resettables StateManager.resetStates(); @@ -249,11 +258,11 @@ public void resetGameState() { if (getNetworkHandler() != null) { // Fix: Close the connection to avoid receiving packets from old server // when playing in another world (MC-128953) - getNetworkHandler().getClientConnection().disconnect(new StringTextComponent("[TooManyCrashes] Client crashed")); + getNetworkHandler().getConnection().disconnect(new LiteralText("[TooManyCrashes] Client crashed")); } - method_1550(null, new CloseWorldGui(I18n.translate("menu.savingLevel"))); - taskQueue.clear(); // Fix: method_1550(null, ...) only clears when integrated server is running + disconnect(new SaveLevelScreen(new TranslatableText("menu.savingLevel"))); + renderTaskQueue.clear(); // Fix: method_1550(null, ...) only clears when integrated server is running // Reset graphics GlUtil.resetState(); @@ -262,7 +271,8 @@ public void resetGameState() { if (originalReservedMemorySize != -1) { try { memoryReservedForCrash = new byte[originalReservedMemorySize]; - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } } System.gc(); @@ -271,11 +281,13 @@ public void resetGameState() { try { StateManager.resetStates(); GlUtil.resetState(); - } catch (Throwable ignored) {} + } catch (Throwable ignored) { + } } } /** + * @author runemoro * @reason Disconnect from the current world and free memory, using a memory reserve * to make sure that an OutOfMemory doesn't happen while doing this. *

diff --git a/src/main/java/org/dimdev/utils/GlUtil.java b/src/main/java/org/dimdev/utils/GlUtil.java index ee26395..5071f53 100644 --- a/src/main/java/org/dimdev/utils/GlUtil.java +++ b/src/main/java/org/dimdev/utils/GlUtil.java @@ -1,157 +1,163 @@ package org.dimdev.utils; -import com.mojang.blaze3d.platform.GLX; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.class_4493; import net.minecraft.client.render.GuiLighting; -import org.lwjgl.opengl.*; +import org.lwjgl.opengl.GL; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL14; +import org.lwjgl.opengl.GL15; public class GlUtil { + public static void resetState() { // Clear matrix stack - GlStateManager.matrixMode(GL11.GL_MODELVIEW); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(GL11.GL_PROJECTION); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(GL11.GL_TEXTURE); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(GL11.GL_COLOR); - GlStateManager.loadIdentity(); + RenderSystem.matrixMode(GL11.GL_MODELVIEW); + RenderSystem.loadIdentity(); + RenderSystem.matrixMode(GL11.GL_PROJECTION); + RenderSystem.loadIdentity(); + RenderSystem.matrixMode(GL11.GL_TEXTURE); + RenderSystem.loadIdentity(); + RenderSystem.matrixMode(GL11.GL_COLOR); + RenderSystem.loadIdentity(); // Clear attribute stacks TODO: Broken, a stack underflow breaks LWJGL // try { - // do GL11.glPopAttrib(); while (GlStateManager.glGetError() == 0); + // do GL11.glPopAttrib(); while (RenderSystem.glGetError() == 0); // } catch (Throwable ignored) {} // // try { - // do GL11.glPopClientAttrib(); while (GlStateManager.glGetError() == 0); + // do GL11.glPopClientAttrib(); while (RenderSystem.glGetError() == 0); // } catch (Throwable ignored) {} // Reset texture - GlStateManager.bindTexture(0); - GlStateManager.disableTexture(); + RenderSystem.bindTexture(0); + RenderSystem.disableTexture(); // Reset GL lighting - GlStateManager.disableLighting(); - GlStateManager.lightModel(GL11.GL_LIGHT_MODEL_AMBIENT, GuiLighting.singletonBuffer(0.2F, 0.2F, 0.2F, 1.0F)); + RenderSystem.disableLighting(); + RenderSystem.lightModel(GL11.GL_LIGHT_MODEL_AMBIENT, GuiLighting.singletonBuffer(0.2F, 0.2F, 0.2F, 1.0F)); for (int i = 0; i < 8; ++i) { - GlStateManager.disableLight(i); - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_AMBIENT, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_POSITION, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + RenderSystem.disableLight(i); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_AMBIENT, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_POSITION, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); if (i == 0) { - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_DIFFUSE, GuiLighting.singletonBuffer(1.0F, 1.0F, 1.0F, 1.0F)); - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_SPECULAR, GuiLighting.singletonBuffer(1.0F, 1.0F, 1.0F, 1.0F)); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_DIFFUSE, GuiLighting.singletonBuffer(1.0F, 1.0F, 1.0F, 1.0F)); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_SPECULAR, GuiLighting.singletonBuffer(1.0F, 1.0F, 1.0F, 1.0F)); } else { - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_DIFFUSE, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); - GlStateManager.light(GL11.GL_LIGHT0 + i, GL11.GL_SPECULAR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_DIFFUSE, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + RenderSystem.light(GL11.GL_LIGHT0 + i, GL11.GL_SPECULAR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); } } - GlStateManager.disableColorMaterial(); - GlStateManager.colorMaterial(1032, 5634); + RenderSystem.disableColorMaterial(); + RenderSystem.colorMaterial(1032, 5634); // Reset depth - GlStateManager.disableDepthTest(); - GlStateManager.depthFunc(513); - GlStateManager.depthMask(true); + RenderSystem.disableDepthTest(); + RenderSystem.depthFunc(513); + RenderSystem.depthMask(true); // Reset blend mode - GlStateManager.disableBlend(); - GlStateManager.blendFunc(GlStateManager.SrcBlendFactor.ONE, GlStateManager.DstBlendFactor.ZERO); - GlStateManager.blendFuncSeparate(GlStateManager.SrcBlendFactor.ONE, GlStateManager.DstBlendFactor.ZERO, GlStateManager.SrcBlendFactor.ONE, GlStateManager.DstBlendFactor.ZERO); - GlStateManager.blendEquation(GL14.GL_FUNC_ADD); + RenderSystem.disableBlend(); + RenderSystem.blendFunc(class_4493.class_4535.ONE, class_4493.class_4534.ZERO); + RenderSystem.blendFuncSeparate(class_4493.class_4535.ONE, class_4493.class_4534.ZERO, class_4493.class_4535.ONE, class_4493.class_4534.ZERO); + RenderSystem.blendEquation(GL14.GL_FUNC_ADD); // Reset fog - GlStateManager.disableFog(); - GlStateManager.fogMode(GlStateManager.FogMode.LINEAR); - GlStateManager.fogDensity(1.0F); - GlStateManager.fogStart(0.0F); - GlStateManager.fogEnd(1.0F); - GlStateManager.fog(GL11.GL_FOG_COLOR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 0.0F)); + RenderSystem.disableFog(); + RenderSystem.fogMode(class_4493.FogMode.LINEAR); + RenderSystem.fogDensity(1.0F); + RenderSystem.fogStart(0.0F); + RenderSystem.fogEnd(1.0F); + RenderSystem.fog(GL11.GL_FOG_COLOR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 0.0F)); if (GL.getCapabilities().GL_NV_fog_distance) { - GlStateManager.fog(GL11.GL_FOG_MODE, 34140); + RenderSystem.fogMode(34140); } // Reset polygon offset - GlStateManager.polygonOffset(0.0F, 0.0F); - GlStateManager.disablePolygonOffset(); + RenderSystem.polygonOffset(0.0F, 0.0F); + RenderSystem.disablePolygonOffset(); // Reset color logic - GlStateManager.disableColorLogicOp(); - GlStateManager.logicOp(5379); + RenderSystem.disableColorLogicOp(); + RenderSystem.logicOp(5379); // Reset texgen - GlStateManager.disableTexGen(GlStateManager.TexCoord.S); - GlStateManager.disableTexGen(GlStateManager.TexCoord.T); - GlStateManager.disableTexGen(GlStateManager.TexCoord.R); - GlStateManager.disableTexGen(GlStateManager.TexCoord.Q); - GlStateManager.texGenMode(GlStateManager.TexCoord.S, 9216); - GlStateManager.texGenMode(GlStateManager.TexCoord.T, 9216); - GlStateManager.texGenMode(GlStateManager.TexCoord.R, 9216); - GlStateManager.texGenMode(GlStateManager.TexCoord.Q, 9216); - GlStateManager.texGenParam(GlStateManager.TexCoord.S, 9474, GuiLighting.singletonBuffer(1.0F, 0.0F, 0.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.T, 9474, GuiLighting.singletonBuffer(0.0F, 1.0F, 0.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.R, 9474, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.Q, 9474, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.S, 9217, GuiLighting.singletonBuffer(1.0F, 0.0F, 0.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.T, 9217, GuiLighting.singletonBuffer(0.0F, 1.0F, 0.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.R, 9217, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); - GlStateManager.texGenParam(GlStateManager.TexCoord.Q, 9217, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + RenderSystem.disableTexGen(class_4493.TexCoord.S); + RenderSystem.disableTexGen(class_4493.TexCoord.T); + RenderSystem.disableTexGen(class_4493.TexCoord.R); + RenderSystem.disableTexGen(class_4493.TexCoord.Q); + RenderSystem.texGenMode(class_4493.TexCoord.S, 9216); + RenderSystem.texGenMode(class_4493.TexCoord.T, 9216); + RenderSystem.texGenMode(class_4493.TexCoord.R, 9216); + RenderSystem.texGenMode(class_4493.TexCoord.Q, 9216); + RenderSystem.texGenParam(class_4493.TexCoord.S, 9474, GuiLighting.singletonBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.T, 9474, GuiLighting.singletonBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.R, 9474, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.Q, 9474, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.S, 9217, GuiLighting.singletonBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.T, 9217, GuiLighting.singletonBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.R, 9217, GuiLighting.singletonBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + RenderSystem.texGenParam(class_4493.TexCoord.Q, 9217, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 1.0F)); // Disable lightmap - GlStateManager.activeTexture(GLX.GL_TEXTURE1); - GlStateManager.disableTexture(); + RenderSystem.activeTexture(GL13.GL_TEXTURE1); + RenderSystem.disableTexture(); - GlStateManager.activeTexture(GLX.GL_TEXTURE0); + RenderSystem.activeTexture(GL13.GL_TEXTURE0); // Reset texture parameters - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 1000); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 1000); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MIN_LOD, -1000); - GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0.0F); - - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 0.0F)); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_MODULATE); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_MODULATE); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC0_RGB, GL11.GL_TEXTURE); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC1_RGB, GL13.GL_PREVIOUS); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC2_RGB, GL13.GL_CONSTANT); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC0_ALPHA, GL11.GL_TEXTURE); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC1_ALPHA, GL13.GL_PREVIOUS); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC2_ALPHA, GL13.GL_CONSTANT); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_RGB_SCALE, 1.0F); - GlStateManager.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_ALPHA_SCALE, 1.0F); - - GlStateManager.disableNormalize(); - GlStateManager.shadeModel(7425); - GlStateManager.disableRescaleNormal(); - GlStateManager.colorMask(true, true, true, true); - GlStateManager.clearDepth(1.0D); - GlStateManager.lineWidth(1.0F); - GlStateManager.normal3f(0.0F, 0.0F, 1.0F); - GlStateManager.polygonMode(GL11.GL_FRONT, GL11.GL_FILL); - GlStateManager.polygonMode(GL11.GL_BACK, GL11.GL_FILL); - - GlStateManager.enableTexture(); - GlStateManager.shadeModel(7425); - GlStateManager.clearDepth(1.0D); - GlStateManager.enableDepthTest(); - GlStateManager.depthFunc(515); - GlStateManager.enableAlphaTest(); - GlStateManager.alphaFunc(516, 0.1F); - GlStateManager.cullFace(GlStateManager.FaceSides.BACK); - GlStateManager.matrixMode(5889); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(5888); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 1000); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 1000); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MIN_LOD, -1000); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0.0F); + + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, GuiLighting.singletonBuffer(0.0F, 0.0F, 0.0F, 0.0F)); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_MODULATE); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_MODULATE); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC0_RGB, GL11.GL_TEXTURE); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC1_RGB, GL13.GL_PREVIOUS); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC2_RGB, GL13.GL_CONSTANT); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC0_ALPHA, GL11.GL_TEXTURE); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC1_ALPHA, GL13.GL_PREVIOUS); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL15.GL_SRC2_ALPHA, GL13.GL_CONSTANT); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL13.GL_RGB_SCALE, 1.0F); + RenderSystem.texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_ALPHA_SCALE, 1.0F); + + RenderSystem.disableNormalize(); + RenderSystem.shadeModel(7425); + RenderSystem.disableRescaleNormal(); + RenderSystem.colorMask(true, true, true, true); + RenderSystem.clearDepth(1.0D); + RenderSystem.lineWidth(1.0F); + RenderSystem.normal3f(0.0F, 0.0F, 1.0F); + RenderSystem.polygonMode(GL11.GL_FRONT, GL11.GL_FILL); + RenderSystem.polygonMode(GL11.GL_BACK, GL11.GL_FILL); + + RenderSystem.enableTexture(); + RenderSystem.shadeModel(7425); + RenderSystem.clearDepth(1.0D); + RenderSystem.enableDepthTest(); + RenderSystem.depthFunc(515); + RenderSystem.enableAlphaTest(); + RenderSystem.alphaFunc(516, 0.1F); + RenderSystem.cullFace(class_4493.FaceSides.BACK); + RenderSystem.matrixMode(5889); + RenderSystem.loadIdentity(); + RenderSystem.matrixMode(5888); } } diff --git a/src/main/java/org/dimdev/utils/HasteUpload.java b/src/main/java/org/dimdev/utils/HasteUpload.java index 1a7d5cd..9e30621 100644 --- a/src/main/java/org/dimdev/utils/HasteUpload.java +++ b/src/main/java/org/dimdev/utils/HasteUpload.java @@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets; public final class HasteUpload { + public static String uploadToHaste(String baseUrl, String extension, String str) throws IOException { byte[] bytes = str.getBytes(StandardCharsets.UTF_8); diff --git a/src/main/java/org/dimdev/utils/ModIdentifier.java b/src/main/java/org/dimdev/utils/ModIdentifier.java index 68d0336..12ce0ad 100644 --- a/src/main/java/org/dimdev/utils/ModIdentifier.java +++ b/src/main/java/org/dimdev/utils/ModIdentifier.java @@ -1,22 +1,28 @@ package org.dimdev.utils; -import net.fabricmc.loader.FabricLoader; -import net.fabricmc.loader.ModContainer; -import net.fabricmc.loader.ModInfo; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.api.metadata.ModMetadata; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.io.File; import java.io.IOException; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; public final class ModIdentifier { + private static final Logger LOGGER = LogManager.getLogger(); - public static Set identifyFromStacktrace(Throwable e) { - Map> modMap = makeModMap(); + public static Set identifyFromStacktrace(Throwable e) { + Map> modMap = makeModMap(); // Get the set of classes Set classes = new LinkedHashSet<>(); @@ -27,51 +33,63 @@ public static Set identifyFromStacktrace(Throwable e) { e = e.getCause(); } - Set mods = new LinkedHashSet<>(); + Set mods = new LinkedHashSet<>(); for (String className : classes) { - Set classMods = identifyFromClass(className, modMap); - if (classMods != null) mods.addAll(classMods); + Set classMods = identifyFromClass(className, modMap); + if (classMods != null) { + mods.addAll(classMods); + } } return mods; } - public static Set identifyFromClass(String className) { + public static Set identifyFromClass(String className) { return identifyFromClass(className, makeModMap()); } // TODO: get a list of mixin transformers that affected the class and blame those too - private static Set identifyFromClass(String className, Map> modMap) { + private static Set identifyFromClass(String className, Map> modMap) { // Skip identification for Mixin, one's mod copy of the library is shared with all other mods - if (className.startsWith("org.spongepowered.asm.mixin.")) return Collections.emptySet(); + if (className.startsWith("org.spongepowered.asm.mixin.")) { + return Collections.emptySet(); + } // Get the URL of the class URL url = ModIdentifier.class.getResource(className); if (url == null) { - LOGGER.warn("Failed to identify " + className); + LOGGER.warn("Failed to identify mod for " + className); return Collections.emptySet(); } // Get the mod containing that class try { - if (url.getProtocol().equals("jar")) url = new URL(url.getFile().substring(0, url.getFile().indexOf('!'))); - return modMap.get(new File(url.toURI()).getCanonicalFile()); - } catch (URISyntaxException | IOException e) { - throw new RuntimeException(e); + return modMap.get(jarFromUrl(url)); + } catch (URISyntaxException | IOException ex) { + return Collections.emptySet(); // we cannot do it } } - private static Map> makeModMap() { - Map> modMap = new HashMap<>(); - for (ModContainer mod : FabricLoader.INSTANCE.getModContainers()) { - Set currentMods = modMap.getOrDefault(mod.getOriginFile(), new HashSet<>()); - currentMods.add(mod.getInfo()); + private static Map> makeModMap() { + Map> modMap = new HashMap<>(); + for (ModContainer mod : FabricLoader.getInstance().getAllMods()) { + if (!(mod instanceof net.fabricmc.loader.ModContainer)) { + continue; + } try { - modMap.put(mod.getOriginFile().getCanonicalFile(), currentMods); - } catch (IOException e) { - throw new RuntimeException(e); + URI modJar = jarFromUrl(((net.fabricmc.loader.ModContainer) mod).getOriginUrl()); + modMap.computeIfAbsent(modJar, f -> new HashSet<>()).add(mod.getMetadata()); + } catch (URISyntaxException | IOException ignored) { + // cannot find jar, so bruh } } return modMap; } + + private static URI jarFromUrl(URL url) throws URISyntaxException, IOException { + if (url.getProtocol().equals("jar")) { + url = new URL(url.getFile().substring(0, url.getFile().indexOf('!'))); + } + return url.toURI().normalize(); + } } diff --git a/src/main/java/org/dimdev/utils/SSLUtils.java b/src/main/java/org/dimdev/utils/SSLUtils.java index 2f1acc7..34040e9 100644 --- a/src/main/java/org/dimdev/utils/SSLUtils.java +++ b/src/main/java/org/dimdev/utils/SSLUtils.java @@ -1,12 +1,24 @@ package org.dimdev.utils; -import javax.net.ssl.*; -import java.io.*; -import java.security.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Arrays; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + public final class SSLUtils { /** Disables SSL certificate validation. */ @@ -16,8 +28,12 @@ public static void trustAllCertificates() { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new X509TrustManager[]{new X509TrustManager() { - @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} - @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} + @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + + @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } diff --git a/src/main/resources/assets/toomanycrashes/icon.png b/src/main/resources/assets/toomanycrashes/icon.png new file mode 100644 index 0000000..ca89446 Binary files /dev/null and b/src/main/resources/assets/toomanycrashes/icon.png differ diff --git a/src/main/resources/assets/toomanycrashes/lang/zh_cn.json b/src/main/resources/assets/toomanycrashes/lang/zh_cn.json index 173b990..26fcfef 100644 --- a/src/main/resources/assets/toomanycrashes/lang/zh_cn.json +++ b/src/main/resources/assets/toomanycrashes/lang/zh_cn.json @@ -2,23 +2,23 @@ "toomanycrashes.gui.getLink": "获取链接", "toomanycrashes.gui.failed": "[失败]", "toomanycrashes.gui.keepPlaying": "继续游戏", - "toomanycrashes.gui.restart": "重启Minecraft", - "toomanycrashes.crashscreen.title": "Minecraft崩溃啦!", - "toomanycrashes.crashscreen.summary": "Minecraft遇到一个问题崩溃了。", - "toomanycrashes.crashscreen.paragraph1.line1": "下列的mod被确定为崩溃的可能原因:", + "toomanycrashes.gui.restart": "重启 Minecraft", + "toomanycrashes.crashscreen.title": "Minecraft 崩溃啦!", + "toomanycrashes.crashscreen.summary": "Minecraft 遇到一个问题崩溃了。", + "toomanycrashes.crashscreen.paragraph1.line1": "下列的 mod 被确定为崩溃的可能原因:", "toomanycrashes.crashscreen.unknownCause": "未知", - "toomanycrashes.crashscreen.identificationErrored": "[鉴别错误,请报告给TooManyCrashes]", - "toomanycrashes.crashscreen.paragraph2.line1": "点击列表中的任意mod即可访问它们的网站获取技术支持。", + "toomanycrashes.crashscreen.identificationErrored": "[鉴别错误,请报告给 TooManyCrashes]", + "toomanycrashes.crashscreen.paragraph2.line1": "点击列表中的任意 mod 即可访问它们的网站获取技术支持。", "toomanycrashes.crashscreen.paragraph2.line2": "一份报告已经生成,你可以在这里找到(点击):", "toomanycrashes.crashscreen.reportSaveFailed": "[保存报告错误,请查看日志]", "toomanycrashes.crashscreen.paragraph3.line1": "点击\"获取链接\"按钮在你的浏览器中打开它。", - "toomanycrashes.crashscreen.paragraph3.line2": "我们建议您将此报告发送给mod的作者以帮助它们修复问题。", - "toomanycrashes.crashscreen.paragraph3.line3": "由于安装了TooManyCrashes,尽管发生了崩溃但是你可以继续游戏。", + "toomanycrashes.crashscreen.paragraph3.line2": "我们建议您将此报告发送给 mod 的作者以帮助它们修复问题。", + "toomanycrashes.crashscreen.paragraph3.line3": "由于安装了 TooManyCrashes,尽管发生了崩溃但你可以继续游戏。", "toomanycrashes.crashscreen.paragraph3.line4": "", "toomanycrashes.initerrorscreen.title": "Minecraft未能启动!", - "toomanycrashes.initerrorscreen.summary": "启动过程中一个错误阻止了Minecraft的启动", + "toomanycrashes.initerrorscreen.summary": "启动时一个错误阻止了 Minecraft 的启动。", "toomanycrashes.initerrorscreen.paragraph3.line1": "点击\"获取链接\"按钮在你的浏览器中打开它。", - "toomanycrashes.initerrorscreen.paragraph3.line2": "我们建议您将此报告发送给mod的作者以帮助它们修复问题。", - "toomanycrashes.initerrorscreen.paragraph3.line3": "不幸的是,在发生这个错误之后继续加载minecraft时不可能的。", + "toomanycrashes.initerrorscreen.paragraph3.line2": "我们建议您将此报告发送给 mod 的作者以帮助它们修复问题。", + "toomanycrashes.initerrorscreen.paragraph3.line3": "不幸的是,在发生这个错误之后不可能继续加载 Minecraft。", "toomanycrashes.initerrorscreen.paragraph3.line4": "" } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1b5b036..fd7b918 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,8 +1,20 @@ { - "id": "toomanycrashes", - "name": "TooManyCrashes", - "version": "1.0", - "mixins": { - "common": "mixins.toomanycrashes.json" - } + "schemaVersion": 1, + "id": "toomanycrashes", + "name": "TooManyCrashes", + "description": "A port of VanillaFix's crash improvement features to Fabric", + "version": "${version}", + "contact": { + "issues": "https://github.com/liachmodded/TooManyCrashes/issues", + "sources": "https://github.com/liachmodded/TooManyCrashes" + }, + "icon": "assets/toomanycrashes/icon.png", + "mixins": [ + "mixins.toomanycrashes.json" + ], + "entrypoints": { + "main": [ + "org.dimdev.toomanycrashes.TooManyCrashes" + ] + } } diff --git a/src/main/resources/mixins.toomanycrashes.json b/src/main/resources/mixins.toomanycrashes.json index 9cd1575..29ecde4 100644 --- a/src/main/resources/mixins.toomanycrashes.json +++ b/src/main/resources/mixins.toomanycrashes.json @@ -8,7 +8,7 @@ "mixins": [ "MixinCrashReport", "MixinCrashReportSection", - "MixinCrashReportSection$MixinElement", + "CrashReportSectionElementMixin", "MixinEntity", "MixinIntegratedServer", "MixinTileEntity" @@ -16,7 +16,7 @@ "client": [ "client.MixinBufferBuilder", "client.MixinKeyboard", - "client.MixinMain", - "client.MixinMinecraftClient" + "client.MixinMinecraftClient", + "client.ClientMainMixin" ] }