Move generic logic from ResourcePackHookPatch to PatchUtil
This commit is contained in:
parent
ded7c20fdb
commit
9cad07b82d
|
@ -1,15 +1,15 @@
|
|||
package io.gitlab.jfronny.libjf.data.manipulation.impl;
|
||||
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.PatchUtil;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.modification.MethodModificationPatch;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.targeting.InterfaceImplTargetPatch;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
public class ResourcePackHookPatch implements AsmConfig {
|
||||
|
@ -17,7 +17,7 @@ public class ResourcePackHookPatch implements AsmConfig {
|
|||
private static final String HOOK_IMPLEMENTATION = Type.getInternalName(ResourcePackHook.class);
|
||||
@Override
|
||||
public Set<String> skipClasses() {
|
||||
return Set.of(getClass(TARGET_CLASS_INTERMEDIARY));
|
||||
return Set.of(PatchUtil.getRemapped(TARGET_CLASS_INTERMEDIARY));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,50 +46,10 @@ public class ResourcePackHookPatch implements AsmConfig {
|
|||
}
|
||||
|
||||
private void hookReturn(MethodNode method, String targetMethod, String targetType, String[] extraParamTypes) {
|
||||
for (AbstractInsnNode node : method.instructions) {
|
||||
if (node.getOpcode() == Opcodes.IRETURN || node.getOpcode() == Opcodes.ARETURN) {
|
||||
method.instructions.insertBefore(node, buildInvoker(targetMethod, targetType, targetType, extraParamTypes));
|
||||
}
|
||||
}
|
||||
PatchUtil.redirectReturn(method, TARGET_CLASS_INTERMEDIARY, HOOK_IMPLEMENTATION, targetMethod, targetType, extraParamTypes);
|
||||
}
|
||||
|
||||
private void catchEx(MethodNode method, String targetMethod, String[] extraParamTypes) {
|
||||
LabelNode start = new LabelNode();
|
||||
LabelNode end = new LabelNode();
|
||||
LabelNode handler = new LabelNode();
|
||||
method.instructions.insertBefore(method.instructions.getFirst(), start);
|
||||
method.instructions.insertBefore(method.instructions.getLast(), end);
|
||||
method.instructions.add(handler);
|
||||
method.instructions.add(buildInvoker(targetMethod, "Ljava/io/IOException;", "Ljava/io/InputStream;", extraParamTypes));
|
||||
method.instructions.add(new InsnNode(Opcodes.ARETURN));
|
||||
method.tryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, Type.getInternalName(IOException.class)));
|
||||
}
|
||||
|
||||
private InsnList buildInvoker(String targetMethod, String inType, String outType, String[] extraParamTypes) {
|
||||
InsnList instructions = new InsnList();
|
||||
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
|
||||
StringBuilder descriptor = new StringBuilder("(").append(inType);
|
||||
descriptor.append('L').append(getClassInternal("net/minecraft/class_3262")).append(';');
|
||||
for (int i = 0; i < extraParamTypes.length; i++) {
|
||||
if (extraParamTypes[i].equals("I"))
|
||||
instructions.add(new VarInsnNode(Opcodes.ILOAD, i + 1));
|
||||
else
|
||||
instructions.add(new VarInsnNode(Opcodes.ALOAD, i + 1));
|
||||
if (extraParamTypes[i].length() == 1)
|
||||
descriptor.append(extraParamTypes[i]);
|
||||
else
|
||||
descriptor.append('L').append(getClassInternal(extraParamTypes[i])).append(';');
|
||||
}
|
||||
descriptor.append(")").append(outType);
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, HOOK_IMPLEMENTATION, targetMethod, descriptor.toString()));
|
||||
return instructions;
|
||||
}
|
||||
|
||||
private String getClassInternal(String name) {
|
||||
return getClass(name.replace('/', '.')).replace('.', '/');
|
||||
}
|
||||
|
||||
private String getClass(String name) {
|
||||
return AsmTransformer.MAPPING_RESOLVER.mapClassName(AsmTransformer.INTERMEDIARY, name);
|
||||
PatchUtil.redirectExceptions(method, TARGET_CLASS_INTERMEDIARY, HOOK_IMPLEMENTATION, Type.getInternalName(IOException.class), Type.getInternalName(InputStream.class), targetMethod, extraParamTypes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class AsmTransformer extends FabricMixinTransformerProxy {
|
|||
return classBytes;
|
||||
}
|
||||
|
||||
public boolean isClassUnmoddable(String className, AsmConfig config) {
|
||||
public static boolean isClassUnmoddable(String className, AsmConfig config) {
|
||||
if (className.replace('/', '.').startsWith("org.objectweb.asm")
|
||||
//|| className.startsWith("net.fabricmc.loader")
|
||||
//|| className.startsWith("io.gitlab.jfronny.libjf.unsafe.asm")
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm.patch;
|
||||
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
public class PatchUtil {
|
||||
public static String getRemappedInternal(String className) {
|
||||
return getRemapped(className.replace('/', '.')).replace('.', '/');
|
||||
}
|
||||
|
||||
public static String getRemapped(String className) {
|
||||
return AsmTransformer.MAPPING_RESOLVER.mapClassName(AsmTransformer.INTERMEDIARY, className);
|
||||
}
|
||||
|
||||
public static void redirectReturn(MethodNode method, String targetClass, String hookClass, String targetMethod, String targetType, String[] extraParamTypes) {
|
||||
for (AbstractInsnNode node : method.instructions) {
|
||||
if (node.getOpcode() == Opcodes.ARETURN
|
||||
|| node.getOpcode() == Opcodes.IRETURN
|
||||
|| node.getOpcode() == Opcodes.DRETURN
|
||||
|| node.getOpcode() == Opcodes.FRETURN
|
||||
|| node.getOpcode() == Opcodes.LRETURN) {
|
||||
method.instructions.insertBefore(node, PatchUtil.buildParamPassingInvoker(targetClass, hookClass, targetMethod, targetType, targetType, extraParamTypes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void redirectExceptions(MethodNode method, String targetClass, String hookClass, String exceptionType, String returnTypeNormal, String targetMethod, String[] extraParamTypes) {
|
||||
LabelNode start = new LabelNode();
|
||||
LabelNode end = new LabelNode();
|
||||
LabelNode handler = new LabelNode();
|
||||
method.instructions.insertBefore(method.instructions.getFirst(), start);
|
||||
method.instructions.insertBefore(method.instructions.getLast(), end);
|
||||
method.instructions.add(handler);
|
||||
method.instructions.add(PatchUtil.buildParamPassingInvoker(targetClass,
|
||||
hookClass,
|
||||
targetMethod,
|
||||
"L" + getRemappedInternal(exceptionType) + ";",
|
||||
"L" + getRemappedInternal(returnTypeNormal) + ";",
|
||||
extraParamTypes));
|
||||
method.instructions.add(new InsnNode(Opcodes.ARETURN));
|
||||
method.tryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, exceptionType));
|
||||
}
|
||||
|
||||
public static InsnList buildParamPassingInvoker(String targetClass, String hookClass, String targetMethod, String inType, String outType, String[] extraParamTypes) {
|
||||
InsnList instructions = new InsnList();
|
||||
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
|
||||
StringBuilder descriptor = new StringBuilder("(").append(inType);
|
||||
descriptor.append('L').append(getRemappedInternal(targetClass)).append(';');
|
||||
for (int i = 0; i < extraParamTypes.length; i++) {
|
||||
instructions.add(new VarInsnNode(switch (extraParamTypes[i]) {
|
||||
case "I" -> Opcodes.ILOAD;
|
||||
case "D" -> Opcodes.DLOAD;
|
||||
case "F" -> Opcodes.FLOAD;
|
||||
case "L" -> Opcodes.LLOAD;
|
||||
default -> Opcodes.ALOAD;
|
||||
}, i + 1));
|
||||
if (extraParamTypes[i].length() == 1)
|
||||
descriptor.append(extraParamTypes[i]);
|
||||
else
|
||||
descriptor.append('L').append(PatchUtil.getRemappedInternal(extraParamTypes[i])).append(';');
|
||||
}
|
||||
descriptor.append(")").append(outType);
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, hookClass, targetMethod, descriptor.toString()));
|
||||
return instructions;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue