// Downloads a rig's managed assemblies (RustDedicated_Data/Managed/*.dll) into a local directory, // for tools/fieldlist, which reads Rust's own field declarations from them (D232). // // node tools/managed.js // // Use the CARBON rig. Oxide's patcher rewrites Assembly-CSharp.dll and makes private fields public, // so the Oxide rig's copy no longer says which fields Rust itself serialises. Carbon leaves the // assembly as Facepunch shipped it. const fs = require('fs') const path = require('path') const { load, serverId, unmsys } = require('./panel') const config = load() const [rig, out] = process.argv.slice(2).map(unmsys) if (!rig || !out) { console.error('usage: node tools/managed.js ') process.exit(2) } const base = `${config.panel}/api/client/servers/${serverId(config, rig)}` const headers = { Authorization: 'Bearer ' + config.key, Accept: 'application/json' } const dir = '/RustDedicated_Data/Managed' async function main() { const list = await fetch(`${base}/files/list?directory=${encodeURIComponent(dir)}`, { headers }) if (!list.ok) throw new Error(`list ${list.status}: ${await list.text()}`) const files = (await list.json()).data .map((f) => f.attributes) .filter((f) => f.is_file && f.name.endsWith('.dll')) fs.mkdirSync(out, { recursive: true }) let bytes = 0 for (const f of files) { const target = path.join(out, f.name) if (fs.existsSync(target) && fs.statSync(target).size === f.size) continue const link = await fetch(`${base}/files/download?file=${encodeURIComponent(`${dir}/${f.name}`)}`, { headers }) if (!link.ok) throw new Error(`${f.name}: ${link.status} ${await link.text()}`) const body = await fetch((await link.json()).attributes.url) fs.writeFileSync(target, Buffer.from(await body.arrayBuffer())) bytes += f.size } console.log(`${files.length} assemblies in ${out} (${(bytes / 1e6).toFixed(1)} MB downloaded)`) } main().catch((e) => { console.error(e.message || e) process.exit(1) })