Skip to content

Commit

Permalink
Add: mixin list
Browse files Browse the repository at this point in the history
  • Loading branch information
xfl03 committed Jan 10, 2023
1 parent 3342ab5 commit 0b23151
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public List<IModFile> scanModsLegacy() {
//1.17+
@Override
public Stream<Path> scanCandidates() {
logger.info("We are now at MoreCrashInfo ModLocator");
logger.debug("We are now at MoreCrashInfo ModLocator");
Path gameFolder = FMLPaths.GAMEDIR.get();
logger.debug("Game folder {}", gameFolder);
Path modFolder = FMLPaths.MODSDIR.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class TransformerService implements ITransformationService {
@Override
public void onLoad(IEnvironment env, Set<String> otherServices) throws IncompatibleEnvironmentException {
logger = LogManager.getLogger("MoreCrashInfoTransformerService");
logger.info("We are now at MoreCrashInfo TransformationService");
logger.debug("We are now at MoreCrashInfo TransformationService");
}

public static Path corePath;
Expand Down
35 changes: 20 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,30 @@ Mod List:
MoreCrashInfo-1.0.2.jar MoreCrashInfo {[email protected] DONE}
forge-1.14.4-28.0.23-universal.jar Forge {[email protected] DONE}
```

From Forge 1.15.2, mods can use Mixin to operate class file, which could cause crash, but it's not shown in crash report.
## What added?
This mod is designed to take mod list and coremod list back with pretty printing.
This mod is designed to show mod list, coremod list and mixin list in crash report with pretty printing.
Feel free to open an issue if other info needed.
What added in crash report:
```
Forge Mods:
| ID | Name | Version | Source | Status |
| ---------------- | ---------------- | ----------------- | -------------------------------------------- | ------ |
| minecraft | Minecraft | 1.14.4 | Not Found | NONE |
| customskinloader | CustomSkinLoader | 14.11-SNAPSHOT-89 | CustomSkinLoader_Forge-14.11-SNAPSHOT-89.jar | DONE |
| morecrashinfo | MoreCrashInfo | 1.0.2 | MoreCrashInfo-1.0.2.jar | DONE |
| forge | Forge | 28.0.23 | forge-1.14.4-28.0.23-universal.jar | DONE |
Forge CoreMods:
| ID | Name | Source | Status |
| ---------------- | ------------------------- | ---------------------------- | ------ |
| customskinloader | transformers | transformers.js | Loaded |
| forge | fieldtomethodtransformers | fieldtomethodtransformers.js | Loaded |
| ID | Name | Version | Source | Status |
| ---------------- | ---------------- | ----------------- | ------------------------------------- | ------ |
| minecraft | Minecraft | 1.19.3 | client-1.19.3-20221207.122022-srg.jar | DONE |
| morecrashinfo | MoreCrashInfo | 2.2.0 | MoreCrashInfo-Core.jar | DONE |
| forge | Forge | 44.1.2 | forge-1.19.3-44.1.2-universal.jar | DONE |
| rubidium | Rubidium | 0.6.3 | rubidium-0.6.3.jar | DONE |
Forge CoreMods:
| ID | Name | Source | Status |
| ----- | ------------------- | ---------------------- | ------ |
| forge | field_to_method | field_to_method.js | Loaded |
| forge | field_to_instanceof | field_to_instanceof.js | Loaded |
| forge | add_bouncer_method | add_bouncer_method.js | Loaded |
Mixin Configs:
| Name | Mixin Package | Priority | Required | Targets |
| -------------------- | -------------------------------- | -------- | -------- | ------- |
| rubidium.mixins.json | me.jellysquid.mods.sodium.mixin. | 1000 | true | 41 |
```
## What's more?
We are trying to analyze some crash automaticly.
Expand All @@ -47,11 +54,9 @@ Error Info:
```

## Compatibility
- Minecraft 1.15+ with Forge
- Minecraft 1.13+ with Forge
- Java 8+

In addition, this mod can be loaded in 1.13.2-1.14.4, but not work. We are trying to find out the reason.

### Tested Environment
- Minecraft 1.16.5, Forge 36.2.39 and Java 8
- Minecraft 1.19.3, Forge 44.1.2 and Java 17
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'net.minecraftforge.gradle' version '5.1.+'
}

version = "2.1.0"
version = "2.2.0"
group = 'me.xfl03'
archivesBaseName = 'MoreCrashInfo_Core'

Expand Down
59 changes: 59 additions & 0 deletions src/main/java/me/xfl03/morecrashinfo/crash/CallableManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package me.xfl03.morecrashinfo.crash;

import me.xfl03.morecrashinfo.MoreCrashInfo;
import me.xfl03.morecrashinfo.util.ReflectionHelper;
import me.xfl03.morecrashinfo.util.VersionUtil;
import net.minecraftforge.fml.ISystemReportExtender;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class CallableManager {
private static final List<CommonCallable> callables = new ArrayList<>();

public static void initCallables() {
try {
MoreCrashInfo.logger.debug("CrashHandler.initCallables");
int majorVersion = VersionUtil.getMinecraftMajorVersion();

//From 1.16, Forge formatted mod list
if (majorVersion <= 15) {
callables.add(new ModList());
}
callables.add(new CoreModList());
//Mixin added in 1.15.2-31.2.44 and 1.16.1-32.0.72
if (majorVersion >= 16 || VersionUtil.getMinecraftVersion().equals("1.15.2")) {
callables.add(new MixinList());
}
MoreCrashInfo.logger.debug("Callable list size {}", callables.size());
MoreCrashInfo.logger.debug("Callable list member {}", callables.stream()
.map(ISystemReportExtender::getLabel).collect(Collectors.joining(", ")));
MoreCrashInfo.logger.info(getCallableMessages());

//1.13-1.14, we added these message behind stacktrace
if (majorVersion >= 15) {
//register callables to Forge
List<ISystemReportExtender> callables0 = ReflectionHelper.getCallables();
callables0.addAll(callables);
ReflectionHelper.printCallables();
// ReflectionHelper.testCallables();
}
} catch (Exception e) {
MoreCrashInfo.logger.warn("Error register callable");
MoreCrashInfo.logger.warn(e);
}
}

public static String getCallableMessages() {
StringBuilder sb = new StringBuilder("\n");
for (CommonCallable callable : callables) {
sb.append("\t");
sb.append(callable.getLabel());
sb.append(":");
sb.append(callable.get());
sb.append("\n");
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import net.minecraftforge.fml.ISystemReportExtender;

public abstract class CommonCrash implements ISystemReportExtender {
public abstract class CommonCallable implements ISystemReportExtender {
abstract String innerCall() throws Exception;

public Object call() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.ArrayList;
import java.util.List;

public class CoreModList extends CommonCrash {
public class CoreModList extends CommonCallable {
@Override
public String getLabel() {
return "Forge CoreMods";
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/me/xfl03/morecrashinfo/crash/MixinList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package me.xfl03.morecrashinfo.crash;

import me.xfl03.morecrashinfo.util.PrintHelper;
import me.xfl03.morecrashinfo.util.Reflection;
import org.spongepowered.asm.mixin.extensibility.IMixinConfig;
import org.spongepowered.asm.service.MixinService;

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

public class MixinList extends CommonCallable {
@Override
String innerCall() throws Exception {
//Avoid mixin not found
try {
Class.forName("org.spongepowered.asm.mixin.Mixins");
} catch (Exception e) {
return "Mixin class not found";
}
List<?> configs;
try {
configs = (List<?>) Reflection.clazz(MixinService.class)
.get("getService()")
.get("transformationHandler")
.get("transformer")
.get("processor")
.get("configs")
.get();
} catch (Exception e) {
return "Error getting mixin config: " + e;
}

List<List<String>> datas = new ArrayList<>();
datas.add(PrintHelper.createLine("Name", "Mixin Package", "Priority", "Required", "Targets"));
for (Object config : configs) {
if (config instanceof IMixinConfig) {
IMixinConfig cfg = (IMixinConfig) config;
datas.add(PrintHelper.createLine(
cfg.getName(),
cfg.getMixinPackage(),
Integer.toString(cfg.getPriority()),
Boolean.toString(cfg.isRequired()),
Integer.toString(cfg.getTargets().size())
));
} else {
System.err.println(config + " is not instance of IMixinConfig");
}
}

return PrintHelper.printLine("\n\t\t", datas);
// return Mixins.getConfigs().stream().map(Config::getName).collect(Collectors.joining(", "));
}

@Override
public String getLabel() {
return "Mixin Configs";
}
}
2 changes: 1 addition & 1 deletion src/main/java/me/xfl03/morecrashinfo/crash/ModList.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.ArrayList;
import java.util.List;

public class ModList extends CommonCrash {
public class ModList extends CommonCallable {
@Override
public String getLabel() {
return "Forge Mods";
Expand Down
33 changes: 12 additions & 21 deletions src/main/java/me/xfl03/morecrashinfo/handler/CrashHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,24 @@

import cpw.mods.modlauncher.log.TransformingThrowablePatternConverter;
import me.xfl03.morecrashinfo.MoreCrashInfo;
import me.xfl03.morecrashinfo.crash.CoreModList;
import me.xfl03.morecrashinfo.crash.ModList;
import me.xfl03.morecrashinfo.crash.*;
import me.xfl03.morecrashinfo.handler.exception.*;
import me.xfl03.morecrashinfo.util.ReflectionHelper;
import net.minecraftforge.fml.ISystemReportExtender;
import me.xfl03.morecrashinfo.util.VersionUtil;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class CrashHandler {
private static final Map<Class<?>, Function<Throwable, ExceptionHandler>> handlers = new HashMap<>();

static {
try {
MoreCrashInfo.logger.info("CrashHandler.static");
CrashHandler.registerHandler(VerifyError.class, VerifyErrorHandler::new);

List<ISystemReportExtender> callables = ReflectionHelper.getCallables();
callables.add(new ModList());
callables.add(new CoreModList());
MoreCrashInfo.logger.debug("Callable list size {}", callables.size());
MoreCrashInfo.logger.debug("Callable list member {}", callables.stream()
.map(ISystemReportExtender::getLabel).collect(Collectors.joining(", ")));
private static void initHandlers() {
registerHandler(VerifyError.class, VerifyErrorHandler::new);
}

ReflectionHelper.printCallables();
// ReflectionHelper.testCallables();
} catch (Exception e) {
MoreCrashInfo.logger.warn("Error register callable");
MoreCrashInfo.logger.warn(e);
}
static {
initHandlers();
CallableManager.initCallables();
}

private static ExceptionHandler handler;
Expand Down Expand Up @@ -60,6 +47,10 @@ public static String generateEnhancedStackTrace(final Throwable throwable) {
StringBuilder stringbuilder = new StringBuilder();
handler.handleException(stringbuilder);
stringbuilder.append(TransformingThrowablePatternConverter.generateEnhancedStackTrace(throwable));
//In 1.13-1.14, add callables message here
if (VersionUtil.getMinecraftMajorVersion() <= 14) {
stringbuilder.append(CallableManager.getCallableMessages());
}
return stringbuilder.toString();
}
}
65 changes: 65 additions & 0 deletions src/main/java/me/xfl03/morecrashinfo/util/Reflection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package me.xfl03.morecrashinfo.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Reflection {
private final Class<?> clazz;
private Object instance;

public Reflection(Class<?> clazz) {
this.clazz = clazz;
}

public Reflection(Object instance) {
if (instance == null) {
throw new IllegalArgumentException("Instance cannot be null");
}
this.clazz = instance.getClass();
this.instance = instance;
}

public static Reflection clazz(String className) throws ClassNotFoundException {
return new Reflection(Class.forName(className));
}

public static Reflection clazz(Class<?> clazz) {
return new Reflection(clazz);
}

public static Reflection clazz(Object instance) {
return new Reflection(instance);
}

private Reflection getField(String field) throws Exception {
Field field0 = clazz.getDeclaredField(field);
field0.setAccessible(true);
return new Reflection(field0.get(instance));
}

private Reflection invokeMethod(String method) throws Exception {
Method method1 = clazz.getDeclaredMethod(method);
method1.setAccessible(true);
return new Reflection(method1.invoke(instance));
}

/**
* Get field or invoke method
*
* @param fieldOrMethod fieldName or methodName()
* @return result
* @throws Exception
*/
public Reflection get(String fieldOrMethod) throws Exception {
// System.out.println("Getting " + fieldOrMethod);
if (fieldOrMethod.endsWith(")")) {
return invokeMethod(fieldOrMethod.replace("()", ""));
} else {
return getField(fieldOrMethod);
}
}

public Object get() {
return instance;
}
}
30 changes: 30 additions & 0 deletions src/main/java/me/xfl03/morecrashinfo/util/VersionUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package me.xfl03.morecrashinfo.util;

import me.xfl03.morecrashinfo.MoreCrashInfo;
import net.minecraftforge.fml.loading.FMLLoader;

import java.lang.reflect.Field;

public class VersionUtil {
public static String getMinecraftVersion() {
Class<FMLLoader> fmlLoaderClass = FMLLoader.class;
try {
//1.13-1.16
Field mcVersionField = fmlLoaderClass.getDeclaredField("mcVersion");
mcVersionField.setAccessible(true);
return (String) mcVersionField.get(null);
} catch (NoSuchFieldException e) {
//1.16-1.19
return FMLLoader.versionInfo().mcVersion();
} catch (IllegalAccessException e) {
MoreCrashInfo.logger.warn("Error getting mcVersion");
MoreCrashInfo.logger.warn(e);
return "1.16.5";
}
}

public static int getMinecraftMajorVersion() {
String[] s = getMinecraftVersion().split("\\.");
return Integer.parseInt(s[1]);
}
}

0 comments on commit 0b23151

Please sign in to comment.