在游戏下载界面提示版本支持状态 (#4471)

This commit is contained in:
Glavo
2025-10-10 16:45:18 +08:00
committed by GitHub
parent 0b9616f460
commit 1e74567a22
7 changed files with 124 additions and 67 deletions

View File

@@ -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
return switch (filter) {
case RELEASE -> versionType == RemoteVersion.Type.RELEASE;
case SNAPSHOTS -> versionType == RemoteVersion.Type.SNAPSHOT
|| versionType == RemoteVersion.Type.PENDING;
case APRIL_FOOLS:
return versionType == RemoteVersion.Type.SNAPSHOT
case APRIL_FOOLS -> versionType == RemoteVersion.Type.SNAPSHOT
&& GameVersionNumber.asGameVersion(it.getGameVersion()).isAprilFools();
case OLD:
return versionType == RemoteVersion.Type.OLD;
case ALL:
default:
return true;
}
case OLD -> versionType == RemoteVersion.Type.OLD;
// case ALL,
default -> true;
};
});
String nameQuery = nameField.getText();

View File

@@ -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() {
}
}

View File

@@ -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<DependencyDescriptor> readDependencies() {
//noinspection ConstantConditions
try (Reader reader = new InputStreamReader(SelfDependencyPatcher.class.getResourceAsStream(DEPENDENCIES_LIST_FILE), UTF_8)) {
Map<String, Map<String, List<DependencyDescriptor>>> allDependencies =
JsonUtils.GSON.fromJson(reader, mapTypeOf(String.class, mapTypeOf(String.class, listTypeOf(DependencyDescriptor.class))));
Map<String, List<DependencyDescriptor>> platform = allDependencies.get(Platform.getPlatform().toString());
Map<String, List<DependencyDescriptor>> platform = allDependencies.get(Platform.CURRENT_PLATFORM.toString());
if (platform == null)
return null;

View File

@@ -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

View File

@@ -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=開始遊戲

View File

@@ -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=开始游戏

View File

@@ -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();