diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
index ef9ad19c..b5971a68 100644
--- a/web/assets/js/model/inbound.js
+++ b/web/assets/js/model/inbound.js
@@ -1085,11 +1085,23 @@ class UdpMask extends XrayCommonClass {
case 'header-wireguard':
return {};
case 'header-custom':
- return { client: [], server: [] };
+ return {
+ client: Array.isArray(settings.client) ? settings.client : [],
+ server: Array.isArray(settings.server) ? settings.server : [],
+ };
case 'noise':
- return { reset: 0, noise: [] };
+ return {
+ reset: settings.reset ?? 0,
+ noise: Array.isArray(settings.noise) ? settings.noise : [],
+ };
case 'sudoku':
- return { ascii: '', customTable: '', customTables: [], paddingMin: 0, paddingMax: 0 };
+ return {
+ ascii: settings.ascii || '',
+ customTable: settings.customTable || '',
+ customTables: settings.customTables ?? [],
+ paddingMin: settings.paddingMin ?? 0,
+ paddingMax: settings.paddingMax ?? 0,
+ };
default:
return settings;
}
@@ -1103,9 +1115,30 @@ class UdpMask extends XrayCommonClass {
}
toJson() {
+ const cleanItem = item => {
+ const out = { ...item };
+ if (out.type === 'array') {
+ delete out.packet;
+ } else {
+ out.rand = 0;
+ }
+ return out;
+ };
+
+ let settings = this.settings;
+ if (this.type === 'noise' && settings && Array.isArray(settings.noise)) {
+ settings = { ...settings, noise: settings.noise.map(cleanItem) };
+ } else if (this.type === 'header-custom' && settings) {
+ settings = {
+ ...settings,
+ client: Array.isArray(settings.client) ? settings.client.map(cleanItem) : settings.client,
+ server: Array.isArray(settings.server) ? settings.server.map(cleanItem) : settings.server,
+ };
+ }
+
return {
type: this.type,
- settings: (this.settings && Object.keys(this.settings).length > 0) ? this.settings : undefined
+ settings: (settings && Object.keys(settings).length > 0) ? settings : undefined
};
}
}
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js
index a84c0318..aa90d20d 100644
--- a/web/assets/js/model/outbound.js
+++ b/web/assets/js/model/outbound.js
@@ -655,11 +655,23 @@ class UdpMask extends CommonClass {
case 'header-wireguard':
return {}; // No settings needed
case 'header-custom':
- return { client: [], server: [] };
+ return {
+ client: Array.isArray(settings.client) ? settings.client : [],
+ server: Array.isArray(settings.server) ? settings.server : [],
+ };
case 'noise':
- return { reset: 0, noise: [] };
+ return {
+ reset: settings.reset ?? 0,
+ noise: Array.isArray(settings.noise) ? settings.noise : [],
+ };
case 'sudoku':
- return { ascii: '', customTable: '', customTables: [], paddingMin: 0, paddingMax: 0 };
+ return {
+ ascii: settings.ascii || '',
+ customTable: settings.customTable || '',
+ customTables: Array.isArray(settings.customTables) ? settings.customTables : [],
+ paddingMin: settings.paddingMin ?? 0,
+ paddingMax: settings.paddingMax ?? 0
+ };
default:
return settings;
}
@@ -673,9 +685,30 @@ class UdpMask extends CommonClass {
}
toJson() {
+ const cleanItem = item => {
+ const out = { ...item };
+ if (out.type === 'array') {
+ delete out.packet;
+ } else {
+ out.rand = 0;
+ }
+ return out;
+ };
+
+ let settings = this.settings;
+ if (this.type === 'noise' && settings && Array.isArray(settings.noise)) {
+ settings = { ...settings, noise: settings.noise.map(cleanItem) };
+ } else if (this.type === 'header-custom' && settings) {
+ settings = {
+ ...settings,
+ client: Array.isArray(settings.client) ? settings.client.map(cleanItem) : settings.client,
+ server: Array.isArray(settings.server) ? settings.server.map(cleanItem) : settings.server,
+ };
+ }
+
return {
type: this.type,
- settings: (this.settings && Object.keys(this.settings).length > 0) ? this.settings : undefined
+ settings: (settings && Object.keys(settings).length > 0) ? settings : undefined
};
}
}
diff --git a/web/assets/js/util/index.js b/web/assets/js/util/index.js
index cc7b9287..1f481c85 100644
--- a/web/assets/js/util/index.js
+++ b/web/assets/js/util/index.js
@@ -152,6 +152,12 @@ class RandomUtil {
return Base64.alternativeEncode(String.fromCharCode(...array));
}
+ static randomBase64(length = 16) {
+ const array = new Uint8Array(length);
+ window.crypto.getRandomValues(array);
+ return Base64.alternativeEncode(String.fromCharCode(...array));
+ }
+
static randomBase32String(length = 16) {
const array = new Uint8Array(length);
diff --git a/web/html/form/outbound.html b/web/html/form/outbound.html
index c350d70f..81b488c7 100644
--- a/web/html/form/outbound.html
+++ b/web/html/form/outbound.html
@@ -972,22 +972,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'array') c.packet = []; else c.packet = ''; }"
>
Array
String
@@ -995,7 +984,21 @@
Base64
-
+
+
+
+
+
+
+
+
+
@@ -1017,22 +1020,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'array') s.packet = []; else s.packet = ''; }"
>
Array
String
@@ -1040,7 +1032,21 @@
Base64
-
+
+
+
+
+
+
+
+
+
@@ -1080,7 +1086,7 @@
type="plus"
type="primary"
size="small"
- @click="mask.settings.noise.push({rand: '1-8192', randRange: '0-255', type: 'array', packet: '', delay: ''})"
+ @click="mask.settings.noise.push({rand: 0, randRange: '0-255', type: 'array', packet: [], delay: ''})"
/>
@@ -1092,22 +1098,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'array') n.packet = []; else n.packet = ''; }"
>
Array
String
@@ -1115,7 +1110,18 @@
Base64
-
+
+
+
+
+
+
+
+
+
diff --git a/web/html/form/stream/stream_finalmask.html b/web/html/form/stream/stream_finalmask.html
index 64bf2c06..f0ec87cf 100644
--- a/web/html/form/stream/stream_finalmask.html
+++ b/web/html/form/stream/stream_finalmask.html
@@ -116,16 +116,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'base64') c.packet = RandomUtil.randomBase64(); else if(t === 'array') c.packet = []; else c.packet = ''; }"
>
Array
String
@@ -133,8 +128,20 @@
Base64
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -155,16 +162,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'base64') s.packet = RandomUtil.randomBase64(); else if(t === 'array') s.packet = []; else s.packet = ''; }"
>
Array
String
@@ -172,8 +174,20 @@
Base64
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -186,7 +200,7 @@
type="plus"
type="primary"
size="small"
- @click="mask.settings.noise.push({rand: '1-8192', randRange: '0-255', type: 'array', packet: '', delay: ''})"
+ @click="mask.settings.noise.push({rand: '1-8192', randRange: '0-255', type: 'array', packet: [], delay: '10-20'})"
/>
@@ -198,16 +212,11 @@
:style="{ color: 'rgb(255, 77, 79)', cursor: 'pointer' }"
>
-
-
-
-
-
-
{ if(t === 'base64') n.packet = RandomUtil.randomBase64(); else if(t === 'array') n.packet = []; else n.packet = ''; }"
>
Array
String
@@ -215,8 +224,20 @@
Base64
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/html/xray.html b/web/html/xray.html
index a4d17459..61c40c80 100644
--- a/web/html/xray.html
+++ b/web/html/xray.html
@@ -1077,7 +1077,8 @@
return;
}
if (!msg.obj) return;
- const { geoip = [], geosite = [] } = msg.obj;
+ const geoip = msg.obj.geoip ?? [];
+ const geosite = msg.obj.geosite ?? [];
const geoSuffix = this.customGeoAliasLabelSuffix || '';
geoip.forEach((x) => {
this.settingsData.IPsOptions.push({