Actually return transformed byte source

This commit is contained in:
IzzelAliz 2021-02-20 17:17:00 +08:00
parent 2a01f3230a
commit 5dd94c727d
2 changed files with 33 additions and 14 deletions

View File

@ -162,7 +162,7 @@ public class ArclightRedirectAdapter implements PluginTransformer {
for (AbstractInsnNode insnNode : methodNode.instructions) {
if (insnNode instanceof MethodInsnNode) {
MethodInsnNode from = (MethodInsnNode) insnNode;
process(from, methodNode.instructions, remapper);
process(from, methodNode.instructions, remapper, classNode);
} else if (insnNode.getOpcode() == Opcodes.INVOKEDYNAMIC) {
InvokeDynamicInsnNode invokeDynamic = (InvokeDynamicInsnNode) insnNode;
Object[] bsmArgs = invokeDynamic.bsmArgs;
@ -193,7 +193,7 @@ public class ArclightRedirectAdapter implements PluginTransformer {
return handle;
}
private static void process(MethodInsnNode node, InsnList insnList, ClassLoaderRemapper remapper) {
private static void process(MethodInsnNode node, InsnList insnList, ClassLoaderRemapper remapper, ClassNode classNode) {
String key = node.name + node.desc;
Collection<Product2<String, MethodInsnNode>> modifyArgsCol = METHOD_MODIFY.get(key);
for (Product2<String, MethodInsnNode> modifyArgs : modifyArgsCol) {
@ -205,7 +205,7 @@ public class ArclightRedirectAdapter implements PluginTransformer {
} else {
handlerNode = modifyArgs._2;
}
processModify(node, insnList, handlerNode);
processModify(node, insnList, handlerNode, classNode);
return;
}
}
@ -233,13 +233,19 @@ public class ArclightRedirectAdapter implements PluginTransformer {
insnList.set(node, handlerNode);
}
private static void processModify(MethodInsnNode node, InsnList insnList, MethodInsnNode handlerNode) {
private static void processModify(MethodInsnNode node, InsnList insnList, MethodInsnNode handlerNode, ClassNode classNode) {
InsnList list = new InsnList();
list.add(handlerNode);
Type methodType = Type.getMethodType(node.desc);
Type[] types = methodType.getArgumentTypes();
if (node.getOpcode() != Opcodes.INVOKESTATIC) {
types = ArrayUtil.prepend(types, Type.getObjectType(node.owner), Type[]::new);
Type selfType;
if (node.getOpcode() == Opcodes.INVOKESPECIAL) {
selfType = Type.getObjectType(classNode.name);
} else {
selfType = Type.getObjectType(node.owner);
}
types = ArrayUtil.prepend(types, selfType, Type[]::new);
}
if (types.length == 1) {
if (node.desc.startsWith("()")) {

View File

@ -1,19 +1,20 @@
package io.izzel.arclight.common.mod.util.remapper.resource;
import com.google.common.io.ByteStreams;
import cpw.mods.modlauncher.ClassTransformer;
import cpw.mods.modlauncher.TransformingClassLoader;
import io.izzel.arclight.api.Unsafe;
import io.izzel.arclight.common.mod.util.remapper.ArclightRemapper;
import io.izzel.arclight.common.mod.util.remapper.GlobalClassRepo;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.service.MixinService;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
@ -28,6 +29,21 @@ public class RemapSourceHandler extends URLStreamHandler {
private static class RemapSourceConnection extends URLConnection {
private static final MethodHandle MH_TRANSFORM;
static {
try {
ClassLoader classLoader = RemapSourceConnection.class.getClassLoader();
Field classTransformer = TransformingClassLoader.class.getDeclaredField("classTransformer");
classTransformer.setAccessible(true);
ClassTransformer tranformer = (ClassTransformer) classTransformer.get(classLoader);
Method transform = tranformer.getClass().getDeclaredMethod("transform", byte[].class, String.class, String.class);
MH_TRANSFORM = Unsafe.lookup().unreflect(transform).bindTo(tranformer);
} catch (Throwable t) {
throw new IllegalStateException("Unknown modlauncher version", t);
}
}
private byte[] array;
protected RemapSourceConnection(URL url) {
@ -38,13 +54,10 @@ public class RemapSourceHandler extends URLStreamHandler {
public void connect() throws IOException {
byte[] bytes = ByteStreams.toByteArray(url.openStream());
String className = new ClassReader(bytes).getClassName();
if (className.startsWith("net/minecraft/")) {
if (className.startsWith("net/minecraft/") || className.equals("com/mojang/brigadier/tree/CommandNode")) {
try {
ClassNode classNode = MixinService.getService().getBytecodeProvider().getClassNode(className);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(cw);
bytes = cw.toByteArray();
} catch (ClassNotFoundException e) {
bytes = (byte[]) MH_TRANSFORM.invokeExact(bytes, className.replace('/', '.'), "source");
} catch (Throwable e) {
throw new IOException(e);
}
}