Skip to content

Commit

Permalink
4.4.5
Browse files Browse the repository at this point in the history
  • Loading branch information
natanfudge committed Jul 19, 2023
1 parent 24aa4ff commit daa1fd3
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 46 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## 4.4.5
- Fixed a crash in Fabric with certain mods
## 4.4.4
- Cleaned up some more things when the game crashes.
## 4.4.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.util.List;

public class NotEnoughCrashes {

public static final Path DIRECTORY = NecPlatform.instance().getGameDirectory().resolve("not-enough-crashes");
public static final String NAME = "Not Enough Crashes";
public static final String MOD_ID = "notenoughcrashes";
Expand All @@ -30,10 +29,12 @@ public static void logDebug(String message) {
if (LOG_DEBUG) getLogger().error(message);
}

public static final boolean ENABLE_GAMELOOP_CATCHING = true;
public static boolean enableGameloopCatching() {
return NecConfig.getCurrent().catchGameloopCrashes() && !NecPlatform.instance().irisExists();
}

public static boolean enableEntrypointCatching() {
return NecConfig.getCurrent().catchInitializationCrashes();
return NecConfig.getCurrent().catchInitializationCrashes() && !NecPlatform.instance().irisExists();
}

public static CommonModMetadata getMetadata() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@


public record NecConfig(boolean disableReturnToMainMenu, boolean catchInitializationCrashes,
boolean debugModIdentification, int crashLimit) {
boolean debugModIdentification, int crashLimit,boolean catchGameloopCrashes) {

public static NecConfig getCurrent() {
return new NecConfig(NecMidnightConfig.disableReturnToMainMenu, NecMidnightConfig.catchInitializationCrashes,
NecMidnightConfig.debugModIdentification, NecMidnightConfig.crashLimit);
NecMidnightConfig.debugModIdentification, NecMidnightConfig.crashLimit, NecMidnightConfig.catchGameloop);
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
package fudge.notenoughcrashes.config;

//TODO: config Migration path.
// Current version:
// - If the new config value is non-default, use it, otherwise, use old config value.
// - Log a warning in the console to use the new format.
// Next MC Version:
// - Log an error in the console that the old config will stop working in the next Minecraft version.
// MC version after that:
// - Remove old config.

public class NecMidnightConfig extends MidnightConfig {
@Comment
public static Comment disableReturnToMainMenuComment1;
@Comment
public static Comment disableReturnToMainMenuComment2;
@Entry
public static boolean disableReturnToMainMenu;
public static boolean disableReturnToMainMenu = false;

@Comment
public static Comment catchInitializationCrashesComment1;
@Comment
public static Comment catchInitializationCrashesComment2;
@Comment
public static Comment catchInitializationCrashesComment3;
@Entry
public static boolean catchInitializationCrashes = true;

Expand All @@ -34,4 +28,11 @@ public class NecMidnightConfig extends MidnightConfig {
@Entry
public static int crashLimit = 20;

@Comment
public static Comment catchGameloopComment1;
@Comment
public static Comment catchGameloopComment2;
@Entry
public static boolean catchGameloop = true;

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import net.minecraft.client.gui.screen.ConfirmLinkScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.*;
import net.minecraft.util.Util;
import net.minecraft.util.crash.CrashReport;
Expand All @@ -30,6 +29,7 @@ public abstract class ProblemScreen extends Screen {
));

private static final int GREEN = 0x00FF00;
private static final int GRAY = 0x9a9a9a;
private static final Text uploadToCrashyText = NecLocalization.translatedText("notenoughcrashes.gui.uploadToCrashy")
.copy().setStyle(Style.EMPTY.withColor(GREEN));
private static final Text uploadToCrashyLoadingText = NecLocalization.translatedText("notenoughcrashes.gui.loadingCrashyUpload");
Expand Down Expand Up @@ -135,16 +135,19 @@ private void handleCrashyUploadClick(ButtonWidget buttonWidget) {
@Override
public void init() {
widgets = new ArrayList<>();

// height / 4 + 120 + 12
addDrawableChild(
ButtonWidget.builder(NecLocalization.translatedText("notenoughcrashes.gui.getLink"), this::handleLegacyLinkClick)
.dimensions(width / 2 - 155 + 160, height / 4 + 132 + 12, 150, 20)
ButtonWidget.builder(
NecLocalization.translatedText("notenoughcrashes.gui.getLink")
.copy().setStyle(Style.EMPTY.withColor(GRAY))
, this::handleLegacyLinkClick)
.dimensions(width / 2 - 155 + 160, height / 4 + 144 + 12, 150, 20)
.build()
);

addDrawableChild(
ButtonWidget.builder(uploadToCrashyText,this::handleCrashyUploadClick)
.dimensions(width / 2 - 155 + 160, height / 4 + 108 + 12, 150, 20)
.dimensions(width / 2 - 155 + 160, height / 4 + 120 + 12, 150, 20)
.build()
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import fudge.notenoughcrashes.mixinhandlers.EntryPointCatcher;
import fudge.notenoughcrashes.mixinhandlers.InGameCatcher;
import fudge.notenoughcrashes.patches.MinecraftClientAccess;
import fudge.notenoughcrashes.stacktrace.CrashUtils;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.profiler.Recorder;
Expand Down Expand Up @@ -36,6 +35,10 @@ public abstract class MixinMinecraftClient extends ReentrantThreadExecutor<Runna
@Shadow
private Recorder recorder;

@Shadow
public static void printCrashReport(CrashReport report) {
}

@Override
public Recorder getRecorder() {
return recorder;
Expand All @@ -57,7 +60,7 @@ private void beforeRun(CallbackInfo ci) {

@Inject(method = "run()V", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;crashReportSupplier:Ljava/util/function/Supplier;"))
private void onRunLoop(CallbackInfo ci) {
if (!NotEnoughCrashes.ENABLE_GAMELOOP_CATCHING) return;
if (!NotEnoughCrashes.enableGameloopCatching()) return;

if (this.crashReportSupplier != null) {
NotEnoughCrashes.logDebug("Handling run loop crash");
Expand All @@ -72,7 +75,7 @@ private void onRunLoop(CallbackInfo ci) {
// Can't capture arg in inject so captured here
@ModifyArg(method = "run()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V", ordinal = 1))
private CrashReport atTheEndOfFirstCatchBeforePrintingCrashReport(CrashReport report) {
if (!NotEnoughCrashes.ENABLE_GAMELOOP_CATCHING) return report;
if (!NotEnoughCrashes.enableGameloopCatching()) return report;

NotEnoughCrashes.logDebug("Handling client game loop try/catch crash in first catch block");
// we MUST use the report passed as parameter, because the field one only gets assigned in integrated server crashes.
Expand All @@ -83,7 +86,7 @@ private CrashReport atTheEndOfFirstCatchBeforePrintingCrashReport(CrashReport re
// Can't capture arg in inject so captured here
@ModifyArg(method = "run()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V", ordinal = 2))
private CrashReport atTheEndOfSecondCatchBeforePrintingCrashReport(CrashReport report) {
if (!NotEnoughCrashes.ENABLE_GAMELOOP_CATCHING) return report;
if (!NotEnoughCrashes.enableGameloopCatching()) return report;

NotEnoughCrashes.logDebug("Handling client game loop try/catch crash in second catch block");
// we MUST use the report passed as parameter, because the field one only gets assigned in integrated server crashes.
Expand All @@ -94,14 +97,17 @@ private CrashReport atTheEndOfSecondCatchBeforePrintingCrashReport(CrashReport r
// Prevent calling printCrashReport which is not needed
@Inject(method = "run()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V"), cancellable = true)
private void cancelRunLoopAfterCrash(CallbackInfo ci) {
if (NotEnoughCrashes.ENABLE_GAMELOOP_CATCHING) ci.cancel();
if (NotEnoughCrashes.enableGameloopCatching()) ci.cancel();
}

@Inject(method = "cleanUpAfterCrash()V", at = @At("HEAD"))
private void beforeCleanUpAfterCrash(CallbackInfo info) {
InGameCatcher.cleanupBeforeMinecraft(renderTaskQueue);
if (NotEnoughCrashes.enableGameloopCatching()) {
InGameCatcher.cleanupBeforeMinecraft(renderTaskQueue);
}
}
//String levelName, LevelStorage.Session session, ResourcePackManager dataPackManager, SaveLoader saveLoader

/**
* Prevent the integrated server from exiting in the case it crashed
*/
Expand All @@ -112,8 +118,9 @@ private void beforeCleanUpAfterCrash(CallbackInfo info) {
")V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V"))
private void redirectPrintCrashReport(CrashReport report) {
// CrashUtils.outputReport(report);
if (!NotEnoughCrashes.enableGameloopCatching()) printCrashReport(report);
}

/**
* Forge only: Prevent the integrated server from exiting in the case it crashed in another case
*/
Expand All @@ -122,6 +129,7 @@ private void redirectPrintCrashReport(CrashReport report) {
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;printCrashReport(Lnet/minecraft/util/crash/CrashReport;)V"),
require = 0)
private void redirectForgePrintCrashReport(CrashReport report) {
if (!NotEnoughCrashes.enableGameloopCatching()) printCrashReport(report);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fudge.notenoughcrashes.mixins.client;

import fudge.notenoughcrashes.NotEnoughCrashes;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.crash.CrashReport;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -19,6 +20,7 @@ public class MixinMinecraftServerClientOnly {
*/
@Redirect(method = "runServer()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/crash/CrashReport;writeToFile(Ljava/io/File;)Z"))
private boolean disableIntegratedServerWriteToFileOnCrash(CrashReport instance, File file) {
return true;
if (NotEnoughCrashes.enableGameloopCatching()) return true;
else return instance.writeToFile(file);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ static NecPlatform instance() {

boolean modContainsFile(CommonModMetadata mod, String path);

// default NecConfig getCurrentConfig() {
//
// }
default boolean irisExists() {
return false;
}

boolean isClient();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"notenoughcrashes.gui.getLink": "Get link",
"notenoughcrashes.gui.uploadToCrashy": "Show on Crashy",
"notenoughcrashes.gui.getLink": "Show crash log (old)",
"notenoughcrashes.gui.uploadToCrashy": "Show crash log",
"notenoughcrashes.gui.loadingCrashyUpload": "Uploading...",
"notenoughcrashes.gui.failed": "[Failed, Report to NEC]",
"notenoughcrashes.gui.keepPlaying": "Keep playing",
Expand Down Expand Up @@ -28,12 +28,16 @@
"notenoughcrashes.midnightconfig.disableReturnToMainMenuComment1": "If true, the \"Return To Main Menu\" button will be disabled when crashing,",
"notenoughcrashes.midnightconfig.disableReturnToMainMenuComment2": "meaning you cannot recover from a crash.",
"notenoughcrashes.midnightconfig.disableReturnToMainMenu": "Disable Return To Main Menu",
"notenoughcrashes.midnightconfig.catchInitializationCrashesComment1": "(Fabric Only) If true, the game will close normally when it fails to initialize,",
"notenoughcrashes.midnightconfig.catchInitializationCrashesComment1": "(Fabric Only) If false, the game will close normally when it fails to initialize,",
"notenoughcrashes.midnightconfig.catchInitializationCrashesComment2": "and will not display a special crash screen.",
"notenoughcrashes.midnightconfig.catchInitializationCrashesComment3": "This will be always disabled (even if the config is set to true) when Iris is installed.",
"notenoughcrashes.midnightconfig.catchInitializationCrashes": "Catch Initialization Crashes",
"notenoughcrashes.midnightconfig.debugModIdentificationComment": "If true, additional info will be logged for the mod developer.",
"notenoughcrashes.midnightconfig.debugModIdentification": "Debug Mod Identification",
"notenoughcrashes.midnightconfig.crashLimitComment": "How many times NEC will try to prevent the game from closing in one session.",
"notenoughcrashes.midnightconfig.crashLimit": "Crash Limit",
"notenoughcrashes.midnightconfig.catchGameloopComment1": "If false, NEC won't attempt to prevent the game from closing when it crashes.",
"notenoughcrashes.midnightconfig.catchGameloopComment2": "This will be always disabled (even if the config is set to true) when Iris is installed.",
"notenoughcrashes.midnightconfig.catchGameloop": "Catch Gameplay Crashes",
"notenoughcrashes.midnightconfig.title": "Not Enough Crashes Configuration"
}
4 changes: 3 additions & 1 deletion fabric/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ repositories {
name = "modmenu"
url = "https://maven.terraformersmc.com"
}
maven { url = "https://api.modrinth.com/maven" }
}

dependencies {
Expand All @@ -36,7 +37,8 @@ dependencies {

// For config modmenu integration.
modCompileOnly("com.terraformersmc:modmenu:6.2.2")
// modRuntimeOnly("com.terraformersmc:modmenu:6.2.2")
modCompileOnly "maven.modrinth:iris:1.6.1+1.19.2"
modRuntimeOnly("com.terraformersmc:modmenu:7.1.0")

// Uncomment to add the test mod at runtime
// runtimeOnly project(path: ":TestFabricMod", configuration: "namedElements")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package fudge.notenoughcrashes.fabric.mixins.iris;

import fudge.notenoughcrashes.NotEnoughCrashes;
import fudge.notenoughcrashes.fabric.platform.FabricPlatform;
import fudge.notenoughcrashes.platform.NecPlatform;
import net.coderbot.iris.Iris;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
* Courtesy of @TBiscuit
*/
@Mixin(Iris.class)
public class SilentNEC {
@Shadow(remap = false)
private static boolean hasNEC;

@Inject(at = @At("TAIL"), method = "onEarlyInitialize", remap = false)
private void onEarlyInitialize(CallbackInfo info) {
var platform = (FabricPlatform)NecPlatform.instance();
platform.setIrisExists();
hasNEC = false; // NEC doesn't exist Iris, it doesn't exist...
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package fudge.notenoughcrashes.fabric.platform;

import fudge.notenoughcrashes.NotEnoughCrashes;
import fudge.notenoughcrashes.config.NecConfig;
import fudge.notenoughcrashes.config.NecMidnightConfig;
import fudge.notenoughcrashes.platform.CommonModMetadata;
import fudge.notenoughcrashes.platform.ModsByLocation;
import fudge.notenoughcrashes.platform.NecPlatform;
Expand All @@ -17,11 +15,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

public class FabricPlatform implements NecPlatform {
private boolean irisExists = false;

public void setIrisExists() {
irisExists = true;
}

@Override
public boolean isForge() {
Expand Down Expand Up @@ -89,14 +93,20 @@ public List<CommonModMetadata> getAllMods() {

@Override
public boolean modContainsFile(CommonModMetadata mod, String path) {
return FabricLoader.getInstance().getModContainer(mod.id()).flatMap(modContainer -> modContainer.findPath(path)).isPresent();
return FabricLoader.getInstance().getModContainer(mod.id()).flatMap(modContainer -> {
try {
return modContainer.findPath(path);
} catch (InvalidPathException e) {
// Sometimes weird mixin file fuck up this method call and throw a InvalidPathException
return Optional.empty();
}
}).isPresent();
}

// @Override
// public NecConfig getCurrentConfig() {
// return new NecConfig(NecMidnightConfig.disableReturnToMainMenu, NecMidnightConfig.catchInitializationCrashes,
// NecMidnightConfig.debugModIdentification, NecMidnightConfig.crashLimit);
// }
@Override
public boolean irisExists() {
return irisExists;
}

@Override
public boolean isClient() {
Expand Down
7 changes: 4 additions & 3 deletions fabric/src/main/resources/notenoughcrashes.fabric.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
"minVersion": "0.8",
"compatibilityLevel": "JAVA_17",
"mixins": [
"MixinMain"
"MixinMain",
"iris.SilentNEC"
],
"client": [
"client.MixinMain",
"client.CatchInitMInecraftClientMixin"
"client.CatchInitMInecraftClientMixin",
"client.MixinMain"
]
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ task_tree = { id = "com.dorongold.task-tree", version.ref = "task_tree" }
[versions]

# This Mod Version
mod_version = "4.4.4"
mod_version = "4.4.5"

# Gradle Plugins
architectury_plugin = "3.4-SNAPSHOT"
Expand Down

0 comments on commit daa1fd3

Please sign in to comment.