From 460f20599040ecca803e08e7cd875ba6ab051905 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Wed, 4 Mar 2026 21:25:51 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=9C=B0?= =?UTF-8?q?=E7=90=86=E4=BD=8D=E7=BD=AE=E6=A3=80=E6=9F=A5=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E4=BB=A5=E4=BC=98=E5=8C=96=E8=B5=84=E6=BA=90=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E6=BA=90=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/util/AssetUtil.java | 33 +++++++------ .../i18nupdatemod/util/GeoLocationUtil.java | 47 +++++++++++++++++++ 2 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/main/java/i18nupdatemod/util/GeoLocationUtil.java diff --git a/src/main/java/i18nupdatemod/util/AssetUtil.java b/src/main/java/i18nupdatemod/util/AssetUtil.java index d75c840..9e52846 100644 --- a/src/main/java/i18nupdatemod/util/AssetUtil.java +++ b/src/main/java/i18nupdatemod/util/AssetUtil.java @@ -45,34 +45,38 @@ public static String getString(String url) throws IOException, URISyntaxExceptio } public static String getFastestUrl() { - List urls = new ArrayList<>(MIRRORS); - urls.add(CFPA_ASSET_ROOT); + List urls = new ArrayList<>(); + + // 根据地理位置选择源列表 + if (GeoLocationUtil.isMainlandChina()) { + // 中国大陆:测速选择最快的国内源 + urls.addAll(MIRRORS); + urls.add(CFPA_ASSET_ROOT); + Log.info("Testing domestic mirror sources for mainland China user..."); + } else { + // 海外用户:直接使用 GitHub 源 + urls.add("https://raw.githubusercontent.com/"); + Log.info("Using GitHub source for overseas user..."); + } ExecutorService executor = Executors.newFixedThreadPool(Math.max(urls.size(), 10)); try { List> futures = new ArrayList<>(); for (String url : urls) { - CompletableFuture future = CompletableFuture.supplyAsync(() -> { + futures.add(CompletableFuture.supplyAsync(() -> { try { return testUrlConnection(url); } catch (IOException e) { - return null; // 表示失败 + return null; } - }, executor); - futures.add(future); + }, executor)); } - // 阻塞等待最快完成且成功的任务 String fastest = null; while (!futures.isEmpty()) { - CompletableFuture first = CompletableFuture.anyOf(futures.toArray(new CompletableFuture[0])); - fastest = (String) first.join(); - - // 移除已完成的 future + fastest = (String) CompletableFuture.anyOf(futures.toArray(new CompletableFuture[0])).join(); futures.removeIf(CompletableFuture::isDone); - if (fastest != null) { - // 成功,取消其他任务 for (CompletableFuture f : futures) { f.cancel(true); } @@ -81,8 +85,7 @@ public static String getFastestUrl() { } } - // 全部失败,返回默认 URL - Log.info("All urls are unreachable, using CFPA_ASSET_ROOT"); + Log.info("All sources unreachable, using CFPA_ASSET_ROOT as fallback"); return CFPA_ASSET_ROOT; } finally { diff --git a/src/main/java/i18nupdatemod/util/GeoLocationUtil.java b/src/main/java/i18nupdatemod/util/GeoLocationUtil.java new file mode 100644 index 0000000..dfae210 --- /dev/null +++ b/src/main/java/i18nupdatemod/util/GeoLocationUtil.java @@ -0,0 +1,47 @@ +package i18nupdatemod.util; + +import org.apache.commons.io.IOUtils; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +/** + * 地理位置检查工具 - 判断用户是否位于中国大陆 + */ +public class GeoLocationUtil { + private static final String GEO_API_URL = "https://mips.kugou.com/check/iscn"; + private static Boolean cached = null; + + /** + * 检查用户是否位于中国大陆 + */ + public static boolean isMainlandChina() { + if (cached != null) { + return cached; + } + + try { + HttpURLConnection conn = (HttpURLConnection) new URL(GEO_API_URL).openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + int code = conn.getResponseCode(); + + if (code == 200) { + String response = IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8).trim(); + cached = "1".equals(response) || "true".equalsIgnoreCase(response); + Log.info("Geo-location: " + (cached ? "mainland China" : "overseas")); + return cached; + } + } catch (Exception e) { + Log.debug("Geo-location check failed: " + e.getMessage()); + } + + cached = false; + return false; + } + + public static void resetCache() { + cached = null; + } +} From 5bb9d3cc12a734a2c592db3a3a7bd65d763c45e0 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:18:54 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E6=A3=80=E6=B5=8B=E5=B7=A5=E5=85=B7=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/util/AssetUtil.java | 6 +++--- .../util/{GeoLocationUtil.java => LocationDetectUtil.java} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/i18nupdatemod/util/{GeoLocationUtil.java => LocationDetectUtil.java} (97%) diff --git a/src/main/java/i18nupdatemod/util/AssetUtil.java b/src/main/java/i18nupdatemod/util/AssetUtil.java index 9e52846..f82681f 100644 --- a/src/main/java/i18nupdatemod/util/AssetUtil.java +++ b/src/main/java/i18nupdatemod/util/AssetUtil.java @@ -48,15 +48,15 @@ public static String getFastestUrl() { List urls = new ArrayList<>(); // 根据地理位置选择源列表 - if (GeoLocationUtil.isMainlandChina()) { + if (LocationDetectUtil.isMainlandChina()) { // 中国大陆:测速选择最快的国内源 urls.addAll(MIRRORS); urls.add(CFPA_ASSET_ROOT); - Log.info("Testing domestic mirror sources for mainland China user..."); + Log.info("Inside mainland China: Testing mirrors..."); } else { // 海外用户:直接使用 GitHub 源 urls.add("https://raw.githubusercontent.com/"); - Log.info("Using GitHub source for overseas user..."); + Log.info("Outside mainland China: Using GitHub source..."); } ExecutorService executor = Executors.newFixedThreadPool(Math.max(urls.size(), 10)); diff --git a/src/main/java/i18nupdatemod/util/GeoLocationUtil.java b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java similarity index 97% rename from src/main/java/i18nupdatemod/util/GeoLocationUtil.java rename to src/main/java/i18nupdatemod/util/LocationDetectUtil.java index dfae210..30cdeb2 100644 --- a/src/main/java/i18nupdatemod/util/GeoLocationUtil.java +++ b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java @@ -9,7 +9,7 @@ /** * 地理位置检查工具 - 判断用户是否位于中国大陆 */ -public class GeoLocationUtil { +public class LocationDetectUtil { private static final String GEO_API_URL = "https://mips.kugou.com/check/iscn"; private static Boolean cached = null; From 7888081e70be9a66877ed50c52a6f0e680fe1df6 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:19:29 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=B0=86=20Github=20=E7=A7=BB=E5=87=BA?= =?UTF-8?q?=E9=95=9C=E5=83=8F=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/util/AssetUtil.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/i18nupdatemod/util/AssetUtil.java b/src/main/java/i18nupdatemod/util/AssetUtil.java index f82681f..d3d1475 100644 --- a/src/main/java/i18nupdatemod/util/AssetUtil.java +++ b/src/main/java/i18nupdatemod/util/AssetUtil.java @@ -28,7 +28,6 @@ public class AssetUtil { static { // 镜像地址可以改成服务器下发 MIRRORS = new ArrayList<>(); - MIRRORS.add("https://raw.githubusercontent.com/"); // 此镜像源维护者:502y MIRRORS.add("http://8.137.167.65:64684/"); } From cd8faa87fcd80f8ad9fee2e81d199481c8cec94b Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:22:44 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20GitHub=20?= =?UTF-8?q?=E6=BA=90=E5=9C=B0=E5=9D=80=E7=9A=84=E7=A1=AC=E7=BC=96=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E4=B8=BA=E4=BD=BF=E7=94=A8=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/util/AssetUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/i18nupdatemod/util/AssetUtil.java b/src/main/java/i18nupdatemod/util/AssetUtil.java index d3d1475..2868978 100644 --- a/src/main/java/i18nupdatemod/util/AssetUtil.java +++ b/src/main/java/i18nupdatemod/util/AssetUtil.java @@ -23,6 +23,7 @@ public class AssetUtil { private static final String CFPA_ASSET_ROOT = "http://downloader1.meitangdehulu.com:22943/"; + private static final String GITHUB = "https://raw.githubusercontent.com/"; private static final List MIRRORS; static { @@ -54,7 +55,7 @@ public static String getFastestUrl() { Log.info("Inside mainland China: Testing mirrors..."); } else { // 海外用户:直接使用 GitHub 源 - urls.add("https://raw.githubusercontent.com/"); + urls.add(GITHUB); Log.info("Outside mainland China: Using GitHub source..."); } From 3264a56f44143572ada505664932393f4f611406 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:25:40 +0800 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E5=9C=B0?= =?UTF-8?q?=E7=90=86=E4=BD=8D=E7=BD=AE=E6=A3=80=E6=B5=8B=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=9A=84=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA=EF=BC=8C=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=86=97=E4=BD=99=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/util/LocationDetectUtil.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java index 30cdeb2..beb9635 100644 --- a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java +++ b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java @@ -6,16 +6,10 @@ import java.net.URL; import java.nio.charset.StandardCharsets; -/** - * 地理位置检查工具 - 判断用户是否位于中国大陆 - */ public class LocationDetectUtil { private static final String GEO_API_URL = "https://mips.kugou.com/check/iscn"; private static Boolean cached = null; - /** - * 检查用户是否位于中国大陆 - */ public static boolean isMainlandChina() { if (cached != null) { return cached; @@ -30,11 +24,11 @@ public static boolean isMainlandChina() { if (code == 200) { String response = IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8).trim(); cached = "1".equals(response) || "true".equalsIgnoreCase(response); - Log.info("Geo-location: " + (cached ? "mainland China" : "overseas")); + Log.info("Location Detected: " + (cached ? "Inside mainland China" : "Outside mainland China")); return cached; } } catch (Exception e) { - Log.debug("Geo-location check failed: " + e.getMessage()); + Log.debug("Location detection failed: " + e.getMessage()); } cached = false; From f5d31a95f98a5081860af585f3c6a0095b6cfeda Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:37:38 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=96=B0=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/LocationDetectUtil.java | 53 +++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java index beb9635..61b064b 100644 --- a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java +++ b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java @@ -5,34 +5,67 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; public class LocationDetectUtil { - private static final String GEO_API_URL = "https://mips.kugou.com/check/iscn"; private static Boolean cached = null; + private static final List GEO_APIS = Arrays.asList( + new GeoApi("Kugou", "https://mips.kugou.com/check/iscn", + response -> "1".equals(response.trim()) || "true".equalsIgnoreCase(response.trim())), + new GeoApi("IP.SB", "https://api.ip.sb/geoip", + response -> response.contains("\"country_code\":\"CN\"") || response.contains("\"country_code\": \"CN\"")) + ); + public static boolean isMainlandChina() { if (cached != null) { return cached; } + for (GeoApi api : GEO_APIS) { + Boolean result = tryApi(api); + if (result != null) { + cached = result; + return cached; + } + } + + // 所有 API 都失败,默认为 false + cached = false; + return false; + } + + private static Boolean tryApi(GeoApi api) { try { - HttpURLConnection conn = (HttpURLConnection) new URL(GEO_API_URL).openConnection(); + HttpURLConnection conn = (HttpURLConnection) new URL(api.url).openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); int code = conn.getResponseCode(); if (code == 200) { - String response = IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8).trim(); - cached = "1".equals(response) || "true".equalsIgnoreCase(response); - Log.info("Location Detected: " + (cached ? "Inside mainland China" : "Outside mainland China")); - return cached; + String response = IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8); + boolean isChina = api.parser.test(response); + Log.info("Location Detected (" + api.name + " API): " + (isChina ? "Inside mainland China" : "Outside mainland China")); + return isChina; } } catch (Exception e) { - Log.debug("Location detection failed: " + e.getMessage()); + Log.debug(api.name + " API detection failed: " + e.getMessage()); + } + return null; + } + + private static class GeoApi { + final String name; + final String url; + final Predicate parser; + + GeoApi(String name, String url, Predicate parser) { + this.name = name; + this.url = url; + this.parser = parser; } - - cached = false; - return false; } public static void resetCache() { From b90ab472d2c0e13a6d125655e7dcf57d57ba4940 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:41:36 +0800 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=E7=AE=80=E5=8C=96=20API=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/LocationDetectUtil.java | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java index 61b064b..625cd15 100644 --- a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java +++ b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java @@ -5,67 +5,61 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; -import java.util.function.Predicate; public class LocationDetectUtil { private static Boolean cached = null; - - private static final List GEO_APIS = Arrays.asList( - new GeoApi("Kugou", "https://mips.kugou.com/check/iscn", - response -> "1".equals(response.trim()) || "true".equalsIgnoreCase(response.trim())), - new GeoApi("IP.SB", "https://api.ip.sb/geoip", - response -> response.contains("\"country_code\":\"CN\"") || response.contains("\"country_code\": \"CN\"")) - ); + + private static final String[][] GEO_APIS = { + {"Kugou", "https://mips.kugou.com/check/iscn"}, + {"IP.SB", "https://api.ip.sb/geoip"} + }; public static boolean isMainlandChina() { if (cached != null) { return cached; } - for (GeoApi api : GEO_APIS) { - Boolean result = tryApi(api); + for (String[] api : GEO_APIS) { + Boolean result = tryApi(api[0], api[1]); if (result != null) { cached = result; return cached; } } - // 所有 API 都失败,默认为 false cached = false; return false; } - private static Boolean tryApi(GeoApi api) { + private static Boolean tryApi(String name, String url) { try { - HttpURLConnection conn = (HttpURLConnection) new URL(api.url).openConnection(); + HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); - int code = conn.getResponseCode(); - if (code == 200) { + if (conn.getResponseCode() == 200) { String response = IOUtils.toString(conn.getInputStream(), StandardCharsets.UTF_8); - boolean isChina = api.parser.test(response); - Log.info("Location Detected (" + api.name + " API): " + (isChina ? "Inside mainland China" : "Outside mainland China")); + boolean isChina = parseResponse(response); + Log.info("Location Detected (" + name + " API): " + (isChina ? "Inside mainland China" : "Outside mainland China")); return isChina; } } catch (Exception e) { - Log.debug(api.name + " API detection failed: " + e.getMessage()); + Log.debug(name + " API detection failed: " + e.getMessage()); } return null; } - private static class GeoApi { - final String name; - final String url; - final Predicate parser; - - GeoApi(String name, String url, Predicate parser) { - this.name = name; - this.url = url; - this.parser = parser; + private static boolean parseResponse(String response) { + response = response.trim(); + // Kugou API 返回 "1" 或 "true" + if ("1".equals(response) || "true".equalsIgnoreCase(response)) { + return true; } + // IP.SB API 返回 JSON,检查 country_code + if (response.contains("\"country_code\":\"CN\"") || response.contains("\"country_code\": \"CN\"")) { + return true; + } + return false; } public static void resetCache() { From 75849a583a97c1a3aea6706ec6d6672d15e78653 Mon Sep 17 00:00:00 2001 From: WingChunWong Date: Thu, 5 Mar 2026 18:45:13 +0800 Subject: [PATCH 8/8] update --- src/main/java/i18nupdatemod/util/LocationDetectUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java index 625cd15..bd942b4 100644 --- a/src/main/java/i18nupdatemod/util/LocationDetectUtil.java +++ b/src/main/java/i18nupdatemod/util/LocationDetectUtil.java @@ -10,7 +10,7 @@ public class LocationDetectUtil { private static Boolean cached = null; private static final String[][] GEO_APIS = { - {"Kugou", "https://mips.kugou.com/check/iscn"}, + {"Kugou", "https://mips.kugou.com/check/iscn?&format=json"}, {"IP.SB", "https://api.ip.sb/geoip"} }; @@ -51,11 +51,11 @@ private static Boolean tryApi(String name, String url) { private static boolean parseResponse(String response) { response = response.trim(); - // Kugou API 返回 "1" 或 "true" - if ("1".equals(response) || "true".equalsIgnoreCase(response)) { + // Kugou API JSON: {"flag": 1} 或 {"flag": true} + if (response.contains("\"flag\":1") || response.contains("\"flag\": 1") ||response.contains("\"flag\":true") || response.contains("\"flag\": true")) { return true; } - // IP.SB API 返回 JSON,检查 country_code + // IP.SB API JSON: {"country_code": "CN"} if (response.contains("\"country_code\":\"CN\"") || response.contains("\"country_code\": \"CN\"")) { return true; }