Compare commits

...

2 Commits

7 changed files with 79 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.14.78",
"version": "2.14.80",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

View File

@@ -642,6 +642,15 @@ function Loon_Trojan() {
const parse = (line) => getLoonParser().parse(line);
return { name, test, parse };
}
function Loon_Hysteria2() {
const name = 'Loon Hysteria2 Parser';
const test = (line) => {
return /^.*=\s*Hysteria2/i.test(line.split(',')[0]);
};
const parse = (line) => getLoonParser().parse(line);
return { name, test, parse };
}
function Loon_Http() {
const name = 'Loon HTTP Parser';
@@ -864,6 +873,7 @@ export default [
Loon_SSR(),
Loon_VMess(),
Loon_Vless(),
Loon_Hysteria2(),
Loon_Trojan(),
Loon_Http(),
Loon_WireGuard(),

View File

@@ -35,7 +35,7 @@ const grammars = String.raw`
}
}
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http) {
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/hysteria2) {
return proxy;
}
@@ -68,6 +68,9 @@ trojan = tag equals "trojan"i address password (transport/transport_host/transpo
proxy.type = "trojan";
handleTransport();
}
hysteria2 = tag equals "hysteria2"i address password (tls_host/tls_verification/udp_relay/download_bandwidth/ecn/others)* {
proxy.type = "hysteria2";
}
https = tag equals "https"i address (username password)? (tls_host/tls_verification/fast_open/udp_relay/others)* {
proxy.type = "http";
proxy.tls = true;
@@ -167,6 +170,9 @@ tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-
fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
udp_relay = comma "udp" equals flag:bool { proxy.udp = flag; }
ecn = comma "ecn" equals flag:bool { proxy.ecn = flag; }
download_bandwidth = comma "download-bandwidth" equals match:[^,]+ { proxy.down = match.join(""); }
tag = match:[^=,]* { proxy.name = match.join("").trim(); }
comma = _ "," _
equals = _ "=" _

View File

@@ -33,7 +33,7 @@
}
}
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http) {
start = (shadowsocksr/shadowsocks/vmess/vless/trojan/https/http/hysteria2) {
return proxy;
}
@@ -66,6 +66,9 @@ trojan = tag equals "trojan"i address password (transport/transport_host/transpo
proxy.type = "trojan";
handleTransport();
}
hysteria2 = tag equals "hysteria2"i address password (tls_host/tls_verification/udp_relay/download_bandwidth/ecn/others)* {
proxy.type = "hysteria2";
}
https = tag equals "https"i address (username password)? (tls_host/tls_verification/fast_open/udp_relay/others)* {
proxy.type = "http";
proxy.tls = true;
@@ -165,6 +168,9 @@ tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-
fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
udp_relay = comma "udp" equals flag:bool { proxy.udp = flag; }
ecn = comma "ecn" equals flag:bool { proxy.ecn = flag; }
download_bandwidth = comma "download-bandwidth" equals match:[^,]+ { proxy.down = match.join(""); }
tag = match:[^=,]* { proxy.name = match.join("").trim(); }
comma = _ "," _
equals = _ "=" _

View File

@@ -20,6 +20,8 @@ export default function Loon_Producer() {
return http(proxy);
case 'wireguard':
return wireguard(proxy);
case 'hysteria2':
return hysteria2(proxy);
}
throw new Error(
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`,
@@ -334,3 +336,33 @@ function wireguard(proxy) {
return result.toString();
}
function hysteria2(proxy) {
if (proxy.obfs || proxy['obfs-password']) {
throw new Error(`obfs is unsupported`);
}
const result = new Result(proxy);
result.append(`${proxy.name}=Hysteria2,${proxy.server},${proxy.port}`);
result.appendIfPresent(`,"${proxy.password}"`, 'password');
// sni
result.appendIfPresent(`,tls-name=${proxy.sni}`, 'sni');
result.appendIfPresent(
`,skip-cert-verify=${proxy['skip-cert-verify']}`,
'skip-cert-verify',
);
// udp
result.appendIfPresent(`,udp=${proxy.udp}`, 'udp');
// download-bandwidth
result.appendIfPresent(
`,download-bandwidth=${`${proxy['down']}`.match(/\d+/)?.[0] || 0}`,
'down',
);
result.appendIfPresent(`,ecn=${proxy.ecn}`, 'ecn');
return result.toString();
}

View File

@@ -22,6 +22,16 @@ export default function register($app) {
function createCollection(req, res) {
const collection = req.body;
$.info(`正在创建组合订阅:${collection.name}`);
if (/\//.test(collection.name)) {
failed(
res,
new RequestInvalidError(
'INVALID_NAME',
`Collection ${collection.name} is invalid`,
),
);
return;
}
const allCols = $.read(COLLECTIONS_KEY);
if (findByName(allCols, collection.name)) {
failed(
@@ -31,6 +41,7 @@ function createCollection(req, res) {
`Collection ${collection.name} already exists.`,
),
);
return;
}
allCols.push(collection);
$.write(allCols, COLLECTIONS_KEY);

View File

@@ -96,6 +96,16 @@ async function getFlowInfo(req, res) {
function createSubscription(req, res) {
const sub = req.body;
$.info(`正在创建订阅: ${sub.name}`);
if (/\//.test(sub.name)) {
failed(
res,
new RequestInvalidError(
'INVALID_NAME',
`Subscription ${sub.name} is invalid`,
),
);
return;
}
const allSubs = $.read(SUBS_KEY);
if (findByName(allSubs, sub.name)) {
failed(
@@ -105,6 +115,7 @@ function createSubscription(req, res) {
`Subscription ${sub.name} already exists.`,
),
);
return;
}
allSubs.push(sub);
$.write(allSubs, SUBS_KEY);