Building but users still not listing
This commit is contained in:
parent
abdd6bca83
commit
1e16bb0ef6
@ -4,8 +4,7 @@
|
|||||||
* without requiring immediate refactoring of all game logic
|
* without requiring immediate refactoring of all game logic
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { GameRoom, GameSession, GameSessionMetadata } from './gameMetadata';
|
import type { GameRoom, GameSession, GameSessionMetadata } from "./gameMetadata";
|
||||||
import type { Session } from '../room/types';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxy handler for Session objects
|
* Proxy handler for Session objects
|
||||||
@ -15,13 +14,13 @@ import type { Session } from '../room/types';
|
|||||||
const sessionProxyHandler: ProxyHandler<GameSession> = {
|
const sessionProxyHandler: ProxyHandler<GameSession> = {
|
||||||
get(target: GameSession, prop: string | symbol): any {
|
get(target: GameSession, prop: string | symbol): any {
|
||||||
// Direct properties take precedence
|
// Direct properties take precedence
|
||||||
if (prop in target && prop !== 'metadata') {
|
if (prop in target && prop !== "metadata") {
|
||||||
return (target as any)[prop];
|
return (target as any)[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map game-specific properties to metadata
|
// Map game-specific properties to metadata
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === "string") {
|
||||||
const gameProps = ['color', 'player', 'resources'];
|
const gameProps = ["color", "player", "resources"];
|
||||||
if (gameProps.includes(prop)) {
|
if (gameProps.includes(prop)) {
|
||||||
return target.metadata?.[prop as keyof GameSessionMetadata];
|
return target.metadata?.[prop as keyof GameSessionMetadata];
|
||||||
}
|
}
|
||||||
@ -33,20 +32,33 @@ const sessionProxyHandler: ProxyHandler<GameSession> = {
|
|||||||
set(target: GameSession, prop: string | symbol, value: any): boolean {
|
set(target: GameSession, prop: string | symbol, value: any): boolean {
|
||||||
// Direct properties
|
// Direct properties
|
||||||
const directProps = [
|
const directProps = [
|
||||||
'id', 'userId', 'name', 'ws', 'live', 'lastActive', 'keepAlive',
|
"id",
|
||||||
'connected', 'has_media', 'protected', 'bot_run_id', 'bot_provider_id',
|
"userId",
|
||||||
'bot_instance_id', '_initialSnapshotSent', '_getBatch', '_pendingMessage',
|
"name",
|
||||||
'_pendingTimeout'
|
"ws",
|
||||||
|
"live",
|
||||||
|
"lastActive",
|
||||||
|
"keepAlive",
|
||||||
|
"connected",
|
||||||
|
"has_media",
|
||||||
|
"protected",
|
||||||
|
"bot_run_id",
|
||||||
|
"bot_provider_id",
|
||||||
|
"bot_instance_id",
|
||||||
|
"_initialSnapshotSent",
|
||||||
|
"_getBatch",
|
||||||
|
"_pendingMessage",
|
||||||
|
"_pendingTimeout",
|
||||||
];
|
];
|
||||||
|
|
||||||
if (typeof prop === 'string' && directProps.includes(prop)) {
|
if (typeof prop === "string" && directProps.includes(prop)) {
|
||||||
(target as any)[prop] = value;
|
(target as any)[prop] = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game-specific properties go to metadata
|
// Game-specific properties go to metadata
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === "string") {
|
||||||
const gameProps = ['color', 'player', 'resources'];
|
const gameProps = ["color", "player", "resources"];
|
||||||
if (gameProps.includes(prop)) {
|
if (gameProps.includes(prop)) {
|
||||||
if (!target.metadata) {
|
if (!target.metadata) {
|
||||||
target.metadata = {};
|
target.metadata = {};
|
||||||
@ -63,8 +75,8 @@ const sessionProxyHandler: ProxyHandler<GameSession> = {
|
|||||||
|
|
||||||
has(target: GameSession, prop: string | symbol): boolean {
|
has(target: GameSession, prop: string | symbol): boolean {
|
||||||
if (prop in target) return true;
|
if (prop in target) return true;
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === "string") {
|
||||||
const gameProps = ['color', 'player', 'resources'];
|
const gameProps = ["color", "player", "resources"];
|
||||||
return gameProps.includes(prop) && target.metadata !== undefined;
|
return gameProps.includes(prop) && target.metadata !== undefined;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -78,13 +90,13 @@ const sessionProxyHandler: ProxyHandler<GameSession> = {
|
|||||||
const gameProxyHandler: ProxyHandler<GameRoom> = {
|
const gameProxyHandler: ProxyHandler<GameRoom> = {
|
||||||
get(target: GameRoom, prop: string | symbol): any {
|
get(target: GameRoom, prop: string | symbol): any {
|
||||||
// Direct room properties
|
// Direct room properties
|
||||||
const roomProps = ['id', 'name', 'sessions', 'state', 'created', 'lastActivity', 'private'];
|
const roomProps = ["id", "name", "sessions", "state", "created", "lastActivity", "private"];
|
||||||
if (typeof prop === 'string' && roomProps.includes(prop)) {
|
if (typeof prop === "string" && roomProps.includes(prop)) {
|
||||||
return (target as any)[prop];
|
return (target as any)[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game properties from metadata
|
// Game properties from metadata
|
||||||
if (typeof prop === 'string' && target.metadata) {
|
if (typeof prop === "string" && target.metadata) {
|
||||||
if (prop in target.metadata) {
|
if (prop in target.metadata) {
|
||||||
return (target.metadata as any)[prop];
|
return (target.metadata as any)[prop];
|
||||||
}
|
}
|
||||||
@ -95,14 +107,14 @@ const gameProxyHandler: ProxyHandler<GameRoom> = {
|
|||||||
|
|
||||||
set(target: GameRoom, prop: string | symbol, value: any): boolean {
|
set(target: GameRoom, prop: string | symbol, value: any): boolean {
|
||||||
// Direct room properties
|
// Direct room properties
|
||||||
const roomProps = ['id', 'name', 'sessions', 'state', 'created', 'lastActivity', 'private'];
|
const roomProps = ["id", "name", "sessions", "state", "created", "lastActivity", "private"];
|
||||||
if (typeof prop === 'string' && roomProps.includes(prop)) {
|
if (typeof prop === "string" && roomProps.includes(prop)) {
|
||||||
(target as any)[prop] = value;
|
(target as any)[prop] = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game properties to metadata
|
// Game properties to metadata
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === "string") {
|
||||||
if (!target.metadata) {
|
if (!target.metadata) {
|
||||||
target.metadata = {} as any;
|
target.metadata = {} as any;
|
||||||
}
|
}
|
||||||
@ -115,8 +127,8 @@ const gameProxyHandler: ProxyHandler<GameRoom> = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
has(target: GameRoom, prop: string | symbol): boolean {
|
has(target: GameRoom, prop: string | symbol): boolean {
|
||||||
const roomProps = ['id', 'name', 'sessions', 'state', 'created', 'lastActivity', 'private'];
|
const roomProps = ["id", "name", "sessions", "state", "created", "lastActivity", "private"];
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === "string") {
|
||||||
if (roomProps.includes(prop)) return true;
|
if (roomProps.includes(prop)) return true;
|
||||||
if (target.metadata && prop in target.metadata) return true;
|
if (target.metadata && prop in target.metadata) return true;
|
||||||
}
|
}
|
||||||
@ -147,8 +159,10 @@ export function wrapGameSessions(game: GameRoom): GameRoom {
|
|||||||
// Wrap each session
|
// Wrap each session
|
||||||
const wrappedSessions: Record<string, GameSession> = {};
|
const wrappedSessions: Record<string, GameSession> = {};
|
||||||
for (const id in game.sessions) {
|
for (const id in game.sessions) {
|
||||||
|
if (game.sessions[id]) {
|
||||||
wrappedSessions[id] = wrapSession(game.sessions[id]);
|
wrappedSessions[id] = wrapSession(game.sessions[id]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wrappedGame.sessions = wrappedSessions;
|
wrappedGame.sessions = wrappedSessions;
|
||||||
return wrappedGame;
|
return wrappedGame;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* These extend the base Room/Session types with Settlers of Catan specific data
|
* These extend the base Room/Session types with Settlers of Catan specific data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Player, Turn, Placements, DevelopmentCard } from './types';
|
import type { Player, Turn, Placements, DevelopmentCard } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Game-specific session metadata
|
* Game-specific session metadata
|
||||||
@ -163,7 +163,7 @@ export function migrateGameToRoomFormat(oldGame: any): GameRoom {
|
|||||||
id: oldGame.id,
|
id: oldGame.id,
|
||||||
name: oldGame.id, // Game ID is the room name
|
name: oldGame.id, // Game ID is the room name
|
||||||
sessions: newSessions,
|
sessions: newSessions,
|
||||||
state: oldGame.state || 'lobby',
|
state: oldGame.state || "lobby",
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
lastActivity: Date.now(),
|
lastActivity: Date.now(),
|
||||||
private: false,
|
private: false,
|
||||||
@ -180,8 +180,10 @@ export function migrateRoomToGameFormat(room: GameRoom): any {
|
|||||||
// Convert sessions back
|
// Convert sessions back
|
||||||
const oldSessions: Record<string, any> = {};
|
const oldSessions: Record<string, any> = {};
|
||||||
for (const sessionId in sessions) {
|
for (const sessionId in sessions) {
|
||||||
|
if (sessions[sessionId]) {
|
||||||
oldSessions[sessionId] = migrateSessionToOldFormat(sessions[sessionId]);
|
oldSessions[sessionId] = migrateSessionToOldFormat(sessions[sessionId]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...roomFields,
|
...roomFields,
|
||||||
|
@ -167,3 +167,22 @@ export const setForSettlementPlacement = (game: Game, limits: number[] | undefin
|
|||||||
game.turn.actions = ["place-settlement"];
|
game.turn.actions = ["place-settlement"];
|
||||||
game.turn.limits = { corners: limits };
|
game.turn.limits = { corners: limits };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Adjust a player's resource counts by a deltas map. Deltas may be negative.
|
||||||
|
export const adjustResources = (player: Player, deltas: Partial<Record<string, number>>): void => {
|
||||||
|
if (!player) return;
|
||||||
|
let total = player.resources || 0;
|
||||||
|
const keys = Object.keys(deltas || {});
|
||||||
|
keys.forEach((k) => {
|
||||||
|
const v = deltas[k] || 0;
|
||||||
|
// update named resource slot if present
|
||||||
|
try {
|
||||||
|
const current = (player as any)[k] || 0;
|
||||||
|
(player as any)[k] = current + v;
|
||||||
|
total += v;
|
||||||
|
} catch (e) {
|
||||||
|
// ignore unexpected keys
|
||||||
|
}
|
||||||
|
});
|
||||||
|
player.resources = total;
|
||||||
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export type ResourceKey = "wood" | "brick" | "sheep" | "wheat" | "stone";
|
export type ResourceKey = "wood" | "brick" | "sheep" | "wheat" | "stone";
|
||||||
|
|
||||||
export type ResourceMap = Partial<Record<ResourceKey, number>> & { [k: string]: any };
|
export type ResourceMap = Partial<Record<ResourceKey, number>>;
|
||||||
|
|
||||||
export interface Player {
|
export interface Player {
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -124,7 +124,7 @@ export interface Game {
|
|||||||
turn: Turn;
|
turn: Turn;
|
||||||
pipOrder?: number[];
|
pipOrder?: number[];
|
||||||
tileOrder?: number[];
|
tileOrder?: number[];
|
||||||
borderOrder?: number[];
|
resources?: number;
|
||||||
tiles?: any[];
|
tiles?: any[];
|
||||||
pips?: any[];
|
pips?: any[];
|
||||||
dice?: number[];
|
dice?: number[];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user