mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-11 01:29:00 +08:00
feat: producers adjustments, VMess URI formats
This commit is contained in:
parent
afb9296158
commit
0320a77451
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sub-store",
|
||||
"version": "2.14.25",
|
||||
"version": "2.14.26",
|
||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
|
@ -217,7 +217,8 @@ function URI_VMess() {
|
||||
} catch (e) {
|
||||
// console.error(e);
|
||||
// Shadowrocket URI format
|
||||
let [_, base64Line, qs] = /(^[^?]+?)\/?\?(.*)$/.exec(line);
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let [__, base64Line, qs] = /(^[^?]+?)\/?\?(.*)$/.exec(line);
|
||||
content = Base64.decode(base64Line);
|
||||
|
||||
for (const addon of qs.split('&')) {
|
||||
@ -230,9 +231,8 @@ function URI_VMess() {
|
||||
params[key] = value.split(',');
|
||||
}
|
||||
}
|
||||
console.log(`content`, content);
|
||||
console.log(`params`, params);
|
||||
let [__, cipher, uuid, server, port] =
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let [___, cipher, uuid, server, port] =
|
||||
/(^[^:]+?):([^:]+?)@(.*):(\d+)$/.exec(content);
|
||||
|
||||
params.scy = cipher;
|
||||
@ -263,7 +263,10 @@ function URI_VMess() {
|
||||
// handle obfs
|
||||
if (params.net === 'ws' || params.obfs === 'websocket') {
|
||||
proxy.network = 'ws';
|
||||
} else if (params.net === 'tcp' || params.obfs === 'http') {
|
||||
} else if (
|
||||
['tcp', 'http'].includes(params.net) ||
|
||||
params.obfs === 'http'
|
||||
) {
|
||||
proxy.network = 'http';
|
||||
}
|
||||
if (proxy.network) {
|
||||
@ -340,6 +343,7 @@ function Clash_All() {
|
||||
'snell',
|
||||
'trojan',
|
||||
'tuic',
|
||||
'vless',
|
||||
].includes(proxy.type)
|
||||
) {
|
||||
throw new Error(
|
||||
@ -348,7 +352,7 @@ function Clash_All() {
|
||||
}
|
||||
|
||||
// handle vmess sni
|
||||
if (proxy.type === 'vmess') {
|
||||
if (['vmess', 'vless'].includes(proxy.type)) {
|
||||
proxy.sni = proxy.servername;
|
||||
delete proxy.servername;
|
||||
if (proxy.tls && !proxy.sni) {
|
||||
|
@ -5,6 +5,7 @@ import Loon_Producer from './loon';
|
||||
import URI_Producer from './uri';
|
||||
import V2Ray_Producer from './v2ray';
|
||||
import QX_Producer from './qx';
|
||||
import ShadowRocket_Producer from './shadowrocket';
|
||||
|
||||
function JSON_Producer() {
|
||||
const type = 'ALL';
|
||||
@ -21,4 +22,5 @@ export default {
|
||||
V2Ray: V2Ray_Producer(),
|
||||
JSON: JSON_Producer(),
|
||||
Stash: Stash_Producer(),
|
||||
ShadowRocket: ShadowRocket_Producer(),
|
||||
};
|
||||
|
@ -189,6 +189,9 @@ function vmess(proxy) {
|
||||
}
|
||||
|
||||
function vless(proxy) {
|
||||
if (proxy['reality-opts']) {
|
||||
throw new Error(`reality is unsupported`);
|
||||
}
|
||||
const result = new Result(proxy);
|
||||
result.append(
|
||||
`${proxy.name}=vless,${proxy.server},${proxy.port},"${proxy.uuid}"`,
|
||||
|
88
backend/src/core/proxy-utils/producers/shadowrocket.js
Normal file
88
backend/src/core/proxy-utils/producers/shadowrocket.js
Normal file
@ -0,0 +1,88 @@
|
||||
import { isPresent } from '@/core/proxy-utils/producers/utils';
|
||||
|
||||
export default function Stash_Producer() {
|
||||
const type = 'ALL';
|
||||
const produce = (proxies) => {
|
||||
return (
|
||||
'proxies:\n' +
|
||||
proxies
|
||||
.filter((proxy) => {
|
||||
if (
|
||||
proxy.type === 'snell' &&
|
||||
String(proxy.version) === '4'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((proxy) => {
|
||||
if (proxy.type === 'vmess') {
|
||||
// handle vmess aead
|
||||
if (isPresent(proxy, 'aead')) {
|
||||
if (proxy.aead) {
|
||||
proxy.alterId = 0;
|
||||
}
|
||||
delete proxy.aead;
|
||||
}
|
||||
if (isPresent(proxy, 'sni')) {
|
||||
proxy.servername = proxy.sni;
|
||||
delete proxy.sni;
|
||||
}
|
||||
// https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/docs/config.yaml#L400
|
||||
// https://stash.wiki/proxy-protocols/proxy-types#vmess
|
||||
if (
|
||||
isPresent(proxy, 'cipher') &&
|
||||
![
|
||||
'auto',
|
||||
'aes-128-gcm',
|
||||
'chacha20-poly1305',
|
||||
'none',
|
||||
].includes(proxy.cipher)
|
||||
) {
|
||||
proxy.cipher = 'auto';
|
||||
}
|
||||
} else if (proxy.type === 'tuic') {
|
||||
if (isPresent(proxy, 'alpn')) {
|
||||
proxy.alpn = Array.isArray(proxy.alpn)
|
||||
? proxy.alpn
|
||||
: [proxy.alpn];
|
||||
} else {
|
||||
proxy.alpn = ['h3'];
|
||||
}
|
||||
// https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/adapter/outbound/tuic.go#L197
|
||||
if (
|
||||
(!proxy.token || proxy.token.length === 0) &&
|
||||
!isPresent(proxy, 'version')
|
||||
) {
|
||||
proxy.version = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
['vmess', 'vless'].includes(proxy.type) &&
|
||||
proxy.network === 'http'
|
||||
) {
|
||||
let httpPath = proxy['http-opts']?.path;
|
||||
if (
|
||||
isPresent(proxy, 'http-opts.path') &&
|
||||
!Array.isArray(httpPath)
|
||||
) {
|
||||
proxy['http-opts'].path = [httpPath];
|
||||
}
|
||||
let httpHost = proxy['http-opts']?.headers?.Host;
|
||||
if (
|
||||
isPresent(proxy, 'http-opts.headers.Host') &&
|
||||
!Array.isArray(httpHost)
|
||||
) {
|
||||
proxy['http-opts'].headers.Host = [httpHost];
|
||||
}
|
||||
}
|
||||
|
||||
delete proxy['tls-fingerprint'];
|
||||
return ' - ' + JSON.stringify(proxy) + '\n';
|
||||
})
|
||||
.join('')
|
||||
);
|
||||
};
|
||||
return { type, produce };
|
||||
}
|
@ -8,8 +8,20 @@ export default function Stash_Producer() {
|
||||
proxies
|
||||
.filter((proxy) => {
|
||||
if (
|
||||
proxy.type === 'snell' &&
|
||||
String(proxy.version) === '4'
|
||||
![
|
||||
'ss',
|
||||
'ssr',
|
||||
'vmess',
|
||||
'socks',
|
||||
'http',
|
||||
'snell',
|
||||
'trojan',
|
||||
'tuic',
|
||||
'vless',
|
||||
].includes(proxy.type) ||
|
||||
(proxy.type === 'snell' &&
|
||||
String(proxy.version) === '4') ||
|
||||
(proxy.type === 'vless' && proxy['reality-opts'])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -55,47 +55,65 @@ export default function URI_Producer() {
|
||||
break;
|
||||
case 'vmess':
|
||||
// V2RayN URI format
|
||||
let type = '';
|
||||
let net = proxy.network || 'tcp';
|
||||
if (proxy.network === 'http') {
|
||||
net = 'tcp';
|
||||
type = 'http';
|
||||
}
|
||||
result = {
|
||||
v: '2',
|
||||
ps: proxy.name,
|
||||
add: proxy.server,
|
||||
port: proxy.port,
|
||||
id: proxy.uuid,
|
||||
type: '',
|
||||
type,
|
||||
aid: 0,
|
||||
net: proxy.network || 'tcp',
|
||||
net,
|
||||
tls: proxy.tls ? 'tls' : '',
|
||||
};
|
||||
if (proxy.tls && proxy.sni) {
|
||||
result.sni = proxy.sni;
|
||||
}
|
||||
// obfs
|
||||
if (proxy.network === 'ws') {
|
||||
result.path = proxy['ws-opts'].path || '/';
|
||||
if (proxy['ws-opts'].headers.Host) {
|
||||
result.host = proxy['ws-opts'].headers.Host;
|
||||
if (proxy.network) {
|
||||
let vmessTransportPath =
|
||||
proxy[`${proxy.network}-opts`]?.path;
|
||||
let vmessTransportHost =
|
||||
proxy[`${proxy.network}-opts`]?.headers?.Host;
|
||||
if (vmessTransportPath) {
|
||||
result.path = Array.isArray(vmessTransportPath)
|
||||
? vmessTransportPath[0]
|
||||
: vmessTransportPath;
|
||||
}
|
||||
if (vmessTransportHost) {
|
||||
result.host = Array.isArray(vmessTransportHost)
|
||||
? vmessTransportHost[0]
|
||||
: vmessTransportHost;
|
||||
}
|
||||
}
|
||||
result = 'vmess://' + Base64.encode(JSON.stringify(result));
|
||||
break;
|
||||
case 'trojan':
|
||||
let transport = '';
|
||||
let trojanTransport = '';
|
||||
if (proxy.network) {
|
||||
transport = `&type=${proxy.network}`;
|
||||
let transportPath = proxy[`${proxy.network}-opts`]?.path;
|
||||
let transportHost =
|
||||
trojanTransport = `&type=${proxy.network}`;
|
||||
let trojanTransportPath =
|
||||
proxy[`${proxy.network}-opts`]?.path;
|
||||
let trojanTransportHost =
|
||||
proxy[`${proxy.network}-opts`]?.headers?.Host;
|
||||
if (transportPath) {
|
||||
transport += `&path=${encodeURIComponent(
|
||||
Array.isArray(transportPath)
|
||||
? transportPath[0]
|
||||
: transportPath,
|
||||
if (trojanTransportPath) {
|
||||
trojanTransport += `&path=${encodeURIComponent(
|
||||
Array.isArray(trojanTransportPath)
|
||||
? trojanTransportPath[0]
|
||||
: trojanTransportPath,
|
||||
)}`;
|
||||
}
|
||||
if (transportHost) {
|
||||
transport += `&host=${encodeURIComponent(
|
||||
Array.isArray(transportHost)
|
||||
? transportHost[0]
|
||||
: transportHost,
|
||||
if (trojanTransportHost) {
|
||||
trojanTransport += `&host=${encodeURIComponent(
|
||||
Array.isArray(trojanTransportHost)
|
||||
? trojanTransportHost[0]
|
||||
: trojanTransportHost,
|
||||
)}`;
|
||||
}
|
||||
}
|
||||
@ -103,7 +121,7 @@ export default function URI_Producer() {
|
||||
proxy.port
|
||||
}?sni=${encodeURIComponent(proxy.sni || proxy.server)}${
|
||||
proxy['skip-cert-verify'] ? '&allowInsecure=1' : ''
|
||||
}${transport}#${encodeURIComponent(proxy.name)}`;
|
||||
}${trojanTransport}#${encodeURIComponent(proxy.name)}`;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
@ -25,9 +25,6 @@ export default function register($app) {
|
||||
async function produceArtifact({ type, name, platform }) {
|
||||
platform = platform || 'JSON';
|
||||
|
||||
// produce Clash node format for ShadowRocket
|
||||
if (platform === 'ShadowRocket') platform = 'Clash';
|
||||
|
||||
if (type === 'subscription') {
|
||||
const allSubs = $.read(SUBS_KEY);
|
||||
const sub = findByName(allSubs, name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user