Added ASM patch to hide achievement parsing errors
This includes hiding the log spam when loading worlds with changed recipes
This commit is contained in:
parent
aff2aab1ea
commit
5745133db7
1 changed files with 157 additions and 0 deletions
|
@ -61,6 +61,14 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
|
|||
nodeMap.put("read.desc", "(Lnet/minecraft/network/PacketBuffer;IZ)V");
|
||||
nodeMap.put("generateHeightMap.name", "func_76590_a");
|
||||
nodeMap.put("generateHeightMap.desc", "()V");
|
||||
|
||||
nodeMap.put("AdvancementManager.class", "nq");
|
||||
nodeMap.put("loadBuiltInAdvancements.name", "func_192777_a");
|
||||
nodeMap.put("loadBuiltInAdvancements.desc", "(Ljava/util/Map;)V");
|
||||
|
||||
nodeMap.put("ForgeHooks.class", "ForgeHooks");
|
||||
nodeMap.put("loadAdvancements.name", "lambda$loadAdvancements$0");
|
||||
nodeMap.put("loadAdvancements.desc", "(Lnet/minecraftforge/fml/common/ModContainer;Ljava/util/Map;Ljava/nio/file/Path;Ljava/nio/file/Path;)Ljava/lang/Boolean;");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,6 +111,14 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
|
|||
bytesNew = transformMinecraftChunk(bytesOld);
|
||||
break;
|
||||
|
||||
case "net.minecraft.advancements.AdvancementManager":
|
||||
bytesNew = transformMinecraftAdvancementManager(bytesOld);
|
||||
break;
|
||||
|
||||
case "net.minecraftforge.common.ForgeHooks":
|
||||
bytesNew = transformMinecraftForgeHooks(bytesOld);
|
||||
break;
|
||||
|
||||
default:
|
||||
bytesNew = null;
|
||||
}
|
||||
|
@ -574,6 +590,147 @@ public class ClassTransformer implements net.minecraft.launchwrapper.IClassTrans
|
|||
return bytesNew;
|
||||
}
|
||||
|
||||
private byte[] transformMinecraftAdvancementManager(@Nonnull final byte[] bytes) {
|
||||
final ClassNode classNode = new ClassNode();
|
||||
final ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
final int countExpected = 1;
|
||||
int countTransformed = 0;
|
||||
for (final MethodNode methodNode : classNode.methods) {
|
||||
// if (debugLog) { FMLLoadingPlugin.logger.info(String.format("- Method %s %s", methodNode.name, methodNode.desc)); }
|
||||
|
||||
if ( (methodNode.name.equals(nodeMap.get("loadBuiltInAdvancements.name")) || methodNode.name.equals("loadBuiltInAdvancements"))
|
||||
&& methodNode.desc.equals(nodeMap.get("loadBuiltInAdvancements.desc")) ) {
|
||||
FMLLoadingPlugin.logger.debug(String.format("Found method to transform: %s %s",
|
||||
methodNode.name, methodNode.desc));
|
||||
|
||||
int indexInstruction = 0;
|
||||
|
||||
while (indexInstruction < methodNode.instructions.size()) {
|
||||
final AbstractInsnNode abstractNode = methodNode.instructions.get(indexInstruction);
|
||||
if (debugLog) { decompile(abstractNode); }
|
||||
|
||||
if (abstractNode instanceof LdcInsnNode) {
|
||||
final LdcInsnNode nodeAt = (LdcInsnNode) abstractNode;
|
||||
|
||||
if ( nodeAt.cst instanceof String
|
||||
&& ((String) nodeAt.cst).contains("Parsing error loading built-in advancement ") ) {
|
||||
final AbstractInsnNode abstractNodeToRemove = methodNode.instructions.get(indexInstruction - 4);
|
||||
if ( (abstractNodeToRemove instanceof FieldInsnNode)
|
||||
&& ((FieldInsnNode) abstractNodeToRemove).desc.equals("Lorg/apache/logging/log4j/Logger;") ) {
|
||||
indexInstruction -= 4;
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
indexInstruction--;
|
||||
|
||||
if (debugLog) { FMLLoadingPlugin.logger.info(String.format("Injecting into %s.%s %s", classNode.name, methodNode.name, methodNode.desc)); }
|
||||
countTransformed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
indexInstruction++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (countTransformed != countExpected) {
|
||||
FMLLoadingPlugin.logger.error(String.format("Transformation failed for %s (%d/%d), aborting...", classNode.name, countTransformed, countExpected));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); // | ClassWriter.COMPUTE_FRAMES);
|
||||
classNode.accept(writer);
|
||||
final byte[] bytesNew = writer.toByteArray();
|
||||
FMLLoadingPlugin.logger.info(String.format("Successful injection in %s", classNode.name));
|
||||
return bytesNew;
|
||||
}
|
||||
|
||||
private byte[] transformMinecraftForgeHooks(@Nonnull final byte[] bytes) {
|
||||
final ClassNode classNode = new ClassNode();
|
||||
final ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
final int countExpected = 1;
|
||||
int countTransformed = 0;
|
||||
for (final MethodNode methodNode : classNode.methods) {
|
||||
// if (debugLog) { FMLLoadingPlugin.logger.info(String.format("- Method %s %s", methodNode.name, methodNode.desc)); }
|
||||
|
||||
if ( (methodNode.name.equals(nodeMap.get("loadAdvancements.name")) || methodNode.name.equals("loadAdvancements"))
|
||||
&& methodNode.desc.equals(nodeMap.get("loadAdvancements.desc")) ) {
|
||||
FMLLoadingPlugin.logger.debug(String.format("Found method to transform: %s %s",
|
||||
methodNode.name, methodNode.desc));
|
||||
|
||||
int indexInstruction = 0;
|
||||
|
||||
while (indexInstruction < methodNode.instructions.size()) {
|
||||
final AbstractInsnNode abstractNode = methodNode.instructions.get(indexInstruction);
|
||||
if (debugLog) { decompile(abstractNode); }
|
||||
|
||||
if (abstractNode instanceof LdcInsnNode) {
|
||||
final LdcInsnNode nodeAt = (LdcInsnNode) abstractNode;
|
||||
|
||||
if ( nodeAt.cst instanceof String
|
||||
&& ((String) nodeAt.cst).contains("Parsing error loading built-in advancement ") ) {
|
||||
final AbstractInsnNode abstractNodeToRemove = methodNode.instructions.get(indexInstruction - 4);
|
||||
if ( (abstractNodeToRemove instanceof FieldInsnNode)
|
||||
&& ((FieldInsnNode) abstractNodeToRemove).desc.equals("Lorg/apache/logging/log4j/Logger;") ) {
|
||||
indexInstruction -= 4;
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
removeInstruction(methodNode, indexInstruction);
|
||||
indexInstruction--;
|
||||
|
||||
if (debugLog) { FMLLoadingPlugin.logger.info(String.format("Injecting into %s.%s %s", classNode.name, methodNode.name, methodNode.desc)); }
|
||||
countTransformed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
indexInstruction++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (countTransformed != countExpected) {
|
||||
FMLLoadingPlugin.logger.error(String.format("Transformation failed for %s (%d/%d), aborting...", classNode.name, countTransformed, countExpected));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); // | ClassWriter.COMPUTE_FRAMES);
|
||||
classNode.accept(writer);
|
||||
final byte[] bytesNew = writer.toByteArray();
|
||||
FMLLoadingPlugin.logger.info(String.format("Successful injection in %s", classNode.name));
|
||||
return bytesNew;
|
||||
}
|
||||
|
||||
private void removeInstruction(@Nonnull final MethodNode methodNode, final int indexInstruction) {
|
||||
final AbstractInsnNode abstractNodeToRemove = methodNode.instructions.get(indexInstruction);
|
||||
if (debugLog) {
|
||||
FMLLoadingPlugin.logger.info("Removing instruction:");
|
||||
decompile(abstractNodeToRemove);
|
||||
}
|
||||
methodNode.instructions.remove(abstractNodeToRemove);
|
||||
}
|
||||
|
||||
private void saveClassToFile(final String path, final String nameClass, final byte[] bytes) {
|
||||
try {
|
||||
// create folder
|
||||
|
|
Loading…
Reference in a new issue