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 skipClasses() { return Set.of(PatchUtil.mapClassName(TARGET_CLASS_INTERMEDIARY)); } @Override public Set 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); } }