diff --git a/backend/package.json b/backend/package.json index ea93a2e..b0af73a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.42", + "version": "2.14.43", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/index.js b/backend/src/core/proxy-utils/index.js index cb66f55..e27367b 100644 --- a/backend/src/core/proxy-utils/index.js +++ b/backend/src/core/proxy-utils/index.js @@ -136,10 +136,21 @@ function produce(proxies, targetPlatform) { $.info(`Producing proxies for target: ${targetPlatform}`); if (typeof producer.type === 'undefined' || producer.type === 'SINGLE') { + let localPort = 10000; return proxies .map((proxy) => { try { - return producer.produce(proxy); + let line = producer.produce(proxy); + if ( + line.length > 0 && + line.includes('__SubStoreLocalPort__') + ) { + line = line.replace( + /__SubStoreLocalPort__/g, + localPort++, + ); + } + return line; } catch (err) { $.error( `Cannot produce proxy: ${JSON.stringify( diff --git a/backend/src/core/proxy-utils/producers/index.js b/backend/src/core/proxy-utils/producers/index.js index ba703ab..449a0f2 100644 --- a/backend/src/core/proxy-utils/producers/index.js +++ b/backend/src/core/proxy-utils/producers/index.js @@ -1,4 +1,5 @@ import Surge_Producer from './surge'; +import SurgeMac_Producer from './surgemac'; import Clash_Producer from './clash'; import ClashMeta_Producer from './clashmeta'; import Stash_Producer from './stash'; @@ -17,6 +18,7 @@ function JSON_Producer() { export default { QX: QX_Producer(), Surge: Surge_Producer(), + SurgeMac: SurgeMac_Producer(), Loon: Loon_Producer(), Clash: Clash_Producer(), ClashMeta: ClashMeta_Producer(), diff --git a/backend/src/core/proxy-utils/producers/surgemac.js b/backend/src/core/proxy-utils/producers/surgemac.js new file mode 100644 index 0000000..c3e3cda --- /dev/null +++ b/backend/src/core/proxy-utils/producers/surgemac.js @@ -0,0 +1,65 @@ +import { Result } from './utils'; +import Surge_Producer from './surge'; + +const targetPlatform = 'SurgeMac'; + +const surge_Producer = Surge_Producer(); + +export default function SurgeMac_Producer() { + const produce = (proxy) => { + switch (proxy.type) { + case 'ssr': + return shadowsocksr(proxy); + case 'ss': + return surge_Producer.produce(proxy); + case 'trojan': + return surge_Producer.produce(proxy); + case 'vmess': + return surge_Producer.produce(proxy); + case 'http': + return surge_Producer.produce(proxy); + case 'socks5': + return surge_Producer.produce(proxy); + case 'snell': + return surge_Producer.produce(proxy); + case 'tuic': + return surge_Producer.produce(proxy); + } + throw new Error( + `Platform ${targetPlatform} does not support proxy type: ${proxy.type}`, + ); + }; + return { produce }; +} + +function shadowsocksr(proxy) { + const result = new Result(proxy); + + proxy.local_port = '__SubStoreLocalPort__'; + proxy.local_address = proxy.local_address ?? '127.0.0.1'; + + result.append( + `${proxy.name} = external, exec = "${ + proxy.exec || '/usr/local/bin/ssr-local' + }", address = "${proxy.server}", local-port = ${proxy.local_port}`, + ); + + for (const [key, value] of Object.entries({ + cipher: '-m', + obfs: '-o', + password: '-k', + port: '-p', + protocol: '-O', + 'protocol-param': '-G', + server: '-s', + local_port: '-l', + local_address: '-b', + })) { + result.appendIfPresent( + `, args = "${value}", args = "${proxy[key]}"`, + key, + ); + } + + return result.toString(); +} diff --git a/backend/src/utils/platform.js b/backend/src/utils/platform.js index ee51683..70eae4a 100644 --- a/backend/src/utils/platform.js +++ b/backend/src/utils/platform.js @@ -11,6 +11,8 @@ export function getPlatformFromHeaders(headers) { } if (UA.indexOf('Quantumult%20X') !== -1) { return 'QX'; + } else if (UA.indexOf('Surge Mac') !== -1) { + return 'SurgeMac'; } else if (UA.indexOf('Surge') !== -1) { return 'Surge'; } else if (UA.indexOf('Decar') !== -1 || UA.indexOf('Loon') !== -1) {