tuning
This commit is contained in:
		@@ -219,7 +219,9 @@ export class DominoesGame extends EventEmitter {
 | 
				
			|||||||
      isTied: this.gameTied,
 | 
					      isTied: this.gameTied,
 | 
				
			||||||
      winner: this.winner?.getState(true),
 | 
					      winner: this.winner?.getState(true),
 | 
				
			||||||
      score: this.players.map(player => ({id: player.id, name: player.name, score: player.score})),
 | 
					      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);
 | 
					    this.emit('game-over', summary);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,10 +6,11 @@ import { getRandomSeed, uuid, wait, whileNot } from "../common/utilities";
 | 
				
			|||||||
import { MatchSessionState } from "./dto/MatchSessionState";
 | 
					import { MatchSessionState } from "./dto/MatchSessionState";
 | 
				
			||||||
import { PlayerNotificationService } from '../server/services/PlayerNotificationService';
 | 
					import { PlayerNotificationService } from '../server/services/PlayerNotificationService';
 | 
				
			||||||
import seedrandom, { PRNG } from "seedrandom";
 | 
					import seedrandom, { PRNG } from "seedrandom";
 | 
				
			||||||
import { NetworkPlayer } from "./entities/player/NetworkPlayer";
 | 
					 | 
				
			||||||
import { PlayerHuman } from "./entities/player/PlayerHuman";
 | 
					import { PlayerHuman } from "./entities/player/PlayerHuman";
 | 
				
			||||||
import { GameSummary } from "./dto/GameSummary";
 | 
					import { GameSummary } from "./dto/GameSummary";
 | 
				
			||||||
import { PlayerMove } from "./entities/PlayerMove";
 | 
					import { PlayerMove } from "./entities/PlayerMove";
 | 
				
			||||||
 | 
					import { SessionService } from "../server/services/SessionService";
 | 
				
			||||||
 | 
					import { Score } from "../server/db/interfaces";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class MatchSession {
 | 
					export class MatchSession {
 | 
				
			||||||
@@ -23,6 +24,7 @@ export class MatchSession {
 | 
				
			|||||||
  private winnerIndex: number | null = null;
 | 
					  private winnerIndex: number | null = null;
 | 
				
			||||||
  private clientsReady: string[] = [];
 | 
					  private clientsReady: string[] = [];
 | 
				
			||||||
  private gameSummaries: GameSummary[] = [];
 | 
					  private gameSummaries: GameSummary[] = [];
 | 
				
			||||||
 | 
					  private sessionService: SessionService = new SessionService();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  id: string;
 | 
					  id: string;
 | 
				
			||||||
  matchInProgress: boolean = false;
 | 
					  matchInProgress: boolean = false;
 | 
				
			||||||
@@ -148,6 +150,7 @@ export class MatchSession {
 | 
				
			|||||||
    this.setScores(gameSummary || undefined);
 | 
					    this.setScores(gameSummary || undefined);
 | 
				
			||||||
    this.checkMatchWinner();
 | 
					    this.checkMatchWinner();
 | 
				
			||||||
    this.resetPlayers();
 | 
					    this.resetPlayers();
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
      if (!this.matchInProgress) {
 | 
					      if (!this.matchInProgress) {
 | 
				
			||||||
        this.status = 'end'
 | 
					        this.status = 'end'
 | 
				
			||||||
        this.notificationService.sendEventToPlayers('server:match-finished', this.players, {
 | 
					        this.notificationService.sendEventToPlayers('server:match-finished', this.players, {
 | 
				
			||||||
@@ -164,6 +167,9 @@ export class MatchSession {
 | 
				
			|||||||
        this.waitingForPlayers = true; 
 | 
					        this.waitingForPlayers = true; 
 | 
				
			||||||
        this.startGame();
 | 
					        this.startGame();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    } finally {      
 | 
				
			||||||
 | 
					      this.sessionService.updateSession(this);
 | 
				
			||||||
 | 
					    }  
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private startGame() {
 | 
					  private startGame() {
 | 
				
			||||||
@@ -327,11 +333,11 @@ export class MatchSession {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getScoreBoardState() {
 | 
					  getScoreBoardState(): Score[] {
 | 
				
			||||||
    return Array.from(this.scoreboard).map(([name, score]) => {
 | 
					    return Array.from(this.scoreboard).map(([name, score]) => {
 | 
				
			||||||
      const player = this.players.find(player => player.name === name);
 | 
					      const player = this.players.find(player => player.name === name);
 | 
				
			||||||
      const id = player?.id || name;
 | 
					      const id = player?.id || name;
 | 
				
			||||||
      return { id, name, score };
 | 
					      return { id, name, score } as Score;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,10 +1,13 @@
 | 
				
			|||||||
import { PlayerDto } from "./PlayerDto";
 | 
					import { Score } from "../../server/db/interfaces";
 | 
				
			||||||
 | 
					import { PlayerDto, TileDto } from "./PlayerDto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface GameSummary {
 | 
					export interface GameSummary {
 | 
				
			||||||
  gameId: string;
 | 
					  gameId: string;
 | 
				
			||||||
  isBlocked: boolean;
 | 
					  isBlocked: boolean;
 | 
				
			||||||
  isTied: boolean;
 | 
					  isTied: boolean;
 | 
				
			||||||
  winner: PlayerDto;
 | 
					  winner: PlayerDto;
 | 
				
			||||||
  score: { id: string, name: string; score: number; }[],
 | 
					  score: Score[],
 | 
				
			||||||
  players?: PlayerDto[];
 | 
					  players?: PlayerDto[];
 | 
				
			||||||
 | 
					  board: TileDto[]
 | 
				
			||||||
 | 
					  boneyard: TileDto[]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import { Score } from "../../server/db/interfaces";
 | 
				
			||||||
import { GameSummary } from "./GameSummary";
 | 
					import { GameSummary } from "./GameSummary";
 | 
				
			||||||
import { PlayerDto } from "./PlayerDto";
 | 
					import { PlayerDto } from "./PlayerDto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,7 +16,7 @@ export interface MatchSessionState {
 | 
				
			|||||||
  maxPlayers: number;
 | 
					  maxPlayers: number;
 | 
				
			||||||
  numPlayers: number;
 | 
					  numPlayers: number;
 | 
				
			||||||
  waitingSeconds: number;
 | 
					  waitingSeconds: number;
 | 
				
			||||||
  scoreboard: { id: string, name: string; score: number; }[];
 | 
					  scoreboard: Score[];
 | 
				
			||||||
  matchWinner: PlayerDto | null;
 | 
					  matchWinner: PlayerDto | null;
 | 
				
			||||||
  matchInProgress: boolean;
 | 
					  matchInProgress: boolean;
 | 
				
			||||||
  playersReady: number,
 | 
					  playersReady: number,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,4 +13,5 @@ export interface PlayerDto {
 | 
				
			|||||||
  hand?: TileDto[];
 | 
					  hand?: TileDto[];
 | 
				
			||||||
  teamedWith?: PlayerDto | null;
 | 
					  teamedWith?: PlayerDto | null;
 | 
				
			||||||
  ready: boolean;
 | 
					  ready: boolean;
 | 
				
			||||||
 | 
					  isHuman: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -7,6 +7,7 @@ import { EventEmitter } from "stream";
 | 
				
			|||||||
import { PlayerInteractionInterface } from "../../PlayerInteractionInterface";
 | 
					import { PlayerInteractionInterface } from "../../PlayerInteractionInterface";
 | 
				
			||||||
import { uuid } from "../../../common/utilities";
 | 
					import { uuid } from "../../../common/utilities";
 | 
				
			||||||
import { PlayerDto, TileDto } from "../../dto/PlayerDto";
 | 
					import { PlayerDto, TileDto } from "../../dto/PlayerDto";
 | 
				
			||||||
 | 
					import { PlayerHuman } from "./PlayerHuman";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class AbstractPlayer extends EventEmitter implements PlayerInterface {
 | 
					export abstract class AbstractPlayer extends EventEmitter implements PlayerInterface {
 | 
				
			||||||
  hand: Tile[] = [];
 | 
					  hand: Tile[] = [];
 | 
				
			||||||
@@ -59,6 +60,7 @@ export abstract class AbstractPlayer extends EventEmitter implements PlayerInter
 | 
				
			|||||||
      hand: this.hand.map(tile => tile.getState(showPips)),
 | 
					      hand: this.hand.map(tile => tile.getState(showPips)),
 | 
				
			||||||
      teamedWith: this.teamedWith?.getState(showPips) ?? null,
 | 
					      teamedWith: this.teamedWith?.getState(showPips) ?? null,
 | 
				
			||||||
      ready: this.ready,
 | 
					      ready: this.ready,
 | 
				
			||||||
 | 
					      isHuman: this instanceof PlayerHuman
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,8 @@ export class GameController extends BaseController {
 | 
				
			|||||||
  public async createMatch(req: Request, res: Response) {
 | 
					  public async createMatch(req: Request, res: Response) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const { user, body } = req;
 | 
					      const { user, body } = req;
 | 
				
			||||||
      const { sessionName, seed } = body;
 | 
					      const { sessionName, seed, options } = body;
 | 
				
			||||||
      const sessionId = await this.sessionService.createSession(user, sessionName, seed);
 | 
					      const sessionId = await this.sessionService.createSession(user, sessionName, seed, options);
 | 
				
			||||||
      res.status(201).json({ sessionId });
 | 
					      res.status(201).json({ sessionId });
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      this.handleError(res, error);
 | 
					      this.handleError(res, error);
 | 
				
			||||||
@@ -39,7 +39,7 @@ export class GameController extends BaseController {
 | 
				
			|||||||
  public async getMatch(req: Request, res: Response) {
 | 
					  public async getMatch(req: Request, res: Response) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const { sessionId } = req.params;
 | 
					      const { sessionId } = req.params;
 | 
				
			||||||
      const session = this.sessionService.getSession(sessionId)
 | 
					      const session = await this.sessionService.getSession(sessionId)
 | 
				
			||||||
      res.status(200).json(session);
 | 
					      res.status(200).json(session);
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      this.handleError(res, error);
 | 
					      this.handleError(res, error);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,23 @@
 | 
				
			|||||||
import { MatchSession } from "../../game/MatchSession";
 | 
					import { MatchSession } from "../../game/MatchSession";
 | 
				
			||||||
import { DbMatchSession } from "./interfaces";
 | 
					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 {
 | 
					    return {
 | 
				
			||||||
        id: session.id,
 | 
					        id: state.id,
 | 
				
			||||||
        name: session.name || '',
 | 
					        name: state.name || '',
 | 
				
			||||||
        creator: session.creator.id,
 | 
					        creator: state.creator,
 | 
				
			||||||
        players: session.players.map(player => player.id),
 | 
					        players: state.players,
 | 
				
			||||||
        seed: session.seed,
 | 
					        seed: state.seed,
 | 
				
			||||||
        mode: session.mode,
 | 
					        mode: state.mode,
 | 
				
			||||||
        pointsToWin: session.pointsToWin,
 | 
					        pointsToWin: state.pointsToWin,
 | 
				
			||||||
        maxPlayers: session.maxPlayers,
 | 
					        maxPlayers: state.maxPlayers,
 | 
				
			||||||
        numPlayers: session.numPlayers,
 | 
					        numPlayers: state.numPlayers,
 | 
				
			||||||
        scoreboard: Array.from(session.scoreboard.entries()).map(([player, score]) => ({ player, score })),
 | 
					        scoreboard: state.scoreboard,
 | 
				
			||||||
        matchWinner: session.matchWinner ? session.matchWinner.id : null,
 | 
					        matchWinner: state.matchWinner,
 | 
				
			||||||
        status: session.status
 | 
					        status: state.status,        
 | 
				
			||||||
 | 
					        matchInProgress: state.matchInProgress,
 | 
				
			||||||
 | 
					        gameSummaries: state.gameSummaries,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					import { GameSummary } from "../../game/dto/GameSummary";
 | 
				
			||||||
 | 
					import { PlayerDto } from "../../game/dto/PlayerDto";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Entity {
 | 
					export interface Entity {
 | 
				
			||||||
  createdAt?: number;
 | 
					  createdAt?: number;
 | 
				
			||||||
  modifiedAt?: number;
 | 
					  modifiedAt?: number;
 | 
				
			||||||
@@ -10,7 +13,8 @@ export interface EntityMongo extends Entity {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Score {
 | 
					export interface Score {
 | 
				
			||||||
  player: string;
 | 
					  id: string;
 | 
				
			||||||
 | 
					  name: string;
 | 
				
			||||||
  score: number;
 | 
					  score: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,15 +49,17 @@ export interface DbMatchSession extends EntityMongo {
 | 
				
			|||||||
  id: string;
 | 
					  id: string;
 | 
				
			||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  creator: string;
 | 
					  creator: string;
 | 
				
			||||||
  players: string[];
 | 
					  players: PlayerDto[];
 | 
				
			||||||
  seed: string;
 | 
					  seed: string;
 | 
				
			||||||
  mode: string;
 | 
					  mode: string;
 | 
				
			||||||
  pointsToWin: number;
 | 
					  pointsToWin: number;
 | 
				
			||||||
  maxPlayers: number;
 | 
					  maxPlayers: number;
 | 
				
			||||||
  numPlayers: number;
 | 
					  numPlayers: number;
 | 
				
			||||||
  scoreboard: Score[];
 | 
					  scoreboard: Score[];
 | 
				
			||||||
  matchWinner: string | null;
 | 
					  matchWinner: PlayerDto | null;
 | 
				
			||||||
  status: string;
 | 
					  status: string;
 | 
				
			||||||
 | 
					  matchInProgress: boolean;
 | 
				
			||||||
 | 
					  gameSummaries: GameSummary[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface DbUser extends EntityMongo {
 | 
					export interface DbUser extends EntityMongo {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ import { MatchSessionMongoManager } from "../db/mongo/MatchSessionMongoManager";
 | 
				
			|||||||
import { SessionManager } from "../managers/SessionManager";
 | 
					import { SessionManager } from "../managers/SessionManager";
 | 
				
			||||||
import { ServiceBase } from "./ServiceBase";
 | 
					import { ServiceBase } from "./ServiceBase";
 | 
				
			||||||
import { SocketIoService } from "./SocketIoService";
 | 
					import { SocketIoService } from "./SocketIoService";
 | 
				
			||||||
import toObjectId from "../db/mongo/common/mongoUtils";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class SessionService extends ServiceBase{
 | 
					export class SessionService extends ServiceBase{
 | 
				
			||||||
  private dbManager: MatchSessionMongoManager = new MatchSessionMongoManager();
 | 
					  private dbManager: MatchSessionMongoManager = new MatchSessionMongoManager();
 | 
				
			||||||
@@ -20,7 +19,7 @@ export class SessionService extends ServiceBase{
 | 
				
			|||||||
    super()
 | 
					    super()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  public async createSession(user: any, sessionName: string, seed: string ): Promise<string> {
 | 
					  public async createSession(user: any, sessionName: string, seed: string, options: any ): Promise<string> {
 | 
				
			||||||
    let socketClient;
 | 
					    let socketClient;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      socketClient = await whileNotUndefined(() => SocketIoService.getClient(user._id));
 | 
					      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 player =  new NetworkPlayer(user._id, user.username, socketClient.socketId);
 | 
				
			||||||
    const session = new MatchSession(player, sessionName, seed);
 | 
					    const session = new MatchSession(player, sessionName, seed);
 | 
				
			||||||
 | 
					    session.pointsToWin = options.pointsToWin;
 | 
				
			||||||
    const dbSessionId = await this.dbManager.create(matchSessionAdapter(session));
 | 
					    const dbSessionId = await this.dbManager.create(matchSessionAdapter(session));
 | 
				
			||||||
    if (dbSessionId === undefined) {
 | 
					    if (dbSessionId === undefined) {
 | 
				
			||||||
      throw new SessionCreationError();
 | 
					      throw new SessionCreationError();
 | 
				
			||||||
@@ -82,7 +82,9 @@ export class SessionService extends ServiceBase{
 | 
				
			|||||||
    return this.dbManager.update(session);
 | 
					    return this.dbManager.update(session);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // public updateSession(session: MatchSession): any {
 | 
					  public updateSession(session: MatchSession): any {
 | 
				
			||||||
  //   this.dbManager.replaceOne({id: session.id}, matchSessionAdapter(session));
 | 
					    const entity = matchSessionAdapter(session);
 | 
				
			||||||
  // }
 | 
					    entity._id = session.id
 | 
				
			||||||
 | 
					    this.dbManager.update(entity);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user