Compare commits

..

15 Commits

Author SHA1 Message Date
xream
0d41eb467f feat: 某些域名仅支持从国内 DNS 解析正确结果, 为方便部署在海外的用户, 使用国内 DNS 解析时, ECS IP 指定为国内 IP 2024-05-18 22:24:58 +08:00
xream
ba1c91a7a5 chore: 文案 2024-05-17 17:49:10 +08:00
xream
30fa87c172 doc: Shadowrocket 模块 2024-05-15 20:58:55 +08:00
xream
1eaa33948b chore: bump release version 2024-05-14 20:45:39 +08:00
xream
619e256ed8 Merge pull request #322 from onejibang/master
chore: Change network request method
2024-05-14 20:45:00 +08:00
onejibang
b46209e164 chore: Change network request method 2024-05-14 16:51:05 +08:00
xream
a1ba4e273e chore: bump release version 2024-05-13 19:44:27 +08:00
xream
bfc95ed92a Merge pull request #320 from onejibang/feature-gui-for-cores
feat: 适配GUI.for.Cores项目组下的客户端程序
2024-05-13 19:41:45 +08:00
xream
32f591ec56 Merge branch 'master' into feature-gui-for-cores 2024-05-13 19:41:28 +08:00
onejibang
cea16d8c44 chore: Canonical variable name 2024-05-13 19:22:33 +08:00
onejibang
93a1ba7b50 feat: support HEAD method 2024-05-13 19:12:22 +08:00
xream
e6d1aa1150 feat: 使用了自定义缓存 cacheKey 的远程订阅 调整为乐观缓存 2024-05-13 17:08:17 +08:00
onejibang
26e83798da feat: Provide virtual disk operation API 2024-05-13 16:35:05 +08:00
xream
b083d2d840 feat: Node.js 版支持 MMDB, 通过环境变量或在脚本中传入数据库文件路径, 可使用 ipaso 和 geoip 方法 2024-05-12 23:17:11 +08:00
onejibang
cf35afcab2 Adapted for GUI.for.Cores 2024-05-11 17:32:01 +08:00
17 changed files with 182 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.14.308",
"version": "2.14.313",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {
@@ -17,6 +17,7 @@
"author": "Peng-YM",
"license": "GPL-3.0",
"dependencies": {
"@maxmind/geoip2-node": "^5.0.0",
"automerge": "1.0.1-preview.7",
"body-parser": "^1.19.0",
"connect-history-api-fallback": "^2.0.0",

63
backend/pnpm-lock.yaml generated
View File

@@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false
dependencies:
'@maxmind/geoip2-node':
specifier: ^5.0.0
version: registry.npmmirror.com/@maxmind/geoip2-node@5.0.0
automerge:
specifier: 1.0.1-preview.7
version: registry.npmmirror.com/automerge@1.0.1-preview.7
@@ -1967,6 +1970,15 @@ packages:
'@jridgewell/sourcemap-codec': registry.npmmirror.com/@jridgewell/sourcemap-codec@1.4.13
dev: true
registry.npmmirror.com/@maxmind/geoip2-node@5.0.0:
resolution: {integrity: sha512-ki+q5//oU4tZ3BAhegZJcB5czoZyic5JSTEKbrUAQB/BzAoAiGyLW0immEmQvVVyy2SMlvBTJ3zqyRj8K9BbwQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@maxmind/geoip2-node/-/geoip2-node-5.0.0.tgz}
name: '@maxmind/geoip2-node'
version: 5.0.0
dependencies:
ip6addr: registry.npmmirror.com/ip6addr@0.2.5
maxmind: registry.npmmirror.com/maxmind@4.3.19
dev: false
registry.npmmirror.com/@sindresorhus/is@0.14.0:
resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@sindresorhus/is/-/is-0.14.0.tgz}
name: '@sindresorhus/is'
@@ -5988,6 +6000,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
registry.npmmirror.com/ip6addr@0.2.5:
resolution: {integrity: sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ip6addr/-/ip6addr-0.2.5.tgz}
name: ip6addr
version: 0.2.5
dependencies:
assert-plus: registry.npmmirror.com/assert-plus@1.0.0
jsprim: registry.npmmirror.com/jsprim@2.0.2
dev: false
registry.npmmirror.com/ipaddr.js@1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz}
name: ipaddr.js
@@ -6556,6 +6577,12 @@ packages:
version: 0.2.3
dev: false
registry.npmmirror.com/json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz}
name: json-schema
version: 0.4.0
dev: false
registry.npmmirror.com/json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz}
name: json-stable-stringify-without-jsonify
@@ -6595,6 +6622,18 @@ packages:
verror: registry.npmmirror.com/verror@1.10.0
dev: false
registry.npmmirror.com/jsprim@2.0.2:
resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsprim/-/jsprim-2.0.2.tgz}
name: jsprim
version: 2.0.2
engines: {'0': node >=0.6.0}
dependencies:
assert-plus: registry.npmmirror.com/assert-plus@1.0.0
extsprintf: registry.npmmirror.com/extsprintf@1.3.0
json-schema: registry.npmmirror.com/json-schema@0.4.0
verror: registry.npmmirror.com/verror@1.10.0
dev: false
registry.npmmirror.com/just-debounce@1.1.0:
resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/just-debounce/-/just-debounce-1.1.0.tgz}
name: just-debounce
@@ -6943,6 +6982,16 @@ packages:
- supports-color
dev: true
registry.npmmirror.com/maxmind@4.3.19:
resolution: {integrity: sha512-Bu/VEN7ZWAOCjifdZaXJQuN6/yO7+OK35pnJsqmz8sOndK3KQFvJoY+6HX09/MmLLqtCfa+sMK0iaQOaTejGNA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/maxmind/-/maxmind-4.3.19.tgz}
name: maxmind
version: 4.3.19
engines: {node: '>=12', npm: '>=6'}
dependencies:
mmdb-lib: registry.npmmirror.com/mmdb-lib@2.1.0
tiny-lru: registry.npmmirror.com/tiny-lru@11.2.6
dev: false
registry.npmmirror.com/md5.js@1.3.5:
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/md5.js/-/md5.js-1.3.5.tgz}
name: md5.js
@@ -7132,6 +7181,13 @@ packages:
version: 0.5.3
dev: true
registry.npmmirror.com/mmdb-lib@2.1.0:
resolution: {integrity: sha512-tdDTZmnI5G4UoSctv2KxM/3VQt2XRj4CmR5R4VsAWsOUcS3LysHR34wtixWm/pXxXdkBDuN92auxkC0T2+qd1Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mmdb-lib/-/mmdb-lib-2.1.0.tgz}
name: mmdb-lib
version: 2.1.0
engines: {node: '>=10', npm: '>=6'}
dev: false
registry.npmmirror.com/mocha@10.0.0:
resolution: {integrity: sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mocha/-/mocha-10.0.0.tgz}
name: mocha
@@ -9424,6 +9480,13 @@ packages:
process: registry.npmmirror.com/process@0.11.10
dev: true
registry.npmmirror.com/tiny-lru@11.2.6:
resolution: {integrity: sha512-0PU3c9PjMnltZaFo2sGYv/nnJsMjG0Cxx8X6FXHPPGjFyoo1SJDxvUXW1207rdiSxYizf31roo+GrkIByQeZoA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tiny-lru/-/tiny-lru-11.2.6.tgz}
name: tiny-lru
version: 11.2.6
engines: {node: '>=12'}
dev: false
registry.npmmirror.com/tinyify@3.0.0:
resolution: {integrity: sha512-RtjVjC1xwwxt8AMVfxEmo+FzRJB6p5sAOtFaJj8vMrkWShtArsM4dLVRWhx2Vc07Me3NWgmP7pi9UPm/a2XNNA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tinyify/-/tinyify-3.0.0.tgz}
name: tinyify

View File

@@ -15,7 +15,7 @@ import $ from '@/core/app';
import { FILES_KEY, MODULES_KEY } from '@/constants';
import { findByName } from '@/utils/database';
import { produceArtifact } from '@/restful/sync';
import { getFlag, getISO } from '@/utils/geo';
import { getFlag, getISO, MMDB } from '@/utils/geo';
import Gist from '@/utils/gist';
function preprocess(raw) {
@@ -273,6 +273,7 @@ export const ProxyUtils = {
yaml: YAML,
getFlag,
getISO,
MMDB,
Gist,
};

View File

@@ -462,7 +462,7 @@ const DOMAIN_RESOLVERS = {
const cached = resourceCache.get(id);
if (!noCache && cached) return cached;
const resp = await $.http.get({
url: `http://223.6.6.6/resolve?name=${encodeURIComponent(
url: `http://223.6.6.6/resolve?edns_client_subnet=223.6.6.6/24&name=${encodeURIComponent(
domain,
)}&type=${type === 'IPv6' ? 'AAAA' : 'A'}&short=1`,
headers: {
@@ -482,7 +482,7 @@ const DOMAIN_RESOLVERS = {
const cached = resourceCache.get(id);
if (!noCache && cached) return cached;
const resp = await $.http.get({
url: `http://119.28.28.28/d?type=${
url: `http://119.28.28.28/d?ip=119.28.28.28&type=${
type === 'IPv6' ? 'AAAA' : 'A'
}&dn=${encodeURIComponent(domain)}`,
headers: {

View File

@@ -14,7 +14,13 @@ import $ from '@/core/app';
const tasks = new Map();
export default async function download(rawUrl, ua, timeout, proxy) {
export default async function download(
rawUrl,
ua,
timeout,
proxy,
skipCustomCache,
) {
let $arguments = {};
let url = rawUrl.replace(/#noFlow$/, '');
const rawArgs = url.split('#');
@@ -39,6 +45,23 @@ export default async function download(rawUrl, ua, timeout, proxy) {
? `#sub-store-cached-custom-${$arguments?.cacheKey}`
: undefined;
if (customCacheKey && !skipCustomCache) {
const cached = $.read(customCacheKey);
if (cached) {
$.info(
`乐观缓存: URL ${url}\n本次返回自定义缓存 ${$arguments?.cacheKey}\n并进行请求 尝试更新缓存`,
);
download(
rawUrl.replace(/(\?|&)cacheKey=.*?(&|$)/, ''),
ua,
timeout,
proxy,
true,
);
return cached;
}
}
// const downloadUrlMatch = url.match(/^\/api\/(file|module)\/(.+)/);
// if (downloadUrlMatch) {
// let type = downloadUrlMatch?.[1];
@@ -81,7 +104,7 @@ export default async function download(rawUrl, ua, timeout, proxy) {
// try to find in app cache
const cached = resourceCache.get(id);
if (!$arguments?.noCache && cached) {
if (!$arguments?.noCache && cached && !skipCustomCache) {
$.info(`使用缓存: ${url}`);
result = cached;
} else {
@@ -120,6 +143,9 @@ export default async function download(rawUrl, ua, timeout, proxy) {
if (shouldCache) {
resourceCache.set(id, body);
if (customCacheKey) {
$.info(
`URL ${url}\n写入自定义缓存 ${$arguments?.cacheKey}`,
);
$.write(body, customCacheKey);
}
}

View File

@@ -10,6 +10,7 @@ const {
isShadowRocket,
isLanceX,
isEgern,
isGUIforCores,
} = ENV();
let backend = 'Node';
if (isNode) backend = 'Node';
@@ -20,6 +21,7 @@ if (isStash) backend = 'Stash';
if (isShadowRocket) backend = 'ShadowRocket';
if (isEgern) backend = 'Egern';
if (isLanceX) backend = 'LanceX';
if (isGUIforCores) backend = 'GUI.for.Cores';
let meta = {};
@@ -36,6 +38,10 @@ try {
// eslint-disable-next-line no-undef
meta.script = $script;
}
if (typeof $Plugin !== 'undefined') {
// eslint-disable-next-line no-undef
meta.plugin = $Plugin;
}
if (isNode) {
meta.node = {
version: eval('process.version'),

View File

@@ -1,3 +1,5 @@
import $ from '@/core/app';
const ISOFlags = {
'🏳️‍🌈': ['EXP', 'BAND'],
'🇸🇱': ['TEST', 'SOS'],
@@ -427,3 +429,31 @@ export function getFlag(name) {
export function getISO(name) {
return ISOFlags[getFlag(name)]?.[0];
}
export class MMDB {
constructor({ country, asn } = {}) {
if ($.env.isNode) {
const Reader = eval(`require("@maxmind/geoip2-node")`).Reader;
const fs = eval("require('fs')");
const countryFile =
country || eval('process.env.SUB_STORE_MMDB_COUNTRY_PATH');
const asnFile = asn || eval('process.env.SUB_STORE_MMDB_ASN_PATH');
if (countryFile) {
this.countryReader = Reader.openBuffer(
fs.readFileSync(countryFile),
);
}
if (asnFile) {
if (!fs.existsSync(asnFile))
throw new Error('GeoLite2 ASN MMDB does not exist');
this.asnReader = Reader.openBuffer(fs.readFileSync(asnFile));
}
}
}
geoip(ip) {
return this.countryReader?.country(ip)?.country?.isoCode;
}
ipaso(ip) {
return this.asnReader?.asn(ip)?.autonomousSystemOrganization;
}
}

View File

@@ -161,7 +161,7 @@ export default function express({ substore: $, port, host }) {
function Response() {
let statusCode = 200;
const { isQX, isLoon, isSurge } = ENV();
const { isQX, isLoon, isSurge, isGUIforCores } = ENV();
const headers = DEFAULT_HEADERS;
const STATUS_CODE_MAP = {
200: 'HTTP/1.1 200 OK',
@@ -184,7 +184,7 @@ export default function express({ substore: $, port, host }) {
body,
headers,
};
if (isQX) {
if (isQX || isGUIforCores) {
$done(response);
} else if (isLoon || isSurge) {
$done({

View File

@@ -8,6 +8,7 @@ const isStash =
const isShadowRocket = 'undefined' !== typeof $rocket;
const isEgern = 'object' == typeof egern;
const isLanceX = 'undefined' != typeof $native;
const isGUIforCores = typeof $Plugins !== 'undefined';
export class OpenAPI {
constructor(name = 'untitled', debug = false) {
@@ -48,7 +49,10 @@ export class OpenAPI {
this.cache = JSON.parse($prefs.valueForKey(this.name) || '{}');
if (isLoon || isSurge)
this.cache = JSON.parse($persistentStore.read(this.name) || '{}');
if (isGUIforCores)
this.cache = JSON.parse(
$Plugins.SubStoreCache.get(this.name) || '{}',
);
if (isNode) {
// create a json for root cache
const basePath =
@@ -86,6 +90,7 @@ export class OpenAPI {
const data = JSON.stringify(this.cache, null, 2);
if (isQX) $prefs.setValueForKey(data, this.name);
if (isLoon || isSurge) $persistentStore.write(data, this.name);
if (isGUIforCores) $Plugins.SubStoreCache.set(this.name, data);
if (isNode) {
const basePath =
eval('process.env.SUB_STORE_DATA_BASE_PATH') || '.';
@@ -118,6 +123,9 @@ export class OpenAPI {
if (isNode) {
this.root[key] = data;
}
if (isGUIforCores) {
return $Plugins.SubStoreCache.set(key, data);
}
} else {
this.cache[key] = data;
}
@@ -137,6 +145,9 @@ export class OpenAPI {
if (isNode) {
return this.root[key];
}
if (isGUIforCores) {
return $Plugins.SubStoreCache.get(key);
}
} else {
return this.cache[key];
}
@@ -155,6 +166,9 @@ export class OpenAPI {
if (isNode) {
delete this.root[key];
}
if (isGUIforCores) {
return $Plugins.SubStoreCache.remove(key);
}
} else {
delete this.cache[key];
}
@@ -220,6 +234,9 @@ export class OpenAPI {
});
}
}
if (isGUIforCores) {
$Plugins.Notify(title, subtitle + '\n' + content);
}
}
// other helper functions
@@ -240,7 +257,7 @@ export class OpenAPI {
}
done(value = {}) {
if (isQX || isLoon || isSurge) {
if (isQX || isLoon || isSurge || isGUIforCores) {
$done(value);
} else if (isNode) {
if (typeof $context !== 'undefined') {
@@ -262,11 +279,12 @@ export function ENV() {
isShadowRocket,
isEgern,
isLanceX,
isGUIforCores,
};
}
export function HTTP(defaultOptions = { baseURL: '' }) {
const { isQX, isLoon, isSurge, isNode } = ENV();
const { isQX, isLoon, isSurge, isNode, isGUIforCores } = ENV();
const methods = [
'GET',
'POST',
@@ -356,6 +374,24 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
});
});
});
} else if (isGUIforCores) {
worker = new Promise(async (resolve, reject) => {
try {
const response = await $Plugins.Requests({
method,
url: options.url,
headers: options.headers,
body: options.body,
});
resolve({
statusCode: response.status,
headers: response.headers,
body: response.body,
});
} catch (error) {
reject(error);
}
});
}
let timeoutid;

View File

@@ -1,5 +1,5 @@
#!name=Sub-Store
#!desc=高级订阅管理工具. 定时任务默认为每天 23 点 55 分
#!desc=高级订阅管理工具. 定时任务默认为每天 23 点 55 分. 定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'
#!openUrl=https://sub.store
#!author=Peng-YM
#!homepage=https://github.com/sub-store-org/Sub-Store

View File

@@ -1,6 +1,6 @@
{
"name": "Sub-Store",
"description": "定时任务默认为每天 23 点 55 分",
"description": "定时任务默认为每天 23 点 55 分. 定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'",
"task": [
"55 23 * * * https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js, tag=Sub-Store Sync, img-url=https://raw.githubusercontent.com/58xinian/icon/master/Sub-Store1.png"
]

View File

@@ -31,7 +31,7 @@ Telegram 频道: [`https://t.me/cool_scripts` ](https://t.me/cool_scripts)
安装使用 覆写 [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Stash.stoverride`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Stash.stoverride) 即可。
### 5. Shadowrocket
安装使用 模块 [`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) 即可。
安装使用 模块 [`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) 即可。
## 使用 Sub-Store
1. 使用 Safari 打开这个 https://sub.store 如网页正常打开并且未弹出任何错误提示,说明 Sub-Store 已经配置成功。

View File

@@ -1,5 +1,5 @@
name: Sub-Store
desc: 高级订阅管理工具 @Peng-YM. 定时任务默认为每天 23 点 55 分
desc: 高级订阅管理工具 @Peng-YM. 定时任务默认为每天 23 点 55 分. 定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'
icon: https://raw.githubusercontent.com/cc63/ICON/main/Sub-Store.png
http:

View File

@@ -2,7 +2,7 @@
#!desc=支持 Surge 正式版的参数设置功能. 测落地功能 ability: http-client-policy, 同步配置的定时 cronexp: 55 23 * * *
#!category=订阅管理
#!arguments=ability:http-client-policy,cronexp:55 23 * * *,sync:"Sub-Store Sync",timeout:120,engine:auto
#!arguments-desc=\n1⃣ ability\n\n默认已开启测落地能力\n需要配合脚本操作\n如 https://raw.githubusercontent.com/Keywos/rule/main/cname.js\n填写任意其他值关闭\n\n2⃣ cronexp\n\n同步配置定时任务\n默认为每天 23 点 55 分\n\n3⃣ sync\n\n自定义定时任务名\n便于在脚本编辑器中选择\n若设为 # 可取消定时任务\n\n4⃣ timeout\n\n超时, 单位为秒\n\n5⃣ engine\n\n默认为自动使用 webview 引擎, 可设为指定 jsc, 但 jsc 容易爆内存
#!arguments-desc=\n1⃣ ability\n\n默认已开启测落地能力\n需要配合脚本操作\n如 https://raw.githubusercontent.com/Keywos/rule/main/cname.js\n填写任意其他值关闭\n\n2⃣ cronexp\n\n同步配置定时任务\n默认为每天 23 点 55 分\n\n定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'\n\n3⃣ sync\n\n自定义定时任务名\n便于在脚本编辑器中选择\n若设为 # 可取消定时任务\n\n4⃣ timeout\n\n超时, 单位为秒\n\n5⃣ engine\n\n默认为自动使用 webview 引擎, 可设为指定 jsc, 但 jsc 容易爆内存
[MITM]
hostname = %APPEND% sub.store

View File

@@ -1,5 +1,5 @@
#!name=Sub-Store
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 23 点 55 分
#!desc=高级订阅管理工具 @Peng-YM 无 ability 参数版本,不会爆内存, 如果需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 可以用带 ability 参数. 定时任务默认为每天 23 点 55 分. 定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'
#!category=订阅管理
[MITM]

View File

@@ -1,5 +1,5 @@
#!name=Sub-Store
#!desc=高级订阅管理工具 @Peng-YM 带 ability 参数版本, 使用 jsc 引擎时, 可能会爆内存, 如果不需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 可以用不带 ability 参数版本. 定时任务默认为每天 23 点 55 分
#!desc=高级订阅管理工具 @Peng-YM 带 ability 参数版本, 使用 jsc 引擎时, 可能会爆内存, 如果不需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 可以用不带 ability 参数版本. 定时任务默认为每天 23 点 55 分. 定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'
#!category=订阅管理
[MITM]

View File

@@ -2,7 +2,7 @@
#!desc=支持 Surge 正式版的参数设置功能. 测落地功能 ability: http-client-policy, 同步配置的定时 cronexp: 55 23 * * *
#!category=订阅管理
#!arguments=ability:http-client-policy,cronexp:55 23 * * *,sync:"Sub-Store Sync",timeout:120,engine:auto
#!arguments-desc=\n1⃣ ability\n\n默认已开启测落地能力\n需要配合脚本操作\n如 https://raw.githubusercontent.com/Keywos/rule/main/cname.js\n填写任意其他值关闭\n\n2⃣ cronexp\n\n同步配置定时任务\n默认为每天 23 点 55 分\n\n3⃣ sync\n\n自定义定时任务名\n便于在脚本编辑器中选择\n若设为 # 可取消定时任务\n\n4⃣ timeout\n\n超时, 单位为秒\n\n5⃣ engine\n\n默认为自动使用 webview 引擎, 可设为指定 jsc, 但 jsc 容易爆内存
#!arguments-desc=\n1⃣ ability\n\n默认已开启测落地能力\n需要配合脚本操作\n如 https://raw.githubusercontent.com/Keywos/rule/main/cname.js\n填写任意其他值关闭\n\n2⃣ cronexp\n\n同步配置定时任务\n默认为每天 23 点 55 分\n\n定时任务指定时将订阅/文件上传到私有 Gist. 在前端, 叫做 '同步' 或 '同步配置'\n\n3⃣ sync\n\n自定义定时任务名\n便于在脚本编辑器中选择\n若设为 # 可取消定时任务\n\n4⃣ timeout\n\n超时, 单位为秒\n\n5⃣ engine\n\n默认为自动使用 webview 引擎, 可设为指定 jsc, 但 jsc 容易爆内存
[MITM]
hostname = %APPEND% sub.store