From 2fdf684ee7198d7f896df4e1f536f3c213ea5ba3 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Mon, 28 Apr 2025 15:30:16 +0800 Subject: [PATCH 01/45] Fix https://github.com/2dust/v2rayNG/issues/4548 --- V2rayNG/app/src/main/assets/v2ray_config.json | 2 +- .../src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/src/main/assets/v2ray_config.json b/V2rayNG/app/src/main/assets/v2ray_config.json index 90abcee0..4f8c3d7e 100644 --- a/V2rayNG/app/src/main/assets/v2ray_config.json +++ b/V2rayNG/app/src/main/assets/v2ray_config.json @@ -97,7 +97,7 @@ } ], "routing": { - "domainStrategy": "IPIfNonMatch", + "domainStrategy": "AsIs", "rules": [] }, "dns": { diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index 3ba5f0a8..2e06f823 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -286,7 +286,7 @@ object V2rayConfigManager { v2rayConfig.routing.domainStrategy = MmkvManager.decodeSettingsString(AppConfig.PREF_ROUTING_DOMAIN_STRATEGY) - ?: "IPIfNonMatch" + ?: "AsIs" val rulesetItems = MmkvManager.decodeRoutingRulesets() rulesetItems?.forEach { key -> From 9bedfe8a7b0d49eb5cda9811a7b53f62a49980d2 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 30 Apr 2025 08:31:51 +0800 Subject: [PATCH 02/45] Bug fix https://github.com/2dust/v2rayNG/issues/4555 --- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/Hysteria2Fmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/WireguardFmt.kt | 2 +- .../app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/Hysteria2Fmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/Hysteria2Fmt.kt index dcc49f06..3b3dc88c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/Hysteria2Fmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/Hysteria2Fmt.kt @@ -25,7 +25,7 @@ object Hysteria2Fmt : FmtBase() { val config = ProfileItem.create(EConfigType.HYSTERIA2) val uri = URI(Utils.fixIllegalUrl(str)) - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() config.password = uri.userInfo diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt index 7a5ac437..172716c9 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt @@ -36,7 +36,7 @@ object ShadowsocksFmt : FmtBase() { if (uri.port <= 0) return null if (uri.userInfo.isNullOrEmpty()) return null - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt index 46046f48..6b727025 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt @@ -23,7 +23,7 @@ object SocksFmt : FmtBase() { if (uri.idnHost.isEmpty()) return null if (uri.port <= 0) return null - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt index 8b6c1dec..6ad0d71b 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt @@ -23,7 +23,7 @@ object TrojanFmt : FmtBase() { val config = ProfileItem.create(EConfigType.TROJAN) val uri = URI(Utils.fixIllegalUrl(str)) - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() config.password = uri.userInfo diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt index 2092843e..f5cf9fff 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt @@ -26,7 +26,7 @@ object VlessFmt : FmtBase() { if (uri.rawQuery.isNullOrEmpty()) return null val queryParam = getQueryParam(uri) - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() config.password = uri.userInfo diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt index e3a72e61..c733f3dc 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt @@ -151,7 +151,7 @@ object VmessFmt : FmtBase() { if (uri.rawQuery.isNullOrEmpty()) return null val queryParam = getQueryParam(uri) - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() config.password = uri.userInfo diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/WireguardFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/WireguardFmt.kt index 30a33577..8f1cec84 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/WireguardFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/WireguardFmt.kt @@ -25,7 +25,7 @@ object WireguardFmt : FmtBase() { if (uri.rawQuery.isNullOrEmpty()) return null val queryParam = getQueryParam(uri) - config.remarks = Utils.urlDecode(uri.fragment.orEmpty()) + config.remarks = Utils.urlDecode(uri.fragment.orEmpty()).let { if (it.isEmpty()) "none" else it } config.server = uri.idnHost config.serverPort = uri.port.toString() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt index cb364531..c528aeb2 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt @@ -216,7 +216,7 @@ object SettingsManager { * @return The ProfileItem. */ fun getServerViaRemarks(remarks: String?): ProfileItem? { - if (remarks == null) { + if (remarks.isNullOrEmpty()) { return null } val serverList = decodeServerList() From af04bbcf87789ce7525822a20ecc07a19adbc704 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 30 Apr 2025 14:35:48 +0800 Subject: [PATCH 03/45] up 1.10.1 --- V2rayNG/app/build.gradle.kts | 4 ++-- .../src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index 7478730e..82b9ef6e 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 650 - versionName = "1.10.0" + versionCode = 651 + versionName = "1.10.1" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index 2e06f823..8ef7a7b7 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -861,7 +861,7 @@ object V2rayConfigManager { EConfigType.VLESS -> VlessFmt.toOutbound(profileItem) EConfigType.TROJAN -> TrojanFmt.toOutbound(profileItem) EConfigType.WIREGUARD -> WireguardFmt.toOutbound(profileItem) - EConfigType.HYSTERIA2 -> Hysteria2Fmt.toOutbound(profileItem) + EConfigType.HYSTERIA2 -> null EConfigType.HTTP -> HttpFmt.toOutbound(profileItem) } } From 42c27a5e7ebc153ff82cf853c5f5de8cfb0a7cea Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 30 Apr 2025 14:48:59 +0800 Subject: [PATCH 04/45] Update hysteria --- hysteria | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hysteria b/hysteria index 245c6e9b..2adeec29 160000 --- a/hysteria +++ b/hysteria @@ -1 +1 @@ -Subproject commit 245c6e9bd17b1ef644f81fc4dafd0a1e1933da85 +Subproject commit 2adeec2900a7a0e3689f118580174cc528f9995a From 02e53ced50efd0654b52cfda749ae958eacf2870 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 30 Apr 2025 14:49:02 +0800 Subject: [PATCH 05/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index c53ff63a..bafb45ff 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit c53ff63a3be2583d4b90f6819dfb0266cada0e18 +Subproject commit bafb45ffcf3b5fb3c8bf8d3afb88aa95b1bc1613 From 71a5b6e4805e3ce66afaeaa88c423c54e596acf4 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 4 May 2025 17:49:02 +0800 Subject: [PATCH 06/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index bafb45ff..ae953fdc 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit bafb45ffcf3b5fb3c8bf8d3afb88aa95b1bc1613 +Subproject commit ae953fdc4da7766e50ffc553c213edd735f38af4 From 7f9cb8dfddf598d6d3f411e9b4943c5a94d881fd Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 7 May 2025 10:14:14 +0800 Subject: [PATCH 07/45] Check upgrade function is visible --- .../main/java/com/v2ray/ang/ui/AboutActivity.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt index 7c2ffdba..dfd26352 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt @@ -106,13 +106,13 @@ class AboutActivity : BaseActivity() { } //If it is the Google Play version, not be displayed within 1 days after update - if (Utils.isGoogleFlavor()) { - val lastUpdateTime = AppManagerUtil.getLastUpdateTime(this) - val currentTime = System.currentTimeMillis() - if ((currentTime - lastUpdateTime) < 1 * 24 * 60 * 60 * 1000L) { - binding.layoutCheckUpdate.visibility = View.GONE - } - } +// if (Utils.isGoogleFlavor()) { +// val lastUpdateTime = AppManagerUtil.getLastUpdateTime(this) +// val currentTime = System.currentTimeMillis() +// if ((currentTime - lastUpdateTime) < 1 * 24 * 60 * 60 * 1000L) { +// binding.layoutCheckUpdate.visibility = View.GONE +// } +// } binding.layoutCheckUpdate.setOnClickListener { checkForUpdates(binding.checkPreRelease.isChecked) } From be0a2506ceda592bea674fd76eaa0d2cd806287d Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 7 May 2025 10:44:19 +0800 Subject: [PATCH 08/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index ae953fdc..5cdcbc61 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit ae953fdc4da7766e50ffc553c213edd735f38af4 +Subproject commit 5cdcbc611f5df8f33cb2040de5369f368e099e3e From 3773962b64b300b3a40cdd620d6f0f37d8b52bcd Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Wed, 7 May 2025 10:47:50 +0800 Subject: [PATCH 09/45] up 1.10.2 --- V2rayNG/app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index 82b9ef6e..2e04a87f 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 651 - versionName = "1.10.1" + versionCode = 652 + versionName = "1.10.2" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') From d447adc97fc24472e4d32213c7f1490b72698785 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 11 May 2025 18:07:26 +0800 Subject: [PATCH 10/45] Fix https://github.com/2dust/v2rayN/discussions/7268 --- V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt | 2 +- V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt | 9 +++++---- .../main/java/com/v2ray/ang/handler/SpeedtestManager.kt | 7 +++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index 649b71c1..9e1b7918 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -103,7 +103,7 @@ object AppConfig { const val TG_CHANNEL_URL = "https://t.me/github_2dust" const val DELAY_TEST_URL = "https://www.gstatic.com/generate_204" const val DELAY_TEST_URL2 = "https://www.google.com/generate_204" - const val IP_API_Url = "https://api.ip.sb/geoip" + const val IP_API_URL = "https://speed.cloudflare.com/meta" /** DNS server addresses. */ const val DNS_PROXY = "1.1.1.1" diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt index 4d29ffc7..97814fbb 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/IPAPIInfo.kt @@ -2,10 +2,11 @@ package com.v2ray.ang.dto data class IPAPIInfo( var ip: String? = null, - var city: String? = null, - var region: String? = null, - var region_code: String? = null, + var clientIp: String? = null, + var ip_addr: String? = null, + var query: String? = null, var country: String? = null, var country_name: String? = null, - var country_code: String? = null + var country_code: String? = null, + var countryCode: String? = null ) \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SpeedtestManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SpeedtestManager.kt index 99898a3a..e547c378 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SpeedtestManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SpeedtestManager.kt @@ -168,10 +168,13 @@ object SpeedtestManager { fun getRemoteIPInfo(): String? { val httpPort = SettingsManager.getHttpPort() - var content = HttpUtil.getUrlContent(AppConfig.IP_API_Url, 5000, httpPort) ?: return null + var content = HttpUtil.getUrlContent(AppConfig.IP_API_URL, 5000, httpPort) ?: return null var ipInfo = JsonUtil.fromJson(content, IPAPIInfo::class.java) ?: return null - return "(${ipInfo.country_code}) ${ipInfo.ip}" + var ip = ipInfo.ip ?: ipInfo.clientIp ?: ipInfo.ip_addr ?: ipInfo.query + var country = ipInfo.country_code ?: ipInfo.country ?: ipInfo.countryCode + + return "(${country ?: "unknown"}) $ip" } /** From 4a87549fa76f6a08c8aba408d1e12d25d7350c44 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 15 May 2025 10:58:52 +0800 Subject: [PATCH 11/45] Update README.md --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 83214e02..4f068ffb 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,6 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-cor [![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayNG/latest/total?logo=github)](https://github.com/2dust/v2rayNG/releases) [![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/v2rayn) - -Get it on Google Play - - ### Telegram Channel [github_2dust](https://t.me/github_2dust) From f22454da5dd52399ae19f525436b1ac8628b0fe0 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 17 May 2025 11:48:15 +0800 Subject: [PATCH 12/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index 5cdcbc61..ddcaecad 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit 5cdcbc611f5df8f33cb2040de5369f368e099e3e +Subproject commit ddcaecad0ae2f0816b33b8a56d1e36fce4efcae4 From 55bc2bf934eff286203545f66aa9e32c7216b308 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 17 May 2025 12:01:34 +0800 Subject: [PATCH 13/45] up 1.10.3 --- V2rayNG/app/build.gradle.kts | 4 ++-- V2rayNG/gradle/libs.versions.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index 2e04a87f..f2c34017 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 652 - versionName = "1.10.2" + versionCode = 653 + versionName = "1.10.3" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') diff --git a/V2rayNG/gradle/libs.versions.toml b/V2rayNG/gradle/libs.versions.toml index 2c4a5d98..8c46149e 100644 --- a/V2rayNG/gradle/libs.versions.toml +++ b/V2rayNG/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.9.2" +agp = "8.9.3" desugarJdkLibs = "2.1.5" gradleLicensePlugin = "0.9.8" kotlin = "2.1.20" @@ -21,7 +21,7 @@ toasty = "1.5.2" editorkit = "2.9.0" core = "3.5.3" workRuntimeKtx = "2.10.1" -lifecycleViewmodelKtx = "2.8.7" +lifecycleViewmodelKtx = "2.9.0" multidex = "2.0.1" mockitoMockitoInline = "5.2.0" flexbox = "3.0.0" From e6f260da76e8843668b0bb031c1e7c991fc57902 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 23 May 2025 14:34:55 +0800 Subject: [PATCH 14/45] Added the check update entry to the main interface drawer menu https://github.com/2dust/v2rayNG/issues/4599 --- V2rayNG/app/src/main/AndroidManifest.xml | 3 + .../java/com/v2ray/ang/ui/AboutActivity.kt | 48 ----------- .../com/v2ray/ang/ui/CheckUpdateActivity.kt | 70 ++++++++++++++++ .../java/com/v2ray/ang/ui/MainActivity.kt | 1 + .../src/main/res/layout/activity_about.xml | 43 ---------- .../main/res/layout/activity_check_update.xml | 82 +++++++++++++++++++ V2rayNG/app/src/main/res/menu/menu_drawer.xml | 4 + .../app/src/main/res/values-ar/strings.xml | 1 + .../app/src/main/res/values-bn/strings.xml | 1 + .../src/main/res/values-bqi-rIR/strings.xml | 1 + .../app/src/main/res/values-fa/strings.xml | 1 + .../app/src/main/res/values-ru/strings.xml | 1 + .../app/src/main/res/values-vi/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + V2rayNG/app/src/main/res/values/strings.xml | 1 + 16 files changed, 169 insertions(+), 91 deletions(-) create mode 100644 V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt create mode 100644 V2rayNG/app/src/main/res/layout/activity_check_update.xml diff --git a/V2rayNG/app/src/main/AndroidManifest.xml b/V2rayNG/app/src/main/AndroidManifest.xml index 4ff08af9..00e4b747 100644 --- a/V2rayNG/app/src/main/AndroidManifest.xml +++ b/V2rayNG/app/src/main/AndroidManifest.xml @@ -144,6 +144,9 @@ + diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt index dfd26352..1931cb45 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/AboutActivity.kt @@ -5,28 +5,21 @@ import android.content.Intent import android.os.Build import android.os.Bundle import android.util.Log -import android.view.View import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.content.FileProvider -import androidx.lifecycle.lifecycleScope import com.tencent.mmkv.MMKV import com.v2ray.ang.AppConfig import com.v2ray.ang.BuildConfig import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivityAboutBinding -import com.v2ray.ang.dto.CheckUpdateResult import com.v2ray.ang.extension.toast import com.v2ray.ang.extension.toastError import com.v2ray.ang.extension.toastSuccess import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.handler.SpeedtestManager -import com.v2ray.ang.handler.UpdateCheckerManager -import com.v2ray.ang.util.AppManagerUtil import com.v2ray.ang.util.Utils import com.v2ray.ang.util.ZipUtil -import kotlinx.coroutines.launch import java.io.File import java.text.SimpleDateFormat import java.util.Locale @@ -105,23 +98,6 @@ class AboutActivity : BaseActivity() { } } - //If it is the Google Play version, not be displayed within 1 days after update -// if (Utils.isGoogleFlavor()) { -// val lastUpdateTime = AppManagerUtil.getLastUpdateTime(this) -// val currentTime = System.currentTimeMillis() -// if ((currentTime - lastUpdateTime) < 1 * 24 * 60 * 60 * 1000L) { -// binding.layoutCheckUpdate.visibility = View.GONE -// } -// } - binding.layoutCheckUpdate.setOnClickListener { - checkForUpdates(binding.checkPreRelease.isChecked) - } - - binding.checkPreRelease.setOnCheckedChangeListener { _, isChecked -> - MmkvManager.encodeSettings(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, isChecked) - } - binding.checkPreRelease.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, false) - binding.layoutSoureCcode.setOnClickListener { Utils.openUri(this, AppConfig.APP_URL) } @@ -222,28 +198,4 @@ class AboutActivity : BaseActivity() { } } } - - private fun checkForUpdates(includePreRelease: Boolean) { - lifecycleScope.launch { - val result = UpdateCheckerManager.checkForUpdate(includePreRelease) - if (result.hasUpdate) { - showUpdateDialog(result) - } else { - toast(R.string.update_already_latest_version) - } - } - } - - private fun showUpdateDialog(result: CheckUpdateResult) { - AlertDialog.Builder(this) - .setTitle(getString(R.string.update_new_version_found, result.latestVersion)) - .setMessage(result.releaseNotes) - .setPositiveButton(R.string.update_now) { _, _ -> - result.downloadUrl?.let { - Utils.openUri(this, it) - } - } - .setNegativeButton(android.R.string.cancel, null) - .show() - } } \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt new file mode 100644 index 00000000..8f464a49 --- /dev/null +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt @@ -0,0 +1,70 @@ +package com.v2ray.ang.ui + +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope +import com.v2ray.ang.AppConfig +import com.v2ray.ang.BuildConfig +import com.v2ray.ang.R +import com.v2ray.ang.databinding.ActivityCheckUpdateBinding +import com.v2ray.ang.dto.CheckUpdateResult +import com.v2ray.ang.extension.toast +import com.v2ray.ang.extension.toastSuccess +import com.v2ray.ang.handler.MmkvManager +import com.v2ray.ang.handler.SpeedtestManager +import com.v2ray.ang.handler.UpdateCheckerManager +import com.v2ray.ang.util.Utils +import kotlinx.coroutines.launch + +class CheckUpdateActivity : BaseActivity() { + + private val binding by lazy { ActivityCheckUpdateBinding.inflate(layoutInflater) } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(binding.root) + + title = getString(R.string.update_check_for_update) + + binding.layoutCheckUpdate.setOnClickListener { + checkForUpdates(binding.checkPreRelease.isChecked) + } + + binding.checkPreRelease.setOnCheckedChangeListener { _, isChecked -> + MmkvManager.encodeSettings(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, isChecked) + } + binding.checkPreRelease.isChecked = MmkvManager.decodeSettingsBool(AppConfig.PREF_CHECK_UPDATE_PRE_RELEASE, false) + + "v${BuildConfig.VERSION_NAME} (${SpeedtestManager.getLibVersion()})".also { + binding.tvVersion.text = it + } + + checkForUpdates(binding.checkPreRelease.isChecked) + } + + private fun checkForUpdates(includePreRelease: Boolean) { + toast(R.string.update_checking_for_update) + + lifecycleScope.launch { + val result = UpdateCheckerManager.checkForUpdate(includePreRelease) + if (result.hasUpdate) { + showUpdateDialog(result) + } else { + toastSuccess(R.string.update_already_latest_version) + } + } + } + + private fun showUpdateDialog(result: CheckUpdateResult) { + AlertDialog.Builder(this) + .setTitle(getString(R.string.update_new_version_found, result.latestVersion)) + .setMessage(result.releaseNotes) + .setPositiveButton(R.string.update_now) { _, _ -> + result.downloadUrl?.let { + Utils.openUri(this, it) + } + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } +} \ No newline at end of file diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt index bb9abc68..0c7584d8 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/MainActivity.kt @@ -685,6 +685,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList R.id.promotion -> Utils.openUri(this, "${Utils.decode(AppConfig.APP_PROMOTION_URL)}?t=${System.currentTimeMillis()}") R.id.logcat -> startActivity(Intent(this, LogcatActivity::class.java)) + R.id.check_for_update -> startActivity(Intent(this, CheckUpdateActivity::class.java)) R.id.about -> startActivity(Intent(this, AboutActivity::class.java)) } diff --git a/V2rayNG/app/src/main/res/layout/activity_about.xml b/V2rayNG/app/src/main/res/layout/activity_about.xml index d4596963..62053559 100644 --- a/V2rayNG/app/src/main/res/layout/activity_about.xml +++ b/V2rayNG/app/src/main/res/layout/activity_about.xml @@ -111,49 +111,6 @@ android:orientation="vertical" android:paddingTop="@dimen/padding_spacing_dp16"> - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/V2rayNG/app/src/main/res/menu/menu_drawer.xml b/V2rayNG/app/src/main/res/menu/menu_drawer.xml index c134759d..4e204e62 100644 --- a/V2rayNG/app/src/main/res/menu/menu_drawer.xml +++ b/V2rayNG/app/src/main/res/menu/menu_drawer.xml @@ -35,6 +35,10 @@ android:id="@+id/logcat" android:icon="@drawable/ic_logcat_24dp" android:title="@string/title_logcat" /> + New version found: %s Update now Check Pre-release + Checking for update… رمز استجابة سريعة (QRcode) diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index 4520f2e2..bd7c492f 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -315,6 +315,7 @@ New version found: %s Update now Check Pre-release + Checking for update… QR কোড diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 45dc5158..73a89fa3 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -324,6 +324,7 @@ نوسخه نۊ ن جوست: %s سکو ورۊ رسۊوی کۊنین واجۊری نوسخه یل پؽش ز تیجنیڌن + Checking for update… QRcode diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index 1341f182..b5455fbb 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -321,6 +321,7 @@ نسخه جدید پیدا شد: %s اکنون به روز رسانی کنید بررسی نسخه پیش از انتشار + Checking for update… QRcode diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index cc56161b..615a33d8 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -323,6 +323,7 @@ Найдена новая версия: %s Обновить Искать предварительный выпуск + Checking for update… QR-код diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index ac247ce0..72cdee64 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -317,6 +317,7 @@ New version found: %s Update now Check Pre-release + Checking for update… Xuất ra mã QR (Chụp màn hình để lưu) diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 38303d49..a0aa7a5a 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -315,6 +315,7 @@ 发现新版本: %s 立即更新 检查 Pre-release + 正在检查更新中… 二维码 diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 959312e9..e655e18f 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -315,6 +315,7 @@ 發現新版本: %s 立即更新 檢查 Pre-release + 正在檢查更新中… QR Code diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 069dcfc7..39defc59 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -325,6 +325,7 @@ New version found: %s Update now Check Pre-release + Checking for update… QRcode From f3f2b7fab51ef4aeaa92396c67849c016f57cb34 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 23 May 2025 16:17:38 +0800 Subject: [PATCH 15/45] Added delete function to subscription group list, secondary confirmation with settings --- .../java/com/v2ray/ang/ui/SubEditActivity.kt | 30 ++-- .../v2ray/ang/ui/SubSettingRecyclerAdapter.kt | 35 ++++ .../res/layout/item_recycler_sub_setting.xml | 165 +++++++++++------- 3 files changed, 161 insertions(+), 69 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt index fff8f42d..f85382f1 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubEditActivity.kt @@ -6,6 +6,7 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope +import com.v2ray.ang.AppConfig import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivitySubEditBinding import com.v2ray.ang.dto.SubscriptionItem @@ -109,19 +110,28 @@ class SubEditActivity : BaseActivity() { */ private fun deleteServer(): Boolean { if (editSubId.isNotEmpty()) { - AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) - .setPositiveButton(android.R.string.ok) { _, _ -> - lifecycleScope.launch(Dispatchers.IO) { - MmkvManager.removeSubscription(editSubId) - launch(Dispatchers.Main) { - finish() + if (MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE) == true) { + AlertDialog.Builder(this).setMessage(R.string.del_config_comfirm) + .setPositiveButton(android.R.string.ok) { _, _ -> + lifecycleScope.launch(Dispatchers.IO) { + MmkvManager.removeSubscription(editSubId) + launch(Dispatchers.Main) { + finish() + } } } + .setNegativeButton(android.R.string.cancel) { _, _ -> + // do nothing + } + .show() + } else { + lifecycleScope.launch(Dispatchers.IO) { + MmkvManager.removeSubscription(editSubId) + launch(Dispatchers.Main) { + finish() + } } - .setNegativeButton(android.R.string.cancel) { _, _ -> - // do nothing - } - .show() + } } return true } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt index bb364c1b..cc2d5404 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SubSettingRecyclerAdapter.kt @@ -8,6 +8,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.v2ray.ang.AppConfig import com.v2ray.ang.R @@ -20,6 +21,8 @@ import com.v2ray.ang.helper.ItemTouchHelperAdapter import com.v2ray.ang.helper.ItemTouchHelperViewHolder import com.v2ray.ang.util.QRCodeDecoder import com.v2ray.ang.util.Utils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView.Adapter(), ItemTouchHelperAdapter { @@ -46,6 +49,10 @@ class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView ) } + holder.itemSubSettingBinding.layoutRemove.setOnClickListener { + removeSubscription(subId, position) + } + holder.itemSubSettingBinding.chkEnable.setOnCheckedChangeListener { it, isChecked -> if (!it.isPressed) return@setOnCheckedChangeListener subItem.enabled = isChecked @@ -54,9 +61,11 @@ class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView } if (TextUtils.isEmpty(subItem.url)) { + holder.itemSubSettingBinding.layoutUrl.visibility = View.GONE holder.itemSubSettingBinding.layoutShare.visibility = View.INVISIBLE holder.itemSubSettingBinding.chkEnable.visibility = View.INVISIBLE } else { + holder.itemSubSettingBinding.layoutUrl.visibility = View.VISIBLE holder.itemSubSettingBinding.layoutShare.visibility = View.VISIBLE holder.itemSubSettingBinding.chkEnable.visibility = View.VISIBLE holder.itemSubSettingBinding.layoutShare.setOnClickListener { @@ -90,6 +99,32 @@ class SubSettingRecyclerAdapter(val activity: SubSettingActivity) : RecyclerView } } + private fun removeSubscription(subId: String, position: Int) { + if (MmkvManager.decodeSettingsBool(AppConfig.PREF_CONFIRM_REMOVE) == true) { + AlertDialog.Builder(mActivity).setMessage(R.string.del_config_comfirm) + .setPositiveButton(android.R.string.ok) { _, _ -> + removeSubscriptionSub(subId, position) + } + .setNegativeButton(android.R.string.cancel) { _, _ -> + //do noting + } + .show() + } else { + removeSubscriptionSub(subId, position) + } + } + + private fun removeSubscriptionSub(subId: String, position: Int) { + mActivity.lifecycleScope.launch(Dispatchers.IO) { + MmkvManager.removeSubscription(subId) + launch(Dispatchers.Main) { + notifyItemRemoved(position) + notifyItemRangeChanged(position, mActivity.subscriptions.size) + mActivity.refreshData() + } + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder { return MainViewHolder( ItemRecyclerSubSettingBinding.inflate( diff --git a/V2rayNG/app/src/main/res/layout/item_recycler_sub_setting.xml b/V2rayNG/app/src/main/res/layout/item_recycler_sub_setting.xml index aa8d9812..47c2b4c5 100644 --- a/V2rayNG/app/src/main/res/layout/item_recycler_sub_setting.xml +++ b/V2rayNG/app/src/main/res/layout/item_recycler_sub_setting.xml @@ -15,97 +15,144 @@ android:clickable="true" android:focusable="true" android:gravity="center" - android:nextFocusRight="@+id/layout_edit" + android:nextFocusRight="@+id/layout_share" android:orientation="horizontal" android:padding="@dimen/padding_spacing_dp8"> - - - - - - - - + android:orientation="vertical"> + android:paddingStart="@dimen/padding_spacing_dp8"> - + + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + - + + android:orientation="horizontal" + android:paddingStart="@dimen/padding_spacing_dp8" + android:paddingEnd="@dimen/padding_spacing_dp8"> - + + + + + + + android:layout_marginTop="@dimen/padding_spacing_dp8" + android:orientation="horizontal"> + + + + + + - + \ No newline at end of file From 7e6b1c247bc6e5b9bf33f9acfee74cf8b9a05580 Mon Sep 17 00:00:00 2001 From: Pk-web6936 <202365630+Pk-web6936@users.noreply.github.com> Date: Fri, 23 May 2025 12:28:03 +0330 Subject: [PATCH 16/45] Update kotlin version to 2.1.21 (#4583) * Update kotlin version to 2.1.21 * Update kotlin version to 2.1.21 --- README.md | 2 +- V2rayNG/gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f068ffb..4bd6f8ec 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A V2Ray client for Android, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) [![API](https://img.shields.io/badge/API-21%2B-yellow.svg?style=flat)](https://developer.android.com/about/versions/lollipop) -[![Kotlin Version](https://img.shields.io/badge/Kotlin-2.1.20-blue.svg)](https://kotlinlang.org) +[![Kotlin Version](https://img.shields.io/badge/Kotlin-2.1.21-blue.svg)](https://kotlinlang.org) [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayNG)](https://github.com/2dust/v2rayNG/commits/master) [![CodeFactor](https://www.codefactor.io/repository/github/2dust/v2rayng/badge)](https://www.codefactor.io/repository/github/2dust/v2rayng) [![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayNG/latest/total?logo=github)](https://github.com/2dust/v2rayNG/releases) diff --git a/V2rayNG/gradle/libs.versions.toml b/V2rayNG/gradle/libs.versions.toml index 8c46149e..3a935aaa 100644 --- a/V2rayNG/gradle/libs.versions.toml +++ b/V2rayNG/gradle/libs.versions.toml @@ -2,7 +2,7 @@ agp = "8.9.3" desugarJdkLibs = "2.1.5" gradleLicensePlugin = "0.9.8" -kotlin = "2.1.20" +kotlin = "2.1.21" coreKtx = "1.16.0" junit = "4.13.2" junitVersion = "1.2.1" From d910b93525ec589349b6b387c06ce25ad2948a94 Mon Sep 17 00:00:00 2001 From: solokot Date: Sun, 25 May 2025 05:12:29 +0300 Subject: [PATCH 17/45] Update Russian translation (#4611) --- V2rayNG/app/src/main/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 615a33d8..9b5e39f6 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -323,7 +323,7 @@ Найдена новая версия: %s Обновить Искать предварительный выпуск - Checking for update… + Проверка обновления… QR-код From 822c1de79c42854f555ca3de0e248036f16d72ae Mon Sep 17 00:00:00 2001 From: Hossein Abaspanah <63148255+hosseinabaspanah@users.noreply.github.com> Date: Sun, 25 May 2025 05:42:39 +0330 Subject: [PATCH 18/45] Update Luri Bakhtiari translation (#4610) --- V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 73a89fa3..4f129d9e 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -324,7 +324,7 @@ نوسخه نۊ ن جوست: %s سکو ورۊ رسۊوی کۊنین واجۊری نوسخه یل پؽش ز تیجنیڌن - Checking for update… + ورۊ رسۊوی ن هونی واجۊری اکونه... QRcode From 90ed02804cb03e2a61d5396ecc6dcf7bdbea9b0b Mon Sep 17 00:00:00 2001 From: Pk-web6936 <202365630+Pk-web6936@users.noreply.github.com> Date: Sun, 25 May 2025 05:42:45 +0330 Subject: [PATCH 19/45] Update Persian translate (#4607) --- V2rayNG/app/src/main/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index b5455fbb..16bbd4ff 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -321,7 +321,7 @@ نسخه جدید پیدا شد: %s اکنون به روز رسانی کنید بررسی نسخه پیش از انتشار - Checking for update… + در حال بررسی برای به‌روزرسانی… QRcode From 69c5bbfd3d7511e599836ea7716941f041f8b09a Mon Sep 17 00:00:00 2001 From: Hossein Abaspanah <63148255+hosseinabaspanah@users.noreply.github.com> Date: Sun, 25 May 2025 05:42:52 +0330 Subject: [PATCH 20/45] Improved Luri Bakhtiari Translation (#4600) --- V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 4f129d9e..41e81fbb 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -148,7 +148,7 @@ سامووا Mux ر وندن Mux - زل تر، ٱما گاشڌ منپیز زی قت بۊ بارت دؽوۉداری، TCP، UDP و QUIC ن ای لم سفارشی کۊنین. + زل تر، ٱما گاشڌ منپیز زی قت بۊ\nمخزن ترافیک TCP وا 8 منپیز پؽش فرز، بارت دؽوۉداری UDP وو QUIC ن ای لم سفارشی کۊنین. منپیزا TCP (تلایه منجا 1-1024) منپیزا XUDP (تلایه منجا 1-1024) دؽوۉداری QUIC من تۊنل mux From aa47fba20d583c9970fd03ee32f95ffe87b36bdc Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 25 May 2025 11:06:15 +0800 Subject: [PATCH 21/45] up 1.10.4 --- V2rayNG/app/build.gradle.kts | 4 ++-- V2rayNG/gradle/libs.versions.toml | 2 +- V2rayNG/gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index f2c34017..c66250d9 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 653 - versionName = "1.10.3" + versionCode = 654 + versionName = "1.10.4" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') diff --git a/V2rayNG/gradle/libs.versions.toml b/V2rayNG/gradle/libs.versions.toml index 3a935aaa..97e74cbf 100644 --- a/V2rayNG/gradle/libs.versions.toml +++ b/V2rayNG/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.9.3" +agp = "8.10.0" desugarJdkLibs = "2.1.5" gradleLicensePlugin = "0.9.8" kotlin = "2.1.21" diff --git a/V2rayNG/gradle/wrapper/gradle-wrapper.properties b/V2rayNG/gradle/wrapper/gradle-wrapper.properties index f221584f..b2eeb9db 100644 --- a/V2rayNG/gradle/wrapper/gradle-wrapper.properties +++ b/V2rayNG/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Nov 14 12:42:51 BDT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f305e26a395650301e5565d95ffb1d3199e846ed Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 31 May 2025 11:12:57 +0800 Subject: [PATCH 22/45] Fix the parsing problem of non-English domain https://github.com/2dust/v2rayNG/issues/4626 --- .../main/java/com/v2ray/ang/fmt/FmtBase.kt | 5 ++- .../main/java/com/v2ray/ang/fmt/HttpFmt.kt | 2 +- .../java/com/v2ray/ang/fmt/ShadowsocksFmt.kt | 2 +- .../main/java/com/v2ray/ang/fmt/SocksFmt.kt | 2 +- .../main/java/com/v2ray/ang/fmt/TrojanFmt.kt | 2 +- .../main/java/com/v2ray/ang/fmt/VlessFmt.kt | 2 +- .../main/java/com/v2ray/ang/fmt/VmessFmt.kt | 2 +- .../com/v2ray/ang/handler/AngConfigManager.kt | 2 +- .../main/java/com/v2ray/ang/util/HttpUtil.kt | 32 ++++++++++++++++--- .../test/java/com/v2ray/ang/HttpUtilTest.kt | 12 +++---- 10 files changed, 45 insertions(+), 18 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt index cc9a70ff..873eaa6a 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt @@ -4,6 +4,7 @@ import com.v2ray.ang.AppConfig import com.v2ray.ang.dto.NetworkType import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.extension.isNotNullEmpty +import com.v2ray.ang.util.HttpUtil import com.v2ray.ang.util.Utils import java.net.URI @@ -149,6 +150,8 @@ open class FmtBase { return dicQuery } - + fun getServerAddress(profileItem: ProfileItem): String { + return HttpUtil.toIdnDomain(profileItem.server.orEmpty()) + } } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/HttpFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/HttpFmt.kt index 73def17e..8c641f24 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/HttpFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/HttpFmt.kt @@ -17,7 +17,7 @@ object HttpFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.HTTP) outboundBean?.settings?.servers?.first()?.let { server -> - server.address = profileItem.server.orEmpty() + server.address = getServerAddress(profileItem) server.port = profileItem.serverPort.orEmpty().toInt() if (profileItem.username.isNotNullEmpty()) { val socksUsersBean = OutboundBean.OutSettingsBean.ServersBean.SocksUsersBean() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt index 172716c9..87ba74f8 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/ShadowsocksFmt.kt @@ -135,7 +135,7 @@ object ShadowsocksFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.SHADOWSOCKS) outboundBean?.settings?.servers?.first()?.let { server -> - server.address = profileItem.server.orEmpty() + server.address = getServerAddress(profileItem) server.port = profileItem.serverPort.orEmpty().toInt() server.password = profileItem.password server.method = profileItem.method diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt index 6b727025..30bc08e4 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/SocksFmt.kt @@ -64,7 +64,7 @@ object SocksFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.SOCKS) outboundBean?.settings?.servers?.first()?.let { server -> - server.address = profileItem.server.orEmpty() + server.address = getServerAddress(profileItem) server.port = profileItem.serverPort.orEmpty().toInt() if (profileItem.username.isNotNullEmpty()) { val socksUsersBean = OutboundBean.OutSettingsBean.ServersBean.SocksUsersBean() diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt index 6ad0d71b..446ef99c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/TrojanFmt.kt @@ -64,7 +64,7 @@ object TrojanFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.TROJAN) outboundBean?.settings?.servers?.first()?.let { server -> - server.address = profileItem.server.orEmpty() + server.address = getServerAddress(profileItem) server.port = profileItem.serverPort.orEmpty().toInt() server.password = profileItem.password server.flow = profileItem.flow diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt index f5cf9fff..9242f0ec 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VlessFmt.kt @@ -60,7 +60,7 @@ object VlessFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.VLESS) outboundBean?.settings?.vnext?.first()?.let { vnext -> - vnext.address = profileItem.server.orEmpty() + vnext.address = getServerAddress(profileItem) vnext.port = profileItem.serverPort.orEmpty().toInt() vnext.users[0].id = profileItem.password.orEmpty() vnext.users[0].encryption = profileItem.method diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt index c733f3dc..4201f4dc 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/VmessFmt.kt @@ -172,7 +172,7 @@ object VmessFmt : FmtBase() { val outboundBean = V2rayConfigManager.createInitOutbound(EConfigType.VMESS) outboundBean?.settings?.vnext?.first()?.let { vnext -> - vnext.address = profileItem.server.orEmpty() + vnext.address = getServerAddress(profileItem) vnext.port = profileItem.serverPort.orEmpty().toInt() vnext.users[0].id = profileItem.password.orEmpty() vnext.users[0].security = profileItem.method diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt index 1dcd1276..d24ae0c2 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/AngConfigManager.kt @@ -415,7 +415,7 @@ object AngConfigManager { if (!it.second.enabled) { return 0 } - val url = HttpUtil.idnToASCII(it.second.url) + val url = HttpUtil.toIdnUrl(it.second.url) if (!Utils.isValidUrl(url)) { return 0 } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/util/HttpUtil.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/util/HttpUtil.kt index 9e08f663..7172728e 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/util/HttpUtil.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/util/HttpUtil.kt @@ -18,12 +18,14 @@ import java.net.URL object HttpUtil { /** - * Converts a URL string to its ASCII representation. + * Converts the domain part of a URL string to its IDN (Punycode, ASCII Compatible Encoding) format. * - * @param str The URL string to convert. - * @return The ASCII representation of the URL. + * For example, a URL like "https://例子.中国/path" will be converted to "https://xn--fsqu00a.xn--fiqs8s/path". + * + * @param str The URL string to convert (can contain non-ASCII characters in the domain). + * @return The URL string with the domain part converted to ASCII-compatible (Punycode) format. */ - fun idnToASCII(str: String): String { + fun toIdnUrl(str: String): String { val url = URL(str) val host = url.host val asciiHost = IDN.toASCII(url.host, IDN.ALLOW_UNASSIGNED) @@ -34,6 +36,28 @@ object HttpUtil { } } + /** + * Converts a Unicode domain name to its IDN (Punycode, ASCII Compatible Encoding) format. + * If the input is an IP address or already an ASCII domain, returns the original string. + * + * @param domain The domain string to convert (can include non-ASCII internationalized characters). + * @return The domain in ASCII-compatible (Punycode) format, or the original string if input is an IP or already ASCII. + */ + fun toIdnDomain(domain: String): String { + // Return as is if it's a pure IP address (IPv4 or IPv6) + if (Utils.isPureIpAddress(domain)) { + return domain + } + + // Return as is if already ASCII (English domain or already punycode) + if (domain.all { it.code < 128 }) { + return domain + } + + // Otherwise, convert to ASCII using IDN + return IDN.toASCII(domain, IDN.ALLOW_UNASSIGNED) + } + /** * Resolves a hostname to an IP address, returns original input if it's already an IP * diff --git a/V2rayNG/app/src/test/java/com/v2ray/ang/HttpUtilTest.kt b/V2rayNG/app/src/test/java/com/v2ray/ang/HttpUtilTest.kt index 207215e5..07d87f4d 100644 --- a/V2rayNG/app/src/test/java/com/v2ray/ang/HttpUtilTest.kt +++ b/V2rayNG/app/src/test/java/com/v2ray/ang/HttpUtilTest.kt @@ -10,31 +10,31 @@ class HttpUtilTest { fun testIdnToASCII() { // Regular URL remains unchanged val regularUrl = "https://example.com/path" - assertEquals(regularUrl, HttpUtil.idnToASCII(regularUrl)) + assertEquals(regularUrl, HttpUtil.toIdnUrl(regularUrl)) // Non-ASCII URL converts to ASCII (Punycode) val nonAsciiUrl = "https://例子.测试/path" val expectedNonAscii = "https://xn--fsqu00a.xn--0zwm56d/path" - assertEquals(expectedNonAscii, HttpUtil.idnToASCII(nonAsciiUrl)) + assertEquals(expectedNonAscii, HttpUtil.toIdnUrl(nonAsciiUrl)) // Mixed URL only converts the host part val mixedUrl = "https://例子.com/测试" val expectedMixed = "https://xn--fsqu00a.com/测试" - assertEquals(expectedMixed, HttpUtil.idnToASCII(mixedUrl)) + assertEquals(expectedMixed, HttpUtil.toIdnUrl(mixedUrl)) // URL with Basic Authentication using regular domain val basicAuthUrl = "https://user:password@example.com/path" - assertEquals(basicAuthUrl, HttpUtil.idnToASCII(basicAuthUrl)) + assertEquals(basicAuthUrl, HttpUtil.toIdnUrl(basicAuthUrl)) // URL with Basic Authentication using non-ASCII domain val basicAuthNonAscii = "https://user:password@例子.测试/path" val expectedBasicAuthNonAscii = "https://user:password@xn--fsqu00a.xn--0zwm56d/path" - assertEquals(expectedBasicAuthNonAscii, HttpUtil.idnToASCII(basicAuthNonAscii)) + assertEquals(expectedBasicAuthNonAscii, HttpUtil.toIdnUrl(basicAuthNonAscii)) // URL with non-ASCII username and password val nonAsciiAuth = "https://用户:密码@example.com/path" // Basic auth credentials should remain unchanged as they're percent-encoded separately - assertEquals(nonAsciiAuth, HttpUtil.idnToASCII(nonAsciiAuth)) + assertEquals(nonAsciiAuth, HttpUtil.toIdnUrl(nonAsciiAuth)) } From 9d1f98ff34c2e085389357c500e2ce22987cae9e Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 31 May 2025 14:03:52 +0800 Subject: [PATCH 23/45] Fix non-English domain https://github.com/2dust/v2rayNG/issues/4626 https://github.com/2dust/v2rayNG/commit/f305e26a395650301e5565d95ffb1d3199e846ed --- V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt index 873eaa6a..ec2d7801 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt @@ -27,7 +27,7 @@ open class FmtBase { val url = String.format( "%s@%s:%s", Utils.urlEncode(userInfo ?: ""), - Utils.getIpv6Address(config.server), + Utils.getIpv6Address(HttpUtil.toIdnDomain(config.server.orEmpty())), config.serverPort ) From 3ead542e2b64851caa6893af004fb3bf5d351be6 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 7 Jun 2025 11:20:37 +0800 Subject: [PATCH 24/45] VPN bypass LAN By default --- .../app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt | 2 +- V2rayNG/app/src/main/res/xml/pref_settings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt index c528aeb2..a488e593 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt @@ -159,7 +159,7 @@ object SettingsManager { * @return True if bypassing LAN, false otherwise. */ fun routingRulesetsBypassLan(): Boolean { - val vpnBypassLan = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_BYPASS_LAN) ?: "0" + val vpnBypassLan = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_BYPASS_LAN) ?: "1" if (vpnBypassLan == "1") { return true } else if (vpnBypassLan == "2") { diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index 75cad848..cbfbb932 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -56,7 +56,7 @@ android:title="@string/title_pref_vpn_dns" /> Date: Sat, 7 Jun 2025 11:20:41 +0800 Subject: [PATCH 25/45] Update libs.versions.toml --- V2rayNG/gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/V2rayNG/gradle/libs.versions.toml b/V2rayNG/gradle/libs.versions.toml index 97e74cbf..5bdd1236 100644 --- a/V2rayNG/gradle/libs.versions.toml +++ b/V2rayNG/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.10.0" +agp = "8.10.1" desugarJdkLibs = "2.1.5" gradleLicensePlugin = "0.9.8" kotlin = "2.1.21" @@ -7,7 +7,7 @@ coreKtx = "1.16.0" junit = "4.13.2" junitVersion = "1.2.1" espressoCore = "3.6.1" -appcompat = "1.7.0" +appcompat = "1.7.1" material = "1.12.0" activity = "1.10.1" constraintlayout = "2.2.1" @@ -21,7 +21,7 @@ toasty = "1.5.2" editorkit = "2.9.0" core = "3.5.3" workRuntimeKtx = "2.10.1" -lifecycleViewmodelKtx = "2.9.0" +lifecycleViewmodelKtx = "2.9.1" multidex = "2.0.1" mockitoMockitoInline = "5.2.0" flexbox = "3.0.0" From ea088376ac78ee81cd8552c1da71da78b33016fd Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 8 Jun 2025 09:25:46 +0800 Subject: [PATCH 26/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index ddcaecad..a031a553 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit ddcaecad0ae2f0816b33b8a56d1e36fce4efcae4 +Subproject commit a031a553f6feb77b3b9db060435cf0c2bff043e6 From fdb67a86f46b4b53b5726aa5986e3f9ba3372189 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 8 Jun 2025 09:26:36 +0800 Subject: [PATCH 27/45] up 1.10.5 --- V2rayNG/app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index c66250d9..eed45b22 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 654 - versionName = "1.10.4" + versionCode = 655 + versionName = "1.10.5" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') From fff6ab30e6000d95885706af34d3e35b8d2aeb60 Mon Sep 17 00:00:00 2001 From: patterniha <71074308+patterniha@users.noreply.github.com> Date: Sat, 14 Jun 2025 09:29:59 +0330 Subject: [PATCH 28/45] Xray-core default FakeIPv6 Pool should not bypass and should route (#4649) * Update V2RayVpnService.kt * Update V2RayVpnService.kt * Update AppConfig.kt --- V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt | 2 +- .../app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index 9e1b7918..4099e7f9 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -189,7 +189,7 @@ object AppConfig { val DNS_YANDEX_ADDRESSES = arrayListOf("77.88.8.8", "77.88.8.1", "2a02:6b8::feed:0ff", "2a02:6b8:0:1::feed:0ff") //minimum list https://serverfault.com/a/304791 - val BYPASS_PRIVATE_IP_LIST = arrayListOf( + val ROUTED_IP_LIST = arrayListOf( "0.0.0.0/5", "8.0.0.0/7", "11.0.0.0/8", diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt index 9fc24d56..6d30843c 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt @@ -167,7 +167,7 @@ class V2RayVpnService : VpnService(), ServiceControl { //builder.addDnsServer(PRIVATE_VLAN4_ROUTER) val bypassLan = SettingsManager.routingRulesetsBypassLan() if (bypassLan) { - AppConfig.BYPASS_PRIVATE_IP_LIST.forEach { + AppConfig.ROUTED_IP_LIST.forEach { val addr = it.split('/') builder.addRoute(addr[0], addr[1].toInt()) } @@ -179,6 +179,7 @@ class V2RayVpnService : VpnService(), ServiceControl { builder.addAddress(PRIVATE_VLAN6_CLIENT, 126) if (bypassLan) { builder.addRoute("2000::", 3) //currently only 1/8 of total ipV6 is in use + builder.addRoute("fc00::", 18) //Xray-core default FakeIPv6 Pool } else { builder.addRoute("::", 0) } From 69e27ed3bb872efc14e98d20c3f4c29a139d055f Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 14 Jun 2025 14:26:33 +0800 Subject: [PATCH 29/45] Fix log for plugin --- V2rayNG/app/src/main/java/com/v2ray/ang/util/PluginUtil.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/util/PluginUtil.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/util/PluginUtil.kt index 48e04b6d..2b9f71aa 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/util/PluginUtil.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/util/PluginUtil.kt @@ -28,13 +28,17 @@ object PluginUtil { fun runPlugin(context: Context, config: ProfileItem?, socksPort: Int?) { Log.i(AppConfig.TAG, "Starting plugin execution") - if (config == null || socksPort == null) { + if (config == null) { Log.w(AppConfig.TAG, "Cannot run plugin: config is null") return } try { if (config.configType == EConfigType.HYSTERIA2) { + if (socksPort == null) { + Log.w(AppConfig.TAG, "Cannot run plugin: socksPort is null") + return + } Log.i(AppConfig.TAG, "Running Hysteria2 plugin") val configFile = genConfigHy2(context, config, socksPort) ?: return val cmd = genCmdHy2(context, configFile) From 6f0b3ce99028a3ed40ae4c8e1ec57792def99cf4 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 14 Jun 2025 14:26:37 +0800 Subject: [PATCH 30/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index a031a553..4de15a6c 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit a031a553f6feb77b3b9db060435cf0c2bff043e6 +Subproject commit 4de15a6c8d2c4d34b0d3cdce61955f8f5b113207 From 51eabe5440ed6704c596b51a049bfa7d51aa227e Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 14 Jun 2025 14:27:09 +0800 Subject: [PATCH 31/45] up 1.10.6 --- V2rayNG/app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index eed45b22..82bfe062 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 655 - versionName = "1.10.5" + versionCode = 656 + versionName = "1.10.6" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') From 72194252583b863aa17d4079704c9fb779167b2e Mon Sep 17 00:00:00 2001 From: DHR60 Date: Sun, 15 Jun 2025 09:46:30 +0800 Subject: [PATCH 32/45] Cloudflare DNS Hosts (#4661) --- .../src/main/java/com/v2ray/ang/AppConfig.kt | 8 +++- .../v2ray/ang/handler/V2rayConfigManager.kt | 38 +++++++++---------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index 4099e7f9..3047874e 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -168,7 +168,9 @@ object AppConfig { // Android Private DNS constants const val DNS_DNSPOD_DOMAIN = "dot.pub" const val DNS_ALIDNS_DOMAIN = "dns.alidns.com" - const val DNS_CLOUDFLARE_DOMAIN = "one.one.one.one" + const val DNS_CLOUDFLARE_ONE_DOMAIN = "one.one.one.one" + const val DNS_CLOUDFLARE_DNS_COM_DOMAIN = "dns.cloudflare.com" + const val DNS_CLOUDFLARE_DNS_DOMAIN = "cloudflare-dns.com" const val DNS_GOOGLE_DOMAIN = "dns.google" const val DNS_QUAD9_DOMAIN = "dns.quad9.net" const val DNS_YANDEX_DOMAIN = "common.dot.dns.yandex.net" @@ -182,7 +184,9 @@ object AppConfig { const val HEADER_TYPE_HTTP = "http" val DNS_ALIDNS_ADDRESSES = arrayListOf("223.5.5.5", "223.6.6.6", "2400:3200::1", "2400:3200:baba::1") - val DNS_CLOUDFLARE_ADDRESSES = arrayListOf("1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001") + val DNS_CLOUDFLARE_ONE_ADDRESSES = arrayListOf("1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001") + val DNS_CLOUDFLARE_DNS_COM_ADDRESSES = arrayListOf("104.16.132.229", "104.16.133.229", "2606:4700::6810:84e5", "2606:4700::6810:85e5") + val DNS_CLOUDFLARE_DNS_ADDRESSES = arrayListOf("104.16.248.249", "104.16.249.249", "2606:4700::6810:f8f9", "2606:4700::6810:f9f9") val DNS_DNSPOD_ADDRESSES = arrayListOf("1.12.12.12", "120.53.53.53") val DNS_GOOGLE_ADDRESSES = arrayListOf("8.8.8.8", "8.8.4.4", "2001:4860:4860::8888", "2001:4860:4860::8844") val DNS_QUAD9_ADDRESSES = arrayListOf("9.9.9.9", "149.112.112.112", "2620:fe::fe", "2620:fe::9") diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index 8ef7a7b7..c0e6fae8 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -16,7 +16,6 @@ import com.v2ray.ang.dto.V2rayConfig.OutboundBean.StreamSettingsBean import com.v2ray.ang.dto.V2rayConfig.RoutingBean.RulesBean import com.v2ray.ang.extension.isNotNullEmpty import com.v2ray.ang.fmt.HttpFmt -import com.v2ray.ang.fmt.Hysteria2Fmt import com.v2ray.ang.fmt.ShadowsocksFmt import com.v2ray.ang.fmt.SocksFmt import com.v2ray.ang.fmt.TrojanFmt @@ -479,6 +478,25 @@ object V2rayConfigManager { ) } + //block dns + val blkDomain = getUserRule2Domain(AppConfig.TAG_BLOCKED) + if (blkDomain.isNotEmpty()) { + hosts.putAll(blkDomain.map { it to AppConfig.LOOPBACK }) + } + + // hardcode googleapi rule to fix play store problems + hosts[AppConfig.GOOGLEAPIS_CN_DOMAIN] = AppConfig.GOOGLEAPIS_COM_DOMAIN + + // hardcode popular Android Private DNS rule to fix localhost DNS problem + hosts[AppConfig.DNS_ALIDNS_DOMAIN] = AppConfig.DNS_ALIDNS_ADDRESSES + hosts[AppConfig.DNS_CLOUDFLARE_ONE_DOMAIN] = AppConfig.DNS_CLOUDFLARE_ONE_ADDRESSES + hosts[AppConfig.DNS_CLOUDFLARE_DNS_COM_DOMAIN] = AppConfig.DNS_CLOUDFLARE_DNS_COM_ADDRESSES + hosts[AppConfig.DNS_CLOUDFLARE_DNS_DOMAIN] = AppConfig.DNS_CLOUDFLARE_DNS_ADDRESSES + hosts[AppConfig.DNS_DNSPOD_DOMAIN] = AppConfig.DNS_DNSPOD_ADDRESSES + hosts[AppConfig.DNS_GOOGLE_DOMAIN] = AppConfig.DNS_GOOGLE_ADDRESSES + hosts[AppConfig.DNS_QUAD9_DOMAIN] = AppConfig.DNS_QUAD9_ADDRESSES + hosts[AppConfig.DNS_YANDEX_DOMAIN] = AppConfig.DNS_YANDEX_ADDRESSES + //User DNS hosts try { val userHosts = MmkvManager.decodeSettingsString(AppConfig.PREF_DNS_HOSTS) @@ -493,24 +511,6 @@ object V2rayConfigManager { Log.e(AppConfig.TAG, "Failed to configure user DNS hosts", e) } - //block dns - val blkDomain = getUserRule2Domain(AppConfig.TAG_BLOCKED) - if (blkDomain.isNotEmpty()) { - hosts.putAll(blkDomain.map { it to AppConfig.LOOPBACK }) - } - - // hardcode googleapi rule to fix play store problems - hosts[AppConfig.GOOGLEAPIS_CN_DOMAIN] = AppConfig.GOOGLEAPIS_COM_DOMAIN - - // hardcode popular Android Private DNS rule to fix localhost DNS problem - hosts[AppConfig.DNS_ALIDNS_DOMAIN] = AppConfig.DNS_ALIDNS_ADDRESSES - hosts[AppConfig.DNS_CLOUDFLARE_DOMAIN] = AppConfig.DNS_CLOUDFLARE_ADDRESSES - hosts[AppConfig.DNS_DNSPOD_DOMAIN] = AppConfig.DNS_DNSPOD_ADDRESSES - hosts[AppConfig.DNS_GOOGLE_DOMAIN] = AppConfig.DNS_GOOGLE_ADDRESSES - hosts[AppConfig.DNS_QUAD9_DOMAIN] = AppConfig.DNS_QUAD9_ADDRESSES - hosts[AppConfig.DNS_YANDEX_DOMAIN] = AppConfig.DNS_YANDEX_ADDRESSES - - // DNS dns v2rayConfig.dns = V2rayConfig.DnsBean( servers = servers, From e0881caab4312beebd48bd90b4771f11df2bfe98 Mon Sep 17 00:00:00 2001 From: DHR60 Date: Tue, 17 Jun 2025 13:43:03 +0800 Subject: [PATCH 33/45] Fix missing sockopt.domainStrategy (#4673) * Fix missing sockopt.domainStrategy * Fix --- .../main/java/com/v2ray/ang/handler/V2rayConfigManager.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index c0e6fae8..ddbc78a3 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -828,7 +828,11 @@ object V2rayConfigManager { for (item in proxyOutboundList) { val domain = item.getServerAddress() if (domain.isNullOrEmpty()) continue - if (newHosts.containsKey(domain)) continue + + if (newHosts.containsKey(domain)) { + item.ensureSockopt().domainStrategy = if (preferIpv6) "UseIPv6v4" else "UseIPv4v6" + continue + } val resolvedIps = HttpUtil.resolveHostToIP(domain, preferIpv6) if (resolvedIps.isNullOrEmpty()) continue From 1a5e105212607fd4bc86421b152b5969548ec81c Mon Sep 17 00:00:00 2001 From: Ural Khamitov Date: Wed, 18 Jun 2025 13:17:28 +0500 Subject: [PATCH 34/45] Fix blinking QSTile when QS panel is opening (#4676) --- .../src/main/java/com/v2ray/ang/service/QSTileService.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/service/QSTileService.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/service/QSTileService.kt index db12287d..7aecf634 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/service/QSTileService.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/service/QSTileService.kt @@ -25,14 +25,13 @@ class QSTileService : TileService() { * @param state The state to set. */ fun setState(state: Int) { + qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name) if (state == Tile.STATE_INACTIVE) { qsTile?.state = Tile.STATE_INACTIVE qsTile?.label = getString(R.string.app_name) - qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name) } else if (state == Tile.STATE_ACTIVE) { qsTile?.state = Tile.STATE_ACTIVE qsTile?.label = V2RayServiceManager.getRunningServerName() - qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name) } qsTile?.updateTile() @@ -45,7 +44,11 @@ class QSTileService : TileService() { override fun onStartListening() { super.onStartListening() - setState(Tile.STATE_INACTIVE) + if (V2RayServiceManager.isRunning()) { + setState(Tile.STATE_ACTIVE) + } else { + setState(Tile.STATE_INACTIVE) + } mMsgReceive = ReceiveMessageHandler(this) val mFilter = IntentFilter(AppConfig.BROADCAST_ACTION_ACTIVITY) ContextCompat.registerReceiver(applicationContext, mMsgReceive, mFilter, Utils.receiverFlags()) From e077c181086dbdbcd8bddffaf2f6fb6141f1bfb4 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 19 Jun 2025 14:40:07 +0800 Subject: [PATCH 35/45] Improved update checking and prompts in case of abnormality --- .../v2ray/ang/handler/UpdateCheckerManager.kt | 5 ----- .../com/v2ray/ang/ui/CheckUpdateActivity.kt | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt index e152002f..37b55c2e 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/UpdateCheckerManager.kt @@ -17,7 +17,6 @@ import java.io.FileOutputStream object UpdateCheckerManager { suspend fun checkForUpdate(includePreRelease: Boolean = false): CheckUpdateResult = withContext(Dispatchers.IO) { - try { val url = if (includePreRelease) { AppConfig.APP_API_URL } else { @@ -53,10 +52,6 @@ object UpdateCheckerManager { } else { CheckUpdateResult(hasUpdate = false) } - } catch (e: Exception) { - Log.e(AppConfig.TAG, "Failed to check for updates: ${e.message}") - return@withContext CheckUpdateResult(hasUpdate = false, error = e.message) - } } suspend fun downloadApk(context: Context, downloadUrl: String): File? = withContext(Dispatchers.IO) { diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt index 8f464a49..a9b698c5 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/CheckUpdateActivity.kt @@ -1,6 +1,7 @@ package com.v2ray.ang.ui import android.os.Bundle +import android.util.Log import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope import com.v2ray.ang.AppConfig @@ -9,6 +10,7 @@ import com.v2ray.ang.R import com.v2ray.ang.databinding.ActivityCheckUpdateBinding import com.v2ray.ang.dto.CheckUpdateResult import com.v2ray.ang.extension.toast +import com.v2ray.ang.extension.toastError import com.v2ray.ang.extension.toastSuccess import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.handler.SpeedtestManager @@ -46,11 +48,16 @@ class CheckUpdateActivity : BaseActivity() { toast(R.string.update_checking_for_update) lifecycleScope.launch { - val result = UpdateCheckerManager.checkForUpdate(includePreRelease) - if (result.hasUpdate) { - showUpdateDialog(result) - } else { - toastSuccess(R.string.update_already_latest_version) + try { + val result = UpdateCheckerManager.checkForUpdate(includePreRelease) + if (result.hasUpdate) { + showUpdateDialog(result) + } else { + toastSuccess(R.string.update_already_latest_version) + } + } catch (e: Exception) { + Log.e(AppConfig.TAG, "Failed to check for updates: ${e.message}") + toastError(e.message ?: getString(R.string.toast_failure)) } } } From f68c35371527c56a19a388e59e6ef237b956a3e8 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 19 Jun 2025 14:40:11 +0800 Subject: [PATCH 36/45] Update AndroidLibXrayLite --- AndroidLibXrayLite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidLibXrayLite b/AndroidLibXrayLite index 4de15a6c..8ad3e1dd 160000 --- a/AndroidLibXrayLite +++ b/AndroidLibXrayLite @@ -1 +1 @@ -Subproject commit 4de15a6c8d2c4d34b0d3cdce61955f8f5b113207 +Subproject commit 8ad3e1ddf165d8d67e488346b2faa9153d3e33a4 From 94cc72d2b991ca6a66d0b6c70af63c9f88ec4fe1 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 19 Jun 2025 14:40:47 +0800 Subject: [PATCH 37/45] up 1.10.7 --- V2rayNG/app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index 82bfe062..2e3ab596 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 656 - versionName = "1.10.6" + versionCode = 657 + versionName = "1.10.7" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') From 2fb6e62e1309d29437c1f4147f5531056b045dab Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:09:03 +0800 Subject: [PATCH 38/45] Added setting option for VPN interface address https://github.com/2dust/v2rayNG/issues/4641 --- .../src/main/java/com/v2ray/ang/AppConfig.kt | 1 + .../ang/dto/VpnInterfaceAddressConfig.kt | 39 +++++++++++++++++++ .../com/v2ray/ang/handler/SettingsManager.kt | 14 +++++++ .../com/v2ray/ang/service/V2RayVpnService.kt | 15 +++---- .../java/com/v2ray/ang/ui/SettingsActivity.kt | 4 +- .../v2ray/ang/viewmodel/SettingsViewModel.kt | 1 + .../app/src/main/res/values-ar/strings.xml | 2 + .../app/src/main/res/values-bn/strings.xml | 2 + .../src/main/res/values-bqi-rIR/strings.xml | 2 + .../app/src/main/res/values-fa/strings.xml | 2 + .../app/src/main/res/values-ru/strings.xml | 2 + .../app/src/main/res/values-vi/strings.xml | 2 + .../src/main/res/values-zh-rCN/strings.xml | 2 + .../src/main/res/values-zh-rTW/strings.xml | 3 ++ V2rayNG/app/src/main/res/values/arrays.xml | 20 ++++++++++ V2rayNG/app/src/main/res/values/strings.xml | 2 + .../app/src/main/res/xml/pref_settings.xml | 14 +++++-- 17 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 V2rayNG/app/src/main/java/com/v2ray/ang/dto/VpnInterfaceAddressConfig.kt diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index 3047874e..a5d6dbdc 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -26,6 +26,7 @@ object AppConfig { const val PREF_LOCAL_DNS_PORT = "pref_local_dns_port" const val PREF_VPN_DNS = "pref_vpn_dns" const val PREF_VPN_BYPASS_LAN = "pref_vpn_bypass_lan" + const val PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX = "pref_vpn_interface_address_config_index" const val PREF_ROUTING_DOMAIN_STRATEGY = "pref_routing_domain_strategy" const val PREF_ROUTING_RULESET = "pref_routing_ruleset" const val PREF_MUX_ENABLED = "pref_mux_enabled" diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/VpnInterfaceAddressConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/VpnInterfaceAddressConfig.kt new file mode 100644 index 00000000..6b7bc379 --- /dev/null +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/VpnInterfaceAddressConfig.kt @@ -0,0 +1,39 @@ +package com.v2ray.ang.dto + +/** + * VPN interface address configuration enum class + * Defines predefined IPv4 and IPv6 address pairs for VPN TUN interface configuration. + * Each option provides client and router addresses to establish point-to-point VPN tunnels. + */ +enum class VpnInterfaceAddressConfig( + val displayName: String, + val ipv4Client: String, + val ipv4Router: String, + val ipv6Client: String, + val ipv6Router: String +) { + OPTION_1("10.10.14.x", "10.10.14.1", "10.10.14.2", "fc00::10:10:14:1", "fc00::10:10:14:2"), + OPTION_2("10.1.0.x", "10.1.0.1", "10.1.0.2", "fc00::10:1:0:1", "fc00::10:1:0:2"), + OPTION_3("10.0.0.x", "10.0.0.1", "10.0.0.2", "fc00::10:0:0:1", "fc00::10:0:0:2"), + OPTION_4("172.31.0.x", "172.31.0.1", "172.31.0.2", "fc00::172:31:0:1", "fc00::172:31:0:2"), + OPTION_5("172.20.0.x", "172.20.0.1", "172.20.0.2", "fc00::172:20:0:1", "fc00::172:20:0:2"), + OPTION_6("172.16.0.x", "172.16.0.1", "172.16.0.2", "fc00::172:16:0:1", "fc00::172:16:0:2"), + OPTION_7("192.168.100.x", "192.168.100.1", "192.168.100.2", "fc00::192:168:100:1", "fc00::192:168:100:2"); + + companion object { + /** + * Retrieves the VPN interface address configuration based on the specified index. + * + * @param index The configuration index (0-based) corresponding to user selection + * @return The VpnInterfaceAddressConfig instance at the specified index, + * or OPTION_1 (default) if the index is out of bounds + */ + fun getConfigByIndex(index: Int): VpnInterfaceAddressConfig { + return if (index in values().indices) { + values()[index] + } else { + OPTION_1 // Default to the first configuration + } + } + } +} diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt index a488e593..b2e23f7f 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/SettingsManager.kt @@ -16,6 +16,7 @@ import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.dto.RoutingType import com.v2ray.ang.dto.RulesetItem import com.v2ray.ang.dto.V2rayConfig +import com.v2ray.ang.dto.VpnInterfaceAddressConfig import com.v2ray.ang.handler.MmkvManager.decodeServerConfig import com.v2ray.ang.handler.MmkvManager.decodeServerList import com.v2ray.ang.util.JsonUtil @@ -356,4 +357,17 @@ object SettingsManager { "2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) } } + + /** + * Retrieves the currently selected VPN interface address configuration. + * This method reads the user's preference for VPN interface addressing and returns + * the corresponding configuration containing IPv4 and IPv6 addresses. + * + * @return The selected VpnInterfaceAddressConfig instance, or the default configuration + * if no valid selection is found or if the stored index is invalid. + */ + fun getCurrentVpnInterfaceAddressConfig(): VpnInterfaceAddressConfig { + val selectedIndex = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX, "0")?.toInt() + return VpnInterfaceAddressConfig.getConfigByIndex(selectedIndex ?: 0) + } } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt index 6d30843c..d734c299 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayVpnService.kt @@ -33,12 +33,7 @@ import java.lang.ref.SoftReference class V2RayVpnService : VpnService(), ServiceControl { companion object { private const val VPN_MTU = 1500 - private const val PRIVATE_VLAN4_CLIENT = "10.10.14.1" - private const val PRIVATE_VLAN4_ROUTER = "10.10.14.2" - private const val PRIVATE_VLAN6_CLIENT = "fc00::10:10:14:1" - private const val PRIVATE_VLAN6_ROUTER = "fc00::10:10:14:2" private const val TUN2SOCKS = "libtun2socks.so" - } private lateinit var mInterface: ParcelFileDescriptor @@ -160,10 +155,11 @@ class V2RayVpnService : VpnService(), ServiceControl { // If the old interface has exactly the same parameters, use it! // Configure a builder while parsing the parameters. val builder = Builder() + val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig() //val enableLocalDns = defaultDPreference.getPrefBoolean(AppConfig.PREF_LOCAL_DNS_ENABLED, false) builder.setMtu(VPN_MTU) - builder.addAddress(PRIVATE_VLAN4_CLIENT, 30) + builder.addAddress(vpnConfig.ipv4Client, 30) //builder.addDnsServer(PRIVATE_VLAN4_ROUTER) val bypassLan = SettingsManager.routingRulesetsBypassLan() if (bypassLan) { @@ -176,7 +172,7 @@ class V2RayVpnService : VpnService(), ServiceControl { } if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) { - builder.addAddress(PRIVATE_VLAN6_CLIENT, 126) + builder.addAddress(vpnConfig.ipv6Client, 126) if (bypassLan) { builder.addRoute("2000::", 3) //currently only 1/8 of total ipV6 is in use builder.addRoute("fc00::", 18) //Xray-core default FakeIPv6 Pool @@ -260,9 +256,10 @@ class V2RayVpnService : VpnService(), ServiceControl { private fun runTun2socks() { Log.i(AppConfig.TAG, "Start run $TUN2SOCKS") val socksPort = SettingsManager.getSocksPort() + val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig() val cmd = arrayListOf( File(applicationContext.applicationInfo.nativeLibraryDir, TUN2SOCKS).absolutePath, - "--netif-ipaddr", PRIVATE_VLAN4_ROUTER, + "--netif-ipaddr", vpnConfig.ipv4Router, "--netif-netmask", "255.255.255.252", "--socks-server-addr", "$LOOPBACK:${socksPort}", "--tunmtu", VPN_MTU.toString(), @@ -273,7 +270,7 @@ class V2RayVpnService : VpnService(), ServiceControl { if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6)) { cmd.add("--netif-ip6addr") - cmd.add(PRIVATE_VLAN6_ROUTER) + cmd.add(vpnConfig.ipv6Router) } if (MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED)) { val localDnsPort = Utils.parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_LOCAL_DNS_PORT), AppConfig.PORT_LOCAL_DNS.toInt()) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt index 4ec2294a..515bc65f 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt @@ -44,6 +44,7 @@ class SettingsActivity : BaseActivity() { private val localDnsPort by lazy { findPreference(AppConfig.PREF_LOCAL_DNS_PORT) } private val vpnDns by lazy { findPreference(AppConfig.PREF_VPN_DNS) } private val vpnBypassLan by lazy { findPreference(AppConfig.PREF_VPN_BYPASS_LAN) } + private val vpnInterfaceAddress by lazy { findPreference(AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX) } private val mux by lazy { findPreference(AppConfig.PREF_MUX_ENABLED) } private val muxConcurrency by lazy { findPreference(AppConfig.PREF_MUX_CONCURRENCY) } @@ -249,6 +250,7 @@ class SettingsActivity : BaseActivity() { listOf( AppConfig.PREF_VPN_BYPASS_LAN, + AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX, AppConfig.PREF_ROUTING_DOMAIN_STRATEGY, AppConfig.PREF_MUX_XUDP_QUIC, AppConfig.PREF_FRAGMENT_PACKETS, @@ -273,7 +275,7 @@ class SettingsActivity : BaseActivity() { localDnsPort?.isEnabled = vpn vpnDns?.isEnabled = vpn vpnBypassLan?.isEnabled = vpn - vpn + vpnInterfaceAddress?.isEnabled = vpn if (vpn) { updateLocalDns( MmkvManager.decodeSettingsBool( diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt index d78b1307..e12a56e5 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt @@ -41,6 +41,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application AppConfig.PREF_MODE, AppConfig.PREF_VPN_DNS, AppConfig.PREF_VPN_BYPASS_LAN, + AppConfig.PREF_VPN_INTERFACE_ADDRESS_CONFIG_INDEX, AppConfig.PREF_REMOTE_DNS, AppConfig.PREF_DOMESTIC_DNS, AppConfig.PREF_DNS_HOSTS, diff --git a/V2rayNG/app/src/main/res/values-ar/strings.xml b/V2rayNG/app/src/main/res/values-ar/strings.xml index 49b724b1..b7843b69 100644 --- a/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -181,6 +181,8 @@ VPN DNS (IPv4/v6 فقط) Does VPN bypass LAN + VPN Interface Address + DNS المحلي (اختياري) DNS diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index bd7c492f..888081e5 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -181,6 +181,8 @@ VPN DNS (শুধুমাত্র IPv4/v6) Does VPN bypass LAN + VPN Interface Address + ঘরোয়া DNS (ঐচ্ছিক) DNS diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 41e81fbb..fe0738f1 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -181,6 +181,8 @@ VPN DNS (تینا IPv4/v6) VPN ز شبکه مهلی اگوڌرته؟ + VPN Interface Address + DNS منی (اختیاری) DNS diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index 16bbd4ff..d4e1ff35 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -179,6 +179,8 @@ VPN DNS (فقط IPv4/v6) آیا VPN از شبکه محلی عبور می کند؟ + VPN Interface Address + DNS داخلی (اختیاری) DNS diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 9b5e39f6..3caf1bd9 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -180,6 +180,8 @@ VPN DNS (только IPv4/v6) VPN пропускает LAN + VPN частный IP + Внутренняя DNS (необязательно) DNS diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index 72cdee64..fbbc17da 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -181,6 +181,8 @@ VPN DNS (Chỉ IPv4 / IPv6) Does VPN bypass LAN + VPN Interface Address + DNS nội địa (Không bắt buộc) DNS diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index a0aa7a5a..246d11c4 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -178,6 +178,8 @@ VPN DNS (仅支持 IPv4/v6) VPN 是否绕过局域网 + VPN 接口地址 + 境内 DNS (可选) DNS diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index e655e18f..135992f4 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -180,6 +180,8 @@ VPN DNS (僅支援 IPv4/v6) VPN 是否繞過區域網 + VPN 介面位址 + DNS 境内 DNS (可选) DNS hosts (格式: 網域:位址,…) @@ -360,4 +362,5 @@ 不繞過 + diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml index 1863ccdd..2f03ac86 100644 --- a/V2rayNG/app/src/main/res/values/arrays.xml +++ b/V2rayNG/app/src/main/res/values/arrays.xml @@ -182,4 +182,24 @@ 2 + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + + + + 10.10.14.x + 10.1.0.x + 10.0.0.x + 172.31.0.x + 172.20.0.x + 172.16.0.x + 192.168.100.x + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 39defc59..90534f20 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -182,6 +182,8 @@ VPN DNS (only IPv4/v6) Does VPN bypass LAN + VPN Interface Address + Domestic DNS (Optional) DNS diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index cbfbb932..b9ed38f2 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -20,9 +20,9 @@ + android:key="pref_prefer_ipv6" + android:summary="@string/summary_pref_prefer_ipv6" + android:title="@string/title_pref_prefer_ipv6" /> + + From 33572477fc8223dfb86cd550604d266d42f0d427 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:39:06 +0800 Subject: [PATCH 39/45] Adjustment setting items --- .../app/src/main/res/values-ar/strings.xml | 1 + .../app/src/main/res/values-bn/strings.xml | 1 + .../src/main/res/values-bqi-rIR/strings.xml | 1 + .../app/src/main/res/values-fa/strings.xml | 1 + .../app/src/main/res/values-ru/strings.xml | 1 + .../app/src/main/res/values-vi/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + V2rayNG/app/src/main/res/values/strings.xml | 1 + .../app/src/main/res/xml/pref_settings.xml | 21 +++++++++++-------- 10 files changed, 21 insertions(+), 9 deletions(-) diff --git a/V2rayNG/app/src/main/res/values-ar/strings.xml b/V2rayNG/app/src/main/res/values-ar/strings.xml index b7843b69..ba499e3d 100644 --- a/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -141,6 +141,7 @@ الإعدادات إعدادات متقدمة + إعدادات النواة إعدادات VPN الوكيل لكل تطبيق عام: التطبيق المحدد هو وكيل، غير المحدد اتصال مباشر؛ \nوضع التجاوز: التطبيق المحدد متصل مباشرة، غير المحدد وكيل. \nخيار تحديد تطبيق الوكيل تلقائيًا في القائمة diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index 888081e5..e71fe170 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -139,6 +139,7 @@ সেটিংস এডভান্সড সেটিংস + কোর সেটিংস VPN সেটিংস প্রতি-অ্যাপ প্রক্সি সাধারণ: চেকড অ্যাপ প্রক্সি, আনচেকড সরাসরি সংযোগ; \nবাইপাস মোড: চেকড অ্যাপ সরাসরি সংযুক্ত, আনচেকড প্রক্সি। \nমেনুতে প্রক্সি অ্যাপ্লিকেশন স্বয়ংক্রিয়ভাবে নির্বাচন করার বিকল্প diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index fe0738f1..002d64df 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -140,6 +140,7 @@ سامووا سامووا پؽش رئڌه + سامووا هسته سامووا VPN پروکسی و ری برنومه پوی وولاتی: برنومه واجۊری بیڌه پروکسی هڌ، منپیز موستقیم بؽ نشووه هڌ. هالت دور زیڌن: برنومه نشووک ناڌه موستقیمن منپیز هڌ، پروکسی نشووک زیڌه نؽڌ. گۊزینه پسند خوتکار برنومه پروکسی من نومگه diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index d4e1ff35..b0a1bd8d 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -137,6 +137,7 @@ تنظیمات تنظیمات پیشرفته + تنظیمات هسته تنظیمات VPN پروکسی به تفکیک برنامه عمومی: برنامه انتخاب شده از طریق یک پروکسی متصل می شود، برنامه انتخاب نشده مستقیماً متصل می شود. \nحالت دور زدن: برنامه انتخاب شده مستقیماً متصل می شود، برنامه انتخاب نشده از طریق یک پروکسی متصل می شود. \nانتخاب خودکار برنامه های پراکسی در منو امکان پذیر است. diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 3caf1bd9..4dcbdfdd 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -139,6 +139,7 @@ Настройки Расширенные настройки + Настройки ядра Настройки VPN Прокси для выбранных приложений Основной: выбранное приложение соединяется через прокси, не выбранное — напрямую;\nРежим обхода: выбранное приложение соединяется напрямую, не выбранное — через прокси.\nЕсть возможность автоматического выбора проксируемых приложений в меню. diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index fbbc17da..e7685ab0 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -138,6 +138,7 @@ Cài đặt Cài đặt nâng cao + Cài đặt lõi Cài đặt VPN Proxy theo Ứng dụng - Bình thường: Ứng dụng đã chọn sẽ kết nối thông qua Proxy, chưa chọn sẽ kết nối trực tiếp. \n- Chế độ Bypass: Ứng dụng đã chọn sẽ kết nối trực tiếp, chưa chọn sẽ kết nối qua Proxy. \n- Nếu bạn đang ở Trung Quốc thì vào Menu, chọn Tự động chọn ứng dụng Proxy. diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 246d11c4..659cb45d 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -137,6 +137,7 @@ 设置 进阶设置 + 核心设置 VPN 设置 分应用 常规: 勾选的 App 被代理, 未勾选的直连;\n绕行模式: 勾选的 App 直连, 未勾选的被代理.\n不明白者在菜单中选择自动选中需代理应用 diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index 135992f4..bd066a5b 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -138,6 +138,7 @@ 設定 進階 + 核心設定 VPN 設定 Proxy 個別應用程式 常規:勾選的 App 啟用 Proxy,未勾選的直接連線;\n繞行模式:勾選的 App 直接連線,未勾選的啟用 Proxy。\n可在選單中選擇自動選中需 Proxy 應用 diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 90534f20..3d298755 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -140,6 +140,7 @@ Settings Advanced Settings + Core Settings VPN Settings Per-app proxy General: Checked apps use proxy, unchecked apps connect directly; \nBypass mode: checked apps connect directly, unchecked apps use proxy. \nThe option to automatically select proxy applications is in the menu diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index b9ed38f2..4a648ed8 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -179,9 +179,7 @@ android:title="@string/title_pref_auto_update_interval" /> - + - - + + + + + + - + + \ No newline at end of file From 777190e861cb616e764b049222850d3947623e15 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:48:31 +0800 Subject: [PATCH 40/45] Added setting option for Outbound domain pre-resolve method https://github.com/2dust/v2rayNG/issues/4679 --- .../src/main/java/com/v2ray/ang/AppConfig.kt | 1 + .../src/main/java/com/v2ray/ang/fmt/FmtBase.kt | 17 +++++++++++++++-- .../com/v2ray/ang/handler/V2rayConfigManager.kt | 5 ++++- .../java/com/v2ray/ang/ui/SettingsActivity.kt | 1 + .../v2ray/ang/viewmodel/SettingsViewModel.kt | 1 + V2rayNG/app/src/main/res/values-ar/strings.xml | 7 +++++++ V2rayNG/app/src/main/res/values-bn/strings.xml | 7 +++++++ .../app/src/main/res/values-bqi-rIR/strings.xml | 7 +++++++ V2rayNG/app/src/main/res/values-fa/strings.xml | 7 +++++++ V2rayNG/app/src/main/res/values-ru/strings.xml | 7 +++++++ V2rayNG/app/src/main/res/values-vi/strings.xml | 7 +++++++ .../app/src/main/res/values-zh-rCN/strings.xml | 7 +++++++ .../app/src/main/res/values-zh-rTW/strings.xml | 6 ++++++ V2rayNG/app/src/main/res/values/arrays.xml | 6 ++++++ V2rayNG/app/src/main/res/values/strings.xml | 7 +++++++ V2rayNG/app/src/main/res/xml/pref_settings.xml | 8 ++++++++ 16 files changed, 98 insertions(+), 3 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt index a5d6dbdc..09e3a9d5 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/AppConfig.kt @@ -56,6 +56,7 @@ object AppConfig { const val PREF_DNS_HOSTS = "pref_dns_hosts" const val PREF_DELAY_TEST_URL = "pref_delay_test_url" const val PREF_LOGLEVEL = "pref_core_loglevel" + const val PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD = "pref_outbound_domain_resolve_method" const val PREF_MODE = "pref_mode" const val PREF_IS_BOOTED = "pref_is_booted" const val PREF_CHECK_UPDATE_PRE_RELEASE = "pref_check_update_pre_release" diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt index ec2d7801..73cdf958 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/fmt/FmtBase.kt @@ -4,6 +4,7 @@ import com.v2ray.ang.AppConfig import com.v2ray.ang.dto.NetworkType import com.v2ray.ang.dto.ProfileItem import com.v2ray.ang.extension.isNotNullEmpty +import com.v2ray.ang.handler.MmkvManager import com.v2ray.ang.util.HttpUtil import com.v2ray.ang.util.Utils import java.net.URI @@ -151,7 +152,19 @@ open class FmtBase { } fun getServerAddress(profileItem: ProfileItem): String { - return HttpUtil.toIdnDomain(profileItem.server.orEmpty()) - } + if (Utils.isPureIpAddress(profileItem.server.orEmpty())) { + return profileItem.server.orEmpty() + } + val domain = HttpUtil.toIdnDomain(profileItem.server.orEmpty()) + if (MmkvManager.decodeSettingsString(AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD, "1") != "2") { + return domain + } + //Resolve and replace domain + val resolvedIps = HttpUtil.resolveHostToIP(domain, MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6)) + if (resolvedIps.isNullOrEmpty()) { + return domain + } + return resolvedIps.first() + } } diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index ddbc78a3..fc77271e 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -131,7 +131,10 @@ object V2rayConfigManager { v2rayConfig.policy = null } - resolveOutboundDomainsToHosts(v2rayConfig) + //Resolve and add to DNS Hosts + if (MmkvManager.decodeSettingsString(AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD, "1") == "1") { + resolveOutboundDomainsToHosts(v2rayConfig) + } result.status = true result.content = JsonUtil.toJsonPretty(v2rayConfig) ?: "" diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt index 515bc65f..6af64e3a 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/SettingsActivity.kt @@ -257,6 +257,7 @@ class SettingsActivity : BaseActivity() { AppConfig.PREF_LANGUAGE, AppConfig.PREF_UI_MODE_NIGHT, AppConfig.PREF_LOGLEVEL, + AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD, AppConfig.PREF_MODE ).forEach { key -> if (MmkvManager.decodeSettingsString(key) != null) { diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt index e12a56e5..7ac5d60f 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/viewmodel/SettingsViewModel.kt @@ -49,6 +49,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application AppConfig.PREF_LOCAL_DNS_PORT, AppConfig.PREF_SOCKS_PORT, AppConfig.PREF_LOGLEVEL, + AppConfig.PREF_OUTBOUND_DOMAIN_RESOLVE_METHOD, AppConfig.PREF_LANGUAGE, AppConfig.PREF_UI_MODE_NIGHT, AppConfig.PREF_ROUTING_DOMAIN_STRATEGY, diff --git a/V2rayNG/app/src/main/res/values-ar/strings.xml b/V2rayNG/app/src/main/res/values-ar/strings.xml index ba499e3d..d74011e9 100644 --- a/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -241,6 +241,7 @@ فاصل التحديث التلقائي (بالدقائق، الحد الأدنى للقيمة 15) مستوى السجل + Outbound domain pre-resolve method الوضع انقر هنا للحصول على مزيد من المساعدة اللغة @@ -357,4 +358,10 @@ Not Bypass + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index e71fe170..f36c9d3a 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -241,6 +241,7 @@ অটো আপডেট ইন্টারভ্যাল (মিনিট, সর্বনিম্ন মান ১৫) লগ স্তর + Outbound domain pre-resolve method মোড আরো সাহায্যের জন্য ক্লিক করুন ভাষা @@ -362,4 +363,10 @@ Not Bypass + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 002d64df..1af31c90 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -241,6 +241,7 @@ فاسله ورۊ کردن خوتکار (اقلن وا 15 دؽقه بۊ) سئت داسووا + Outbound domain pre-resolve method هالت سی دووسمندیا وو هیاری بیشتر، ری ای هؽل بزݩ زۉݩ @@ -372,4 +373,10 @@ دور زیڌه نبۊ + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index b0a1bd8d..081571a3 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -238,6 +238,7 @@ اشتراک های خود را به طور خودکار با فاصله زمانی در پس زمینه به روز کنید. بسته به دستگاه، این ویژگی ممکن است همیشه کار نکند. فاصله به‌ روزرسانی خودکار ( حداقل مقدار ، 15 دقیقه ) سطح گزارشات + Outbound domain pre-resolve method حالت برای اطلاعات و راهنمایی بیشتر، روی این متن کلیک کنید زبان @@ -371,4 +372,10 @@ دور زده نشود + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 4dcbdfdd..c71054a0 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -240,6 +240,7 @@ Интервал автообновления (минут, не менее 15) Подробность ведения журнала + Outbound domain pre-resolve method Режим Нажмите для получения дополнительной информации Язык @@ -371,4 +372,10 @@ Не пропускает + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index e7685ab0..86238b79 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -241,6 +241,7 @@ Thời gian cập nhật tự động (Phút, giá trị tối thiểu là 15) Cấp độ nhật ký + Outbound domain pre-resolve method Chế độ kết nối Nhấn vào đây nếu bạn cần trợ giúp! Ngôn ngữ @@ -359,4 +360,10 @@ Not Bypass + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 659cb45d..a8eec856 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -238,6 +238,7 @@ 自动更新间隔(分钟,最小值 15) 日志级别 + Outbound 域名预解析方式 模式 点此查看更多帮助 语言 @@ -363,4 +364,10 @@ 不绕过 + + 不解析 + 解析后添加至 DNS Hosts + 解析后替换原域名 + + diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index bd066a5b..f8b938c5 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -239,6 +239,7 @@ 自動更新間隔(分鐘,最小值 15) 記錄層級 + Outbound 網域預解析方式 模式 輕觸以檢視說明 語言 @@ -363,5 +364,10 @@ 不繞過 + + 不解析 + 解析後加入 DNS Hosts + 解析後替換原網域名稱 + diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml index 2f03ac86..27f0846e 100644 --- a/V2rayNG/app/src/main/res/values/arrays.xml +++ b/V2rayNG/app/src/main/res/values/arrays.xml @@ -202,4 +202,10 @@ 192.168.100.x + + 0 + 1 + 2 + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 3d298755..57106306 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -242,6 +242,7 @@ Auto Update Interval (Minutes, Min value 15) Log Level + Outbound domain pre-resolve method Mode Click me for more help Language @@ -373,4 +374,10 @@ Not Bypass + + Do not resolve + Resolve and add to DNS Hosts + Resolve and replace domain + + diff --git a/V2rayNG/app/src/main/res/xml/pref_settings.xml b/V2rayNG/app/src/main/res/xml/pref_settings.xml index 4a648ed8..b5ee7aab 100644 --- a/V2rayNG/app/src/main/res/xml/pref_settings.xml +++ b/V2rayNG/app/src/main/res/xml/pref_settings.xml @@ -222,6 +222,14 @@ android:summary="%s" android:title="@string/title_core_loglevel" /> + + From 0700e834f1f5e68494fc74142e4b043840a6473c Mon Sep 17 00:00:00 2001 From: Hossein Abaspanah <63148255+hosseinabaspanah@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:08:31 +0330 Subject: [PATCH 41/45] Update Luri Bakhtiari translation (#4695) --- V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 1af31c90..21b7186f 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -140,7 +140,6 @@ سامووا سامووا پؽش رئڌه - سامووا هسته سامووا VPN پروکسی و ری برنومه پوی وولاتی: برنومه واجۊری بیڌه پروکسی هڌ، منپیز موستقیم بؽ نشووه هڌ. هالت دور زیڌن: برنومه نشووک ناڌه موستقیمن منپیز هڌ، پروکسی نشووک زیڌه نؽڌ. گۊزینه پسند خوتکار برنومه پروکسی من نومگه @@ -168,7 +167,7 @@ ز نوم دامنه sniffed تینا سی تور جوستن استفاڌه کۊنین وو نشۊوی مۉرد نزرن و عونوان نشۊوی IP ووردارین. ر وندن DNS مهلی - DNS پردازشت وابیڌه و دس هسته ماژول DNS (پؽشنهاڌ ابۊ، ٱر نیاز هڌ ک جوستن تور وو ولات ٱسلین دور زنی) + درخاستا DNS و هسته و من ایان وو و دست ماژول DNS پردازشت ابۊن (پؽشنهاڌ ابۊ ٱر لنگ تور جوستن سی دور زیڌن نشۊویا LAN وو وولات ٱسلی هڌین فعال بۊ) ر وندن DNS جئلی DNS مهلی نشۊویا IP جئلی ن وورگنه (زل تر، ٱما گاشڌ من یقرد ز برنومه یل کار نکونه) @@ -182,7 +181,7 @@ VPN DNS (تینا IPv4/v6) VPN ز شبکه مهلی اگوڌرته؟ - VPN Interface Address + نشۊوی رابت VPN DNS منی (اختیاری) DNS From 1f42d7fc07d4699e5af4546bf25122b6e1f6ad26 Mon Sep 17 00:00:00 2001 From: Hossein Abaspanah <63148255+hosseinabaspanah@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:09:05 +0330 Subject: [PATCH 42/45] Update strings.xml (#4696) --- .../src/main/res/values-bqi-rIR/strings.xml | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index 21b7186f..df275ff3 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -175,18 +175,18 @@ ترجی IPv6 تورا IPv6 ن فعال کۊنین وو نشۊویا IPv6 ن ترجی بڌین - DNS ز ر دیر (اختیاری) (udp/tcp/https/quic) (اختیاری) + ز ر دیر (اختیاری) DNS (udp/tcp/https/quic) (اختیاری) DNS VPN DNS (تینا IPv4/v6) - VPN ز شبکه مهلی اگوڌرته؟ + ز شبکه مهلی اگوڌرته؟ VPN نشۊوی رابت VPN - DNS منی (اختیاری) + منی (اختیاری) DNS DNS - DNS هاست موستقیم (قالوو: دامنه: نشۊوی،...) + هاست موستقیم (قالوو: دامنه: نشۊوی،...) DNS دامنه:نشۊوی،... نشۊوی اینترنتی آزمایش تئخیر واقعی (http/https) @@ -206,20 +206,20 @@ پورت DNS مهلی قوۊل کردن پاک کردن کانفیگ - سی پاک وابیڌن فایل کانفیگ نیاز به قوۊل کردن دووارته ز سمت منتور هڌ + سی پاک وابیڌن فایل کانفیگ نیاز به قوۊل کردن دووارته ز سمت منتور هڌ. زی اسکنن ر ون - شؽواتگرن سی اسکن، زی مجال ر وندن بۊگۊشین، اندی ترین کودن اسکن کۊنین یا شؽواتی ن منه نوار ٱوزار پسند کۊنین. + شؽواتگرن سی اسکن، زی مجال ر وندن بۊگۊشین، ٱندی ترین کودن اسکن کۊنین یا شؽواتی ن منه نوار ٱوزار پسند کۊنین. پروکسی HTTP ن و VPN ازاف کۊنین پروکسی HTTP ن موسقیمن ز (مۊرۊرگر/ی قرد ز برنومه یل لادراری بیڌه)، بؽ استفاڌه ز دسگا NIC مجازی (Android 10+) استفاڌه ابۊ. ر وندن نشۉݩ داڌن دو سۊتۊنی - نومگه نمایه یل من دو سۊتۊن نشۉݩ داڌه ابۊن وو چینۉ ترین موئتوا بیشتری ن سیل کۊنین. سی ر وستن وا برنومه ن ز نۊ ر ونین. + نومگه نمایه یل من دو سۊتۊن نشۉݩ داڌه ابۊن وو چینۉ ترین موئتوا بیشتری ن سیل کۊنین. سی ر وستن، وا برنومه ن ز نۊ ر ونین. فشناڌن منشڌ - فشناڌن منشڌ یا داسوو موشکلا من Github + فشناڌن منشڌ یا داسووݩ موشکلا من Github ٱووڌن من جرگه تلگرام برنومه تلگرامن نجوست هریم سیخومی @@ -240,7 +240,7 @@ فاسله ورۊ کردن خوتکار (اقلن وا 15 دؽقه بۊ) سئت داسووا - Outbound domain pre-resolve method + بارت پؽش هل دامنه دری هالت سی دووسمندیا وو هیاری بیشتر، ری ای هؽل بزݩ زۉݩ @@ -373,9 +373,9 @@ - Do not resolve - Resolve and add to DNS Hosts - Resolve and replace domain + هل وو فسل مکۊنین + هل وو ٱووردن و میزبووݩ یل دامنه DNS + هل وو جایونی دامنه From 8e03de8055872c11e4e2eccfbc1817c7182b30af Mon Sep 17 00:00:00 2001 From: Hossein Abaspanah <63148255+hosseinabaspanah@users.noreply.github.com> Date: Sat, 28 Jun 2025 04:15:00 +0330 Subject: [PATCH 43/45] Update strings.xml (#4698) Add "title_core_settings" string --- V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml index df275ff3..90e5cc26 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -140,6 +140,7 @@ سامووا سامووا پؽش رئڌه + سامووا هسته سامووا VPN پروکسی و ری برنومه پوی وولاتی: برنومه واجۊری بیڌه پروکسی هڌ، منپیز موستقیم بؽ نشووه هڌ. هالت دور زیڌن: برنومه نشووک ناڌه موستقیمن منپیز هڌ، پروکسی نشووک زیڌه نؽڌ. گۊزینه پسند خوتکار برنومه پروکسی من نومگه From 3f778a1ea239d2f6780acab734776ffe76cd242d Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 28 Jun 2025 10:02:25 +0800 Subject: [PATCH 44/45] Optimize the source of tls sni --- .../com/v2ray/ang/handler/V2rayConfigManager.kt | 14 +++++++++++--- .../com/v2ray/ang/service/V2RayServiceManager.kt | 2 +- .../app/src/main/java/com/v2ray/ang/util/Utils.kt | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index fc77271e..f53697bb 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -97,7 +97,7 @@ object V2rayConfigManager { val result = ConfigResult(false) val address = config.server ?: return result - if (!Utils.isIpAddress(address)) { + if (!Utils.isPureIpAddress(address)) { if (!Utils.isValidUrl(address)) { Log.w(AppConfig.TAG, "$address is an invalid ip or domain") return result @@ -154,7 +154,7 @@ object V2rayConfigManager { val result = ConfigResult(false) val address = config.server ?: return result - if (!Utils.isIpAddress(address)) { + if (!Utils.isPureIpAddress(address)) { if (!Utils.isValidUrl(address)) { Log.w(AppConfig.TAG, "$address is an invalid ip or domain") return result @@ -1052,7 +1052,15 @@ object V2rayConfigManager { fun populateTlsSettings(streamSettings: StreamSettingsBean, profileItem: ProfileItem, sniExt: String?) { val streamSecurity = profileItem.security.orEmpty() val allowInsecure = profileItem.insecure == true - val sni = if (profileItem.sni.isNullOrEmpty()) sniExt else profileItem.sni + val sni = if (profileItem.sni.isNullOrEmpty()) { + when { + sniExt.isNotNullEmpty() && Utils.isDomainName(sniExt) -> sniExt + profileItem.server.isNotNullEmpty() && Utils.isDomainName(profileItem.server) -> profileItem.server + else -> sniExt + } + } else { + profileItem.sni + } val fingerprint = profileItem.fingerPrint val alpns = profileItem.alpn val publicKey = profileItem.publicKey diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayServiceManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayServiceManager.kt index 659158a5..4f42ca23 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayServiceManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/service/V2RayServiceManager.kt @@ -102,7 +102,7 @@ object V2RayServiceManager { val config = MmkvManager.decodeServerConfig(guid) ?: return if (config.configType != EConfigType.CUSTOM && !Utils.isValidUrl(config.server) - && !Utils.isIpAddress(config.server) + && !Utils.isPureIpAddress(config.server.orEmpty()) ) return // val result = V2rayConfigUtil.getV2rayConfig(context, guid) // if (!result.status) return diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/util/Utils.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/util/Utils.kt index 6a61afe5..148ce4ec 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/util/Utils.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/util/Utils.kt @@ -198,6 +198,21 @@ object Utils { return isIpv4Address(value) || isIpv6Address(value) } + /** + * Check if a string is a valid domain name. + * + * A valid domain name must not be an IP address and must be a valid URL format. + * + * @param input The string to check. + * @return True if the string is a valid domain name, false otherwise. + */ + fun isDomainName(input: String?): Boolean { + if (input.isNullOrEmpty()) return false + + // Must not be an IP address and must be a valid URL format + return !isPureIpAddress(input) && isValidUrl(input) + } + /** * Check if a string is a valid IPv4 address. * From 3bf911da9c5a7c1092e3f8594e08a5ae5d29b9bc Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:27:57 +0800 Subject: [PATCH 45/45] up 1.10.8 --- V2rayNG/app/build.gradle.kts | 4 ++-- V2rayNG/gradle/libs.versions.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/V2rayNG/app/build.gradle.kts b/V2rayNG/app/build.gradle.kts index 2e3ab596..1624786c 100644 --- a/V2rayNG/app/build.gradle.kts +++ b/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 657 - versionName = "1.10.7" + versionCode = 658 + versionName = "1.10.8" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';') diff --git a/V2rayNG/gradle/libs.versions.toml b/V2rayNG/gradle/libs.versions.toml index 5bdd1236..04900e8c 100644 --- a/V2rayNG/gradle/libs.versions.toml +++ b/V2rayNG/gradle/libs.versions.toml @@ -20,7 +20,7 @@ swiperefreshlayout = "1.1.0" toasty = "1.5.2" editorkit = "2.9.0" core = "3.5.3" -workRuntimeKtx = "2.10.1" +workRuntimeKtx = "2.10.2" lifecycleViewmodelKtx = "2.9.1" multidex = "2.0.1" mockitoMockitoInline = "5.2.0"