mirror of
https://github.com/AlecM33/Werewolf.git
synced 2026-02-10 04:03:33 +01:00
* Initial plan * Refactor timer system to run on main thread instead of child processes Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Remove obsolete GameProcess.js and simplify TimerManager to stub Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Address code review feedback: add comments and reduce duplication Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Remove comments, delete TimerManager, and simplify SOURCE_TIMER_EVENT Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Fix cross-instance timer communication and expired timer handling - GET_TIME_REMAINING now publishes response through Redis for cross-instance communication - SOURCE_TIMER_EVENT handles GET_TIME_REMAINING even when timer is not running locally - Returns 0 time remaining when timer has expired or timerParams is null - Updated test to expect Redis publish instead of direct method call Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Simplify GET_TIME_REMAINING flow and add ended flag - Add ended: true flag to timerParams when timer completes - Simplify TIMER_EVENT to check ended flag first, then local timer, then publish SOURCE_TIMER_EVENT - SOURCE_TIMER_EVENT only publishes GET_TIME_REMAINING if it has the timer - Remove GET_TIME_REMAINING from handleTimerCommand helper - Direct socket emission for local timers instead of Redis publish - Updated test to verify socket emission Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Refactor GET_TIME_REMAINING into handleTimerCommand switch case - Moved GET_TIME_REMAINING logic from TIMER_EVENT handler into handleTimerCommand function - Simplified TIMER_EVENT to just call handleTimerCommand for all timer operations - Maintains same flow: check ended flag, check local timer, publish SOURCE_TIMER_EVENT if needed - All tests passing Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Remove unused getTimeRemaining function from GameManager - Function is no longer called after refactoring GET_TIME_REMAINING into handleTimerCommand - All timer time remaining logic now handled in Events.js handleTimerCommand switch case - Tests still passing Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * Reset timerParams.ended flag when restarting game - Added reset of ended flag to false in restartGame function - Ensures restarted games don't have timer marked as already ended - Placed right after timer cleanup for logical grouping Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> * remuse unused constant --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: AlecM33 <24642328+AlecM33@users.noreply.github.com> Co-authored-by: AlecM33 <leohfx@gmail.com>
502 lines
21 KiB
JavaScript
502 lines
21 KiB
JavaScript
const GameStateCurator = require('./GameStateCurator');
|
|
const GameCreationRequest = require('../model/GameCreationRequest');
|
|
const { EVENT_IDS, STATUS, USER_TYPES, GAME_PROCESS_COMMANDS, REDIS_CHANNELS, PRIMITIVES } = require('../config/globals');
|
|
|
|
async function handleTimerCommand (timerEventSubtype, game, socketId, vars) {
|
|
switch (timerEventSubtype) {
|
|
case GAME_PROCESS_COMMANDS.PAUSE_TIMER:
|
|
const pauseTimeRemaining = await vars.gameManager.pauseTimer(game);
|
|
if (pauseTimeRemaining !== null) {
|
|
await vars.eventManager.handleEventById(
|
|
EVENT_IDS.PAUSE_TIMER,
|
|
null,
|
|
game,
|
|
null,
|
|
game.accessCode,
|
|
{ timeRemaining: pauseTimeRemaining },
|
|
null,
|
|
false
|
|
);
|
|
await vars.gameManager.refreshGame(game);
|
|
await vars.eventManager.publisher.publish(
|
|
REDIS_CHANNELS.ACTIVE_GAME_STREAM,
|
|
vars.eventManager.createMessageToPublish(
|
|
game.accessCode,
|
|
EVENT_IDS.PAUSE_TIMER,
|
|
vars.instanceId,
|
|
JSON.stringify({ timeRemaining: pauseTimeRemaining })
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
case GAME_PROCESS_COMMANDS.RESUME_TIMER:
|
|
const resumeTimeRemaining = await vars.gameManager.resumeTimer(game);
|
|
if (resumeTimeRemaining !== null) {
|
|
await vars.eventManager.handleEventById(
|
|
EVENT_IDS.RESUME_TIMER,
|
|
null,
|
|
game,
|
|
null,
|
|
game.accessCode,
|
|
{ timeRemaining: resumeTimeRemaining },
|
|
null,
|
|
false
|
|
);
|
|
await vars.gameManager.refreshGame(game);
|
|
await vars.eventManager.publisher.publish(
|
|
REDIS_CHANNELS.ACTIVE_GAME_STREAM,
|
|
vars.eventManager.createMessageToPublish(
|
|
game.accessCode,
|
|
EVENT_IDS.RESUME_TIMER,
|
|
vars.instanceId,
|
|
JSON.stringify({ timeRemaining: resumeTimeRemaining })
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
case GAME_PROCESS_COMMANDS.GET_TIME_REMAINING:
|
|
if (game.timerParams && game.timerParams.ended) {
|
|
const socket = vars.gameManager.namespace.sockets.get(socketId);
|
|
if (socket) {
|
|
vars.gameManager.namespace.to(socket.id).emit(
|
|
GAME_PROCESS_COMMANDS.GET_TIME_REMAINING,
|
|
0,
|
|
false
|
|
);
|
|
}
|
|
} else {
|
|
const timer = vars.gameManager.timers[game.accessCode];
|
|
if (timer) {
|
|
const socket = vars.gameManager.namespace.sockets.get(socketId);
|
|
if (socket) {
|
|
vars.gameManager.namespace.to(socket.id).emit(
|
|
GAME_PROCESS_COMMANDS.GET_TIME_REMAINING,
|
|
timer.currentTimeInMillis,
|
|
game.timerParams ? game.timerParams.paused : false
|
|
);
|
|
}
|
|
} else {
|
|
await vars.eventManager.publisher?.publish(
|
|
REDIS_CHANNELS.ACTIVE_GAME_STREAM,
|
|
vars.eventManager.createMessageToPublish(
|
|
game.accessCode,
|
|
EVENT_IDS.SOURCE_TIMER_EVENT,
|
|
vars.instanceId,
|
|
JSON.stringify({ socketId: socketId, timerEventSubtype: timerEventSubtype })
|
|
)
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
const Events = [
|
|
{
|
|
id: EVENT_IDS.PLAYER_JOINED,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.people.push(socketArgs);
|
|
game.isStartable = vars.gameManager.isGameStartable(game);
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.PLAYER_JOINED,
|
|
GameStateCurator.mapPerson(socketArgs),
|
|
game.isStartable
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.KICK_PERSON,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const toBeClearedIndex = game.people.findIndex(
|
|
(person) => person.id === socketArgs.personId && person.assigned === true
|
|
);
|
|
if (toBeClearedIndex >= 0) {
|
|
game.people.splice(toBeClearedIndex, 1);
|
|
game.isStartable = vars.gameManager.isGameStartable(game);
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.KICK_PERSON,
|
|
socketArgs.personId,
|
|
game.isStartable
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.LEAVE_ROOM,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const toBeClearedIndex = game.people.findIndex(
|
|
(person) => person.id === socketArgs.personId && person.assigned === true
|
|
);
|
|
if (toBeClearedIndex >= 0) {
|
|
game.people.splice(toBeClearedIndex, 1);
|
|
game.isStartable = vars.gameManager.isGameStartable(game);
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.LEAVE_ROOM,
|
|
socketArgs.personId,
|
|
game.isStartable
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.CHANGE_NAME,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const toChangeIndex = game.people.findIndex(
|
|
(person) => person.id === socketArgs.personId
|
|
);
|
|
if (toChangeIndex >= 0) {
|
|
if (vars.gameManager.isNameTaken(game, socketArgs.newName)) {
|
|
vars.hasNameChanged = false;
|
|
if (game.people[toChangeIndex].name.toLowerCase().trim() === socketArgs.newName.toLowerCase().trim()) {
|
|
return;
|
|
}
|
|
vars.ackFn({ errorFlag: 1, message: 'This name is taken.' });
|
|
} else if (socketArgs.newName.length > PRIMITIVES.MAX_PERSON_NAME_LENGTH) {
|
|
vars.ackFn({ errorFlag: 1, message: 'Your new name is too long - the max is ' + PRIMITIVES.MAX_PERSON_NAME_LENGTH + ' characters.' });
|
|
vars.hasNameChanged = false;
|
|
} else if (socketArgs.newName.length === 0) {
|
|
vars.ackFn({ errorFlag: 1, message: 'Your new name cannot be empty.' });
|
|
vars.hasNameChanged = false;
|
|
} else {
|
|
game.people[toChangeIndex].name = socketArgs.newName;
|
|
vars.ackFn({ errorFlag: 0, message: 'Name updated!' });
|
|
vars.hasNameChanged = true;
|
|
}
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.hasNameChanged) {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.CHANGE_NAME,
|
|
socketArgs.personId,
|
|
socketArgs.newName
|
|
);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.UPDATE_GAME_ROLES,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
if (GameCreationRequest.deckIsValid(socketArgs.deck)) {
|
|
game.deck = socketArgs.deck;
|
|
game.gameSize = socketArgs.deck.reduce(
|
|
(accumulator, currentValue) => accumulator + currentValue.quantity,
|
|
0
|
|
);
|
|
game.isStartable = vars.gameManager.isGameStartable(game);
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.UPDATE_GAME_ROLES,
|
|
game.deck,
|
|
game.gameSize,
|
|
game.isStartable
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.ADD_SPECTATOR,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.people.push(socketArgs);
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.ADD_SPECTATOR,
|
|
GameStateCurator.mapPerson(socketArgs)
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.FETCH_GAME_STATE,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const matchingPerson = vars.gameManager.findPersonByField(game, 'cookie', socketArgs.personId);
|
|
if (matchingPerson && matchingPerson.socketId !== vars.requestingSocketId) {
|
|
matchingPerson.socketId = vars.requestingSocketId;
|
|
vars.gameManager.namespace.sockets.get(vars.requestingSocketId)?.join(game.accessCode);
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (!vars.ackFn) return;
|
|
const matchingPerson = vars.gameManager.findPersonByField(game, 'cookie', socketArgs.personId);
|
|
if (matchingPerson && vars.gameManager.namespace.sockets.get(matchingPerson.socketId)) {
|
|
vars.ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson));
|
|
} else {
|
|
vars.ackFn(null);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.SYNC_GAME_STATE,
|
|
stateChange: async (game, socketArgs, vars) => {},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
const matchingPerson = vars.gameManager.findPersonByField(game, 'id', socketArgs.personId);
|
|
if (matchingPerson && vars.gameManager.namespace.sockets.get(matchingPerson.socketId)) {
|
|
vars.gameManager.namespace.to(matchingPerson.socketId).emit(EVENT_IDS.SYNC_GAME_STATE);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.START_GAME,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
if (game.isStartable) {
|
|
game.status = STATUS.IN_PROGRESS;
|
|
vars.gameManager.deal(game);
|
|
if (game.hasTimer) {
|
|
game.timerParams.paused = true;
|
|
await vars.gameManager.runTimer(game);
|
|
}
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
vars.gameManager.namespace.in(game.accessCode).emit(EVENT_IDS.START_GAME);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.KILL_PLAYER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const person = game.people.find((person) => person.id === socketArgs.personId);
|
|
if (person && !person.out) {
|
|
person.userType = person.userType === USER_TYPES.BOT
|
|
? USER_TYPES.KILLED_BOT
|
|
: USER_TYPES.KILLED_PLAYER;
|
|
person.out = true;
|
|
person.killed = true;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
const person = game.people.find((person) => person.id === socketArgs.personId);
|
|
if (person) {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(EVENT_IDS.KILL_PLAYER, person);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.REVEAL_PLAYER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const person = game.people.find((person) => person.id === socketArgs.personId);
|
|
if (person && !person.revealed) {
|
|
person.revealed = true;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
const person = game.people.find((person) => person.id === socketArgs.personId);
|
|
if (person) {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.REVEAL_PLAYER,
|
|
{
|
|
id: person.id,
|
|
gameRole: person.gameRole,
|
|
alignment: person.alignment
|
|
}
|
|
);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.END_GAME,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.status = STATUS.ENDED;
|
|
if (game.hasTimer && vars.gameManager.timers[game.accessCode]) {
|
|
vars.logger.trace('STOPPING TIMER FOR ENDED GAME ' + game.accessCode);
|
|
vars.gameManager.timers[game.accessCode].stopTimer();
|
|
delete vars.gameManager.timers[game.accessCode];
|
|
}
|
|
for (const person of game.people) {
|
|
person.revealed = true;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode)
|
|
.emit(EVENT_IDS.END_GAME, GameStateCurator.mapPeopleForModerator(game.people));
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.TRANSFER_MODERATOR,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const currentModerator = vars.gameManager.findPersonByField(game, 'id', game.currentModeratorId);
|
|
const toTransferTo = vars.gameManager.findPersonByField(game, 'id', socketArgs.personId);
|
|
if (currentModerator) {
|
|
if (currentModerator.gameRole) {
|
|
currentModerator.userType = USER_TYPES.KILLED_PLAYER;
|
|
} else {
|
|
currentModerator.userType = USER_TYPES.SPECTATOR;
|
|
}
|
|
game.previousModeratorId = currentModerator.id;
|
|
}
|
|
if (toTransferTo) {
|
|
toTransferTo.userType = USER_TYPES.MODERATOR;
|
|
game.currentModeratorId = toTransferTo.id;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
vars.gameManager.namespace.to(game.accessCode).emit(EVENT_IDS.SYNC_GAME_STATE);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.ASSIGN_DEDICATED_MOD,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
const currentModerator = vars.gameManager.findPersonByField(game, 'id', game.currentModeratorId);
|
|
const toTransferTo = vars.gameManager.findPersonByField(game, 'id', socketArgs.personId);
|
|
if (currentModerator && toTransferTo) {
|
|
if (currentModerator.id !== toTransferTo.id) {
|
|
currentModerator.userType = USER_TYPES.PLAYER;
|
|
}
|
|
|
|
toTransferTo.userType = USER_TYPES.MODERATOR;
|
|
toTransferTo.out = true;
|
|
toTransferTo.killed = true;
|
|
game.previousModeratorId = currentModerator.id;
|
|
game.currentModeratorId = toTransferTo.id;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
const moderator = vars.gameManager.findPersonByField(game, 'id', game.currentModeratorId);
|
|
const moderatorSocket = vars.gameManager.namespace.sockets.get(moderator?.socketId);
|
|
if (moderator && moderatorSocket) {
|
|
vars.gameManager.namespace.to(moderator.socketId).emit(EVENT_IDS.SYNC_GAME_STATE);
|
|
moderatorSocket.to(game.accessCode).emit(EVENT_IDS.KILL_PLAYER, moderator);
|
|
} else {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(EVENT_IDS.KILL_PLAYER, moderator);
|
|
}
|
|
const previousModerator = vars.gameManager.findPersonByField(game, 'id', game.previousModeratorId);
|
|
if (previousModerator && previousModerator.id !== moderator.id && vars.gameManager.namespace.sockets.get(previousModerator.socketId)) {
|
|
vars.gameManager.namespace.to(previousModerator.socketId).emit(EVENT_IDS.SYNC_GAME_STATE);
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.RESTART_GAME,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
if (vars.instanceId !== vars.senderInstanceId
|
|
&& vars.gameManager.timers[game.accessCode]
|
|
) {
|
|
vars.gameManager.timers[game.accessCode].stopTimer();
|
|
delete vars.gameManager.timers[game.accessCode];
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
vars.gameManager.namespace.in(game.accessCode).emit(EVENT_IDS.RESTART_GAME);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.TIMER_EVENT,
|
|
stateChange: async (game, socketArgs, vars) => {},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
await handleTimerCommand(vars.timerEventSubtype, game, vars.requestingSocketId, vars);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.SOURCE_TIMER_EVENT,
|
|
stateChange: async (game, socketArgs, vars) => {},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (socketArgs.timerEventSubtype === GAME_PROCESS_COMMANDS.GET_TIME_REMAINING) {
|
|
const timer = vars.gameManager.timers[game.accessCode];
|
|
if (timer) {
|
|
await vars.eventManager.publisher.publish(
|
|
REDIS_CHANNELS.ACTIVE_GAME_STREAM,
|
|
vars.eventManager.createMessageToPublish(
|
|
game.accessCode,
|
|
GAME_PROCESS_COMMANDS.GET_TIME_REMAINING,
|
|
vars.instanceId,
|
|
JSON.stringify({
|
|
socketId: socketArgs.socketId,
|
|
timeRemaining: timer.currentTimeInMillis,
|
|
paused: game.timerParams ? game.timerParams.paused : false
|
|
})
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
const timer = vars.gameManager.timers[game.accessCode];
|
|
if (timer) {
|
|
await handleTimerCommand(socketArgs.timerEventSubtype, game, socketArgs.socketId, vars);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.UPDATE_GAME_TIMER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
if (GameCreationRequest.timerParamsAreValid(socketArgs.hasTimer, socketArgs.timerParams)) {
|
|
game.hasTimer = socketArgs.hasTimer;
|
|
game.timerParams = socketArgs.timerParams;
|
|
}
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
if (vars.ackFn) {
|
|
vars.ackFn();
|
|
}
|
|
vars.gameManager.namespace.in(game.accessCode).emit(
|
|
EVENT_IDS.UPDATE_GAME_TIMER,
|
|
game.hasTimer,
|
|
game.timerParams
|
|
);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.END_TIMER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.timerParams.paused = false;
|
|
game.timerParams.timeRemaining = 0;
|
|
game.timerParams.ended = true;
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(GAME_PROCESS_COMMANDS.END_TIMER);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.PAUSE_TIMER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.timerParams.paused = true;
|
|
game.timerParams.timeRemaining = socketArgs.timeRemaining;
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(GAME_PROCESS_COMMANDS.PAUSE_TIMER, socketArgs.timeRemaining);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.RESUME_TIMER,
|
|
stateChange: async (game, socketArgs, vars) => {
|
|
game.timerParams.paused = false;
|
|
game.timerParams.timeRemaining = socketArgs.timeRemaining;
|
|
},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
vars.gameManager.namespace.in(game.accessCode).emit(GAME_PROCESS_COMMANDS.RESUME_TIMER, socketArgs.timeRemaining);
|
|
}
|
|
},
|
|
{
|
|
id: EVENT_IDS.GET_TIME_REMAINING,
|
|
stateChange: async (game, socketArgs, vars) => {},
|
|
communicate: async (game, socketArgs, vars) => {
|
|
const socket = vars.gameManager.namespace.sockets.get(socketArgs.socketId);
|
|
if (socket) {
|
|
vars.gameManager.namespace.to(socket.id).emit(GAME_PROCESS_COMMANDS.GET_TIME_REMAINING, socketArgs.timeRemaining, game.timerParams.paused);
|
|
}
|
|
}
|
|
}
|
|
];
|
|
|
|
module.exports = Events;
|