mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-30 09:47:50 +01:00
redis for everything but timer/transferring mod/restarting game
This commit is contained in:
@@ -1,16 +1,20 @@
|
||||
const globals = require('../../config/globals');
|
||||
const EVENT_IDS = globals.EVENT_IDS;
|
||||
const { RateLimiterMemory } = require('rate-limiter-flexible');
|
||||
const redis = require('redis');
|
||||
const GameStateCurator = require("../GameStateCurator");
|
||||
|
||||
class SocketManager {
|
||||
constructor (logger, activeGameRunner) {
|
||||
constructor (logger, activeGameRunner, instanceId) {
|
||||
if (SocketManager.instance) {
|
||||
throw new Error('The server attempted to instantiate more than one SocketManager.');
|
||||
}
|
||||
logger.info('CREATING SINGLETON SOCKET MANAGER');
|
||||
this.logger = logger;
|
||||
this.io = null;
|
||||
this.publisher = null;
|
||||
this.activeGameRunner = activeGameRunner;
|
||||
this.instanceId = instanceId;
|
||||
SocketManager.instance = this;
|
||||
}
|
||||
|
||||
@@ -18,6 +22,12 @@ class SocketManager {
|
||||
this.io?.emit(globals.EVENTS.BROADCAST, message);
|
||||
};
|
||||
|
||||
createRedisPublisher = async () => {
|
||||
this.publisher = redis.createClient();
|
||||
await this.publisher.connect();
|
||||
this.logger.info('SOCKET MANAGER - CREATED GAME SYNC PUBLISHER');
|
||||
}
|
||||
|
||||
createSocketServer = (main, app, port, logger) => {
|
||||
let io;
|
||||
if (process.env.NODE_ENV.trim() === 'development') {
|
||||
@@ -54,60 +64,99 @@ class SocketManager {
|
||||
socket.on(globals.SOCKET_EVENTS.IN_GAME_MESSAGE, async (eventId, accessCode, args = null, ackFn = null) => {
|
||||
const game = gameManager.activeGameRunner.activeGames.get(accessCode);
|
||||
if (game) {
|
||||
switch (eventId) {
|
||||
case EVENT_IDS.FETCH_GAME_STATE:
|
||||
await gameManager.handleRequestForGameState(
|
||||
game,
|
||||
this.namespace,
|
||||
this.logger,
|
||||
gameManager.activeGameRunner,
|
||||
accessCode,
|
||||
args.personId,
|
||||
ackFn,
|
||||
socket
|
||||
);
|
||||
break;
|
||||
case EVENT_IDS.START_GAME:
|
||||
gameManager.startGame(game, namespace);
|
||||
ackFn();
|
||||
break;
|
||||
case EVENT_IDS.PAUSE_TIMER:
|
||||
gameManager.pauseTimer(game, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.RESUME_TIMER:
|
||||
gameManager.resumeTimer(game, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.GET_TIME_REMAINING:
|
||||
gameManager.getTimeRemaining(game, socket);
|
||||
break;
|
||||
case EVENT_IDS.KILL_PLAYER:
|
||||
gameManager.killPlayer(socket, game, game.people.find((person) => person.id === args.personId), namespace, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.REVEAL_PLAYER:
|
||||
gameManager.revealPlayer(game, args.personId);
|
||||
break;
|
||||
case EVENT_IDS.TRANSFER_MODERATOR:
|
||||
let person = game.people.find((person) => person.id === args.personId);
|
||||
if (!person) {
|
||||
person = game.spectators.find((spectator) => spectator.id === args.personId);
|
||||
}
|
||||
gameManager.transferModeratorPowers(socket, game, person, namespace, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.CHANGE_NAME:
|
||||
gameManager.changeName(game, args.data, ackFn);
|
||||
break;
|
||||
case EVENT_IDS.END_GAME:
|
||||
gameManager.endGame(game);
|
||||
ackFn();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
await this.handleEventById(eventId, game, socket.id, gameManager, accessCode, args, ackFn);
|
||||
/* This server should publish events initiated by a connected socket to Redis for consumption by other instances. */
|
||||
if (Object.values(EVENT_IDS).includes(eventId)) {
|
||||
await gameManager.refreshGame(game);
|
||||
this.publisher?.publish(
|
||||
globals.REDIS_CHANNELS.ACTIVE_GAME_STREAM,
|
||||
accessCode + ';' + eventId + ';' + JSON.stringify(args) + ';' + this.instanceId
|
||||
);
|
||||
}
|
||||
} else {
|
||||
ackFn(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
handleEventById = async (eventId, game, socketId, gameManager, accessCode, args, ackFn) => {
|
||||
this.logger.debug('ARGS TO HANDLER: ' + JSON.stringify(args));
|
||||
switch (eventId) {
|
||||
case EVENT_IDS.NEW_GAME:
|
||||
this.activeGameRunner.activeGames.set(accessCode, args.newGame);
|
||||
break;
|
||||
case EVENT_IDS.PLAYER_JOINED:
|
||||
let toBeAssignedIndex = game.people.findIndex((person) => person.id === args.id && person.assigned === false);
|
||||
if (toBeAssignedIndex >= 0) {
|
||||
game.people[toBeAssignedIndex] = args;
|
||||
game.isFull = gameManager.isGameFull(game);
|
||||
gameManager.namespace.in(game.accessCode).emit(
|
||||
globals.EVENTS.PLAYER_JOINED,
|
||||
GameStateCurator.mapPerson(args),
|
||||
game.isFull
|
||||
);
|
||||
}
|
||||
break;
|
||||
case EVENT_IDS.SPECTATOR_JOINED:
|
||||
if (!game.spectators.find((spectator) => spectator.id === args.id)) {
|
||||
game.spectators.push(args);
|
||||
}
|
||||
gameManager.namespace.in(game.accessCode).emit(
|
||||
globals.EVENTS.UPDATE_SPECTATORS,
|
||||
game.spectators.map((spectator) => { return GameStateCurator.mapPerson(spectator); })
|
||||
);
|
||||
break;
|
||||
case EVENT_IDS.FETCH_GAME_STATE:
|
||||
if (!socketId) break;
|
||||
await gameManager.handleRequestForGameState(
|
||||
game,
|
||||
this.namespace,
|
||||
this.logger,
|
||||
gameManager.activeGameRunner,
|
||||
accessCode,
|
||||
args.personId,
|
||||
ackFn,
|
||||
socketId
|
||||
);
|
||||
break;
|
||||
case EVENT_IDS.START_GAME:
|
||||
await gameManager.startGame(game, gameManager.namespace);
|
||||
if (ackFn) {
|
||||
ackFn();
|
||||
}
|
||||
break;
|
||||
case EVENT_IDS.PAUSE_TIMER:
|
||||
await gameManager.pauseTimer(game, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.RESUME_TIMER:
|
||||
await gameManager.resumeTimer(game, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.GET_TIME_REMAINING:
|
||||
await gameManager.getTimeRemaining(game, socketId);
|
||||
break;
|
||||
case EVENT_IDS.KILL_PLAYER:
|
||||
await gameManager.killPlayer(socketId, game, game.people.find((person) => person.id === args.personId), gameManager.namespace, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.REVEAL_PLAYER:
|
||||
await gameManager.revealPlayer(game, args.personId);
|
||||
break;
|
||||
case EVENT_IDS.TRANSFER_MODERATOR:
|
||||
let person = game.people.find((person) => person.id === args.personId);
|
||||
if (!person) {
|
||||
person = game.spectators.find((spectator) => spectator.id === args.personId);
|
||||
}
|
||||
await gameManager.transferModeratorPowers(socketId, game, person, gameManager.namespace, this.logger);
|
||||
break;
|
||||
case EVENT_IDS.END_GAME:
|
||||
await gameManager.endGame(game);
|
||||
if (ackFn) {
|
||||
ackFn();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerRateLimiter (server, logger) {
|
||||
|
||||
Reference in New Issue
Block a user