From ae84df7367e8999247db53cfa6922c8affdfe3f7 Mon Sep 17 00:00:00 2001 From: hippo2025 <253848751+hippo2025@users.noreply.github.com> Date: Sat, 25 Apr 2026 19:55:44 +0800 Subject: [PATCH] Add MTU and TTI settings in KCP network (#5539) * Add MTU and TTI settings in KCP network * Rename ProfileItem.tti to kcpTti Rename the ProfileItem field `tti` to `kcpTti` and update all usages accordingly. Changes update parsing/serialization in FmtBase (map query param "tti" to config.kcpTti and emit it), KCP stream settings mapping in V2rayConfigManager, UI bindings in ServerActivity, and equality checks in ProfileItem to use kcpTti. This clarifies that the field applies to KCP-specific TTI values while preserving the external query key. Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com> * Add kcpMtu/kcpTti for KCP transport Introduce kcpMtu and kcpTti properties on ProfileItem and update equality checks. Parse and emit KCP-specific mtu/tti in FmtBase (use kcpMtu/kcpTti instead of the generic mtu). Wire kcpMtu into V2rayConfigManager when building KCP stream settings and update ServerActivity to read/write the UI field to profileItem.kcpMtu/kcpTti. This separates KCP MTU/TTI from the general mtu field and removes a duplicated kcpTti entry. Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com> --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- .../java/com/v2ray/ang/dto/ProfileItem.kt | 5 +++ .../main/java/com/v2ray/ang/fmt/FmtBase.kt | 4 ++ .../v2ray/ang/handler/V2rayConfigManager.kt | 5 ++- .../java/com/v2ray/ang/ui/ServerActivity.kt | 13 ++++++ .../src/main/res/layout/layout_transport.xml | 43 +++++++++++++++++++ .../app/src/main/res/values-ar/strings.xml | 2 + .../app/src/main/res/values-bn/strings.xml | 2 + .../src/main/res/values-bqi-rIR/strings.xml | 2 + .../app/src/main/res/values-fa/strings.xml | 2 + .../app/src/main/res/values-ru/strings.xml | 2 + .../app/src/main/res/values-vi/strings.xml | 2 + .../src/main/res/values-zh-rCN/strings.xml | 2 + .../src/main/res/values-zh-rTW/strings.xml | 2 + V2rayNG/app/src/main/res/values/strings.xml | 2 + 14 files changed, 87 insertions(+), 1 deletion(-) 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 d2737866f..9d4b1c405 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 @@ -29,6 +29,9 @@ data class ProfileItem( var host: String? = null, var path: String? = null, var seed: String? = null, + var kcpMtu: Int? = null, + var kcpTti: Int? = null, + var quicSecurity: String? = null, var quicKey: String? = null, var mode: String? = null, @@ -102,6 +105,8 @@ data class ProfileItem( && this.host == obj.host && this.path == obj.path && this.seed == obj.seed + && this.kcpMtu == obj.kcpMtu + && this.kcpTti == obj.kcpTti && this.quicSecurity == obj.quicSecurity && this.quicKey == obj.quicKey && this.mode == obj.mode 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 d3fd4772a..ac636289b 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 @@ -60,6 +60,8 @@ open class FmtBase { config.path = queryParam["path"] config.seed = queryParam["seed"] + config.kcpMtu = queryParam["mtu"]?.toIntOrNull() + config.kcpTti = queryParam["tti"]?.toIntOrNull() config.quicSecurity = queryParam["quicSecurity"] config.quicKey = queryParam["key"] config.mode = queryParam["mode"] @@ -112,6 +114,8 @@ open class FmtBase { config.mldsa65Verify?.nullIfBlank()?.let { dicQuery["pqv"] = it } config.flow?.nullIfBlank()?.let { dicQuery["flow"] = it } config.finalMask?.nullIfBlank()?.let { dicQuery["fm"] = it } + config.kcpMtu?.let { dicQuery["mtu"] = it.toString() } + config.kcpTti?.let { dicQuery["tti"] = it.toString() } // Add two keys for compatibility: "insecure" and "allowInsecure" if (config.security == AppConfig.TLS) { val insecureFlag = if (config.insecure == true) "1" else "0" 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 1db600228..a2db386f9 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 @@ -1305,7 +1305,10 @@ object V2rayConfigManager { } NetworkType.KCP.type -> { - streamSettings.kcpSettings = StreamSettingsBean.KcpSettingsBean() + val kcpSetting = StreamSettingsBean.KcpSettingsBean() + profileItem.kcpMtu?.let { kcpSetting.mtu = it } + profileItem.kcpTti?.let { kcpSetting.tti = it } + streamSettings.kcpSettings = kcpSetting val udpMaskList = mutableListOf() if (!headerType.isNullOrEmpty() && headerType != "none") { val kcpHeaderType = when { 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 345d29b54..b792d5bac 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 @@ -132,6 +132,9 @@ class ServerActivity : BaseActivity() { private val et_port_hop_interval: EditText? by lazy { findViewById(R.id.et_port_hop_interval) } private val et_bandwidth_down: EditText? by lazy { findViewById(R.id.et_bandwidth_down) } private val et_bandwidth_up: EditText? by lazy { findViewById(R.id.et_bandwidth_up) } + private val et_kcp_mtu: EditText? by lazy { findViewById(R.id.et_kcp_mtu) } + private val et_kcp_tti: EditText? by lazy { findViewById(R.id.et_kcp_tti) } + private val layout_kcp: LinearLayout? by lazy { findViewById(R.id.layout_kcp) } private val et_extra: EditText? by lazy { findViewById(R.id.et_extra) } private val et_fm: EditText? by lazy { findViewById(R.id.et_fm) } private val layout_extra: LinearLayout? by lazy { findViewById(R.id.layout_extra) } @@ -245,6 +248,14 @@ class ServerActivity : BaseActivity() { ) et_fm?.text = Utils.getEditable(config?.finalMask) + layout_kcp?.visibility = + when (networks[position]) { + NetworkType.KCP.type -> View.VISIBLE + else -> View.GONE + } + et_kcp_mtu?.text = Utils.getEditable(config?.kcpMtu?.toString().orEmpty()) + et_kcp_tti?.text = Utils.getEditable(config?.kcpTti?.toString().orEmpty()) + layout_extra?.visibility = when (networks[position]) { NetworkType.XHTTP.type -> View.VISIBLE @@ -569,6 +580,8 @@ class ServerActivity : BaseActivity() { profileItem.xhttpMode = transportTypes(networks[network])[type] profileItem.xhttpExtra = et_extra?.text?.toString()?.trim().nullIfBlank() profileItem.finalMask = et_fm?.text?.toString()?.trim()?.nullIfBlank() + profileItem.kcpMtu = et_kcp_mtu?.text?.toString()?.toIntOrNull() + profileItem.kcpTti = et_kcp_tti?.text?.toString()?.toIntOrNull() } private fun saveTls(config: ProfileItem) { diff --git a/V2rayNG/app/src/main/res/layout/layout_transport.xml b/V2rayNG/app/src/main/res/layout/layout_transport.xml index 07e59251c..9e3190537 100644 --- a/V2rayNG/app/src/main/res/layout/layout_transport.xml +++ b/V2rayNG/app/src/main/res/layout/layout_transport.xml @@ -96,6 +96,49 @@ android:inputType="text" /> + + + + + + + + + + + + + + + + + محجوز (اختياري) العنوان المحلي (اختياري IPv4/IPv6، مفصولة بفواصل) Mtu (اختياري، الافتراضي 1420) + mKCP MTU (اختياري، الافتراضي في النواة 1350) + mKCP TTI (اختياري، الافتراضي في النواة 50) نجاح فشل لا يوجد شيء diff --git a/V2rayNG/app/src/main/res/values-bn/strings.xml b/V2rayNG/app/src/main/res/values-bn/strings.xml index 51a3c7477..6efc80f99 100644 --- a/V2rayNG/app/src/main/res/values-bn/strings.xml +++ b/V2rayNG/app/src/main/res/values-bn/strings.xml @@ -88,6 +88,8 @@ সংরক্ষিত (ঐচ্ছিক) স্থানীয় ঠিকানা (ঐচ্ছিক IPv4/IPv6, কমা দ্বারা পৃথক করা) MTU (ঐচ্ছিক, ডিফল্ট 1420) + mKCP MTU (ঐচ্ছিক, কোর ডিফল্ট 1350) + mKCP TTI (ঐচ্ছিক, কোর ডিফল্ট 50) সফল ব্যর্থ কোনও তথ্য নেই 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 3b173e43c..a92f77093 100644 --- a/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml +++ b/V2rayNG/app/src/main/res/values-bqi-rIR/strings.xml @@ -88,6 +88,8 @@ Reserved(اختیاری، وا کاما ز یک جوڌا ابۊن) نشۊوی مهلی (اختیاری IPv4/IPv6، وا کاما ز یک جوڌا ابۊن) Mtu(اختیاری، پؽش فرز 1420) + mKCP MTU (اختیاری، پؽش فرز هسته 1350) + mKCP TTI (اختیاری، پؽش فرز هسته 50) وا مووفقیت ٱنجوم وابی شکست خرد هیچ داده ای وۊجۊڌ نڌاره diff --git a/V2rayNG/app/src/main/res/values-fa/strings.xml b/V2rayNG/app/src/main/res/values-fa/strings.xml index 4a8dedffb..d7f2d009d 100644 --- a/V2rayNG/app/src/main/res/values-fa/strings.xml +++ b/V2rayNG/app/src/main/res/values-fa/strings.xml @@ -88,6 +88,8 @@ Reserved (اختیاری، جدا شده با کاما) آدرس محلی (IPv4/IPv6 اختیاری، جدا شده با کاما) MTU (اختیاری، پیش‌فرض 1420) + mKCP MTU (اختیاری، پیش‌فرض هسته 1350) + mKCP TTI (اختیاری، پیش‌فرض هسته 50) با موفقیت انجام شد شکست هیچ داده ای وجود ندارد diff --git a/V2rayNG/app/src/main/res/values-ru/strings.xml b/V2rayNG/app/src/main/res/values-ru/strings.xml index 55cba3dfc..474edfae5 100644 --- a/V2rayNG/app/src/main/res/values-ru/strings.xml +++ b/V2rayNG/app/src/main/res/values-ru/strings.xml @@ -88,6 +88,8 @@ Reserved (необязательно, через запятую) Локальный адрес (необязательно, IPv4/IPv6 через запятую) MTU (необязательно, по умолчанию 1420) + mKCP MTU (необязательно, по умолчанию 1350) + mKCP TTI (необязательно, по умолчанию 50) Успешно Ошибка Ничего нет diff --git a/V2rayNG/app/src/main/res/values-vi/strings.xml b/V2rayNG/app/src/main/res/values-vi/strings.xml index 86701ce34..b2da9945d 100644 --- a/V2rayNG/app/src/main/res/values-vi/strings.xml +++ b/V2rayNG/app/src/main/res/values-vi/strings.xml @@ -88,6 +88,8 @@ Reserved (Không bắt buộc) Địa chỉ cục bộ (IPv4 / IPv6, phân cách bằng dấu phẩy) MTU (Không bắt buộc, mặc định là 1420) + mKCP MTU (Không bắt buộc, mặc định core là 1350) + mKCP TTI (Không bắt buộc, mặc định core là 50) Thành công! Đã xảy ra lỗi, vui lòng thử lại! Không có gì ở đây! 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 bc062b87a..b4d031896 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -88,6 +88,8 @@ Reserved (可选,逗号隔开) 本地地址 (可选 IPv4/IPv6,逗号隔开) Mtu (可选, 默认 1420) + mKCP MTU (可选, 默认 1350) + mKCP TTI (可选, 默认 50) 成功 失败 没有数据 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 0d86c26cb..b990e1ad8 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -88,6 +88,8 @@ Reserved (可選,逗號隔開) 本機位址 (可選 IPv4/IPv6,逗號隔開) MTU (可選, 預設 1420) + mKCP MTU (可選, 預設 1350) + mKCP TTI (可選, 預設 50) 成功 失敗 無資料 diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 88a1a3c18..635ff0e22 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -89,6 +89,8 @@ Reserved(Optional, separated by commas) Local address (optional IPv4/IPv6, separated by commas) Mtu(optional, default 1420) + mKCP MTU (Optional, core default 1350) + mKCP TTI (Optional, core default 50) Success Failure There is nothing