add maxsplit fragment option (#5821)

* add maxsplit fragment option

* Add a docs folder

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
Enqvyand2dust authored and GitHub committed 2026-06-25 19:08:13 +08:00
1 parent 5436d67e47
commit de351d4438
16 files changed
+106 -2

No files matched your search

@@ -43,6 +43,7 @@ object AppConfig {
const val PREF_FRAGMENT_PACKETS = "pref_fragment_packets" const val PREF_FRAGMENT_PACKETS = "pref_fragment_packets"
const val PREF_FRAGMENT_LENGTH = "pref_fragment_length" const val PREF_FRAGMENT_LENGTH = "pref_fragment_length"
const val PREF_FRAGMENT_INTERVAL = "pref_fragment_interval" const val PREF_FRAGMENT_INTERVAL = "pref_fragment_interval"
const val PREF_FRAGMENT_MAXSPLIT = "pref_fragment_maxsplit"
const val SUBSCRIPTION_UPDATE_TASK_NAME = "subscription_updater" const val SUBSCRIPTION_UPDATE_TASK_NAME = "subscription_updater"
const val SUBSCRIPTION_MIN_INTERVAL_MINUTES = 15L const val SUBSCRIPTION_MIN_INTERVAL_MINUTES = 15L
const val PREF_SPEED_ENABLED = "pref_speed_enabled" const val PREF_SPEED_ENABLED = "pref_speed_enabled"
@@ -624,7 +624,9 @@ object CoreOutboundBuilder {
length = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH) length = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_LENGTH)
?: "50-100", ?: "50-100",
delay = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL) delay = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_INTERVAL)
?: "10-20" ?: "10-20",
maxSplit = MmkvManager.decodeSettingsString(AppConfig.PREF_FRAGMENT_MAXSPLIT)
?: "10"
) )
) )
val noiseMask = OutboundBean.StreamSettingsBean.FinalMaskBean.MaskBean( val noiseMask = OutboundBean.StreamSettingsBean.FinalMaskBean.MaskBean(
@@ -301,7 +301,7 @@ data class V2rayConfig(
val packets: String? = null, val packets: String? = null,
val length: String? = null, val length: String? = null,
val delay: String? = null, val delay: String? = null,
// val maxSplit: String? = null, val maxSplit: String? = null,
// noise // noise
val reset: Int? = null, val reset: Int? = null,
val noise: List<NoiseMaskBean>? = null val noise: List<NoiseMaskBean>? = null
@@ -527,6 +527,7 @@ object SettingsManager {
ensureDefaultValue(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8") ensureDefaultValue(AppConfig.PREF_MUX_XUDP_CONCURRENCY, "8")
ensureDefaultValue(AppConfig.PREF_FRAGMENT_LENGTH, "50-100") ensureDefaultValue(AppConfig.PREF_FRAGMENT_LENGTH, "50-100")
ensureDefaultValue(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20") ensureDefaultValue(AppConfig.PREF_FRAGMENT_INTERVAL, "10-20")
ensureDefaultValue(AppConfig.PREF_FRAGMENT_MAXSPLIT, "10")
} }
private fun ensureDefaultValue(key: String, default: String) { private fun ensureDefaultValue(key: String, default: String) {
@@ -40,6 +40,7 @@ class SettingsActivity : BaseActivity() {
private val fragmentPackets by lazy { findPreference<ListPreference>(AppConfig.PREF_FRAGMENT_PACKETS) } private val fragmentPackets by lazy { findPreference<ListPreference>(AppConfig.PREF_FRAGMENT_PACKETS) }
private val fragmentLength by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_LENGTH) } private val fragmentLength by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_LENGTH) }
private val fragmentInterval by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_INTERVAL) } private val fragmentInterval by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_INTERVAL) }
private val fragmentMaxSplit by lazy { findPreference<EditTextPreference>(AppConfig.PREF_FRAGMENT_MAXSPLIT) }
private val mode by lazy { findPreference<ListPreference>(AppConfig.PREF_MODE) } private val mode by lazy { findPreference<ListPreference>(AppConfig.PREF_MODE) }
@@ -243,6 +244,7 @@ class SettingsActivity : BaseActivity() {
fragmentPackets?.isEnabled = enabled fragmentPackets?.isEnabled = enabled
fragmentLength?.isEnabled = enabled fragmentLength?.isEnabled = enabled
fragmentInterval?.isEnabled = enabled fragmentInterval?.isEnabled = enabled
fragmentMaxSplit?.isEnabled = enabled
} }
private fun updateDynamicSocksPort(enabled: Boolean) { private fun updateDynamicSocksPort(enabled: Boolean) {
@@ -368,6 +368,7 @@
<string name="title_pref_fragment_length">طول الجزء (الحد الأدنى - الحد الأقصى)</string> <string name="title_pref_fragment_length">طول الجزء (الحد الأدنى - الحد الأقصى)</string>
<string name="title_pref_fragment_interval">فاصل الجزء (الحد الأدنى - الحد الأقصى)</string> <string name="title_pref_fragment_interval">فاصل الجزء (الحد الأدنى - الحد الأقصى)</string>
<string name="title_pref_fragment_enabled">تفعيل الجزء</string> <string name="title_pref_fragment_enabled">تفعيل الجزء</string>
<string name="title_pref_fragment_maxsplit">ماكس سبليت الجزء</string>
<string name="update_check_for_update">Check for update</string> <string name="update_check_for_update">Check for update</string>
<string name="update_already_latest_version">Already on the latest version</string> <string name="update_already_latest_version">Already on the latest version</string>
@@ -367,6 +367,7 @@
<string name="title_pref_fragment_length">ফ্র্যাগমেন্ট দৈর্ঘ্য (ন্যূনতম-সর্বাধিক)</string> <string name="title_pref_fragment_length">ফ্র্যাগমেন্ট দৈর্ঘ্য (ন্যূনতম-সর্বাধিক)</string>
<string name="title_pref_fragment_interval">ফ্র্যাগমেন্ট ইন্টারভ্যাল (ন্যূনতম-সর্বাধিক)</string> <string name="title_pref_fragment_interval">ফ্র্যাগমেন্ট ইন্টারভ্যাল (ন্যূনতম-সর্বাধিক)</string>
<string name="title_pref_fragment_enabled">ফ্র্যাগমেন্ট সক্রিয় করুন</string> <string name="title_pref_fragment_enabled">ফ্র্যাগমেন্ট সক্রিয় করুন</string>
<string name="title_pref_fragment_maxsplit">ফ্র্যাগমেন্ট ম্যাক্স স্প্লিট</string>
<string name="update_check_for_update">Check for update</string> <string name="update_check_for_update">Check for update</string>
<string name="update_already_latest_version">Already on the latest version</string> <string name="update_already_latest_version">Already on the latest version</string>
@@ -367,6 +367,7 @@
<string name="title_pref_fragment_length">تۊل کتنا فرگمنت (هدقل-هدکسر)</string> <string name="title_pref_fragment_length">تۊل کتنا فرگمنت (هدقل-هدکسر)</string>
<string name="title_pref_fragment_interval">فاسله منجا کتنا فرگمنت (هدقل-هدکسر)</string> <string name="title_pref_fragment_interval">فاسله منجا کتنا فرگمنت (هدقل-هدکسر)</string>
<string name="title_pref_fragment_enabled">ره وندن فرگمنت</string> <string name="title_pref_fragment_enabled">ره وندن فرگمنت</string>
<string name="title_pref_fragment_maxsplit">مکسیمم تقسیم فرگمنت</string>
<string name="update_check_for_update">واجۊری سی ورۊ رسۊوی</string> <string name="update_check_for_update">واجۊری سی ورۊ رسۊوی</string>
<string name="update_already_latest_version">سکو نوسخه دیندایی پۊرنیڌه هڌ</string> <string name="update_already_latest_version">سکو نوسخه دیندایی پۊرنیڌه هڌ</string>
@@ -364,6 +364,7 @@
<string name="title_pref_fragment_length">طول بسته های فرگمنت (حداقل-حداکثر)</string> <string name="title_pref_fragment_length">طول بسته های فرگمنت (حداقل-حداکثر)</string>
<string name="title_pref_fragment_interval">فاصله بین بسته های فرگمنت (حداقل-حداکثر)</string> <string name="title_pref_fragment_interval">فاصله بین بسته های فرگمنت (حداقل-حداکثر)</string>
<string name="title_pref_fragment_enabled">فعال کردن فرگمنت</string> <string name="title_pref_fragment_enabled">فعال کردن فرگمنت</string>
<string name="title_pref_fragment_maxsplit">حداکثر تقسیم فرگمنت</string>
<string name="update_check_for_update">بررسی به روز رسانی</string> <string name="update_check_for_update">بررسی به روز رسانی</string>
<string name="update_already_latest_version">در حال حاضر آخرین نسخه نصب شده است</string> <string name="update_already_latest_version">در حال حاضر آخرین نسخه نصب شده است</string>
@@ -373,6 +373,7 @@
<string name="title_pref_fragment_length">Длина фрагмента (от — до)</string> <string name="title_pref_fragment_length">Длина фрагмента (от — до)</string>
<string name="title_pref_fragment_interval">Интервал фрагментов (от — до)</string> <string name="title_pref_fragment_interval">Интервал фрагментов (от — до)</string>
<string name="title_pref_fragment_enabled">Использовать фрагментирование</string> <string name="title_pref_fragment_enabled">Использовать фрагментирование</string>
<string name="title_pref_fragment_maxsplit">Максимальное число фрагментов</string>
<string name="update_check_for_update">Проверить обновление</string> <string name="update_check_for_update">Проверить обновление</string>
<string name="update_already_latest_version">Установлена последняя версия</string> <string name="update_already_latest_version">Установлена последняя версия</string>
@@ -369,6 +369,7 @@
<string name="title_pref_fragment_length">Fragment Length (min-max)</string> <string name="title_pref_fragment_length">Fragment Length (min-max)</string>
<string name="title_pref_fragment_interval">Fragment Interval (min-max)</string> <string name="title_pref_fragment_interval">Fragment Interval (min-max)</string>
<string name="title_pref_fragment_enabled">Enable Fragment</string> <string name="title_pref_fragment_enabled">Enable Fragment</string>
<string name="title_pref_fragment_maxsplit">Fragment Max Split</string>
<string name="update_check_for_update">Check for update</string> <string name="update_check_for_update">Check for update</string>
<string name="update_already_latest_version">Already on the latest version</string> <string name="update_already_latest_version">Already on the latest version</string>
@@ -371,6 +371,7 @@
<string name="title_pref_fragment_length">分片包长(最小 - 最大)</string> <string name="title_pref_fragment_length">分片包长(最小 - 最大)</string>
<string name="title_pref_fragment_interval">分片间隔(最小 - 最大)</string> <string name="title_pref_fragment_interval">分片间隔(最小 - 最大)</string>
<string name="title_pref_fragment_enabled">启用分片(Fragment)</string> <string name="title_pref_fragment_enabled">启用分片(Fragment)</string>
<string name="title_pref_fragment_maxsplit">分片最大分割数</string>
<string name="update_check_for_update">检查更新</string> <string name="update_check_for_update">检查更新</string>
<string name="update_already_latest_version">目前已是最新版本</string> <string name="update_already_latest_version">目前已是最新版本</string>
@@ -369,6 +369,7 @@
<string name="title_pref_fragment_length">分片包長(最小-最大)</string> <string name="title_pref_fragment_length">分片包長(最小-最大)</string>
<string name="title_pref_fragment_interval">分片間隔(最小-最大)</string> <string name="title_pref_fragment_interval">分片間隔(最小-最大)</string>
<string name="title_pref_fragment_enabled">啟用分片(Fragment)</string> <string name="title_pref_fragment_enabled">啟用分片(Fragment)</string>
<string name="title_pref_fragment_maxsplit">分片最大分割數</string>
<string name="update_check_for_update">檢查更新</string> <string name="update_check_for_update">檢查更新</string>
<string name="update_already_latest_version">当前已是最新版本</string> <string name="update_already_latest_version">当前已是最新版本</string>
@@ -376,6 +376,7 @@
<string name="title_pref_fragment_length">Fragment Length (min-max)</string> <string name="title_pref_fragment_length">Fragment Length (min-max)</string>
<string name="title_pref_fragment_interval">Fragment Interval (min-max)</string> <string name="title_pref_fragment_interval">Fragment Interval (min-max)</string>
<string name="title_pref_fragment_enabled">Enable Fragment</string> <string name="title_pref_fragment_enabled">Enable Fragment</string>
<string name="title_pref_fragment_maxsplit">Fragment Max Split</string>
<string name="update_check_for_update">Check for update</string> <string name="update_check_for_update">Check for update</string>
<string name="update_already_latest_version">Already on the latest version</string> <string name="update_already_latest_version">Already on the latest version</string>
@@ -264,6 +264,11 @@
android:summary="10-20" android:summary="10-20"
android:title="@string/title_pref_fragment_interval" /> android:title="@string/title_pref_fragment_interval" />
<EditTextPreference
android:key="pref_fragment_maxsplit"
android:summary="10"
android:title="@string/title_pref_fragment_maxsplit" />
<ListPreference <ListPreference
android:defaultValue="tlshello" android:defaultValue="tlshello"
android:entries="@array/fragment_packets" android:entries="@array/fragment_packets"
+84
View File
@@ -0,0 +1,84 @@
# v2rayNG — Agent guide
## Build
```sh
cd V2rayNG
./gradlew assembleFdroidDebug # or assemblePlaystoreDebug
```
Kotlin 2.4.0, AGP 9.2.1, Gradle Kotlin DSL. No lint/format/typecheck tasks configured.
## Test
```sh
cd V2rayNG && ./gradlew test
```
JUnit 4 + Mockito. Unit tests only under `app/src/test/java/`. No instrumented tests beyond defaults.
## Project structure
```
V2rayNG/
app/
src/main/java/com/v2ray/ang/
AngApplication.kt # extends MultiDexApplication, inits MMKV + WorkManager
AppConfig.kt # all constants, pref keys, URLs, ports, tags
core/ # v2ray core integration
CoreServiceManager.kt # start/stop core, traffic stats, delay measurement
CoreConfigManager.kt # generates JSON config for v2ray core
CoreNativeManager.kt # JNI bridge to libv2ray AAR
CoreOutboundBuilder.kt # outbound config construction
CoreConfigContextBuilder.kt
service/ # Android foreground services
CoreVpnService.kt # VPN mode (VpnService)
CoreProxyOnlyService.kt # proxy-only mode (no VPN)
CoreTestService.kt # delay test
TProxyService.kt
DialerNativeService.kt / DialerWebviewService.kt # browser dialer
RealPingWorkerService.kt # WorkManager-based real ping
QSTileService.kt # quick settings tile
ProcessService.kt
handler/ # business logic
MmkvManager.kt # all MMKV CRUD (servers, subs, settings, routing)
SettingsManager.kt # preference defaults, config generation (633 lines)
AngConfigManager.kt # server config operations
NotificationManager.kt
SpeedtestManager.kt
SubscriptionUpdater.kt
WebDavManager.kt
UpdateCheckerManager.kt
CertificateFingerprintManager.kt
SettingsChangeManager.kt
ui/ # activities, adapters, fragments
MainActivity.kt # main screen with drawer + tabs
ServerActivity.kt # edit server config
ServerCustomConfigActivity.kt / ServerGroupActivity.kt / ServerProxyChainActivity.kt
SettingsActivity.kt / PerAppProxyActivity.kt / AppPickerActivity.kt
ScannerActivity.kt / LogcatActivity.kt
RoutingSettingActivity.kt / RoutingEditActivity.kt
SubSettingActivity.kt / SubEditActivity.kt
UserAssetActivity.kt / UserAssetUrlActivity.kt
TaskerActivity.kt / UrlSchemeActivity.kt
BackupActivity.kt / CheckUpdateActivity.kt / AboutActivity.kt
fmt/ # protocol URL parsers (VMESS, VLESS, TROJAN, SS, SOCKS, etc.)
dto/ # data classes + entities/
enums/ # EConfigType, Language, RoutingType, etc.
extension/_Ext.kt # extension functions (toast, traffic string, etc.)
util/ # Utils, JsonUtil, HttpUtil, LogUtil, etc.
receiver/ # BootReceiver, TaskerReceiver, WidgetProvider
contracts/ # interfaces (ServiceControl, Tun2SocksControl)
helper/ # QRCodeScannerHelper, PermissionHelper, FileChooserHelper etc.
```
## Key facts
- **Storage**: MMKV exclusively — never SharedPreferences. `MmkvManager` is the data layer.
- **Core**: Native AAR (`libv2ray`) from [AndroidLibV2rayLite](https://github.com/2dust/AndroidLibV2rayLite) or [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite). Prebuilt `.aar` files go in `app/libs/`.
- **Services** run in dedicated process `:RunSoLibV2RayDaemon`. `CoreServiceManager` controls start/stop lifecycle.
- **Two modes**: VPN (`CoreVpnService`, uses `VpnService.Builder`) or proxy-only (`CoreProxyOnlyService`, local SOCKS/HTTP).
- **Flavors**: `fdroid` (suffix `.fdroid`) and `playstore` (no suffix). ABI version codes differ per flavor.
- **hev-socks5-tunnel**: Optional tun2socks binary. Build with `./compile-hevtun.sh` (requires `NDK_HOME`).
- **ViewBinding** enabled, no DataBinding.
- **No CI**, no pre-commit hooks, no lint/format enforcement.