diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaMetadata.java b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaMetadata.java index c2bcec77a..d2a8a7e9f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaMetadata.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaMetadata.java @@ -23,7 +23,9 @@ import org.jackhuang.hmcl.task.FileDownloadTask; import org.jackhuang.hmcl.terracotta.provider.GeneralProvider; import org.jackhuang.hmcl.terracotta.provider.ITerracottaProvider; import org.jackhuang.hmcl.terracotta.provider.MacOSProvider; +import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.gson.JsonUtils; +import org.jackhuang.hmcl.util.i18n.LocaleUtils; import org.jackhuang.hmcl.util.i18n.LocalizedText; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.NetworkUtils; @@ -61,11 +63,14 @@ public final class TerracottaMetadata { @SerializedName("classifiers") Map classifiers, @SerializedName("downloads") List downloads, + @SerializedName("downloads_CN") List downloadsCN, @SerializedName("links") List links ) { private TerracottaNative of(String classifier) { - List links = new ArrayList<>(this.downloads.size()); - for (String download : this.downloads) { + List links = new ArrayList<>(this.downloads.size() + this.downloadsCN.size()); + for (String download : LocaleUtils.IS_CHINA_MAINLAND + ? Lang.merge(this.downloadsCN, this.downloads) + : Lang.merge(this.downloads, this.downloadsCN)) { links.add(URI.create(download.replace("${version}", this.latest).replace("${classifier}", classifier))); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java index bfaafc74a..c66eb2609 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java @@ -19,7 +19,13 @@ package org.jackhuang.hmcl.ui.account; import com.jfoenix.controls.JFXButton; import javafx.beans.binding.Bindings; -import javafx.beans.property.*; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ListProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleListProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; @@ -45,51 +51,23 @@ import org.jackhuang.hmcl.util.i18n.LocaleUtils; import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.MappedObservableList; -import org.jackhuang.hmcl.util.platform.NativeUtils; -import org.jackhuang.hmcl.util.platform.OperatingSystem; -import org.jackhuang.hmcl.util.platform.windows.Kernel32; -import org.jackhuang.hmcl.util.platform.windows.WinConstants; -import java.time.Duration; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.Locale; import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig; import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap; -import static org.jackhuang.hmcl.util.logging.Logger.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; public final class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage { static final BooleanProperty RESTRICTED = new SimpleBooleanProperty(true); - private static boolean isExemptedRegion() { - if ("Asia/Shanghai".equals(ZoneId.systemDefault().getId())) - return true; - - // Check if the time zone is UTC+8 - if (ZonedDateTime.now().getOffset().getTotalSeconds() == Duration.ofHours(8).toSeconds()) { - if ("CN".equals(LocaleUtils.SYSTEM_DEFAULT.getCountry())) - return true; - - if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS && NativeUtils.USE_JNA) { - Kernel32 kernel32 = Kernel32.INSTANCE; - - // https://learn.microsoft.com/windows/win32/intl/table-of-geographical-locations - if (kernel32 != null && kernel32.GetUserGeoID(WinConstants.GEOCLASS_NATION) == 45) // China - return true; - } - } - - return false; - } - static { String property = System.getProperty("hmcl.offline.auth.restricted", "auto"); if ("false".equals(property) - || "auto".equals(property) && isExemptedRegion() + || "auto".equals(property) && LocaleUtils.IS_CHINA_MAINLAND || globalConfig().isEnableOfflineAccount()) RESTRICTED.set(false); else diff --git a/HMCL/src/main/resources/assets/terracotta.json b/HMCL/src/main/resources/assets/terracotta.json index e240d35da..5b7366239 100644 --- a/HMCL/src/main/resources/assets/terracotta.json +++ b/HMCL/src/main/resources/assets/terracotta.json @@ -15,12 +15,12 @@ "windows-x86_64.exe": "sha256:de518b2b4e60336fd272092326799966efc4e72acd65576d83e61d4d242fd61d" }, "downloads": [ - "https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}", + "https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}" + ], + "downloads_CN": [ "https://gitee.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}", - "https://alist.8mi.tech/d/mirror/HMCL-Terracotta/Auto/v${version}/terracotta-${version}-${classifier}", - "https://ghfast.top/https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}", - "https://cdn.crashmc.com/https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}", - "https://cp.zkitefly.eu.org/https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}" + "https://cnb.cool/HMCL-Terracotta/Terracotta/-/releases/download/v${version}/terracotta-${version}-${classifier}", + "https://alist.8mi.tech/d/mirror/HMCL-Terracotta/Auto/v${version}/terracotta-${version}-${classifier}" ], "links": [ { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocaleUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocaleUtils.java index 783c95163..3d36152b8 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocaleUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocaleUtils.java @@ -20,6 +20,10 @@ package org.jackhuang.hmcl.util.i18n; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.IOUtils; +import org.jackhuang.hmcl.util.platform.NativeUtils; +import org.jackhuang.hmcl.util.platform.OperatingSystem; +import org.jackhuang.hmcl.util.platform.windows.Kernel32; +import org.jackhuang.hmcl.util.platform.windows.WinConstants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Unmodifiable; @@ -27,6 +31,9 @@ import org.jetbrains.annotations.Unmodifiable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -385,6 +392,29 @@ public final class LocaleUtils { return "zh".equals(getRootLanguage(locale)); } + public static final boolean IS_CHINA_MAINLAND = isChinaMainland(); + + private static boolean isChinaMainland() { + if ("Asia/Shanghai".equals(ZoneId.systemDefault().getId())) + return true; + + // Check if the time zone is UTC+8 + if (ZonedDateTime.now().getOffset().getTotalSeconds() == Duration.ofHours(8).toSeconds()) { + if ("CN".equals(LocaleUtils.SYSTEM_DEFAULT.getCountry())) + return true; + + if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS && NativeUtils.USE_JNA) { + Kernel32 kernel32 = Kernel32.INSTANCE; + + // https://learn.microsoft.com/windows/win32/intl/table-of-geographical-locations + if (kernel32 != null && kernel32.GetUserGeoID(WinConstants.GEOCLASS_NATION) == 45) // China + return true; + } + } + + return false; + } + private LocaleUtils() { } }