From 2b54efb604fda7b9dd12b2f3a7fa4b6b1af6237b Mon Sep 17 00:00:00 2001 From: Jose Conde Date: Tue, 16 Jul 2024 19:21:35 +0200 Subject: [PATCH] tuning --- src/game/DominoesGame.ts | 4 +- src/game/MatchSession.ts | 44 ++++++++++++---------- src/game/dto/GameSummary.ts | 7 +++- src/game/dto/MatchSessionState.ts | 3 +- src/game/dto/PlayerDto.ts | 1 + src/game/entities/player/AbstractPlayer.ts | 2 + src/server/controllers/GameController.ts | 6 +-- src/server/db/DbAdapter.ts | 29 +++++++------- src/server/db/interfaces.ts | 12 ++++-- src/server/services/SessionService.ts | 12 +++--- 10 files changed, 73 insertions(+), 47 deletions(-) diff --git a/src/game/DominoesGame.ts b/src/game/DominoesGame.ts index 20097ad..badefff 100644 --- a/src/game/DominoesGame.ts +++ b/src/game/DominoesGame.ts @@ -219,7 +219,9 @@ export class DominoesGame extends EventEmitter { isTied: this.gameTied, winner: this.winner?.getState(true), score: this.players.map(player => ({id: player.id, name: player.name, score: player.score})), - players: this.players.map(player => player.getState(true)) + players: this.players.map(player => player.getState(true)), + board: this.board.tiles.map(tile => tile.getState(true)), + boneyard: this.board.boneyard.map(tile => tile.getState(true)), } this.emit('game-over', summary); } diff --git a/src/game/MatchSession.ts b/src/game/MatchSession.ts index 95c2689..a243ea8 100644 --- a/src/game/MatchSession.ts +++ b/src/game/MatchSession.ts @@ -6,10 +6,11 @@ import { getRandomSeed, uuid, wait, whileNot } from "../common/utilities"; import { MatchSessionState } from "./dto/MatchSessionState"; import { PlayerNotificationService } from '../server/services/PlayerNotificationService'; import seedrandom, { PRNG } from "seedrandom"; -import { NetworkPlayer } from "./entities/player/NetworkPlayer"; import { PlayerHuman } from "./entities/player/PlayerHuman"; import { GameSummary } from "./dto/GameSummary"; import { PlayerMove } from "./entities/PlayerMove"; +import { SessionService } from "../server/services/SessionService"; +import { Score } from "../server/db/interfaces"; export class MatchSession { @@ -23,6 +24,7 @@ export class MatchSession { private winnerIndex: number | null = null; private clientsReady: string[] = []; private gameSummaries: GameSummary[] = []; + private sessionService: SessionService = new SessionService(); id: string; matchInProgress: boolean = false; @@ -148,22 +150,26 @@ export class MatchSession { this.setScores(gameSummary || undefined); this.checkMatchWinner(); this.resetPlayers(); - if (!this.matchInProgress) { - this.status = 'end' - this.notificationService.sendEventToPlayers('server:match-finished', this.players, { - lastGame: gameSummary, - sessionState: this.getState(true), - }); - } else { - this.status = 'waiting' - // await this.playerNotificationManager.notifyMatchState(this); - this.notificationService.sendEventToPlayers('server:game-finished', this.players, { - lastGame: gameSummary, - sessionState: this.getState(true) - }); - this.waitingForPlayers = true; - this.startGame(); - } + try { + if (!this.matchInProgress) { + this.status = 'end' + this.notificationService.sendEventToPlayers('server:match-finished', this.players, { + lastGame: gameSummary, + sessionState: this.getState(true), + }); + } else { + this.status = 'waiting' + // await this.playerNotificationManager.notifyMatchState(this); + this.notificationService.sendEventToPlayers('server:game-finished', this.players, { + lastGame: gameSummary, + sessionState: this.getState(true) + }); + this.waitingForPlayers = true; + this.startGame(); + } + } finally { + this.sessionService.updateSession(this); + } } private startGame() { @@ -327,11 +333,11 @@ export class MatchSession { }; } - getScoreBoardState() { + getScoreBoardState(): Score[] { return Array.from(this.scoreboard).map(([name, score]) => { const player = this.players.find(player => player.name === name); const id = player?.id || name; - return { id, name, score }; + return { id, name, score } as Score; }); } } \ No newline at end of file diff --git a/src/game/dto/GameSummary.ts b/src/game/dto/GameSummary.ts index 5edf262..8e7c571 100644 --- a/src/game/dto/GameSummary.ts +++ b/src/game/dto/GameSummary.ts @@ -1,10 +1,13 @@ -import { PlayerDto } from "./PlayerDto"; +import { Score } from "../../server/db/interfaces"; +import { PlayerDto, TileDto } from "./PlayerDto"; export interface GameSummary { gameId: string; isBlocked: boolean; isTied: boolean; winner: PlayerDto; - score: { id: string, name: string; score: number; }[], + score: Score[], players?: PlayerDto[]; + board: TileDto[] + boneyard: TileDto[] } \ No newline at end of file diff --git a/src/game/dto/MatchSessionState.ts b/src/game/dto/MatchSessionState.ts index 14aea07..8d5540b 100644 --- a/src/game/dto/MatchSessionState.ts +++ b/src/game/dto/MatchSessionState.ts @@ -1,3 +1,4 @@ +import { Score } from "../../server/db/interfaces"; import { GameSummary } from "./GameSummary"; import { PlayerDto } from "./PlayerDto"; @@ -15,7 +16,7 @@ export interface MatchSessionState { maxPlayers: number; numPlayers: number; waitingSeconds: number; - scoreboard: { id: string, name: string; score: number; }[]; + scoreboard: Score[]; matchWinner: PlayerDto | null; matchInProgress: boolean; playersReady: number, diff --git a/src/game/dto/PlayerDto.ts b/src/game/dto/PlayerDto.ts index c06b921..29a1bce 100644 --- a/src/game/dto/PlayerDto.ts +++ b/src/game/dto/PlayerDto.ts @@ -13,4 +13,5 @@ export interface PlayerDto { hand?: TileDto[]; teamedWith?: PlayerDto | null; ready: boolean; + isHuman: boolean; } \ No newline at end of file diff --git a/src/game/entities/player/AbstractPlayer.ts b/src/game/entities/player/AbstractPlayer.ts index 0aaedbd..6eee596 100644 --- a/src/game/entities/player/AbstractPlayer.ts +++ b/src/game/entities/player/AbstractPlayer.ts @@ -7,6 +7,7 @@ import { EventEmitter } from "stream"; import { PlayerInteractionInterface } from "../../PlayerInteractionInterface"; import { uuid } from "../../../common/utilities"; import { PlayerDto, TileDto } from "../../dto/PlayerDto"; +import { PlayerHuman } from "./PlayerHuman"; export abstract class AbstractPlayer extends EventEmitter implements PlayerInterface { hand: Tile[] = []; @@ -59,6 +60,7 @@ export abstract class AbstractPlayer extends EventEmitter implements PlayerInter hand: this.hand.map(tile => tile.getState(showPips)), teamedWith: this.teamedWith?.getState(showPips) ?? null, ready: this.ready, + isHuman: this instanceof PlayerHuman }; } } diff --git a/src/server/controllers/GameController.ts b/src/server/controllers/GameController.ts index ad07bbe..1398bc1 100644 --- a/src/server/controllers/GameController.ts +++ b/src/server/controllers/GameController.ts @@ -8,8 +8,8 @@ export class GameController extends BaseController { public async createMatch(req: Request, res: Response) { try { const { user, body } = req; - const { sessionName, seed } = body; - const sessionId = await this.sessionService.createSession(user, sessionName, seed); + const { sessionName, seed, options } = body; + const sessionId = await this.sessionService.createSession(user, sessionName, seed, options); res.status(201).json({ sessionId }); } catch (error) { this.handleError(res, error); @@ -39,7 +39,7 @@ export class GameController extends BaseController { public async getMatch(req: Request, res: Response) { try { const { sessionId } = req.params; - const session = this.sessionService.getSession(sessionId) + const session = await this.sessionService.getSession(sessionId) res.status(200).json(session); } catch (error) { this.handleError(res, error); diff --git a/src/server/db/DbAdapter.ts b/src/server/db/DbAdapter.ts index 3bed7e3..3c4f6d9 100644 --- a/src/server/db/DbAdapter.ts +++ b/src/server/db/DbAdapter.ts @@ -1,20 +1,23 @@ import { MatchSession } from "../../game/MatchSession"; import { DbMatchSession } from "./interfaces"; -export function matchSessionAdapter(session: MatchSession) : DbMatchSession { +export function matchSessionAdapter(session: MatchSession, showPips: boolean = false) : DbMatchSession { + const state = session.getState(showPips); return { - id: session.id, - name: session.name || '', - creator: session.creator.id, - players: session.players.map(player => player.id), - seed: session.seed, - mode: session.mode, - pointsToWin: session.pointsToWin, - maxPlayers: session.maxPlayers, - numPlayers: session.numPlayers, - scoreboard: Array.from(session.scoreboard.entries()).map(([player, score]) => ({ player, score })), - matchWinner: session.matchWinner ? session.matchWinner.id : null, - status: session.status + id: state.id, + name: state.name || '', + creator: state.creator, + players: state.players, + seed: state.seed, + mode: state.mode, + pointsToWin: state.pointsToWin, + maxPlayers: state.maxPlayers, + numPlayers: state.numPlayers, + scoreboard: state.scoreboard, + matchWinner: state.matchWinner, + status: state.status, + matchInProgress: state.matchInProgress, + gameSummaries: state.gameSummaries, } } \ No newline at end of file diff --git a/src/server/db/interfaces.ts b/src/server/db/interfaces.ts index ea2c93f..dda4837 100644 --- a/src/server/db/interfaces.ts +++ b/src/server/db/interfaces.ts @@ -1,3 +1,6 @@ +import { GameSummary } from "../../game/dto/GameSummary"; +import { PlayerDto } from "../../game/dto/PlayerDto"; + export interface Entity { createdAt?: number; modifiedAt?: number; @@ -10,7 +13,8 @@ export interface EntityMongo extends Entity { } export interface Score { - player: string; + id: string; + name: string; score: number; } @@ -45,15 +49,17 @@ export interface DbMatchSession extends EntityMongo { id: string; name: string; creator: string; - players: string[]; + players: PlayerDto[]; seed: string; mode: string; pointsToWin: number; maxPlayers: number; numPlayers: number; scoreboard: Score[]; - matchWinner: string | null; + matchWinner: PlayerDto | null; status: string; + matchInProgress: boolean; + gameSummaries: GameSummary[]; } export interface DbUser extends EntityMongo { diff --git a/src/server/services/SessionService.ts b/src/server/services/SessionService.ts index e42413d..db43197 100644 --- a/src/server/services/SessionService.ts +++ b/src/server/services/SessionService.ts @@ -10,7 +10,6 @@ import { MatchSessionMongoManager } from "../db/mongo/MatchSessionMongoManager"; import { SessionManager } from "../managers/SessionManager"; import { ServiceBase } from "./ServiceBase"; import { SocketIoService } from "./SocketIoService"; -import toObjectId from "../db/mongo/common/mongoUtils"; export class SessionService extends ServiceBase{ private dbManager: MatchSessionMongoManager = new MatchSessionMongoManager(); @@ -20,7 +19,7 @@ export class SessionService extends ServiceBase{ super() } - public async createSession(user: any, sessionName: string, seed: string ): Promise { + public async createSession(user: any, sessionName: string, seed: string, options: any ): Promise { let socketClient; try { socketClient = await whileNotUndefined(() => SocketIoService.getClient(user._id)); @@ -29,6 +28,7 @@ export class SessionService extends ServiceBase{ } const player = new NetworkPlayer(user._id, user.username, socketClient.socketId); const session = new MatchSession(player, sessionName, seed); + session.pointsToWin = options.pointsToWin; const dbSessionId = await this.dbManager.create(matchSessionAdapter(session)); if (dbSessionId === undefined) { throw new SessionCreationError(); @@ -82,7 +82,9 @@ export class SessionService extends ServiceBase{ return this.dbManager.update(session); } - // public updateSession(session: MatchSession): any { - // this.dbManager.replaceOne({id: session.id}, matchSessionAdapter(session)); - // } + public updateSession(session: MatchSession): any { + const entity = matchSessionAdapter(session); + entity._id = session.id + this.dbManager.update(entity); + } } \ No newline at end of file