mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 15:57:50 +01:00
progress on new lobby
This commit is contained in:
@@ -2,10 +2,13 @@ const globals = require('../config/globals');
|
||||
const ActiveGameRunner = require('./ActiveGameRunner');
|
||||
const Game = require('../model/Game');
|
||||
const Person = require('../model/Person');
|
||||
const GameStateCurator = require('./GameStateCurator');
|
||||
const UsernameGenerator = require('./UsernameGenerator');
|
||||
|
||||
class GameManager {
|
||||
constructor (logger) {
|
||||
constructor (logger, environment) {
|
||||
this.logger = logger;
|
||||
this.environment = environment;
|
||||
this.activeGameRunner = new ActiveGameRunner().getInstance();
|
||||
this.namespace = null;
|
||||
//this.gameSocketUtility = GameSocketUtility;
|
||||
@@ -14,8 +17,20 @@ class GameManager {
|
||||
addGameSocketHandlers = (namespace, socket) => {
|
||||
this.namespace = namespace;
|
||||
socket.on(globals.CLIENT_COMMANDS.FETCH_GAME_STATE, (accessCode, personId, ackFn) => {
|
||||
handleRequestForGameState(this.namespace, this.logger, this.activeGameRunner, accessCode, personId, ackFn, socket);
|
||||
handleRequestForGameState(
|
||||
this.namespace,
|
||||
this.logger,
|
||||
this.activeGameRunner,
|
||||
accessCode,
|
||||
personId,
|
||||
ackFn,
|
||||
socket
|
||||
);
|
||||
});
|
||||
|
||||
socket.on(globals.CLIENT_COMMANDS.GET_ENVIRONMENT, (ackFn) => {
|
||||
ackFn(this.environment);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +41,18 @@ class GameManager {
|
||||
return Promise.reject('Tried to create game with invalid options: ' + gameParams);
|
||||
} else {
|
||||
const newAccessCode = this.generateAccessCode();
|
||||
let moderator = initializeModerator(gameParams.moderatorName, gameParams.hasDedicatedModerator);
|
||||
this.activeGameRunner.activeGames[newAccessCode] = new Game(
|
||||
globals.STATUS.LOBBY,
|
||||
initializePeopleForGame(gameParams.moderatorName, gameParams.deck),
|
||||
initializePeopleForGame(gameParams.deck),
|
||||
gameParams.deck,
|
||||
gameParams.hasTimer,
|
||||
moderator,
|
||||
gameParams.timerParams
|
||||
);
|
||||
if (!gameParams.hasDedicatedModerator) {
|
||||
this.activeGameRunner.activeGames[newAccessCode].people.push(moderator);
|
||||
}
|
||||
return Promise.resolve(newAccessCode);
|
||||
}
|
||||
}
|
||||
@@ -69,14 +89,16 @@ function getRandomInt (max) {
|
||||
return Math.floor(Math.random() * Math.floor(max));
|
||||
}
|
||||
|
||||
function initializeModerator(name) {
|
||||
return new Person(createRandomUserId(), name, globals.USER_TYPES.MODERATOR)
|
||||
function initializeModerator(name, hasDedicatedModerator) {
|
||||
const userType = hasDedicatedModerator
|
||||
? globals.USER_TYPES.MODERATOR
|
||||
: globals.USER_TYPES.TEMPORARY_MODERATOR;
|
||||
return new Person(createRandomUserId(), name, userType)
|
||||
}
|
||||
|
||||
function initializePeopleForGame(modName, uniqueCards) {
|
||||
function initializePeopleForGame(uniqueCards) {
|
||||
let people = [];
|
||||
let cards = []; // this will contain copies of each card equal to the quantity.
|
||||
people.push(initializeModerator(modName));
|
||||
let numberOfRoles = 0;
|
||||
for (let card of uniqueCards) {
|
||||
for (let i = 0; i < card.quantity; i ++) {
|
||||
@@ -88,7 +110,7 @@ function initializePeopleForGame(modName, uniqueCards) {
|
||||
cards = shuffleArray(cards); // The deck should probably be shuffled, ey?.
|
||||
|
||||
for(let j = 0; j < numberOfRoles; j ++) {
|
||||
people.push(new Person(createRandomUserId(), null, globals.USER_TYPES.PLAYER, cards[j].role, cards[j].description))
|
||||
people.push(new Person(createRandomUserId(), UsernameGenerator.generate(), globals.USER_TYPES.PLAYER, cards[j].role, cards[j].description))
|
||||
}
|
||||
|
||||
return people;
|
||||
@@ -113,10 +135,10 @@ function createRandomUserId () {
|
||||
}
|
||||
|
||||
class Singleton {
|
||||
constructor (logger) {
|
||||
constructor (logger, environment) {
|
||||
if (!Singleton.instance) {
|
||||
logger.log('CREATING SINGLETON GAME MANAGER');
|
||||
Singleton.instance = new GameManager(logger);
|
||||
Singleton.instance = new GameManager(logger, environment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,16 +159,19 @@ function handleRequestForGameState(namespace, logger, gameRunner, accessCode, pe
|
||||
const game = gameRunner.activeGames[accessCode];
|
||||
if (game) {
|
||||
let matchingPerson = game.people.find((person) => person.id === personId);
|
||||
if (!matchingPerson && game.moderator.id === personId) {
|
||||
matchingPerson = game.moderator;
|
||||
}
|
||||
if (matchingPerson) {
|
||||
if (matchingPerson.socketId === socket.id) {
|
||||
logger.debug("matching person found with an established connection to the room: " + matchingPerson.name);
|
||||
ackFn(getGameStateFromPerspectiveOfPerson(game, matchingPerson));
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson));
|
||||
} else {
|
||||
if (!roomContainsSocketOfMatchingPerson(namespace, matchingPerson, logger, accessCode)) {
|
||||
logger.debug("matching person found with a new connection to the room: " + matchingPerson.name);
|
||||
socket.join(accessCode);
|
||||
matchingPerson.socketId = socket.id;
|
||||
ackFn(getGameStateFromPerspectiveOfPerson(game, matchingPerson));
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, matchingPerson));
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
}
|
||||
@@ -155,15 +180,21 @@ function handleRequestForGameState(namespace, logger, gameRunner, accessCode, pe
|
||||
let personWithMatchingSocketId = findPersonWithMatchingSocketId(game.people, socket.id);
|
||||
if (personWithMatchingSocketId) {
|
||||
logger.debug("matching person found whose cookie got cleared after establishing a connection to the room: " + personWithMatchingSocketId.name);
|
||||
ackFn(getGameStateFromPerspectiveOfPerson(game, personWithMatchingSocketId));
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, personWithMatchingSocketId));
|
||||
} else {
|
||||
let unassignedPerson = game.people.find((person) => person.assigned === false);
|
||||
let unassignedPerson = game.moderator.assigned === false
|
||||
? game.moderator
|
||||
: game.people.find((person) => person.assigned === false);
|
||||
if (unassignedPerson) {
|
||||
logger.debug("completely new person with a first connection to the room: " + unassignedPerson.name);
|
||||
socket.join(accessCode);
|
||||
unassignedPerson.assigned = true;
|
||||
unassignedPerson.socketId = socket.id;
|
||||
ackFn(getGameStateFromPerspectiveOfPerson(game, unassignedPerson));
|
||||
ackFn(GameStateCurator.getGameStateFromPerspectiveOfPerson(game, unassignedPerson));
|
||||
socket.to(accessCode).emit(
|
||||
globals.EVENTS.PLAYER_JOINED,
|
||||
{ name: unassignedPerson.name }
|
||||
);
|
||||
} else {
|
||||
rejectClientRequestForGameState(ackFn);
|
||||
}
|
||||
@@ -174,10 +205,6 @@ function handleRequestForGameState(namespace, logger, gameRunner, accessCode, pe
|
||||
}
|
||||
}
|
||||
|
||||
function getGameStateFromPerspectiveOfPerson(game, person) {
|
||||
return person;
|
||||
}
|
||||
|
||||
// in socket.io 2.x , the rooms property is an object. in 3.x and 4.x, it is a javascript Set.
|
||||
function roomContainsSocketOfMatchingPerson(namespace, matchingPerson, logger, accessCode) {
|
||||
return namespace.adapter
|
||||
|
||||
84
server/modules/GameStateCurator.js
Normal file
84
server/modules/GameStateCurator.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const globals = require("../config/globals")
|
||||
|
||||
const GameStateCurator = {
|
||||
getGameStateFromPerspectiveOfPerson: (game, person) => {
|
||||
return getGameStateBasedOnPermissions(game, person);
|
||||
}
|
||||
}
|
||||
|
||||
function getGameStateBasedOnPermissions(game, person) {
|
||||
let client = game.status === globals.STATUS.LOBBY // people won't be able to know their role until past the lobby stage.
|
||||
? { name: person.name, id: person.id }
|
||||
: {
|
||||
name: person.name,
|
||||
id: person.id,
|
||||
gameRole: person.gameRole,
|
||||
roleDescription: person.roleDescription
|
||||
}
|
||||
switch (person.userType) {
|
||||
case globals.USER_TYPES.PLAYER:
|
||||
return {
|
||||
status: game.status,
|
||||
moderator: mapPerson(game.moderator),
|
||||
userType: globals.USER_TYPES.PLAYER,
|
||||
client: client,
|
||||
deck: game.deck,
|
||||
people: game.people
|
||||
.filter((person) => {
|
||||
return person.assigned === true && person.id !== client.id && person.userType !== globals.USER_TYPES.MODERATOR
|
||||
})
|
||||
.map((filteredPerson) => ({ name: filteredPerson.name, userType: filteredPerson.userType })),
|
||||
timerParams: game.timerParams
|
||||
}
|
||||
case globals.USER_TYPES.MODERATOR:
|
||||
return {
|
||||
status: game.status,
|
||||
moderator: mapPerson(game.moderator),
|
||||
userType: globals.USER_TYPES.MODERATOR,
|
||||
client: client,
|
||||
deck: game.deck,
|
||||
people: mapPeopleForModerator(game.people, client),
|
||||
timerParams: game.timerParams
|
||||
}
|
||||
case globals.USER_TYPES.TEMPORARY_MODERATOR:
|
||||
return {
|
||||
status: game.status,
|
||||
moderator: mapPerson(game.moderator),
|
||||
userType: globals.USER_TYPES.TEMPORARY_MODERATOR,
|
||||
client: client,
|
||||
deck: game.deck,
|
||||
people: mapPeopleForTempModerator(game.people, client),
|
||||
timerParams: game.timerParams
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function mapPeopleForModerator(people, client) {
|
||||
return people
|
||||
.filter((person) => {
|
||||
return person.assigned === true && person.id !== client.id
|
||||
})
|
||||
.map((person) => ({
|
||||
name: person.name,
|
||||
gameRole: person.gameRole,
|
||||
gameRoleDescription: person.gameRoleDescription
|
||||
}));
|
||||
}
|
||||
|
||||
function mapPeopleForTempModerator(people, client) {
|
||||
return people
|
||||
.filter((person) => {
|
||||
return person.assigned === true && person.id !== client.id
|
||||
})
|
||||
.map((person) => ({
|
||||
name: person.name,
|
||||
}));
|
||||
}
|
||||
|
||||
function mapPerson(person) {
|
||||
return { name: person.name };
|
||||
}
|
||||
|
||||
module.exports = GameStateCurator;
|
||||
@@ -15,6 +15,12 @@ module.exports = function (debugMode = false) {
|
||||
if (!debugMode) return;
|
||||
const now = new Date();
|
||||
console.error('ERROR ', now.toGMTString(), ': ', message);
|
||||
},
|
||||
|
||||
warn (message = '') {
|
||||
if (!debugMode) return;
|
||||
const now = new Date();
|
||||
console.error('WARNING ', now.toGMTString(), ': ', message);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
1338
server/modules/UsernameGenerator.js
Normal file
1338
server/modules/UsernameGenerator.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user