Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 37 additions & 9 deletions HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,16 @@ private static Task<JavaRuntime> checkGameState(Profile profile, VersionSetting
if (setting.getJavaVersionType() == JavaVersionType.VERSION) {
try {
int targetJavaVersionMajor = Integer.parseInt(setting.getJavaVersion());
GameJavaVersion minimumJavaVersion = GameJavaVersion.getMinimumJavaVersion(gameVersion);
GameJavaVersion minimumJavaVersion = null;
if (gameVersion.compareTo("1.12.2") == 0) {
Optional<String> cleanroomVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.CLEANROOM);
if (cleanroomVersion.isPresent()) {
minimumJavaVersion = GameJavaVersion.getCleanroomJavaVersion(cleanroomVersion.get());
}
}

if (minimumJavaVersion == null)
minimumJavaVersion = GameJavaVersion.getMinimumJavaVersion(gameVersion);

if (minimumJavaVersion != null && targetJavaVersionMajor < minimumJavaVersion.majorVersion()) {
Controllers.dialog(
Expand All @@ -402,8 +411,17 @@ private static Task<JavaRuntime> checkGameState(Profile profile, VersionSetting
targetJavaVersion = GameJavaVersion.get(targetJavaVersionMajor);
} catch (NumberFormatException ignored) {
}
} else
targetJavaVersion = version.getJavaVersion();
} else {
if (gameVersion.compareTo("1.12.2") == 0) {
Optional<String> cleanroomVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.CLEANROOM);
if (cleanroomVersion.isPresent()) {
targetJavaVersion = GameJavaVersion.getCleanroomJavaVersion(cleanroomVersion.get());
}
}

if (targetJavaVersion == null)
targetJavaVersion = version.getJavaVersion();
}

if (targetJavaVersion != null && supportedVersions.contains(targetJavaVersion)) {
downloadJava(targetJavaVersion, profile)
Expand Down Expand Up @@ -433,7 +451,7 @@ private static Task<JavaRuntime> checkGameState(Profile profile, VersionSetting
if (java != null) {
for (JavaVersionConstraint constraint : JavaVersionConstraint.ALL) {
if (constraint.appliesToVersion(gameVersion, version, java, analyzer)) {
if (!constraint.checkJava(gameVersion, version, java)) {
if (!constraint.checkJava(gameVersion, version, java, analyzer)) {
if (constraint.isMandatory()) {
violatedMandatoryConstraints.add(constraint);
} else {
Expand Down Expand Up @@ -468,9 +486,14 @@ private static Task<JavaRuntime> checkGameState(Profile profile, VersionSetting
return result;
} else {
GameJavaVersion gameJavaVersion;
if (violatedMandatoryConstraints.contains(JavaVersionConstraint.CLEANROOM_JAVA_21))
gameJavaVersion = GameJavaVersion.JAVA_21;
else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.GAME_JSON))
if (violatedMandatoryConstraints.contains(JavaVersionConstraint.CLEANROOM)) {
String cleanroomVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.CLEANROOM)
.orElse("");

gameJavaVersion = !cleanroomVersion.isEmpty()
? GameJavaVersion.getCleanroomJavaVersion(cleanroomVersion)
: GameJavaVersion.JAVA_21;
} else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.GAME_JSON))
gameJavaVersion = version.getJavaVersion();
else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
gameJavaVersion = GameJavaVersion.getMinimumJavaVersion(gameVersion);
Expand Down Expand Up @@ -560,9 +583,14 @@ else if (violatedMandatoryConstraints.contains(JavaVersionConstraint.VANILLA))
case MODDED_JAVA_21:
suggestions.add(i18n("launch.advice.modded_java", 21, gameVersion));
break;
case CLEANROOM_JAVA_21:
suggestions.add(i18n("launch.advice.cleanroom"));
case CLEANROOM: {
String cleanroomVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.CLEANROOM).orElse("");
if (!cleanroomVersion.isEmpty())
suggestions.add(i18n("launch.advice.cleanroom", GameJavaVersion.getCleanroomJavaVersion(cleanroomVersion).majorVersion(), cleanroomVersion));
else
suggestions.add(i18n("launch.advice.cleanroom", 21, ""));
break;
}
case VANILLA_JAVA_8_51:
suggestions.add(i18n("launch.advice.java8_51_1_13"));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public static JavaRuntime findSuitableJava(Collection<JavaRuntime> javaRuntimes,

for (JavaVersionConstraint constraint : JavaVersionConstraint.ALL) {
if (constraint.appliesToVersion(gameVersion, version, java, analyzer)) {
if (!constraint.checkJava(gameVersion, version, java)) {
if (!constraint.checkJava(gameVersion, version, java, analyzer)) {
if (constraint.isMandatory()) {
violationMandatory = true;
} else {
Expand Down
2 changes: 1 addition & 1 deletion HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ launch.advice=%s Do you still want to continue to launch?
launch.advice.multi=The following problems were detected:\n\n%s\n\nThese problems may prevent you from launching the game or affect gaming experience.\nDo you still want to continue to launch?
launch.advice.java.auto=The current Java version is not compatible with the instance.\n\nClick "Yes" to automatically choose the most compatible Java version. Or, you can navigate to "Global/Instance-specific Settings → Java" to choose one yourself.
launch.advice.java.modded_java_7=Minecraft 1.7.2 and previous versions require Java 7 or earlier.
launch.advice.cleanroom=Cleanroom can only be run on Java 21 or later. Please use Java 21 or later versions.
launch.advice.cleanroom=Cleanroom %2$s can only be run on Java %1$s or later. Please use Java %1$s or later versions.
launch.advice.corrected=We have resolved the Java problem. If you still want to use your choice of Java version, you can disable "Do not check JVM compatibility" in "Global/Instance-specific Settings → Advanced Settings".
launch.advice.uncorrected=If you still want to use your choice of Java version, you can disable "Do not check JVM compatibility" in "Global/Instance-specific Settings → Advanced Settings".
launch.advice.different_platform=The 64-bit Java version is recommended for your device, but you have installed a 32-bit one.
Expand Down
2 changes: 1 addition & 1 deletion HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ launch.advice=%s 是否繼續啟動?
launch.advice.multi=檢測到以下問題:\n\n%s\n\n這些問題可能導致遊戲無法正常啟動或影響遊戲體驗,是否繼續啟動?
launch.advice.java.auto=目前選取的 Java 版本不滿足遊戲要求,是否自動選取合適的 Java 版本?\n或者你可以到「(全域/實例特定) 遊戲設定 → 遊戲 Java」中選取一個合適的 Java 版本。
launch.advice.java.modded_java_7=Minecraft 1.7.2 及更低版本需要 Java 7 及更低版本。
launch.advice.cleanroom=Cleanroom 僅支援 Java 21 或更高版本。請使用 Java 21 或最新版本。
launch.advice.cleanroom=Cleanroom %2$s 只能在 Java %1$s 或更高版本上運行。請使用 Java %1$s 或最新版本。
launch.advice.corrected=我們已經修正了 Java 版本問題。如果你確實希望使用你自訂的 Java,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 Java 虛擬機與遊戲的相容性」。
launch.advice.uncorrected=如果你確實希望使用你自訂的 Java,你可以在「(全域/實例特定) 遊戲設定 → 進階設定」中往下滑,開啟「不檢查 Java 虛擬機與遊戲的相容性」。
launch.advice.different_platform=你正在使用 32 位元 Java 啟動遊戲。建議更換至 64 位元 Java。
Expand Down
2 changes: 1 addition & 1 deletion HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ launch.advice=%s 是否继续启动?
launch.advice.multi=检测到以下问题:\n\n%s\n\n这些问题可能导致游戏无法正常启动或影响游戏体验,是否继续启动?\n你可以点击右上角帮助按钮进行求助。
launch.advice.java.auto=当前选择的 Java 版本不满足游戏要求。\n点击“是”即可由 HMCL 来自动选取合适的 Java 版本。\n或者你可以在“(全局/实例特定) 游戏设置 → 游戏 Java”中选择一个合适的 Java 版本。
launch.advice.java.modded_java_7=Minecraft 1.7.2 及更低版本需要 Java 7 及更低版本。
launch.advice.cleanroom=Cleanroom 只能在 Java 21 或更高版本上运行。请使用 Java 21 或最新版本。
launch.advice.cleanroom=Cleanroom %2$s 只能在 Java %1$s 或更高版本上运行。请使用 Java %1$s 或最新版本。
launch.advice.corrected=我们已经修复了 Java 版本问题。如果你确实希望使用你自定义的 Java,你可以在“(全局/实例特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 Java 虚拟机与游戏的兼容性”。
launch.advice.uncorrected=如果你确实希望使用你自定义的 Java,你可以在“(全局/实例特定) 游戏设置 → 高级设置”中往下滑,启用“不检查 Java 虚拟机与游戏的兼容性”。
launch.advice.different_platform=你正在使用 32 位 Java 启动游戏。建议更换至 64 位 Java。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
*/
package org.jackhuang.hmcl.game;

import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonSerializable;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.Platform;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import org.jackhuang.hmcl.util.versioning.VersionNumber;

import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -51,6 +53,14 @@ public static GameJavaVersion getMinimumJavaVersion(GameVersionNumber gameVersio
return null;
}

public static GameJavaVersion getCleanroomJavaVersion(String cleanroomVersion) {
VersionNumber versionNumber = VersionNumber.asVersion(StringUtils.removeSuffix(cleanroomVersion, "-alpha"));
if (versionNumber.compareTo("0.5.0") >= 0)
return JAVA_25;
else
return JAVA_21;
}

public static GameJavaVersion get(int major) {
return switch (major) {
case 8 -> JAVA_8;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
}

@Override
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java) {
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java, LibraryAnalyzer analyzer) {
GameJavaVersion minimumJavaVersion = GameJavaVersion.getMinimumJavaVersion(gameVersionNumber);
return minimumJavaVersion == null || java.getParsedVersion() >= minimumJavaVersion.majorVersion();
}
Expand All @@ -57,7 +57,7 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
}

@Override
public VersionRange<VersionNumber> getJavaVersionRange(Version version) {
public VersionRange<VersionNumber> getJavaVersionRange(Version version, LibraryAnalyzer analyzer) {
String javaVersion;
if (Objects.requireNonNull(version.getJavaVersion()).majorVersion() >= 9) {
javaVersion = "" + version.getJavaVersion().majorVersion();
Expand Down Expand Up @@ -108,13 +108,26 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
&& super.appliesToVersionImpl(gameVersionNumber, version, java, analyzer);
}
},
CLEANROOM_JAVA_21(true, GameVersionNumber.between("1.12.2", "1.12.999"), VersionNumber.atLeast("21")) {
CLEANROOM(true, GameVersionNumber.between("1.12.2", "1.12.999"), VersionRange.all()) {
@Override
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version,
@Nullable JavaRuntime java, @Nullable LibraryAnalyzer analyzer) {
protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nullable Version version, @Nullable JavaRuntime java, @Nullable LibraryAnalyzer analyzer) {
return analyzer != null && analyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM)
&& super.appliesToVersionImpl(gameVersionNumber, version, java, analyzer);
}

@Override
public VersionRange<VersionNumber> getJavaVersionRange(Version version, LibraryAnalyzer analyzer) {
if (analyzer == null || !analyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM))
return VersionRange.all();

String cleanroomVersion = analyzer.getVersion(LibraryAnalyzer.LibraryType.CLEANROOM).orElse("");
if (cleanroomVersion.isEmpty())
return VersionRange.all();
else
return VersionNumber.atLeast(
String.valueOf(GameJavaVersion.getCleanroomJavaVersion(cleanroomVersion).majorVersion())
);
}
},
// LaunchWrapper<=1.12 will crash because LaunchWrapper assumes the system class loader is an instance of URLClassLoader (Java 8)
LAUNCH_WRAPPER(true, GameVersionNumber.atMost("1.12.999"), VersionNumber.atMost("1.8.999")) {
Expand Down Expand Up @@ -143,8 +156,8 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
}

@Override
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java) {
return java.getArchitecture() != Architecture.X86_64 || super.checkJava(gameVersionNumber, version, java);
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java, LibraryAnalyzer analyzer) {
return java.getArchitecture() != Architecture.X86_64 || super.checkJava(gameVersionNumber, version, java, analyzer);
}
},
// Minecraft currently does not provide official support for architectures other than x86 and x86-64.
Expand All @@ -162,7 +175,7 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
}

@Override
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java) {
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java, LibraryAnalyzer analyzer) {
return java.getArchitecture().isX86();
}
},
Expand Down Expand Up @@ -194,7 +207,7 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
}

@Override
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java) {
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java, LibraryAnalyzer analyzer) {
int parsedJavaVersion = java.getParsedVersion();
if (parsedJavaVersion > 17) {
return false;
Expand Down Expand Up @@ -230,7 +243,7 @@ public VersionRange<GameVersionNumber> getGameVersionRange() {
return gameVersionRange;
}

public VersionRange<VersionNumber> getJavaVersionRange(Version version) {
public VersionRange<VersionNumber> getJavaVersionRange(Version version, LibraryAnalyzer analyzer) {
return javaVersionRange;
}

Expand All @@ -251,15 +264,15 @@ protected boolean appliesToVersionImpl(GameVersionNumber gameVersionNumber, @Nul
? String.valueOf(gameJavaVersion.majorVersion())
: "1." + gameJavaVersion.majorVersion();

VersionRange<VersionNumber> range = getJavaVersionRange(version);
VersionRange<VersionNumber> range = getJavaVersionRange(version, analyzer);
VersionNumber maximum = range.getMaximum();

return maximum == null || maximum.compareTo(versionNumber) >= 0;
}

@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java) {
return getJavaVersionRange(version).contains(java.getVersionNumber());
public boolean checkJava(GameVersionNumber gameVersionNumber, Version version, JavaRuntime java, LibraryAnalyzer analyzer) {
return getJavaVersionRange(version, analyzer).contains(java.getVersionNumber());
}

public static final List<JavaVersionConstraint> ALL = Lang.immutableListOf(values());
Expand Down
Loading