mirror of
https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-10 00:52:40 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d53947d820 | ||
|
|
7e75031e92 | ||
|
|
4a07c02dc1 | ||
|
|
95d6688539 | ||
|
|
a23e2ffcd6 | ||
|
|
fda1252d0e | ||
|
|
62c5c2e15b | ||
|
|
ffabcc9391 | ||
|
|
0825f15d04 | ||
|
|
fbf6b5ce6e | ||
|
|
3eb0816c88 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.16.44",
|
"version": "2.16.55",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { produceArtifact } from '@/restful/sync';
|
|||||||
import { getFlag, removeFlag, getISO, MMDB } from '@/utils/geo';
|
import { getFlag, removeFlag, getISO, MMDB } from '@/utils/geo';
|
||||||
import Gist from '@/utils/gist';
|
import Gist from '@/utils/gist';
|
||||||
import { isPresent } from './producers/utils';
|
import { isPresent } from './producers/utils';
|
||||||
|
import { doh } from '@/utils/dns';
|
||||||
|
|
||||||
function preprocess(raw) {
|
function preprocess(raw) {
|
||||||
for (const processor of PROXY_PREPROCESSORS) {
|
for (const processor of PROXY_PREPROCESSORS) {
|
||||||
@@ -81,9 +82,9 @@ function parse(raw) {
|
|||||||
if (['vless', 'vmess'].includes(proxy.type)) {
|
if (['vless', 'vmess'].includes(proxy.type)) {
|
||||||
const isProxyUUIDValid = isValidUUID(proxy.uuid);
|
const isProxyUUIDValid = isValidUUID(proxy.uuid);
|
||||||
if (!isProxyUUIDValid) {
|
if (!isProxyUUIDValid) {
|
||||||
$.error(`UUID is invalid: ${proxy.name} ${proxy.uuid}`);
|
$.error(`UUID may be invalid: ${proxy.name} ${proxy.uuid}`);
|
||||||
}
|
}
|
||||||
return isProxyUUIDValid;
|
// return isProxyUUIDValid;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -235,8 +236,8 @@ function produce(proxies, targetPlatform, type, opts = {}) {
|
|||||||
if (['vless', 'vmess'].includes(proxy.type)) {
|
if (['vless', 'vmess'].includes(proxy.type)) {
|
||||||
const isProxyUUIDValid = isValidUUID(proxy.uuid);
|
const isProxyUUIDValid = isValidUUID(proxy.uuid);
|
||||||
if (!isProxyUUIDValid)
|
if (!isProxyUUIDValid)
|
||||||
$.error(`UUID is invalid: ${proxy.name} ${proxy.uuid}`);
|
$.error(`UUID may be invalid: ${proxy.name} ${proxy.uuid}`);
|
||||||
return isProxyUUIDValid;
|
// return isProxyUUIDValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -326,6 +327,8 @@ export const ProxyUtils = {
|
|||||||
MMDB,
|
MMDB,
|
||||||
Gist,
|
Gist,
|
||||||
download,
|
download,
|
||||||
|
isValidUUID,
|
||||||
|
doh,
|
||||||
};
|
};
|
||||||
|
|
||||||
function tryParse(parser, line) {
|
function tryParse(parser, line) {
|
||||||
@@ -423,9 +426,14 @@ function lastParse(proxy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
['trojan', 'tuic', 'hysteria', 'hysteria2', 'juicity'].includes(
|
[
|
||||||
proxy.type,
|
'trojan',
|
||||||
)
|
'tuic',
|
||||||
|
'hysteria',
|
||||||
|
'hysteria2',
|
||||||
|
'juicity',
|
||||||
|
'anytls',
|
||||||
|
].includes(proxy.type)
|
||||||
) {
|
) {
|
||||||
proxy.tls = true;
|
proxy.tls = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,8 @@ function URI_SS() {
|
|||||||
|
|
||||||
// handle obfs
|
// handle obfs
|
||||||
const pluginMatch = content.match(/[?&]plugin=([^&]+)/);
|
const pluginMatch = content.match(/[?&]plugin=([^&]+)/);
|
||||||
|
const shadowTlsMatch = content.match(/[?&]shadow-tls=([^&]+)/);
|
||||||
|
|
||||||
if (pluginMatch) {
|
if (pluginMatch) {
|
||||||
const pluginInfo = (
|
const pluginInfo = (
|
||||||
'plugin=' + decodeURIComponent(pluginMatch[1])
|
'plugin=' + decodeURIComponent(pluginMatch[1])
|
||||||
@@ -233,6 +235,25 @@ function URI_SS() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Shadowrocket
|
||||||
|
if (shadowTlsMatch) {
|
||||||
|
const params = JSON.parse(Base64.decode(shadowTlsMatch[1]));
|
||||||
|
const version = getIfNotBlank(params['version']);
|
||||||
|
const address = getIfNotBlank(params['address']);
|
||||||
|
const port = getIfNotBlank(params['port']);
|
||||||
|
proxy.plugin = 'shadow-tls';
|
||||||
|
proxy['plugin-opts'] = {
|
||||||
|
host: getIfNotBlank(params['host']),
|
||||||
|
password: getIfNotBlank(params['password']),
|
||||||
|
version: version ? parseInt(version, 10) : undefined,
|
||||||
|
};
|
||||||
|
if (address) {
|
||||||
|
proxy.server = address;
|
||||||
|
}
|
||||||
|
if (port) {
|
||||||
|
proxy.port = parseInt(port, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (/(&|\?)uot=(1|true)/i.test(query)) {
|
if (/(&|\?)uot=(1|true)/i.test(query)) {
|
||||||
proxy['udp-over-tcp'] = true;
|
proxy['udp-over-tcp'] = true;
|
||||||
}
|
}
|
||||||
@@ -865,18 +886,18 @@ function URI_TUIC() {
|
|||||||
|
|
||||||
for (const addon of addons.split('&')) {
|
for (const addon of addons.split('&')) {
|
||||||
let [key, value] = addon.split('=');
|
let [key, value] = addon.split('=');
|
||||||
key = key.replace(/_/, '-');
|
key = key.replace(/_/g, '-');
|
||||||
value = decodeURIComponent(value);
|
value = decodeURIComponent(value);
|
||||||
if (['alpn'].includes(key)) {
|
if (['alpn'].includes(key)) {
|
||||||
proxy[key] = value ? value.split(',') : undefined;
|
proxy[key] = value ? value.split(',') : undefined;
|
||||||
} else if (['allow_insecure'].includes(key)) {
|
} else if (['allow-insecure'].includes(key)) {
|
||||||
proxy['skip-cert-verify'] = /(TRUE)|1/i.test(value);
|
proxy['skip-cert-verify'] = /(TRUE)|1/i.test(value);
|
||||||
} else if (['fast_open'].includes(key)) {
|
} else if (['fast-open'].includes(key)) {
|
||||||
proxy.tfo = true;
|
proxy.tfo = true;
|
||||||
} else if (['disable_sni', 'reduce_rtt'].includes(key)) {
|
} else if (['disable-sni', 'reduce-rtt'].includes(key)) {
|
||||||
proxy[key.replace(/_/g, '-')] = /(TRUE)|1/i.test(value);
|
proxy[key] = /(TRUE)|1/i.test(value);
|
||||||
} else {
|
} else {
|
||||||
proxy[key.replace(/_/g, '-')] = value;
|
proxy[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,6 +1031,7 @@ function Clash_All() {
|
|||||||
const proxy = JSON.parse(line);
|
const proxy = JSON.parse(line);
|
||||||
if (
|
if (
|
||||||
![
|
![
|
||||||
|
'anytls',
|
||||||
'mieru',
|
'mieru',
|
||||||
'juicity',
|
'juicity',
|
||||||
'ss',
|
'ss',
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ function Clash() {
|
|||||||
// 防止 VLESS节点 reality-opts 选项中的 short-id 被解析成 Infinity
|
// 防止 VLESS节点 reality-opts 选项中的 short-id 被解析成 Infinity
|
||||||
// 匹配 short-id 冒号后面的值(包含空格和引号)
|
// 匹配 short-id 冒号后面的值(包含空格和引号)
|
||||||
const afterReplace = raw.replace(
|
const afterReplace = raw.replace(
|
||||||
/short-id:([ ]*[^,\n}]*)/g,
|
/short-id:([ \t]*[^#\n,}]*)/g,
|
||||||
(matched, value) => {
|
(matched, value) => {
|
||||||
const afterTrim = value.trim();
|
const afterTrim = value.trim();
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ export default function Clash_Producer() {
|
|||||||
'hysteria',
|
'hysteria',
|
||||||
'hysteria2',
|
'hysteria2',
|
||||||
'juicity',
|
'juicity',
|
||||||
|
'anytls',
|
||||||
].includes(proxy.type)
|
].includes(proxy.type)
|
||||||
) {
|
) {
|
||||||
delete proxy.tls;
|
delete proxy.tls;
|
||||||
|
|||||||
@@ -105,6 +105,9 @@ export default function ClashMeta_Producer() {
|
|||||||
password: proxy['shadow-tls-password'],
|
password: proxy['shadow-tls-password'],
|
||||||
version: proxy['shadow-tls-version'],
|
version: proxy['shadow-tls-version'],
|
||||||
};
|
};
|
||||||
|
delete proxy['shadow-tls-password'];
|
||||||
|
delete proxy['shadow-tls-sni'];
|
||||||
|
delete proxy['shadow-tls-version'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +163,7 @@ export default function ClashMeta_Producer() {
|
|||||||
'hysteria',
|
'hysteria',
|
||||||
'hysteria2',
|
'hysteria2',
|
||||||
'juicity',
|
'juicity',
|
||||||
|
'anytls',
|
||||||
].includes(proxy.type)
|
].includes(proxy.type)
|
||||||
) {
|
) {
|
||||||
delete proxy.tls;
|
delete proxy.tls;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import { isPresent } from './utils';
|
||||||
|
|
||||||
export default function Egern_Producer() {
|
export default function Egern_Producer() {
|
||||||
const type = 'ALL';
|
const type = 'ALL';
|
||||||
const produce = (proxies, type, opts = {}) => {
|
const produce = (proxies, type) => {
|
||||||
// https://egernapp.com/zh-CN/docs/configuration/proxies
|
// https://egernapp.com/zh-CN/docs/configuration/proxies
|
||||||
const list = proxies
|
const list = proxies
|
||||||
.filter((proxy) => {
|
.filter((proxy) => {
|
||||||
@@ -71,6 +73,7 @@ export default function Egern_Producer() {
|
|||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.map((proxy) => {
|
.map((proxy) => {
|
||||||
|
const original = { ...proxy };
|
||||||
if (proxy.tls && !proxy.sni) {
|
if (proxy.tls && !proxy.sni) {
|
||||||
proxy.sni = proxy.server;
|
proxy.sni = proxy.server;
|
||||||
}
|
}
|
||||||
@@ -215,7 +218,9 @@ export default function Egern_Producer() {
|
|||||||
proxy.transport = {
|
proxy.transport = {
|
||||||
http1: {
|
http1: {
|
||||||
method: proxy['http-opts']?.method,
|
method: proxy['http-opts']?.method,
|
||||||
path: proxy['http-opts']?.path,
|
path: Array.isArray(proxy['http-opts']?.path)
|
||||||
|
? proxy['http-opts']?.path[0]
|
||||||
|
: proxy['http-opts']?.path,
|
||||||
headers: {
|
headers: {
|
||||||
Host: Array.isArray(
|
Host: Array.isArray(
|
||||||
proxy['http-opts']?.headers?.Host,
|
proxy['http-opts']?.headers?.Host,
|
||||||
@@ -230,7 +235,9 @@ export default function Egern_Producer() {
|
|||||||
proxy.transport = {
|
proxy.transport = {
|
||||||
http2: {
|
http2: {
|
||||||
method: proxy['h2-opts']?.method,
|
method: proxy['h2-opts']?.method,
|
||||||
path: proxy['h2-opts']?.path,
|
path: Array.isArray(proxy['h2-opts']?.path)
|
||||||
|
? proxy['h2-opts']?.path[0]
|
||||||
|
: proxy['h2-opts']?.path,
|
||||||
headers: {
|
headers: {
|
||||||
Host: Array.isArray(
|
Host: Array.isArray(
|
||||||
proxy['h2-opts']?.headers?.Host,
|
proxy['h2-opts']?.headers?.Host,
|
||||||
@@ -288,7 +295,9 @@ export default function Egern_Producer() {
|
|||||||
proxy.transport = {
|
proxy.transport = {
|
||||||
http: {
|
http: {
|
||||||
method: proxy['http-opts']?.method,
|
method: proxy['http-opts']?.method,
|
||||||
path: proxy['http-opts']?.path,
|
path: Array.isArray(proxy['http-opts']?.path)
|
||||||
|
? proxy['http-opts']?.path[0]
|
||||||
|
: proxy['http-opts']?.path,
|
||||||
headers: {
|
headers: {
|
||||||
Host: Array.isArray(
|
Host: Array.isArray(
|
||||||
proxy['http-opts']?.headers?.Host,
|
proxy['http-opts']?.headers?.Host,
|
||||||
@@ -326,6 +335,39 @@ export default function Egern_Producer() {
|
|||||||
// skip_tls_verify: proxy['skip-cert-verify'],
|
// skip_tls_verify: proxy['skip-cert-verify'],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'http',
|
||||||
|
'socks5',
|
||||||
|
'ss',
|
||||||
|
'trojan',
|
||||||
|
'vless',
|
||||||
|
'vmess',
|
||||||
|
].includes(original.type)
|
||||||
|
) {
|
||||||
|
if (isPresent(original, 'shadow-tls-password')) {
|
||||||
|
if (original['shadow-tls-version'] != 3)
|
||||||
|
throw new Error(
|
||||||
|
`shadow-tls version ${original['shadow-tls-version']} is not supported`,
|
||||||
|
);
|
||||||
|
proxy.shadow_tls = {
|
||||||
|
password: original['shadow-tls-password'],
|
||||||
|
sni: original['shadow-tls-sni'],
|
||||||
|
};
|
||||||
|
} else if (
|
||||||
|
['shadow-tls'].includes(original.plugin) &&
|
||||||
|
original['plugin-opts']
|
||||||
|
) {
|
||||||
|
if (original['plugin-opts'].version != 3)
|
||||||
|
throw new Error(
|
||||||
|
`shadow-tls version ${original['plugin-opts'].version} is not supported`,
|
||||||
|
);
|
||||||
|
proxy.shadow_tls = {
|
||||||
|
password: original['plugin-opts'].password,
|
||||||
|
sni: original['plugin-opts'].host,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete proxy.subName;
|
delete proxy.subName;
|
||||||
delete proxy.collectionName;
|
delete proxy.collectionName;
|
||||||
|
|||||||
@@ -341,10 +341,9 @@ function vmess(proxy) {
|
|||||||
// udp
|
// udp
|
||||||
if (proxy.udp) {
|
if (proxy.udp) {
|
||||||
result.append(`,udp=true`);
|
result.append(`,udp=true`);
|
||||||
const ip_version =
|
|
||||||
ipVersions[proxy['ip-version']] || proxy['ip-version'];
|
|
||||||
result.appendIfPresent(`,ip-mode=${ip_version}`, 'ip-version');
|
|
||||||
}
|
}
|
||||||
|
const ip_version = ipVersions[proxy['ip-version']] || proxy['ip-version'];
|
||||||
|
result.appendIfPresent(`,ip-mode=${ip_version}`, 'ip-version');
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,10 +415,9 @@ function vless(proxy) {
|
|||||||
// udp
|
// udp
|
||||||
if (proxy.udp) {
|
if (proxy.udp) {
|
||||||
result.append(`,udp=true`);
|
result.append(`,udp=true`);
|
||||||
const ip_version =
|
|
||||||
ipVersions[proxy['ip-version']] || proxy['ip-version'];
|
|
||||||
result.appendIfPresent(`,ip-mode=${ip_version}`, 'ip-version');
|
|
||||||
}
|
}
|
||||||
|
const ip_version = ipVersions[proxy['ip-version']] || proxy['ip-version'];
|
||||||
|
result.appendIfPresent(`,ip-mode=${ip_version}`, 'ip-version');
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function Shadowrocket_Producer() {
|
|||||||
if (opts['include-unsupported-proxy']) return true;
|
if (opts['include-unsupported-proxy']) return true;
|
||||||
if (proxy.type === 'snell' && String(proxy.version) === '4') {
|
if (proxy.type === 'snell' && String(proxy.version) === '4') {
|
||||||
return false;
|
return false;
|
||||||
} else if (['mieru'].includes(proxy.type)) {
|
} else if (['mieru', 'anytls'].includes(proxy.type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -110,6 +110,21 @@ export default function Shadowrocket_Producer() {
|
|||||||
proxy.servername = proxy.sni;
|
proxy.servername = proxy.sni;
|
||||||
delete proxy.sni;
|
delete proxy.sni;
|
||||||
}
|
}
|
||||||
|
} else if (proxy.type === 'ss') {
|
||||||
|
if (
|
||||||
|
isPresent(proxy, 'shadow-tls-password') &&
|
||||||
|
!isPresent(proxy, 'plugin')
|
||||||
|
) {
|
||||||
|
proxy.plugin = 'shadow-tls';
|
||||||
|
proxy['plugin-opts'] = {
|
||||||
|
host: proxy['shadow-tls-sni'],
|
||||||
|
password: proxy['shadow-tls-password'],
|
||||||
|
version: proxy['shadow-tls-version'],
|
||||||
|
};
|
||||||
|
delete proxy['shadow-tls-password'];
|
||||||
|
delete proxy['shadow-tls-sni'];
|
||||||
|
delete proxy['shadow-tls-version'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -163,6 +178,7 @@ export default function Shadowrocket_Producer() {
|
|||||||
'hysteria',
|
'hysteria',
|
||||||
'hysteria2',
|
'hysteria2',
|
||||||
'juicity',
|
'juicity',
|
||||||
|
'anytls',
|
||||||
].includes(proxy.type)
|
].includes(proxy.type)
|
||||||
) {
|
) {
|
||||||
delete proxy.tls;
|
delete proxy.tls;
|
||||||
|
|||||||
@@ -641,6 +641,23 @@ const tuic5Parser = (proxy = {}) => {
|
|||||||
smuxParser(proxy.smux, parsedProxy);
|
smuxParser(proxy.smux, parsedProxy);
|
||||||
return parsedProxy;
|
return parsedProxy;
|
||||||
};
|
};
|
||||||
|
const anytlsParser = (proxy = {}) => {
|
||||||
|
const parsedProxy = {
|
||||||
|
tag: proxy.name,
|
||||||
|
type: 'anytls',
|
||||||
|
server: proxy.server,
|
||||||
|
server_port: parseInt(`${proxy.port}`, 10),
|
||||||
|
password: proxy.password,
|
||||||
|
tls: { enabled: true, server_name: proxy.server, insecure: false },
|
||||||
|
};
|
||||||
|
if (/^\d+$/.test(proxy['idle-session-check-interval']))
|
||||||
|
parsedProxy.idle_session_check_interval = `${proxy['idle-session-check-interval']}s`;
|
||||||
|
if (/^\d+$/.test(proxy['idle-session-timeout']))
|
||||||
|
parsedProxy.idle_session_timeout = `${proxy['idle-session-timeout']}s`;
|
||||||
|
detourParser(proxy, parsedProxy);
|
||||||
|
tlsParser(proxy, parsedProxy);
|
||||||
|
return parsedProxy;
|
||||||
|
};
|
||||||
|
|
||||||
const wireguardParser = (proxy = {}) => {
|
const wireguardParser = (proxy = {}) => {
|
||||||
const local_address = ['ip', 'ipv6']
|
const local_address = ['ip', 'ipv6']
|
||||||
@@ -829,6 +846,9 @@ export default function singbox_Producer() {
|
|||||||
case 'wireguard':
|
case 'wireguard':
|
||||||
list.push(wireguardParser(proxy));
|
list.push(wireguardParser(proxy));
|
||||||
break;
|
break;
|
||||||
|
case 'anytls':
|
||||||
|
list.push(anytlsParser(proxy));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Platform sing-box does not support proxy type: ${proxy.type}`,
|
`Platform sing-box does not support proxy type: ${proxy.type}`,
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ export default function Stash_Producer() {
|
|||||||
'hysteria',
|
'hysteria',
|
||||||
'hysteria2',
|
'hysteria2',
|
||||||
'juicity',
|
'juicity',
|
||||||
|
'anytls',
|
||||||
].includes(proxy.type)
|
].includes(proxy.type)
|
||||||
) {
|
) {
|
||||||
delete proxy.tls;
|
delete proxy.tls;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ function numberToString(value) {
|
|||||||
function isValidUUID(uuid) {
|
function isValidUUID(uuid) {
|
||||||
return (
|
return (
|
||||||
typeof uuid === 'string' &&
|
typeof uuid === 'string' &&
|
||||||
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/.test(
|
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(
|
||||||
uuid,
|
uuid,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// 16. `sing-box` 支持使用 `_network` 来设置 `network`, 例如 `tcp`, `udp`
|
// 16. `sing-box` 支持使用 `_network` 来设置 `network`, 例如 `tcp`, `udp`
|
||||||
|
|
||||||
// require 为 Node.js 的 require, 在 Node.js 运行环境下 可以用来引入模块
|
// require 为 Node.js 的 require, 在 Node.js 运行环境下 可以用来引入模块
|
||||||
|
// 例如在 Node.js 环境下, 将文件内容写入 /tmp/1.txt 文件
|
||||||
|
// const fs = eval(`require("fs")`)
|
||||||
|
// // const path = eval(`require("path")`)
|
||||||
|
// fs.writeFileSync('/tmp/1.txt', $content, "utf8");
|
||||||
|
|
||||||
// $arguments 为传入的脚本参数
|
// $arguments 为传入的脚本参数
|
||||||
|
|
||||||
@@ -69,6 +73,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// Gist, // Gist 类
|
// Gist, // Gist 类
|
||||||
// download, // 内部的下载方法, 见 backend/src/utils/download.js
|
// download, // 内部的下载方法, 见 backend/src/utils/download.js
|
||||||
// MMDB, // Node.js 环境 可用于模拟 Surge/Loon 的 $utils.ipasn, $utils.ipaso, $utils.geoip. 具体见 https://t.me/zhetengsha/1269
|
// MMDB, // Node.js 环境 可用于模拟 Surge/Loon 的 $utils.ipasn, $utils.ipaso, $utils.geoip. 具体见 https://t.me/zhetengsha/1269
|
||||||
|
// isValidUUID, // 辅助判断是否为有效的 UUID
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 如果只是为了快速修改或者筛选 可以参考 脚本操作支持节点快捷脚本 https://t.me/zhetengsha/970 和 脚本筛选支持节点快捷脚本 https://t.me/zhetengsha/1009
|
// 如果只是为了快速修改或者筛选 可以参考 脚本操作支持节点快捷脚本 https://t.me/zhetengsha/970 和 脚本筛选支持节点快捷脚本 https://t.me/zhetengsha/1009
|
||||||
|
|||||||
Reference in New Issue
Block a user