diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt index e035f687..4dd19c8f 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/ProfileItem.kt @@ -40,6 +40,8 @@ data class ProfileItem( var alpn: String? = null, var fingerPrint: String? = null, var insecure: Boolean? = null, + var echConfigList: String? = null, + var echForceQuery: String? = null, var publicKey: String? = null, var shortId: String? = null, diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt index 2b3ddbfc..1a598d31 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/dto/V2rayConfig.kt @@ -267,6 +267,8 @@ data class V2rayConfig( val certificates: List? = null, val disableSystemRoot: Boolean? = null, val enableSessionResumption: Boolean? = null, + var echConfigList: String? = null, + var echForceQuery: String? = null, // REALITY settings val show: Boolean = false, var publicKey: String? = null, 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 bbd2989c..2ba5d9de 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 @@ -82,6 +82,7 @@ open class FmtBase { config.sni = queryParam["sni"] config.fingerPrint = queryParam["fp"] config.alpn = queryParam["alpn"] + config.echConfigList = queryParam["ech"] config.publicKey = queryParam["pbk"] config.shortId = queryParam["sid"] config.spiderX = queryParam["spx"] @@ -100,6 +101,7 @@ open class FmtBase { dicQuery["security"] = config.security?.ifEmpty { "none" }.orEmpty() config.sni.let { if (it.isNotNullEmpty()) dicQuery["sni"] = it.orEmpty() } config.alpn.let { if (it.isNotNullEmpty()) dicQuery["alpn"] = it.orEmpty() } + config.echConfigList.let { if (it.isNotNullEmpty()) dicQuery["ech"] = it.orEmpty() } config.fingerPrint.let { if (it.isNotNullEmpty()) dicQuery["fp"] = it.orEmpty() } config.publicKey.let { if (it.isNotNullEmpty()) dicQuery["pbk"] = it.orEmpty() } config.shortId.let { if (it.isNotNullEmpty()) dicQuery["sid"] = it.orEmpty() } 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 5b09dabe..f70e427f 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 @@ -1223,6 +1223,8 @@ object V2rayConfigManager { } val fingerprint = profileItem.fingerPrint val alpns = profileItem.alpn + val echConfigList = profileItem.echConfigList + val echForceQuery = profileItem.echForceQuery val publicKey = profileItem.publicKey val shortId = profileItem.shortId val spiderX = profileItem.spiderX @@ -1235,6 +1237,8 @@ object V2rayConfigManager { serverName = if (sni.isNullOrEmpty()) null else sni, fingerprint = if (fingerprint.isNullOrEmpty()) null else fingerprint, alpn = if (alpns.isNullOrEmpty()) null else alpns.split(",").map { it.trim() }.filter { it.isNotEmpty() }, + echConfigList = if (echConfigList.isNullOrEmpty()) null else echConfigList, + echForceQuery = if (echForceQuery.isNullOrEmpty()) null else echForceQuery, publicKey = if (publicKey.isNullOrEmpty()) null else publicKey, shortId = if (shortId.isNullOrEmpty()) null else shortId, spiderX = if (spiderX.isNullOrEmpty()) null else spiderX, diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt index 4e2ebf93..b29c77a1 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt @@ -82,6 +82,9 @@ class ServerActivity : BaseActivity() { private val xhttpMode: Array by lazy { resources.getStringArray(R.array.xhttp_mode) } + private val echForceQuerys: Array by lazy { + resources.getStringArray(R.array.ech_force_query_value) + } // Kotlin synthetics was used, but since it is removed in 1.8. We switch to old manual approach. @@ -130,6 +133,10 @@ class ServerActivity : BaseActivity() { private val et_bandwidth_up: EditText? by lazy { findViewById(R.id.et_bandwidth_up) } private val et_extra: EditText? by lazy { findViewById(R.id.et_extra) } private val layout_extra: LinearLayout? by lazy { findViewById(R.id.layout_extra) } + private val et_ech_config_list: EditText? by lazy { findViewById(R.id.et_ech_config_list) } + private val container_ech_config_list: LinearLayout? by lazy { findViewById(R.id.lay_ech_config_list) } + private val sp_ech_force_query: Spinner? by lazy { findViewById(R.id.sp_ech_force_query) } + private val container_ech_force_query: LinearLayout? by lazy { findViewById(R.id.lay_ech_force_query) } override fun onCreate(savedInstanceState: Bundle?) { @@ -263,7 +270,9 @@ class ServerActivity : BaseActivity() { container_public_key, container_short_id, container_spider_x, - container_mldsa65_verify + container_mldsa65_verify, + container_ech_config_list, + container_ech_force_query ).forEach { it?.visibility = View.GONE } } @@ -272,9 +281,11 @@ class ServerActivity : BaseActivity() { listOf( container_sni, container_fingerprint, - container_alpn + container_alpn, + container_allow_insecure, + container_ech_config_list, + container_ech_force_query ).forEach { it?.visibility = View.VISIBLE } - container_allow_insecure?.visibility = View.VISIBLE listOf( container_public_key, container_short_id, @@ -285,11 +296,16 @@ class ServerActivity : BaseActivity() { // Case 3: Other reality values else -> { - listOf(container_sni, container_fingerprint).forEach { - it?.visibility = View.VISIBLE - } - container_alpn?.visibility = View.GONE - container_allow_insecure?.visibility = View.GONE + listOf( + container_sni, + container_fingerprint + ).forEach { it?.visibility = View.VISIBLE } + listOf( + container_alpn, + container_allow_insecure, + container_ech_config_list, + container_ech_force_query + ).forEach { it?.visibility = View.GONE } listOf( container_public_key, container_short_id, @@ -357,10 +373,6 @@ class ServerActivity : BaseActivity() { val streamSecurity = Utils.arrayFind(streamSecuritys, config.security.orEmpty()) if (streamSecurity >= 0) { sp_stream_security?.setSelection(streamSecurity) - container_sni?.visibility = View.VISIBLE - container_fingerprint?.visibility = View.VISIBLE - container_alpn?.visibility = View.VISIBLE - et_sni?.text = Utils.getEditable(config.sni) config.fingerPrint?.let { it -> val utlsIndex = Utils.arrayFind(uTlsItems, it) @@ -371,42 +383,23 @@ class ServerActivity : BaseActivity() { alpnIndex.let { sp_stream_alpn?.setSelection(if (it >= 0) it else 0) } } if (config.security == TLS) { - container_allow_insecure?.visibility = View.VISIBLE val allowinsecure = Utils.arrayFind(allowinsecures, config.insecure.toString()) if (allowinsecure >= 0) { sp_allow_insecure?.setSelection(allowinsecure) } - listOf( - container_public_key, - container_short_id, - container_spider_x, - container_mldsa65_verify - ).forEach { it?.visibility = View.GONE } + et_ech_config_list?.text = Utils.getEditable(config.echConfigList) + config.echForceQuery?.let { it -> + val index = Utils.arrayFind(echForceQuerys, it) + index.let { sp_ech_force_query?.setSelection(if (it >= 0) it else 0) } + } } else if (config.security == REALITY) { - container_public_key?.visibility = View.VISIBLE et_public_key?.text = Utils.getEditable(config.publicKey.orEmpty()) - container_short_id?.visibility = View.VISIBLE et_short_id?.text = Utils.getEditable(config.shortId.orEmpty()) - container_spider_x?.visibility = View.VISIBLE et_spider_x?.text = Utils.getEditable(config.spiderX.orEmpty()) - container_mldsa65_verify?.visibility = View.VISIBLE et_mldsa65_verify?.text = Utils.getEditable(config.mldsa65Verify.orEmpty()) - container_allow_insecure?.visibility = View.GONE } } - if (config.security.isNullOrEmpty()) { - listOf( - container_sni, - container_fingerprint, - container_alpn, - container_allow_insecure, - container_public_key, - container_short_id, - container_spider_x, - container_mldsa65_verify - ).forEach { it?.visibility = View.GONE } - } val network = Utils.arrayFind(networks, config.network.orEmpty()) if (network >= 0) { sp_network?.setSelection(network) @@ -569,6 +562,8 @@ class ServerActivity : BaseActivity() { val shortId = et_short_id?.text?.toString() val spiderX = et_spider_x?.text?.toString() val mldsa65Verify = et_mldsa65_verify?.text?.toString() + val echConfigList = et_ech_config_list?.text?.toString() + val echForceQueryIndex = sp_ech_force_query?.selectedItemPosition ?: 0 val allowInsecure = if (allowInsecureField == null || allowinsecures[allowInsecureField].isBlank()) { @@ -586,6 +581,8 @@ class ServerActivity : BaseActivity() { config.shortId = shortId config.spiderX = spiderX config.mldsa65Verify = mldsa65Verify + config.echConfigList = echConfigList + config.echForceQuery = echForceQuerys[echForceQueryIndex] } private fun transportTypes(network: String?): Array { diff --git a/V2rayNG/app/src/main/res/layout/layout_tls.xml b/V2rayNG/app/src/main/res/layout/layout_tls.xml index 1866660f..c75a79f0 100644 --- a/V2rayNG/app/src/main/res/layout/layout_tls.xml +++ b/V2rayNG/app/src/main/res/layout/layout_tls.xml @@ -113,7 +113,49 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_spacing_dp8" android:layout_marginBottom="@dimen/padding_spacing_dp8" - android:entries="@array/allowinsecures" /> + android:entries="@array/allowinsecures" + android:nextFocusDown="@+id/et_ech_config_list"/> + + + + + + + + + + + + + + + + android:nextFocusDown="@+id/et_short_id" /> @@ -154,7 +196,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:nextFocusDown="@+id/et_spider_x" /> @@ -175,7 +217,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:nextFocusDown="@+id/et_mldsa65_verify" /> @@ -195,8 +237,7 @@ android:id="@+id/et_mldsa65_verify" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="text" - android:nextFocusDown="@+id/sp_stream_fingerprint" /> + android:inputType="text" /> \ No newline at end of file diff --git a/V2rayNG/app/src/main/res/values-ar/strings.xml b/V2rayNG/app/src/main/res/values-ar/strings.xml index 6bd3bc8e..a263f6d2 100644 --- a/V2rayNG/app/src/main/res/values-ar/strings.xml +++ b/V2rayNG/app/src/main/res/values-ar/strings.xml @@ -114,6 +114,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery فشل نسخ الملف، يرجى استخدام مدير الملفات diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index bd8bcf5c..2ab6c414 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -113,6 +113,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery ফাইল কপি ব্যর্থ, অনুগ্রহ করে ফাইল ম্যানেজার ব্যবহার করুন 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 97c3bee6..36a939fb 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -113,6 +113,8 @@ وا روء رئڌن پئنا باند (واهڌ) هالت XHTTP XHTTP Extra خام JSON، قالوو: { XHTTPObject } + EchConfigList + EchForceQuery لف گیری فایل ٱنجوم نوابی، ز ی برنومه دؽوۉداری فایل هیاری بگرین diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index ff3cd1f8..2d21fe0c 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -113,6 +113,8 @@ افزایش پهنای باند (واحد) حالت XHTTP خام JSON XHTTP Extra، قالب: { XHTTPObject } + EchConfigList + EchForceQuery کپی فایل انجام نشد، لطفا از برنامه مدیریت فایل استفاده کنید diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index de6ecb9d..915f6f04 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -113,6 +113,8 @@ Исходящая пропускная способность (допускаются: k/m/g/t) Режим XHTTP Необработанный JSON XHTTP Extra, формат: { XHTTPObject } + EchConfigList + EchForceQuery Невозможно скопировать файл, используйте файловый менеджер diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index db6d1493..68c8a203 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -113,6 +113,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery Không thể sao chép tệp tin, hãy dùng trình quản lý tệp! 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 102d508d..370e3347 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -113,6 +113,8 @@ 带宽上行 (支持的单位 k/m/g/t) XHTTP 模式 XHTTP Extra 原始 JSON,格式: { XHTTPObject } + EchConfigList + EchForceQuery 失败, 请使用文件管理器 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 b603b59d..a206a350 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -113,6 +113,8 @@ 頻寬上行 (支持的單位 k/m/g/t) XHTTP 模式 XHTTP Extra 原始 JSON,格式: { XHTTPObject } + EchConfigList + EchForceQuery 失敗,請使用檔案總管 diff --git a/V2rayNG/app/src/main/res/values/arrays.xml b/V2rayNG/app/src/main/res/values/arrays.xml index 1cdaede4..e4ceda63 100644 --- a/V2rayNG/app/src/main/res/values/arrays.xml +++ b/V2rayNG/app/src/main/res/values/arrays.xml @@ -215,4 +215,11 @@ 2 + + + none + half + full + + \ 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 29da7c20..3022b215 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -114,6 +114,8 @@ Bandwidth up (Supported units: k/m/g/t) XHTTP Mode XHTTP Extra raw JSON, format: { XHTTPObject } + EchConfigList + EchForceQuery File copy failed, please use File Manager