mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 07:47:50 +01:00
Merge pull request #105 from AlecM33/4-digit-access-codes
4-digit access codes
This commit is contained in:
@@ -4,7 +4,7 @@ export const globals = {
|
||||
MAX_CUSTOM_ROLE_NAME_LENGTH: 30,
|
||||
MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH: 500,
|
||||
TOAST_DURATION_DEFAULT: 6,
|
||||
ACCESS_CODE_LENGTH: 6,
|
||||
ACCESS_CODE_LENGTH: 4,
|
||||
PLAYER_ID_COOKIE_KEY: 'play-werewolf-anon-id',
|
||||
ACCESS_CODE_CHAR_POOL: 'abcdefghijklmnopqrstuvwxyz0123456789',
|
||||
COMMANDS: {
|
||||
|
||||
@@ -462,7 +462,7 @@ function showButtons (back, forward, forwardHandler, backHandler, builtGame = nu
|
||||
// Display a widget for each default card that allows copies of it to be added/removed. Set initial deck state.
|
||||
function showIncludedCards (deckManager) {
|
||||
document.querySelectorAll('.compact-card').forEach((el) => { el.remove(); });
|
||||
for (let i = 0; i < deckManager.getCurrentDeck().length; i++) {
|
||||
for (let i = 0; i < deckManager.getCurrentDeck().length; i ++) {
|
||||
const card = deckManager.getCurrentDeck()[i];
|
||||
const cardEl = constructCompactDeckBuilderElement(card, deckManager);
|
||||
if (card.team === globals.ALIGNMENT.GOOD) {
|
||||
@@ -487,7 +487,7 @@ function loadDefaultCards (deckManager) {
|
||||
return a.role.localeCompare(b.role);
|
||||
});
|
||||
const deck = [];
|
||||
for (let i = 0; i < defaultCards.length; i++) {
|
||||
for (let i = 0; i < defaultCards.length; i ++) {
|
||||
const card = defaultCards[i];
|
||||
card.quantity = 0;
|
||||
deck.push(card);
|
||||
@@ -631,7 +631,7 @@ function addOptionsToList (deckManager, selectEl) {
|
||||
}
|
||||
return a.role.localeCompare(b.role);
|
||||
});
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
for (let i = 0; i < options.length; i ++) {
|
||||
const optionEl = document.createElement('div');
|
||||
optionEl.innerHTML = HTMLFragments.DECK_SELECT_ROLE;
|
||||
optionEl.classList.add('deck-select-role');
|
||||
|
||||
@@ -56,7 +56,7 @@ export const UserUtility = {
|
||||
|
||||
function createRandomUserId () {
|
||||
let id = '';
|
||||
for (let i = 0; i < globals.USER_SIGNATURE_LENGTH; i++) {
|
||||
for (let i = 0; i < globals.USER_SIGNATURE_LENGTH; i ++) {
|
||||
id += globals.ACCESS_CODE_CHAR_POOL[Math.floor(Math.random() * globals.ACCESS_CODE_CHAR_POOL.length)];
|
||||
}
|
||||
return id;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const globals = {
|
||||
ACCESS_CODE_CHAR_POOL: 'BCDFGHJKLMNPQRSTVWXYZ0123456789',
|
||||
ACCESS_CODE_LENGTH: 6,
|
||||
ACCESS_CODE_LENGTH: 4,
|
||||
ACCESS_CODE_GENERATION_ATTEMPTS: 50,
|
||||
CLOCK_TICK_INTERVAL_MILLIS: 10,
|
||||
STALE_GAME_HOURS: 12,
|
||||
CLIENT_COMMANDS: {
|
||||
@@ -33,7 +34,8 @@ const globals = {
|
||||
},
|
||||
ERROR_MESSAGE: {
|
||||
GAME_IS_FULL: 'This game is full',
|
||||
BAD_CREATE_REQUEST: 'Game has invalid options.'
|
||||
BAD_CREATE_REQUEST: 'Game has invalid options.',
|
||||
NO_UNIQUE_ACCESS_CODE: 'Could not generate a unique access code.'
|
||||
},
|
||||
EVENTS: {
|
||||
PLAYER_JOINED: 'playerJoined',
|
||||
|
||||
@@ -171,7 +171,10 @@ class GameManager {
|
||||
} else {
|
||||
// to avoid excessive memory build-up, every time a game is created, check for and purge any stale games.
|
||||
pruneStaleGames(this.activeGameRunner.activeGames, this.activeGameRunner.timerThreads, this.logger);
|
||||
const newAccessCode = this.generateAccessCode();
|
||||
const newAccessCode = this.generateAccessCode(globals.ACCESS_CODE_CHAR_POOL);
|
||||
if (newAccessCode === null) {
|
||||
return Promise.reject(globals.ERROR_MESSAGE.NO_UNIQUE_ACCESS_CODE);
|
||||
}
|
||||
const moderator = initializeModerator(gameParams.moderatorName, gameParams.hasDedicatedModerator);
|
||||
moderator.assigned = true;
|
||||
if (gameParams.timerParams !== null) {
|
||||
@@ -205,15 +208,23 @@ class GameManager {
|
||||
}
|
||||
};
|
||||
|
||||
generateAccessCode = () => {
|
||||
const numLetters = globals.ACCESS_CODE_CHAR_POOL.length;
|
||||
const codeDigits = [];
|
||||
let iterations = globals.ACCESS_CODE_LENGTH;
|
||||
while (iterations > 0) {
|
||||
iterations--;
|
||||
codeDigits.push(globals.ACCESS_CODE_CHAR_POOL[getRandomInt(numLetters)]);
|
||||
generateAccessCode = (charPool) => {
|
||||
const charCount = charPool.length;
|
||||
let codeDigits, accessCode;
|
||||
let attempts = 0;
|
||||
while (!accessCode || (this.activeGameRunner.activeGames[accessCode] && attempts < globals.ACCESS_CODE_GENERATION_ATTEMPTS)) {
|
||||
codeDigits = [];
|
||||
let iterations = globals.ACCESS_CODE_LENGTH;
|
||||
while (iterations > 0) {
|
||||
iterations --;
|
||||
codeDigits.push(charPool[getRandomInt(charCount)]);
|
||||
}
|
||||
accessCode = codeDigits.join('');
|
||||
attempts ++;
|
||||
}
|
||||
return codeDigits.join('');
|
||||
return this.activeGameRunner.activeGames[accessCode]
|
||||
? null
|
||||
: accessCode;
|
||||
};
|
||||
|
||||
transferModeratorPowers = (game, person, namespace, logger) => {
|
||||
@@ -362,9 +373,9 @@ function initializePeopleForGame (uniqueCards, moderator) {
|
||||
let cards = []; // this will contain copies of each card equal to the quantity.
|
||||
let numberOfRoles = 0;
|
||||
for (const card of uniqueCards) {
|
||||
for (let i = 0; i < card.quantity; i++) {
|
||||
for (let i = 0; i < card.quantity; i ++) {
|
||||
cards.push(card);
|
||||
numberOfRoles++;
|
||||
numberOfRoles ++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +388,7 @@ function initializePeopleForGame (uniqueCards, moderator) {
|
||||
moderator.gameRoleDescription = cards[j].description;
|
||||
moderator.alignment = cards[j].team;
|
||||
people.push(moderator);
|
||||
j++;
|
||||
j ++;
|
||||
}
|
||||
|
||||
while (j < numberOfRoles) {
|
||||
@@ -393,14 +404,14 @@ function initializePeopleForGame (uniqueCards, moderator) {
|
||||
person.customRole = cards[j].custom;
|
||||
person.hasEnteredName = false;
|
||||
people.push(person);
|
||||
j++;
|
||||
j ++;
|
||||
}
|
||||
|
||||
return people;
|
||||
}
|
||||
|
||||
function shuffleArray (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
for (let i = 0; i < array.length; i ++) {
|
||||
const randIndex = Math.floor(Math.random() * i);
|
||||
const temp = array[i];
|
||||
array[i] = array[randIndex];
|
||||
@@ -411,7 +422,7 @@ function shuffleArray (array) {
|
||||
|
||||
function createRandomId () {
|
||||
let id = '';
|
||||
for (let i = 0; i < globals.USER_SIGNATURE_LENGTH; i++) {
|
||||
for (let i = 0; i < globals.USER_SIGNATURE_LENGTH; i ++) {
|
||||
id += globals.ACCESS_CODE_CHAR_POOL[Math.floor(Math.random() * globals.ACCESS_CODE_CHAR_POOL.length)];
|
||||
}
|
||||
return id;
|
||||
|
||||
@@ -260,4 +260,24 @@ describe('GameManager', () => {
|
||||
expect(gameManager.namespace.in().emit).toHaveBeenCalledWith(globals.EVENTS.NEW_SPECTATOR, jasmine.anything());
|
||||
});
|
||||
});
|
||||
|
||||
describe('#generateAccessCode', () => {
|
||||
it('should continue to generate access codes up to the max attempts when the generated code is already in use by another game', () => {
|
||||
gameManager.activeGameRunner.activeGames = {
|
||||
AAAA: {}
|
||||
};
|
||||
|
||||
const accessCode = gameManager.generateAccessCode(['A']);
|
||||
expect(accessCode).toEqual(null); // we might the max generation attempts of 50.
|
||||
});
|
||||
|
||||
it('should generate and return a unique access code', () => {
|
||||
gameManager.activeGameRunner.activeGames = {
|
||||
AAAA: {}
|
||||
};
|
||||
|
||||
const accessCode = gameManager.generateAccessCode(['B']);
|
||||
expect(accessCode).toEqual('BBBB');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user