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
[](https://github.com/2dust/v2rayNG/releases)
[](https://t.me/v2rayn)
-
-
-
-
### 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)
[](https://developer.android.com/about/versions/lollipop)
-[](https://kotlinlang.org)
+[](https://kotlinlang.org)
[](https://github.com/2dust/v2rayNG/commits/master)
[](https://www.codefactor.io/repository/github/2dust/v2rayng)
[](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"