mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-04-28 18:36:19 +00:00
sub: kcp finalmask
This commit is contained in:
parent
8529f4f0cf
commit
0aca2d3b3d
4 changed files with 731 additions and 615 deletions
1262
sub/subService.go
1262
sub/subService.go
File diff suppressed because it is too large
Load diff
|
|
@ -1370,6 +1370,50 @@ class Inbound extends XrayCommonClass {
|
|||
}
|
||||
}
|
||||
|
||||
static hasShareableFinalMaskValue(value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.some(item => Inbound.hasShareableFinalMaskValue(item));
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
return Object.values(value).some(item => Inbound.hasShareableFinalMaskValue(item));
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return value.length > 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static serializeFinalMask(finalmask) {
|
||||
if (!finalmask) {
|
||||
return '';
|
||||
}
|
||||
const value = typeof finalmask.toJson === 'function' ? finalmask.toJson() : finalmask;
|
||||
return Inbound.hasShareableFinalMaskValue(value) ? JSON.stringify(value) : '';
|
||||
}
|
||||
|
||||
// Export finalmask with the same compact JSON payload shape that
|
||||
// v2rayN-compatible share links use: fm=<json>.
|
||||
static applyFinalMaskToParams(finalmask, params) {
|
||||
if (!params) return;
|
||||
const payload = Inbound.serializeFinalMask(finalmask);
|
||||
if (payload.length > 0) {
|
||||
params.set("fm", payload);
|
||||
}
|
||||
}
|
||||
|
||||
// VMess links are a base64 JSON object, so keep the same fm payload
|
||||
// under a flat property instead of a URL query string.
|
||||
static applyFinalMaskToObj(finalmask, obj) {
|
||||
if (!obj) return;
|
||||
const payload = Inbound.serializeFinalMask(finalmask);
|
||||
if (payload.length > 0) {
|
||||
obj.fm = payload;
|
||||
}
|
||||
}
|
||||
|
||||
get clients() {
|
||||
switch (this.protocol) {
|
||||
case Protocols.VMESS: return this.settings.vmesses;
|
||||
|
|
@ -1590,6 +1634,8 @@ class Inbound extends XrayCommonClass {
|
|||
Inbound.applyXhttpPaddingToObj(xhttp, obj);
|
||||
}
|
||||
|
||||
Inbound.applyFinalMaskToObj(this.stream.finalmask, obj);
|
||||
|
||||
if (tls === 'tls') {
|
||||
if (!ObjectUtil.isEmpty(this.stream.tls.sni)) {
|
||||
obj.sni = this.stream.tls.sni;
|
||||
|
|
@ -1658,6 +1704,8 @@ class Inbound extends XrayCommonClass {
|
|||
break;
|
||||
}
|
||||
|
||||
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||
|
||||
if (security === 'tls') {
|
||||
params.set("security", "tls");
|
||||
if (this.stream.isTls) {
|
||||
|
|
@ -1761,6 +1809,8 @@ class Inbound extends XrayCommonClass {
|
|||
break;
|
||||
}
|
||||
|
||||
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||
|
||||
if (security === 'tls') {
|
||||
params.set("security", "tls");
|
||||
if (this.stream.isTls) {
|
||||
|
|
@ -1840,6 +1890,8 @@ class Inbound extends XrayCommonClass {
|
|||
break;
|
||||
}
|
||||
|
||||
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||
|
||||
if (security === 'tls') {
|
||||
params.set("security", "tls");
|
||||
if (this.stream.isTls) {
|
||||
|
|
@ -1907,6 +1959,8 @@ class Inbound extends XrayCommonClass {
|
|||
}
|
||||
}
|
||||
|
||||
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||
|
||||
const url = new URL(link);
|
||||
for (const [key, value] of params) {
|
||||
url.searchParams.set(key, value);
|
||||
|
|
|
|||
|
|
@ -992,6 +992,10 @@ class Outbound extends CommonClass {
|
|||
stream.kcp = new KcpStreamSettings();
|
||||
stream.type = json.type;
|
||||
stream.seed = json.path;
|
||||
const mtu = Number(json.mtu);
|
||||
if (Number.isFinite(mtu) && mtu > 0) stream.kcp.mtu = mtu;
|
||||
const tti = Number(json.tti);
|
||||
if (Number.isFinite(tti) && tti > 0) stream.kcp.tti = tti;
|
||||
} else if (network === 'ws') {
|
||||
stream.ws = new WsStreamSettings(json.path, json.host);
|
||||
} else if (network === 'grpc') {
|
||||
|
|
@ -1029,6 +1033,7 @@ class Outbound extends CommonClass {
|
|||
let headerType = url.searchParams.get('headerType') ?? undefined;
|
||||
let host = url.searchParams.get('host') ?? undefined;
|
||||
let path = url.searchParams.get('path') ?? undefined;
|
||||
let seed = url.searchParams.get('seed') ?? path ?? undefined;
|
||||
let mode = url.searchParams.get('mode') ?? undefined;
|
||||
|
||||
if (type === 'tcp' || type === 'none') {
|
||||
|
|
@ -1036,7 +1041,11 @@ class Outbound extends CommonClass {
|
|||
} else if (type === 'kcp') {
|
||||
stream.kcp = new KcpStreamSettings();
|
||||
stream.kcp.type = headerType ?? 'none';
|
||||
stream.kcp.seed = path;
|
||||
stream.kcp.seed = seed;
|
||||
const mtu = Number(url.searchParams.get('mtu'));
|
||||
if (Number.isFinite(mtu) && mtu > 0) stream.kcp.mtu = mtu;
|
||||
const tti = Number(url.searchParams.get('tti'));
|
||||
if (Number.isFinite(tti) && tti > 0) stream.kcp.tti = tti;
|
||||
} else if (type === 'ws') {
|
||||
stream.ws = new WsStreamSettings(path, host);
|
||||
} else if (type === 'grpc') {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,23 @@
|
|||
<script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
|
||||
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
|
||||
<style>
|
||||
.subscription-page tr-qr-box.qr-box {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.subscription-page tr-qr-box.qr-box .qr-tag {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.subscription-page tr-qr-box.qr-box .qr-bg,
|
||||
.subscription-page tr-qr-box.qr-box .qr-bg-sub {
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.subscription-page .subscription-link-box {
|
||||
cursor: pointer;
|
||||
border-radius: 12px;
|
||||
|
|
@ -193,8 +210,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<a-form layout="vertical">
|
||||
|
|
|
|||
Loading…
Reference in a new issue