mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-12 02:18:59 +08:00
Reworked QX producer
This commit is contained in:
parent
1e22243808
commit
4b73a1494b
6
backend/dist/sub-store-parser.loon.min.js
vendored
6
backend/dist/sub-store-parser.loon.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sub-store",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.5",
|
||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
|
@ -352,6 +352,15 @@ function QX_Http() {
|
||||
return { name, test, parse };
|
||||
}
|
||||
|
||||
function QX_Socks5() {
|
||||
const name = 'QX Socks5 Parser';
|
||||
const test = (line) => {
|
||||
return /^socks5\s*=/.test(line.split(',')[0].trim());
|
||||
};
|
||||
const parse = (line) => getQXParser().parse(line);
|
||||
return { name, test, parse };
|
||||
}
|
||||
|
||||
function Loon_SS() {
|
||||
const name = 'Loon SS Parser';
|
||||
const test = (line) => {
|
||||
@ -481,4 +490,5 @@ export default [
|
||||
QX_VMess(),
|
||||
QX_Trojan(),
|
||||
QX_Http(),
|
||||
QX_Socks5(),
|
||||
];
|
||||
|
@ -56,6 +56,7 @@ shadowsocks = tag equals "shadowsocks"i address method password (obfs_ss/obfs_ho
|
||||
}
|
||||
vmess = tag equals "vmess"i address method uuid (transport/transport_host/transport_path/over_tls/tls_host/tls_verification/vmess_alterId/fast_open/udp_relay/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleTransport();
|
||||
}
|
||||
vless = tag equals "vless"i address uuid (transport/transport_host/transport_path/over_tls/tls_host/tls_verification/fast_open/udp_relay/others)* {
|
||||
|
@ -54,6 +54,7 @@ shadowsocks = tag equals "shadowsocks"i address method password (obfs_ss/obfs_ho
|
||||
}
|
||||
vmess = tag equals "vmess"i address method uuid (transport/transport_host/transport_path/over_tls/tls_host/tls_verification/vmess_alterId/fast_open/udp_relay/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleTransport();
|
||||
}
|
||||
vless = tag equals "vless"i address uuid (transport/transport_host/transport_path/over_tls/tls_host/tls_verification/fast_open/udp_relay/others)* {
|
||||
|
@ -29,8 +29,7 @@ const grammars = String.raw`
|
||||
$set(proxy, "ws-opts.path", obfs.path);
|
||||
$set(proxy, "ws-opts.headers.Host", obfs.host);
|
||||
} else if (obfs.type === "over-tls") {
|
||||
proxy.tls = true;
|
||||
proxy.sni = proxy.sni || proxy.server;
|
||||
throw new Error("over-tls is not supported");
|
||||
} else if (obfs.type === "http") {
|
||||
proxy.network = "http";
|
||||
$set(proxy, "http-opts.path", obfs.path);
|
||||
@ -83,6 +82,7 @@ shadowsocks = "shadowsocks" equals address
|
||||
vmess = "vmess" equals address
|
||||
(uuid/method/over_tls/tls_host/tls_verification/tag/obfs/obfs_host/obfs_uri/udp_relay/udp_over_tcp/fast_open/aead/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleObfs();
|
||||
}
|
||||
|
||||
@ -145,9 +145,7 @@ fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
|
||||
over_tls = comma "over-tls" equals flag:bool { proxy.tls = flag; }
|
||||
tls_host = comma "tls-host" equals sni:domain { proxy.sni = sni; }
|
||||
tls_verification = comma "tls-verification" equals flag:bool {
|
||||
if (!flag) {
|
||||
proxy["skip-cert-verify"] = true;
|
||||
}
|
||||
proxy["skip-cert-verify"] = !flag;
|
||||
}
|
||||
|
||||
obfs_ss = comma "obfs" equals type:("http"/"tls"/"wss"/"ws") { obfs.type = type; return type; }
|
||||
|
@ -27,8 +27,7 @@
|
||||
$set(proxy, "ws-opts.path", obfs.path);
|
||||
$set(proxy, "ws-opts.headers.Host", obfs.host);
|
||||
} else if (obfs.type === "over-tls") {
|
||||
proxy.tls = true;
|
||||
proxy.sni = proxy.sni || proxy.server;
|
||||
throw new Error("over-tls is not supported");
|
||||
} else if (obfs.type === "http") {
|
||||
proxy.network = "http";
|
||||
$set(proxy, "http-opts.path", obfs.path);
|
||||
@ -81,6 +80,7 @@ shadowsocks = "shadowsocks" equals address
|
||||
vmess = "vmess" equals address
|
||||
(uuid/method/over_tls/tls_host/tls_verification/tag/obfs/obfs_host/obfs_uri/udp_relay/udp_over_tcp/fast_open/aead/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleObfs();
|
||||
}
|
||||
|
||||
@ -143,9 +143,7 @@ fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
|
||||
over_tls = comma "over-tls" equals flag:bool { proxy.tls = flag; }
|
||||
tls_host = comma "tls-host" equals sni:domain { proxy.sni = sni; }
|
||||
tls_verification = comma "tls-verification" equals flag:bool {
|
||||
if (!flag) {
|
||||
proxy["skip-cert-verify"] = true;
|
||||
}
|
||||
proxy["skip-cert-verify"] = !flag;
|
||||
}
|
||||
|
||||
obfs_ss = comma "obfs" equals type:("http"/"tls"/"wss"/"ws") { obfs.type = type; return type; }
|
||||
|
@ -45,6 +45,7 @@ shadowsocks = tag equals "ss" address (method/passwordk/obfs/obfs_host/obfs_uri/
|
||||
}
|
||||
vmess = tag equals "vmess" address (vmess_uuid/vmess_aead/ws/ws_path/ws_headers/method/tls/sni/tls_verification/fast_open/udp_relay/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleWebsocket();
|
||||
}
|
||||
trojan = tag equals "trojan" address (passwordk/ws/ws_path/ws_headers/tls/sni/tls_verification/fast_open/udp_relay/others)* {
|
||||
|
@ -43,6 +43,7 @@ shadowsocks = tag equals "ss" address (method/passwordk/obfs/obfs_host/obfs_uri/
|
||||
}
|
||||
vmess = tag equals "vmess" address (vmess_uuid/vmess_aead/ws/ws_path/ws_headers/method/tls/sni/tls_verification/fast_open/udp_relay/others)* {
|
||||
proxy.type = "vmess";
|
||||
proxy.cipher = proxy.cipher || "none";
|
||||
handleWebsocket();
|
||||
}
|
||||
trojan = tag equals "trojan" address (passwordk/ws/ws_path/ws_headers/tls/sni/tls_verification/fast_open/udp_relay/others)* {
|
||||
|
@ -1,115 +1,21 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
import { Result } from './utils';
|
||||
const targetPlatform = 'QX';
|
||||
|
||||
export default function QX_Producer() {
|
||||
const targetPlatform = 'QX';
|
||||
const produce = (proxy) => {
|
||||
let obfs_opts;
|
||||
let tls_opts;
|
||||
switch (proxy.type) {
|
||||
case 'ss':
|
||||
obfs_opts = '';
|
||||
if (proxy.plugin === 'obfs') {
|
||||
const { host, mode } = proxy['plugin-opts'];
|
||||
obfs_opts = `,obfs=${mode}${
|
||||
host ? ',obfs-host=' + host : ''
|
||||
}`;
|
||||
}
|
||||
if (proxy.plugin === 'v2ray-plugin') {
|
||||
const { tls, host, path } = proxy['plugin-opts'];
|
||||
obfs_opts = `,obfs=${tls ? 'wss' : 'ws'}${
|
||||
host ? ',obfs-host=' + host : ''
|
||||
}${path ? ',obfs-uri=' + path : ''}`;
|
||||
}
|
||||
return `shadowsocks=${proxy.server}:${proxy.port},method=${
|
||||
proxy.cipher
|
||||
},password=${proxy.password}${obfs_opts}${
|
||||
proxy.tfo ? ',fast-open=true' : ',fast-open=false'
|
||||
}${proxy.udp ? ',udp-relay=true' : ',udp-relay=false'},tag=${
|
||||
proxy.name
|
||||
}`;
|
||||
return shadowsocks(proxy);
|
||||
case 'ssr':
|
||||
return `shadowsocks=${proxy.server}:${proxy.port},method=${
|
||||
proxy.cipher
|
||||
},password=${proxy.password},ssr-protocol=${proxy.protocol}${
|
||||
proxy['protocol-param']
|
||||
? ',ssr-protocol-param=' + proxy['protocol-param']
|
||||
: ''
|
||||
}${proxy.obfs ? ',obfs=' + proxy.obfs : ''}${
|
||||
proxy['obfs-param']
|
||||
? ',obfs-host=' + proxy['obfs-param']
|
||||
: ''
|
||||
},fast-open=${proxy.tfo || false}${
|
||||
proxy.udp ? ',udp-relay=true' : ',udp-relay=false'
|
||||
},tag=${proxy.name}`;
|
||||
case 'vmess':
|
||||
obfs_opts = '';
|
||||
if (proxy.network === 'ws') {
|
||||
// websocket
|
||||
if (proxy.tls) {
|
||||
// ws-tls
|
||||
obfs_opts = `,obfs=wss${
|
||||
proxy.sni ? ',obfs-host=' + proxy.sni : ''
|
||||
}${
|
||||
proxy['ws-opts'].path
|
||||
? ',obfs-uri=' + proxy['ws-opts'].path
|
||||
: ''
|
||||
},tls-verification=${
|
||||
proxy['skip-cert-verify'] ? 'false' : 'true'
|
||||
}`;
|
||||
} else {
|
||||
// ws
|
||||
obfs_opts = `,obfs=ws${
|
||||
proxy['ws-opts'].headers.Host
|
||||
? ',obfs-host=' + proxy['ws-opts'].headers.Host
|
||||
: ''
|
||||
}${
|
||||
proxy['ws-opts'].path
|
||||
? ',obfs-uri=' + proxy['ws-opts'].path
|
||||
: ''
|
||||
}`;
|
||||
}
|
||||
} else {
|
||||
// tcp
|
||||
if (proxy.tls) {
|
||||
obfs_opts = `,obfs=over-tls${
|
||||
proxy.sni ? ',obfs-host=' + proxy.sni : ''
|
||||
},tls-verification=${
|
||||
proxy['skip-cert-verify'] ? 'false' : 'true'
|
||||
}`;
|
||||
}
|
||||
}
|
||||
let result = `vmess=${proxy.server}:${proxy.port},method=${
|
||||
proxy.cipher === 'auto' ? 'none' : proxy.cipher
|
||||
},password=${proxy.uuid}${obfs_opts},fast-open=${
|
||||
proxy.tfo || false
|
||||
}${proxy.udp ? ',udp-relay=true' : ',udp-relay=false'}`;
|
||||
if (proxy.alterId === 0) proxy['vmess-aead'] = true;
|
||||
if (typeof proxy['vmess-aead'] !== 'undefined') {
|
||||
result += `,aead=${proxy['vmess-aead']}`;
|
||||
}
|
||||
result += `,tag=${proxy.name}`;
|
||||
return result;
|
||||
return shadowsocksr(proxy);
|
||||
case 'trojan':
|
||||
return `trojan=${proxy.server}:${proxy.port},password=${
|
||||
proxy.password
|
||||
}${
|
||||
proxy.sni ? ',tls-host=' + proxy.sni : ''
|
||||
},over-tls=true,tls-verification=${
|
||||
proxy['skip-cert-verify'] ? 'false' : 'true'
|
||||
},fast-open=${proxy.tfo || false}${
|
||||
proxy.udp ? ',udp-relay=true' : ',udp-relay=false'
|
||||
},tag=${proxy.name}`;
|
||||
return trojan(proxy);
|
||||
case 'vmess':
|
||||
return vmess(proxy);
|
||||
case 'http':
|
||||
tls_opts = '';
|
||||
if (proxy.tls) {
|
||||
tls_opts = `,over-tls=true,tls-verification=${
|
||||
proxy['skip-cert-verify'] ? 'false' : 'true'
|
||||
}${proxy.sni ? ',tls-host=' + proxy.sni : ''}`;
|
||||
}
|
||||
return `http=${proxy.server}:${proxy.port},username=${
|
||||
proxy.username
|
||||
},password=${proxy.password}${tls_opts},fast-open=${
|
||||
proxy.tfo || false
|
||||
},tag=${proxy.name}`;
|
||||
return http(proxy);
|
||||
case 'socks5':
|
||||
return socks5(proxy);
|
||||
}
|
||||
throw new Error(
|
||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`,
|
||||
@ -117,3 +23,241 @@ export default function QX_Producer() {
|
||||
};
|
||||
return { produce };
|
||||
}
|
||||
|
||||
function shadowsocks(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`shadowsocks=${proxy.server}:${proxy.port}`);
|
||||
append(`,method=${proxy.cipher}`);
|
||||
append(`,password=${proxy.password}`);
|
||||
|
||||
// obfs
|
||||
if (proxy.plugin) {
|
||||
if (proxy.plugin === 'obfs') {
|
||||
const opts = proxy['plugin-opts'];
|
||||
append(`,obfs=${opts.mode}`);
|
||||
} else if (
|
||||
proxy.plugin === 'v2ray-plugin' &&
|
||||
proxy['plugin-opts'].mode === 'websocket'
|
||||
) {
|
||||
const opts = proxy['plugin-opts'];
|
||||
if (opts.tls) append(`,obfs=wss`);
|
||||
else append(`,obfs=ws`);
|
||||
}
|
||||
appendIfPresent(
|
||||
`,obfs-host=${proxy['plugin-opts'].host}`,
|
||||
'plugin-opts.host',
|
||||
);
|
||||
appendIfPresent(
|
||||
`,obfs-uri=${proxy['plugin-opts'].path}`,
|
||||
'plugin-opts.path',
|
||||
);
|
||||
}
|
||||
|
||||
// tls verification
|
||||
appendIfPresent(
|
||||
`,tls-verification=${!proxy['skip-cert-verify']}`,
|
||||
'skip-cert-verify',
|
||||
);
|
||||
appendIfPresent(`,tls-host=${proxy.sni}`, 'sni');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function shadowsocksr(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`shadowsocksr=${proxy.server}:${proxy.port}`);
|
||||
append(`,method=${proxy.cipher}`);
|
||||
append(`,password=${proxy.password}`);
|
||||
|
||||
// ssr protocol
|
||||
append(`,ssr-protocol=${proxy.protocol}`);
|
||||
appendIfPresent(
|
||||
`,ssr-proctol-param=${proxy['proctol-param']}`,
|
||||
'proctol-param',
|
||||
);
|
||||
|
||||
// obfs
|
||||
appendIfPresent(`,obfs=${proxy.obfs}`, 'obfs');
|
||||
appendIfPresent(`,obfs-host=${proxy['obfs-param']}`, 'obfs-param');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function trojan(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`trojan=${proxy.server}:${proxy.port}`);
|
||||
append(`,password=${proxy.password}`);
|
||||
|
||||
// obfs ws
|
||||
if (proxy.network === 'ws') {
|
||||
if (proxy.tls) append(`,obfs=wss`);
|
||||
else append(`,obfs=ws`);
|
||||
appendIfPresent(`,obfs-uri=${proxy['ws-opts'].path}`, 'ws-opts.path');
|
||||
appendIfPresent(
|
||||
`,obfs-host=${proxy['ws-opts'].headers.Host}`,
|
||||
'ws-opts.headers.Host',
|
||||
);
|
||||
}
|
||||
|
||||
// tls
|
||||
appendIfPresent(`,over-tls=${proxy.tls}`, 'tls');
|
||||
|
||||
// tls verification
|
||||
appendIfPresent(
|
||||
`,tls-verification=${!proxy['skip-cert-verify']}`,
|
||||
'skip-cert-verify',
|
||||
);
|
||||
appendIfPresent(`,tls-host=${proxy.sni}`, 'sni');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function vmess(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`vmess=${proxy.server}:${proxy.port}`);
|
||||
append(`,method=${proxy.cipher}`);
|
||||
append(`,password=${proxy.uuid}`);
|
||||
|
||||
// obfs
|
||||
if (proxy.network === 'ws') {
|
||||
if (proxy.tls) append(`,obfs=wss`);
|
||||
else append(`,obfs=ws`);
|
||||
appendIfPresent(`,obfs-uri=${proxy['ws-opts'].path}`, 'ws-opts.path');
|
||||
appendIfPresent(
|
||||
`,obfs-host=${proxy['ws-opts'].headers.Host}`,
|
||||
'ws-opts.headers.Host',
|
||||
);
|
||||
} else if (proxy.network === 'http') {
|
||||
append(`,obfs=http`);
|
||||
appendIfPresent(
|
||||
`,obfs-uri=${proxy['http-opts'].path}`,
|
||||
'http-opts.path',
|
||||
);
|
||||
appendIfPresent(
|
||||
`,obfs-host=${proxy['http-opts'].headers.Host}`,
|
||||
'http-opts.headers.Host',
|
||||
);
|
||||
}
|
||||
|
||||
// tls verification
|
||||
appendIfPresent(
|
||||
`,tls-verification=${!proxy['skip-cert-verify']}`,
|
||||
'skip-cert-verify',
|
||||
);
|
||||
appendIfPresent(`,tls-host=${proxy.sni}`, 'sni');
|
||||
|
||||
// AEAD
|
||||
appendIfPresent(`,aead=${proxy.alterId === 0}`, 'alterId');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function http(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`http=${proxy.server}:${proxy.port}`);
|
||||
appendIfPresent(`,username=${proxy.username}`, 'username');
|
||||
appendIfPresent(`,password=${proxy.password}`, 'password');
|
||||
|
||||
// tls
|
||||
appendIfPresent(`,over-tls=${proxy.tls}`, 'tls');
|
||||
|
||||
// tls verification
|
||||
appendIfPresent(
|
||||
`,tls-verification=${!proxy['skip-cert-verify']}`,
|
||||
'skip-cert-verify',
|
||||
);
|
||||
appendIfPresent(`,tls-host=${proxy.sni}`, 'sni');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function socks5(proxy) {
|
||||
const result = new Result(proxy);
|
||||
const append = result.append.bind(result);
|
||||
const appendIfPresent = result.appendIfPresent.bind(result);
|
||||
|
||||
append(`socks5=${proxy.server}:${proxy.port}`);
|
||||
appendIfPresent(`,username=${proxy.username}`, 'username');
|
||||
appendIfPresent(`,password=${proxy.password}`, 'password');
|
||||
|
||||
// tls
|
||||
appendIfPresent(`,over-tls=${proxy.tls}`, 'tls');
|
||||
|
||||
// tls verification
|
||||
appendIfPresent(
|
||||
`,tls-verification=${!proxy['skip-cert-verify']}`,
|
||||
'skip-cert-verify',
|
||||
);
|
||||
appendIfPresent(`,tls-host=${proxy.sni}`, 'sni');
|
||||
|
||||
// tfo
|
||||
appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo');
|
||||
|
||||
// udp
|
||||
appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
|
||||
|
||||
// tag
|
||||
append(`,tag=${proxy.name}`);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
22
backend/src/core/proxy-utils/producers/utils.js
Normal file
22
backend/src/core/proxy-utils/producers/utils.js
Normal file
@ -0,0 +1,22 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
export class Result {
|
||||
constructor(proxy) {
|
||||
this.proxy = proxy;
|
||||
this.output = [];
|
||||
}
|
||||
|
||||
append(data) {
|
||||
this.output.push(data);
|
||||
}
|
||||
|
||||
appendIfPresent(data, attr) {
|
||||
if (typeof _.get(this.proxy, attr) !== 'undefined') {
|
||||
this.append(data);
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.output.join('');
|
||||
}
|
||||
}
|
6
backend/sub-store.min.js
vendored
6
backend/sub-store.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user