mancala/src/game/GameManager.ts

158 lines
6.1 KiB
TypeScript
Raw Normal View History

2022-07-15 21:43:16 +03:00
import { CommonMancalaGame, MancalaGame } from "mancala.js";
import { RTMT } from "../rtmt/rtmt";
import { GameStore } from "./gamestore/GameStore";
import { generateKey } from "../util/key_factory";
import {
channel_game_move,
channel_leave_game,
channel_new_game,
channel_on_game_crashed,
channel_on_game_start,
channel_on_game_update,
2022-07-23 00:32:55 +03:00
channel_on_game_user_leave,
channel_on_user_connection_change
2022-07-15 21:43:16 +03:00
} from "../consts/channel_names";
import { GameMove } from "../models/GameMove";
import { GameCrashManager } from "./GameCrashManager";
import { MatchMaker } from "../matchmaker/MatchMaker";
import { Game, GameUsersConnectionInfo } from "../models/Game";
2022-07-15 21:43:16 +03:00
export class GameManager {
gameStore: GameStore;
rtmt: RTMT;
matchMaker: MatchMaker;
2022-07-23 00:32:55 +03:00
2022-07-15 21:43:16 +03:00
constructor(params: { gameStore: GameStore, rtmt: RTMT, matchMaker: MatchMaker }) {
this.gameStore = params.gameStore;
this.rtmt = params.rtmt;
this.matchMaker = params.matchMaker;
this.initialize();
}
private initialize() {
this.listenOnPlayersPaired();
this.listenRtmtMessages();
2022-07-23 00:32:55 +03:00
this.listenUserConnectionChange();
2022-07-15 21:43:16 +03:00
}
private listenRtmtMessages() {
this.rtmt.listenMessage(channel_new_game, (userKey: string, message: Object) => {
this.matchMaker.join(userKey);
});
this.rtmt.listenMessage(channel_game_move, (userKey: string, message: Object) => {
this.onGameMove(userKey, message as GameMove);
});
this.rtmt.listenMessage(channel_leave_game, (userKey: string, message: Object) => {
this.onPlayerLeave(userKey)
2022-07-23 00:32:55 +03:00
});
2022-07-15 21:43:16 +03:00
}
private onGameMove(userKey: string, gameMove: GameMove) {
const game = this.gameStore.getGameByUser(userKey);
2022-07-15 21:43:16 +03:00
if (game) {
try {
game.mancalaGame.moveByPlayerPit(userKey, gameMove.index);
game.gameUsersConnectionInfo = this.getGameUsersConnectionInfo(game);
this.rtmt.sendMessage(game.mancalaGame.player1Id, channel_on_game_update, game);
this.rtmt.sendMessage(game.mancalaGame.player2Id, channel_on_game_update, game);
if (game.mancalaGame.state == "ended") {
2022-07-15 21:43:16 +03:00
this.deleteGame(game);
}
} catch (err: any) {
this.onGameError(game, err)
}
} else {
console.log("Game not found!");
}
}
private onGameError(game: Game, error: any) {
2022-07-15 21:43:16 +03:00
console.error(error);
const crashFileName = GameCrashManager.logGameCrash(error, game);
console.info(`Game crash saved to file : ${crashFileName}`);
this.rtmt.sendMessage(game.mancalaGame.player1Id, channel_on_game_crashed, error);
this.rtmt.sendMessage(game.mancalaGame.player2Id, channel_on_game_crashed, error);
2022-07-15 21:43:16 +03:00
}
private onPlayerLeave(userKey: string) {
const game = this.gameStore.getGameByUser(userKey);
2022-07-15 21:43:16 +03:00
if (game) {
this.deleteGame(game);
this.rtmt.sendMessage(game.mancalaGame.player1Id, channel_on_game_user_leave, userKey);
this.rtmt.sendMessage(game.mancalaGame.player2Id, channel_on_game_user_leave, userKey);
2022-07-15 21:43:16 +03:00
}
}
private listenOnPlayersPaired() {
this.matchMaker.listenOnPlayersPaired((player1Id: string, player2Id: string) => {
const game = this.createMancalaGame(player1Id, player2Id);
this.startGame(game);
});
}
public fireOnPlayerConnected(playerId: string) {}
2022-07-15 21:43:16 +03:00
public createMancalaGame(userKey1: string, userKey2: string): Game {
const mancalaGame = new CommonMancalaGame(generateKey(), userKey1, userKey2);
2022-07-15 21:43:16 +03:00
const random = Math.random();
mancalaGame.turnPlayerId = random > 0.5 ? userKey1 : userKey2;
const game: Game = {
id: mancalaGame.id,
mancalaGame,
gameUsersConnectionInfo: this.getGameUsersConnectionInfoFromUsers(mancalaGame.player1Id, mancalaGame.player2Id),
};
2022-07-15 21:43:16 +03:00
this.gameStore.set(game.id, game);
this.gameStore.setGameByUser(userKey1, game);
this.gameStore.setGameByUser(userKey2, game);
2022-07-15 21:43:16 +03:00
return game;
}
public getGameUsersConnectionInfo(game: Game): GameUsersConnectionInfo {
return this.getGameUsersConnectionInfoFromUsers(game.mancalaGame.player1Id, game.mancalaGame.player2Id);
2022-07-23 00:32:55 +03:00
}
public getGameUsersConnectionInfoFromUsers(user1Id: string, user2Id: string): GameUsersConnectionInfo {
const isPlayer1Online = this.rtmt.isClientOnline(user1Id);
const isPlayer2Online = this.rtmt.isClientOnline(user2Id);
return {
user1ConnectionInfo: { userId: user1Id, isOnline: isPlayer1Online },
user2ConnectionInfo: { userId: user2Id, isOnline: isPlayer2Online }
};
}
public startGame(game: Game) {
const mancalaGame = game.mancalaGame;
this.rtmt.sendMessage(mancalaGame.player1Id, channel_on_game_start, game);
this.rtmt.sendMessage(mancalaGame.player2Id, channel_on_game_start, game);
this.sendUserConnectionInfo(game);
this.sendUserConnectionInfo(game);
}
public sendUserConnectionInfo(game: Game) {
const user1 = game.mancalaGame.player1Id;
const user2 = game.mancalaGame.player2Id;
const gameUsersConnectionInfo = this.getGameUsersConnectionInfo(game);
2022-07-23 00:32:55 +03:00
//todo: reimplement when watch game feature added
this.rtmt.sendMessage(user1, channel_on_user_connection_change, gameUsersConnectionInfo);
this.rtmt.sendMessage(user2, channel_on_user_connection_change, gameUsersConnectionInfo);
2022-07-15 21:43:16 +03:00
}
public deleteGame(game: Game) {
2022-07-15 21:43:16 +03:00
if (game) {
this.gameStore.removeGameByPlayer(game.mancalaGame.player1Id);
this.gameStore.removeGameByPlayer(game.mancalaGame.player2Id);
2022-07-15 21:43:16 +03:00
}
}
2022-07-23 00:32:55 +03:00
private listenUserConnectionChange() {
this.rtmt.listenOnClientConnectionChange((clientId: string, isOnline: boolean) => {
const game = this.gameStore.getGameByUser(clientId);
if (game) this.sendUserConnectionInfo(game);
2022-07-23 00:32:55 +03:00
});
}
2022-07-15 21:43:16 +03:00
}