reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const path = require('path');
const https = require('https');
const REPOS = {
ruyitrace: { owner: 'LoseNine', repo: 'Firefox-FingerPrint-Analyzer', asset: /RuyiTrace\.zip$/i },
'ruyipage-firefox': { owner: 'LoseNine', repo: 'ruyipage', asset: null },
};
function parseArgs(argv) {
const args = { tool: '', dest: '', dryRun: false, json: false, markdown: false };
for (let i = 2; i < argv.length; i++) {
const a = argv[i];
if (a === '--tool') args.tool = argv[++i] || '';
else if (a === '--dest') args.dest = argv[++i] || '';
else if (a === '--dry-run') args.dryRun = true;
else if (a === '--json') args.json = true;
else if (a === '--markdown') args.markdown = true;
else if (a === '--help' || a === '-h') args.help = true;
else throw new Error(`未知参数:${a}`);
}
if (!args.json && !args.markdown) args.markdown = true;
return args;
}
function usage() {
return `用法:
node scripts/download_ruyi_tool.js --tool ruyitrace --dest <download-dir> --dry-run --markdown
node scripts/download_ruyi_tool.js --tool ruyitrace --dest <download-dir> --markdown
node scripts/download_ruyi_tool.js --tool ruyipage-firefox --dest <download-dir> --dry-run --markdown
说明:仅在用户确认后下载。下载后仍需要用户解压 / 安装或确认可执行文件路径。`;
}
function getJson(url) {
return new Promise((resolve, reject) => {
const req = https.get(url, { headers: { 'User-Agent': 'web-js-env-patcher-skill' } }, res => {
let data = '';
res.setEncoding('utf8');
res.on('data', chunk => { data += chunk; });
res.on('end', () => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
getJson(res.headers.location).then(resolve, reject);
return;
}
if (res.statusCode !== 200) reject(new Error(`请求失败 ${res.statusCode}: ${url}`));
else {
try { resolve(JSON.parse(data)); } catch (err) { reject(err); }
}
});
});
req.on('error', reject);
req.setTimeout(60000, () => req.destroy(new Error('请求超时')));
});
}
function pickRuyiPageAsset(assets) {
if (process.platform === 'win32') return assets.find(a => /win64\.zip$/i.test(a.name));
if (process.platform === 'linux' && process.arch === 'x64') return assets.find(a => /linux.*x86_64.*\.tar\.xz$/i.test(a.name));
return assets.find(a => /firefox/i.test(a.name));
}
function selectAsset(tool, assets) {
if (tool === 'ruyipage-firefox') return pickRuyiPageAsset(assets);
const rule = REPOS[tool].asset;
return assets.find(a => rule.test(a.name));
}
function downloadFile(url, file) {
return new Promise((resolve, reject) => {
fs.mkdirSync(path.dirname(file), { recursive: true });
const out = fs.createWriteStream(file);
function request(u) {
https.get(u, { headers: { 'User-Agent': 'web-js-env-patcher-skill' } }, res => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
request(res.headers.location);
return;
}
if (res.statusCode !== 200) {
out.close();
reject(new Error(`下载失败 ${res.statusCode}: ${u}`));
return;
}
res.pipe(out);
out.on('finish', () => out.close(() => resolve(file)));
}).on('error', err => {
out.close();
reject(err);
});
}
request(url);
});
}
async function plan(args) {
if (!args.tool || !REPOS[args.tool]) throw new Error(`必须提供 --tool,可选:${Object.keys(REPOS).join(', ')}`);
if (!args.dest) throw new Error('必须提供 --dest');
const repo = REPOS[args.tool];
const release = await getJson(`https://api.github.com/repos/${repo.owner}/${repo.repo}/releases/latest`);
const asset = selectAsset(args.tool, release.assets || []);
if (!asset) throw new Error(`未找到适合当前工具 / 平台的 release asset:${args.tool}`);
const destDir = path.resolve(args.dest);
const file = path.join(destDir, asset.name);
const result = {
tool: args.tool,
repo: `${repo.owner}/${repo.repo}`,
releaseName: release.name || '',
tagName: release.tag_name || '',
releaseUrl: release.html_url || '',
assetName: asset.name,
assetSize: asset.size,
downloadUrl: asset.browser_download_url,
destFile: file,
dryRun: args.dryRun,
downloaded: false,
};
if (!args.dryRun) {
await downloadFile(asset.browser_download_url, file);
result.downloaded = true;
}
return result;
}
function renderMarkdown(result) {
const lines = ['# Ruyi 工具下载结果', '', `- 工具:${result.tool}`, `- 仓库:${result.repo}`, `- Release:${result.releaseName || result.tagName}`, `- Release URL:${result.releaseUrl}`, `- 资产:${result.assetName}`, `- 大小:${result.assetSize}`, `- 目标文件:${result.destFile}`, `- dry-run:${result.dryRun ? '是' : '否'}`, `- 是否已下载:${result.downloaded ? '是' : '否'}`];
lines.push('', '## 下一步');
if (result.dryRun) lines.push('- 当前只是下载计划;只有用户确认后再去掉 `--dry-run` 下载。');
else lines.push('- 下载完成。请用户解压 / 安装后,提供工具目录并重新运行检测脚本。');
return lines.join('\n') + '\n';
}
async function main() {
const args = parseArgs(process.argv);
if (args.help) { console.log(usage()); return; }
const result = await plan(args);
if (args.json) console.log(JSON.stringify(result, null, 2));
if (args.markdown) process.stdout.write(renderMarkdown(result));
}
main().catch(err => {
console.error(err.message || String(err));
console.error(usage());
process.exit(1);
});