LibJF/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/impl/ResourcePackHookPatch.java

67 lines
3.7 KiB
Java

package io.gitlab.jfronny.libjf.data.manipulation.impl;
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig;
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 java.io.IOException;
import java.util.Set;
public class ResourcePackHookPatch implements AsmConfig {
private static final String TARGET_CLASS_INTERMEDIARY = "net.minecraft.class_3262";
private static final String HOOK_IMPLEMENTATION = Type.getInternalName(ResourcePackHook.class);
@Override
public Set<String> skipClasses() {
return Set.of(PatchUtil.mapClassName(TARGET_CLASS_INTERMEDIARY));
}
@Override
public Set<Patch> getPatches() {
// https://maven.fabricmc.net/docs/yarn-21w38a+build.9/net/minecraft/resource/ResourcePack.html
return Set.of(new InterfaceImplTargetPatch(TARGET_CLASS_INTERMEDIARY, new MethodModificationPatch(TARGET_CLASS_INTERMEDIARY, Set.of(
// open root
new MethodModificationPatch.MethodDescriptorPatch("method_14410", "([Ljava/lang/String;)Lnet/minecraft/class_7367;", (method, klazz) -> {
hookReturn(method, "hookOpenRoot", "Lnet/minecraft/class_7367;", "[java/lang/String");
}),
// open
new MethodModificationPatch.MethodDescriptorPatch("method_14405", "(Lnet/minecraft/class_3264;Lnet/minecraft/class_2960;)Lnet/minecraft/class_7367;", (method, klazz) -> {
hookReturn(method, "hookOpen", "Lnet/minecraft/class_7367;", "net/minecraft/class_3264", "net/minecraft/class_2960");
}),
// find resource
new MethodModificationPatch.MethodDescriptorPatch("method_14408", "(Lnet/minecraft/class_3264;Ljava/lang/String;Ljava/lang/String;Lnet/minecraft/class_3262$class_7664;)V", (method, klazz) -> {
InsnList head = PatchUtil.buildParamPassingInvoker(
TARGET_CLASS_INTERMEDIARY,
HOOK_IMPLEMENTATION,
"hookFindResources",
null,
"Lnet/minecraft/class_3262$class_7664;",
"net/minecraft/class_3264", "java/lang/String", "java/lang/String", "net/minecraft/class_3262$class_7664");
head.add(new VarInsnNode(Opcodes.ASTORE, 4));
method.instructions.insert(head);
}),
// parse metadata
new MethodModificationPatch.MethodDescriptorPatch("method_14407", "(Lnet/minecraft/class_3270;)Ljava/lang/Object;", (method, klazz) -> {
hookReturn(method, "hookParseMetadata", "Ljava/lang/Object;", "net/minecraft/class_3270");
PatchUtil.redirectExceptions(
method,
TARGET_CLASS_INTERMEDIARY,
HOOK_IMPLEMENTATION,
Type.getInternalName(IOException.class),
Type.getInternalName(Object.class),
"hookParseMetadataEx",
"net/minecraft/class_3270");
})
))));
}
private void hookReturn(MethodNode method, String targetMethod, String targetType, String... extraParamTypes) {
PatchUtil.redirectReturn(method, TARGET_CLASS_INTERMEDIARY, HOOK_IMPLEMENTATION, targetMethod, targetType, extraParamTypes);
}
}