diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/V2rayConfig.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/V2rayConfig.kt index cfc771b1..b8b0ad9e 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/V2rayConfig.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/V2rayConfig.kt @@ -29,7 +29,7 @@ data class V2rayConfig( const val DEFAULT_NETWORK = "tcp" const val TLS = "tls" - const val XTLS = "xtls" + const val REALITY = "reality" const val HTTP = "http" } @@ -130,7 +130,7 @@ data class V2rayConfig( var httpSettings: HttpSettingsBean? = null, var tlsSettings: TlsSettingsBean? = null, var quicSettings: QuicSettingBean? = null, - var xtlsSettings: TlsSettingsBean? = null, + var realitySettings: TlsSettingsBean? = null, var grpcSettings: GrpcSettingsBean? = null, val dsSettings: Any? = null, val sockopt: Any? = null @@ -189,7 +189,12 @@ data class V2rayConfig( val fingerprint: String? = null, val certificates: List? = null, val disableSystemRoot: Boolean? = null, - val enableSessionResumption: Boolean? = null) + val enableSessionResumption: Boolean? = null, + // REALITY settings + val show: Boolean = true, + var publicKey: String? = null, + var shortId: String? = null, + var spiderX: String? = null) data class QuicSettingBean(var security: String = "none", var key: String = "", @@ -265,20 +270,24 @@ data class V2rayConfig( return sni } - fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String, fingerprint: String?, alpns: String?) { + fun populateTlsSettings(streamSecurity: String, allowInsecure: Boolean, sni: String, fingerprint: String?, alpns: String?, + publicKey: String?, shortId: String?, spiderX: String?) { security = streamSecurity val tlsSetting = TlsSettingsBean( - allowInsecure = allowInsecure, - serverName = sni, - fingerprint = fingerprint, - alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() } + allowInsecure = allowInsecure, + serverName = sni, + fingerprint = fingerprint, + alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() }, + publicKey = publicKey, + shortId = shortId, + spiderX = spiderX ) if (security == TLS) { tlsSettings = tlsSetting - xtlsSettings = null - } else if (security == XTLS) { + realitySettings = null + } else if (security == REALITY) { tlsSettings = null - xtlsSettings = tlsSetting + realitySettings = tlsSetting } } } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt index 7fc1973b..e5ac4dc6 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ServerActivity.kt @@ -15,6 +15,7 @@ import com.v2ray.ang.dto.EConfigType import com.v2ray.ang.dto.ServerConfig import com.v2ray.ang.dto.V2rayConfig import com.v2ray.ang.dto.V2rayConfig.Companion.DEFAULT_PORT +import com.v2ray.ang.dto.V2rayConfig.Companion.TLS import com.v2ray.ang.extension.toast import com.v2ray.ang.util.MmkvManager import com.v2ray.ang.util.MmkvManager.ID_MAIN @@ -84,14 +85,24 @@ class ServerActivity : BaseActivity() { private val sp_security: Spinner? by lazy { findViewById(R.id.sp_security) } private val sp_stream_security: Spinner? by lazy { findViewById(R.id.sp_stream_security) } private val sp_allow_insecure: Spinner? by lazy { findViewById(R.id.sp_allow_insecure) } + private val container_allow_insecure: LinearLayout? by lazy { findViewById(R.id.l5) } private val et_sni: EditText? by lazy { findViewById(R.id.et_sni) } + private val container_sni: LinearLayout? by lazy { findViewById(R.id.l2) } private val sp_stream_fingerprint: Spinner? by lazy { findViewById(R.id.sp_stream_fingerprint) } //uTLS + private val container_fingerprint: LinearLayout? by lazy { findViewById(R.id.l3) } private val sp_network: Spinner? by lazy { findViewById(R.id.sp_network) } private val sp_header_type: Spinner? by lazy { findViewById(R.id.sp_header_type) } private val sp_header_type_title: TextView? by lazy { findViewById(R.id.sp_header_type_title) } private val et_request_host: EditText? by lazy { findViewById(R.id.et_request_host) } private val et_path: EditText? by lazy { findViewById(R.id.et_path) } private val sp_stream_alpn: Spinner? by lazy { findViewById(R.id.sp_stream_alpn) } //uTLS + private val container_alpn: LinearLayout? by lazy { findViewById(R.id.l4) } + private val et_public_key: EditText? by lazy { findViewById(R.id.et_public_key) } + private val container_public_key: LinearLayout? by lazy { findViewById(R.id.l6) } + private val et_short_id: EditText? by lazy { findViewById(R.id.et_short_id) } + private val container_short_id: LinearLayout? by lazy { findViewById(R.id.l7) } + private val et_spider_x: EditText? by lazy { findViewById(R.id.et_spider_x) } + private val container_spider_x: LinearLayout? by lazy { findViewById(R.id.l8) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -126,6 +137,37 @@ class ServerActivity : BaseActivity() { // do nothing } } + sp_stream_security?.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + if (streamSecuritys[position].isBlank()) { + container_sni?.visibility = View.GONE + container_fingerprint?.visibility = View.GONE + container_alpn?.visibility = View.GONE + container_allow_insecure?.visibility = View.GONE + container_public_key?.visibility = View.GONE + container_short_id?.visibility = View.GONE + container_spider_x?.visibility = View.GONE + } else { + container_sni?.visibility = View.VISIBLE + container_fingerprint?.visibility = View.VISIBLE + container_alpn?.visibility = View.VISIBLE + if (streamSecuritys[position] == TLS) { + container_allow_insecure?.visibility = View.VISIBLE + container_public_key?.visibility = View.GONE + container_short_id?.visibility = View.GONE + container_spider_x?.visibility = View.GONE + } else { + container_allow_insecure?.visibility = View.GONE + container_public_key?.visibility = View.VISIBLE + container_short_id?.visibility = View.VISIBLE + container_spider_x?.visibility = View.VISIBLE + } + } + } + override fun onNothingSelected(p0: AdapterView<*>?) { + // do nothing + } + } if (config != null) { bindingServer(config) } else { @@ -169,13 +211,11 @@ class ServerActivity : BaseActivity() { val streamSecurity = Utils.arrayFind(streamSecuritys, streamSetting.security) if (streamSecurity >= 0) { sp_stream_security?.setSelection(streamSecurity) - (streamSetting.tlsSettings?: streamSetting.xtlsSettings)?.let { tlsSetting -> - val allowinsecure = Utils.arrayFind(allowinsecures, tlsSetting.allowInsecure.toString()) - if (allowinsecure >= 0) { - sp_allow_insecure?.setSelection(allowinsecure) - } + (streamSetting.tlsSettings?: streamSetting.realitySettings)?.let { tlsSetting -> + container_sni?.visibility = View.VISIBLE + container_fingerprint?.visibility = View.VISIBLE + container_alpn?.visibility = View.VISIBLE et_sni?.text = Utils.getEditable(tlsSetting.serverName) - tlsSetting.fingerprint?.let { val utlsIndex = Utils.arrayFind(uTlsItems, tlsSetting.fingerprint) sp_stream_fingerprint?.setSelection(utlsIndex) @@ -184,7 +224,33 @@ class ServerActivity : BaseActivity() { val alpnIndex = Utils.arrayFind(alpns, Utils.removeWhiteSpace(tlsSetting.alpn.joinToString())!!) sp_stream_alpn?.setSelection(alpnIndex) } - + if (streamSetting.tlsSettings != null) { + container_allow_insecure?.visibility = View.VISIBLE + val allowinsecure = Utils.arrayFind(allowinsecures, tlsSetting.allowInsecure.toString()) + if (allowinsecure >= 0) { + sp_allow_insecure?.setSelection(allowinsecure) + } + container_public_key?.visibility = View.GONE + container_short_id?.visibility = View.GONE + container_spider_x?.visibility = View.GONE + } else { // reality settings + container_public_key?.visibility = View.VISIBLE + et_public_key?.text = Utils.getEditable(tlsSetting.publicKey.orEmpty()) + container_short_id?.visibility = View.VISIBLE + et_short_id?.text = Utils.getEditable(tlsSetting.shortId.orEmpty()) + container_spider_x?.visibility = View.VISIBLE + et_spider_x?.text = Utils.getEditable(tlsSetting.spiderX.orEmpty()) + container_allow_insecure?.visibility = View.GONE + } + } + if (streamSetting.tlsSettings == null && streamSetting.realitySettings == null) { + container_sni?.visibility = View.GONE + container_fingerprint?.visibility = View.GONE + container_alpn?.visibility = View.GONE + container_allow_insecure?.visibility = View.GONE + container_public_key?.visibility = View.GONE + container_short_id?.visibility = View.GONE + container_spider_x?.visibility = View.GONE } } val network = Utils.arrayFind(networks, streamSetting.network) @@ -304,12 +370,6 @@ class ServerActivity : BaseActivity() { } } else if (config.configType == EConfigType.TROJAN) { server.password = et_id.text.toString().trim() - server.flow = - if (streamSecuritys[sp_stream_security?.selectedItemPosition ?: 0] == V2rayConfig.XTLS) { - flows[sp_flow?.selectedItemPosition ?: 0] - } else { - "" - } } } @@ -323,6 +383,9 @@ class ServerActivity : BaseActivity() { val streamSecurity = sp_stream_security?.selectedItemPosition ?: return var utlsIndex = sp_stream_fingerprint?.selectedItemPosition ?: return var alpnIndex = sp_stream_alpn?.selectedItemPosition ?: return + val publicKey = et_public_key?.text?.toString()?.trim() ?: return + val shortId = et_short_id?.text?.toString()?.trim() ?: return + val spiderX = et_spider_x?.text?.toString()?.trim() ?: return var sni = streamSetting.populateTransportSettings( transport = networks[network], @@ -344,7 +407,16 @@ class ServerActivity : BaseActivity() { allowinsecures[allowInsecureField].toBoolean() } - streamSetting.populateTlsSettings(streamSecuritys[streamSecurity], allowInsecure, sni, uTlsItems[utlsIndex], alpns[alpnIndex]) + streamSetting.populateTlsSettings( + streamSecurity = streamSecuritys[streamSecurity], + allowInsecure = allowInsecure, + sni = sni, + fingerprint = uTlsItems[utlsIndex], + alpns = alpns[alpnIndex], + publicKey = publicKey, + shortId = shortId, + spiderX = spiderX + ) } private fun transportTypes(network: String?): Array { 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 c4a3c4a5..0b0d53cf 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 @@ -145,7 +145,7 @@ object AngConfigManager { } var fingerprint = streamSetting.tlsSettings?.fingerprint streamSetting.populateTlsSettings(vmessBean.streamSecurity, allowInsecure, - vmessBean.sni.ifBlank { sni }, fingerprint, null) + vmessBean.sni.ifBlank { sni }, fingerprint, null, null, null, null) } } val key = MmkvManager.encodeServerConfig(vmessBean.guid, config) @@ -221,7 +221,8 @@ object AngConfigManager { val fingerprint = vmessQRCode.fp ?: streamSetting.tlsSettings?.fingerprint streamSetting.populateTlsSettings(vmessQRCode.tls, allowInsecure, - if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni, fingerprint, vmessQRCode.alpn) + if (TextUtils.isEmpty(vmessQRCode.sni)) sni else vmessQRCode.sni, + fingerprint, vmessQRCode.alpn, null, null, null) } } } else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) { @@ -305,11 +306,13 @@ object AngConfigManager { queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"], queryParam["mode"], queryParam["serviceName"]) fingerprint = queryParam["fp"] ?: "" - config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS, allowInsecure, queryParam["sni"] ?: sni!!, fingerprint, queryParam["alpn"]) + config.outboundBean?.streamSettings?.populateTlsSettings(queryParam["security"] ?: TLS, + allowInsecure, queryParam["sni"] ?: sni!!, fingerprint, queryParam["alpn"], + null, null, null) flow = queryParam["flow"] ?: "" } else { - - config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "", fingerprint, null) + config.outboundBean?.streamSettings?.populateTlsSettings(TLS, allowInsecure, "", + fingerprint, null, null, null, null) } config.outboundBean?.settings?.servers?.get(0)?.let { server -> @@ -339,7 +342,8 @@ object AngConfigManager { queryParam["host"], queryParam["path"], queryParam["seed"], queryParam["quicSecurity"], queryParam["key"], queryParam["mode"], queryParam["serviceName"]) fingerprint = queryParam["fp"] ?: "" - streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure, queryParam["sni"] ?: sni, fingerprint, queryParam["alpn"]) + streamSetting.populateTlsSettings(queryParam["security"] ?: "", allowInsecure, + queryParam["sni"] ?: sni, fingerprint, queryParam["alpn"], null, null, null) } if (config == null){ return R.string.toast_incorrect_protocol @@ -384,7 +388,8 @@ object AngConfigManager { queryParam["host"]?.split("|")?.get(0) ?: "", queryParam["path"]?.takeIf { it.trim() != "/" } ?: "", queryParam["seed"], queryParam["security"], queryParam["key"], queryParam["mode"], queryParam["serviceName"]) - streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni, fingerprint, null) + streamSetting.populateTlsSettings(if (tls) TLS else "", allowInsecure, sni, fingerprint, null, + null, null, null) true }.getOrElse { false } } @@ -529,7 +534,7 @@ object AngConfigManager { } dicQuery["security"] = streamSetting.security.ifEmpty { "none" } - (streamSetting.tlsSettings?: streamSetting.xtlsSettings)?.let { tlsSetting -> + (streamSetting.tlsSettings?: streamSetting.realitySettings)?.let { tlsSetting -> if (!TextUtils.isEmpty(tlsSetting.serverName)) { dicQuery["sni"] = tlsSetting.serverName } diff --git a/V2rayNG/app/src/main/res/layout/activity_server_trojan.xml b/V2rayNG/app/src/main/res/layout/activity_server_trojan.xml index 757a6c78..88eb70f7 100644 --- a/V2rayNG/app/src/main/res/layout/activity_server_trojan.xml +++ b/V2rayNG/app/src/main/res/layout/activity_server_trojan.xml @@ -98,24 +98,6 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml index b9c898b7..387a4349 100644 --- a/V2rayNG/app/src/main/res/values/arrays.xml +++ b/V2rayNG/app/src/main/res/values/arrays.xml @@ -57,7 +57,7 @@ tls - xtls + reality @@ -116,12 +116,6 @@ - xtls-rprx-origin - xtls-rprx-origin-udp443 - xtls-rprx-direct - xtls-rprx-direct-udp443 - xtls-rprx-splice - xtls-rprx-splice-udp443 xtls-rprx-vision xtls-rprx-vision-udp443 diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 2a053f39..47be27cb 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -61,6 +61,9 @@ User(Optional) encryption flow + public key + short Id + spiderX Success Failure There is nothing