From 74232d86b42086bb544ebd6f160ac26b9ba4e906 Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:30:34 +0300 Subject: [PATCH] Patch ModDirTransformerDiscoverer to not crash with UnionFS paths --- .../ModDirTransformerDiscovererPatch.java | 43 +++++++++++++++++++ .../loom/util/ClassVisitorUtil.java | 2 +- .../forge/ForgeLibrariesProvider.java | 6 +++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/main/java/dev/architectury/loom/forge/ModDirTransformerDiscovererPatch.java diff --git a/src/main/java/dev/architectury/loom/forge/ModDirTransformerDiscovererPatch.java b/src/main/java/dev/architectury/loom/forge/ModDirTransformerDiscovererPatch.java new file mode 100644 index 00000000..0bd59456 --- /dev/null +++ b/src/main/java/dev/architectury/loom/forge/ModDirTransformerDiscovererPatch.java @@ -0,0 +1,43 @@ +package dev.architectury.loom.forge; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Patches {@code ModDirTransformerDiscovererPatch} in Forge 49.0.50+ so that it doesn't try to create modules + * directly out of UnionFS root paths created by Union Relauncher. SecureModules can't infer the module names + * from those paths, so the game crashes without this patch. + */ +public final class ModDirTransformerDiscovererPatch extends ClassVisitor { + public ModDirTransformerDiscovererPatch(ClassVisitor classVisitor) { + super(Opcodes.ASM9, classVisitor); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + MethodVisitor next = super.visitMethod(access, name, descriptor, signature, exceptions); + + if (name.equals("isServiceProvider") && descriptor.equals("(Ljava/nio/file/Path;)Z")) { + return new MethodVisitor(Opcodes.ASM9, next) { + @Override + public void visitCode() { + super.visitCode(); + + // Don't even try to examine the path if it's not a default fs path, just return false. + var after = new Label(); + visitVarInsn(Opcodes.ALOAD, 0); + visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/nio/file/Path", "getFileSystem", "()Ljava/nio/file/FileSystem;", true); + visitMethodInsn(Opcodes.INVOKESTATIC, "java/nio/file/FileSystems", "getDefault", "()Ljava/nio/file/FileSystem;", false); + visitJumpInsn(Opcodes.IF_ACMPEQ, after); + visitInsn(Opcodes.ICONST_0); + visitInsn(Opcodes.IRETURN); + visitLabel(after); + } + }; + } + + return next; + } +} diff --git a/src/main/java/dev/architectury/loom/util/ClassVisitorUtil.java b/src/main/java/dev/architectury/loom/util/ClassVisitorUtil.java index f0e0003a..a6bec6c0 100644 --- a/src/main/java/dev/architectury/loom/util/ClassVisitorUtil.java +++ b/src/main/java/dev/architectury/loom/util/ClassVisitorUtil.java @@ -17,7 +17,7 @@ public final class ClassVisitorUtil { try { final byte[] inputBytes = Files.readAllBytes(path); final var reader = new ClassReader(inputBytes); - final var writer = new ClassWriter(0); + final var writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES); reader.accept(visitorFactory.apply(writer), 0); final byte[] outputBytes = writer.toByteArray(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeLibrariesProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeLibrariesProvider.java index 31be3cfa..7243f27d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeLibrariesProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeLibrariesProvider.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import com.google.common.hash.Hashing; +import dev.architectury.loom.forge.ModDirTransformerDiscovererPatch; import dev.architectury.loom.neoforge.LaunchHandlerPatcher; import dev.architectury.loom.util.ClassVisitorUtil; import org.gradle.api.Project; @@ -63,6 +64,7 @@ public class ForgeLibrariesProvider { private static final String FANCYML_LOADER_NAME = "loader"; private static final String FORGE_OBJECT_HOLDER_FILE = "net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.class"; + private static final String FORGE_MOD_DIR_TRANSFORMER_DISCOVERER_FILE = "net/minecraftforge/fml/loading/ModDirTransformerDiscoverer.class"; private static final String NEOFORGE_OBJECT_HOLDER_FILE = "net/neoforged/fml/common/asm/ObjectHolderDefinalize.class"; private static final String NEOFORGE_LAUNCH_HANDLER_FILE = "net/neoforged/fml/loading/targets/CommonUserdevLaunchHandler.class"; @@ -176,6 +178,10 @@ public class ForgeLibrariesProvider { remapObjectHolder(project, outputJar, mappingConfiguration); } + if (Files.exists(fs.getPath(FORGE_MOD_DIR_TRANSFORMER_DISCOVERER_FILE))) { + ClassVisitorUtil.rewriteClassFile(fs.getPath(FORGE_MOD_DIR_TRANSFORMER_DISCOVERER_FILE), ModDirTransformerDiscovererPatch::new); + } + if (Files.exists(fs.getPath(NEOFORGE_OBJECT_HOLDER_FILE))) { remapNeoForgeObjectHolder(project, outputJar, mappingConfiguration); }