Auto-re-parse game data when parser version changes
All checks were successful
Deploy / deploy (push) Successful in 2m13s
All checks were successful
Deploy / deploy (push) Successful in 2m13s
The first-boot parse only ran on an empty DB, so deploying a parser fix left existing rows stale (e.g. enchanted ingredients still flat T6). Add PARSER_VERSION, stored in meta on parse; on boot the server re-parses when the stored version differs, auto-healing existing data after a deploy — no manual "Re-download game data" needed. Bumped to v2 for the enchanted-ingredient id fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7ed585d6a9
commit
9cd17d0934
2 changed files with 31 additions and 13 deletions
|
|
@ -8,6 +8,14 @@ import { gamedataFilePath } from './download.js';
|
|||
* attributes appear as "@name" keys, and any child element may be an object or an array).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bump whenever the parsing logic changes in a way that alters stored items/recipes.
|
||||
* The server re-parses on boot when the DB's stored version differs, so a deploy that
|
||||
* fixes parsing auto-heals existing data without a manual "re-download".
|
||||
* v2: enchanted resource/ingredient ids carry @<enchant> (e.g. T6_SHOES_PLATE_SET1@4)
|
||||
*/
|
||||
export const PARSER_VERSION = 2;
|
||||
|
||||
type Raw = Record<string, any>;
|
||||
|
||||
function asArray<T>(v: T | T[] | undefined | null): T[] {
|
||||
|
|
@ -246,6 +254,7 @@ export async function parseGameData(): Promise<ParseStats> {
|
|||
};
|
||||
await setMeta('gamedata_parsed_at', new Date().toISOString());
|
||||
await setMeta('gamedata_stats', JSON.stringify(stats));
|
||||
await setMeta('gamedata_parser_version', String(PARSER_VERSION));
|
||||
cacheClear(); // items/recipes changed → drop every cached read
|
||||
return stats;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,22 +26,31 @@ const app = Fastify({ logger: { level: 'info' } });
|
|||
|
||||
await initDb(); // create schema on startup
|
||||
|
||||
// First-boot convenience: if no game data is loaded yet, download + parse it in
|
||||
// the background so a fresh deployment is usable without a manual step.
|
||||
// On boot: (re)parse game data if the DB is empty OR was parsed by an older parser
|
||||
// version — so a deploy that fixes parsing auto-heals existing data. Runs in the
|
||||
// background so it doesn't block startup.
|
||||
void (async () => {
|
||||
try {
|
||||
const { get } = await import('./db/index.js');
|
||||
const row = await get<{ n: number }>('SELECT COUNT(*) AS n FROM items');
|
||||
if ((row?.n ?? 0) === 0) {
|
||||
app.log.info('No game data found — downloading and parsing (first boot)...');
|
||||
const { get, getMeta } = await import('./db/index.js');
|
||||
const { PARSER_VERSION, parseGameData } = await import('./gamedata/parse.js');
|
||||
const { downloadGameData } = await import('./gamedata/download.js');
|
||||
const { parseGameData } = await import('./gamedata/parse.js');
|
||||
await downloadGameData(false);
|
||||
|
||||
const count = (await get<{ n: number }>('SELECT COUNT(*) AS n FROM items'))?.n ?? 0;
|
||||
const storedVersion = Number((await getMeta('gamedata_parser_version')) ?? 0);
|
||||
const empty = count === 0;
|
||||
const stale = storedVersion !== PARSER_VERSION;
|
||||
if (!empty && !stale) return;
|
||||
|
||||
app.log.info(
|
||||
empty
|
||||
? 'No game data found — downloading and parsing (first boot)...'
|
||||
: `Game data parsed by an older version (v${storedVersion} → v${PARSER_VERSION}) — re-parsing...`,
|
||||
);
|
||||
await downloadGameData(false); // uses cached files if already present
|
||||
const stats = await parseGameData();
|
||||
app.log.info(`Game data loaded: ${stats.items} items, ${stats.recipes} recipes.`);
|
||||
}
|
||||
} catch (e) {
|
||||
app.log.error(`First-boot game data load failed: ${e instanceof Error ? e.message : e}`);
|
||||
app.log.error(`Startup game data load failed: ${e instanceof Error ? e.message : e}`);
|
||||
}
|
||||
})();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue