Fix transformers causing NCDF on specific servers (#374)

This commit is contained in:
Yang Xizhi
2024-01-16 09:36:22 +08:00
committed by GitHub
parent a8f0bbe06b
commit 10f47a560a
@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.fml.common.Loader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
@@ -31,7 +32,11 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import java.io.IOException;
import java.io.InputStream;
@@ -48,7 +53,7 @@ public class AE2ELTransformer implements IClassTransformer {
if ("net.minecraftforge.common.ForgeHooks".equals(transformedName)) {
ClassReader cr = new ClassReader(basicClass);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassWriter cw = new SafeClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassVisitor cv = new PickBlockPatch(cw);
cr.accept(cv, ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
@@ -188,4 +193,39 @@ public class AE2ELTransformer implements IClassTransformer {
}
private static class SafeClassWriter extends ClassWriter {
public SafeClassWriter(int flags) {
super(flags);
}
@Override
protected String getCommonSuperClass(final String type1, final String type2) {
Class<?> c, d;
// clueless
ClassLoader classLoader = Launch.classLoader;
try {
c = Class.forName(type1.replace('/', '.'), false, classLoader);
d = Class.forName(type2.replace('/', '.'), false, classLoader);
} catch (Exception e) {
throw new RuntimeException(e.toString());
}
if (c.isAssignableFrom(d)) {
return type1;
}
if (d.isAssignableFrom(c)) {
return type2;
}
if (c.isInterface() || d.isInterface()) {
return "java/lang/Object";
} else {
do {
c = c.getSuperclass();
} while (!c.isAssignableFrom(d));
return c.getName().replace('.', '/');
}
}
}
}