Feature: Download Terracotta binary from Gitee, CNB, alist (sponsored by 8mi) first in China mainland. (#4700)
Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
@@ -23,7 +23,9 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.terracotta.provider.GeneralProvider;
|
import org.jackhuang.hmcl.terracotta.provider.GeneralProvider;
|
||||||
import org.jackhuang.hmcl.terracotta.provider.ITerracottaProvider;
|
import org.jackhuang.hmcl.terracotta.provider.ITerracottaProvider;
|
||||||
import org.jackhuang.hmcl.terracotta.provider.MacOSProvider;
|
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.gson.JsonUtils;
|
||||||
|
import org.jackhuang.hmcl.util.i18n.LocaleUtils;
|
||||||
import org.jackhuang.hmcl.util.i18n.LocalizedText;
|
import org.jackhuang.hmcl.util.i18n.LocalizedText;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||||
@@ -61,11 +63,14 @@ public final class TerracottaMetadata {
|
|||||||
|
|
||||||
@SerializedName("classifiers") Map<String, String> classifiers,
|
@SerializedName("classifiers") Map<String, String> classifiers,
|
||||||
@SerializedName("downloads") List<String> downloads,
|
@SerializedName("downloads") List<String> downloads,
|
||||||
|
@SerializedName("downloads_CN") List<String> downloadsCN,
|
||||||
@SerializedName("links") List<Link> links
|
@SerializedName("links") List<Link> links
|
||||||
) {
|
) {
|
||||||
private TerracottaNative of(String classifier) {
|
private TerracottaNative of(String classifier) {
|
||||||
List<URI> links = new ArrayList<>(this.downloads.size());
|
List<URI> links = new ArrayList<>(this.downloads.size() + this.downloadsCN.size());
|
||||||
for (String download : this.downloads) {
|
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)));
|
links.add(URI.create(download.replace("${version}", this.latest).replace("${classifier}", classifier)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,13 @@ package org.jackhuang.hmcl.ui.account;
|
|||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import javafx.beans.binding.Bindings;
|
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.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
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.io.NetworkUtils;
|
||||||
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
import org.jackhuang.hmcl.util.javafx.BindingMapping;
|
||||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
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 java.util.Locale;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
|
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
|
||||||
import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap;
|
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.i18n.I18n.i18n;
|
||||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor;
|
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 {
|
public final class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||||
static final BooleanProperty RESTRICTED = new SimpleBooleanProperty(true);
|
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 {
|
static {
|
||||||
String property = System.getProperty("hmcl.offline.auth.restricted", "auto");
|
String property = System.getProperty("hmcl.offline.auth.restricted", "auto");
|
||||||
|
|
||||||
if ("false".equals(property)
|
if ("false".equals(property)
|
||||||
|| "auto".equals(property) && isExemptedRegion()
|
|| "auto".equals(property) && LocaleUtils.IS_CHINA_MAINLAND
|
||||||
|| globalConfig().isEnableOfflineAccount())
|
|| globalConfig().isEnableOfflineAccount())
|
||||||
RESTRICTED.set(false);
|
RESTRICTED.set(false);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -15,12 +15,12 @@
|
|||||||
"windows-x86_64.exe": "sha256:de518b2b4e60336fd272092326799966efc4e72acd65576d83e61d4d242fd61d"
|
"windows-x86_64.exe": "sha256:de518b2b4e60336fd272092326799966efc4e72acd65576d83e61d4d242fd61d"
|
||||||
},
|
},
|
||||||
"downloads": [
|
"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://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://cnb.cool/HMCL-Terracotta/Terracotta/-/releases/download/v${version}/terracotta-${version}-${classifier}",
|
||||||
"https://ghfast.top/https://github.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://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}"
|
|
||||||
],
|
],
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ package org.jackhuang.hmcl.util.i18n;
|
|||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.io.IOUtils;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
@@ -27,6 +31,9 @@ import org.jetbrains.annotations.Unmodifiable;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@@ -385,6 +392,29 @@ public final class LocaleUtils {
|
|||||||
return "zh".equals(getRootLanguage(locale));
|
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() {
|
private LocaleUtils() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user