Fix launching 1.20.6 NeoForge with Yarn (#213)

Fixes #212.
This commit is contained in:
Juuz
2024-05-11 16:00:14 +03:00
committed by GitHub
parent 52b59feecb
commit 8da7cc0f87
3 changed files with 84 additions and 3 deletions

View File

@@ -0,0 +1,40 @@
package dev.architectury.loom.neoforge;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/*
* Patches the Minecraft.class check in FML's CommonUserdevLaunchHandler
* to refer to a class that is found in any mapping set (Main.class).
*
* See https://github.com/architectury/architectury-loom/issues/212
*/
public final class LaunchHandlerPatcher extends ClassVisitor {
private static final String INPUT_CLASS_FILE = "net/minecraft/client/Minecraft.class";
private static final String OUTPUT_CLASS_FILE = "net/minecraft/client/main/Main.class";
public LaunchHandlerPatcher(ClassVisitor next) {
super(Opcodes.ASM9, next);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return new MethodPatcher(super.visitMethod(access, name, descriptor, signature, exceptions));
}
private static final class MethodPatcher extends MethodVisitor {
MethodPatcher(MethodVisitor next) {
super(Opcodes.ASM9, next);
}
@Override
public void visitLdcInsn(Object value) {
if (INPUT_CLASS_FILE.equals(value)) {
value = OUTPUT_CLASS_FILE;
}
super.visitLdcInsn(value);
}
}
}

View File

@@ -0,0 +1,31 @@
package dev.architectury.loom.util;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.function.UnaryOperator;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import net.fabricmc.loom.util.ExceptionUtil;
public final class ClassVisitorUtil {
public static void rewriteClassFile(Path path, UnaryOperator<ClassVisitor> visitorFactory) throws IOException {
try {
final byte[] inputBytes = Files.readAllBytes(path);
final var reader = new ClassReader(inputBytes);
final var writer = new ClassWriter(0);
reader.accept(visitorFactory.apply(writer), 0);
final byte[] outputBytes = writer.toByteArray();
if (!Arrays.equals(inputBytes, outputBytes)) {
Files.write(path, outputBytes);
}
} catch (IOException e) {
throw ExceptionUtil.createDescriptiveWrapper(IOException::new, "Failed to patch " + path, e);
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2022-2023 FabricMC
* Copyright (c) 2022-2024 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,8 @@ import java.util.ArrayList;
import java.util.List;
import com.google.common.hash.Hashing;
import dev.architectury.loom.neoforge.LaunchHandlerPatcher;
import dev.architectury.loom.util.ClassVisitorUtil;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.ModuleDependency;
@@ -60,6 +62,10 @@ public class ForgeLibrariesProvider {
private static final String FANCYML_LOADER_GROUP = "net.neoforged.fancymodloader";
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 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";
public static void provide(MappingConfiguration mappingConfiguration, Project project) throws Exception {
LoomGradleExtension extension = LoomGradleExtension.get(project);
final List<Dependency> dependencies = new ArrayList<>();
@@ -166,13 +172,17 @@ public class ForgeLibrariesProvider {
Path path = fs.get().getPath("META-INF/services/cpw.mods.modlauncher.api.INameMappingService");
Files.deleteIfExists(path);
if (Files.exists(fs.get().getPath("net/minecraftforge/fml/common/asm/ObjectHolderDefinalize.class"))) {
if (Files.exists(fs.get().getPath(FORGE_OBJECT_HOLDER_FILE))) {
remapObjectHolder(project, outputJar, mappingConfiguration);
}
if (Files.exists(fs.getPath("net/neoforged/fml/common/asm/ObjectHolderDefinalize.class"))) {
if (Files.exists(fs.getPath(NEOFORGE_OBJECT_HOLDER_FILE))) {
remapNeoForgeObjectHolder(project, outputJar, mappingConfiguration);
}
if (Files.exists(fs.getPath(NEOFORGE_LAUNCH_HANDLER_FILE))) {
ClassVisitorUtil.rewriteClassFile(fs.getPath(NEOFORGE_LAUNCH_HANDLER_FILE), LaunchHandlerPatcher::new);
}
}
// Copy sources when not running under CI.