mirror of
https://github.com/AlecM33/Werewolf.git
synced 2026-01-02 01:03:24 +01:00
refactor of networking when first reaching game page
This commit is contained in:
@@ -35,9 +35,9 @@ router.post('/create', function (req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/availability/:code', function (req, res) {
|
||||
const joinGamePromise = gameManager.joinGame(req.params.code);
|
||||
joinGamePromise.then((result) => {
|
||||
router.get('/:code/availability', function (req, res) {
|
||||
const availabilityPromise = gameManager.checkAvailability(req.params.code);
|
||||
availabilityPromise.then((result) => {
|
||||
if (result === 404) {
|
||||
res.status(404).send();
|
||||
} else if (result instanceof Error) {
|
||||
@@ -51,4 +51,26 @@ router.get('/availability/:code', function (req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.patch('/:code/players', function (req, res) {
|
||||
console.log(typeof req.body.cookie);
|
||||
console.log(req.body.cookie);
|
||||
if (
|
||||
req.body === null
|
||||
|| req.body.cookie === null
|
||||
|| (typeof req.body.cookie !== 'string' && req.body.cookie !== false)
|
||||
|| (req.body.cookie.length !== globals.USER_SIGNATURE_LENGTH && req.body.cookie !== false)
|
||||
) {
|
||||
res.status(400).send();
|
||||
}
|
||||
gameManager.joinGame(req.body.cookie, req.params.code).then((data) => {
|
||||
res.status(200).send(data);
|
||||
}).catch((code) => {
|
||||
res.status(code).send();
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/environment', function (req, res) {
|
||||
res.status(200).send(gameManager.environment);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -5,7 +5,6 @@ const globals = {
|
||||
STALE_GAME_HOURS: 12,
|
||||
CLIENT_COMMANDS: {
|
||||
FETCH_GAME_STATE: 'fetchGameState',
|
||||
GET_ENVIRONMENT: 'getEnvironment',
|
||||
START_GAME: 'startGame',
|
||||
PAUSE_TIMER: 'pauseTimer',
|
||||
RESUME_TIMER: 'resumeTimer',
|
||||
@@ -14,8 +13,7 @@ const globals = {
|
||||
REVEAL_PLAYER: 'revealPlayer',
|
||||
TRANSFER_MODERATOR: 'transferModerator',
|
||||
CHANGE_NAME: 'changeName',
|
||||
END_GAME: 'endGame',
|
||||
FETCH_IN_PROGRESS_STATE: 'fetchInitialInProgressState'
|
||||
END_GAME: 'endGame'
|
||||
},
|
||||
MESSAGES: {
|
||||
ENTER_NAME: 'Client must enter name.'
|
||||
|
||||
@@ -24,14 +24,6 @@ app.set('port', args.port);
|
||||
|
||||
const inGameSocketServer = ServerBootstrapper.createSocketServer(main, app, args.port);
|
||||
|
||||
inGameSocketServer.on('connection', function (socket) {
|
||||
socket.on('disconnecting', (reason) => {
|
||||
logger.trace('client socket disconnecting because: ' + reason);
|
||||
gameManager.removeClientFromLobbyIfApplicable(socket);
|
||||
});
|
||||
gameManager.addGameSocketHandlers(inGameSocketServer, socket);
|
||||
});
|
||||
|
||||
let gameManager;
|
||||
|
||||
/* Instantiate the singleton game manager */
|
||||
@@ -41,6 +33,16 @@ if (process.env.NODE_ENV.trim() === 'development') {
|
||||
gameManager = new GameManager(logger, globals.ENVIRONMENT.PRODUCTION).getInstance();
|
||||
}
|
||||
|
||||
gameManager.namespace = inGameSocketServer;
|
||||
|
||||
inGameSocketServer.on('connection', function (socket) {
|
||||
socket.on('disconnecting', (reason) => {
|
||||
logger.trace('client socket disconnecting because: ' + reason);
|
||||
gameManager.removeClientFromLobbyIfApplicable(socket);
|
||||
});
|
||||
gameManager.addGameSocketHandlers(inGameSocketServer, socket);
|
||||
});
|
||||
|
||||
/* api endpoints */
|
||||
const games = require('./api/GamesAPI');
|
||||
app.use('/api/games', games);
|
||||
|
||||
@@ -14,7 +14,6 @@ class GameManager {
|
||||
}
|
||||
|
||||
addGameSocketHandlers = (namespace, socket) => {
|
||||
this.namespace = namespace;
|
||||
socket.on(globals.CLIENT_COMMANDS.FETCH_GAME_STATE, (accessCode, personId, ackFn) => {
|
||||
this.logger.trace('request for game state for accessCode: ' + accessCode + ' from socket: ' + socket.id + ' with cookie: ' + personId);
|
||||
this.handleRequestForGameState(
|
||||
@@ -28,27 +27,6 @@ class GameManager {
|
||||
);
|
||||
});
|
||||
|
||||
/* this event handler will call handleRequestForGameState() with the 'handleNoMatch' arg as false - only
|
||||
connections that match a participant in the game at that time will have the game state sent to them.
|
||||
*/
|
||||
socket.on(globals.CLIENT_COMMANDS.FETCH_IN_PROGRESS_STATE, (accessCode, personId, ackFn) => {
|
||||
this.logger.trace('request for game state for accessCode ' + accessCode + ', person ' + personId);
|
||||
this.handleRequestForGameState(
|
||||
this.namespace,
|
||||
this.logger,
|
||||
this.activeGameRunner,
|
||||
accessCode,
|
||||
personId,
|
||||
ackFn,
|
||||
socket,
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
socket.on(globals.CLIENT_COMMANDS.GET_ENVIRONMENT, (ackFn) => {
|
||||
ackFn(this.environment);
|
||||
});
|
||||
|
||||
socket.on(globals.CLIENT_COMMANDS.START_GAME, (accessCode) => {
|
||||
const game = this.activeGameRunner.activeGames[accessCode];
|
||||
if (game && game.isFull) {
|
||||
@@ -152,7 +130,7 @@ class GameManager {
|
||||
socket.on(globals.CLIENT_COMMANDS.CHANGE_NAME, (accessCode, data, ackFn) => {
|
||||
const game = this.activeGameRunner.activeGames[accessCode];
|
||||
if (game) {
|
||||
const person = findPersonById(game, data.personId);
|
||||
const person = findPersonByField(game, 'id', data.personId);
|
||||
if (person) {
|
||||
if (!isNameTaken(game, data.name)) {
|
||||
ackFn('changed');
|
||||
@@ -207,7 +185,7 @@ class GameManager {
|
||||
}
|
||||
};
|
||||
|
||||
joinGame = (code) => {
|
||||
checkAvailability = (code) => {
|
||||
const game = this.activeGameRunner.activeGames[code];
|
||||
if (game) {
|
||||
const unassignedPerson = game.people.find((person) => person.assigned === false);
|
||||
@@ -275,16 +253,47 @@ class GameManager {
|
||||
}
|
||||
};
|
||||
|
||||
handleRequestForGameState = (namespace, logger, gameRunner, accessCode, personCookie, ackFn, socket, handleNoMatch = true) => {
|
||||
joinGame = (cookie, accessCode) => {
|
||||
const game = this.activeGameRunner.activeGames[accessCode];
|
||||
if (game) {
|
||||
const person = findPersonByField(game, 'cookie', cookie);
|
||||
if (person) {
|
||||
return Promise.resolve(person.cookie);
|
||||
} else {
|
||||
const unassignedPerson = game.moderator.assigned === false
|
||||
? game.moderator
|
||||
: game.people.find((person) => person.assigned === false);
|
||||
if (unassignedPerson) {
|
||||
this.logger.trace('request from client to join game. Assigning: ' + unassignedPerson.name);
|
||||
unassignedPerson.assigned = true;
|
||||
game.isFull = isGameFull(game);
|
||||
this.namespace.in(game.accessCode).emit(
|
||||
globals.EVENTS.PLAYER_JOINED,
|
||||
GameStateCurator.mapPerson(unassignedPerson),
|
||||
game.isFull
|
||||
);
|
||||
return Promise.resolve(unassignedPerson.cookie);
|
||||
} else { // if the game is full, make them a spectator.
|
||||
const spectator = new Person(
|
||||
createRandomId(),
|
||||
createRandomId(),
|
||||
UsernameGenerator.generate(),
|
||||
globals.USER_TYPES.SPECTATOR
|
||||
);
|
||||
this.logger.trace('new spectator: ' + spectator.name);
|
||||
game.spectators.push(spectator);
|
||||
return Promise.resolve(spectator.cookie);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Promise.reject(404);
|
||||
}
|
||||
};
|
||||
|
||||
handleRequestForGameState = (namespace, logger, gameRunner, accessCode, personCookie, ackFn, socket) => {
|
||||
const game = gameRunner.activeGames[accessCode];
|
||||
if (game) {
|
||||
let matchingPerson = game.people.find((person) => person.cookie === personCookie);
|
||||
if (!matchingPerson) {
|
||||
matchingPerson = game.spectators.find((spectator) => spectator.cookie === personCookie);
|
||||
}
|
||||
if (!matchingPerson && game.moderator.cookie === personCookie) {
|
||||
matchingPerson = game.moderator;
|
||||
}
|
||||
const matchingPerson = findPersonByField(game, 'cookie', personCookie);
|
||||
if (matchingPerson) {
|
||||
if (matchingPerson.socketId === socket.id) {
|
||||
logger.trace('matching person found with an established connection to the room: ' + matchingPerson.name);
|
||||
@@ -295,8 +304,8 @@ class GameManager {
|
||||
matchingPerson.socketId = socket.id;
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson, gameRunner, socket, logger));
|
||||
}
|
||||
} else if (handleNoMatch) {
|
||||
this.handleRequestFromNonMatchingPerson(game, socket, gameRunner, ackFn, logger);
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
}
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
@@ -304,43 +313,6 @@ class GameManager {
|
||||
}
|
||||
};
|
||||
|
||||
handleRequestFromNonMatchingPerson = (game, socket, gameRunner, ackFn, logger) => {
|
||||
const personWithMatchingSocketId = findPersonWithMatchingSocketId(game, socket.id);
|
||||
if (personWithMatchingSocketId) {
|
||||
logger.trace('matching person found whose cookie got cleared after establishing a connection to the room: ' + personWithMatchingSocketId.name);
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, personWithMatchingSocketId, gameRunner, socket, logger));
|
||||
} else {
|
||||
const unassignedPerson = game.moderator.assigned === false
|
||||
? game.moderator
|
||||
: game.people.find((person) => person.assigned === false);
|
||||
if (unassignedPerson) {
|
||||
logger.trace('completely new person with a first connection to the room: ' + unassignedPerson.name);
|
||||
unassignedPerson.assigned = true;
|
||||
unassignedPerson.socketId = socket.id;
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, unassignedPerson, gameRunner, socket, logger));
|
||||
const isFull = isGameFull(game);
|
||||
game.isFull = isFull;
|
||||
socket.to(game.accessCode).emit(
|
||||
globals.EVENTS.PLAYER_JOINED,
|
||||
GameStateCurator.mapPerson(unassignedPerson),
|
||||
isFull
|
||||
);
|
||||
} else { // if the game is full, make them a spectator.
|
||||
const spectator = new Person(
|
||||
createRandomId(),
|
||||
createRandomId(),
|
||||
UsernameGenerator.generate(),
|
||||
globals.USER_TYPES.SPECTATOR
|
||||
);
|
||||
spectator.socketId = socket.id;
|
||||
logger.trace('new spectator: ' + spectator.name);
|
||||
game.spectators.push(spectator);
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, spectator, gameRunner, socket, logger));
|
||||
}
|
||||
socket.join(game.accessCode);
|
||||
}
|
||||
};
|
||||
|
||||
removeClientFromLobbyIfApplicable (socket) {
|
||||
socket.rooms.forEach((room) => {
|
||||
if (this.activeGameRunner.activeGames[room]) {
|
||||
@@ -442,17 +414,6 @@ function rejectClientRequestForGameState (acknowledgementFunction) {
|
||||
return acknowledgementFunction(null);
|
||||
}
|
||||
|
||||
function findPersonWithMatchingSocketId (game, socketId) {
|
||||
let person = game.people.find((person) => person.socketId === socketId);
|
||||
if (!person) {
|
||||
person = game.spectators.find((spectator) => spectator.socketId === socketId);
|
||||
}
|
||||
if (!person && game.moderator.socketId === socketId) {
|
||||
person = game.moderator;
|
||||
}
|
||||
return person;
|
||||
}
|
||||
|
||||
function findPlayerBySocketId (people, socketId) {
|
||||
return people.find((person) => person.socketId === socketId && person.userType === globals.USER_TYPES.PLAYER);
|
||||
}
|
||||
@@ -461,16 +422,16 @@ function isGameFull (game) {
|
||||
return game.moderator.assigned === true && !game.people.find((person) => person.assigned === false);
|
||||
}
|
||||
|
||||
function findPersonById (game, id) {
|
||||
function findPersonByField (game, fieldName, value) {
|
||||
let person;
|
||||
if (id === game.moderator.id) {
|
||||
if (value === game.moderator[fieldName]) {
|
||||
person = game.moderator;
|
||||
}
|
||||
if (!person) {
|
||||
person = game.people.find((person) => person.id === id);
|
||||
person = game.people.find((person) => person[fieldName] === value);
|
||||
}
|
||||
if (!person) {
|
||||
person = game.spectators.find((spectator) => spectator.id === id);
|
||||
person = game.spectators.find((spectator) => spectator[fieldName] === value);
|
||||
}
|
||||
return person;
|
||||
}
|
||||
|
||||
@@ -65,15 +65,11 @@ const ServerBootstrapper = {
|
||||
let io;
|
||||
if (process.env.NODE_ENV.trim() === 'development') {
|
||||
io = require('socket.io')(main, {
|
||||
cors: { origin: 'http://localhost:' + port },
|
||||
pingTimeout: 5000,
|
||||
pingInterval: 5000
|
||||
cors: { origin: 'http://localhost:' + port }
|
||||
});
|
||||
} else {
|
||||
io = require('socket.io')(main, {
|
||||
cors: { origin: 'https://playwerewolf.uk.r.appspot.com' },
|
||||
pingTimeout: 5000,
|
||||
pingInterval: 5000
|
||||
cors: { origin: 'https://playwerewolf.uk.r.appspot.com' }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user