mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-04-29 02:46:08 +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() {
|
get clients() {
|
||||||
switch (this.protocol) {
|
switch (this.protocol) {
|
||||||
case Protocols.VMESS: return this.settings.vmesses;
|
case Protocols.VMESS: return this.settings.vmesses;
|
||||||
|
|
@ -1590,6 +1634,8 @@ class Inbound extends XrayCommonClass {
|
||||||
Inbound.applyXhttpPaddingToObj(xhttp, obj);
|
Inbound.applyXhttpPaddingToObj(xhttp, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inbound.applyFinalMaskToObj(this.stream.finalmask, obj);
|
||||||
|
|
||||||
if (tls === 'tls') {
|
if (tls === 'tls') {
|
||||||
if (!ObjectUtil.isEmpty(this.stream.tls.sni)) {
|
if (!ObjectUtil.isEmpty(this.stream.tls.sni)) {
|
||||||
obj.sni = this.stream.tls.sni;
|
obj.sni = this.stream.tls.sni;
|
||||||
|
|
@ -1658,6 +1704,8 @@ class Inbound extends XrayCommonClass {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
params.set("security", "tls");
|
params.set("security", "tls");
|
||||||
if (this.stream.isTls) {
|
if (this.stream.isTls) {
|
||||||
|
|
@ -1761,6 +1809,8 @@ class Inbound extends XrayCommonClass {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
params.set("security", "tls");
|
params.set("security", "tls");
|
||||||
if (this.stream.isTls) {
|
if (this.stream.isTls) {
|
||||||
|
|
@ -1840,6 +1890,8 @@ class Inbound extends XrayCommonClass {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||||
|
|
||||||
if (security === 'tls') {
|
if (security === 'tls') {
|
||||||
params.set("security", "tls");
|
params.set("security", "tls");
|
||||||
if (this.stream.isTls) {
|
if (this.stream.isTls) {
|
||||||
|
|
@ -1907,6 +1959,8 @@ class Inbound extends XrayCommonClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inbound.applyFinalMaskToParams(this.stream.finalmask, params);
|
||||||
|
|
||||||
const url = new URL(link);
|
const url = new URL(link);
|
||||||
for (const [key, value] of params) {
|
for (const [key, value] of params) {
|
||||||
url.searchParams.set(key, value);
|
url.searchParams.set(key, value);
|
||||||
|
|
|
||||||
|
|
@ -992,6 +992,10 @@ class Outbound extends CommonClass {
|
||||||
stream.kcp = new KcpStreamSettings();
|
stream.kcp = new KcpStreamSettings();
|
||||||
stream.type = json.type;
|
stream.type = json.type;
|
||||||
stream.seed = json.path;
|
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') {
|
} else if (network === 'ws') {
|
||||||
stream.ws = new WsStreamSettings(json.path, json.host);
|
stream.ws = new WsStreamSettings(json.path, json.host);
|
||||||
} else if (network === 'grpc') {
|
} else if (network === 'grpc') {
|
||||||
|
|
@ -1029,6 +1033,7 @@ class Outbound extends CommonClass {
|
||||||
let headerType = url.searchParams.get('headerType') ?? undefined;
|
let headerType = url.searchParams.get('headerType') ?? undefined;
|
||||||
let host = url.searchParams.get('host') ?? undefined;
|
let host = url.searchParams.get('host') ?? undefined;
|
||||||
let path = url.searchParams.get('path') ?? undefined;
|
let path = url.searchParams.get('path') ?? undefined;
|
||||||
|
let seed = url.searchParams.get('seed') ?? path ?? undefined;
|
||||||
let mode = url.searchParams.get('mode') ?? undefined;
|
let mode = url.searchParams.get('mode') ?? undefined;
|
||||||
|
|
||||||
if (type === 'tcp' || type === 'none') {
|
if (type === 'tcp' || type === 'none') {
|
||||||
|
|
@ -1036,7 +1041,11 @@ class Outbound extends CommonClass {
|
||||||
} else if (type === 'kcp') {
|
} else if (type === 'kcp') {
|
||||||
stream.kcp = new KcpStreamSettings();
|
stream.kcp = new KcpStreamSettings();
|
||||||
stream.kcp.type = headerType ?? 'none';
|
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') {
|
} else if (type === 'ws') {
|
||||||
stream.ws = new WsStreamSettings(path, host);
|
stream.ws = new WsStreamSettings(path, host);
|
||||||
} else if (type === 'grpc') {
|
} 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/js/util/index.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
|
||||||
<style>
|
<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 {
|
.subscription-page .subscription-link-box {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|
@ -193,8 +210,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<a-form layout="vertical">
|
<a-form layout="vertical">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue