mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-12 04:29:00 +08:00
feat: VLESS URI
This commit is contained in:
parent
5e14d05c30
commit
8bfa4dbbf2
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.14.30",
|
"version": "2.14.31",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -306,6 +306,85 @@ function URI_VMess() {
|
|||||||
return { name, test, parse };
|
return { name, test, parse };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function URI_VLESS() {
|
||||||
|
const name = 'URI VLESS Parser';
|
||||||
|
const test = (line) => {
|
||||||
|
return /^vless:\/\//.test(line);
|
||||||
|
};
|
||||||
|
const parse = (line) => {
|
||||||
|
line = line.split('vless://')[1];
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
let [__, uuid, server, port, addons, name] =
|
||||||
|
/^(.*?)@(.*?):(\d+)\/?\?(.*?)(?:#(.*?))$/.exec(line);
|
||||||
|
port = parseInt(`${port}`, 10);
|
||||||
|
uuid = decodeURIComponent(uuid);
|
||||||
|
name = decodeURIComponent(name) ?? `VLESS ${server}:${port}`;
|
||||||
|
const proxy = {
|
||||||
|
type: 'vless',
|
||||||
|
name,
|
||||||
|
server,
|
||||||
|
port,
|
||||||
|
uuid,
|
||||||
|
};
|
||||||
|
const params = {};
|
||||||
|
for (const addon of addons.split('&')) {
|
||||||
|
const [key, valueRaw] = addon.split('=');
|
||||||
|
let value = valueRaw;
|
||||||
|
value = decodeURIComponent(valueRaw);
|
||||||
|
params[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.tls = params.security && params.security !== 'none';
|
||||||
|
proxy.sni = params.sni;
|
||||||
|
proxy.flow = params.flow;
|
||||||
|
proxy['client-fingerprint'] = params.fp;
|
||||||
|
proxy.alpn = params.alpn ? params.alpn.split(',') : undefined;
|
||||||
|
proxy['skip-cert-verify'] = /(TRUE)|1/i.test(params.allowInsecure);
|
||||||
|
|
||||||
|
if (['reality'].includes(params.security)) {
|
||||||
|
const opts = {};
|
||||||
|
if (params.pbk) {
|
||||||
|
opts['public-key'] = params.pbk;
|
||||||
|
}
|
||||||
|
if (params.sid) {
|
||||||
|
opts['short-id'] = params.sid;
|
||||||
|
}
|
||||||
|
if (Object.keys(opts).length > 0) {
|
||||||
|
proxy[`${params.security}-opts`] = opts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.network = params.type;
|
||||||
|
if (proxy.network && !['tcp', 'none'].includes(proxy.network)) {
|
||||||
|
const opts = {};
|
||||||
|
if (params.path) {
|
||||||
|
opts.path = params.path;
|
||||||
|
}
|
||||||
|
if (params.host) {
|
||||||
|
opts.headers = { Host: params.host };
|
||||||
|
}
|
||||||
|
if (params.serviceName) {
|
||||||
|
opts[`${proxy.network}-service-name`] = params.serviceName;
|
||||||
|
}
|
||||||
|
if (Object.keys(opts).length > 0) {
|
||||||
|
proxy[`${proxy.network}-opts`] = opts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxy.tls && !proxy.sni) {
|
||||||
|
if (proxy.network === 'ws') {
|
||||||
|
proxy.sni = proxy['ws-opts']?.headers?.Host;
|
||||||
|
} else if (proxy.network === 'http') {
|
||||||
|
let httpHost = proxy['http-opts']?.headers?.Host;
|
||||||
|
proxy.sni = Array.isArray(httpHost) ? httpHost[0] : httpHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy;
|
||||||
|
};
|
||||||
|
return { name, test, parse };
|
||||||
|
}
|
||||||
|
|
||||||
// Trojan URI format
|
// Trojan URI format
|
||||||
function URI_Trojan() {
|
function URI_Trojan() {
|
||||||
const name = 'URI Trojan Parser';
|
const name = 'URI Trojan Parser';
|
||||||
@ -680,6 +759,7 @@ export default [
|
|||||||
URI_SS(),
|
URI_SS(),
|
||||||
URI_SSR(),
|
URI_SSR(),
|
||||||
URI_VMess(),
|
URI_VMess(),
|
||||||
|
URI_VLESS(),
|
||||||
URI_Trojan(),
|
URI_Trojan(),
|
||||||
Clash_All(),
|
Clash_All(),
|
||||||
Surge_SS(),
|
Surge_SS(),
|
||||||
|
@ -94,6 +94,89 @@ export default function URI_Producer() {
|
|||||||
}
|
}
|
||||||
result = 'vmess://' + Base64.encode(JSON.stringify(result));
|
result = 'vmess://' + Base64.encode(JSON.stringify(result));
|
||||||
break;
|
break;
|
||||||
|
case 'vless':
|
||||||
|
let security = 'none';
|
||||||
|
const isReality = proxy['reality-opts'];
|
||||||
|
let sid = '';
|
||||||
|
let pbk = '';
|
||||||
|
if (isReality) {
|
||||||
|
security = 'reality';
|
||||||
|
const publicKey = proxy['reality-opts']?.['public-key'];
|
||||||
|
if (publicKey) {
|
||||||
|
pbk = `&pbk=${encodeURIComponent(publicKey)}`;
|
||||||
|
}
|
||||||
|
const shortId = proxy['reality-opts']?.['short-id'];
|
||||||
|
if (shortId) {
|
||||||
|
sid = `&sid=${encodeURIComponent(shortId)}`;
|
||||||
|
}
|
||||||
|
} else if (proxy.tls) {
|
||||||
|
security = 'tls';
|
||||||
|
}
|
||||||
|
let alpn = '';
|
||||||
|
if (proxy.alpn) {
|
||||||
|
alpn = `&alpn=${encodeURIComponent(
|
||||||
|
Array.isArray(proxy.alpn)
|
||||||
|
? proxy.alpn
|
||||||
|
: proxy.alpn.join(','),
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
let allowInsecure = '';
|
||||||
|
if (proxy['skip-cert-verify']) {
|
||||||
|
allowInsecure = `&allowInsecure=1`;
|
||||||
|
}
|
||||||
|
let sni = '';
|
||||||
|
if (proxy.sni) {
|
||||||
|
sni = `&sni=${encodeURIComponent(proxy.sni)}`;
|
||||||
|
}
|
||||||
|
let fp = '';
|
||||||
|
if (proxy['client-fingerprint']) {
|
||||||
|
fp = `&fp=${encodeURIComponent(
|
||||||
|
proxy['client-fingerprint'],
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
let flow = '';
|
||||||
|
if (proxy.flow) {
|
||||||
|
flow = `&flow=${encodeURIComponent(proxy.flow)}`;
|
||||||
|
}
|
||||||
|
let vlessTransport = `&type=${encodeURIComponent(
|
||||||
|
proxy.network,
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
let vlessTransportServiceName =
|
||||||
|
proxy[`${proxy.network}-opts`]?.[
|
||||||
|
`${proxy.network}-service-name`
|
||||||
|
];
|
||||||
|
let vlessTransportPath = proxy[`${proxy.network}-opts`]?.path;
|
||||||
|
let vlessTransportHost =
|
||||||
|
proxy[`${proxy.network}-opts`]?.headers?.Host;
|
||||||
|
if (vlessTransportPath) {
|
||||||
|
vlessTransport += `&path=${encodeURIComponent(
|
||||||
|
Array.isArray(vlessTransportPath)
|
||||||
|
? vlessTransportPath[0]
|
||||||
|
: vlessTransportPath,
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
if (vlessTransportHost) {
|
||||||
|
vlessTransport += `&host=${encodeURIComponent(
|
||||||
|
Array.isArray(vlessTransportHost)
|
||||||
|
? vlessTransportHost[0]
|
||||||
|
: vlessTransportHost,
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
if (vlessTransportServiceName) {
|
||||||
|
vlessTransport += `&serviceName=${encodeURIComponent(
|
||||||
|
vlessTransportServiceName,
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = `vless://${proxy.uuid}@${proxy.server}:${
|
||||||
|
proxy.port
|
||||||
|
}?${vlessTransport}&security=${encodeURIComponent(
|
||||||
|
security,
|
||||||
|
)}${alpn}${allowInsecure}${sni}${fp}${flow}${sid}${pbk}#${encodeURIComponent(
|
||||||
|
proxy.name,
|
||||||
|
)}`;
|
||||||
|
break;
|
||||||
case 'trojan':
|
case 'trojan':
|
||||||
let trojanTransport = '';
|
let trojanTransport = '';
|
||||||
if (proxy.network) {
|
if (proxy.network) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user