import * as e from './extract.mjs'; import * as s from './stages.mjs'; import {table_bindings} from './rounds.mjs'; // Client tables behind node rewards (bonus rules -> basic / combination / random // bonus pools), Encounter (elite branch) options and the Plot Armor (SpotLight) // recommendations. Every table is decoded byte-exactly; nothing is derived here. export const TYPES = [ 'GridFightBasicBonusConfigRow', 'GridFightCombinationBonusConfigRow', 'GridFightRandomBonusPoolConfigRow', 'GridFightVictoryBonusConfigRow', 'GridFightRoleRecomSpotLightConfigRow', 'GridFightSpotLightTagConfigRow' ]; export function main() { const a = e.cli(['client', 'dump', 'identity', 'literals', 'output']); const ctx = s.extractionContext(a); const literals = new Map(e.loadJSON(a.literals).map(r => [Number(BigInt(r.Address)), r.Value])); const tables = {}, proofs = []; for (const name of TYPES) { const assets = table_bindings(ctx.codec, literals, 'RPG.GameCore.' + name, null); tables[name] = []; for (const asset of assets) { const match = asset.match(/^BakedConfig\/ExcelOutput(GameCore)?\/(\w+)\.bytes$/); if (!match) e.fail('Unsupported table path: ' + asset); const [rows, proof] = s.table(ctx.assets, ctx.codec, name, match[1] ?? '', match[2]); tables[name].push(...rows); proofs.push(proof); console.log(`${name}: ${rows.length} byte-exact rows`); } } s.publish(a, ctx, tables, proofs, {'bonus.raw.json': tables}, 'bonus', {gameplay_verified: false}); } e.runMain(import.meta.url, main);