Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhsanaei <ho3ein.sanaei@gmail.com>2024-10-30 16:40:41 +0300
committermhsanaei <ho3ein.sanaei@gmail.com>2024-10-30 16:46:27 +0300
commit19a31686da26c0c8a8f0ee255d3b0728524bb95f (patch)
tree89cb854958e838f3e41ea2ff4de8823585eaab7b /web/assets/js/model/inbound.js
parent13f7e071285f57327c8c741d5c691ddf2a9f9621 (diff)
REALITY: SplitHTTP transport
Diffstat (limited to 'web/assets/js/model/inbound.js')
-rw-r--r--web/assets/js/model/inbound.js2531
1 files changed, 2531 insertions, 0 deletions
diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
new file mode 100644
index 00000000..ea6f56fa
--- /dev/null
+++ b/web/assets/js/model/inbound.js
@@ -0,0 +1,2531 @@
+const Protocols = {
+ VMESS: 'vmess',
+ VLESS: 'vless',
+ TROJAN: 'trojan',
+ SHADOWSOCKS: 'shadowsocks',
+ DOKODEMO: 'dokodemo-door',
+ SOCKS: 'socks',
+ HTTP: 'http',
+ WIREGUARD: 'wireguard',
+};
+
+const SSMethods = {
+ AES_256_GCM: 'aes-256-gcm',
+ AES_128_GCM: 'aes-128-gcm',
+ CHACHA20_POLY1305: 'chacha20-poly1305',
+ CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305',
+ XCHACHA20_POLY1305: 'xchacha20-poly1305',
+ XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305',
+ BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm',
+ BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm',
+ BLAKE3_CHACHA20_POLY1305: '2022-blake3-chacha20-poly1305',
+};
+
+const TLS_FLOW_CONTROL = {
+ VISION: "xtls-rprx-vision",
+ VISION_UDP443: "xtls-rprx-vision-udp443",
+};
+
+const TLS_VERSION_OPTION = {
+ TLS10: "1.0",
+ TLS11: "1.1",
+ TLS12: "1.2",
+ TLS13: "1.3",
+};
+
+const TLS_CIPHER_OPTION = {
+ RSA_AES_128_CBC: "TLS_RSA_WITH_AES_128_CBC_SHA",
+ RSA_AES_256_CBC: "TLS_RSA_WITH_AES_256_CBC_SHA",
+ RSA_AES_128_GCM: "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ RSA_AES_256_GCM: "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ AES_128_GCM: "TLS_AES_128_GCM_SHA256",
+ AES_256_GCM: "TLS_AES_256_GCM_SHA384",
+ CHACHA20_POLY1305: "TLS_CHACHA20_POLY1305_SHA256",
+ ECDHE_ECDSA_AES_128_CBC: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+ ECDHE_ECDSA_AES_256_CBC: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ ECDHE_RSA_AES_128_CBC: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+ ECDHE_RSA_AES_256_CBC: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ ECDHE_ECDSA_AES_128_GCM: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ ECDHE_ECDSA_AES_256_GCM: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ ECDHE_RSA_AES_128_GCM: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ ECDHE_RSA_AES_256_GCM: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ ECDHE_ECDSA_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+ ECDHE_RSA_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+};
+
+const UTLS_FINGERPRINT = {
+ UTLS_CHROME: "chrome",
+ UTLS_FIREFOX: "firefox",
+ UTLS_SAFARI: "safari",
+ UTLS_IOS: "ios",
+ UTLS_android: "android",
+ UTLS_EDGE: "edge",
+ UTLS_360: "360",
+ UTLS_QQ: "qq",
+ UTLS_RANDOM: "random",
+ UTLS_RANDOMIZED: "randomized",
+};
+
+const ALPN_OPTION = {
+ H3: "h3",
+ H2: "h2",
+ HTTP1: "http/1.1",
+};
+
+const SNIFFING_OPTION = {
+ HTTP: "http",
+ TLS: "tls",
+ QUIC: "quic",
+ FAKEDNS: "fakedns"
+};
+
+const USAGE_OPTION = {
+ ENCIPHERMENT: "encipherment",
+ VERIFY: "verify",
+ ISSUE: "issue",
+};
+
+const DOMAIN_STRATEGY_OPTION = {
+ AS_IS: "AsIs",
+ USE_IP: "UseIP",
+ USE_IPV6V4: "UseIPv6v4",
+ USE_IPV6: "UseIPv6",
+ USE_IPV4V6: "UseIPv4v6",
+ USE_IPV4: "UseIPv4",
+ FORCE_IP: "ForceIP",
+ FORCE_IPV6V4: "ForceIPv6v4",
+ FORCE_IPV6: "ForceIPv6",
+ FORCE_IPV4V6: "ForceIPv4v6",
+ FORCE_IPV4: "ForceIPv4",
+};
+
+const TCP_CONGESTION_OPTION = {
+ BBR: "bbr",
+ CUBIC: "cubic",
+ RENO: "reno",
+};
+
+const USERS_SECURITY = {
+ AES_128_GCM: "aes-128-gcm",
+ CHACHA20_POLY1305: "chacha20-poly1305",
+ AUTO: "auto",
+ NONE: "none",
+ ZERO: "zero",
+};
+
+Object.freeze(Protocols);
+Object.freeze(SSMethods);
+Object.freeze(TLS_FLOW_CONTROL);
+Object.freeze(TLS_VERSION_OPTION);
+Object.freeze(TLS_CIPHER_OPTION);
+Object.freeze(UTLS_FINGERPRINT);
+Object.freeze(ALPN_OPTION);
+Object.freeze(SNIFFING_OPTION);
+Object.freeze(USAGE_OPTION);
+Object.freeze(DOMAIN_STRATEGY_OPTION);
+Object.freeze(TCP_CONGESTION_OPTION);
+Object.freeze(USERS_SECURITY);
+
+class XrayCommonClass {
+
+ static toJsonArray(arr) {
+ return arr.map(obj => obj.toJson());
+ }
+
+ static fromJson() {
+ return new XrayCommonClass();
+ }
+
+ toJson() {
+ return this;
+ }
+
+ toString(format = true) {
+ return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());
+ }
+
+ static toHeaders(v2Headers) {
+ let newHeaders = [];
+ if (v2Headers) {
+ Object.keys(v2Headers).forEach(key => {
+ let values = v2Headers[key];
+ if (typeof (values) === 'string') {
+ newHeaders.push({ name: key, value: values });
+ } else {
+ for (let i = 0; i < values.length; ++i) {
+ newHeaders.push({ name: key, value: values[i] });
+ }
+ }
+ });
+ }
+ return newHeaders;
+ }
+
+ static toV2Headers(headers, arr = true) {
+ let v2Headers = {};
+ for (let i = 0; i < headers.length; ++i) {
+ let name = headers[i].name;
+ let value = headers[i].value;
+ if (ObjectUtil.isEmpty(name) || ObjectUtil.isEmpty(value)) {
+ continue;
+ }
+ if (!(name in v2Headers)) {
+ v2Headers[name] = arr ? [value] : value;
+ } else {
+ if (arr) {
+ v2Headers[name].push(value);
+ } else {
+ v2Headers[name] = value;
+ }
+ }
+ }
+ return v2Headers;
+ }
+}
+
+class TcpStreamSettings extends XrayCommonClass {
+ constructor(
+ acceptProxyProtocol = false,
+ type = 'none',
+ request = new TcpStreamSettings.TcpRequest(),
+ response = new TcpStreamSettings.TcpResponse(),
+ ) {
+ super();
+ this.acceptProxyProtocol = acceptProxyProtocol;
+ this.type = type;
+ this.request = request;
+ this.response = response;
+ }
+
+ static fromJson(json = {}) {
+ let header = json.header;
+ if (!header) {
+ header = {};
+ }
+ return new TcpStreamSettings(json.acceptProxyProtocol,
+ header.type,
+ TcpStreamSettings.TcpRequest.fromJson(header.request),
+ TcpStreamSettings.TcpResponse.fromJson(header.response),
+ );
+ }
+
+ toJson() {
+ return {
+ acceptProxyProtocol: this.acceptProxyProtocol,
+ header: {
+ type: this.type,
+ request: this.type === 'http' ? this.request.toJson() : undefined,
+ response: this.type === 'http' ? this.response.toJson() : undefined,
+ },
+ };
+ }
+}
+
+TcpStreamSettings.TcpRequest = class extends XrayCommonClass {
+ constructor(
+ version = '1.1',
+ method = 'GET',
+ path = ['/'],
+ headers = [],
+ ) {
+ super();
+ this.version = version;
+ this.method = method;
+ this.path = path.length === 0 ? ['/'] : path;
+ this.headers = headers;
+ }
+
+ addPath(path) {
+ this.path.push(path);
+ }
+
+ removePath(index) {
+ this.path.splice(index, 1);
+ }
+
+ addHeader(name, value) {
+ this.headers.push({ name: name, value: value });
+ }
+
+ removeHeader(index) {
+ this.headers.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new TcpStreamSettings.TcpRequest(
+ json.version,
+ json.method,
+ json.path,
+ XrayCommonClass.toHeaders(json.headers),
+ );
+ }
+
+ toJson() {
+ return {
+ version: this.version,
+ method: this.method,
+ path: ObjectUtil.clone(this.path),
+ headers: XrayCommonClass.toV2Headers(this.headers),
+ };
+ }
+};
+
+TcpStreamSettings.TcpResponse = class extends XrayCommonClass {
+ constructor(
+ version = '1.1',
+ status = '200',
+ reason = 'OK',
+ headers = [],
+ ) {
+ super();
+ this.version = version;
+ this.status = status;
+ this.reason = reason;
+ this.headers = headers;
+ }
+
+ addHeader(name, value) {
+ this.headers.push({ name: name, value: value });
+ }
+
+ removeHeader(index) {
+ this.headers.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new TcpStreamSettings.TcpResponse(
+ json.version,
+ json.status,
+ json.reason,
+ XrayCommonClass.toHeaders(json.headers),
+ );
+ }
+
+ toJson() {
+ return {
+ version: this.version,
+ status: this.status,
+ reason: this.reason,
+ headers: XrayCommonClass.toV2Headers(this.headers),
+ };
+ }
+};
+
+class KcpStreamSettings extends XrayCommonClass {
+ constructor(
+ mtu = 1350,
+ tti = 50,
+ uplinkCapacity = 5,
+ downlinkCapacity = 20,
+ congestion = false,
+ readBufferSize = 2,
+ writeBufferSize = 2,
+ type = 'none',
+ seed = RandomUtil.randomSeq(10),
+ ) {
+ super();
+ this.mtu = mtu;
+ this.tti = tti;
+ this.upCap = uplinkCapacity;
+ this.downCap = downlinkCapacity;
+ this.congestion = congestion;
+ this.readBuffer = readBufferSize;
+ this.writeBuffer = writeBufferSize;
+ this.type = type;
+ this.seed = seed;
+ }
+
+ static fromJson(json = {}) {
+ return new KcpStreamSettings(
+ json.mtu,
+ json.tti,
+ json.uplinkCapacity,
+ json.downlinkCapacity,
+ json.congestion,
+ json.readBufferSize,
+ json.writeBufferSize,
+ ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,
+ json.seed,
+ );
+ }
+
+ toJson() {
+ return {
+ mtu: this.mtu,
+ tti: this.tti,
+ uplinkCapacity: this.upCap,
+ downlinkCapacity: this.downCap,
+ congestion: this.congestion,
+ readBufferSize: this.readBuffer,
+ writeBufferSize: this.writeBuffer,
+ header: {
+ type: this.type,
+ },
+ seed: this.seed,
+ };
+ }
+}
+
+class WsStreamSettings extends XrayCommonClass {
+ constructor(
+ acceptProxyProtocol = false,
+ path = '/',
+ host = '',
+ headers = []
+ ) {
+ super();
+ this.acceptProxyProtocol = acceptProxyProtocol;
+ this.path = path;
+ this.host = host;
+ this.headers = headers;
+ }
+
+ addHeader(name, value) {
+ this.headers.push({ name: name, value: value });
+ }
+
+ removeHeader(index) {
+ this.headers.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new WsStreamSettings(
+ json.acceptProxyProtocol,
+ json.path,
+ json.host,
+ XrayCommonClass.toHeaders(json.headers),
+ );
+ }
+
+ toJson() {
+ return {
+ acceptProxyProtocol: this.acceptProxyProtocol,
+ path: this.path,
+ host: this.host,
+ headers: XrayCommonClass.toV2Headers(this.headers, false),
+ };
+ }
+}
+
+class HttpStreamSettings extends XrayCommonClass {
+ constructor(
+ path = '/',
+ host = [''],
+ ) {
+ super();
+ this.path = path;
+ this.host = host.length === 0 ? [''] : host;
+ }
+
+ addHost(host) {
+ this.host.push(host);
+ }
+
+ removeHost(index) {
+ this.host.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new HttpStreamSettings(json.path, json.host);
+ }
+
+ toJson() {
+ let host = [];
+ for (let i = 0; i < this.host.length; ++i) {
+ if (!ObjectUtil.isEmpty(this.host[i])) {
+ host.push(this.host[i]);
+ }
+ }
+ return {
+ path: this.path,
+ host: host,
+ }
+ }
+}
+
+class GrpcStreamSettings extends XrayCommonClass {
+ constructor(
+ serviceName = "",
+ authority = "",
+ multiMode = false,
+ ) {
+ super();
+ this.serviceName = serviceName;
+ this.authority = authority;
+ this.multiMode = multiMode;
+ }
+
+ static fromJson(json = {}) {
+ return new GrpcStreamSettings(
+ json.serviceName,
+ json.authority,
+ json.multiMode
+ );
+ }
+
+ toJson() {
+ return {
+ serviceName: this.serviceName,
+ authority: this.authority,
+ multiMode: this.multiMode,
+ }
+ }
+}
+
+class HTTPUpgradeStreamSettings extends XrayCommonClass {
+ constructor(
+ acceptProxyProtocol = false,
+ path = '/',
+ host = '',
+ headers = []
+ ) {
+ super();
+ this.acceptProxyProtocol = acceptProxyProtocol;
+ this.path = path;
+ this.host = host;
+ this.headers = headers;
+ }
+
+ addHeader(name, value) {
+ this.headers.push({ name: name, value: value });
+ }
+
+ removeHeader(index) {
+ this.headers.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new HTTPUpgradeStreamSettings(
+ json.acceptProxyProtocol,
+ json.path,
+ json.host,
+ XrayCommonClass.toHeaders(json.headers),
+ );
+ }
+
+ toJson() {
+ return {
+ acceptProxyProtocol: this.acceptProxyProtocol,
+ path: this.path,
+ host: this.host,
+ headers: XrayCommonClass.toV2Headers(this.headers, false),
+ };
+ }
+}
+
+class SplitHTTPStreamSettings extends XrayCommonClass {
+ constructor(
+ path = '/',
+ host = '',
+ headers = [],
+ scMaxConcurrentPosts = "100-200",
+ scMaxEachPostBytes = "1000000-2000000",
+ scMinPostsIntervalMs = "10-50",
+ noSSEHeader = false,
+ xPaddingBytes = "100-1000",
+ xmux = {
+ maxConcurrency: "16-32",
+ maxConnections: 0,
+ cMaxReuseTimes: "64-128",
+ cMaxLifetimeMs: 0
+ }
+ ) {
+ super();
+ this.path = path;
+ this.host = host;
+ this.headers = headers;
+ this.scMaxConcurrentPosts = scMaxConcurrentPosts;
+ this.scMaxEachPostBytes = scMaxEachPostBytes;
+ this.scMinPostsIntervalMs = scMinPostsIntervalMs;
+ this.noSSEHeader = noSSEHeader;
+ this.xPaddingBytes = xPaddingBytes;
+ this.xmux = xmux;
+ }
+
+ addHeader(name, value) {
+ this.headers.push({ name: name, value: value });
+ }
+
+ removeHeader(index) {
+ this.headers.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ return new SplitHTTPStreamSettings(
+ json.path,
+ json.host,
+ XrayCommonClass.toHeaders(json.headers),
+ json.scMaxConcurrentPosts,
+ json.scMaxEachPostBytes,
+ json.scMinPostsIntervalMs,
+ json.noSSEHeader,
+ json.xPaddingBytes,
+ json.xmux,
+ );
+ }
+
+ toJson() {
+ return {
+ path: this.path,
+ host: this.host,
+ headers: XrayCommonClass.toV2Headers(this.headers, false),
+ scMaxConcurrentPosts: this.scMaxConcurrentPosts,
+ scMaxEachPostBytes: this.scMaxEachPostBytes,
+ scMinPostsIntervalMs: this.scMinPostsIntervalMs,
+ noSSEHeader: this.noSSEHeader,
+ xPaddingBytes: this.xPaddingBytes,
+ xmux: {
+ maxConcurrency: this.xmux.maxConcurrency,
+ maxConnections: this.xmux.maxConnections,
+ cMaxReuseTimes: this.xmux.cMaxReuseTimes,
+ cMaxLifetimeMs: this.xmux.cMaxLifetimeMs
+ }
+ };
+ }
+}
+
+class TlsStreamSettings extends XrayCommonClass {
+ constructor(
+ serverName = '',
+ minVersion = TLS_VERSION_OPTION.TLS12,
+ maxVersion = TLS_VERSION_OPTION.TLS13,
+ cipherSuites = '',
+ rejectUnknownSni = false,
+ disableSystemRoot = false,
+ enableSessionResumption = false,
+ certificates = [new TlsStreamSettings.Cert()],
+ alpn = [ALPN_OPTION.H3, ALPN_OPTION.H2, ALPN_OPTION.HTTP1],
+ settings = new TlsStreamSettings.Settings()
+ ) {
+ super();
+ this.sni = serverName;
+ this.minVersion = minVersion;
+ this.maxVersion = maxVersion;
+ this.cipherSuites = cipherSuites;
+ this.rejectUnknownSni = rejectUnknownSni;
+ this.disableSystemRoot = disableSystemRoot;
+ this.enableSessionResumption = enableSessionResumption;
+ this.certs = certificates;
+ this.alpn = alpn;
+ this.settings = settings;
+ }
+
+ addCert() {
+ this.certs.push(new TlsStreamSettings.Cert());
+ }
+
+ removeCert(index) {
+ this.certs.splice(index, 1);
+ }
+
+ static fromJson(json = {}) {
+ let certs;
+ let settings;
+ if (!ObjectUtil.isEmpty(json.certificates)) {
+ certs = json.certificates.map(cert => TlsStreamSettings.Cert.fromJson(cert));
+ }
+
+ if (!ObjectUtil.isEmpty(json.settings)) {
+ settings = new TlsStreamSettings.Settings(json.settings.allowInsecure, json.settings.fingerprint, json.settings.serverName, json.settings.domains);
+ }
+ return new TlsStreamSettings(
+ json.serverName,
+ json.minVersion,
+ json.maxVersion,
+ json.cipherSuites,
+ json.rejectUnknownSni,
+ json.disableSystemRoot,
+ json.enableSessionResumption,
+ certs,
+ json.alpn,
+ settings,
+ );
+ }
+
+ toJson() {
+ return {
+ serverName: this.sni,
+ minVersion: this.minVersion,
+ maxVersion: this.maxVersion,
+ cipherSuites: this.cipherSuites,
+ rejectUnknownSni: this.rejectUnknownSni,
+ disableSystemRoot: this.disableSystemRoot,
+ enableSessionResumption: this.enableSessionResumption,
+ certificates: TlsStreamSettings.toJsonArray(this.certs),
+ alpn: this.alpn,
+ settings: this.settings,
+ };
+ }
+}
+
+TlsStreamSettings.Cert = class extends XrayCommonClass {
+ constructor(
+ useFile = true,
+ certificateFile = '',
+ keyFile = '',
+ certificate = '',
+ key = '',
+ ocspStapling = 3600,
+ oneTimeLoading = false,
+ usage = USAGE_OPTION.ENCIPHERMENT,
+ buildChain = false,
+ ) {
+ super();
+ this.useFile = useFile;
+ this.certFile = certificateFile;
+ this.keyFile = keyFile;
+ this.cert = Array.isArray(certificate) ? certificate.join('\n') : certificate;
+ this.key = Array.isArray(key) ? key.join('\n') : key;
+ this.ocspStapling = ocspStapling;
+ this.oneTimeLoading = oneTimeLoading;
+ this.usage = usage;
+ this.buildChain = buildChain
+ }
+
+ static fromJson(json = {}) {
+ if ('certificateFile' in json && 'keyFile' in json) {
+ return new TlsStreamSettings.Cert(
+ true,
+ json.certificateFile,
+ json.keyFile, '', '',
+ json.ocspStapling,
+ json.oneTimeLoading,
+ json.usage,
+ json.buildChain,
+ );
+ } else {
+ return new TlsStreamSettings.Cert(
+ false, '', '',
+ json.certificate.join('\n'),
+ json.key.join('\n'),
+ json.ocspStapling,
+ json.oneTimeLoading,
+ json.usage,
+ json.buildChain,
+ );
+ }
+ }
+
+ toJson() {
+ if (this.useFile) {
+ return {
+ certificateFile: this.certFile,
+ keyFile: this.keyFile,
+ ocspStapling: this.ocspStapling,
+ oneTimeLoading: this.oneTimeLoading,
+ usage: this.usage,
+ buildChain: this.buildChain,
+ };
+ } else {
+ return {
+ certificate: this.cert.split('\n'),
+ key: this.key.split('\n'),
+ ocspStapling: this.ocspStapling,
+ oneTimeLoading: this.oneTimeLoading,
+ usage: this.usage,
+ buildChain: this.buildChain,
+ };
+ }
+ }
+};
+
+TlsStreamSettings.Settings = class extends XrayCommonClass {
+ constructor(allowInsecure = false, fingerprint = '') {
+ super();
+ this.allowInsecure = allowInsecure;
+ this.fingerprint = fingerprint;
+ }
+ static fromJson(json = {}) {
+ return new TlsStreamSettings.Settings(
+ json.allowInsecure,
+ json.fingerprint,
+ );
+ }
+ toJson() {
+ return {
+ allowInsecure: this.allowInsecure,
+ fingerprint: this.fingerprint,
+ };
+ }
+};
+
+
+class RealityStreamSettings extends XrayCommonClass {
+ constructor(
+ show = false,
+ xver = 0,
+ dest = 'yahoo.com:443',
+ serverNames = 'yahoo.com,www.yahoo.com',
+ privateKey = '',
+ minClient = '',
+ maxClient = '',
+ maxTimediff = 0,
+ shortIds = RandomUtil.randomShortIds(),
+ settings = new RealityStreamSettings.Settings()
+ ) {
+ super();
+ this.show = show;
+ this.xver = xver;
+ this.dest = dest;
+ this.serverNames = Array.isArray(serverNames) ? serverNames.join(",") : serverNames;
+ this.privateKey = privateKey;
+ this.minClient = minClient;
+ this.maxClient = maxClient;
+ this.maxTimediff = maxTimediff;
+ this.shortIds = Array.isArray(shortIds) ? shortIds.join(",") : shortIds;
+ this.settings = settings;
+ }
+
+ static fromJson(json = {}) {
+ let settings;
+ if (!ObjectUtil.isEmpty(json.settings)) {
+ settings = new RealityStreamSettings.Settings(
+ json.settings.publicKey,
+ json.settings.fingerprint,
+ json.settings.serverName,
+ json.settings.spiderX
+ );
+ }
+ return new RealityStreamSettings(
+ json.show,
+ json.xver,
+ json.dest,
+ json.serverNames,
+ json.privateKey,
+ json.minClient,
+ json.maxClient,
+ json.maxTimediff,
+ json.shortIds,
+ json.settings,
+ );
+ }
+
+ toJson() {
+ return {
+ show: this.show,
+ xver: this.xver,
+ dest: this.dest,
+ serverNames: this.serverNames.split(","),
+ privateKey: this.privateKey,
+ minClient: this.minClient,
+ maxClient: this.maxClient,
+ maxTimediff: this.maxTimediff,
+ shortIds: this.shortIds.split(","),
+ settings: this.settings,
+ };
+ }
+}
+
+RealityStreamSettings.Settings = class extends XrayCommonClass {
+ constructor(
+ publicKey = '',
+ fingerprint = UTLS_FINGERPRINT.UTLS_RANDOM,
+ serverName = '',
+ spiderX = '/'
+ ) {
+ super();
+ this.publicKey = publicKey;
+ this.fingerprint = fingerprint;
+ this.serverName = serverName;
+ this.spiderX = spiderX;
+ }
+ static fromJson(json = {}) {
+ return new RealityStreamSettings.Settings(
+ json.publicKey,
+ json.fingerprint,
+ json.serverName,
+ json.spiderX,
+ );
+ }
+ toJson() {
+ return {
+ publicKey: this.publicKey,
+ fingerprint: this.fingerprint,
+ serverName: this.serverName,
+ spiderX: this.spiderX,
+ };
+ }
+};
+
+class SockoptStreamSettings extends XrayCommonClass {
+ constructor(
+ acceptProxyProtocol = false,
+ tcpFastOpen = false,
+ mark = 0,
+ tproxy = "off",
+ tcpMptcp = false,
+ tcpNoDelay = false,
+ domainStrategy = DOMAIN_STRATEGY_OPTION.USE_IP,
+ tcpMaxSeg = 1440,
+ dialerProxy = "",
+ tcpKeepAliveInterval = 0,
+ tcpKeepAliveIdle = 300,
+ tcpUserTimeout = 10000,
+ tcpcongestion = TCP_CONGESTION_OPTION.BBR,
+ V6Only = false,
+ tcpWindowClamp = 600,
+ interfaceName = "",
+ ) {
+ super();
+ this.acceptProxyProtocol = acceptProxyProtocol;
+ this.tcpFastOpen = tcpFastOpen;
+ this.mark = mark;
+ this.tproxy = tproxy;
+ this.tcpMptcp = tcpMptcp;
+ this.tcpNoDelay = tcpNoDelay;
+ this.domainStrategy = domainStrategy;
+ this.tcpMaxSeg = tcpMaxSeg;
+ this.dialerProxy = dialerProxy;
+ this.tcpKeepAliveInterval = tcpKeepAliveInterval;
+ this.tcpKeepAliveIdle = tcpKeepAliveIdle;
+ this.tcpUserTimeout = tcpUserTimeout;
+ this.tcpcongestion = tcpcongestion;
+ this.V6Only = V6Only;
+ this.tcpWindowClamp = tcpWindowClamp;
+ this.interfaceName = interfaceName;
+ }
+
+ static fromJson(json = {}) {
+ if (Object.keys(json).length === 0) return undefined;
+ return new SockoptStreamSettings(
+ json.acceptProxyProtocol,
+ json.tcpFastOpen,
+ json.mark,
+ json.tproxy,
+ json.tcpMptcp,
+ json.tcpNoDelay,
+ json.domainStrategy,
+ json.tcpMaxSeg,
+ json.dialerProxy,
+ json.tcpKeepAliveInterval,
+ json.tcpKeepAliveIdle,
+ json.tcpUserTimeout,
+ json.tcpcongestion,
+ json.V6Only,
+ json.tcpWindowClamp,
+ json.interface,
+ );
+ }
+
+ toJson() {
+ return {
+ acceptProxyProtocol: this.acceptProxyProtocol,
+ tcpFastOpen: this.tcpFastOpen,
+ mark: this.mark,
+ tproxy: this.tproxy,
+ tcpMptcp: this.tcpMptcp,
+ tcpNoDelay: this.tcpNoDelay,
+ domainStrategy: this.domainStrategy,
+ tcpMaxSeg: this.tcpMaxSeg,
+ dialerProxy: this.dialerProxy,
+ tcpKeepAliveInterval: this.tcpKeepAliveInterval,
+ tcpKeepAliveIdle: this.tcpKeepAliveIdle,
+ tcpUserTimeout: this.tcpUserTimeout,
+ tcpcongestion: this.tcpcongestion,
+ V6Only: this.V6Only,
+ tcpWindowClamp: this.tcpWindowClamp,
+ interface: this.interfaceName,
+ };
+ }
+}
+
+class StreamSettings extends XrayCommonClass {
+ constructor(network = 'tcp',
+ security = 'none',
+ externalProxy = [],
+ tlsSettings = new TlsStreamSettings(),
+ realitySettings = new RealityStreamSettings(),
+ tcpSettings = new TcpStreamSettings(),
+ kcpSettings = new KcpStreamSettings(),
+ wsSettings = new WsStreamSettings(),
+ httpSettings = new HttpStreamSettings(),
+ grpcSettings = new GrpcStreamSettings(),
+ httpupgradeSettings = new HTTPUpgradeStreamSettings(),
+ splithttpSettings = new SplitHTTPStreamSettings(),
+ sockopt = undefined,
+ ) {
+ super();
+ this.network = network;
+ this.security = security;
+ this.externalProxy = externalProxy;
+ this.tls = tlsSettings;
+ this.reality = realitySettings;
+ this.tcp = tcpSettings;
+ this.kcp = kcpSettings;
+ this.ws = wsSettings;
+ this.http = httpSettings;
+ this.grpc = grpcSettings;
+ this.httpupgrade = httpupgradeSettings;
+ this.splithttp = splithttpSettings;
+ this.sockopt = sockopt;
+ }
+
+ get isTls() {
+ return this.security === "tls";
+ }
+
+ set isTls(isTls) {
+ if (isTls) {
+ this.security = 'tls';
+ } else {
+ this.security = 'none';
+ }
+ }
+
+ //for Reality
+ get isReality() {
+ return this.security === "reality";
+ }
+
+ set isReality(isReality) {
+ if (isReality) {
+ this.security = 'reality';
+ } else {
+ this.security = 'none';
+ }
+ }
+
+ get sockoptSwitch() {
+ return this.sockopt != undefined;
+ }
+
+ set sockoptSwitch(value) {
+ this.sockopt = value ? new SockoptStreamSettings() : undefined;
+ }
+
+ static fromJson(json = {}) {
+ return new StreamSettings(
+ json.network,
+ json.security,
+ json.externalProxy,
+ TlsStreamSettings.fromJson(json.tlsSettings),
+ RealityStreamSettings.fromJson(json.realitySettings),
+ TcpStreamSettings.fromJson(json.tcpSettings),
+ KcpStreamSettings.fromJson(json.kcpSettings),
+ WsStreamSettings.fromJson(json.wsSettings),
+ HttpStreamSettings.fromJson(json.httpSettings),
+ GrpcStreamSettings.fromJson(json.grpcSettings),
+ HTTPUpgradeStreamSettings.fromJson(json.httpupgradeSettings),
+ SplitHTTPStreamSettings.fromJson(json.splithttpSettings),
+ SockoptStreamSettings.fromJson(json.sockopt),
+ );
+ }
+
+ toJson() {
+ const network = this.network;
+ return {
+ network: network,
+ security: this.security,
+ externalProxy: this.externalProxy,
+ tlsSettings: this.isTls ? this.tls.toJson() : undefined,
+ realitySettings: this.isReality ? this.reality.toJson() : undefined,
+ tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,
+ kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined,
+ wsSettings: network === 'ws' ? this.ws.toJson() : undefined,
+ httpSettings: network === 'http' ? this.http.toJson() : undefined,
+ grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,
+ httpupgradeSettings: network === 'httpupgrade' ? this.httpupgrade.toJson() : undefined,
+ splithttpSettings: network === 'splithttp' ? this.splithttp.toJson() : undefined,
+ sockopt: this.sockopt != undefined ? this.sockopt.toJson() : undefined,
+ };
+ }
+}
+
+class Sniffing extends XrayCommonClass {
+ constructor(
+ enabled = false,
+ destOverride = ['http', 'tls', 'quic', 'fakedns'],
+ metadataOnly = false,
+ routeOnly = false) {
+ super();
+ this.enabled = enabled;
+ this.destOverride = destOverride;
+ this.metadataOnly = metadataOnly;
+ this.routeOnly = routeOnly;
+ }
+
+ static fromJson(json = {}) {
+ let destOverride = ObjectUtil.clone(json.destOverride);
+ if (!ObjectUtil.isEmpty(destOverride) && !ObjectUtil.isArrEmpty(destOverride)) {
+ if (ObjectUtil.isEmpty(destOverride[0])) {
+ destOverride = ['http', 'tls', 'quic', 'fakedns'];
+ }
+ }
+ return new Sniffing(
+ !!json.enabled,
+ destOverride,
+ json.metadataOnly,
+ json.routeOnly,
+ );
+ }
+}
+
+class Allocate extends XrayCommonClass {
+ constructor(
+ strategy = "always",
+ refresh = 5,
+ concurrency = 3,
+ ) {
+ super();
+ this.strategy = strategy;
+ this.refresh = refresh;
+ this.concurrency = concurrency;
+ }
+
+ static fromJson(json = {}) {
+ return new Allocate(
+ json.strategy,
+ json.refresh,
+ json.concurrency,
+ );
+ }
+}
+
+class Inbound extends XrayCommonClass {
+ constructor(
+ port = RandomUtil.randomIntRange(10000, 60000),
+ listen = '',
+ protocol = Protocols.VLESS,
+ settings = null,
+ streamSettings = new StreamSettings(),
+ tag = '',
+ sniffing = new Sniffing(),
+ allocate = new Allocate(),
+ clientStats = '',
+ ) {
+ super();
+ this.port = port;
+ this.listen = listen;
+ this._protocol = protocol;
+ this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings;
+ this.stream = streamSettings;
+ this.tag = tag;
+ this.sniffing = sniffing;
+ this.allocate = allocate;
+ this.clientStats = clientStats;
+ }
+ getClientStats() {
+ return this.clientStats;
+ }
+
+ get clients() {
+ switch (this.protocol) {
+ case Protocols.VMESS: return this.settings.vmesses;
+ case Protocols.VLESS: return this.settings.vlesses;
+ case Protocols.TROJAN: return this.settings.trojans;
+ case Protocols.SHADOWSOCKS: return this.isSSMultiUser ? this.settings.shadowsockses : null;
+ default: return null;
+ }
+ }
+