UNPKG

playship_ludo_pseudo_quick

Version:

Server side neutrino plugin code for ludo game

285 lines (270 loc) 10.7 kB
const logger = require('../utils/playshipUtils').getLogger(); const enums = require('../utils/enums'); const gameLogic = require('./logic'); const events = enums.NEW_EVENTS const eventObjs = require('../utils/newGameEvent') const { _gameObjById, _getMeta, _setPlayerProp, _getPlayerProp, _setGameProp, _getGameProp, _isHighestScore, _getGameTimeLeft, _isForfeitTurnCountBreached, _publishGameDiceRollsInfo, _setPLayerInitGameScore } = require('../utils/utils'); const PLAYER_PROPS = enums.PLAYER_PROPS; const GAME_PROPS = enums.GAME_PROPS; const OBJECT_PROPS = enums.OBJECT_PROPS; const gameStarted = function(game) { const gameKey = game.getId(); let numPlayers = game.getNumberOfPlayers(); let meta = _getMeta(game); let gameTime = meta.selectedPawn[numPlayers]; logger.info({key: gameKey}, 'game time %s for max players %s', gameTime, numPlayers); let ts = Date.now(); let gameTimerEndTs = ts + gameTime; game.sendTip(game.getPlayerSeating()[0], 16); _setGameProp(game, GAME_PROPS.GAME_TIMER_END_TS, gameTimerEndTs); game.syncGameStateServVars(); }; const mapToLoad = function(game, initialMaps) { const gameKey = game.getId(); let playerCount = game.getNumberOfPlayers(); let meta = _getMeta(game); let version = parseInt(meta.mapVersion) || 3; logger.debug(gameKey,'map version ,', version); let map = null; for (let i = 0; i < initialMaps.length; i++) { if (playerCount === parseInt(initialMaps[i].maxPlayer) && version === parseInt(initialMaps[i].version)) { logger.debug(gameKey,'map selected ,', initialMaps[i]); map = initialMaps[i]; break; } } return map; }; const startGame = function(game, cb) { initGameProps(game); initPlayerProps(game); gameLogic.turnInit(game); gameLogic.issueTurnStartSavePoint(game); initRevPosMap(game); cb(null); }; function initGameProps(game) { let meta = _getMeta(game); let isTournament = game.getBattleType() === enums.BATTLE_TYPES.TOURNAMENT game.setGameProp('maxMissMoves', meta.maxMissMoves); game.setGameProp('maxPieceKills', meta.maxPieceKills); game.setGameProp('playerSeating', game.getPlayerSeating()); game.setGameProp('maxMovesPerPlayer', meta.maxMovesPerPlayer); game.setGameProp('isDiceRevealed', false); game.setGameProp('autoRollTrigBeforeTurnEndMill', meta.autoRollTrigBeforeTurnEndMill); let numPlayers = game.getNumberOfPlayers(); let gameTime = meta.selectedPawn[numPlayers]; _setGameProp(game, GAME_PROPS.GAME_TIMER, gameTime); _setGameProp(game, GAME_PROPS.GAME_TIMER_REMAINING, gameTime); _setGameProp(game, GAME_PROPS.TOTAL_EXTRA_TIME, isTournament ? 0 : meta.extraTime); _setGameProp(game, GAME_PROPS.IS_GAME_PAUSED,false); _setGameProp(game, GAME_PROPS.IS_FORFEIT_FRAUD_BY_ANY_PLAYER,false); _setGameProp(game, GAME_PROPS.NO_POSSIBLE_MOVE,true); _setGameProp(game, GAME_PROPS.IS_TURN_COMPLETED, false); } function initRevPosMap(game) { let objIds = game.getAllObjIds(); let objIdList = []; for (let objId of objIds) { let obj = _gameObjById(game, objId); objIdList.push({id: objId, posKey: obj._get(OBJECT_PROPS.PATH_INDEX)}); } game.initCollisionMap(objIdList); for (let objId of objIds) { let obj = _gameObjById(game, objId); obj._set(OBJECT_PROPS.PATH_INDEX, null); } } function getColours(playerCount) { switch (parseInt(playerCount)) { case 2 : return ['greenPiece', 'bluePiece']; case 3 : return ['greenPiece', 'yellowPiece', 'bluePiece']; case 4 : return ['greenPiece', 'yellowPiece', 'bluePiece', 'redPiece']; } } function initPlayerProps(game) { let i = 0; const meta = _getMeta(game); let isTournament = game.getBattleType() === enums.BATTLE_TYPES.TOURNAMENT let shuffledColors = getColours(game.getNumberOfPlayers()); let users = []// for random color assignment for (let p of game.getPlayerSeating()) { const pieceType = shuffledColors[i] _setPlayerProp(game, p, PLAYER_PROPS.KILLS, 0); _setPlayerProp(game, p, PLAYER_PROPS.GOT_KILLED,0); _setPlayerProp(game, p, PLAYER_PROPS.TOTAL_TIME_PLAYED,0) _setPlayerProp(game, p, PLAYER_PROPS.ASCEND_COUNT, 0); _setPlayerProp(game, p, PLAYER_PROPS.COLOR, pieceType); _setPlayerProp(game, p, PLAYER_PROPS.MISS_MOVES, 0); _setPlayerProp(game, p, PLAYER_PROPS.TURN_COUNT, 0); _setPlayerProp(game, p, PLAYER_PROPS.ARE_PAWNS_DESTROYED, false); _setPlayerProp(game, p, PLAYER_PROPS.KILL_TYPES, {types: []}); _setPlayerProp(game, p, PLAYER_PROPS.CONSECUTIVE_SIXES, 0); _setPlayerProp(game, p, PLAYER_PROPS.AUTO_ROLL_COUNT,0) _setPlayerProp(game, p, PLAYER_PROPS.PLAYER_ROLL_COUNT,0) _setPlayerProp(game, p, PLAYER_PROPS.MISSED_SAFE_ZONES,0) gameLogic.initPlayerShuffleRoller(game,p); _setPLayerInitGameScore(game,p); users.push(game.getUserIdByPlayerId(p)) game.setPlayerRemainingExtraTime(p,isTournament ? 0 : meta.extraTime) if (p === game.getPlayerSeating()[0]) { let newRoll = gameLogic.rollADie(game, p); _setPlayerProp(game, p, PLAYER_PROPS.DIE_ROLL, newRoll); gameLogic.enablePawns(game, p); gameLogic.sendTurnInitHHEvent(game,p,newRoll) } else { _setPlayerProp(game, p, PLAYER_PROPS.DIE_ROLL, null); } let objIds = game.getAllObjIds(); for (let objId of objIds) { let obj = _gameObjById(game, objId); if (shuffledColors[i] === obj.type) game.changeOwner(p, objId); } i++; for( let p1 of game.getPlayerSeating()) { // mapping - Key[PlayerId_killCount] : Value[opponentKilledCount (# of time opponentPlayer has been killed by player)] // (initially : 0), p1 - PlayerId, p - OpponentId if(p!==p1) { const key = `${p1.toString()}_killCount`; game.setPlayerProp(p,key,0); } } } game.publishHHGameEvent(1,"players_initialized", { assigned_colors : shuffledColors, turn_wise_player_id : users, update_time : Date.now() } ) _publishGameDiceRollsInfo(game); } const onRestoreFromSavepoint = function(game, _) { const gameKey = game.getId(); const meta = _getMeta(game); let duration = meta.turnDuration; let turnExpiry = Date.now() + duration; logger.info({key: gameKey}, 'Setting turn expiry as', turnExpiry, 'current time is ', Date.now()); game.setGameProp('turnExpiry', turnExpiry); initRevPosMap(game); _setGameProp(game, GAME_PROPS.NEXT_TURN_TS, null); }; const onServerRestart = function(game) { const gameKey = game.getId(); if (game.getState() >= 30) return logger.debug({key: gameKey}, 'Game has ended, nothing to do'); game.restoreFromSavepoint('__turn_start', (err, res) => { if (err) return logger.error({key: gameKey}, 'Error reverting to prev savepoint, post server restart', 'continuing game without restore', err); logger.info({key: gameKey}, 'Successfully reverted to previous state, post server restart'); }); }; const kickTimeHackers = function(game, playerId) { // logger.info({key: game.getId()}, 'auto forfeiting player', playerId, // 'due to time hack detection'); // game.forfeitGameForPlayer(playerId, enums.TIME_HACK_DETECTION); }; function onForfeitForPlayer(game, playerId) { const gk = {key: game.getId()}; let forfeitEventObj = new eventObjs.forfeit() logger.info(gk, 'forfeit for player ', playerId); game.publishGameEvent(1607, [playerId]); const meta = _getMeta(game); let isHighestScore = _isHighestScore(game,playerId) forfeitEventObj.kingdom = _getPlayerProp(game, playerId, PLAYER_PROPS.MISS_MOVES) forfeitEventObj.score = game.getPlayerScore(playerId) forfeitEventObj.genus = isHighestScore game.publishNewGameEvent(playerId, forfeitEventObj) game.publishHHGameEvent(playerId,"player_forfeit",{ turn_id : game.getCurrentTurnId(), update_time : Date.now() }) const currentPlayerId = game.getCurrentTurnPlayerId() if (playerId !== currentPlayerId) { _setGameProp(game,GAME_PROPS.ABSOLUTE_WIN_TYPE,0) if(isHighestScore) triggerForfeitHighScoreEvent(game,playerId) const isTurnCompleted = _getGameProp(game, GAME_PROPS.IS_TURN_COMPLETED); const nextTurnPlayerId = game.fetchNextTurnPlayerId() if(isTurnCompleted && nextTurnPlayerId !== playerId){ gameLogic.turnInit(game,nextTurnPlayerId, false); } game.syncGameStateServVars(); return; } let curMissMoves = _getPlayerProp(game, playerId, PLAYER_PROPS.MISS_MOVES) if (curMissMoves < meta.maxMissMoves) { _setGameProp(game,GAME_PROPS.ABSOLUTE_WIN_TYPE,0) if(isHighestScore) triggerForfeitHighScoreEvent(game,playerId) } logger.debug(gk, 'forfeit player is current player', playerId); gameLogic.destroyForfeitPlayerPawns(game).catch(e => { logger.error(gk, 'forfeit player failed with exception', e); }); gameLogic.turnEndHandler(game, playerId); } const triggerForfeitHighScoreEvent = function (game,playerId){ const gk = {key: game.getId()}; let isForfeitTurnCountBreached = _isForfeitTurnCountBreached(game,playerId) if(isForfeitTurnCountBreached) { _setGameProp(game,GAME_PROPS.FORFEIT_HIGHEST_PLAYER_SCORE,game.getPlayerScore(playerId)) _setGameProp(game,GAME_PROPS.FORFEIT_HIGHEST_PLAYER_ID,playerId) _setGameProp(game,GAME_PROPS.IS_FORFEIT_FRAUD_BY_ANY_PLAYER,true) logger.debug(gk, 'forfeit turn count threshold breached player is current player', playerId, isForfeitTurnCountBreached); let fraudForfeitEvent = new eventObjs.fraudForfeit() game.publishGameFraudEvent(playerId,fraudForfeitEvent) } } const playerConnected = function(game, playerId) { const gk = {key: game.getId()}; let currentPlayerId = game.getCurrentTurnPlayerId(); let timeLeft = _getGameTimeLeft(game,currentPlayerId) if (isNaN(timeLeft.gameTime)) return; _setGameProp(game, GAME_PROPS.GAME_TIMER_REMAINING, timeLeft.gameTime >= 0 ? timeLeft.gameTime : 0); logger.debug(gk,"time left while player connected,", timeLeft) if(timeLeft.isExtraTimeEnabled && timeLeft.extraTime) { game.setPlayerRemainingExtraTime(currentPlayerId, timeLeft.extraTime) _setGameProp(game, enums.GAME_PROPS.EXTRA_TIME_CHECK_TIME, Date.now()); } return true; }; const handleGameOptions = function(game, gameOptions) { if (!(typeof gameOptions === 'object') || !gameOptions.prizeDist) { return; } _setGameProp(game, 'prizeDist', JSON.stringify(gameOptions.prizeDist)); }; module.exports = { startGame, onRestoreFromSavepoint, onServerRestart, kickTimeHackers, mapToLoad, onForfeitForPlayer, gameStarted, playerConnected, handleGameOptions, };