mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-28 00:24:19 +00:00
feat(ui): allow custom fragment packets ranges, not just presets (#5075)
The fragment "packets" field was a locked dropdown (tlshello / 1-3 / 1-5) in both the finalmask TCP-mask form and the Freedom outbound form, while xray-core accepts any "n-m" packet range. Replace both with an AutoComplete that keeps the presets as suggestions and validates free input as "tlshello" or a numeric range.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Button, Divider, Form, Input, InputNumber, Select, Space, Switch } from 'antd';
|
||||
import { AutoComplete, Button, Divider, Form, Input, InputNumber, Select, Space, Switch } from 'antd';
|
||||
import { DeleteOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||
import type { FormInstance } from 'antd/es/form';
|
||||
import type { NamePath } from 'antd/es/form/interface';
|
||||
@@ -205,13 +205,18 @@ function TcpMaskItem({
|
||||
if (type === 'fragment') {
|
||||
return (
|
||||
<>
|
||||
<Form.Item label="Packets" name={[fieldName, 'settings', 'packets']}>
|
||||
<Select
|
||||
<Form.Item
|
||||
label="Packets"
|
||||
name={[fieldName, 'settings', 'packets']}
|
||||
rules={[{ validator: validateFragmentPackets }]}
|
||||
>
|
||||
<AutoComplete
|
||||
options={[
|
||||
{ value: 'tlshello', label: 'tlshello' },
|
||||
{ value: '1-3', label: '1-3' },
|
||||
{ value: '1-5', label: '1-5' },
|
||||
]}
|
||||
placeholder="tlshello or n-m, e.g. 1-3"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
@@ -264,6 +269,16 @@ function TcpMaskItem({
|
||||
);
|
||||
}
|
||||
|
||||
// xray's fragment `packets` accepts "tlshello" or an arbitrary packet-number
|
||||
// range like "1-3" (#5075 — presets only covered the common cases).
|
||||
function validateFragmentPackets(_rule: unknown, value: unknown): Promise<void> {
|
||||
const str = typeof value === 'string' ? value.trim() : String(value ?? '').trim();
|
||||
if (str.length === 0 || str === 'tlshello' || /^\d+-\d+$/.test(str)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error('Use "tlshello" or a packet range like 1-3'));
|
||||
}
|
||||
|
||||
// Walks a deep object path safely. Used inside shouldUpdate which gets
|
||||
// the whole form values blob; we need to compare a deep field across
|
||||
// prev/curr without crashing on missing intermediates.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Input, InputNumber, Select, Switch, type FormInstance } from 'antd';
|
||||
import { AutoComplete, Button, Form, Input, InputNumber, Select, Switch, type FormInstance } from 'antd';
|
||||
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
|
||||
import { OutboundDomainStrategies } from '@/schemas/primitives';
|
||||
@@ -67,12 +67,24 @@ export default function FreedomFields({ form }: { form: FormInstance<OutboundFor
|
||||
<Form.Item
|
||||
label={t('pages.settings.subFormats.packets')}
|
||||
name={['settings', 'fragment', 'packets']}
|
||||
rules={[{
|
||||
validator: (_rule, value) => {
|
||||
const str = String(value ?? '').trim();
|
||||
// xray accepts "tlshello" or any packet-number range (#5075)
|
||||
if (str === '' || str === 'tlshello' || /^\d+-\d+$/.test(str)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error('Use "tlshello" or a packet range like 1-3'));
|
||||
},
|
||||
}]}
|
||||
>
|
||||
<Select
|
||||
<AutoComplete
|
||||
options={[
|
||||
{ value: '1-3', label: '1-3' },
|
||||
{ value: 'tlshello', label: 'tlshello' },
|
||||
{ value: '1-3', label: '1-3' },
|
||||
{ value: '1-5', label: '1-5' },
|
||||
]}
|
||||
placeholder="tlshello or n-m, e.g. 1-3"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('pages.settings.subFormats.length')} name={['settings', 'fragment', 'length']}>
|
||||
|
||||
Reference in New Issue
Block a user