From e259ed2e6eeb724e510abed6981ec4065b9af3f2 Mon Sep 17 00:00:00 2001 From: Peng-YM <1048217874pengym@gmail.com> Date: Sun, 6 Sep 2020 11:39:48 +0800 Subject: [PATCH] Supported URI Producer --- backend/sub-store.js | 80 ++++++++++++++++++++++++++++++++++++----- web/public/favicon.ico | Bin 7475 -> 4858 bytes web/public/index.html | 6 ++-- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/backend/sub-store.js b/backend/sub-store.js index 79efa2c..344d335 100644 --- a/backend/sub-store.js +++ b/backend/sub-store.js @@ -137,7 +137,7 @@ async function parseSub(sub, platform) { let raw; const key = new Base64Code().safeEncode(sub.url); - if (platform === "Raw") { + if (platform === "Raw" || platform === 'URI') { const cache = $.read(`#${key}`); if (!cache) { raw = await $.http @@ -273,6 +273,7 @@ async function parseSub(sub, platform) { Loon_Producer, Surge_Producer, Raw_Producer, + URI_Producer ]); return $parser.produce(proxies); } @@ -598,13 +599,9 @@ function ProxyParser(targetPlatform) { } // skip unsupported proxies // if proxy.supported is undefined, assume that all platforms are supported. - if ( - typeof proxy.supported === "undefined" || - proxy.supported[targetPlatform] - ) { - result.push(proxy); - break; - } + if (proxy.supported && proxy.supported[targetPlatform] === false) continue; + result.push(proxy); + break; } catch (err) { console.log( `ERROR: Failed to parse line: \n ${line}\n Reason: ${err}` @@ -635,6 +632,7 @@ function ProxyParser(targetPlatform) { return ""; } }) + .filter(v => v.length > 0) // discard empty lines .join("\n"); } } @@ -805,6 +803,7 @@ function URI_SS() { mode: "websocket", host: params["obfs-host"], path: params.path || "", + tls: params.tls }; break; default: @@ -880,6 +879,8 @@ function URI_SSR() { // V2rayN URI VMess format // reference: https://github.com/2dust/v2rayN/wiki/%E5%88%86%E4%BA%AB%E9%93%BE%E6%8E%A5%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E(ver-2) + +// Quantumult VMess format function URI_VMess() { const patternTest = (line) => { return /^vmess:\/\//.test(line); @@ -978,9 +979,10 @@ function URI_Trojan() { } line = line.split("trojan://")[1]; const server = line.split("@")[1].split(":443")[0]; + const name = line.split("#")[1].trim(); return { - name: `[Trojan] ${server}`, // trojan uri has no server tag! + name: name || `[Trojan] ${server}`, // trojan uri may have no server tag! type: "trojan", server, port: 443, @@ -1722,6 +1724,66 @@ function Raw_Producer() { return {targetPlatform, output}; } +function URI_Producer() { + const targetPlatform = "URI"; + const Base64 = new Base64Code(); + const output = (proxy) => { + let result = ""; + switch (proxy.type) { + case "ss": + const userinfo = `${proxy.cipher}:${proxy.password}`; + result = `ss://${Base64.safeEncode(userinfo)}@${proxy.server}:${proxy.port}/`; + if (proxy.plugin) { + result += "?plugin="; + const opts = proxy['plugin-opts']; + switch (proxy.plugin) { + case "obfs": + result += encodeURIComponent(`simple-obfs;obfs=${opts.mode}${opts.host ? ";obfs-host=" + opts.host : ""}`); + break + case "v2ray-plugin": + result += encodeURIComponent(`v2ray-plugin;obfs=${opts.mode}${opts.host ? ";obfs-host" + opts.host : ""}${opts.tls ? ";tls" : ""}`); + break + default: + throw new Error(`Unsupported plugin option: ${proxy.plugin}`); + } + } + result += `#${encodeURIComponent(proxy.name)}`; + break + case "ssr": + result = `${proxy.server}:${proxy.port}:${proxy.protocol}:${proxy.cipher}:${proxy.obfs}:${Base64.safeEncode(proxy.password)}/`; + result += `?remarks=${proxy.name}${proxy['obfs-param'] ? "&obfsparam=" + Base64.safeEncode(proxy['obfs-param']) : ""}${proxy['protocol-param'] ? "&protocolparam=" + Base64.safeEncode(proxy['protocol-param']) : ""}`; + result = "vmess://" + Base64.safeEncode(result); + break + case "vmess": + // V2RayN URI format + result = { + ps: proxy.name, + add: proxy.server, + port: proxy.port, + id: proxy.uuid, + type: "", + aid: 0, + net: proxy.network || "tcp", + tls: proxy.tls ? "tls" : "" + } + // obfs + if (proxy.network === 'ws') { + result.path = proxy['ws-path'] || "/"; + result.host = proxy['ws-headers'].Host || proxy.server; + } + result = Base64.safeEncode(JSON.stringify(result)); + break + case "trojan": + result = `trojan://${proxy.password}@${proxy.server}:${proxy.port}#${proxy.name}`; + break + default: + throw new Error(`Cannot handle proxy type: ${proxy.type}`); + } + return result; + }; + return {targetPlatform, output}; +} + /**************************** Operators ***************************************/ // force to set some properties (e.g., scert, udp, tfo, etc.) function SetPropertyOperator({key, value}) { diff --git a/web/public/favicon.ico b/web/public/favicon.ico index a0a1ee2b8762f2d399c6bef886393882706e7ce7..7fe6f585feccb65026d09e186cb8059c1e335d96 100644 GIT binary patch delta 4210 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 G#s3Fp6c0K8 delta 6844 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 diff --git a/web/public/index.html b/web/public/index.html index 5eac9eb..7e83902 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -9,9 +9,9 @@ - - - + + + Sub-Store