Compare commits

..

1 Commits

Author SHA1 Message Date
xream
decdf31198 feat: 带参数 includeUnsupportedProxy 时, 支持输出 Surge WireGuard Section 2024-02-13 14:59:40 +08:00
16 changed files with 57 additions and 247 deletions

3
.gitmodules vendored
View File

@@ -0,0 +1,3 @@
[submodule "web"]
path = web
url = https://github.com/sub-store-org/Sub-Store-Front-End.git

View File

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

View File

@@ -6,9 +6,6 @@ import PROXY_PREPROCESSORS from './preprocessors';
import PROXY_PRODUCERS from './producers';
import PROXY_PARSERS from './parsers';
import $ from '@/core/app';
import { FILES_KEY, MODULES_KEY } from '@/constants';
import { findByName } from '@/utils/database';
import { produceArtifact } from '@/restful/sync';
function preprocess(raw) {
for (const processor of PROXY_PREPROCESSORS) {
@@ -98,50 +95,18 @@ async function processFn(proxies, operators = [], targetPlatform, source) {
}
}
}
url = `${url.split('#')[0]}${noCache ? '#noCache' : ''}`;
const downloadUrlMatch = url.match(
/^\/api\/(file|module)\/(.+)/,
);
if (downloadUrlMatch) {
let type = '';
try {
type = downloadUrlMatch?.[1];
let name = downloadUrlMatch?.[2];
if (name == null) {
throw new Error(`本地 ${type} URL 无效: ${url}`);
}
name = decodeURIComponent(name);
const key = type === 'module' ? MODULES_KEY : FILES_KEY;
const item = findByName($.read(key), name);
if (!item) {
throw new Error(`找不到 ${type}: ${name}`);
}
if (type === 'module') {
script = item.content;
} else {
script = await produceArtifact({
type: 'file',
name,
});
}
} catch (err) {
$.error(
`Error when loading ${type}: ${item.args.content}.\n Reason: ${err}`,
);
throw new Error(`无法加载 ${type}: ${url}`);
}
} else {
// if this is a remote script, download it
try {
script = await download(url);
// $.info(`Script loaded: >>>\n ${script}`);
} catch (err) {
$.error(
`Error when downloading remote script: ${item.args.content}.\n Reason: ${err}`,
);
throw new Error(`无法下载脚本: ${url}`);
}
// if this is a remote script, download it
try {
script = await download(
`${url.split('#')[0]}${noCache ? '#noCache' : ''}`,
);
// $.info(`Script loaded: >>>\n ${script}`);
} catch (err) {
$.error(
`Error when downloading remote script: ${item.args.content}.\n Reason: ${err}`,
);
throw new Error(`无法下载脚本: ${url}`);
}
} else {
script = content;

View File

@@ -406,7 +406,7 @@ function URI_VLESS() {
proxy.tls = true;
params.security = params.security ?? 'reality';
}
proxy.sni = params.sni || params.peer;
proxy.sni = params.sni ?? params.peer;
proxy.flow = params.flow;
if (!proxy.flow && isShadowrocket && params.xtls) {
// "none" is undefined

View File

@@ -121,7 +121,7 @@ function QuickSettingOperator(args) {
}
// add or remove flag for proxies
function FlagOperator({ mode, tw }) {
function FlagOperator({ mode }) {
return {
name: 'Flag Operator',
func: (proxies) => {
@@ -135,13 +135,7 @@ function FlagOperator({ mode, tw }) {
// remove old flag
proxy.name = removeFlag(proxy.name);
proxy.name = newFlag + ' ' + proxy.name;
if (tw == 'ws') {
proxy.name = proxy.name.replace(/🇹🇼/g, '🇼🇸');
} else if (tw == 'tw') {
// 不变
} else {
proxy.name = proxy.name.replace(/🇹🇼/g, '🇨🇳');
}
proxy.name = proxy.name.replace(/🇹🇼/g, '🇨🇳');
}
return proxy;
});

View File

@@ -14,6 +14,7 @@ const ipVersions = {
export default function Surge_Producer() {
const produce = (proxy, type, opts = {}) => {
console.log(opts);
switch (proxy.type) {
case 'ss':
return shadowsocks(proxy);

View File

@@ -1,14 +1,8 @@
import { version } from '../../package.json';
import {
SETTINGS_KEY,
ARTIFACTS_KEY,
SUBS_KEY,
COLLECTIONS_KEY,
} from '@/constants';
import { SETTINGS_KEY, ARTIFACTS_KEY } from '@/constants';
import $ from '@/core/app';
import { produceArtifact } from '@/restful/sync';
import { syncToGist } from '@/restful/artifacts';
import { findByName } from '@/utils/database';
!(async function () {
const settings = $.read(SETTINGS_KEY);
@@ -36,83 +30,23 @@ async function doSync() {
const files = {};
try {
const invalid = [];
const allSubs = $.read(SUBS_KEY);
const allCols = $.read(COLLECTIONS_KEY);
const subNames = [];
allArtifacts.map((artifact) => {
if (artifact.sync && artifact.source) {
if (artifact.type === 'subscription') {
const subName = artifact.source;
const sub = findByName(allSubs, subName);
if (sub && sub.url && !subNames.includes(subName)) {
subNames.push(subName);
}
} else if (artifact.type === 'collection') {
const collection = findByName(allCols, artifact.source);
if (collection && Array.isArray(collection.subscriptions)) {
collection.subscriptions.map((subName) => {
const sub = findByName(allSubs, subName);
if (sub && sub.url && !subNames.includes(subName)) {
subNames.push(subName);
}
});
}
}
}
});
if (subNames.length > 0) {
await Promise.all(
subNames.map(async (subName) => {
try {
await produceArtifact({
type: 'subscription',
name: subName,
});
} catch (e) {
// $.error(`${e.message ?? e}`);
}
}),
);
}
await Promise.all(
allArtifacts.map(async (artifact) => {
try {
if (artifact.sync && artifact.source) {
$.info(`正在同步云配置:${artifact.name}...`);
const output = await produceArtifact({
type: artifact.type,
name: artifact.source,
platform: artifact.platform,
produceOpts: {
'include-unsupported-proxy':
artifact.includeUnsupportedProxy,
},
});
if (artifact.sync) {
$.info(`正在同步云配置:${artifact.name}...`);
const output = await produceArtifact({
type: artifact.type,
name: artifact.source,
platform: artifact.platform,
});
// if (!output || output.length === 0)
// throw new Error('该配置的结果为空 不进行上传');
files[encodeURIComponent(artifact.name)] = {
content: output,
};
}
} catch (e) {
$.error(
`同步配置 ${artifact.name} 发生错误: ${e.message ?? e}`,
);
invalid.push(artifact.name);
files[encodeURIComponent(artifact.name)] = {
content: output,
};
}
}),
);
if (invalid.length > 0) {
throw new Error(
`同步配置 ${invalid.join(', ')} 发生错误 详情请查看日志`,
);
}
const resp = await syncToGist(files);
const body = JSON.parse(resp.body);
@@ -137,8 +71,8 @@ async function doSync() {
$.write(allArtifacts, ARTIFACTS_KEY);
$.notify('🌍 Sub-Store', '全部订阅同步成功!');
} catch (e) {
$.notify('🌍 Sub-Store', '同步订阅失败', `原因:${e.message ?? e}`);
$.error(`无法同步订阅配置到 Gist原因${e}`);
} catch (err) {
$.notify('🌍 Sub-Store', '同步订阅失败', `原因:${err}`);
$.error(`无法同步订阅配置到 Gist原因${err}`);
}
}

View File

@@ -448,46 +448,6 @@ async function syncArtifacts() {
try {
const invalid = [];
const allSubs = $.read(SUBS_KEY);
const allCols = $.read(COLLECTIONS_KEY);
const subNames = [];
allArtifacts.map((artifact) => {
if (artifact.sync && artifact.source) {
if (artifact.type === 'subscription') {
const subName = artifact.source;
const sub = findByName(allSubs, subName);
if (sub && sub.url && !subNames.includes(subName)) {
subNames.push(subName);
}
} else if (artifact.type === 'collection') {
const collection = findByName(allCols, artifact.source);
if (collection && Array.isArray(collection.subscriptions)) {
collection.subscriptions.map((subName) => {
const sub = findByName(allSubs, subName);
if (sub && sub.url && !subNames.includes(subName)) {
subNames.push(subName);
}
});
}
}
}
});
if (subNames.length > 0) {
await Promise.all(
subNames.map(async (subName) => {
try {
await produceArtifact({
type: 'subscription',
name: subName,
});
} catch (e) {
// $.error(`${e.message ?? e}`);
}
}),
);
}
await Promise.all(
allArtifacts.map(async (artifact) => {
try {

View File

@@ -1,4 +1,5 @@
import { SETTINGS_KEY } from '@/constants';
import { FILES_KEY, MODULES_KEY, SETTINGS_KEY } from '@/constants';
import { findByName } from '@/utils/database';
import { HTTP, ENV } from '@/vendor/open-api';
import { hex_md5 } from '@/vendor/md5';
import resourceCache from '@/utils/resource-cache';
@@ -35,22 +36,22 @@ export default async function download(rawUrl, ua, timeout) {
}
}
// const downloadUrlMatch = url.match(/^\/api\/(file|module)\/(.+)/);
// if (downloadUrlMatch) {
// let type = downloadUrlMatch?.[1];
// let name = downloadUrlMatch?.[2];
// if (name == null) {
// throw new Error(`本地 ${type} URL 无效: ${url}`);
// }
// name = decodeURIComponent(name);
// const key = type === 'module' ? MODULES_KEY : FILES_KEY;
// const item = findByName($.read(key), name);
// if (!item) {
// throw new Error(`找不到本地 ${type}: ${name}`);
// }
const downloadUrlMatch = url.match(/^\/api\/(file|module)\/(.+)/);
if (downloadUrlMatch) {
let type = downloadUrlMatch?.[1];
let name = downloadUrlMatch?.[2];
if (name == null) {
throw new Error(`本地 ${type} URL 无效: ${url}`);
}
name = decodeURIComponent(name);
const key = type === 'module' ? MODULES_KEY : FILES_KEY;
const item = findByName($.read(key), name);
if (!item) {
throw new Error(`找不到本地 ${type}: ${name}`);
}
// return item.content;
// }
return item.content;
}
const { isNode } = ENV();
const { defaultUserAgent, defaultTimeout } = $.read(SETTINGS_KEY);
@@ -73,7 +74,6 @@ export default async function download(rawUrl, ua, timeout) {
// try to find in app cache
const cached = resourceCache.get(id);
if (!$arguments?.noCache && cached) {
$.info(`使用缓存: ${url}`);
result = cached;
} else {
$.info(

View File

@@ -213,16 +213,11 @@ export function getFlag(name) {
'🇹🇼': [
'Taiwan',
'台湾',
'臺灣',
'台灣',
'中華民國',
'中华民国',
'台北',
'台中',
'新北',
'彰化',
'台',
'臺',
'Taipei',
],
'🇺🇦': ['Ukraine', '乌克兰', '烏克蘭'],
@@ -376,7 +371,7 @@ export function getFlag(name) {
'🇹🇭': ['TH', 'THA'],
'🇹🇳': ['TN', 'TUN'],
'🇹🇷': ['TR', 'TUR'],
'🇹🇼': ['TW', 'TWN', 'CHT', 'HINET', 'ROC'],
'🇹🇼': ['TW', 'TWN', 'CHT', 'HINET'],
'🇺🇦': ['UA', 'UKR'],
'🇺🇸': ['US', 'USA', 'LAX', 'SFO'],
'🇺🇾': ['UY', 'URY'],

View File

@@ -17,7 +17,7 @@ Telegram 频道: [`https://t.me/cool_scripts` ](https://t.me/cool_scripts)
1. 官方默认版模块(目前不带 ability 参数, 不保证以后不会改动): [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule)
2. 固定带 ability 参数版本,可能会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 请使用此带 ability 参数版本: [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule)
2. 固定带 ability 参数版本,可能会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 请使用此带 ability 参数版本: [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule)
3. 固定不带 ability 参数版本: [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-Noability.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-Noability.sgmodule)

View File

@@ -1,12 +1,12 @@
#!name=Sub-Store
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 0 点
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 0 点
#!category=订阅管理
[MITM]
hostname = %APPEND% sub.store
[Script]
# 主程序 已经去掉 Sub-Store Core 的参数 [,ability=http-client-policy] 不会爆内存,这个参数在 Surge 非常占用内存; 如果不需要使用指定节点功能 例如[加旗脚本或者cname脚本] 则可以使用此脚本
# 主程序 已经去掉 Sub-Store Core 的参数 [,ability=http-client-policy] 不会爆内存,这个参数在 Surge 非常占用内存; 如果不需要使用指定节点功能 例如[加旗脚本或者cname脚本] 则可以使用此脚本
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true

View File

@@ -1,5 +1,5 @@
#!name=Sub-Store
#!desc=高级订阅管理工具 @Peng-YM 带 ability 参数版本, 可能会爆内存, 如果不需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用不带 ability 参数版本. 定时任务默认为每天 0 点
#!desc=高级订阅管理工具 @Peng-YM 带 ability 参数版本, 可能会爆内存, 如果不需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用不带 ability 参数版本. 定时任务默认为每天 0 点
#!category=订阅管理
[MITM]

View File

@@ -1,5 +1,5 @@
#!name=Sub-Store
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 0 点
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 0 点
#!category=订阅管理
[MITM]

View File

@@ -35,49 +35,6 @@ function operator(proxies = [], targetPlatform, context) {
// yaml, // yaml 解析和生成
// }
// 1. Surge 输出 WireGuard 完整配置
// let proxies = await produceArtifact({
// type: 'subscription',
// name: 'sub',
// platform: 'Surge',
// produceOpts: {
// 'include-unsupported-proxy': true,
// }
// })
// $content = proxies
// 2. sing-box
// 但是一般不需要这样用, 可参考 1. https://t.me/zhetengsha/1111 和 2. https://t.me/zhetengsha/1070
// let singboxProxies = await produceArtifact({
// type: 'subscription', // type: 'subscription' 或 'collection'
// name: 'sub', // subscription name
// platform: 'sing-box', // target platform
// produceType: 'internal' // 'internal' produces an Array, otherwise produces a String( JSON.parse('JSON String') )
// })
// // JSON
// $content = JSON.stringify({}, null, 2)
// 3. clash.meta
// 但是一般不需要这样用, 可参考 1. https://t.me/zhetengsha/1111 和 2. https://t.me/zhetengsha/1070
// let clashMetaProxies = await produceArtifact({
// type: 'subscription',
// name: 'sub',
// platform: 'ClashMeta',
// produceType: 'internal' // 'internal' produces an Array, otherwise produces a String( ProxyUtils.yaml.safeLoad('YAML String').proxies )
// }))
// // YAML
// $content = ProxyUtils.yaml.safeDump({})
// { $content, $files } will be passed to the next operator
// $content is the final content of the file
// flowUtils 为机场订阅流量信息处理工具
// 可参考 https://t.me/zhetengsha/948
// https://github.com/sub-store-org/Sub-Store/blob/31b6dd0507a9286d6ab834ec94ad3050f6bdc86b/backend/src/utils/download.js#L104

1
web Submodule

Submodule web added at b10b708c34