mirror of
https://github.com/TiagoVal97/cheatspecter.git
synced 2026-10-18 20:05:16 +02:00
Browser-based real-time modding tool for offline single-player games on a jailbroken PS5, served by a payload on the console. - Value search, memory and code views, find what writes to a value - Cheats as patches, held values, injected code, calls and scripts - .cspector cheat files, saved on the PS5 or on your device - Community tables in JSON, SHN and MC4 from three repositories - Game library with names, logos and sizes; start a game from the browser - MCP server for assistants
65 lines
2.4 KiB
JavaScript
65 lines
2.4 KiB
JavaScript
// Turns the built web app (dist/) into a C file the payload compiles in.
|
|
// Every file is stored gzip-compressed and served that way.
|
|
//
|
|
// node scripts/embed-assets.mjs <dist dir> <output .c>
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import zlib from 'node:zlib';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const [distDir, outFile] = process.argv.slice(2);
|
|
if (!distDir || !outFile) {
|
|
console.error('usage: embed-assets.mjs <dist dir> <output .c>');
|
|
process.exit(1);
|
|
}
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const version = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).version;
|
|
|
|
const MIME = {
|
|
'.html': 'text/html; charset=utf-8',
|
|
'.js': 'text/javascript; charset=utf-8',
|
|
'.css': 'text/css; charset=utf-8',
|
|
'.svg': 'image/svg+xml',
|
|
'.json': 'application/json; charset=utf-8',
|
|
'.png': 'image/png',
|
|
'.ico': 'image/x-icon',
|
|
'.wasm': 'application/wasm',
|
|
};
|
|
|
|
function walk(dir, prefix = '') {
|
|
const out = [];
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const rel = `${prefix}/${entry.name}`;
|
|
if (entry.isDirectory()) out.push(...walk(path.join(dir, entry.name), rel));
|
|
else out.push(rel);
|
|
}
|
|
return out.sort();
|
|
}
|
|
|
|
const files = walk(distDir);
|
|
if (!files.includes('/index.html')) {
|
|
console.error(`${distDir} has no index.html; run "npm run build" first`);
|
|
process.exit(1);
|
|
}
|
|
|
|
let c = '/* Generated by scripts/embed-assets.mjs. Do not edit. */\n#include "assets.h"\n\n';
|
|
c += `const char CS_VERSION[] = ${JSON.stringify(version)};\n\n`;
|
|
const rows = [];
|
|
let total = 0;
|
|
files.forEach((rel, i) => {
|
|
const gz = zlib.gzipSync(fs.readFileSync(path.join(distDir, rel)), { level: 9 });
|
|
total += gz.length;
|
|
const bytes = [];
|
|
for (let o = 0; o < gz.length; o += 20) bytes.push(' ' + [...gz.subarray(o, o + 20)].join(','));
|
|
c += `static const unsigned char asset_${i}[] = {\n${bytes.join(',\n')}\n};\n\n`;
|
|
const mime = MIME[path.extname(rel).toLowerCase()] ?? 'application/octet-stream';
|
|
rows.push(` {${JSON.stringify(rel)}, ${JSON.stringify(mime)}, asset_${i}, sizeof asset_${i}, ${rel.startsWith('/assets/') ? 1 : 0}}`);
|
|
});
|
|
c += `const struct asset CS_ASSETS[] = {\n${rows.join(',\n')}\n};\n\nconst int CS_ASSET_COUNT = ${files.length};\n`;
|
|
|
|
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
|
fs.writeFileSync(outFile, c);
|
|
console.log(`Embedded ${files.length} files, ${(total / 1024).toFixed(0)} KB compressed -> ${outFile}`);
|