Patch ModDirTransformerDiscoverer to not crash with UnionFS paths

This commit is contained in:
Juuz
2024-07-03 16:30:34 +03:00
parent 1033f250f2
commit 10441e3985
3 changed files with 50 additions and 1 deletions

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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);
}