feat: Add scripts for mob dependency management and server setup

- Implemented `findMobDependencies.ts` to identify foreign key constraints referencing the Mob table and log dependent rows.
- Created `fullServerSetup.ts` for idempotent server setup, including economy items, item recipes, game areas, mobs, and optional demo mob attacks.
- Developed `removeInvalidMobsWithDeps.ts` to delete invalid mobs and their dependencies, backing up affected scheduled mob attacks.
- Added unit tests in `testMobUnit.ts` and `mob.test.ts` for mob functionality, including stats computation and instance retrieval.
- Introduced reward modification tests in `testRewardMods.ts` and `rewardMods.unit.ts` to validate drop selection and coin multiplier behavior.
- Enhanced command handling for mob deletion in `mobDelete.ts` and setup examples in `setup.ts`, ensuring proper permissions and feedback.
- Created utility functions in `testHelpers.ts` for deterministic drop selection from mob definitions.
This commit is contained in:
Shni
2025-10-14 14:58:38 -05:00
parent f36fa24e46
commit 852b1d02a2
24 changed files with 2158 additions and 177 deletions

View File

@@ -0,0 +1,80 @@
import fs from "fs";
import { prisma } from "../src/core/database/prisma";
async function run() {
if (!process.env.XATA_DB) {
console.error("XATA_DB not set — aborting");
process.exit(1);
}
if (!fs.existsSync("invalid_mobs_backup.json")) {
console.error("invalid_mobs_backup.json not found — run cleanup first");
process.exit(1);
}
const bak = JSON.parse(fs.readFileSync("invalid_mobs_backup.json", "utf8"));
const ids: string[] = bak.map((b: any) => b.id).filter(Boolean);
if (ids.length === 0) {
console.log("No ids found in invalid_mobs_backup.json");
return;
}
console.log("Looking for FK constraints that reference the Mob table...");
const fkSql = `
SELECT
tc.constraint_name, kcu.table_name, kcu.column_name, ccu.table_name AS referenced_table, ccu.column_name AS referenced_column
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name AND tc.constraint_schema = kcu.constraint_schema
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name AND ccu.constraint_schema = tc.constraint_schema
WHERE tc.constraint_type = 'FOREIGN KEY' AND LOWER(ccu.table_name) = 'mob'
`;
const refs: any[] = await (prisma as any).$queryRawUnsafe(fkSql);
if (!refs || refs.length === 0) {
console.log("No FK constraints found referencing mob table.");
return;
}
console.log("Found referencing constraints:");
for (const r of refs) {
console.log(
` - ${r.table_name}.${r.column_name} -> ${r.referenced_table}.${r.referenced_column} (constraint ${r.constraint_name})`
);
}
// For each referencing table/column, search rows that use our ids
for (const r of refs) {
const table = r.table_name;
const column = r.column_name;
console.log(
`\nChecking table ${table} (column ${column}) for dependent rows...`
);
for (const id of ids) {
try {
const cntRes: any[] = await (prisma as any).$queryRawUnsafe(
`SELECT COUNT(*) AS cnt FROM "${table}" WHERE "${column}" = '${id}'`
);
const cnt =
cntRes && cntRes[0]
? Number(cntRes[0].cnt || cntRes[0].count || 0)
: 0;
console.log(` mob id=${id} -> ${cnt} dependent row(s)`);
if (cnt > 0) {
const rows: any[] = await (prisma as any).$queryRawUnsafe(
`SELECT * FROM "${table}" WHERE "${column}" = '${id}' LIMIT 5`
);
console.log(" Sample rows:", rows);
}
} catch (e) {
console.warn(" Failed to query", table, column, e?.message ?? e);
}
}
}
console.log("\nDependency scan complete.");
}
run().catch((e) => {
console.error(e);
process.exit(1);
});