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 ->