generated from nhcarrigan/template
fix: create fresh game state when no save record exists
Replaces the 404 response with a fresh INITIAL_GAME_STATE seeded from the player's existing Player record. Handles the v1 GameState nuke gracefully — returning players get a clean slate instead of an error.
This commit is contained in:
@@ -10,7 +10,7 @@ import { DEFAULT_BOSSES } from "../data/bosses.js";
|
|||||||
import { DEFAULT_EQUIPMENT } from "../data/equipment.js";
|
import { DEFAULT_EQUIPMENT } from "../data/equipment.js";
|
||||||
import { DEFAULT_EQUIPMENT_SETS } from "../data/equipmentSets.js";
|
import { DEFAULT_EQUIPMENT_SETS } from "../data/equipmentSets.js";
|
||||||
import { DEFAULT_EXPLORATIONS } from "../data/explorations.js";
|
import { DEFAULT_EXPLORATIONS } from "../data/explorations.js";
|
||||||
import { INITIAL_EXPLORATION } from "../data/initialState.js";
|
import { INITIAL_EXPLORATION, INITIAL_GAME_STATE } from "../data/initialState.js";
|
||||||
import { DAILY_REWARDS } from "../data/loginBonus.js";
|
import { DAILY_REWARDS } from "../data/loginBonus.js";
|
||||||
import { DEFAULT_QUESTS } from "../data/quests.js";
|
import { DEFAULT_QUESTS } from "../data/quests.js";
|
||||||
import { authMiddleware } from "../middleware/auth.js";
|
import { authMiddleware } from "../middleware/auth.js";
|
||||||
@@ -364,7 +364,37 @@ gameRouter.get("/load", async (context) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if (!record) {
|
if (!record) {
|
||||||
return context.json({ error: "No save found" }, 404);
|
// No save found — create a fresh state (handles nuked DB or first-time load race)
|
||||||
|
if (!playerRecord) {
|
||||||
|
return context.json({ error: "No player found" }, 404);
|
||||||
|
}
|
||||||
|
const freshState = INITIAL_GAME_STATE(
|
||||||
|
{
|
||||||
|
discordId: playerRecord.discordId,
|
||||||
|
username: playerRecord.username,
|
||||||
|
discriminator: playerRecord.discriminator,
|
||||||
|
avatar: playerRecord.avatar,
|
||||||
|
characterName: playerRecord.characterName,
|
||||||
|
createdAt: playerRecord.createdAt,
|
||||||
|
lastSavedAt: Date.now(),
|
||||||
|
totalGoldEarned: 0,
|
||||||
|
totalClicks: 0,
|
||||||
|
lifetimeGoldEarned: playerRecord.lifetimeGoldEarned,
|
||||||
|
lifetimeClicks: playerRecord.lifetimeClicks,
|
||||||
|
lifetimeBossesDefeated: playerRecord.lifetimeBossesDefeated,
|
||||||
|
lifetimeQuestsCompleted: playerRecord.lifetimeQuestsCompleted,
|
||||||
|
lifetimeAdventurersRecruited: playerRecord.lifetimeAdventurersRecruited,
|
||||||
|
lifetimeAchievementsUnlocked: playerRecord.lifetimeAchievementsUnlocked,
|
||||||
|
},
|
||||||
|
playerRecord.characterName,
|
||||||
|
);
|
||||||
|
const createdAt = Date.now();
|
||||||
|
await prisma.gameState.create({
|
||||||
|
data: { discordId, state: freshState as object, updatedAt: createdAt },
|
||||||
|
});
|
||||||
|
const secret = process.env.ANTI_CHEAT_SECRET;
|
||||||
|
const signature = secret ? computeHmac(JSON.stringify(freshState), secret) : undefined;
|
||||||
|
return context.json({ state: freshState, offlineGold: 0, offlineEssence: 0, offlineSeconds: 0, signature, loginBonus: null, loginStreak: playerRecord.loginStreak ?? 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = record.state as unknown as GameState;
|
const state = record.state as unknown as GameState;
|
||||||
|
|||||||
Reference in New Issue
Block a user