Compare commits

..

5 Commits

Author SHA1 Message Date
xream
630bac0575 fix: 简单修复 SS URI 多参数拼接 2024-05-05 02:14:55 +08:00
xream
7f3cb2b191 feat: 当无插件参数时, 去除 SS URI 输出中的 / 以兼容部分客户端 2024-05-05 02:11:50 +08:00
xream
92e1e4a0fb feat: ProxyUtils 中增加 Gist 类; 补充 demo.js 中的示例 2024-05-04 21:35:27 +08:00
xream
3b85d313fe fix: 兼容不规范的 QX URI 2024-05-03 03:56:59 +08:00
xream
c91d8e28e4 fix: 哪吒探针在线时长 2024-04-30 15:39:14 +08:00
7 changed files with 61 additions and 10 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.14.301",
"version": "2.14.307",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

View File

@@ -16,6 +16,7 @@ import { FILES_KEY, MODULES_KEY } from '@/constants';
import { findByName } from '@/utils/database';
import { produceArtifact } from '@/restful/sync';
import { getFlag, getISO } from '@/utils/geo';
import Gist from '@/utils/gist';
function preprocess(raw) {
for (const processor of PROXY_PREPROCESSORS) {
@@ -272,6 +273,7 @@ export const ProxyUtils = {
yaml: YAML,
getFlag,
getISO,
Gist,
};
function tryParse(parser, line) {

View File

@@ -50,8 +50,11 @@ trojan = "trojan" equals address
shadowsocks = "shadowsocks" equals address
(password/method/obfs_ssr/obfs_ss/obfs_host/obfs_uri/ssr_protocol/ssr_protocol_param/tls_pubkey_sha256/tls_alpn/tls_no_session_ticket/tls_no_session_reuse/tls_fingerprint/tls_verification/udp_relay/udp_over_tcp/fast_open/tag/server_check_url/others)* {
if (proxy.protocol) {
if (proxy.protocol || proxy.type === "ssr") {
proxy.type = "ssr";
if (!proxy.protocol) {
proxy.protocol = "origin";
}
// handle ssr obfs
if (obfs.host) proxy["obfs-param"] = obfs.host;
if (obfs.type) proxy.obfs = obfs.type;
@@ -172,7 +175,7 @@ tls_no_session_reuse = comma "tls-no-session-reuse" equals flag:bool {
}
obfs_ss = comma "obfs" equals type:("http"/"tls"/"wss"/"ws"/"over-tls") { obfs.type = type; return type; }
obfs_ssr = comma "obfs" equals type:("plain"/"http_simple"/"http_post"/"random_head"/"tls1.2_ticket_auth"/"tls1.2_ticket_fastauth") { obfs.type = type; return type; }
obfs_ssr = comma "obfs" equals type:("plain"/"http_simple"/"http_post"/"random_head"/"tls1.2_ticket_auth"/"tls1.2_ticket_fastauth") { proxy.type = "ssr"; obfs.type = type; return type; }
obfs = comma "obfs" equals type:("wss"/"ws"/"over-tls"/"http") { obfs.type = type; return type; };
obfs_host = comma "obfs-host" equals host:domain { obfs.host = host; }

View File

@@ -48,8 +48,11 @@ trojan = "trojan" equals address
shadowsocks = "shadowsocks" equals address
(password/method/obfs_ssr/obfs_ss/obfs_host/obfs_uri/ssr_protocol/ssr_protocol_param/tls_pubkey_sha256/tls_alpn/tls_no_session_ticket/tls_no_session_reuse/tls_fingerprint/tls_verification/udp_relay/udp_over_tcp/fast_open/tag/server_check_url/others)* {
if (proxy.protocol) {
if (proxy.protocol || proxy.type === "ssr") {
proxy.type = "ssr";
if (!proxy.protocol) {
proxy.protocol = "origin";
}
// handle ssr obfs
if (obfs.host) proxy["obfs-param"] = obfs.host;
if (obfs.type) proxy.obfs = obfs.type;
@@ -170,7 +173,7 @@ tls_no_session_reuse = comma "tls-no-session-reuse" equals flag:bool {
}
obfs_ss = comma "obfs" equals type:("http"/"tls"/"wss"/"ws"/"over-tls") { obfs.type = type; return type; }
obfs_ssr = comma "obfs" equals type:("plain"/"http_simple"/"http_post"/"random_head"/"tls1.2_ticket_auth"/"tls1.2_ticket_fastauth") { obfs.type = type; return type; }
obfs_ssr = comma "obfs" equals type:("plain"/"http_simple"/"http_post"/"random_head"/"tls1.2_ticket_auth"/"tls1.2_ticket_fastauth") { proxy.type = "ssr"; obfs.type = type; return type; }
obfs = comma "obfs" equals type:("wss"/"ws"/"over-tls"/"http") { obfs.type = type; return type; };
obfs_host = comma "obfs-host" equals host:domain { obfs.host = host; }

View File

@@ -26,7 +26,7 @@ export default function URI_Producer() {
const userinfo = `${proxy.cipher}:${proxy.password}`;
result = `ss://${Base64.encode(userinfo)}@${proxy.server}:${
proxy.port
}/`;
}${proxy.plugin ? '/' : ''}`;
if (proxy.plugin) {
result += '?plugin=';
const opts = proxy['plugin-opts'];
@@ -55,7 +55,9 @@ export default function URI_Producer() {
result = `${result}${proxy.plugin ? '&' : '?'}uot=1`;
}
if (proxy.tfo) {
result = `${result}${proxy.plugin ? '&' : '?'}tfo=1`;
result = `${result}${
proxy.plugin || proxy['udp-over-tcp'] ? '&' : '?'
}tfo=1`;
}
result += `#${encodeURIComponent(proxy.name)}`;
break;

View File

@@ -469,7 +469,11 @@ function nezhaTransform(output) {
// 简单判断下
if (/^[a-z]{2}$/i.test(CountryCode)) {
// 如果节点上有数据 就取节点上的数据
let time = proxy._unavailable ? 0 : Date.now();
let now = Math.round(new Date().getTime() / 1000);
let time = proxy._unavailable ? 0 : now;
const uptime = parseInt(proxy._uptime || 0, 10);
result.result.push({
id: index,
name: proxy.name,
@@ -489,7 +493,7 @@ function nezhaTransform(output) {
SwapTotal: 1024,
Arch: '',
Virtualization: '',
BootTime: time,
BootTime: now - uptime,
CountryCode, // 目前需要
Version: '0.0.1',
},
@@ -502,7 +506,7 @@ function nezhaTransform(output) {
NetOutTransfer: 0,
NetInSpeed: 0,
NetOutSpeed: 0,
Uptime: parseInt(proxy._uptime ?? index, 10),
Uptime: uptime,
Load1: 0,
Load5: 0,
Load15: 0,

View File

@@ -39,6 +39,7 @@ function operator(proxies = [], targetPlatform, context) {
// yaml, // yaml 解析和生成
// getFlag, // 获取 emoji 旗帜
// getISO, // 获取 ISO 3166-1 alpha-2 代码
// Gist, // Gist 类
// }
// 示例: 给节点名添加前缀
@@ -94,6 +95,42 @@ function operator(proxies = [], targetPlatform, context) {
// produceType: 'internal' // 'internal' produces an Array, otherwise produces a String( ProxyUtils.yaml.safeLoad('YAML String').proxies )
// })
// 4. 一个比较折腾的方案: 在脚本操作中, 把内容同步到另一个 gist
// async function operator(proxies = []) {
// const $ = $substore
// const GITHUB_TOKEN = 'ghp_xxxxxxxxxxxxxxxxxxxxx'
// const GIST_NAME = 'share'
// const FILENAME = 'mihomo.yaml'
// let files = {}
// let content = await produceArtifact({
// type: 'subscription',
// subscription: {},
// content: 'proxies:\n' + proxies.map((proxy) => ' - ' + JSON.stringify(proxy) + '\n').join(''),
// platform: 'ClashMeta',
// })
// const manager = new ProxyUtils.Gist({
// token: GITHUB_TOKEN,
// key: GIST_NAME,
// });
// files[encodeURIComponent(FILENAME)] = {
// content,
// };
// const res = await manager.upload(files);
// let body = {};
// try {
// body = JSON.parse(res.body);
// // eslint-disable-next-line no-empty
// } catch (e) {}
// const raw_url =
// body.files[encodeURIComponent(FILENAME)]?.raw_url;
// console.log(raw_url)
// const new_url = raw_url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
// console.log(new_url)
// $.notify('🌍 Sub-Store', `更新到 Gist: ${new_url}`);
// return proxies
// }
// // YAML
// ProxyUtils.yaml.load('YAML String')
// ProxyUtils.yaml.safeLoad('YAML String')