diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
index 6c0ec1ce..bccab5bb 100644
--- a/web/assets/js/model/inbound.js
+++ b/web/assets/js/model/inbound.js
@@ -318,15 +318,13 @@ TcpStreamSettings.TcpResponse = class extends XrayCommonClass {
class KcpStreamSettings extends XrayCommonClass {
constructor(
- mtu = 1250,
- tti = 50,
+ mtu = 1350,
+ tti = 20,
uplinkCapacity = 5,
downlinkCapacity = 20,
congestion = false,
- readBufferSize = 2,
- writeBufferSize = 2,
- type = 'none',
- seed = RandomUtil.randomSeq(10),
+ readBufferSize = 1,
+ writeBufferSize = 1,
) {
super();
this.mtu = mtu;
@@ -336,8 +334,6 @@ class KcpStreamSettings extends XrayCommonClass {
this.congestion = congestion;
this.readBuffer = readBufferSize;
this.writeBuffer = writeBufferSize;
- this.type = type;
- this.seed = seed;
}
static fromJson(json = {}) {
@@ -349,8 +345,6 @@ class KcpStreamSettings extends XrayCommonClass {
json.congestion,
json.readBufferSize,
json.writeBufferSize,
- ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,
- json.seed,
);
}
@@ -363,10 +357,6 @@ class KcpStreamSettings extends XrayCommonClass {
congestion: this.congestion,
readBufferSize: this.readBuffer,
writeBufferSize: this.writeBuffer,
- header: {
- type: this.type,
- },
- seed: this.seed,
};
}
}
@@ -923,6 +913,51 @@ class SockoptStreamSettings extends XrayCommonClass {
}
}
+class FinalMask extends XrayCommonClass {
+ constructor(type = 'salamander', settings = {}) {
+ super();
+ this.type = type;
+ this.settings = this._getDefaultSettings(type, settings);
+ }
+
+ _getDefaultSettings(type, settings = {}) {
+ switch (type) {
+ case 'salamander':
+ case 'mkcp-aes128gcm':
+ return { password: settings.password || '' };
+ case 'header-dns':
+ case 'xdns':
+ return { domain: settings.domain || '' };
+ case 'mkcp-original':
+ case 'header-dtls':
+ case 'header-srtp':
+ case 'header-utp':
+ case 'header-wechat':
+ case 'header-wireguard':
+ return {};
+ default:
+ return settings;
+ }
+ }
+
+ static fromJson(json = {}) {
+ return new FinalMask(
+ json.type || 'salamander',
+ json.settings || {}
+ );
+ }
+
+ toJson() {
+ const result = {
+ type: this.type
+ };
+ if (this.settings && Object.keys(this.settings).length > 0) {
+ result.settings = this.settings;
+ }
+ return result;
+ }
+}
+
class StreamSettings extends XrayCommonClass {
constructor(network = 'tcp',
security = 'none',
@@ -935,6 +970,7 @@ class StreamSettings extends XrayCommonClass {
grpcSettings = new GrpcStreamSettings(),
httpupgradeSettings = new HttpUpgradeStreamSettings(),
xhttpSettings = new xHTTPStreamSettings(),
+ finalmask = { udp: [] },
sockopt = undefined,
) {
super();
@@ -949,9 +985,23 @@ class StreamSettings extends XrayCommonClass {
this.grpc = grpcSettings;
this.httpupgrade = httpupgradeSettings;
this.xhttp = xhttpSettings;
+ this.finalmask = finalmask;
this.sockopt = sockopt;
}
+ addUdpMask(type = 'salamander') {
+ if (!this.finalmask.udp) {
+ this.finalmask.udp = [];
+ }
+ this.finalmask.udp.push(new FinalMask(type));
+ }
+
+ delUdpMask(index) {
+ if (this.finalmask.udp) {
+ this.finalmask.udp.splice(index, 1);
+ }
+ }
+
get isTls() {
return this.security === "tls";
}
@@ -986,6 +1036,14 @@ class StreamSettings extends XrayCommonClass {
}
static fromJson(json = {}) {
+ let finalmask = { udp: [] };
+ if (json.finalmask) {
+ if (Array.isArray(json.finalmask)) {
+ finalmask.udp = json.finalmask.map(mask => FinalMask.fromJson(mask));
+ } else if (json.finalmask.udp) {
+ finalmask.udp = json.finalmask.udp.map(mask => FinalMask.fromJson(mask));
+ }
+ }
return new StreamSettings(
json.network,
json.security,
@@ -998,6 +1056,7 @@ class StreamSettings extends XrayCommonClass {
GrpcStreamSettings.fromJson(json.grpcSettings),
HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
xHTTPStreamSettings.fromJson(json.xhttpSettings),
+ finalmask,
SockoptStreamSettings.fromJson(json.sockopt),
);
}
@@ -1016,6 +1075,9 @@ class StreamSettings extends XrayCommonClass {
grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,
httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined,
xhttpSettings: network === 'xhttp' ? this.xhttp.toJson() : undefined,
+ finalmask: (this.finalmask.udp && this.finalmask.udp.length > 0) ? {
+ udp: this.finalmask.udp.map(mask => mask.toJson())
+ } : undefined,
sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined,
};
}
@@ -1927,7 +1989,8 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
json.selectedAuth = this.selectedAuth;
}
- if (this.testseed && this.testseed.length >= 4) {
+ const hasFlow = this.vlesses && this.vlesses.some(vless => vless.flow && vless.flow !== '');
+ if (hasFlow && this.testseed && this.testseed.length >= 4) {
json.testseed = this.testseed;
}
@@ -2443,7 +2506,7 @@ Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass {
Inbound.WireguardSettings = class extends XrayCommonClass {
constructor(
protocol,
- mtu = 1250,
+ mtu = 1420,
secretKey = Wireguard.generateKeypair().privateKey,
peers = [new Inbound.WireguardSettings.Peer()],
kernelMode = false
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js
index 35626ef5..e0423cee 100644
--- a/web/assets/js/model/outbound.js
+++ b/web/assets/js/model/outbound.js
@@ -163,15 +163,13 @@ class TcpStreamSettings extends CommonClass {
class KcpStreamSettings extends CommonClass {
constructor(
- mtu = 1250,
- tti = 50,
+ mtu = 1350,
+ tti = 20,
uplinkCapacity = 5,
downlinkCapacity = 20,
congestion = false,
- readBufferSize = 2,
- writeBufferSize = 2,
- type = 'none',
- seed = '',
+ readBufferSize = 1,
+ writeBufferSize = 1,
) {
super();
this.mtu = mtu;
@@ -181,8 +179,6 @@ class KcpStreamSettings extends CommonClass {
this.congestion = congestion;
this.readBuffer = readBufferSize;
this.writeBuffer = writeBufferSize;
- this.type = type;
- this.seed = seed;
}
static fromJson(json = {}) {
@@ -194,8 +190,6 @@ class KcpStreamSettings extends CommonClass {
json.congestion,
json.readBufferSize,
json.writeBufferSize,
- ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,
- json.seed,
);
}
@@ -208,10 +202,6 @@ class KcpStreamSettings extends CommonClass {
congestion: this.congestion,
readBufferSize: this.readBuffer,
writeBufferSize: this.writeBuffer,
- header: {
- type: this.type,
- },
- seed: this.seed,
};
}
}
@@ -561,27 +551,48 @@ class SockoptStreamSettings extends CommonClass {
}
}
-class UdpMask extends CommonClass {
- constructor(type = 'salamander', password = '') {
+class FinalMask extends CommonClass {
+ constructor(type = 'salamander', settings = {}) {
super();
this.type = type;
- this.password = password;
+ this.settings = this._getDefaultSettings(type, settings);
+ }
+
+ _getDefaultSettings(type, settings = {}) {
+ switch (type) {
+ case 'salamander':
+ case 'mkcp-aes128gcm':
+ return { password: settings.password || '' };
+ case 'header-dns':
+ case 'xdns':
+ return { domain: settings.domain || '' };
+ case 'mkcp-original':
+ case 'header-dtls':
+ case 'header-srtp':
+ case 'header-utp':
+ case 'header-wechat':
+ case 'header-wireguard':
+ return {}; // No settings needed
+ default:
+ return settings;
+ }
}
static fromJson(json = {}) {
- return new UdpMask(
- json.type,
- json.settings?.password || ''
+ return new FinalMask(
+ json.type || 'salamander',
+ json.settings || {}
);
}
toJson() {
- return {
- type: this.type,
- settings: {
- password: this.password
- }
+ const result = {
+ type: this.type
};
+ if (this.settings && Object.keys(this.settings).length > 0) {
+ result.settings = this.settings;
+ }
+ return result;
}
}
@@ -598,7 +609,7 @@ class StreamSettings extends CommonClass {
httpupgradeSettings = new HttpUpgradeStreamSettings(),
xhttpSettings = new xHTTPStreamSettings(),
hysteriaSettings = new HysteriaStreamSettings(),
- udpmasks = [],
+ finalmask = { udp: [] },
sockopt = undefined,
) {
super();
@@ -613,16 +624,21 @@ class StreamSettings extends CommonClass {
this.httpupgrade = httpupgradeSettings;
this.xhttp = xhttpSettings;
this.hysteria = hysteriaSettings;
- this.udpmasks = udpmasks;
+ this.finalmask = finalmask;
this.sockopt = sockopt;
}
- addUdpMask() {
- this.udpmasks.push(new UdpMask());
+ addUdpMask(type = 'salamander') {
+ if (!this.finalmask.udp) {
+ this.finalmask.udp = [];
+ }
+ this.finalmask.udp.push(new FinalMask(type));
}
delUdpMask(index) {
- this.udpmasks.splice(index, 1);
+ if (this.finalmask.udp) {
+ this.finalmask.udp.splice(index, 1);
+ }
}
get isTls() {
@@ -642,6 +658,14 @@ class StreamSettings extends CommonClass {
}
static fromJson(json = {}) {
+ let finalmask = { udp: [] };
+ if (json.finalmask) {
+ if (Array.isArray(json.finalmask)) {
+ finalmask.udp = json.finalmask.map(mask => FinalMask.fromJson(mask));
+ } else if (json.finalmask.udp) {
+ finalmask.udp = json.finalmask.udp.map(mask => FinalMask.fromJson(mask));
+ }
+ }
return new StreamSettings(
json.network,
json.security,
@@ -654,7 +678,7 @@ class StreamSettings extends CommonClass {
HttpUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
xHTTPStreamSettings.fromJson(json.xhttpSettings),
HysteriaStreamSettings.fromJson(json.hysteriaSettings),
- json.udpmasks ? json.udpmasks.map(mask => UdpMask.fromJson(mask)) : [],
+ finalmask,
SockoptStreamSettings.fromJson(json.sockopt),
);
}
@@ -673,7 +697,9 @@ class StreamSettings extends CommonClass {
httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined,
xhttpSettings: network === 'xhttp' ? this.xhttp.toJson() : undefined,
hysteriaSettings: network === 'hysteria' ? this.hysteria.toJson() : undefined,
- udpmasks: this.udpmasks.length > 0 ? this.udpmasks.map(mask => mask.toJson()) : undefined,
+ finalmask: (this.finalmask.udp && this.finalmask.udp.length > 0) ? {
+ udp: this.finalmask.udp.map(mask => mask.toJson())
+ } : undefined,
sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined,
};
}
@@ -1279,11 +1305,13 @@ Outbound.VLESSSettings = class extends CommonClass {
flow: this.flow,
encryption: this.encryption,
};
- if (this.testpre > 0) {
- result.testpre = this.testpre;
- }
- if (this.testseed && this.testseed.length >= 4) {
- result.testseed = this.testseed;
+ if (this.flow && this.flow !== '') {
+ if (this.testpre > 0) {
+ result.testpre = this.testpre;
+ }
+ if (this.testseed && this.testseed.length >= 4) {
+ result.testseed = this.testseed;
+ }
}
return result;
}
@@ -1416,7 +1444,7 @@ Outbound.HttpSettings = class extends CommonClass {
Outbound.WireguardSettings = class extends CommonClass {
constructor(
- mtu = 1250,
+ mtu = 1420,
secretKey = '',
address = [''],
workers = 2,
diff --git a/web/html/xui/form/outbound.html b/web/html/xui/form/outbound.html
index 55d2d4e4..50ad731c 100644
--- a/web/html/xui/form/outbound.html
+++ b/web/html/xui/form/outbound.html
@@ -331,20 +331,6 @@
-
-
- None
- SRTP
- uTP
- WeChat
- DTLS 1.2
- WireGuard
- DNS
-
-
-
-
-
@@ -446,8 +432,9 @@
-
- BBR (Auto)
+
+ BBR (Auto)
Brutal
@@ -502,25 +489,57 @@
-
+
-
+
-
-
+
UDP Mask [[ index + 1 ]]
- outbound.stream.delUdpMask(index)"
+ outbound.stream.delUdpMask(index)"
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }">
-
- Salamander
+ mask.settings = mask._getDefaultSettings(type, {})"
+ :dropdown-class-name="themeSwitcher.currentTheme">
+
+ Salamander (Hysteria2)
+
+
+ mKCP AES-128-GCM
+ Header DNS
+ Header DTLS 1.2
+ Header SRTP
+ Header uTP
+ Header WeChat Video
+ Header WireGuard
+ mKCP Original
+
+
+ xDNS (Experimental)
+
-
-
+
+
+
+
+
diff --git a/web/html/xui/form/stream/stream_finalmask.html b/web/html/xui/form/stream/stream_finalmask.html
new file mode 100644
index 00000000..be213507
--- /dev/null
+++ b/web/html/xui/form/stream/stream_finalmask.html
@@ -0,0 +1,66 @@
+{{define "form/streamFinalMask"}}
+
+
+
+
+
+
+
+ UDP Mask [[ index + 1 ]]
+ inbound.stream.delUdpMask(index)"
+ :style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }">
+
+
+ mask.settings = mask._getDefaultSettings(type, {})"
+ :dropdown-class-name="themeSwitcher.currentTheme">
+
+ mKCP AES-128-GCM
+
+ Header DNS
+
+ Header DTLS 1.2
+
+ Header SRTP
+
+ Header uTP
+
+ Header WeChat Video
+
+ Header WireGuard
+
+ mKCP Original
+
+ xDNS (Experimental)
+
+
+
+
+
+
+
+
+
+
+
+{{end}}
diff --git a/web/html/xui/form/stream/stream_kcp.html b/web/html/xui/form/stream/stream_kcp.html
index 3b6bbd96..11f89ebd 100644
--- a/web/html/xui/form/stream/stream_kcp.html
+++ b/web/html/xui/form/stream/stream_kcp.html
@@ -1,48 +1,32 @@
{{define "form/streamKCP"}}
-
-
-
- None
- SRTP
- uTP
- WeChat
- DTLS 1.2
- WireGuard
- DNS
-
-
-
-
-
-
- {{ i18n "reset" }}
-
- {{ i18n "password" }}
-
-
-
-
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
{{end}}
diff --git a/web/html/xui/form/stream/stream_settings.html b/web/html/xui/form/stream/stream_settings.html
index 07bc6042..85620ceb 100644
--- a/web/html/xui/form/stream/stream_settings.html
+++ b/web/html/xui/form/stream/stream_settings.html
@@ -44,6 +44,12 @@
{{template "form/streamXHTTP"}}
+
+
+ {{template "form/streamFinalMask"}}
+
+
{{template "form/streamSockopt"}}