Update Healer Man server
This commit is contained in:
1 parent
cc3b2fa4d5
commit
daa417ec17
46 files changed
+1334
-172
No files matched your search
@@ -72,7 +72,8 @@ export function createDungeonLeaderboardRepository(database, { ErrorType }) {
|
||||
if (!Array.isArray(input.killedBossIds) || input.killedBossIds.length > 100
|
||||
|| input.killedBossIds.some((id) => !difficulty.bossIds.includes(id))) fail("Provide bosses from this dungeon and difficulty.");
|
||||
const killedBossIds = [...new Set(input.killedBossIds)].sort();
|
||||
if (!killedBossIds.includes(difficulty.finalBossId)) fail("The final boss must be defeated before recording a run.");
|
||||
const finalBossIds = difficulty.finalBossIds ?? [difficulty.finalBossId];
|
||||
if (!finalBossIds.some((id) => killedBossIds.includes(id))) fail("The final boss must be defeated before recording a run.");
|
||||
if (!Array.isArray(input.party) || input.party.length < 1 || input.party.length > 5) fail("Provide the run's party.");
|
||||
const party = input.party.map((member) => {
|
||||
if (!member || typeof member !== "object" || typeof member.name !== "string" || !member.name.trim()
|
||||
@@ -84,7 +85,9 @@ export function createDungeonLeaderboardRepository(database, { ErrorType }) {
|
||||
role: member.role, npc: member.npc,
|
||||
...(member.secondaryClassId ? { secondaryClassId: member.secondaryClassId } : {}) };
|
||||
});
|
||||
const fullClear = difficulty.bossIds.every((id) => killedBossIds.includes(id));
|
||||
const fullClear = difficulty.finalBossIds
|
||||
? difficulty.finalBossIds.some((id) => killedBossIds.includes(id))
|
||||
: difficulty.bossIds.every((id) => killedBossIds.includes(id));
|
||||
const run = { id: input.id, dungeonId: dungeon.id, difficultyId, durationMs: input.durationMs,
|
||||
...(bossDifficulty > 0 ? { bossDifficulty } : {}),
|
||||
finishedAt: input.finishedAt, killedBossIds, party, fullClear };
|
||||
|
||||
@@ -58,6 +58,17 @@ test("validates final boss, dungeon/difficulty, duration and party without trust
|
||||
assert.throws(() => database.listDungeonLeaderboard({ dungeonId: "deadmines", clear: "bad" }), { status: 400 });
|
||||
assert.throws(() => database.listDungeonLeaderboard({ dungeonId: "deadmines", offset: -1 }), { status: 400 });
|
||||
}));
|
||||
test("accepts any rolled bite-sized Stockades boss as the run's full clear", () => withDatabase((database) => {
|
||||
const dungeon = catalog.dungeons.find((entry) => entry.id === "bite-sized-stormwind-stockade");
|
||||
const difficulty = dungeon.difficulties[0];
|
||||
assert.equal(difficulty.finalBossIds.length, 5);
|
||||
for (const [index, bossId] of difficulty.finalBossIds.entries()) {
|
||||
const payload = run(`bite-sized-${index}-run`, 1000 + index, false, dungeon.id);
|
||||
payload.killedBossIds = [bossId];
|
||||
assert.equal(database.submitDungeonRun(null, payload).run.fullClear, true);
|
||||
}
|
||||
assert.equal(database.listDungeonLeaderboard({ dungeonId: dungeon.id, clear: "full" }).total, 5);
|
||||
}));
|
||||
test("public HTTP leaderboards accept completion records and return results with rank while rejecting unfinished runs", async () => {
|
||||
const directory = mkdtempSync(path.join(os.tmpdir(), "healer-man-leaderboard-http-"));
|
||||
const { server } = createGameServer({ dataDir: directory, enableShelvedModes: false });
|
||||
|
||||
@@ -2,7 +2,11 @@ import { randomUUID } from "node:crypto";
|
||||
import availability from "../src/game/generated/dungeonAvailability.json" with { type: "json" };
|
||||
import policy from "../shared/dungeon-report-policy.json" with { type: "json" };
|
||||
|
||||
export const REPORT_DUNGEON_IDS = new Set(["forsaken-abbey", ...Object.keys(availability.enabled)]);
|
||||
export const REPORT_DUNGEON_IDS = new Set([
|
||||
"bite-sized-stormwind-stockade",
|
||||
"forsaken-abbey",
|
||||
...Object.keys(availability.enabled),
|
||||
]);
|
||||
|
||||
export function createDungeonReportRepository(database, { isGameMaster, ErrorType }) {
|
||||
database.exec(`
|
||||
|
||||
@@ -26,7 +26,12 @@ test("validates comments and dungeon IDs and stamps new reports as Submitted", (
|
||||
assert.equal(report.status, "Submitted");
|
||||
assert.equal(report.submittedBy, "Reporter");
|
||||
assert.equal(database.submitDungeonReport(null, { dungeonId: "forsaken-abbey", comment: " Door is stuck\r\nAfter a wipe " }).comment, "Door is stuck\nAfter a wipe");
|
||||
assert.deepEqual(database.listDungeonReports().openCounts, { "forsaken-abbey": 1, "stormwind-stockade": 1 });
|
||||
assert.equal(database.submitDungeonReport(null, { dungeonId: "bite-sized-stormwind-stockade", comment: "Wall issue" }).status, "Submitted");
|
||||
assert.deepEqual(database.listDungeonReports().openCounts, {
|
||||
"bite-sized-stormwind-stockade": 1,
|
||||
"forsaken-abbey": 1,
|
||||
"stormwind-stockade": 1,
|
||||
});
|
||||
}));
|
||||
|
||||
test("enforces GM updates, counts all open statuses, supports reopening, and prevents stale changes", () => withDatabase(async (database) => {
|
||||
|
||||
Reference in new issue
Block a user