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 7ebcaef99..21e6f3517 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 @@ -43,9 +43,14 @@ import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; 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.net.URI; import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Locale; import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig; @@ -57,11 +62,28 @@ import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedIt 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; + + if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS + && NativeUtils.USE_JNA + && ZonedDateTime.now().getOffset().getTotalSeconds() == 8 * 3600) { // GMT+8 + Kernel32 kernel32 = Kernel32.INSTANCE; + + // https://learn.microsoft.com/windows/win32/intl/table-of-geographical-locations + if (kernel32 != null && kernel32.GetUserGeoID(WinConstants.GEOCLASS_NATION) == 45) + return true; + } + + return false; + } + static { String property = System.getProperty("hmcl.offline.auth.restricted", "auto"); if ("false".equals(property) - || "auto".equals(property) && "Asia/Shanghai".equals(ZoneId.systemDefault().getId()) + || "auto".equals(property) && isExemptedRegion() || globalConfig().isEnableOfflineAccount()) RESTRICTED.set(false); else diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Kernel32.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Kernel32.java index f179155bf..28eb6120e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Kernel32.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Kernel32.java @@ -44,4 +44,8 @@ public interface Kernel32 extends StdCallLibrary { */ int GetACP(); + /** + * @see GetUserGeoID function + */ + int GetUserGeoID(int geoClass); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java index 0bd878bb4..8645ffc95 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java @@ -36,4 +36,8 @@ public interface WinConstants { long HKEY_CURRENT_CONFIG = 0x80000005L; long HKEY_DYN_DATA = 0x80000006L; long HKEY_CURRENT_USER_LOCAL_SETTINGS = 0x80000007L; + + int GEOCLASS_NATION = 16; + int GEOCLASS_REGION = 14; + int GEOCLASS_ALL = 0; }