Skip to content

Commit 2d8b1df

Browse files
authored
在 Windows 平台通过 GeoID 检测用户所处国家/区域 (#3891)
1 parent 1ab7ab0 commit 2d8b1df

3 files changed

Lines changed: 31 additions & 1 deletion

File tree

HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPage.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@
4343
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
4444
import org.jackhuang.hmcl.util.javafx.BindingMapping;
4545
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
46+
import org.jackhuang.hmcl.util.platform.NativeUtils;
47+
import org.jackhuang.hmcl.util.platform.OperatingSystem;
48+
import org.jackhuang.hmcl.util.platform.windows.Kernel32;
49+
import org.jackhuang.hmcl.util.platform.windows.WinConstants;
4650

4751
import java.net.URI;
4852
import java.time.ZoneId;
53+
import java.time.ZonedDateTime;
4954
import java.util.Locale;
5055

5156
import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig;
@@ -57,11 +62,28 @@
5762
public final class AccountListPage extends DecoratorAnimatedPage implements DecoratorPage {
5863
static final BooleanProperty RESTRICTED = new SimpleBooleanProperty(true);
5964

65+
private static boolean isExemptedRegion() {
66+
if ("Asia/Shanghai".equals(ZoneId.systemDefault().getId()))
67+
return true;
68+
69+
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
70+
&& NativeUtils.USE_JNA
71+
&& ZonedDateTime.now().getOffset().getTotalSeconds() == 8 * 3600) { // GMT+8
72+
Kernel32 kernel32 = Kernel32.INSTANCE;
73+
74+
// https://learn.microsoft.com/windows/win32/intl/table-of-geographical-locations
75+
if (kernel32 != null && kernel32.GetUserGeoID(WinConstants.GEOCLASS_NATION) == 45)
76+
return true;
77+
}
78+
79+
return false;
80+
}
81+
6082
static {
6183
String property = System.getProperty("hmcl.offline.auth.restricted", "auto");
6284

6385
if ("false".equals(property)
64-
|| "auto".equals(property) && "Asia/Shanghai".equals(ZoneId.systemDefault().getId())
86+
|| "auto".equals(property) && isExemptedRegion()
6587
|| globalConfig().isEnableOfflineAccount())
6688
RESTRICTED.set(false);
6789
else

HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/Kernel32.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,8 @@ public interface Kernel32 extends StdCallLibrary {
4444
*/
4545
int GetACP();
4646

47+
/**
48+
* @see <a href="https://learn.microsoft.com/windows/win32/api/winnls/nf-winnls-getusergeoid">GetUserGeoID function</a>
49+
*/
50+
int GetUserGeoID(int geoClass);
4751
}

HMCLCore/src/main/java/org/jackhuang/hmcl/util/platform/windows/WinConstants.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,8 @@ public interface WinConstants {
3636
long HKEY_CURRENT_CONFIG = 0x80000005L;
3737
long HKEY_DYN_DATA = 0x80000006L;
3838
long HKEY_CURRENT_USER_LOCAL_SETTINGS = 0x80000007L;
39+
40+
int GEOCLASS_NATION = 16;
41+
int GEOCLASS_REGION = 14;
42+
int GEOCLASS_ALL = 0;
3943
}

0 commit comments

Comments
 (0)