diff --git a/server/routes/games.ts b/server/routes/games.ts index 89496c1..d77429d 100755 --- a/server/routes/games.ts +++ b/server/routes/games.ts @@ -11,6 +11,8 @@ import basePath from '../basepath'; import { getValidRoads, getValidCorners, isRuleEnabled } from '../util/validLocations.js'; import { Player } from './games/types.js'; import { normalizeIncoming, shuffleArray } from './games/utils.js'; +import type { GameState } from './games/state.js'; +import { serializeGame, deserializeGame, cloneGame } from './games/serialize.js'; const router = express.Router(); diff --git a/server/routes/games/serialize.ts b/server/routes/games/serialize.ts new file mode 100644 index 0000000..71c1b29 --- /dev/null +++ b/server/routes/games/serialize.ts @@ -0,0 +1,19 @@ +import type { GameState } from './state.js'; + +export function serializeGame(game: GameState): string { + // Use a deterministic JSON serializer for snapshots; currently use JSON.stringify + return JSON.stringify(game); +} + +export function deserializeGame(serialized: string): GameState { + try { + return JSON.parse(serialized) as GameState; + } catch (e) { + // If parsing fails, return a minimal empty game state to avoid crashes + return { players: [], placements: { corners: [], roads: [] } } as GameState; + } +} + +export function cloneGame(game: GameState): GameState { + return deserializeGame(serializeGame(game)); +} diff --git a/server/routes/games/state.ts b/server/routes/games/state.ts new file mode 100644 index 0000000..a2c59cb --- /dev/null +++ b/server/routes/games/state.ts @@ -0,0 +1,34 @@ +import { Player } from './types.js'; + +export interface PlacementCorner { + color?: string | null; + type?: string | null; // settlement/city + data?: any; +} + +export interface PlacementRoad { + color?: string | null; + data?: any; +} + +export interface Placements { + corners: PlacementCorner[]; + roads: PlacementRoad[]; +} + +export interface GameState { + id?: string | number; + name?: string; + players: Player[]; + placements: Placements; + rules?: Record; + state?: string; + robber?: number; + turn?: number; + history?: any[]; + createdAt?: string; + [key: string]: any; +} + +export type GameId = string | number; +