fix(vless): scope testseed to xtls-rprx-vision flow

testseed is only meaningful for the exact xtls-rprx-vision flow, but the
panel was emitting it for any non-empty flow (including the UDP variant)
and keeping it on the inbound after the flow was cleared via the client
modal. Tighten the gate end-to-end:

- VLESSSettings.toJson (inbound + outbound) now only emits testseed when
  the flow is exactly xtls-rprx-vision and the array is 4 positive ints;
  default state is empty so unmodified inbounds omit the field entirely.
- canEnableVisionSeed drops the udp443 variant per spec.
- Form adds a tooltip + theme-aware help text and an inline error when
  the user partially fills the four inputs; submit is blocked in that
  state. Reset clears to empty (= use server defaults).
- UpdateInboundClient strips a now-orphaned testseed when the spliced
  client no longer leaves any XRV flow in the inbound.
- MigrationRequirements cleans up legacy rows where testseed lingered
  after flow changes or was saved for non-XRV flows by older versions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MHSanaei
2026-05-07 14:44:33 +02:00
parent 3349dcbc13
commit 79a7e7a5b5
5 changed files with 173 additions and 102 deletions

View File

@@ -81,30 +81,38 @@
</template>
<template v-if="inbound.canEnableVisionSeed()">
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
<a-form-item label="Vision Seed">
<a-form-item
:validate-status="testseedError() ? 'error' : ''"
:help="testseedError() || ''">
<template slot="label">
Vision Seed
<a-tooltip title="Optional. Controls XTLS Vision padding. Provide exactly 4 positive integers, or leave empty to use defaults: [900, 500, 900, 256].">
<a-icon type="question-circle" :style="{ marginLeft: '4px' }"></a-icon>
</a-tooltip>
</template>
<a-row :gutter="8">
<a-col :span="6">
<a-input-number
:value="(inbound.settings.testseed && inbound.settings.testseed[0] !== undefined) ? inbound.settings.testseed[0] : 900"
@change="(val) => updateTestseed(0, val)" :min="0" :max="9999" :style="{ width: '100%' }" placeholder="900"
:value="(inbound.settings.testseed && inbound.settings.testseed[0] !== undefined) ? inbound.settings.testseed[0] : null"
@change="(val) => updateTestseed(0, val)" :min="1" :max="9999" :style="{ width: '100%' }" placeholder="900"
addon-before="[0]"></a-input-number>
</a-col>
<a-col :span="6">
<a-input-number
:value="(inbound.settings.testseed && inbound.settings.testseed[1] !== undefined) ? inbound.settings.testseed[1] : 500"
@change="(val) => updateTestseed(1, val)" :min="0" :max="9999" :style="{ width: '100%' }" placeholder="500"
:value="(inbound.settings.testseed && inbound.settings.testseed[1] !== undefined) ? inbound.settings.testseed[1] : null"
@change="(val) => updateTestseed(1, val)" :min="1" :max="9999" :style="{ width: '100%' }" placeholder="500"
addon-before="[1]"></a-input-number>
</a-col>
<a-col :span="6">
<a-input-number
:value="(inbound.settings.testseed && inbound.settings.testseed[2] !== undefined) ? inbound.settings.testseed[2] : 900"
@change="(val) => updateTestseed(2, val)" :min="0" :max="9999" :style="{ width: '100%' }" placeholder="900"
:value="(inbound.settings.testseed && inbound.settings.testseed[2] !== undefined) ? inbound.settings.testseed[2] : null"
@change="(val) => updateTestseed(2, val)" :min="1" :max="9999" :style="{ width: '100%' }" placeholder="900"
addon-before="[2]"></a-input-number>
</a-col>
<a-col :span="6">
<a-input-number
:value="(inbound.settings.testseed && inbound.settings.testseed[3] !== undefined) ? inbound.settings.testseed[3] : 256"
@change="(val) => updateTestseed(3, val)" :min="0" :max="9999" :style="{ width: '100%' }" placeholder="256"
:value="(inbound.settings.testseed && inbound.settings.testseed[3] !== undefined) ? inbound.settings.testseed[3] : null"
@change="(val) => updateTestseed(3, val)" :min="1" :max="9999" :style="{ width: '100%' }" placeholder="256"
addon-before="[3]"></a-input-number>
</a-col>
</a-row>
@@ -116,6 +124,10 @@
Reset
</a-button>
</a-space>
<div :style="{ marginTop: '6px', fontSize: '12px', color: 'inherit', opacity: 0.65, lineHeight: 1.4 }">
Optional. Controls XTLS Vision padding behavior (used only for xtls-rprx-vision).
Provide exactly four positive integers to customize padding; otherwise leave empty to use safe defaults.
</div>
</a-form-item>
</a-form>
<a-divider :style="{ margin: '5px 0' }"></a-divider>