customizable packet fragmentation settings (#9597)

* first changes

* fix: use ItemsSource for fragment packets ComboBox so value saves correctly

* feat: add customizable packet fragmentation for Xray-core

- Add fragment settings in Core tab: Packets (dropdown), Length (range), Interval (range), MaxSplit (0-10000)
- Support both 'from-to' (e.g., 50-100) and single value (e.g., 50) formats for Length, Interval, and MaxSplit
- Validation with shortened error message: 'Invalid range format. Use from-to (e.g., 50-100).'
- UI in PopupBox (materialDesign) visible only when EnableFragment is checked
- Only Xray-core supported (Mihomo/sing-box fragment code removed)
- Localization updated for 8 languages

* fix: address 2dust review feedback

- Move FragmentPacketsOptions to Global class
- Remove default values from Fragment4RayItem model (set in ConfigHandler)
- Fix Avalonia bindings: move ItemsSource and SelectedItem to code-behind
- Update ViewModel to use Global.FragmentPacketsOptions
- Remove defaults from model properties

* Adjust ui

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
This commit is contained in:
Enqvy
2026-06-22 11:30:13 +03:30
committed by GitHub
parent f1b88ccf2a
commit 81c118c9b2
21 changed files with 713 additions and 5 deletions
@@ -300,6 +300,115 @@
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<Button
Grid.Row="20"
Grid.Column="2"
Margin="{StaticResource MarginLr8}"
HorizontalAlignment="Left"
Classes="IconButton">
<Button.Content>
<PathIcon Data="{StaticResource SemiIconMore}">
<PathIcon.RenderTransform>
<RotateTransform Angle="90" />
</PathIcon.RenderTransform>
</PathIcon>
</Button.Content>
<Button.Flyout>
<Flyout>
<StackPanel Margin="{StaticResource Margin8}">
<Grid ColumnDefinitions="Auto,Auto,400" RowDefinitions="Auto,Auto,Auto,Auto,Auto">
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentPackets}" />
<ComboBox
x:Name="cmbFragmentPackets"
Grid.Row="0"
Grid.Column="1"
Width="120"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="0"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentPacketsTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentLength}" />
<TextBox
x:Name="txtFragmentLength"
Grid.Row="1"
Grid.Column="1"
Width="120"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Watermark="50-100" />
<TextBlock
Grid.Row="1"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentLengthTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentInterval}" />
<TextBox
x:Name="txtFragmentInterval"
Grid.Row="2"
Grid.Column="1"
Width="120"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Watermark="10-20" />
<TextBlock
Grid.Row="2"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentIntervalTip}"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentMaxSplit}" />
<TextBox
x:Name="txtFragmentMaxSplit"
Grid.Row="3"
Grid.Column="1"
Width="120"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left"
Watermark="0" />
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsFragmentMaxSplitTip}"
TextWrapping="Wrap" />
</Grid>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<TextBlock
Grid.Row="21"
Grid.Column="0"