mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 07:47:50 +01:00
revert conversion of join to XHR call
This commit is contained in:
@@ -12,26 +12,6 @@ import { XHRUtility } from '../modules/XHRUtility.js';
|
||||
|
||||
const game = () => {
|
||||
injectNavbar();
|
||||
const socket = io('/in-game');
|
||||
const timerWorker = new Worker(new URL('../modules/Timer.js', import.meta.url));
|
||||
const gameTimerManager = new GameTimerManager(stateBucket, socket);
|
||||
const gameStateRenderer = new GameStateRenderer(stateBucket, socket);
|
||||
socket.on('disconnect', () => {
|
||||
toast('Disconnected. Attempting reconnect...', 'error', true, false);
|
||||
});
|
||||
socket.on('connect', () => {
|
||||
if (!stateBucket.joinRequestInFlight) {
|
||||
prepareGamePage(
|
||||
stateBucket,
|
||||
stateBucket.accessCode,
|
||||
gameTimerManager,
|
||||
gameStateRenderer,
|
||||
timerWorker,
|
||||
socket,
|
||||
UserUtility.validateAnonUserSignature(stateBucket.environment)
|
||||
);
|
||||
}
|
||||
});
|
||||
XHRUtility.xhr(
|
||||
'/api/games/environment',
|
||||
'GET',
|
||||
@@ -40,81 +20,74 @@ const game = () => {
|
||||
)
|
||||
.then((res) => {
|
||||
stateBucket.environment = res.content;
|
||||
joinGame(res, gameTimerManager, gameStateRenderer, socket, timerWorker);
|
||||
const socket = io('/in-game');
|
||||
const timerWorker = new Worker(new URL('../modules/Timer.js', import.meta.url));
|
||||
const gameTimerManager = new GameTimerManager(stateBucket, socket);
|
||||
const gameStateRenderer = new GameStateRenderer(stateBucket, socket);
|
||||
socket.on('connect', () => {
|
||||
syncWithGame(
|
||||
stateBucket,
|
||||
gameTimerManager,
|
||||
gameStateRenderer,
|
||||
timerWorker,
|
||||
socket,
|
||||
UserUtility.validateAnonUserSignature(res.content)
|
||||
);
|
||||
});
|
||||
socket.on('disconnect', () => {
|
||||
toast('Disconnected. Attempting reconnect...', 'error', true, false);
|
||||
});
|
||||
setClientSocketHandlers(stateBucket, gameStateRenderer, socket, timerWorker, gameTimerManager);
|
||||
}).catch((res) => {
|
||||
toast(res.content, 'error', true);
|
||||
});
|
||||
};
|
||||
|
||||
function joinGame (environmentResponse, gameTimerManager, gameStateRenderer, socket, timerWorker) {
|
||||
let cookie = UserUtility.validateAnonUserSignature(environmentResponse.content);
|
||||
function syncWithGame (stateBucket, gameTimerManager, gameStateRenderer, timerWorker, socket, cookie) {
|
||||
const splitUrl = window.location.href.split('/game/');
|
||||
const accessCode = splitUrl[1];
|
||||
if (/^[a-zA-Z0-9]+$/.test(accessCode) && accessCode.length === globals.ACCESS_CODE_LENGTH) {
|
||||
XHRUtility.xhr(
|
||||
'/api/games/' + accessCode + '/players',
|
||||
'PATCH',
|
||||
null,
|
||||
JSON.stringify({ cookie: cookie })
|
||||
)
|
||||
.then((res) => {
|
||||
UserUtility.setAnonymousUserId(res.content, environmentResponse.content);
|
||||
stateBucket.accessCode = accessCode;
|
||||
stateBucket.joinRequestInFlight = false;
|
||||
cookie = res.content;
|
||||
setClientSocketHandlers(stateBucket, gameStateRenderer, socket, timerWorker, gameTimerManager);
|
||||
prepareGamePage(stateBucket, accessCode, gameTimerManager, gameStateRenderer, timerWorker, socket, cookie);
|
||||
}).catch((res) => {
|
||||
if (res.status === 404) {
|
||||
window.location = '/not-found?reason=' + encodeURIComponent('game-not-found');
|
||||
} else if (res.status >= 500) {
|
||||
toast(
|
||||
'The server is experiencing problems. Please try again later',
|
||||
'error',
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
socket.emit(globals.COMMANDS.FETCH_GAME_STATE, accessCode, cookie, function (gameState) {
|
||||
cookie = gameState.client.cookie;
|
||||
UserUtility.setAnonymousUserId(cookie, stateBucket.environment);
|
||||
stateBucket.currentGameState = gameState;
|
||||
document.querySelector('.spinner-container')?.remove();
|
||||
document.querySelector('.spinner-background')?.remove();
|
||||
document.getElementById('game-content').innerHTML = templates.INITIAL_GAME_DOM;
|
||||
toast('You are connected.', 'success', true, true, 2);
|
||||
processGameState(stateBucket.currentGameState, cookie, socket, gameStateRenderer, gameTimerManager, timerWorker);
|
||||
if (!gameState.client.hasEnteredName) {
|
||||
document.getElementById('prompt').innerHTML = templates.NAME_CHANGE_MODAL;
|
||||
document.getElementById('change-name-form').onsubmit = (e) => {
|
||||
e.preventDefault();
|
||||
const name = document.getElementById('player-new-name').value;
|
||||
if (validateName(name)) {
|
||||
socket.emit(globals.COMMANDS.CHANGE_NAME, gameState.accessCode, {
|
||||
name: name,
|
||||
personId: gameState.client.id
|
||||
}, (result) => {
|
||||
switch (result) {
|
||||
case 'taken':
|
||||
toast('This name is already taken.', 'error', true, true, 8);
|
||||
break;
|
||||
case 'changed':
|
||||
ModalManager.dispelModal('change-name-modal', 'change-name-modal-background');
|
||||
toast('Name set.', 'success', true, true, 5);
|
||||
propagateNameChange(stateBucket.currentGameState, name, stateBucket.currentGameState.client.id);
|
||||
processGameState(stateBucket.currentGameState, cookie, socket, gameStateRenderer, gameTimerManager, timerWorker);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toast('Name must be between 1 and 30 characters.', 'error', true, true, 8);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
} else {
|
||||
window.location = '/not-found?reason=' + encodeURIComponent('invalid-access-code');
|
||||
}
|
||||
}
|
||||
|
||||
function prepareGamePage (stateBucket, accessCode, gameTimerManager, gameStateRenderer, timerWorker, socket, cookie) {
|
||||
socket.emit(globals.COMMANDS.FETCH_GAME_STATE, accessCode, cookie, function (gameState) {
|
||||
stateBucket.currentGameState = gameState;
|
||||
document.querySelector('.spinner-container')?.remove();
|
||||
document.querySelector('.spinner-background')?.remove();
|
||||
document.getElementById('game-content').innerHTML = templates.INITIAL_GAME_DOM;
|
||||
toast('You are connected.', 'success', true, true, 2);
|
||||
processGameState(stateBucket.currentGameState, cookie, socket, gameStateRenderer, gameTimerManager, timerWorker);
|
||||
if (!gameState.client.hasEnteredName) {
|
||||
document.getElementById('prompt').innerHTML = templates.NAME_CHANGE_MODAL;
|
||||
document.getElementById('change-name-form').onsubmit = (e) => {
|
||||
e.preventDefault();
|
||||
const name = document.getElementById('player-new-name').value;
|
||||
if (validateName(name)) {
|
||||
socket.emit(globals.COMMANDS.CHANGE_NAME, gameState.accessCode, {
|
||||
name: name,
|
||||
personId: gameState.client.id
|
||||
}, (result) => {
|
||||
switch (result) {
|
||||
case 'taken':
|
||||
toast('This name is already taken.', 'error', true, true, 8);
|
||||
break;
|
||||
case 'changed':
|
||||
ModalManager.dispelModal('change-name-modal', 'change-name-modal-background');
|
||||
toast('Name set.', 'success', true, true, 5);
|
||||
propagateNameChange(stateBucket.currentGameState, name, stateBucket.currentGameState.client.id);
|
||||
processGameState(stateBucket.currentGameState, cookie, socket, gameStateRenderer, gameTimerManager, timerWorker);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toast('Name must be between 1 and 30 characters.', 'error', true, true, 8);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function processGameState (currentGameState, userId, socket, gameStateRenderer, gameTimerManager, timerWorker, refreshPrompt = true) {
|
||||
displayClientInfo(currentGameState.client.name, currentGameState.client.userType);
|
||||
if (refreshPrompt) {
|
||||
|
||||
@@ -19,7 +19,7 @@ const apiLimiter = rateLimit({
|
||||
const corsOptions = process.env.NODE_ENV.trim() === 'development'
|
||||
? {
|
||||
origin: '*',
|
||||
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
|
||||
optionsSuccessStatus: 200
|
||||
}
|
||||
: {
|
||||
origin: 'https://playwerewolf.uk.r.appspot.com',
|
||||
@@ -27,7 +27,7 @@ const corsOptions = process.env.NODE_ENV.trim() === 'development'
|
||||
};
|
||||
|
||||
router.use(cors(corsOptions));
|
||||
router.options('/:code/players', cors(corsOptions)); // enable pre-flight request for DELETE
|
||||
//router.options('/:code/players', cors(corsOptions));
|
||||
|
||||
if (process.env.NODE_ENV.trim() === 'production') { // in prod, limit clients to creating 5 games per 10 minutes.
|
||||
router.use('/create', apiLimiter);
|
||||
@@ -65,21 +65,21 @@ router.get('/:code/availability', function (req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.patch('/:code/players', function (req, res) {
|
||||
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.patch('/:code/players', function (req, res) {
|
||||
// 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);
|
||||
|
||||
@@ -14,9 +14,9 @@ class GameManager {
|
||||
}
|
||||
|
||||
addGameSocketHandlers = (namespace, socket) => {
|
||||
socket.on(globals.CLIENT_COMMANDS.FETCH_GAME_STATE, (accessCode, personId, ackFn) => {
|
||||
socket.on(globals.CLIENT_COMMANDS.FETCH_GAME_STATE, async (accessCode, personId, ackFn) => {
|
||||
this.logger.trace('request for game state for accessCode: ' + accessCode + ' from socket: ' + socket.id + ' with cookie: ' + personId);
|
||||
this.handleRequestForGameState(
|
||||
await this.handleRequestForGameState(
|
||||
this.namespace,
|
||||
this.logger,
|
||||
this.activeGameRunner,
|
||||
@@ -253,59 +253,55 @@ class GameManager {
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
joinGame = (game) => {
|
||||
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 unassignedPerson;
|
||||
} 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 spectator;
|
||||
}
|
||||
};
|
||||
|
||||
handleRequestForGameState = (namespace, logger, gameRunner, accessCode, personCookie, ackFn, socket) => {
|
||||
handleRequestForGameState = async (namespace, logger, gameRunner, accessCode, personCookie, ackFn, clientSocket) => {
|
||||
const game = gameRunner.activeGames[accessCode];
|
||||
if (game) {
|
||||
const matchingPerson = findPersonByField(game, 'cookie', personCookie);
|
||||
if (matchingPerson) {
|
||||
if (matchingPerson.socketId === socket.id) {
|
||||
if (matchingPerson.socketId === clientSocket.id) {
|
||||
logger.trace('matching person found with an established connection to the room: ' + matchingPerson.name);
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson, gameRunner, socket, logger));
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson, gameRunner, clientSocket, logger));
|
||||
} else {
|
||||
logger.trace('matching person found with a new connection to the room: ' + matchingPerson.name);
|
||||
socket.join(accessCode);
|
||||
matchingPerson.socketId = socket.id;
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson, gameRunner, socket, logger));
|
||||
clientSocket.join(accessCode);
|
||||
matchingPerson.socketId = clientSocket.id;
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson, gameRunner, clientSocket, logger));
|
||||
}
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
const namespaceSockets = await namespace.in(accessCode).fetchSockets();
|
||||
if (!namespaceSockets.find((namespaceSocket) => namespaceSocket.id === clientSocket.id)) {
|
||||
let newlyAssignedPerson = this.joinGame(game);
|
||||
clientSocket.join(accessCode);
|
||||
newlyAssignedPerson.socketId = clientSocket.id;
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, newlyAssignedPerson, gameRunner, clientSocket, logger));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
|
||||
Reference in New Issue
Block a user