@@ -710,8 +710,6 @@ object V2rayConfigManager {
710710 } else {
711711 v2rayConfig.outbounds.add(outbound)
712712 }
713-
714- updateOutboundFragment(v2rayConfig)
715713 return true
716714 }
717715
@@ -955,68 +953,80 @@ object V2rayConfigManager {
955953 *
956954 * Configures packet fragmentation for TLS and REALITY protocols if enabled.
957955 *
958- * @param v2rayConfig The V2ray configuration object to be modified
956+ * @param streamSettings The streamSettings object to be modified
959957 * @return true if fragment configuration was successful, false otherwise
960958 */
961- private fun updateOutboundFragment (v2rayConfig : V2rayConfig ): Boolean {
959+ private fun updateOutboundFragment (streamSettings : StreamSettingsBean ): Boolean {
962960 try {
963961 if (MmkvManager .decodeSettingsBool(AppConfig .PREF_FRAGMENT_ENABLED , false ) == false ) {
964962 return true
965963 }
966- if (v2rayConfig.outbounds[ 0 ]. streamSettings? .security != AppConfig .TLS
967- && v2rayConfig.outbounds[ 0 ]. streamSettings? .security != AppConfig .REALITY
964+ if (streamSettings.security != AppConfig .TLS
965+ && streamSettings.security != AppConfig .REALITY
968966 ) {
969967 return true
970968 }
971-
972- val fragmentOutbound =
973- OutboundBean (
974- protocol = AppConfig .PROTOCOL_FREEDOM ,
975- tag = AppConfig .TAG_FRAGMENT ,
976- mux = null
977- )
969+ if (streamSettings.sockopt?.dialerProxy.isNotNullEmpty()) {
970+ return true
971+ }
978972
979973 var packets =
980974 MmkvManager .decodeSettingsString(AppConfig .PREF_FRAGMENT_PACKETS ) ? : " tlshello"
981- if (v2rayConfig.outbounds[ 0 ]. streamSettings? .security == AppConfig .REALITY
975+ if (streamSettings.security == AppConfig .REALITY
982976 && packets == " tlshello"
983977 ) {
984978 packets = " 1-3"
985- } else if (v2rayConfig.outbounds[ 0 ]. streamSettings? .security == AppConfig .TLS
979+ } else if (streamSettings.security == AppConfig .TLS
986980 && packets != " tlshello"
987981 ) {
988982 packets = " tlshello"
989983 }
990984
991- fragmentOutbound.settings = OutSettingsBean (
992- fragment = OutSettingsBean .FragmentBean (
985+ val fragmentMask = StreamSettingsBean .FinalMaskBean .MaskBean (
986+ type = " fragment" ,
987+ settings = StreamSettingsBean .FinalMaskBean .MaskBean .MaskSettingsBean (
993988 packets = packets,
994989 length = MmkvManager .decodeSettingsString(AppConfig .PREF_FRAGMENT_LENGTH )
995990 ? : " 50-100" ,
996- interval = MmkvManager .decodeSettingsString(AppConfig .PREF_FRAGMENT_INTERVAL )
991+ delay = MmkvManager .decodeSettingsString(AppConfig .PREF_FRAGMENT_INTERVAL )
997992 ? : " 10-20"
998- ),
999- noises = listOf (
1000- OutSettingsBean .NoiseBean (
1001- type = " rand" ,
1002- packet = " 10-20" ,
1003- delay = " 10-16" ,
1004- )
1005- ),
993+ )
1006994 )
1007- fragmentOutbound.streamSettings = StreamSettingsBean (
1008- sockopt = StreamSettingsBean .SockoptBean (
1009- TcpNoDelay = true ,
1010- mark = 255
995+ val noiseMask = StreamSettingsBean .FinalMaskBean .MaskBean (
996+ type = " noise" ,
997+ settings = StreamSettingsBean .FinalMaskBean .MaskBean .MaskSettingsBean (
998+ noise = listOf (
999+ StreamSettingsBean .FinalMaskBean .MaskBean .MaskSettingsBean .NoiseMaskBean (
1000+ rand = " 10-20" ,
1001+ delay = " 10-16" ,
1002+ )
1003+ )
10111004 )
10121005 )
1013- v2rayConfig.outbounds.add(fragmentOutbound)
10141006
1015- // proxy chain
1016- v2rayConfig.outbounds[0 ].streamSettings?.sockopt =
1017- StreamSettingsBean .SockoptBean (
1018- dialerProxy = AppConfig .TAG_FRAGMENT
1019- )
1007+ val finalMaskObj = streamSettings.finalmask?.let { existingFinalMask ->
1008+ JsonUtil .parseString(JsonUtil .toJson(existingFinalMask))
1009+ } ? : com.google.gson.JsonObject ()
1010+
1011+ // finalmask.tcp / finalmask.udp are arrays; prepend mask at index 0.
1012+ fun prependMask (scope : String , mask : StreamSettingsBean .FinalMaskBean .MaskBean ) {
1013+ val current = finalMaskObj.get(scope)
1014+ if (current != null && current.isJsonArray && current.asJsonArray.size() > 0 ) {
1015+ return
1016+ }
1017+
1018+ val newArray = JsonArray ()
1019+ newArray.add(JsonUtil .parseString(JsonUtil .toJson(mask)))
1020+
1021+ if (current != null && current.isJsonArray) {
1022+ current.asJsonArray.forEach { newArray.add(it) }
1023+ }
1024+ finalMaskObj.add(scope, newArray)
1025+ }
1026+
1027+ prependMask(" tcp" , fragmentMask)
1028+ prependMask(" udp" , noiseMask)
1029+ streamSettings.finalmask = finalMaskObj
10201030 } catch (e: Exception ) {
10211031 Log .e(AppConfig .TAG , " Failed to update outbound fragment" , e)
10221032 return false
@@ -1402,6 +1412,10 @@ object V2rayConfigManager {
14021412 streamSettings.tlsSettings = null
14031413 streamSettings.realitySettings = tlsSetting
14041414 }
1415+
1416+ if (profileItem.finalMask.isNullOrEmpty()) {
1417+ updateOutboundFragment(streamSettings)
1418+ }
14051419 }
14061420
14071421 // endregion
0 commit comments