Files
Werewolf/client/src/modules/DeckStateManager.js
2022-02-26 00:25:53 -05:00

164 lines
6.0 KiB
JavaScript

import { globals } from '../config/globals.js';
import { toast } from './Toast.js';
import { ModalManager } from './ModalManager.js';
export class DeckStateManager {
constructor () {
this.deck = null;
this.customRoleOptions = [];
this.createMode = false;
this.currentlyEditingRoleName = null;
}
addToDeck (role) {
const option = this.customRoleOptions.find((option) => option.role === role);
if (option) {
option.quantity = 0;
this.deck.push(option);
this.customRoleOptions.splice(this.customRoleOptions.indexOf(option), 1);
}
}
addToCustomRoleOptions (role) {
this.customRoleOptions.push(role);
localStorage.setItem('play-werewolf-custom-roles', JSON.stringify(this.customRoleOptions.concat(this.deck.filter(card => card.custom === true))));
}
updateCustomRoleOption (option, name, description, team) {
option.role = name;
option.description = description;
option.team = team;
localStorage.setItem('play-werewolf-custom-roles', JSON.stringify(this.customRoleOptions.concat(this.deck.filter(card => card.custom === true))));
}
removeFromCustomRoleOptions (name) {
const option = this.customRoleOptions.find((option) => option.role === name);
if (option) {
this.customRoleOptions.splice(this.customRoleOptions.indexOf(option), 1);
localStorage.setItem('play-werewolf-custom-roles', JSON.stringify(this.customRoleOptions.concat(this.deck.filter(card => card.custom === true))));
toast('"' + name + '" deleted.', 'error', true, true, 'short');
}
}
addCopyOfCard (role) {
const existingCard = this.deck.find((card) => card.role === role);
if (existingCard) {
existingCard.quantity += 1;
}
}
removeCopyOfCard (role) {
const existingCard = this.deck.find((card) => card.role === role);
if (existingCard && existingCard.quantity > 0) {
existingCard.quantity -= 1;
}
}
getCurrentDeck () { return this.deck; }
getCard (role) {
return this.deck.find(
(card) => card.role.toLowerCase().trim() === role.toLowerCase().trim()
);
}
getCurrentCustomRoleOptions () { return this.customRoleOptions; }
getCustomRoleOption (role) {
return this.customRoleOptions.find(
(option) => option.role.toLowerCase().trim() === role.toLowerCase().trim()
);
};
getDeckSize () {
let total = 0;
for (const role of this.deck) {
total += role.quantity;
}
return total;
}
loadCustomRolesFromCookies () {
const customRoles = localStorage.getItem('play-werewolf-custom-roles');
if (customRoles !== null && validateCustomRoleCookie(customRoles)) {
this.customRoleOptions = JSON.parse(customRoles); // we know it is valid JSON from the validate function
}
}
loadCustomRolesFromFile (file, updateRoleListFunction, loadDefaultCardsFn, showIncludedCardsFn) {
const reader = new FileReader();
reader.onerror = (e) => {
toast(reader.error.message, 'error', true, true, 'medium');
};
reader.onload = (e) => {
let string;
if (typeof e.target.result !== 'string') {
string = new TextDecoder('utf-8').decode(e.target.result);
} else {
string = e.target.result;
}
if (validateCustomRoleCookie(string)) {
this.customRoleOptions = JSON.parse(string); // we know it is valid JSON from the validate function
ModalManager.dispelModal('upload-custom-roles-modal', 'modal-background');
toast('Roles imported successfully', 'success', true, true, 'short');
localStorage.setItem('play-werewolf-custom-roles', JSON.stringify(this.customRoleOptions));
updateRoleListFunction(this, document.getElementById('deck-select'));
// loadDefaultCardsFn(this);
// showIncludedCardsFn(this);
} else {
toast(
'Invalid formatting. Make sure you import the file as downloaded from this page.',
'error',
true,
true,
'medium'
);
}
};
reader.readAsText(file);
}
// via https://stackoverflow.com/a/18197341
downloadCustomRoles (filename, text) {
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
}
// this is user-supplied, so we should validate it fully
function validateCustomRoleCookie (cookie) {
const valid = false;
if (typeof cookie === 'string' && new Blob([cookie]).size <= 1000000) {
try {
const cookieJSON = JSON.parse(cookie);
if (Array.isArray(cookieJSON)) {
for (const entry of cookieJSON) {
if (typeof entry === 'object') {
if (typeof entry.role !== 'string' || entry.role.length > globals.MAX_CUSTOM_ROLE_NAME_LENGTH
|| typeof entry.team !== 'string' || (entry.team !== globals.ALIGNMENT.GOOD && entry.team !== globals.ALIGNMENT.EVIL)
|| typeof entry.description !== 'string' || entry.description.length > globals.MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH
) {
return false;
}
} else {
return false;
}
}
return true;
}
} catch (e) {
return false;
}
}
return valid;
}