修复在非官方支持的平台上 Minecraft 1.21 与 Sodium 不兼容的问题 (#3622)

* update

* update

* update
This commit is contained in:
Glavo 2025-02-18 23:58:16 +08:00 committed by GitHub
parent 15a3fb5f59
commit 5fa01c8838
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 9 deletions

View File

@ -374,7 +374,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
vs.setUsesGlobal(true); vs.setUsesGlobal(true);
} }
public LaunchOptions getLaunchOptions(String version, JavaRuntime javaVersion, File gameDir, List<String> javaAgents, boolean makeLaunchScript) { public LaunchOptions getLaunchOptions(String version, JavaRuntime javaVersion, File gameDir, List<String> javaAgents, List<String> javaArguments, boolean makeLaunchScript) {
VersionSetting vs = getVersionSetting(version); VersionSetting vs = getVersionSetting(version);
LaunchOptions.Builder builder = new LaunchOptions.Builder() LaunchOptions.Builder builder = new LaunchOptions.Builder()
@ -417,7 +417,8 @@ public class HMCLGameRepository extends DefaultGameRepository {
.setUseNativeGLFW(vs.isUseNativeGLFW()) .setUseNativeGLFW(vs.isUseNativeGLFW())
.setUseNativeOpenAL(vs.isUseNativeOpenAL()) .setUseNativeOpenAL(vs.isUseNativeOpenAL())
.setDaemon(!makeLaunchScript && vs.getLauncherVisibility().isDaemon()) .setDaemon(!makeLaunchScript && vs.getLauncherVisibility().isDaemon())
.setJavaAgents(javaAgents); .setJavaAgents(javaAgents)
.setJavaArguments(javaArguments);
if (config().hasProxy()) { if (config().hasProxy()) {
builder.setProxy(ProxyManager.getProxy()); builder.setProxy(ProxyManager.getProxy());
if (config().hasProxyAuth()) { if (config().hasProxyAuth()) {

View File

@ -131,13 +131,14 @@ public final class LauncherHelper {
boolean integrityCheck = repository.unmarkVersionLaunchedAbnormally(selectedVersion); boolean integrityCheck = repository.unmarkVersionLaunchedAbnormally(selectedVersion);
CountDownLatch launchingLatch = new CountDownLatch(1); CountDownLatch launchingLatch = new CountDownLatch(1);
List<String> javaAgents = new ArrayList<>(0); List<String> javaAgents = new ArrayList<>(0);
List<String> javaArguments = new ArrayList<>(0);
AtomicReference<JavaRuntime> javaVersionRef = new AtomicReference<>(); AtomicReference<JavaRuntime> javaVersionRef = new AtomicReference<>();
TaskExecutor executor = checkGameState(profile, setting, version.get()) TaskExecutor executor = checkGameState(profile, setting, version.get())
.thenComposeAsync(java -> { .thenComposeAsync(java -> {
javaVersionRef.set(Objects.requireNonNull(java)); javaVersionRef.set(Objects.requireNonNull(java));
version.set(NativePatcher.patchNative(version.get(), gameVersion.orElse(null), java, setting)); version.set(NativePatcher.patchNative(repository, version.get(), gameVersion.orElse(null), java, setting, javaArguments));
if (setting.isNotCheckGame()) if (setting.isNotCheckGame())
return null; return null;
return Task.allOf( return Task.allOf(
@ -155,7 +156,7 @@ public final class LauncherHelper {
Task.composeAsync(() -> { Task.composeAsync(() -> {
Renderer renderer = setting.getRenderer(); Renderer renderer = setting.getRenderer();
if (renderer != Renderer.DEFAULT && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) { if (renderer != Renderer.DEFAULT && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
Library lib = NativePatcher.getMesaLoader(java, renderer); Library lib = NativePatcher.getMesaLoader(java);
if (lib == null) if (lib == null)
return null; return null;
File file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib); File file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib);
@ -182,7 +183,8 @@ public final class LauncherHelper {
.thenComposeAsync(() -> gameVersion.map(s -> new GameVerificationFixTask(dependencyManager, s, version.get())).orElse(null)) .thenComposeAsync(() -> gameVersion.map(s -> new GameVerificationFixTask(dependencyManager, s, version.get())).orElse(null))
.thenComposeAsync(() -> logIn(account).withStage("launch.state.logging_in")) .thenComposeAsync(() -> logIn(account).withStage("launch.state.logging_in"))
.thenComposeAsync(authInfo -> Task.supplyAsync(() -> { .thenComposeAsync(authInfo -> Task.supplyAsync(() -> {
LaunchOptions launchOptions = repository.getLaunchOptions(selectedVersion, javaVersionRef.get(), profile.getGameDir(), javaAgents, scriptFile != null); LaunchOptions launchOptions = repository.getLaunchOptions(
selectedVersion, javaVersionRef.get(), profile.getGameDir(), javaAgents, javaArguments, scriptFile != null);
LOG.info("Here's the structure of game mod directory:\n" + FileUtils.printFileStructure(repository.getModManager(selectedVersion).getModsDirectory(), 10)); LOG.info("Here's the structure of game mod directory:\n" + FileUtils.printFileStructure(repository.getModManager(selectedVersion).getModsDirectory(), 10));

View File

@ -18,6 +18,8 @@
package org.jackhuang.hmcl.util; package org.jackhuang.hmcl.util;
import org.jackhuang.hmcl.game.*; import org.jackhuang.hmcl.game.*;
import org.jackhuang.hmcl.mod.LocalModFile;
import org.jackhuang.hmcl.mod.ModManager;
import org.jackhuang.hmcl.setting.VersionSetting; import org.jackhuang.hmcl.setting.VersionSetting;
import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.platform.Architecture; import org.jackhuang.hmcl.util.platform.Architecture;
@ -60,7 +62,11 @@ public final class NativePatcher {
}); });
} }
public static Version patchNative(Version version, String gameVersion, JavaRuntime javaVersion, VersionSetting settings) { public static Version patchNative(DefaultGameRepository repository,
Version version, String gameVersion,
JavaRuntime javaVersion,
VersionSetting settings,
List<String> javaArguments) {
if (settings.getNativesDirType() == NativesDirectoryType.CUSTOM) { if (settings.getNativesDirType() == NativesDirectoryType.CUSTOM) {
if (gameVersion != null && GameVersionNumber.compare(gameVersion, "1.19") < 0) if (gameVersion != null && GameVersionNumber.compare(gameVersion, "1.19") < 0)
return version; return version;
@ -124,6 +130,7 @@ public final class NativePatcher {
return version; return version;
} }
boolean lwjglVersionChanged = false;
ArrayList<Library> newLibraries = new ArrayList<>(); ArrayList<Library> newLibraries = new ArrayList<>();
for (Library library : version.getLibraries()) { for (Library library : version.getLibraries()) {
if (!library.appliesToCurrentEnvironment()) if (!library.appliesToCurrentEnvironment())
@ -145,14 +152,33 @@ public final class NativePatcher {
} else if (replacement != null) { } else if (replacement != null) {
LOG.info("Replace " + library.getName() + " with " + replacement.getName()); LOG.info("Replace " + library.getName() + " with " + replacement.getName());
newLibraries.add(replacement); newLibraries.add(replacement);
if ("org.lwjgl:lwjgl".equals(library.getName()) && !Objects.equals(library.getVersion(), replacement.getVersion())) {
lwjglVersionChanged = true;
}
} }
} }
} }
if (lwjglVersionChanged) {
ModManager modManager = repository.getModManager(version.getId());
try {
for (LocalModFile mod : modManager.getMods()) {
if ("sodium".equals(mod.getId())) {
// https://github.com/CaffeineMC/sodium/issues/2561
javaArguments.add("-Dsodium.checks.issue2561=false");
break;
}
}
} catch (Throwable e) {
LOG.warning("Failed to get mods", e);
}
}
return version.setLibraries(newLibraries); return version.setLibraries(newLibraries);
} }
public static Library getMesaLoader(JavaRuntime javaVersion, Renderer renderer) { public static Library getMesaLoader(JavaRuntime javaVersion) {
return getNatives(javaVersion.getPlatform()).get("mesa-loader"); return getNatives(javaVersion.getPlatform()).get("mesa-loader");
} }
} }

View File

@ -50,6 +50,8 @@ import static org.jackhuang.hmcl.util.Pair.pair;
*/ */
public class DefaultLauncher extends Launcher { public class DefaultLauncher extends Launcher {
private final LibraryAnalyzer analyzer;
public DefaultLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options) { public DefaultLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options) {
this(repository, version, authInfo, options, null); this(repository, version, authInfo, options, null);
} }
@ -60,6 +62,8 @@ public class DefaultLauncher extends Launcher {
public DefaultLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean daemon) { public DefaultLauncher(GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options, ProcessListener listener, boolean daemon) {
super(repository, version, authInfo, options, listener, daemon); super(repository, version, authInfo, options, listener, daemon);
this.analyzer = LibraryAnalyzer.analyze(version, repository.getGameVersion(version).orElse(null));
} }
private Command generateCommandLine(File nativeFolder) throws IOException { private Command generateCommandLine(File nativeFolder) throws IOException {
@ -496,7 +500,7 @@ public class DefaultLauncher extends Launcher {
break; break;
case ZINK: case ZINK:
env.put("MESA_LOADER_DRIVER_OVERRIDE", "zink"); env.put("MESA_LOADER_DRIVER_OVERRIDE", "zink");
/** /*
* The amdgpu DDX is missing support for modifiers, causing Zink to fail. * The amdgpu DDX is missing support for modifiers, causing Zink to fail.
* Disable DRI3 to workaround this issue. * Disable DRI3 to workaround this issue.
* *
@ -508,7 +512,6 @@ public class DefaultLauncher extends Launcher {
} }
} }
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version, repository.getGameVersion(version).orElse(null));
if (analyzer.has(LibraryAnalyzer.LibraryType.FORGE)) { if (analyzer.has(LibraryAnalyzer.LibraryType.FORGE)) {
env.put("INST_FORGE", "1"); env.put("INST_FORGE", "1");
} }