From a4558cf954490ed66c010bdadbe12fb3ffdbb694 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Tue, 16 Nov 2021 20:44:20 +0800
Subject: [PATCH 1/5] Add support for sharing ipv6 addresses
---
.../kotlin/com/v2ray/ang/extension/_Ext.kt | 4 ++
.../com/v2ray/ang/util/AngConfigManager.kt | 53 ++++++++++---------
.../main/kotlin/com/v2ray/ang/util/Utils.kt | 8 +++
3 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt
index e238ff274..9d8291c00 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt
@@ -6,6 +6,7 @@ import android.widget.Toast
import com.v2ray.ang.AngApplication
import me.drakeet.support.toast.ToastCompat
import org.json.JSONObject
+import java.net.URI
import java.net.URLConnection
/**
@@ -74,3 +75,6 @@ private fun Float.toShortString(): String {
val URLConnection.responseLength: Long
get() = if (Build.VERSION.SDK_INT >= 24) contentLengthLong else contentLength.toLong()
+
+val URI.idnHost: String
+ get() = (host!!).replace("[", "").replace("]", "")
\ No newline at end of file
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
index 8888ecb06..85f49198e 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
@@ -18,6 +18,7 @@ import com.v2ray.ang.dto.V2rayConfig.Companion.TLS
import com.v2ray.ang.util.MmkvManager.KEY_SELECTED_SERVER
import java.net.URI
import java.util.*
+import com.v2ray.ang.extension.idnHost
object AngConfigManager {
private val mainStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_MAIN, MMKV.MULTI_PROCESS_MODE) }
@@ -53,27 +54,31 @@ object AngConfigManager {
}
private fun copyLegacySettings(sharedPreferences: SharedPreferences) {
- listOf(AppConfig.PREF_MODE,
- AppConfig.PREF_REMOTE_DNS,
- AppConfig.PREF_DOMESTIC_DNS,
-// AppConfig.PREF_LOCAL_DNS_PORT,
-// AppConfig.PREF_SOCKS_PORT,
-// AppConfig.PREF_HTTP_PORT,
-// AppConfig.PREF_LOGLEVEL,
- AppConfig.PREF_ROUTING_DOMAIN_STRATEGY,
- AppConfig.PREF_ROUTING_MODE,
- AppConfig.PREF_V2RAY_ROUTING_AGENT,
- AppConfig.PREF_V2RAY_ROUTING_BLOCKED,
- AppConfig.PREF_V2RAY_ROUTING_DIRECT,).forEach { key ->
+ listOf(
+ AppConfig.PREF_MODE,
+ AppConfig.PREF_REMOTE_DNS,
+ AppConfig.PREF_DOMESTIC_DNS,
+ AppConfig.PREF_LOCAL_DNS_PORT,
+// AppConfig.PREF_SOCKS_PORT,
+// AppConfig.PREF_HTTP_PORT,
+// AppConfig.PREF_LOGLEVEL,
+ AppConfig.PREF_ROUTING_DOMAIN_STRATEGY,
+ AppConfig.PREF_ROUTING_MODE,
+ AppConfig.PREF_V2RAY_ROUTING_AGENT,
+ AppConfig.PREF_V2RAY_ROUTING_BLOCKED,
+ AppConfig.PREF_V2RAY_ROUTING_DIRECT,
+ ).forEach { key ->
settingsStorage?.encode(key, sharedPreferences.getString(key, null))
}
- listOf(AppConfig.PREF_SPEED_ENABLED,
- AppConfig.PREF_PROXY_SHARING,
- AppConfig.PREF_LOCAL_DNS_ENABLED,
-// AppConfig.PREF_ALLOW_INSECURE,
-// AppConfig.PREF_PREFER_IPV6,
- AppConfig.PREF_PER_APP_PROXY,
- AppConfig.PREF_BYPASS_APPS,).forEach { key ->
+ listOf(
+ AppConfig.PREF_SPEED_ENABLED,
+ AppConfig.PREF_PROXY_SHARING,
+ AppConfig.PREF_LOCAL_DNS_ENABLED,
+// AppConfig.PREF_ALLOW_INSECURE,
+// AppConfig.PREF_PREFER_IPV6,
+ AppConfig.PREF_PER_APP_PROXY,
+ AppConfig.PREF_BYPASS_APPS,
+ ).forEach { key ->
settingsStorage?.encode(key, sharedPreferences.getBoolean(key, false))
}
settingsStorage?.encode(AppConfig.PREF_SNIFFING_ENABLED, sharedPreferences.getBoolean(AppConfig.PREF_SNIFFING_ENABLED, true))
@@ -281,7 +286,7 @@ object AngConfigManager {
config = ServerConfig.create(EConfigType.TROJAN)
config.remarks = uri.fragment ?: ""
config.outboundBean?.settings?.servers?.get(0)?.let { server ->
- server.address = uri.host
+ server.address = uri.idnHost
server.port = uri.port
server.password = uri.userInfo
}
@@ -300,7 +305,7 @@ object AngConfigManager {
val streamSetting = config.outboundBean?.streamSettings ?: return -1
config.remarks = uri.fragment ?: ""
config.outboundBean?.settings?.vnext?.get(0)?.let { vnext ->
- vnext.address = uri.host
+ vnext.address = uri.idnHost
vnext.port = uri.port
vnext.users[0].id = uri.userInfo
vnext.users[0].encryption = queryParam["encryption"] ?: "none"
@@ -344,7 +349,7 @@ object AngConfigManager {
val streamSetting = config.outboundBean?.streamSettings ?: return false
config.remarks = uri.fragment
config.outboundBean.settings?.vnext?.get(0)?.let { vnext ->
- vnext.address = uri.host
+ vnext.address = uri.idnHost
vnext.port = uri.port
vnext.users[0].id = uuid
vnext.users[0].encryption = DEFAULT_SECURITY
@@ -501,7 +506,7 @@ object AngConfigManager {
val url = String.format("%s@%s:%s",
outbound.getPassword(),
- outbound.getServerAddress(),
+ Utils.getIpv6Address(outbound.getServerAddress()!!),
outbound.getServerPort())
url + query + remark
}
@@ -515,7 +520,7 @@ object AngConfigManager {
}
val url = String.format("%s@%s:%s",
outbound.getPassword(),
- outbound.getServerAddress(),
+ Utils.getIpv6Address(outbound.getServerAddress()!!),
outbound.getServerPort())
url + query + remark
}
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
index e81cfecf9..804011c85 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
@@ -477,5 +477,13 @@ object Utils {
it.bufferedReader().readText()
}
}
+
+ fun getIpv6Address(address: String): String {
+ return if (isIpv6Address(address)) {
+ String.format("[%s]", address)
+ } else {
+ address
+ }
+ }
}
From 2b21203c53a25dd544ece315ffa6d802af817d34 Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sat, 25 Dec 2021 10:43:07 +0800
Subject: [PATCH 2/5] Update AngConfigManager.kt
---
.../src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
index 85f49198e..3d0537c5f 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
@@ -284,7 +284,7 @@ object AngConfigManager {
} else if (str.startsWith(EConfigType.TROJAN.protocolScheme)) {
val uri = URI(str)
config = ServerConfig.create(EConfigType.TROJAN)
- config.remarks = uri.fragment ?: ""
+ config.remarks = Utils.urlDecode(uri.fragment ?: "")
config.outboundBean?.settings?.servers?.get(0)?.let { server ->
server.address = uri.idnHost
server.port = uri.port
@@ -303,7 +303,7 @@ object AngConfigManager {
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
config = ServerConfig.create(EConfigType.VLESS)
val streamSetting = config.outboundBean?.streamSettings ?: return -1
- config.remarks = uri.fragment ?: ""
+ config.remarks = Utils.urlDecode(uri.fragment ?: "")
config.outboundBean?.settings?.vnext?.get(0)?.let { vnext ->
vnext.address = uri.idnHost
vnext.port = uri.port
@@ -347,7 +347,7 @@ object AngConfigManager {
.associate { it.split("=").let { (k, v) -> k to Utils.urlDecode(v) } }
val streamSetting = config.outboundBean?.streamSettings ?: return false
- config.remarks = uri.fragment
+ config.remarks = Utils.urlDecode(uri.fragment ?: "")
config.outboundBean.settings?.vnext?.get(0)?.let { vnext ->
vnext.address = uri.idnHost
vnext.port = uri.port
From 5a368440369d62a28963d4f83463e832703fdf6c Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Sun, 29 May 2022 19:04:32 +0800
Subject: [PATCH 3/5] add Shadowsocks-2022 for xray-core
---
V2rayNG/app/src/main/res/values/arrays.xml | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml
index 3d5d469f5..ba9a23ce1 100644
--- a/V2rayNG/app/src/main/res/values/arrays.xml
+++ b/V2rayNG/app/src/main/res/values/arrays.xml
@@ -8,14 +8,15 @@
- zero
- - aes-256-cfb
- - aes-128-cfb
- - chacha20
- - chacha20-ietf
- aes-256-gcm
- aes-128-gcm
- chacha20-poly1305
- chacha20-ietf-poly1305
+ - none
+ - plain
+ - 2022-blake3-aes-128-gcm
+ - 2022-blake3-aes-256-gcm
+ - 2022-blake3-chacha20-poly1305
From c6579556c42e72d85b3beca4dcdb3441f1f6887a Mon Sep 17 00:00:00 2001
From: 2dust <31833384+2dust@users.noreply.github.com>
Date: Tue, 31 May 2022 15:39:41 +0800
Subject: [PATCH 4/5] Support 2022-blake3 share
---
.../com/v2ray/ang/util/AngConfigManager.kt | 81 +++++++++++++------
1 file changed, 57 insertions(+), 24 deletions(-)
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
index 3d0537c5f..34427d31c 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
@@ -218,35 +218,37 @@ object AngConfigManager {
}
}
} else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) {
- var result = str.replace(EConfigType.SHADOWSOCKS.protocolScheme, "")
- val indexSplit = result.indexOf("#")
config = ServerConfig.create(EConfigType.SHADOWSOCKS)
- if (indexSplit > 0) {
- try {
- config.remarks = Utils.urlDecode(result.substring(indexSplit + 1, result.length))
- } catch (e: Exception) {
- e.printStackTrace()
- }
+ if (!tryResolveResolveSip002(str, config)) {
+ var result = str.replace(EConfigType.SHADOWSOCKS.protocolScheme, "")
+ val indexSplit = result.indexOf("#")
+ if (indexSplit > 0) {
+ try {
+ config.remarks = Utils.urlDecode(result.substring(indexSplit + 1, result.length))
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
- result = result.substring(0, indexSplit)
- }
+ result = result.substring(0, indexSplit)
+ }
- //part decode
- val indexS = result.indexOf("@")
- result = if (indexS > 0) {
- Utils.decode(result.substring(0, indexS)) + result.substring(indexS, result.length)
- } else {
- Utils.decode(result)
- }
+ //part decode
+ val indexS = result.indexOf("@")
+ result = if (indexS > 0) {
+ Utils.decode(result.substring(0, indexS)) + result.substring(indexS, result.length)
+ } else {
+ Utils.decode(result)
+ }
- val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)/?$".toRegex()
- val match = legacyPattern.matchEntire(result) ?: return R.string.toast_incorrect_protocol
+ val legacyPattern = "^(.+?):(.*)@(.+?):(\\d+?)/?$".toRegex()
+ val match = legacyPattern.matchEntire(result) ?: return R.string.toast_incorrect_protocol
- config.outboundBean?.settings?.servers?.get(0)?.let { server ->
- server.address = match.groupValues[3].removeSurrounding("[", "]")
- server.port = match.groupValues[4].toInt()
- server.password = match.groupValues[2]
- server.method = match.groupValues[1].lowercase()
+ config.outboundBean?.settings?.servers?.get(0)?.let { server ->
+ server.address = match.groupValues[3].removeSurrounding("[", "]")
+ server.port = match.groupValues[4].toInt()
+ server.password = match.groupValues[2]
+ server.method = match.groupValues[1].lowercase()
+ }
}
} else if (str.startsWith(EConfigType.SOCKS.protocolScheme)) {
var result = str.replace(EConfigType.SOCKS.protocolScheme, "")
@@ -393,6 +395,37 @@ object AngConfigManager {
return true
}
+ private fun tryResolveResolveSip002(server: String, config: ServerConfig): Boolean {
+ val uri = URI(server.replace(" ", "%20"))
+ config.remarks = Utils.urlDecode(uri.fragment ?: "")
+
+ val method: String
+ val password: String
+ if (uri.userInfo.contains(":")) {
+ val arrUserInfo = uri.userInfo.split(":").map { it.trim() }
+ if (arrUserInfo.count() < 2) {
+ return false
+ }
+ method = arrUserInfo[0]
+ password = Utils.urlDecode(arrUserInfo[1])
+ } else {
+ val arrUserInfo = Utils.decode(uri.userInfo).split(":").map { it.trim() }
+ if (arrUserInfo.count() < 2) {
+ return false
+ }
+ method = arrUserInfo[0]
+ password = arrUserInfo[1]
+ }
+
+ config.outboundBean?.settings?.servers?.get(0)?.let { server ->
+ server.address = uri.idnHost
+ server.port = uri.port
+ server.password = password
+ server.method = method
+ }
+ return true
+ }
+
/**
* share config
*/
From b4d970552e5b694687126eea51250ab17269abdc Mon Sep 17 00:00:00 2001
From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com>
Date: Fri, 17 Jun 2022 20:10:26 -0400
Subject: [PATCH 5/5] Fix ss2022 import for multi clients format
---
.../kotlin/com/v2ray/ang/util/AngConfigManager.kt | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
index 34427d31c..6f12e7f61 100644
--- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
+++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
@@ -395,26 +395,27 @@ object AngConfigManager {
return true
}
- private fun tryResolveResolveSip002(server: String, config: ServerConfig): Boolean {
- val uri = URI(server.replace(" ", "%20"))
+ private fun tryResolveResolveSip002(str: String, config: ServerConfig): Boolean {
+ val uri = URI(str.replace(" ", "%20"))
config.remarks = Utils.urlDecode(uri.fragment ?: "")
val method: String
val password: String
if (uri.userInfo.contains(":")) {
val arrUserInfo = uri.userInfo.split(":").map { it.trim() }
- if (arrUserInfo.count() < 2) {
+ if (arrUserInfo.count() != 2) {
return false
}
method = arrUserInfo[0]
password = Utils.urlDecode(arrUserInfo[1])
} else {
- val arrUserInfo = Utils.decode(uri.userInfo).split(":").map { it.trim() }
- if (arrUserInfo.count() < 2) {
+ val base64Decode = Utils.decode(uri.userInfo)
+ val arrUserInfo = base64Decode.split(":").map { it.trim() }
+ if (arrUserInfo.count() != 2 && arrUserInfo.count() != 3) {
return false
}
method = arrUserInfo[0]
- password = arrUserInfo[1]
+ password = base64Decode.substringAfter(":")
}
config.outboundBean?.settings?.servers?.get(0)?.let { server ->