fix: use patched Forge client jar instead of vanilla version jar
Vanilla 1.20.1.jar on -cp creates automatic module _1._20._1 which conflicts with Forge minecraft module. Use forge-*-client.jar from libraries/ instead (contains all MC classes). Falls back to vanilla.
This commit is contained in:
+52
-6
@@ -63,14 +63,16 @@ public class LaunchCommandBuilder {
|
|||||||
// always use ModLauncher as main class (version.json might have
|
// always use ModLauncher as main class (version.json might have
|
||||||
// BootstrapLauncher which breaks with Java module system)
|
// BootstrapLauncher which breaks with Java module system)
|
||||||
if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) {
|
if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) {
|
||||||
// Forge manifest's -p is a HARDCODED list of 8 bootstrap JARs
|
// Forge: vanilla version jar on -cp creates automatic module _1._20._1
|
||||||
// (bootstraplauncher, securejarhandler, asm-*, JarJarFileSystems)
|
// which conflicts with Forge's "minecraft" module → split-package error.
|
||||||
// using ${library_directory}. Version jar is NOT on -p.
|
// Fix: use patched Forge client jar instead of vanilla version jar.
|
||||||
// Put version jar on -cp only → PreparableReloadListener loadable,
|
// The patched jar (forge-1.20.1-47.4.20-client.jar) is created by the
|
||||||
// no _1._20._1 vs minecraft split-package conflict.
|
// Forge installer in libraries/ and contains all MC classes including
|
||||||
|
// PreparableReloadListener. It is NOT listed in version.json manifest,
|
||||||
|
// so we find and add it separately.
|
||||||
String classpath;
|
String classpath;
|
||||||
if (manifest != null) {
|
if (manifest != null) {
|
||||||
classpath = buildClasspathFromManifest(manifest, true);
|
classpath = buildClasspathFromManifest(manifest, false);
|
||||||
} else {
|
} else {
|
||||||
classpath = "";
|
classpath = "";
|
||||||
}
|
}
|
||||||
@@ -78,6 +80,21 @@ public class LaunchCommandBuilder {
|
|||||||
classpath = buildVanillaClasspath();
|
classpath = buildVanillaClasspath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find and add the patched Forge client jar
|
||||||
|
Path patchedJar = findPatchedForgeJar();
|
||||||
|
if (patchedJar != null) {
|
||||||
|
String sep = System.getProperty("os.name").toLowerCase().contains("win") ? ";" : ":";
|
||||||
|
classpath = patchedJar.toAbsolutePath().toString() + sep + classpath;
|
||||||
|
System.out.println(ZAnsi.green(" Added patched Forge jar: " + patchedJar.getFileName()));
|
||||||
|
} else {
|
||||||
|
System.out.println(ZAnsi.yellow(" No patched Forge client jar found, falling back to vanilla version jar"));
|
||||||
|
Path versionJar = findVersionJar();
|
||||||
|
if (versionJar != null && isValidJar(versionJar)) {
|
||||||
|
String sep = System.getProperty("os.name").toLowerCase().contains("win") ? ";" : ":";
|
||||||
|
classpath = versionJar.toAbsolutePath().toString() + sep + classpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
command.add("-cp");
|
command.add("-cp");
|
||||||
String cpFile = writeClasspathFile(classpath);
|
String cpFile = writeClasspathFile(classpath);
|
||||||
command.add(cpFile);
|
command.add(cpFile);
|
||||||
@@ -640,6 +657,35 @@ public class LaunchCommandBuilder {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the patched Forge client jar in libraries/.
|
||||||
|
* The Forge installer creates it via binarypatcher processor:
|
||||||
|
* libraries/net/minecraftforge/forge/<version>/forge-<version>-client.jar
|
||||||
|
* This jar contains all vanilla MC classes + Forge patches.
|
||||||
|
* Using it instead of vanilla 1.20.1.jar avoids the _1._20._1 vs minecraft
|
||||||
|
* split-package conflict, because the filename produces a different automatic
|
||||||
|
* module name.
|
||||||
|
*/
|
||||||
|
private Path findPatchedForgeJar() {
|
||||||
|
Path librariesDir = instance.getPath().resolve("libraries");
|
||||||
|
String mcVersion = instance.getMinecraftVersion();
|
||||||
|
String loaderVer = instance.getLoaderVersion();
|
||||||
|
|
||||||
|
String[] candidates = {
|
||||||
|
"net/minecraftforge/forge/" + mcVersion + "-" + loaderVer + "/forge-" + mcVersion + "-" + loaderVer + "-client.jar",
|
||||||
|
"net/neoforged/neoforge/" + mcVersion + "-" + loaderVer + "/neoforge-" + mcVersion + "-" + loaderVer + "-client.jar"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String candidate : candidates) {
|
||||||
|
Path jarPath = librariesDir.resolve(candidate);
|
||||||
|
if (Files.exists(jarPath) && isValidJar(jarPath)) {
|
||||||
|
return jarPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private String mavenToPath(String mavenName) {
|
private String mavenToPath(String mavenName) {
|
||||||
String[] parts = mavenName.split(":");
|
String[] parts = mavenName.split(":");
|
||||||
if (parts.length < 3) return mavenName;
|
if (parts.length < 3) return mavenName;
|
||||||
|
|||||||
Reference in New Issue
Block a user