Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix ss2022 import for multi clients format #1555

Merged
merged 5 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -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("]", "")
141 changes: 90 additions & 51 deletions V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -213,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, "")
Expand Down Expand Up @@ -279,9 +286,9 @@ 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.host
server.address = uri.idnHost
server.port = uri.port
server.password = uri.userInfo
}
Expand All @@ -298,9 +305,9 @@ 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.host
vnext.address = uri.idnHost
vnext.port = uri.port
vnext.users[0].id = uri.userInfo
vnext.users[0].encryption = queryParam["encryption"] ?: "none"
Expand Down Expand Up @@ -342,9 +349,9 @@ 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.host
vnext.address = uri.idnHost
vnext.port = uri.port
vnext.users[0].id = uuid
vnext.users[0].encryption = DEFAULT_SECURITY
Expand Down Expand Up @@ -388,6 +395,38 @@ object AngConfigManager {
return true
}

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) {
return false
}
method = arrUserInfo[0]
password = Utils.urlDecode(arrUserInfo[1])
} else {
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 = base64Decode.substringAfter(":")
}

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
*/
Expand Down Expand Up @@ -501,7 +540,7 @@ object AngConfigManager {

val url = String.format("%s@%s:%s",
outbound.getPassword(),
outbound.getServerAddress(),
Utils.getIpv6Address(outbound.getServerAddress()!!),
outbound.getServerPort())
url + query + remark
}
Expand All @@ -515,7 +554,7 @@ object AngConfigManager {
}
val url = String.format("%s@%s:%s",
outbound.getPassword(),
outbound.getServerAddress(),
Utils.getIpv6Address(outbound.getServerAddress()!!),
outbound.getServerPort())
url + query + remark
}
Expand Down
8 changes: 8 additions & 0 deletions V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -477,5 +477,13 @@ object Utils {
it.bufferedReader().readText()
}
}

fun getIpv6Address(address: String): String {
return if (isIpv6Address(address)) {
String.format("[%s]", address)
} else {
address
}
}
}

9 changes: 5 additions & 4 deletions V2rayNG/app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
<item>zero</item>
</string-array>
<string-array name="ss_securitys" translatable="false">
<item>aes-256-cfb</item>
<item>aes-128-cfb</item>
<item>chacha20</item>
<item>chacha20-ietf</item>
<item>aes-256-gcm</item>
<item>aes-128-gcm</item>
<item>chacha20-poly1305</item>
<item>chacha20-ietf-poly1305</item>
<item>none</item>
<item>plain</item>
<item>2022-blake3-aes-128-gcm</item>
<item>2022-blake3-aes-256-gcm</item>
<item>2022-blake3-chacha20-poly1305</item>
</string-array>

<string-array name="networks" translatable="false">
Expand Down