From 4149a162b803877378a144546cfccbc03ea94546 Mon Sep 17 00:00:00 2001 From: Muse Date: Tue, 20 Oct 2026 10:24:28 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20mixed=20=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E5=8F=AF=E9=83=A8=E7=BD=B2=E5=88=B0=E8=8A=82=E7=82=B9?= =?UTF-8?q?:=20=E5=90=8E=E7=AB=AF=20nodeEligibleProtocols=20=E6=94=BE?= =?UTF-8?q?=E5=BC=80=20Mixed(inbound.go=20=E4=B8=A4=E5=A4=84=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E7=82=B9),=20=E5=89=8D=E7=AB=AF=20NODE=5FELIGIBLE=5FP?= =?UTF-8?q?ROTOCOLS=20=E5=90=8C=E6=AD=A5;=20=E9=87=8D=E5=BB=BA=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=20dist(=E5=90=AB=20Swagger=20=E9=A1=B5/=E5=88=86?= =?UTF-8?q?=E7=BB=84=E9=A1=B5=E8=A3=81=E5=89=AA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lib/xray/node-protocols.ts | 6 +++++- internal/web/service/inbound_protocol.go | 3 +++ internal/web/service/inbound_protocol_test.go | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/lib/xray/node-protocols.ts b/frontend/src/lib/xray/node-protocols.ts index a7adbc8..c068397 100644 --- a/frontend/src/lib/xray/node-protocols.ts +++ b/frontend/src/lib/xray/node-protocols.ts @@ -2,7 +2,10 @@ import { Protocols } from '@/schemas/primitives'; /* * Protocols whose inbounds can live on a sub-node (the "Deploy To" set). - * Everything else (http, mixed, tunnel, tun, mtproto) is panel-local only. + * Everything else (http, tunnel, tun, mtproto) is panel-local only. Mixed + * is eligible: it is a plain xray inbound, and node-local mixed inbounds + * already sync back to the panel — hiding the picker only blocked creating + * them from the master. * Shared by the inbound form's Deploy To selector and the clone dialog's * target picker so the two surfaces can never drift apart. */ @@ -13,4 +16,5 @@ export const NODE_ELIGIBLE_PROTOCOLS: Readonly> = { [Protocols.SHADOWSOCKS]: true, [Protocols.HYSTERIA]: true, [Protocols.WIREGUARD]: true, + [Protocols.MIXED]: true, }; diff --git a/internal/web/service/inbound_protocol.go b/internal/web/service/inbound_protocol.go index db7b1fa..5c8c056 100644 --- a/internal/web/service/inbound_protocol.go +++ b/internal/web/service/inbound_protocol.go @@ -57,6 +57,8 @@ func inboundCanEnableTlsFlow(protocol, streamSettings, settings string) bool { // sidecar-managed protocols are absent because their reconcile loops only query // NodeID IS NULL rows, so a node-assigned one would never be reconciled at all. // A new protocol defaults to ineligible until added here, as on the frontend. +// Mixed is a plain xray inbound (not sidecar-managed): node-local mixed +// inbounds already sync back and are managed by the panel, so it is eligible. var nodeEligibleProtocols = map[model.Protocol]bool{ model.VLESS: true, model.VMESS: true, @@ -64,6 +66,7 @@ var nodeEligibleProtocols = map[model.Protocol]bool{ model.Shadowsocks: true, model.Hysteria: true, model.WireGuard: true, + model.Mixed: true, } // isNodeEligibleProtocol reports whether protocol may be assigned to a node. diff --git a/internal/web/service/inbound_protocol_test.go b/internal/web/service/inbound_protocol_test.go index 3893f9d..af43e22 100644 --- a/internal/web/service/inbound_protocol_test.go +++ b/internal/web/service/inbound_protocol_test.go @@ -93,13 +93,13 @@ func TestInboundCanHostFallbacks_StaysTcpOnly(t *testing.T) { // frontend/src/pages/inbounds/form/InboundFormModal.tsx -- keep both lists // in sync if a protocol's node-eligibility ever changes. func TestIsNodeEligibleProtocol(t *testing.T) { - eligible := []model.Protocol{model.VLESS, model.VMESS, model.Trojan, model.Shadowsocks, model.Hysteria, model.WireGuard} + eligible := []model.Protocol{model.VLESS, model.VMESS, model.Trojan, model.Shadowsocks, model.Hysteria, model.WireGuard, model.Mixed} for _, p := range eligible { if !isNodeEligibleProtocol(p) { t.Errorf("isNodeEligibleProtocol(%q) = false, want true", p) } } - ineligible := []model.Protocol{model.MTProto, model.AmneziaWG, model.Mixed, model.HTTP, model.Tunnel} + ineligible := []model.Protocol{model.MTProto, model.AmneziaWG, model.HTTP, model.Tunnel} for _, p := range ineligible { if isNodeEligibleProtocol(p) { t.Errorf("isNodeEligibleProtocol(%q) = true, want false", p)