diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java index 2400ca0dd..0b3be3146 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java @@ -58,9 +58,12 @@ import org.jackhuang.hmcl.ui.wizard.Navigation; import org.jackhuang.hmcl.ui.wizard.Refreshable; import org.jackhuang.hmcl.ui.wizard.WizardPage; import org.jackhuang.hmcl.util.Holder; +import org.jackhuang.hmcl.util.NativePatcher; import org.jackhuang.hmcl.util.SettingsMap; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.i18n.I18n; +import org.jackhuang.hmcl.util.platform.OperatingSystem; +import org.jackhuang.hmcl.util.platform.Platform; import org.jackhuang.hmcl.util.versioning.GameVersionNumber; import java.util.Locale; @@ -240,13 +243,14 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab if (remoteVersion instanceof GameRemoteVersion) { RemoteVersion.Type versionType = remoteVersion.getVersionType(); + GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(remoteVersion.getGameVersion()); + switch (versionType) { - case RELEASE: + case RELEASE -> { twoLineListItem.addTag(i18n("version.game.release")); imageView.setImage(VersionIconType.GRASS.getIcon()); - break; - case PENDING: - case SNAPSHOT: + } + case PENDING, SNAPSHOT -> { if (versionType == RemoteVersion.Type.SNAPSHOT && GameVersionNumber.asGameVersion(remoteVersion.getGameVersion()).isAprilFools()) { twoLineListItem.addTag(i18n("version.game.april_fools")); @@ -255,11 +259,16 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab twoLineListItem.addTag(i18n("version.game.snapshot")); imageView.setImage(VersionIconType.COMMAND.getIcon()); } - break; - default: + } + default -> { twoLineListItem.addTag(i18n("version.game.old")); imageView.setImage(VersionIconType.CRAFT_TABLE.getIcon()); - break; + } + } + + switch (NativePatcher.checkSupportedStatus(gameVersion, Platform.SYSTEM_PLATFORM, OperatingSystem.SYSTEM_VERSION)) { + case UNTESTED -> twoLineListItem.addTagWarning(i18n("version.game.support_status.untested")); + case UNSUPPORTED -> twoLineListItem.addTagWarning(i18n("version.game.support_status.unsupported")); } } else { VersionIconType iconType; @@ -368,18 +377,6 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab ); } } -// { -// HBox actionsBox = new HBox(8); -// GridPane.setColumnSpan(actionsBox, 4); -// actionsBox.setAlignment(Pos.CENTER_RIGHT); -// -// JFXButton refreshButton = FXUtils.newRaisedButton(i18n("button.refresh")); -// refreshButton.setOnAction(event -> control.onRefresh()); -// -// actionsBox.getChildren().setAll(refreshButton); -// -// searchPane.addRow(rowIndex++, actionsBox); -// } } { @@ -455,21 +452,16 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab if (filter != null) versions = versions.filter(it -> { RemoteVersion.Type versionType = it.getVersionType(); - switch (filter) { - case RELEASE: - return versionType == RemoteVersion.Type.RELEASE; - case SNAPSHOTS: - return versionType == RemoteVersion.Type.SNAPSHOT - || versionType == RemoteVersion.Type.PENDING; - case APRIL_FOOLS: - return versionType == RemoteVersion.Type.SNAPSHOT - && GameVersionNumber.asGameVersion(it.getGameVersion()).isAprilFools(); - case OLD: - return versionType == RemoteVersion.Type.OLD; - case ALL: - default: - return true; - } + return switch (filter) { + case RELEASE -> versionType == RemoteVersion.Type.RELEASE; + case SNAPSHOTS -> versionType == RemoteVersion.Type.SNAPSHOT + || versionType == RemoteVersion.Type.PENDING; + case APRIL_FOOLS -> versionType == RemoteVersion.Type.SNAPSHOT + && GameVersionNumber.asGameVersion(it.getGameVersion()).isAprilFools(); + case OLD -> versionType == RemoteVersion.Type.OLD; + // case ALL, + default -> true; + }; }); String nameQuery = nameField.getText(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/NativePatcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/NativePatcher.java index db4550494..d34f4a0b0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/util/NativePatcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/NativePatcher.java @@ -45,8 +45,6 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG; * @author Glavo */ public final class NativePatcher { - private NativePatcher() { - } private static final Library NONEXISTENT_LIBRARY = new Library(null); @@ -196,4 +194,84 @@ public final class NativePatcher { return null; } } + + public static SupportStatus checkSupportedStatus(GameVersionNumber gameVersion, Platform platform, + OSVersion systemVersion) { + if (platform.equals(Platform.WINDOWS_X86_64)) { + if (!systemVersion.isAtLeast(OSVersion.WINDOWS_10) && gameVersion.isAtLeast("1.20.5", "24w14a")) + return SupportStatus.UNSUPPORTED; + + return SupportStatus.OFFICIAL_SUPPORTED; + } + + if (platform.equals(Platform.MACOS_X86_64) || platform.equals(Platform.LINUX_X86_64)) + return SupportStatus.OFFICIAL_SUPPORTED; + + if (platform.equals(Platform.WINDOWS_X86) || platform.equals(Platform.LINUX_X86)) { + if (gameVersion.isAtLeast("1.20.5", "24w14a")) + return SupportStatus.UNSUPPORTED; + else + return SupportStatus.OFFICIAL_SUPPORTED; + } + + if (platform.equals(Platform.WINDOWS_ARM64) || platform.equals(Platform.MACOS_ARM64)) { + if (gameVersion.compareTo("1.19") >= 0) + return SupportStatus.OFFICIAL_SUPPORTED; + + String minVersion = platform.getOperatingSystem() == OperatingSystem.WINDOWS + ? "1.8" + : "1.6"; + + return gameVersion.compareTo(minVersion) >= 0 + ? SupportStatus.LAUNCHER_SUPPORTED + : SupportStatus.TRANSLATION_SUPPORTED; + } + + String minVersion = null; + String maxVersion = null; + + if (platform.equals(Platform.FREEBSD_X86_64)) { + minVersion = "1.13"; + } else if (platform.equals(Platform.LINUX_ARM64)) { + minVersion = "1.6"; + } else if (platform.equals(Platform.LINUX_RISCV64)) { + minVersion = "1.8"; + } else if (platform.equals(Platform.LINUX_LOONGARCH64)) { + minVersion = "1.6"; + } else if (platform.equals(Platform.LINUX_LOONGARCH64_OW)) { + minVersion = "1.6"; + maxVersion = "1.20.1"; + } else if (platform.equals(Platform.LINUX_MIPS64EL) || platform.equals(Platform.LINUX_ARM32)) { + minVersion = "1.8"; + maxVersion = "1.20.1"; + } + + if (minVersion != null) { + if (gameVersion.compareTo(minVersion) >= 0) { + if (maxVersion != null && gameVersion.compareTo(maxVersion) >= 0) + return SupportStatus.UNSUPPORTED; + + String[] defaultGameVersions = GameVersionNumber.getDefaultGameVersions(); + if (defaultGameVersions.length > 0 && gameVersion.compareTo(defaultGameVersions[0]) > 0) { + return SupportStatus.UNTESTED; + } + return SupportStatus.LAUNCHER_SUPPORTED; + } else { + return SupportStatus.UNSUPPORTED; + } + } + + return SupportStatus.UNTESTED; + } + + public enum SupportStatus { + OFFICIAL_SUPPORTED, + LAUNCHER_SUPPORTED, + TRANSLATION_SUPPORTED, + UNTESTED, + UNSUPPORTED, + } + + private NativePatcher() { + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java index a4c36edff..ae206f97c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/util/SelfDependencyPatcher.java @@ -101,14 +101,14 @@ public final class SelfDependencyPatcher { private static final class DependencyDescriptor { private static final String DEPENDENCIES_LIST_FILE = "/assets/openjfx-dependencies.json"; - private static final Path DEPENDENCIES_DIR_PATH = Metadata.DEPENDENCIES_DIRECTORY.resolve(Platform.getPlatform().toString()).resolve("openjfx"); + private static final Path DEPENDENCIES_DIR_PATH = Metadata.DEPENDENCIES_DIRECTORY.resolve(Platform.CURRENT_PLATFORM.toString()).resolve("openjfx"); static List readDependencies() { //noinspection ConstantConditions try (Reader reader = new InputStreamReader(SelfDependencyPatcher.class.getResourceAsStream(DEPENDENCIES_LIST_FILE), UTF_8)) { Map>> allDependencies = JsonUtils.GSON.fromJson(reader, mapTypeOf(String.class, mapTypeOf(String.class, listTypeOf(DependencyDescriptor.class)))); - Map> platform = allDependencies.get(Platform.getPlatform().toString()); + Map> platform = allDependencies.get(Platform.CURRENT_PLATFORM.toString()); if (platform == null) return null; diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 8fa6bfd1b..f52158633 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -1533,6 +1533,8 @@ version.game.release=Release version.game.releases=Releases version.game.snapshot=Snapshot version.game.snapshots=Snapshots +version.game.support_status.unsupported=Unsupported +version.game.support_status.untested=Untested version.game.type=Type version.launch=Launch Game version.launch.empty=Start Game diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index baf8a2e86..23aeabadf 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -1317,6 +1317,8 @@ version.game.release=正式版 version.game.releases=正式版 version.game.snapshot=快照 version.game.snapshots=快照 +version.game.support_status.unsupported=不支援 +version.game.support_status.untested=未經測試 version.game.type=版本類型 version.launch=啟動遊戲 version.launch.empty=開始遊戲 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index d1f0cbb68..84153f606 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -1327,6 +1327,8 @@ version.game.release=正式版 version.game.releases=正式版 version.game.snapshot=快照 version.game.snapshots=快照 +version.game.support_status.unsupported=不支持 +version.game.support_status.untested=未经测试 version.game.type=版本类型 version.launch=启动游戏 version.launch.empty=开始游戏 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/Platform.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/Platform.java index f79278c19..fcd4c8cd0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/Platform.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/Platform.java @@ -1,37 +1,31 @@ package org.jackhuang.hmcl.util.platform; -import java.util.Objects; - -public final class Platform { +public record Platform(OperatingSystem os, Architecture arch) { public static final Platform UNKNOWN = new Platform(OperatingSystem.UNKNOWN, Architecture.UNKNOWN); public static final Platform WINDOWS_X86 = new Platform(OperatingSystem.WINDOWS, Architecture.X86); public static final Platform WINDOWS_X86_64 = new Platform(OperatingSystem.WINDOWS, Architecture.X86_64); public static final Platform WINDOWS_ARM64 = new Platform(OperatingSystem.WINDOWS, Architecture.ARM64); + public static final Platform LINUX_X86 = new Platform(OperatingSystem.LINUX, Architecture.X86); public static final Platform LINUX_X86_64 = new Platform(OperatingSystem.LINUX, Architecture.X86_64); public static final Platform LINUX_ARM64 = new Platform(OperatingSystem.LINUX, Architecture.ARM64); + public static final Platform LINUX_ARM32 = new Platform(OperatingSystem.LINUX, Architecture.ARM32); + public static final Platform LINUX_RISCV64 = new Platform(OperatingSystem.LINUX, Architecture.RISCV64); + public static final Platform LINUX_LOONGARCH64 = new Platform(OperatingSystem.LINUX, Architecture.LOONGARCH64); + public static final Platform LINUX_LOONGARCH64_OW = new Platform(OperatingSystem.LINUX, Architecture.LOONGARCH64_OW); + public static final Platform LINUX_MIPS64EL = new Platform(OperatingSystem.LINUX, Architecture.MIPS64EL); public static final Platform MACOS_X86_64 = new Platform(OperatingSystem.MACOS, Architecture.X86_64); public static final Platform MACOS_ARM64 = new Platform(OperatingSystem.MACOS, Architecture.ARM64); + public static final Platform FREEBSD_X86_64 = new Platform(OperatingSystem.FREEBSD, Architecture.X86); + public static final Platform CURRENT_PLATFORM = Platform.getPlatform(OperatingSystem.CURRENT_OS, Architecture.CURRENT_ARCH); public static final Platform SYSTEM_PLATFORM = Platform.getPlatform(OperatingSystem.CURRENT_OS, Architecture.SYSTEM_ARCH); public static boolean isCompatibleWithX86Java() { - return Architecture.SYSTEM_ARCH.isX86() || SYSTEM_PLATFORM == MACOS_ARM64 || SYSTEM_PLATFORM == WINDOWS_ARM64; - } - - private final OperatingSystem os; - private final Architecture arch; - - private Platform(OperatingSystem os, Architecture arch) { - this.os = os; - this.arch = arch; - } - - public static Platform getPlatform() { - return CURRENT_PLATFORM; + return Architecture.SYSTEM_ARCH.isX86() || SYSTEM_PLATFORM.equals(MACOS_ARM64) || SYSTEM_PLATFORM.equals(WINDOWS_ARM64); } public static Platform getPlatform(OperatingSystem os, Architecture arch) { @@ -74,23 +68,10 @@ public final class Platform { return arch.getBits(); } - @Override - public int hashCode() { - return Objects.hash(os, arch); - } - public boolean equals(OperatingSystem os, Architecture arch) { return this.os == os && this.arch == arch; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Platform)) return false; - Platform platform = (Platform) o; - return os == platform.os && arch == platform.arch; - } - @Override public String toString() { return os.getCheckedName() + "-" + arch.getCheckedName();