Skip to content

Commit

Permalink
Add: ITransformationService
Browse files Browse the repository at this point in the history
  • Loading branch information
xfl03 committed Jan 7, 2023
1 parent 2358995 commit caa691a
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 94 deletions.
3 changes: 3 additions & 0 deletions ForgeApi/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
plugins {
id 'java'
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.minecraftforge.fml.common;

// 1.16.5-
public interface ICrashCallable {
String getLabel();
String call() throws Exception;
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ sourceSets.main.resources { srcDir 'src/generated/resources' }

dependencies {
minecraft 'net.minecraftforge:forge:1.19.3-44.1.2'
implementation project(":ForgeApi")
}

jar {
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pluginManagement {
maven { url = 'https://maven.minecraftforge.net/' }
}
}
//include "CrashMaker"
//include "CrashMaker"
include "ForgeApi"
4 changes: 1 addition & 3 deletions src/main/java/me/xfl03/morecrashinfo/crash/CoreModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import me.xfl03.morecrashinfo.util.ModHelper;
import me.xfl03.morecrashinfo.util.PrintHelper;
import net.minecraftforge.coremod.CoreMod;
import net.minecraftforge.fml.ISystemReportExtender;
import net.minecraftforge.fml.common.ICrashCallable;
import net.minecraftforge.forgespi.coremod.ICoreModFile;

import java.util.ArrayList;
import java.util.List;

public class CoreModList implements ICrashCallable, ISystemReportExtender {
public class CoreModList implements CustomCrashExtender {
@Override
public String getLabel() {
return "Forge CoreMods";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.xfl03.morecrashinfo.crash;

import net.minecraftforge.fml.ISystemReportExtender;
import net.minecraftforge.fml.common.ICrashCallable;

public interface CustomCrashExtender extends ICrashCallable, ISystemReportExtender {
}
4 changes: 1 addition & 3 deletions src/main/java/me/xfl03/morecrashinfo/crash/ModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import me.xfl03.morecrashinfo.util.ModHelper;
import me.xfl03.morecrashinfo.util.PrintHelper;
import net.minecraftforge.fml.ISystemReportExtender;
import net.minecraftforge.fml.common.ICrashCallable;
import net.minecraftforge.forgespi.language.IModInfo;

import java.util.ArrayList;
import java.util.List;

public class ModList implements ICrashCallable, ISystemReportExtender {
public class ModList implements CustomCrashExtender {
@Override
public String getLabel() {
return "Forge Mods";
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/me/xfl03/morecrashinfo/fml/ModLocator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package me.xfl03.morecrashinfo.fml;

import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.loading.moddiscovery.AbstractJarFileModLocator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Stream;
import java.util.zip.ZipFile;

public class ModLocator extends AbstractJarFileModLocator {
private final Logger logger = LogManager.getLogger("MoreCrashInfoModLocator");
private Path modPath = null;

private void visitModFile(Path path) {
// logger.info("Try to Visit {} {} {}", path, Files.isRegularFile(path), path.toString().endsWith(".jar"));
if (!Files.isRegularFile(path) || !path.toString().endsWith(".jar")) {
return;
}
try (ZipFile zip = new ZipFile(new File(path.toUri()))) {
// logger.info("Visiting {}", path);
if (zip.getEntry("me/xfl03/morecrashinfo/MoreCrashInfo.class") != null) {
logger.info("MoreCrashInfo mod found at {}", path);
modPath = path;
}
} catch (Exception e) {
logger.warn("Error while loading {}", path);
}
}

private void visitModDir(Path path) {
try (Stream<Path> paths = Files.list(path)) {
paths.forEach(this::visitModFile);
} catch (Exception e) {
logger.warn("Error while visiting mod dir");
}
}

@Override
public Stream<Path> scanCandidates() {
Path modFolder = FMLPaths.MODSDIR.get();
logger.warn("Mod folder {}", modFolder);
visitModDir(modFolder);
logger.warn("Mod path {}", modPath);
return Stream.ofNullable(modPath);
}

@Override
public String name() {
return "MoreCrashInfoModLocator";
}

@Override
public void initArguments(Map<String, ?> arguments) {

}
}
29 changes: 18 additions & 11 deletions src/main/java/me/xfl03/morecrashinfo/handler/CrashHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
public class CrashHandler {
private static final Map<Class<?>, Function<Throwable, ExceptionHandler>> handlers = new HashMap<>();

static {
CrashHandler.registerHandler(VerifyError.class, VerifyErrorHandler::new);

net.minecraftforge.fml.CrashReportCallables.registerCrashCallable(new ModList());// 1.16.5- net.minecraftforge.fml.CrashReportExtender
net.minecraftforge.fml.CrashReportCallables.registerCrashCallable(new CoreModList());// 1.16.5- net.minecraftforge.fml.CrashReportExtender
}
// private static void init() {
// CrashHandler.registerHandler(VerifyError.class, VerifyErrorHandler::new);
//
// net.minecraftforge.fml.CrashReportCallables.registerCrashCallable(new ModList());// 1.16.5- net.minecraftforge.fml.CrashReportExtender
// net.minecraftforge.fml.CrashReportCallables.registerCrashCallable(new CoreModList());// 1.16.5- net.minecraftforge.fml.CrashReportExtender
// }

private static ExceptionHandler handler;

Expand All @@ -27,17 +27,24 @@ public static void registerHandler(Class<?> exception, Function<Throwable, Excep
// 1.16.5- net.minecraftforge.fml.CrashReportExtender.addCrashReportHeader
// 1.17.1 net.minecraftforge.fmllegacy.CrashReportExtender.addCrashReportHeader
public static void addCrashReportHeader(StringBuilder stringbuilder, net.minecraft.CrashReport crashReport) {
Throwable cause = crashReport.getException();//1.16.5- net.minecraft.crash.CrashReport.func_71505_b
handler = Optional.ofNullable(handlers.get(cause.getClass()))
.orElse(ExceptionHandler::new).apply(cause);
handler.handleHeader(stringbuilder);
try {
// init();
} catch (Exception e) {
e.printStackTrace();
}
// Throwable cause = crashReport.getException();//1.16.5- net.minecraft.crash.CrashReport.func_71505_b
// handler = Optional.ofNullable(handlers.get(cause.getClass()))
// .orElse(ExceptionHandler::new).apply(cause);
// handler.handleHeader(stringbuilder);
}

// 1.16.5- net.minecraftforge.fml.CrashReportExtender.generateEnhancedStackTrace
// 1.17.1 net.minecraftforge.fmllegacy.CrashReportExtender.generateEnhancedStackTrace
public static String generateEnhancedStackTrace(final Throwable throwable) {
StringBuilder stringbuilder = new StringBuilder();
handler.handleException(stringbuilder);
if (handler != null) {
handler.handleException(stringbuilder);
}
stringbuilder.append(TransformingThrowablePatternConverter.generateEnhancedStackTrace(throwable));
return stringbuilder.toString();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package me.xfl03.morecrashinfo.modlauncher;

import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.ITransformerVotingContext;
import cpw.mods.modlauncher.api.TransformerVoteResult;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;

import java.util.LinkedHashSet;
import java.util.Set;

public class CrashReportExtenderTransformer implements ITransformer<MethodNode> {
private static MethodNode redirectStaticMethod(MethodNode method, String className) {
Type[] args = Type.getArgumentTypes(method.desc);
int returnOp = -1;
for (AbstractInsnNode insnNode : method.instructions) {
if (insnNode.getOpcode() != -1) {
returnOp = insnNode.getOpcode();
}
}
method.instructions.clear();
// method.maxStack = Math.max(argNum, returnOp == Opcodes.RETURN ? 0 : 1);

for (int i = 0; i < args.length; ++i) {
TransformerService.logger.info("ALOAD {}", i);
method.instructions.add(new VarInsnNode(Opcodes.ALOAD, i));
}
TransformerService.logger.info("INVOKESTATIC {} {} {}", className, method.name, method.desc);
method.instructions.add(new MethodInsnNode(
Opcodes.INVOKESTATIC, className, method.name, method.desc, false));
TransformerService.logger.info("{}", returnOp);
method.instructions.add(new InsnNode(returnOp));

return method;
}

@Override
public @NotNull MethodNode transform(MethodNode input, ITransformerVotingContext context) {
TransformerService.logger.info("Transforming {} {}", input.name, input.desc);
return redirectStaticMethod(input, "me/xfl03/morecrashinfo/handler/CrashHandler");
}

@Override
public @NotNull TransformerVoteResult castVote(ITransformerVotingContext context) {
return TransformerVoteResult.YES;
}

@Override
public @NotNull Set<Target> targets() {
Set<Target> targets = new LinkedHashSet<>();
//Minecraft 1.16-
targets.add(Target.targetMethod(
"net/minecraftforge/fml/CrashReportExtender",
"addCrashReportHeader",
"(Ljava/lang/StringBuilder;Lnet/minecraft/crash/CrashReport;)V"
));
targets.add(Target.targetMethod(
"net/minecraftforge/fml/CrashReportExtender",
"generateEnhancedStackTrace",
"(Ljava/lang/Throwable;)Ljava/lang/String;"
));
//Minecraft 1.17
targets.add(Target.targetMethod(
"net/minecraftforge/fmllegacy/CrashReportExtender",
"addCrashReportHeader",
"(Ljava/lang/StringBuilder;Lnet/minecraft/CrashReport;)V"
));
targets.add(Target.targetMethod(
"net/minecraftforge/fmllegacy/CrashReportExtender",
"generateEnhancedStackTrace",
"(Ljava/lang/Throwable;)Ljava/lang/String;"
));
//Minecraft 1.18+
targets.add(Target.targetMethod(
"net/minecraftforge/logging/CrashReportExtender",
"addCrashReportHeader",
"(Ljava/lang/StringBuilder;Lnet/minecraft/CrashReport;)V"
));
targets.add(Target.targetMethod(
"net/minecraftforge/logging/CrashReportExtender",
"generateEnhancedStackTrace",
"(Ljava/lang/Throwable;)Ljava/lang/String;"
));
return targets;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package me.xfl03.morecrashinfo.modlauncher;

import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.ITransformerVotingContext;
import cpw.mods.modlauncher.api.TransformerVoteResult;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.tree.ClassNode;

import java.util.LinkedHashSet;
import java.util.Set;

public class CustomCrashExtenderTransformer implements ITransformer<ClassNode> {
@Override
public @NotNull ClassNode transform(ClassNode input, ITransformerVotingContext context) {
TransformerService.logger.info("Transforming class {}", input.name);
input.interfaces.removeIf(it -> it.equals("net/minecraftforge/fml/common/ICrashCallable"));
return input;
}

@Override
public @NotNull TransformerVoteResult castVote(ITransformerVotingContext context) {
return TransformerVoteResult.YES;
}

@Override
public @NotNull Set<Target> targets() {
Set<Target> targets = new LinkedHashSet<>();
targets.add(Target.targetClass("me/xfl03/morecrashinfo/crash/CustomCrashExtender"));
return targets;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package me.xfl03.morecrashinfo.modlauncher;

import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class TransformerService implements ITransformationService {
public static Logger logger;

@Override
public @NotNull String name() {
return "MoreCrashInfoTransformerService";
}

@Override
public void onLoad(IEnvironment env, Set<String> otherServices) throws IncompatibleEnvironmentException {
logger = LogManager.getLogger("MoreCrashInfoTransformerService");
}

@Override
public void initialize(IEnvironment environment) {
}

@Override
public @NotNull List<ITransformer> transformers() {
return Arrays.asList(new CustomCrashExtenderTransformer(), new CrashReportExtenderTransformer());
}
}
3 changes: 0 additions & 3 deletions src/main/resources/META-INF/coremods.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
me.xfl03.morecrashinfo.modlauncher.TransformerService
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
me.xfl03.morecrashinfo.fml.ModLocator
Loading

0 comments on commit caa691a

Please sign in to comment.