From 41d24b131a3f9d77d2b119dcfda8e1ab09eeba5d Mon Sep 17 00:00:00 2001 From: xream Date: Tue, 29 Aug 2023 01:46:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=B9=E6=8D=AE=20UA=20=E8=AF=86?= =?UTF-8?q?=E5=88=AB=20macOS=20=E7=89=88=20Surge(=E4=B9=9F=E5=8F=AF?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=8F=82=E6=95=B0=20=20target=3DSurgeMac)=20?= =?UTF-8?q?=E5=B9=B6=E6=94=AF=E6=8C=81=20SSR=20=E5=8D=8F=E8=AE=AE(?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=AD=97=E6=AE=B5=20exec=20=E4=B8=BA=20ssr-l?= =?UTF-8?q?ocal=20=E8=B7=AF=E5=BE=84,=20=E9=BB=98=E8=AE=A4=20/usr/local/bi?= =?UTF-8?q?n/ssr-local;=20=E7=AB=AF=E5=8F=A3=E4=BB=8E=2010000=20=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E9=80=92=E5=A2=9E,=20=E6=9A=82=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=85=8D=E7=BD=AE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 +- backend/src/core/proxy-utils/index.js | 13 +++- .../src/core/proxy-utils/producers/index.js | 2 + .../core/proxy-utils/producers/surgemac.js | 65 +++++++++++++++++++ backend/src/utils/platform.js | 2 + 5 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 backend/src/core/proxy-utils/producers/surgemac.js 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) {