Files
GaCy-GO/tools/capture_named_baked_modules.js
T
2026-10-28 18:54:43 +07:00

33 lines
1.8 KiB
JavaScript

// Passive capture only. Supply GAC_NAMED_BAKED_CAPTURE={output_directory, modules}
// in the caller's private prelude. Each entry is {module, file}; filenames must
// be plain basenames. This does not load or execute any Lua closure itself.
const plan = globalThis.GAC_NAMED_BAKED_CAPTURE;
if (!plan || typeof plan.output_directory !== 'string' || !Array.isArray(plan.modules) ||
plan.modules.length < 1 || plan.modules.length > 5) throw Error('Exact bounded capture plan required');
const requested = new Map();
for (const entry of plan.modules) {
if (!/^Ui\.[A-Za-z0-9_.]+$/.test(entry.module) || !/^[a-z0-9_-]+\.luau$/.test(entry.file))
throw Error('Invalid exact module or output basename');
requested.set('@BakedLua/' + entry.module.replace(/\./g, '/') + '.bytes', entry.file);
}
const module = Process.getModuleByName('xluau.dll');
const load = module.getExportByName('xluaL_loadbuffer');
const completed = new Set();
Interceptor.attach(load, {
onEnter(args) {
try {
const name = args[3].readUtf8String();
if (!requested.has(name) || completed.has(name)) return;
const size = args[2].toUInt32();
if (size < 4 || size > 131072) throw Error('Named chunk outside capture size bound');
const bytes = args[1].readByteArray(size);
const path = plan.output_directory.replace(/[\\/]$/, '') + '/' + requested.get(name);
const output = new File(path, 'wb');
try { output.write(bytes); output.flush(); } finally { output.close(); }
completed.add(name);
send({kind:'CAPTURED', module:name, path, bytes:size});
} catch (error) { send({kind:'ERROR', error:String(error)}); }
}
});
send({kind:'ATTACHED', modules:Array.from(requested.keys()), policy:'passive exact-name loadbuffer capture; no closure execution'});