diff --git a/go.mod b/go.mod
index 458eefcb..2f81efb8 100644
--- a/go.mod
+++ b/go.mod
@@ -19,7 +19,7 @@ require (
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/valyala/fasthttp v1.68.0
github.com/xlzd/gotp v0.1.0
- github.com/xtls/xray-core v1.251202.0
+ github.com/xtls/xray-core v1.251208.0
go.uber.org/atomic v1.11.0
golang.org/x/crypto v0.45.0
golang.org/x/sys v0.38.0
diff --git a/go.sum b/go.sum
index 287a33bb..03a17d8e 100644
--- a/go.sum
+++ b/go.sum
@@ -203,8 +203,8 @@ github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 h1:UXjrmniKlY+ZbIqpN91lejB3pszQQQRVu1vqH/p/aGM=
github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ=
-github.com/xtls/xray-core v1.251202.0 h1:VwoBnq9IRTbYWEBhR0CqEw2cNjTlXYH6WxzKbSjx+XE=
-github.com/xtls/xray-core v1.251202.0/go.mod h1:kclzboEF0g6VBrp9/NXm8C0Aj64SDBt52OfthH1LSr4=
+github.com/xtls/xray-core v1.251208.0 h1:9jIXi+9KXnfmT5esSYNf9VAQlQkaAP8bG413B0eyAes=
+github.com/xtls/xray-core v1.251208.0/go.mod h1:kclzboEF0g6VBrp9/NXm8C0Aj64SDBt52OfthH1LSr4=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
index 15410750..366cda5d 100644
--- a/web/assets/js/model/inbound.js
+++ b/web/assets/js/model/inbound.js
@@ -857,6 +857,7 @@ class SockoptStreamSettings extends XrayCommonClass {
V6Only = false,
tcpWindowClamp = 600,
interfaceName = "",
+ trustedXForwardedFor = [],
) {
super();
this.acceptProxyProtocol = acceptProxyProtocol;
@@ -875,6 +876,7 @@ class SockoptStreamSettings extends XrayCommonClass {
this.V6Only = V6Only;
this.tcpWindowClamp = tcpWindowClamp;
this.interfaceName = interfaceName;
+ this.trustedXForwardedFor = trustedXForwardedFor;
}
static fromJson(json = {}) {
@@ -896,11 +898,12 @@ class SockoptStreamSettings extends XrayCommonClass {
json.V6Only,
json.tcpWindowClamp,
json.interface,
+ json.trustedXForwardedFor || [],
);
}
toJson() {
- return {
+ const result = {
acceptProxyProtocol: this.acceptProxyProtocol,
tcpFastOpen: this.tcpFastOpen,
mark: this.mark,
@@ -918,6 +921,10 @@ class SockoptStreamSettings extends XrayCommonClass {
tcpWindowClamp: this.tcpWindowClamp,
interface: this.interfaceName,
};
+ if (this.trustedXForwardedFor && this.trustedXForwardedFor.length > 0) {
+ result.trustedXForwardedFor = this.trustedXForwardedFor;
+ }
+ return result;
}
}
@@ -1870,6 +1877,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
encryption = "none",
fallbacks = [],
selectedAuth = undefined,
+ testseed = [900, 500, 900, 256],
) {
super(protocol);
this.vlesses = vlesses;
@@ -1877,6 +1885,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
this.encryption = encryption;
this.fallbacks = fallbacks;
this.selectedAuth = selectedAuth;
+ this.testseed = testseed;
}
addFallback() {
@@ -1894,7 +1903,8 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
json.decryption,
json.encryption,
Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks || []),
- json.selectedAuth
+ json.selectedAuth,
+ json.testseed && json.testseed.length >= 4 ? json.testseed : [900, 500, 900, 256]
);
return obj;
}
@@ -1920,6 +1930,10 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
json.selectedAuth = this.selectedAuth;
}
+ if (this.testseed && this.testseed.length >= 4) {
+ json.testseed = this.testseed;
+ }
+
return json;
}
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js
index c727abae..c631040e 100644
--- a/web/assets/js/model/outbound.js
+++ b/web/assets/js/model/outbound.js
@@ -432,6 +432,7 @@ class SockoptStreamSettings extends CommonClass {
tcpMptcp = false,
penetrate = false,
addressPortStrategy = Address_Port_Strategy.NONE,
+ trustedXForwardedFor = [],
) {
super();
this.dialerProxy = dialerProxy;
@@ -440,6 +441,7 @@ class SockoptStreamSettings extends CommonClass {
this.tcpMptcp = tcpMptcp;
this.penetrate = penetrate;
this.addressPortStrategy = addressPortStrategy;
+ this.trustedXForwardedFor = trustedXForwardedFor;
}
static fromJson(json = {}) {
@@ -450,12 +452,13 @@ class SockoptStreamSettings extends CommonClass {
json.tcpKeepAliveInterval,
json.tcpMptcp,
json.penetrate,
- json.addressPortStrategy
+ json.addressPortStrategy,
+ json.trustedXForwardedFor || []
);
}
toJson() {
- return {
+ const result = {
dialerProxy: this.dialerProxy,
tcpFastOpen: this.tcpFastOpen,
tcpKeepAliveInterval: this.tcpKeepAliveInterval,
@@ -463,6 +466,10 @@ class SockoptStreamSettings extends CommonClass {
penetrate: this.penetrate,
addressPortStrategy: this.addressPortStrategy
};
+ if (this.trustedXForwardedFor && this.trustedXForwardedFor.length > 0) {
+ result.trustedXForwardedFor = this.trustedXForwardedFor;
+ }
+ return result;
}
}
@@ -1050,13 +1057,15 @@ Outbound.VmessSettings = class extends CommonClass {
}
};
Outbound.VLESSSettings = class extends CommonClass {
- constructor(address, port, id, flow, encryption) {
+ constructor(address, port, id, flow, encryption, testpre = 0, testseed = [900, 500, 900, 256]) {
super();
this.address = address;
this.port = port;
this.id = id;
this.flow = flow;
this.encryption = encryption;
+ this.testpre = testpre;
+ this.testseed = testseed;
}
static fromJson(json = {}) {
@@ -1066,18 +1075,27 @@ Outbound.VLESSSettings = class extends CommonClass {
json.port,
json.id,
json.flow,
- json.encryption
+ json.encryption,
+ json.testpre || 0,
+ json.testseed && json.testseed.length >= 4 ? json.testseed : [900, 500, 900, 256]
);
}
toJson() {
- return {
+ const result = {
address: this.address,
port: this.port,
id: this.id,
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;
+ }
+ return result;
}
};
Outbound.TrojanSettings = class extends CommonClass {
diff --git a/web/html/form/outbound.html b/web/html/form/outbound.html
index aa6aa323..51371e17 100644
--- a/web/html/form/outbound.html
+++ b/web/html/form/outbound.html
@@ -239,6 +239,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+ Random
+
+
+
+
@@ -501,6 +531,15 @@
+
+
+ CF-Connecting-IP
+ X-Real-IP
+ True-Client-IP
+ X-Client-IP
+
+
diff --git a/web/html/form/protocol/vless.html b/web/html/form/protocol/vless.html
index 140b9c1a..c22824d7 100644
--- a/web/html/form/protocol/vless.html
+++ b/web/html/form/protocol/vless.html
@@ -69,4 +69,34 @@
+
+
+ XTLS Vision Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+ Random
+
+
+
+
+
+
{{end}}
diff --git a/web/html/form/stream/stream_sockopt.html b/web/html/form/stream/stream_sockopt.html
index 4480594a..062b83df 100644
--- a/web/html/form/stream/stream_sockopt.html
+++ b/web/html/form/stream/stream_sockopt.html
@@ -61,6 +61,15 @@
+
+
+ CF-Connecting-IP
+ X-Real-IP
+ True-Client-IP
+ X-Client-IP
+
+
{{end}}
diff --git a/web/html/settings/xray/dns.html b/web/html/settings/xray/dns.html
index ba768cb8..8a18bbb4 100644
--- a/web/html/settings/xray/dns.html
+++ b/web/html/settings/xray/dns.html
@@ -56,6 +56,13 @@
+
+ {{ i18n "pages.xray.dns.enableParallelQuery" }}
+ {{ i18n "pages.xray.dns.enableParallelQueryDesc" }}
+
+
+
+
{{ i18n "pages.xray.dns.useSystemHosts" }}
diff --git a/web/html/xray.html b/web/html/xray.html
index 4dacd021..da29f0fb 100644
--- a/web/html/xray.html
+++ b/web/html/xray.html
@@ -269,7 +269,7 @@
tag: "direct",
protocol: "freedom"
},
- routingDomainStrategies: ["AsIs", "IPIfNonMatch", "IPOnDemand"],
+ routingDomainStrategies: ["AsIs", "IpIfNonMatch", "IpOnDemand"],
log: {
loglevel: ["none", "debug", "info", "warning", "error"],
access: ["none", "./access.log"],
@@ -1315,7 +1315,8 @@
newTemplateSettings.dns = {
servers: [],
queryStrategy: "UseIP",
- tag: "dns_inbound"
+ tag: "dns_inbound",
+ enableParallelQuery: false
};
newTemplateSettings.fakedns = null;
} else {
@@ -1391,6 +1392,20 @@
this.templateSettings = newTemplateSettings;
}
},
+ dnsEnableParallelQuery: {
+ get: function () {
+ return this.enableDNS ? (this.templateSettings.dns.enableParallelQuery || false) : false;
+ },
+ set: function (newValue) {
+ newTemplateSettings = this.templateSettings;
+ if (newValue) {
+ newTemplateSettings.dns.enableParallelQuery = newValue;
+ } else {
+ delete newTemplateSettings.dns.enableParallelQuery
+ }
+ this.templateSettings = newTemplateSettings;
+ }
+ },
dnsUseSystemHosts: {
get: function () {
return this.enableDNS ? this.templateSettings.dns.useSystemHosts : false;
diff --git a/web/translation/translate.ar_EG.toml b/web/translation/translate.ar_EG.toml
index 71d1710f..fad0e872 100644
--- a/web/translation/translate.ar_EG.toml
+++ b/web/translation/translate.ar_EG.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "بيعطل استعلامات DNS الاحتياطية"
"disableFallbackIfMatch" = "تعطيل النسخ الاحتياطي عند التطابق"
"disableFallbackIfMatchDesc" = "بيعطل استعلامات DNS الاحتياطية لما يتحقق تطابق مع قائمة الدومينات"
+"enableParallelQuery" = "تفعيل الاستعلام المتوازي"
+"enableParallelQueryDesc" = "تفعيل استعلامات DNS المتوازية لعدة خوادم لحل أسرع"
"strategy" = "استراتيجية الاستعلام"
"strategyDesc" = "الاستراتيجية العامة لحل أسماء الدومين"
"add" = "أضف سيرفر"
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 92203a85..b1ac6523 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Disables fallback DNS queries"
"disableFallbackIfMatch" = "Disable Fallback If Match"
"disableFallbackIfMatchDesc" = "Disables fallback DNS queries when the matching domain list of the DNS server is hit"
+"enableParallelQuery" = "Enable Parallel Query"
+"enableParallelQueryDesc" = "Enable parallel DNS queries to multiple servers for faster resolution"
"strategy" = "Query Strategy"
"strategyDesc" = "Overall strategy to resolve domain names"
"add" = "Add Server"
diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml
index 3da08775..203945c5 100644
--- a/web/translation/translate.es_ES.toml
+++ b/web/translation/translate.es_ES.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Desactiva las consultas DNS de respaldo"
"disableFallbackIfMatch" = "Desactivar respaldo si coincide"
"disableFallbackIfMatchDesc" = "Desactiva las consultas DNS de respaldo cuando se acierta en la lista de dominios coincidentes del servidor DNS"
+"enableParallelQuery" = "Habilitar consulta paralela"
+"enableParallelQueryDesc" = "Habilitar consultas DNS paralelas a múltiples servidores para una resolución más rápida"
"strategy" = "Estrategia de Consulta"
"strategyDesc" = "Estrategia general para resolver nombres de dominio"
"add" = "Agregar Servidor"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 0da0f9ad..985158d7 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "درخواستهای DNS Fallback را غیرفعال میکند"
"disableFallbackIfMatch" = "غیرفعالسازی Fallback در صورت تطابق"
"disableFallbackIfMatchDesc" = "درخواستهای DNS Fallback را زمانی که لیست دامنههای مطابقتیافته سرور DNS فعال است، غیرفعال میکند"
+"enableParallelQuery" = "فعالسازی پرسوجوی موازی"
+"enableParallelQueryDesc" = "فعالسازی پرسوجوهای DNS موازی به چندین سرور برای وضوح سریعتر"
"strategy" = "استراتژی پرسوجو"
"strategyDesc" = "استراتژی کلی برای حل نام دامنه"
"add" = "افزودن سرور"
diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml
index 37d5a3c9..fb1fe427 100644
--- a/web/translation/translate.id_ID.toml
+++ b/web/translation/translate.id_ID.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Menonaktifkan kueri DNS fallback"
"disableFallbackIfMatch" = "Nonaktifkan Fallback Jika Cocok"
"disableFallbackIfMatchDesc" = "Menonaktifkan kueri DNS fallback ketika daftar domain yang cocok dari server DNS terpenuhi"
+"enableParallelQuery" = "Aktifkan Kueri Paralel"
+"enableParallelQueryDesc" = "Aktifkan kueri DNS paralel ke beberapa server untuk resolusi yang lebih cepat"
"strategy" = "Strategi Kueri"
"strategyDesc" = "Strategi keseluruhan untuk menyelesaikan nama domain"
"add" = "Tambahkan Server"
diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml
index ebd19ea0..992573c4 100644
--- a/web/translation/translate.ja_JP.toml
+++ b/web/translation/translate.ja_JP.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "フォールバックDNSクエリを無効にします"
"disableFallbackIfMatch" = "一致した場合にフォールバックを無効にする"
"disableFallbackIfMatchDesc" = "DNSサーバーの一致するドメインリストにヒットした場合、フォールバックDNSクエリを無効にします"
+"enableParallelQuery" = "並列クエリを有効にする"
+"enableParallelQueryDesc" = "複数のサーバーへの並列DNSクエリを有効にして、より高速な解決を実現"
"strategy" = "クエリ戦略"
"strategyDesc" = "ドメイン名解決の全体的な戦略"
"add" = "サーバー追加"
diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml
index 0ad1be58..c44ac161 100644
--- a/web/translation/translate.pt_BR.toml
+++ b/web/translation/translate.pt_BR.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Desativa consultas DNS de fallback"
"disableFallbackIfMatch" = "Desativar Fallback Se Corresponder"
"disableFallbackIfMatchDesc" = "Desativa consultas DNS de fallback quando a lista de domínios correspondentes do servidor DNS é atingida"
+"enableParallelQuery" = "Habilitar Consulta Paralela"
+"enableParallelQueryDesc" = "Habilitar consultas DNS paralelas para múltiplos servidores para resolução mais rápida"
"strategy" = "Estratégia de Consulta"
"strategyDesc" = "Estratégia geral para resolver nomes de domínio"
"add" = "Adicionar Servidor"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index bea5b5e9..50f0c5b3 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Отключает резервные DNS-запросы"
"disableFallbackIfMatch" = "Отключить резервный DNS при совпадении"
"disableFallbackIfMatchDesc" = "Отключает резервные DNS-запросы при совпадении списка доменов DNS-сервера"
+"enableParallelQuery" = "Включить параллельные запросы"
+"enableParallelQueryDesc" = "Включить параллельные DNS-запросы к нескольким серверам для более быстрого разрешения"
"strategy" = "Стратегия запроса"
"strategyDesc" = "Общая стратегия разрешения доменных имен"
"add" = "Создать DNS"
diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml
index de5716aa..aa450f4a 100644
--- a/web/translation/translate.tr_TR.toml
+++ b/web/translation/translate.tr_TR.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Yedek DNS sorgularını devre dışı bırakır"
"disableFallbackIfMatch" = "Eşleşirse Yedeklemeyi Devre Dışı Bırak"
"disableFallbackIfMatchDesc" = "DNS sunucusunun eşleşen alan adı listesi vurulduğunda yedek DNS sorgularını devre dışı bırakır"
+"enableParallelQuery" = "Paralel Sorguyu Etkinleştir"
+"enableParallelQueryDesc" = "Daha hızlı çözümleme için birden fazla sunucuya paralel DNS sorgularını etkinleştir"
"strategy" = "Sorgu Stratejisi"
"strategyDesc" = "Alan adlarını çözmek için genel strateji"
"add" = "Sunucu Ekle"
diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml
index d53b0bc0..c90957d0 100644
--- a/web/translation/translate.uk_UA.toml
+++ b/web/translation/translate.uk_UA.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Вимкнути резервні DNS-запити"
"disableFallbackIfMatch" = "Вимкнути резервний DNS при збігу"
"disableFallbackIfMatchDesc" = "Вимкнути резервні DNS-запити при збігу списку доменів DNS-сервера"
+"enableParallelQuery" = "Увімкнути паралельні запити"
+"enableParallelQueryDesc" = "Увімкнути паралельні DNS-запити до кількох серверів для швидшого вирішення"
"strategy" = "Стратегія запиту"
"strategyDesc" = "Загальна стратегія вирішення доменних імен"
"add" = "Додати сервер"
diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml
index cb21cc3b..af880c05 100644
--- a/web/translation/translate.vi_VN.toml
+++ b/web/translation/translate.vi_VN.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "Tắt các truy vấn DNS Fallback"
"disableFallbackIfMatch" = "Tắt Fallback Nếu Khớp"
"disableFallbackIfMatchDesc" = "Tắt các truy vấn DNS Fallback khi danh sách tên miền khớp của máy chủ DNS được kích hoạt"
+"enableParallelQuery" = "Bật Truy vấn Song song"
+"enableParallelQueryDesc" = "Bật truy vấn DNS song song đến nhiều máy chủ để phân giải nhanh hơn"
"strategy" = "Chiến lược truy vấn"
"strategyDesc" = "Chiến lược tổng thể để phân giải tên miền"
"add" = "Thêm máy chủ"
diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml
index 2ee5f9a0..64d6120d 100644
--- a/web/translation/translate.zh_CN.toml
+++ b/web/translation/translate.zh_CN.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "禁用回退DNS查询"
"disableFallbackIfMatch" = "匹配时禁用回退"
"disableFallbackIfMatchDesc" = "当DNS服务器的匹配域名列表命中时,禁用回退DNS查询"
+"enableParallelQuery" = "启用并行查询"
+"enableParallelQueryDesc" = "启用并行DNS查询到多个服务器以实现更快的解析"
"strategy" = "查询策略"
"strategyDesc" = "解析域名的总体策略"
"add" = "添加服务器"
diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml
index dc600d21..9c5c956f 100644
--- a/web/translation/translate.zh_TW.toml
+++ b/web/translation/translate.zh_TW.toml
@@ -544,6 +544,8 @@
"disableFallbackDesc" = "禁用回退DNS查詢"
"disableFallbackIfMatch" = "匹配時禁用回退"
"disableFallbackIfMatchDesc" = "當DNS伺服器的匹配域名列表命中時,禁用回退DNS查詢"
+"enableParallelQuery" = "啟用並行查詢"
+"enableParallelQueryDesc" = "啟用並行DNS查詢到多個伺服器以實現更快的解析"
"strategy" = "查詢策略"
"strategyDesc" = "解析域名的總體策略"
"add" = "新增伺服器"
diff --git a/xray/api.go b/xray/api.go
index 11119709..95d8c473 100644
--- a/xray/api.go
+++ b/xray/api.go
@@ -110,10 +110,33 @@ func (x *XrayAPI) AddUser(Protocol string, inboundTag string, user map[string]an
Id: user["id"].(string),
})
case "vless":
- account = serial.ToTypedMessage(&vless.Account{
+ vlessAccount := &vless.Account{
Id: user["id"].(string),
Flow: user["flow"].(string),
- })
+ }
+ // Add testseed if provided
+ if testseedVal, ok := user["testseed"]; ok {
+ if testseedArr, ok := testseedVal.([]interface{}); ok && len(testseedArr) >= 4 {
+ testseed := make([]uint32, len(testseedArr))
+ for i, v := range testseedArr {
+ if num, ok := v.(float64); ok {
+ testseed[i] = uint32(num)
+ }
+ }
+ vlessAccount.Testseed = testseed
+ } else if testseedArr, ok := testseedVal.([]uint32); ok && len(testseedArr) >= 4 {
+ vlessAccount.Testseed = testseedArr
+ }
+ }
+ // Add testpre if provided (for outbound, but can be in user for compatibility)
+ if testpreVal, ok := user["testpre"]; ok {
+ if testpre, ok := testpreVal.(float64); ok && testpre > 0 {
+ vlessAccount.Testpre = uint32(testpre)
+ } else if testpre, ok := testpreVal.(uint32); ok && testpre > 0 {
+ vlessAccount.Testpre = testpre
+ }
+ }
+ account = serial.ToTypedMessage(vlessAccount)
case "trojan":
account = serial.ToTypedMessage(&trojan.Account{
Password: user["password"].(string),