diff --git a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java index c58add8..974eea6 100644 --- a/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java +++ b/launcher/launcher/src/main/java/sashegdev/zernmc/launcher/minecraft/launch/LaunchCommandBuilder.java @@ -63,18 +63,12 @@ public class LaunchCommandBuilder { // always use ModLauncher as main class (version.json might have // BootstrapLauncher which breaks with Java module system) if ("forge".equals(loaderType) || "neoforge".equals(loaderType)) { - // Ensure securejarhandler can create the "minecraft" module. - // The Forge installer only creates versions//.json, - // NOT the jar. We copy the vanilla version jar there so - // securejarhandler finds it and creates the "minecraft" module. - ensureVersionJarForForge(); - - // Build classpath from manifest libraries + the copied version jar. - // The copied jar (e.g. 1.20.1-forge-47.4.20.jar) does NOT match the - // "-DignoreList" pattern "forge-" (it starts with "1", not "forge-"), - // so securejarhandler will include it in the module layer. - // It also won't create automatic module "_1._20._1" because the - // filename is "1.20.1-forge-47.4.20.jar", not "1.20.1.jar". + // Build classpath from manifest libraries only. + // The forge client jar (forge-*-client.jar) on the classpath + // contains the patched Minecraft classes and has + // Automatic-Module-Name: minecraft in its MANIFEST. + // We modify the ignoreList below to NOT exclude it, + // so securejarhandler creates the "minecraft" module from it. String classpath; if (manifest != null) { classpath = buildClasspathFromManifest(manifest, false); @@ -85,31 +79,38 @@ public class LaunchCommandBuilder { classpath = buildVanillaClasspath(); } - // Add the copied version jar to classpath (if it exists). - // securejarhandler scans classpath JARs and creates modules. - // The jar name "1.20.1-forge-47.4.20.jar" is NOT in ignoreList, - // so it becomes a proper module with Automatic-Module-Name: minecraft. - Path copiedVersionJar = instance.getPath().resolve("versions") - .resolve(getVersionId()).resolve(getVersionId() + ".jar"); - if (Files.exists(copiedVersionJar) && isValidJar(copiedVersionJar)) { - String sep = System.getProperty("os.name").toLowerCase().contains("win") ? ";" : ":"; - classpath = copiedVersionJar.toAbsolutePath().toString() + sep + classpath; - System.out.println(ZAnsi.green(" Added version jar for minecraft module: " + copiedVersionJar.getFileName())); - } - command.add("-cp"); String cpFile = writeClasspathFile(classpath); command.add(cpFile); - // Add JVM arguments from version.json manifest as-is. - // Forge's -p is a HARDCODED list of 8 bootstrap JARs (bootstraplauncher, - // securejarhandler, asm-*, JarJarFileSystems) — NOT ${classpath}. - // Do NOT intercept it. + // Add JVM arguments from version.json manifest. + // Forge's -p is a HARDCODED list of 8 bootstrap JARs + // (bootstraplauncher, securejarhandler, asm-*, JarJarFileSystems). + // Intercept -DignoreList to remove "forge-" pattern, which + // blocks the forge client jar (forge-*-client.jar) from being + // processed by securejarhandler into the "minecraft" module. if (manifest != null) { Map vars = buildVariableMap(options); vars.put("classpath", cpFile); for (String arg : manifest.getJvmArguments()) { - command.add(resolveVariable(arg, vars)); + String resolved = resolveVariable(arg, vars); + if (resolved.startsWith("-DignoreList=")) { + String value = resolved.substring("-DignoreList=".length()); + // Remove forge- from the comma-separated list: + // - ,forge-, in the middle → just the comma + // - ,forge- at the end → remove + // - forge-, at the start → remove + String modified = value + .replace(",forge-,", ",") + .replace(",forge-", "") + .replace("forge-,", ""); + if (modified.equals("forge-")) modified = ""; + if (!modified.equals(value)) { + System.out.println(ZAnsi.green(" Removed 'forge-' from ignoreList")); + } + resolved = "-DignoreList=" + modified; + } + command.add(resolved); } }