在 Windows 平台通过 GeoID 检测用户所处国家/区域 (#3891)

This commit is contained in:
Glavo 2025-05-04 23:13:40 +08:00 committed by GitHub
parent 1ab7ab0750
commit 2d8b1df465
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 1 deletions

View File

@ -43,9 +43,14 @@ import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage;
import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
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.net.URI; import java.net.URI;
import java.time.ZoneId; 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;
@ -57,11 +62,28 @@ import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedIt
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;
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 { 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) && "Asia/Shanghai".equals(ZoneId.systemDefault().getId()) || "auto".equals(property) && isExemptedRegion()
|| globalConfig().isEnableOfflineAccount()) || globalConfig().isEnableOfflineAccount())
RESTRICTED.set(false); RESTRICTED.set(false);
else else

View File

@ -44,4 +44,8 @@ public interface Kernel32 extends StdCallLibrary {
*/ */
int GetACP(); int GetACP();
/**
* @see <a href="https://learn.microsoft.com/windows/win32/api/winnls/nf-winnls-getusergeoid">GetUserGeoID function</a>
*/
int GetUserGeoID(int geoClass);
} }

View File

@ -36,4 +36,8 @@ public interface WinConstants {
long HKEY_CURRENT_CONFIG = 0x80000005L; long HKEY_CURRENT_CONFIG = 0x80000005L;
long HKEY_DYN_DATA = 0x80000006L; long HKEY_DYN_DATA = 0x80000006L;
long HKEY_CURRENT_USER_LOCAL_SETTINGS = 0x80000007L; long HKEY_CURRENT_USER_LOCAL_SETTINGS = 0x80000007L;
int GEOCLASS_NATION = 16;
int GEOCLASS_REGION = 14;
int GEOCLASS_ALL = 0;
} }