Bump xtls/xray-core to 50231eaf (v26.7.11) and the three binary pins
(DockerInit.sh, release.yml x2) in lockstep.
Adapt the panel to the upstream changes:
- Shadowsocks "none"/"plain" and VMess "none"/"zero" were removed from
the core. A migration rewrites stored none/plain SS methods to a
supported cipher and none/zero VMess security to "auto" (on both the
clients column and inbound settings JSON); the SS build-time heal does
the same so a row injected after boot cannot brick startup. The removed
values are dropped from every frontend option list, schema and adapter,
and coerced to "auto" at the Go link/sub/Clash emit sites and both link
importers. Fix the CipherType_NONE sentinel that no longer compiles.
- Unencrypted vless/trojan outbounds to a public address are now refused
by the core. Validate outbounds through the vendored config loader when
saving the xray template and when storing/merging outbound
subscriptions, so one such outbound cannot keep the core from starting.
- New TCP finalmask type "xmc" (Minecraft mimicry): add it to the sub
link allowlist, the frontend enum and the FinalMask form (hostname,
usernames, required password), and document it.
- streamSettings gained a "method" alias for "network"; canonicalize it
to "network" at inbound save time and in the form adapters/schema so a
method-keyed config keeps its transport.
- New root "env" config key is passed through xray.Config, compared in
Equals, and forces a restart in the hot diff.
- REALITY now defaults minClientVer to 26.3.27; update the form
placeholder.
When a client expired or hit its traffic limit, XrayTrafficJob called
RestartXray(true), stopping the whole process and dropping every live
connection on every inbound (#5712 reported this as XHTTP on 443 dying) —
even though disableInvalidClients had already removed the user from the
running core over gRPC. The force restart existed only to re-sync the
process's config snapshot.
Switch the job to a non-forced restart and teach ComputeHotDiff to express
a client-only inbound change as per-user AlterInbound operations for
vless/vmess/trojan, so the reconcile is a no-op RemoveUser plus a snapshot
update rather than a handler swap that would still blip that inbound's
listener. Anything beyond the clients list still falls back to handler
replacement or a full restart as before.
Closes#5712
Add a hot-apply layer that computes a diff between the old and new
generated config and applies only the changed parts through the Xray
gRPC HandlerService and RoutingService, avoiding a full process restart
whenever possible. A restart is still performed when sections that have
no reload API (log, dns, policy, observatory, ...) actually change.
Key additions:
- internal/xray/hot_diff.go: ComputeHotDiff with canonical-JSON
comparison (sorted keys, null=absent, full number precision) so UI
reformatting never triggers a spurious restart
- internal/xray/api.go: AddOutbound/DelOutbound, ApplyRoutingConfig,
GetBalancerInfo, SetBalancerTarget, TestRoute gRPC wrappers
- internal/web/service/xray.go: tryHotApply, ensureAPIServices,
GetBalancersStatus, OverrideBalancer, TestRoute service methods
- internal/web/controller/xray_setting.go: balancerStatus,
balancerOverride, routeTest API endpoints
- frontend: BalancersTab live-status/override columns, RouteTester
component, Restart button removed (Save now hot-applies)
- balancer-helpers.ts: syncObservatories never creates observatory
sections for random/roundRobin balancers (no reload API → restart)
- i18n: balancerLive/Override/routeTester keys added to all 13 locales