mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-10 14:09:01 +08:00
feat: 支持更多不规范的 SS URI; 去除 Surfboard 节点名中的等号; 支持 Mihomo shadowsocks shadow-tls
This commit is contained in:
parent
64117c50c7
commit
8a2087c53a
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.14.190",
|
"version": "2.14.191",
|
||||||
"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": {
|
||||||
|
@ -237,6 +237,7 @@ function lastParse(proxy) {
|
|||||||
delete proxy['ws-path'];
|
delete proxy['ws-path'];
|
||||||
delete proxy['ws-headers'];
|
delete proxy['ws-headers'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy.type === 'trojan') {
|
if (proxy.type === 'trojan') {
|
||||||
if (proxy.network === 'tcp') {
|
if (proxy.network === 'tcp') {
|
||||||
delete proxy.network;
|
delete proxy.network;
|
||||||
@ -253,11 +254,22 @@ function lastParse(proxy) {
|
|||||||
if (proxy.network) {
|
if (proxy.network) {
|
||||||
let transportHost = proxy[`${proxy.network}-opts`]?.headers?.Host;
|
let transportHost = proxy[`${proxy.network}-opts`]?.headers?.Host;
|
||||||
let transporthost = proxy[`${proxy.network}-opts`]?.headers?.host;
|
let transporthost = proxy[`${proxy.network}-opts`]?.headers?.host;
|
||||||
if (transporthost && !transportHost) {
|
if (proxy.network === 'h2') {
|
||||||
|
if (!transporthost && transportHost) {
|
||||||
|
proxy[`${proxy.network}-opts`].headers.host = transportHost;
|
||||||
|
delete proxy[`${proxy.network}-opts`].headers.Host;
|
||||||
|
}
|
||||||
|
} else if (transporthost && !transportHost) {
|
||||||
proxy[`${proxy.network}-opts`].headers.Host = transporthost;
|
proxy[`${proxy.network}-opts`].headers.Host = transporthost;
|
||||||
delete proxy[`${proxy.network}-opts`].headers.host;
|
delete proxy[`${proxy.network}-opts`].headers.host;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (proxy.network === 'h2') {
|
||||||
|
const host = proxy['h2-opts']?.headers?.host;
|
||||||
|
if (host && !Array.isArray(host)) {
|
||||||
|
proxy['h2-opts'].headers.host = [host];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (proxy.tls && !proxy.sni) {
|
if (proxy.tls && !proxy.sni) {
|
||||||
if (proxy.network) {
|
if (proxy.network) {
|
||||||
let transportHost = proxy[`${proxy.network}-opts`]?.headers?.Host;
|
let transportHost = proxy[`${proxy.network}-opts`]?.headers?.Host;
|
||||||
|
@ -34,14 +34,24 @@ function URI_SS() {
|
|||||||
let userInfoStr = Base64.decode(content.split('@')[0]);
|
let userInfoStr = Base64.decode(content.split('@')[0]);
|
||||||
let query = '';
|
let query = '';
|
||||||
if (!serverAndPortArray) {
|
if (!serverAndPortArray) {
|
||||||
// 暂时先这样处理 目前够用
|
if (content.includes('?')) {
|
||||||
if (content.includes('?plugin=')) {
|
const parsed = content.match(/^(.*)(\?.*)$/);
|
||||||
const parsed = content.match(/^(.*)(\?plugin=.*)$/);
|
|
||||||
content = parsed[1];
|
content = parsed[1];
|
||||||
query = parsed[2];
|
query = parsed[2];
|
||||||
}
|
}
|
||||||
content = Base64.decode(content);
|
content = Base64.decode(content);
|
||||||
if (query) {
|
if (query) {
|
||||||
|
console.log(query);
|
||||||
|
if (/(&|\?)v2ray-plugin=/.test(query)) {
|
||||||
|
const parsed = query.match(/(&|\?)v2ray-plugin=(.*?)(&|$)/);
|
||||||
|
let v2rayPlugin = parsed[2];
|
||||||
|
if (v2rayPlugin) {
|
||||||
|
proxy.obfs = 'v2ray-plugin';
|
||||||
|
proxy['plugin-opts'] = JSON.parse(
|
||||||
|
Base64.decode(v2rayPlugin),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
content = `${content}${query}`;
|
content = `${content}${query}`;
|
||||||
}
|
}
|
||||||
userInfoStr = content.split('@')[0];
|
userInfoStr = content.split('@')[0];
|
||||||
@ -57,6 +67,7 @@ function URI_SS() {
|
|||||||
const userInfo = userInfoStr.split(':');
|
const userInfo = userInfoStr.split(':');
|
||||||
proxy.cipher = userInfo[0];
|
proxy.cipher = userInfo[0];
|
||||||
proxy.password = userInfo[1];
|
proxy.password = userInfo[1];
|
||||||
|
|
||||||
// handle obfs
|
// handle obfs
|
||||||
const idx = content.indexOf('?plugin=');
|
const idx = content.indexOf('?plugin=');
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
@ -96,6 +107,9 @@ function URI_SS() {
|
|||||||
if (/(&|\?)uot=(1|true)/i.test(query)) {
|
if (/(&|\?)uot=(1|true)/i.test(query)) {
|
||||||
proxy['udp-over-tcp'] = true;
|
proxy['udp-over-tcp'] = true;
|
||||||
}
|
}
|
||||||
|
if (/(&|\?)tfo=(1|true)/i.test(query)) {
|
||||||
|
proxy.tfo = true;
|
||||||
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return { name, test, parse };
|
return { name, test, parse };
|
||||||
@ -449,7 +463,7 @@ function URI_VLESS() {
|
|||||||
if (params.serviceName) {
|
if (params.serviceName) {
|
||||||
opts[`${proxy.network}-service-name`] = params.serviceName;
|
opts[`${proxy.network}-service-name`] = params.serviceName;
|
||||||
} else if (isShadowrocket && params.path) {
|
} else if (isShadowrocket && params.path) {
|
||||||
if (!['ws', 'http'].includes(proxy.network)) {
|
if (!['ws', 'http', 'h2'].includes(proxy.network)) {
|
||||||
opts[`${proxy.network}-service-name`] = params.path;
|
opts[`${proxy.network}-service-name`] = params.path;
|
||||||
delete params.path;
|
delete params.path;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,25 @@ export default function Clash_Producer() {
|
|||||||
proxy['http-opts'].headers.Host = [httpHost];
|
proxy['http-opts'].headers.Host = [httpHost];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
['vmess', 'vless'].includes(proxy.type) &&
|
||||||
|
proxy.network === 'h2'
|
||||||
|
) {
|
||||||
|
let path = proxy['h2-opts']?.path;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.path') &&
|
||||||
|
Array.isArray(path)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].path = path[0];
|
||||||
|
}
|
||||||
|
let host = proxy['h2-opts']?.headers?.host;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.headers.Host') &&
|
||||||
|
!Array.isArray(host)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].headers.host = [host];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
||||||
proxy.type,
|
proxy.type,
|
||||||
|
@ -110,7 +110,25 @@ export default function ClashMeta_Producer() {
|
|||||||
proxy['http-opts'].headers.Host = [httpHost];
|
proxy['http-opts'].headers.Host = [httpHost];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
['vmess', 'vless'].includes(proxy.type) &&
|
||||||
|
proxy.network === 'h2'
|
||||||
|
) {
|
||||||
|
let path = proxy['h2-opts']?.path;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.path') &&
|
||||||
|
Array.isArray(path)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].path = path[0];
|
||||||
|
}
|
||||||
|
let host = proxy['h2-opts']?.headers?.host;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.headers.Host') &&
|
||||||
|
!Array.isArray(host)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].headers.host = [host];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
||||||
proxy.type,
|
proxy.type,
|
||||||
|
@ -126,6 +126,25 @@ export default function ShadowRocket_Producer() {
|
|||||||
proxy['http-opts'].headers.Host = [httpHost];
|
proxy['http-opts'].headers.Host = [httpHost];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
['vmess', 'vless'].includes(proxy.type) &&
|
||||||
|
proxy.network === 'h2'
|
||||||
|
) {
|
||||||
|
let path = proxy['h2-opts']?.path;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.path') &&
|
||||||
|
Array.isArray(path)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].path = path[0];
|
||||||
|
}
|
||||||
|
let host = proxy['h2-opts']?.headers?.host;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.headers.Host') &&
|
||||||
|
!Array.isArray(host)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].headers.host = [host];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
||||||
|
@ -206,6 +206,25 @@ export default function Stash_Producer() {
|
|||||||
proxy['http-opts'].headers.Host = [httpHost];
|
proxy['http-opts'].headers.Host = [httpHost];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
['vmess', 'vless'].includes(proxy.type) &&
|
||||||
|
proxy.network === 'h2'
|
||||||
|
) {
|
||||||
|
let path = proxy['h2-opts']?.path;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.path') &&
|
||||||
|
Array.isArray(path)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].path = path[0];
|
||||||
|
}
|
||||||
|
let host = proxy['h2-opts']?.headers?.host;
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'h2-opts.headers.Host') &&
|
||||||
|
!Array.isArray(host)
|
||||||
|
) {
|
||||||
|
proxy['h2-opts'].headers.host = [host];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
['trojan', 'tuic', 'hysteria', 'hysteria2'].includes(
|
||||||
proxy.type,
|
proxy.type,
|
||||||
|
@ -6,6 +6,7 @@ const targetPlatform = 'Surfboard';
|
|||||||
|
|
||||||
export default function Surfboard_Producer() {
|
export default function Surfboard_Producer() {
|
||||||
const produce = (proxy) => {
|
const produce = (proxy) => {
|
||||||
|
proxy.name = proxy.name.replace(/=/g, '');
|
||||||
switch (proxy.type) {
|
switch (proxy.type) {
|
||||||
case 'ss':
|
case 'ss':
|
||||||
return shadowsocks(proxy);
|
return shadowsocks(proxy);
|
||||||
|
@ -69,7 +69,7 @@ function shadowsocks(proxy) {
|
|||||||
`,obfs-uri=${proxy['plugin-opts'].path}`,
|
`,obfs-uri=${proxy['plugin-opts'].path}`,
|
||||||
'plugin-opts.path',
|
'plugin-opts.path',
|
||||||
);
|
);
|
||||||
} else {
|
} else if (!['shadow-tls'].includes(proxy.plugin)) {
|
||||||
throw new Error(`plugin ${proxy.plugin} is not supported`);
|
throw new Error(`plugin ${proxy.plugin} is not supported`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,6 +95,24 @@ function shadowsocks(proxy) {
|
|||||||
`,shadow-tls-sni=${proxy['shadow-tls-sni']}`,
|
`,shadow-tls-sni=${proxy['shadow-tls-sni']}`,
|
||||||
'shadow-tls-sni',
|
'shadow-tls-sni',
|
||||||
);
|
);
|
||||||
|
} else if (['shadow-tls'].includes(proxy.plugin) && proxy['plugin-opts']) {
|
||||||
|
const password = proxy['plugin-opts'].password;
|
||||||
|
const host = proxy['plugin-opts'].host;
|
||||||
|
const version = proxy['plugin-opts'].version;
|
||||||
|
if (password) {
|
||||||
|
result.append(`,shadow-tls-password=${password}`);
|
||||||
|
if (host) {
|
||||||
|
result.append(`,shadow-tls-sni=${host}`);
|
||||||
|
}
|
||||||
|
if (version) {
|
||||||
|
if (version < 2) {
|
||||||
|
throw new Error(
|
||||||
|
`shadow-tls version ${version} is not supported`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
result.append(`,shadow-tls-version=${version}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// block-quic
|
// block-quic
|
||||||
|
@ -42,6 +42,9 @@ export default function URI_Producer() {
|
|||||||
if (proxy['udp-over-tcp']) {
|
if (proxy['udp-over-tcp']) {
|
||||||
result = `${result}${proxy.plugin ? '&' : '?'}uot=1`;
|
result = `${result}${proxy.plugin ? '&' : '?'}uot=1`;
|
||||||
}
|
}
|
||||||
|
if (proxy.tfo) {
|
||||||
|
result = `${result}${proxy.plugin ? '&' : '?'}tfo=1`;
|
||||||
|
}
|
||||||
result += `#${encodeURIComponent(proxy.name)}`;
|
result += `#${encodeURIComponent(proxy.name)}`;
|
||||||
break;
|
break;
|
||||||
case 'ssr':
|
case 'ssr':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user