{ "version": 3, "sources": ["../../../../server/chat-plugins/mafia.ts"], "sourcesContent": ["import {Utils, FS} from '../../lib';\r\n\r\ninterface MafiaData {\r\n\t// keys for all of these are IDs\r\n\talignments: {[k: string]: MafiaDataAlignment};\r\n\troles: {[k: string]: MafiaDataRole};\r\n\tthemes: {[k: string]: MafiaDataTheme};\r\n\tIDEAs: {[k: string]: MafiaDataIDEA};\r\n\tterms: {[k: string]: MafiaDataTerm};\r\n\taliases: {[k: string]: ID};\r\n}\r\ninterface MafiaDataAlignment {\r\n\tname: string;\r\n\tplural: string;\r\n\tcolor?: string;\r\n\tbuttonColor?: string;\r\n\tmemo: string[];\r\n\timage?: string;\r\n}\r\ninterface MafiaDataRole {\r\n\tname: string;\r\n\tmemo: string[];\r\n\talignment?: string;\r\n\timage?: string;\r\n}\r\ninterface MafiaDataTheme {\r\n\tname: string;\r\n\tdesc: string;\r\n\t// roles\r\n\t[players: number]: string;\r\n}\r\ninterface MafiaDataIDEA {\r\n\tname: string;\r\n\troles: string[];\r\n\tpicks: string[];\r\n\tchoices: number;\r\n}\r\ninterface MafiaDataTerm {\r\n\tname: string;\r\n\tmemo: string[];\r\n}\r\n\r\ninterface MafiaLogTable {\r\n\t[date: string]: {[userid: string]: number};\r\n}\r\ntype MafiaLogSection = 'leaderboard' | 'mvps' | 'hosts' | 'plays' | 'leavers';\r\ntype MafiaLog = {[section in MafiaLogSection]: MafiaLogTable};\r\n\r\ninterface MafiaRole {\r\n\tname: string;\r\n\tsafeName: string;\r\n\tid: string;\r\n\tmemo: string[];\r\n\talignment: string;\r\n\timage: string;\r\n}\r\n\r\ninterface MafiaVote {\r\n\t// number of people on this vote\r\n\tcount: number;\r\n\t// number of votes, accounting for doublevoter etc\r\n\ttrueCount: number;\r\n\tlastVote: number;\r\n\tdir: 'up' | 'down';\r\n\tvoters: ID[];\r\n}\r\n\r\ninterface MafiaIDEAData {\r\n\tname: string;\r\n\t// do we trust the roles to parse properly\r\n\tuntrusted?: true;\r\n\troles: string[];\r\n\t// eg, GestI has 3 choices\r\n\tchoices: number;\r\n\t// eg, GestI has 2 things to pick, role and alignment\r\n\tpicks: string[];\r\n}\r\ninterface MafiaIDEAModule {\r\n\tdata: MafiaIDEAData | null;\r\n\ttimer: NodeJS.Timer | null;\r\n\tdiscardsHidden: boolean;\r\n\tdiscardsHTML: string;\r\n\t// users that haven't picked a role yet\r\n\twaitingPick: string[];\r\n}\r\ninterface MafiaIDEAPlayerData {\r\n\tchoices: string[];\r\n\toriginalChoices: string[];\r\n\tpicks: {[choice: string]: string | null};\r\n}\r\n\r\nconst DATA_FILE = 'config/chat-plugins/mafia-data.json';\r\nconst LOGS_FILE = 'config/chat-plugins/mafia-logs.json';\r\n\r\n// see: https://play.pokemonshowdown.com/fx/\r\nconst VALID_IMAGES = [\r\n\t'cop', 'dead', 'doctor', 'fool', 'godfather', 'goon', 'hooker', 'mafia', 'mayor', 'villager', 'werewolf',\r\n];\r\n\r\nlet MafiaData: MafiaData = Object.create(null);\r\nlet logs: MafiaLog = {leaderboard: {}, mvps: {}, hosts: {}, plays: {}, leavers: {}};\r\n\r\nPunishments.addRoomPunishmentType({\r\n\ttype: 'MAFIAGAMEBAN',\r\n\tdesc: 'banned from playing mafia games',\r\n});\r\nPunishments.addRoomPunishmentType({\r\n\ttype: 'MAFIAHOSTBAN',\r\n\tdesc: 'banned from hosting mafia games',\r\n});\r\n\r\nconst hostQueue: ID[] = [];\r\n\r\nconst IDEA_TIMER = 60 * 1000;\r\n\r\nfunction readFile(path: string) {\r\n\ttry {\r\n\t\tconst json = FS(path).readIfExistsSync();\r\n\t\tif (!json) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn Object.assign(Object.create(null), JSON.parse(json));\r\n\t} catch (e: any) {\r\n\t\tif (e.code !== 'ENOENT') throw e;\r\n\t}\r\n}\r\nfunction writeFile(path: string, data: AnyObject) {\r\n\tFS(path).writeUpdate(() => (\r\n\t\tJSON.stringify(data)\r\n\t));\r\n}\r\n\r\n// data assumptions -\r\n// the alignments \"town\" and \"solo\" always exist (defaults)\r\n// .alignment is always a valid key in data.alignments\r\n// roles and alignments have no common keys (looked up together in the role parser)\r\n// themes and IDEAs have no common keys (looked up together when setting themes)\r\n\r\n// Load data\r\nMafiaData = readFile(DATA_FILE) || {alignments: {}, roles: {}, themes: {}, IDEAs: {}, terms: {}, aliases: {}};\r\nif (!MafiaData.alignments.town) {\r\n\tMafiaData.alignments.town = {\r\n\t\tname: 'town', plural: 'town', memo: [`This alignment is required for the script to function properly.`],\r\n\t};\r\n}\r\nif (!MafiaData.alignments.solo) {\r\n\tMafiaData.alignments.solo = {\r\n\t\tname: 'solo', plural: 'solo', memo: [`This alignment is required for the script to function properly.`],\r\n\t};\r\n}\r\n\r\nlogs = readFile(LOGS_FILE) || {leaderboard: {}, mvps: {}, hosts: {}, plays: {}, leavers: {}};\r\n\r\nconst tables: MafiaLogSection[] = ['leaderboard', 'mvps', 'hosts', 'plays', 'leavers'];\r\nfor (const section of tables) {\r\n\t// Check to see if we need to eliminate an old month's data.\r\n\tconst month = new Date().toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\tif (!logs[section]) logs[section] = {};\r\n\tif (!logs[section][month]) logs[section][month] = {};\r\n\tif (Object.keys(logs[section]).length >= 3) {\r\n\t\t// eliminate the oldest month(s)\r\n\t\tconst keys = Utils.sortBy(Object.keys(logs[section]), key => {\r\n\t\t\tconst [monthStr, yearStr] = key.split('/');\r\n\t\t\treturn [parseInt(yearStr), parseInt(monthStr)];\r\n\t\t});\r\n\t\twhile (keys.length > 2) {\r\n\t\t\tconst curKey = keys.shift();\r\n\t\t\tif (!curKey) break; // should never happen\r\n\t\t\tdelete logs[section][curKey];\r\n\t\t}\r\n\t}\r\n}\r\nwriteFile(LOGS_FILE, logs);\r\n\r\nclass MafiaPlayer extends Rooms.RoomGamePlayer {\r\n\tsafeName: string;\r\n\trole: MafiaRole | null;\r\n\tvoting: ID;\r\n\t/** false - can't hammer (priest), true - can only hammer (actor) */\r\n\thammerRestriction: null | boolean;\r\n\tlastVote: number;\r\n\ttreestump: boolean;\r\n\trestless: boolean;\r\n\tsilenced: boolean;\r\n\tnighttalk: boolean;\r\n\trevealed: string;\r\n\tIDEA: MafiaIDEAPlayerData | null;\r\n\t/** false - used an action, true - idled, null - no response */\r\n\taction: null | boolean | string;\r\n\tactionArr: string[];\r\n\tconstructor(user: User, game: Mafia) {\r\n\t\tsuper(user, game);\r\n\t\tthis.safeName = Utils.escapeHTML(this.name);\r\n\t\tthis.role = null;\r\n\t\tthis.voting = '';\r\n\t\tthis.hammerRestriction = null;\r\n\t\tthis.lastVote = 0;\r\n\t\tthis.treestump = false;\r\n\t\tthis.restless = false;\r\n\t\tthis.silenced = false;\r\n\t\tthis.nighttalk = false;\r\n\t\tthis.revealed = '';\r\n\t\tthis.IDEA = null;\r\n\t\tthis.action = null;\r\n\t\tthis.actionArr = [];\r\n\t}\r\n\r\n\tgetRole(button = false) {\r\n\t\tif (!this.role) return;\r\n\t\tlet color = MafiaData.alignments[this.role.alignment].color;\r\n\t\tif (button && MafiaData.alignments[this.role.alignment].buttonColor) {\r\n\t\t\tcolor = MafiaData.alignments[this.role.alignment].buttonColor;\r\n\t\t}\r\n\t\treturn `${this.role.safeName}`;\r\n\t}\r\n\r\n\tupdateHtmlRoom() {\r\n\t\tconst user = Users.get(this.id);\r\n\t\tif (!user?.connected) return;\r\n\t\tif (this.game.ended) return user.send(`>view-mafia-${this.game.room.roomid}\\n|deinit`);\r\n\t\tfor (const conn of user.connections) {\r\n\t\t\tvoid Chat.resolvePage(`view-mafia-${this.game.room.roomid}`, user, conn);\r\n\t\t}\r\n\t}\r\n\tupdateHtmlVotes() {\r\n\t\tconst user = Users.get(this.id);\r\n\t\tif (!user?.connected) return;\r\n\t\tconst votes = this.game.voteBoxFor(this.id);\r\n\t\tuser.send(`>view-mafia-${this.game.room.roomid}\\n|selectorhtml|#mafia-votes|` + votes);\r\n\t}\r\n}\r\n\r\nclass Mafia extends Rooms.RoomGame {\r\n\tstarted: boolean;\r\n\ttheme: MafiaDataTheme | null;\r\n\thostid: ID;\r\n\thost: string;\r\n\tcohostids: ID[];\r\n\tcohosts: string[];\r\n\tdead: {[userid: string]: MafiaPlayer};\r\n\r\n\tsubs: ID[];\r\n\tautoSub: boolean;\r\n\trequestedSub: ID[];\r\n\thostRequestedSub: ID[];\r\n\tplayed: ID[];\r\n\r\n\thammerCount: number;\r\n\tvotes: {[userid: string]: MafiaVote};\r\n\tvoteModifiers: {[userid: string]: number};\r\n\thammerModifiers: {[userid: string]: number};\r\n\thasPlurality: ID | null;\r\n\r\n\tenableNL: boolean;\r\n\tvoteLock: boolean;\r\n\tvotingAll: boolean;\r\n\tforceVote: boolean;\r\n\tclosedSetup: boolean;\r\n\tnoReveal: boolean;\r\n\tselfEnabled: boolean | 'hammer';\r\n\ttakeIdles: boolean;\r\n\r\n\toriginalRoles: MafiaRole[];\r\n\toriginalRoleString: string;\r\n\troles: MafiaRole[];\r\n\troleString: string;\r\n\r\n\tphase: 'signups' | 'locked' | 'IDEApicking' | 'IDEAlocked' | 'day' | 'night';\r\n\tdayNum: number;\r\n\r\n\ttimer: NodeJS.Timer | null;\r\n\tdlAt: number;\r\n\r\n\tIDEA: MafiaIDEAModule;\r\n\tconstructor(room: ChatRoom, host: User) {\r\n\t\tsuper(room);\r\n\r\n\t\tthis.gameid = 'mafia' as ID;\r\n\t\tthis.title = 'Mafia';\r\n\t\tthis.playerCap = 20;\r\n\t\tthis.allowRenames = false;\r\n\t\tthis.started = false;\r\n\t\tthis.ended = false;\r\n\r\n\t\tthis.theme = null;\r\n\r\n\t\tthis.hostid = host.id;\r\n\t\tthis.host = Utils.escapeHTML(host.name);\r\n\t\tthis.cohostids = [];\r\n\t\tthis.cohosts = [];\r\n\r\n\t\tthis.dead = Object.create(null);\r\n\t\tthis.subs = [];\r\n\t\tthis.autoSub = true;\r\n\t\tthis.requestedSub = [];\r\n\t\tthis.hostRequestedSub = [];\r\n\t\tthis.played = [];\r\n\r\n\t\tthis.hammerCount = 0;\r\n\t\tthis.votes = Object.create(null);\r\n\t\tthis.voteModifiers = Object.create(null);\r\n\t\tthis.hammerModifiers = Object.create(null);\r\n\t\tthis.hasPlurality = null;\r\n\r\n\t\tthis.enableNL = true;\r\n\t\tthis.voteLock = false;\r\n\t\tthis.votingAll = true;\r\n\t\tthis.forceVote = false;\r\n\t\tthis.closedSetup = false;\r\n\t\tthis.noReveal = true;\r\n\t\tthis.selfEnabled = false;\r\n\t\tthis.takeIdles = true;\r\n\r\n\t\tthis.originalRoles = [];\r\n\t\tthis.originalRoleString = '';\r\n\t\tthis.roles = [];\r\n\t\tthis.roleString = '';\r\n\r\n\t\tthis.phase = \"signups\";\r\n\t\tthis.dayNum = 0;\r\n\t\tthis.timer = null;\r\n\t\tthis.dlAt = 0;\r\n\r\n\t\tthis.IDEA = {\r\n\t\t\tdata: null,\r\n\t\t\ttimer: null,\r\n\t\t\tdiscardsHidden: false,\r\n\t\t\tdiscardsHTML: '',\r\n\t\t\twaitingPick: [],\r\n\t\t};\r\n\r\n\t\tthis.sendHTML(this.roomWindow());\r\n\t}\r\n\r\n\tjoin(user: User) {\r\n\t\tif (this.phase !== 'signups') return user.sendTo(this.room, `|error|The game of ${this.title} has already started.`);\r\n\t\tthis.canJoin(user, true);\r\n\t\tif (this.playerCount >= this.playerCap) return user.sendTo(this.room, `|error|The game of ${this.title} is full.`);\r\n\t\tif (!this.addPlayer(user)) return user.sendTo(this.room, `|error|You have already joined the game of ${this.title}.`);\r\n\t\tif (this.subs.includes(user.id)) this.subs.splice(this.subs.indexOf(user.id), 1);\r\n\t\tthis.playerTable[user.id].updateHtmlRoom();\r\n\t\tthis.sendRoom(`${this.playerTable[user.id].name} has joined the game.`);\r\n\t}\r\n\r\n\tleave(user: User) {\r\n\t\tif (!(user.id in this.playerTable)) {\r\n\t\t\treturn user.sendTo(this.room, `|error|You have not joined the game of ${this.title}.`);\r\n\t\t}\r\n\t\tif (this.phase !== 'signups') return user.sendTo(this.room, `|error|The game of ${this.title} has already started.`);\r\n\t\tthis.playerTable[user.id].destroy();\r\n\t\tdelete this.playerTable[user.id];\r\n\t\tthis.playerCount--;\r\n\t\tlet subIndex = this.requestedSub.indexOf(user.id);\r\n\t\tif (subIndex !== -1) this.requestedSub.splice(subIndex, 1);\r\n\t\tsubIndex = this.hostRequestedSub.indexOf(user.id);\r\n\t\tif (subIndex !== -1) this.hostRequestedSub.splice(subIndex, 1);\r\n\t\tthis.sendRoom(`${user.name} has left the game.`);\r\n\t\tfor (const conn of user.connections) {\r\n\t\t\tvoid Chat.resolvePage(`view-mafia-${this.room.roomid}`, user, conn);\r\n\t\t}\r\n\t}\r\n\r\n\tstatic isGameBanned(room: Room, user: User) {\r\n\t\treturn Punishments.hasRoomPunishType(room, toID(user), 'MAFIAGAMEBAN');\r\n\t}\r\n\r\n\tstatic gameBan(room: Room, user: User, reason: string, duration: number) {\r\n\t\tPunishments.roomPunish(room, user, {\r\n\t\t\ttype: 'MAFIAGAMEBAN',\r\n\t\t\tid: toID(user),\r\n\t\t\texpireTime: Date.now() + (duration * 24 * 60 * 60 * 1000),\r\n\t\t\treason,\r\n\t\t});\r\n\t}\r\n\r\n\tstatic ungameBan(room: Room, user: User) {\r\n\t\tPunishments.roomUnpunish(room, toID(user), 'MAFIAGAMEBAN', false);\r\n\t}\r\n\r\n\tstatic isHostBanned(room: Room, user: User) {\r\n\t\treturn Mafia.isGameBanned(room, user) || Punishments.hasRoomPunishType(room, toID(user), 'MAFIAGAMEBAN');\r\n\t}\r\n\r\n\tstatic hostBan(room: Room, user: User, reason: string, duration: number) {\r\n\t\tPunishments.roomPunish(room, user, {\r\n\t\t\ttype: 'MAFIAHOSTBAN',\r\n\t\t\tid: toID(user),\r\n\t\t\texpireTime: Date.now() + (duration * 24 * 60 * 60 * 1000),\r\n\t\t\treason,\r\n\t\t});\r\n\t}\r\n\r\n\tstatic unhostBan(room: Room, user: User) {\r\n\t\tPunishments.roomUnpunish(room, toID(user), 'MAFIAHOSTBAN', false);\r\n\t}\r\n\r\n\tmakePlayer(user: User) {\r\n\t\treturn new MafiaPlayer(user, this);\r\n\t}\r\n\r\n\tsetRoles(user: User, roleString: string, force = false, reset = false) {\r\n\t\tlet roles = roleString.split(',').map(x => x.trim());\r\n\r\n\t\tif (roles.length === 1) {\r\n\t\t\t// Attempt to set roles from a theme\r\n\t\t\tlet themeName: string = toID(roles[0]);\r\n\t\t\tif (themeName in MafiaData.aliases) themeName = MafiaData.aliases[themeName];\r\n\r\n\t\t\tif (themeName in MafiaData.themes) {\r\n\t\t\t\t// setting a proper theme\r\n\t\t\t\tconst theme = MafiaData.themes[themeName];\r\n\t\t\t\tif (!theme[this.playerCount]) {\r\n\t\t\t\t\treturn user.sendTo(\r\n\t\t\t\t\t\tthis.room,\r\n\t\t\t\t\t\t`|error|The theme \"${theme.name}\" does not have a role list for ${this.playerCount} players.`\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tconst themeRoles: string = theme[this.playerCount];\r\n\t\t\t\troles = themeRoles.split(',').map(x => x.trim());\r\n\t\t\t\tthis.theme = theme;\r\n\t\t\t} else if (themeName in MafiaData.IDEAs) {\r\n\t\t\t\t// setting an IDEA's rolelist as a theme, a la Great Idea\r\n\t\t\t\tconst IDEA = MafiaData.IDEAs[themeName];\r\n\t\t\t\troles = IDEA.roles;\r\n\t\t\t\tthis.theme = null;\r\n\t\t\t} else {\r\n\t\t\t\treturn user.sendTo(this.room, `|error|${roles[0]} is not a valid theme or IDEA.`);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.theme = null;\r\n\t\t}\r\n\r\n\t\tif (roles.length < this.playerCount) {\r\n\t\t\treturn user.sendTo(this.room, `|error|You have not provided enough roles for the players.`);\r\n\t\t} else if (roles.length > this.playerCount) {\r\n\t\t\tuser.sendTo(\r\n\t\t\t\tthis.room,\r\n\t\t\t\t`|error|You have provided too many roles, ${roles.length - this.playerCount} ${Chat.plural(roles.length - this.playerCount, 'roles', 'role')} will not be assigned.`\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (force) {\r\n\t\t\tthis.originalRoles = roles.map(r => ({\r\n\t\t\t\tname: r,\r\n\t\t\t\tsafeName: Utils.escapeHTML(r),\r\n\t\t\t\tid: toID(r),\r\n\t\t\t\talignment: 'solo',\r\n\t\t\t\timage: '',\r\n\t\t\t\tmemo: [`To learn more about your role, PM the host (${this.host}).`],\r\n\t\t\t}));\r\n\t\t\tUtils.sortBy(this.originalRoles, role => role.name);\r\n\t\t\tthis.roles = this.originalRoles.slice();\r\n\t\t\tthis.originalRoleString = this.originalRoles.map(\r\n\t\t\t\tr => `${r.safeName}`\r\n\t\t\t).join(', ');\r\n\t\t\tthis.roleString = this.originalRoleString;\r\n\t\t\tthis.sendRoom(`The roles have been ${reset ? 're' : ''}set.`);\r\n\t\t\tif (reset) this.distributeRoles();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst newRoles: MafiaRole[] = [];\r\n\t\tconst problems: string[] = [];\r\n\t\tconst alignments: string[] = [];\r\n\t\tconst cache: {[k: string]: MafiaRole} = Object.create(null);\r\n\t\tfor (const roleName of roles) {\r\n\t\t\tconst roleId = roleName.toLowerCase().replace(/[^\\w\\d\\s]/g, '');\r\n\t\t\tif (roleId in cache) {\r\n\t\t\t\tnewRoles.push({...cache[roleId]});\r\n\t\t\t} else {\r\n\t\t\t\tconst role = Mafia.parseRole(roleName);\r\n\t\t\t\tif (role.problems.length) {\r\n\t\t\t\t\tproblems.push(...role.problems);\r\n\t\t\t\t}\r\n\t\t\t\tif (!alignments.includes(role.role.alignment)) alignments.push(role.role.alignment);\r\n\t\t\t\tcache[roleId] = role.role;\r\n\t\t\t\tnewRoles.push(role.role);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (alignments.length < 2 && alignments[0] !== 'solo') {\r\n\t\t\tproblems.push(`There must be at least 2 different alignments in a game!`);\r\n\t\t}\r\n\t\tif (problems.length) {\r\n\t\t\tfor (const problem of problems) {\r\n\t\t\t\tuser.sendTo(this.room, `|error|${problem}`);\r\n\t\t\t}\r\n\t\t\treturn user.sendTo(this.room, `|error|To forcibly set the roles, use /mafia force${reset ? \"re\" : \"\"}setroles`);\r\n\t\t}\r\n\r\n\t\tthis.IDEA.data = null;\r\n\r\n\t\tthis.originalRoles = newRoles;\r\n\t\tUtils.sortBy(this.originalRoles, role => [role.alignment, role.name]);\r\n\t\tthis.roles = this.originalRoles.slice();\r\n\t\tthis.originalRoleString = this.originalRoles.map(\r\n\t\t\tr => `${r.safeName}`\r\n\t\t).join(', ');\r\n\t\tthis.roleString = this.originalRoleString;\r\n\r\n\t\tif (!reset) this.phase = 'locked';\r\n\t\tthis.updatePlayers();\r\n\t\tthis.sendRoom(`The roles have been ${reset ? 're' : ''}set.`);\r\n\t\tif (reset) this.distributeRoles();\r\n\t}\r\n\r\n\tresetGame() {\r\n\t\tthis.clearVotes();\r\n\t\tthis.dayNum = 0;\r\n\t\tthis.phase = 'night';\r\n\t\tfor (const hostid of [...this.cohostids, this.hostid]) {\r\n\t\t\tconst host = Users.get(hostid);\r\n\t\t\tif (host?.connected) host.send(`>${this.room.roomid}\\n|notify|It's night in your game of Mafia!`);\r\n\t\t}\r\n\t\tfor (const player of Object.values(this.playerTable)) {\r\n\t\t\tconst user = Users.get(player.id);\r\n\t\t\tif (user?.connected) {\r\n\t\t\t\tuser.sendTo(this.room.roomid, `|notify|It's night in the game of Mafia! Send in an action or idle.`);\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (const player in this.playerTable) {\r\n\t\t\tthis.playerTable[player].actionArr.splice(0, this.playerTable[player].actionArr.length);\r\n\t\t}\r\n\t\tif (this.timer) this.setDeadline(0);\r\n\t\tthis.sendDeclare(`The game has been reset.`);\r\n\t\tthis.distributeRoles();\r\n\t\tif (this.takeIdles) {\r\n\t\t\tthis.sendDeclare(`Night ${this.dayNum}. Submit whether you are using an action or idle. If you are using an action, DM your action to the host.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`Night ${this.dayNum}. PM the host your action, or idle.`);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\tstatic parseRole(roleString: string) {\r\n\t\tconst roleName = roleString.replace(/solo/, '').trim();\r\n\r\n\t\tconst role = {\r\n\t\t\tname: roleName,\r\n\t\t\tsafeName: Utils.escapeHTML(roleName),\r\n\t\t\tid: toID(roleName),\r\n\t\t\timage: '',\r\n\t\t\tmemo: ['During the Day, you may vote for someone to be eliminated.'],\r\n\t\t\talignment: '',\r\n\t\t};\r\n\t\tconst problems: string[] = [];\r\n\r\n\t\t// if a role has a modifier with an alignment and a proper alignment,\r\n\t\t// the proper alignment overrides the modifier's alignment\r\n\t\tlet modAlignment = '';\r\n\r\n\t\tconst roleWords = roleString\r\n\t\t\t.replace(/\\(.+?\\)/g, '') // remove (notes within brackets)\r\n\t\t\t.split(' ')\r\n\t\t\t.map(toID);\r\n\r\n\t\tlet iters = 0;\r\n\t\touter: while (roleWords.length) {\r\n\t\t\tconst currentWord = roleWords.slice();\r\n\r\n\t\t\twhile (currentWord.length) {\r\n\t\t\t\tif (iters++ === 1000) throw new Error(`Infinite loop.`);\r\n\r\n\t\t\t\tlet currentSearch = currentWord.join('');\r\n\t\t\t\tif (currentSearch in MafiaData.aliases) currentSearch = MafiaData.aliases[currentSearch];\r\n\r\n\t\t\t\tif (currentSearch in MafiaData.roles) {\r\n\t\t\t\t\t// we found something with our current search, remove it from the main role and restart\r\n\t\t\t\t\tconst mod = MafiaData.roles[currentSearch];\r\n\r\n\t\t\t\t\tif (mod.memo) role.memo.push(...mod.memo);\r\n\t\t\t\t\tif (mod.alignment && !modAlignment) modAlignment = mod.alignment;\r\n\t\t\t\t\tif (mod.image && !role.image) role.image = mod.image;\r\n\r\n\t\t\t\t\troleWords.splice(0, currentWord.length);\r\n\t\t\t\t\tcontinue outer;\r\n\t\t\t\t} else if (currentSearch in MafiaData.alignments) {\r\n\t\t\t\t\tif (role.alignment && role.alignment !== currentSearch) {\r\n\t\t\t\t\t\tproblems.push(`The role ${roleString} has multiple possible alignments (${role.alignment} and ${currentSearch})`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\trole.alignment = currentSearch;\r\n\r\n\t\t\t\t\troleWords.splice(0, currentWord.length);\r\n\t\t\t\t\tcontinue outer;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// we didnt find something, take the last word off our current search and continue\r\n\t\t\t\tcurrentWord.pop();\r\n\t\t\t}\r\n\t\t\t// no matches, take the first word off and continue\r\n\t\t\troleWords.shift();\r\n\t\t}\r\n\r\n\t\trole.alignment = role.alignment || modAlignment;\r\n\t\tif (!role.alignment) {\r\n\t\t\t// Default to town\r\n\t\t\trole.alignment = 'town';\r\n\t\t}\r\n\t\tif (problems.length) {\r\n\t\t\t// multiple possible alignment, default to solo\r\n\t\t\trole.alignment = 'solo';\r\n\t\t\trole.memo.push(`Your role has multiple conflicting alignments, ask the host for details.`);\r\n\t\t} else {\r\n\t\t\tconst alignment = MafiaData.alignments[role.alignment];\r\n\t\t\tif (alignment) {\r\n\t\t\t\trole.memo.push(...MafiaData.alignments[role.alignment].memo);\r\n\t\t\t\tif (alignment.image && !role.image) role.image = alignment.image;\r\n\t\t\t} else {\r\n\t\t\t\tproblems.push(`Alignment desync: role ${role.name}'s alignment ${role.alignment} doesn't exist in data. Please report this to a mod.`);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {role, problems};\r\n\t}\r\n\r\n\tstart(user: User, day = false) {\r\n\t\tif (!user) return;\r\n\t\tif (this.phase !== 'locked' && this.phase !== 'IDEAlocked') {\r\n\t\t\tif (this.phase === 'signups') return user.sendTo(this.room, `You need to close the signups first.`);\r\n\t\t\tif (this.phase === 'IDEApicking') {\r\n\t\t\t\treturn user.sendTo(this.room, `You must wait for IDEA picks to finish before starting.`);\r\n\t\t\t}\r\n\t\t\treturn user.sendTo(this.room, `The game is already started!`);\r\n\t\t}\r\n\t\tif (this.playerCount < 2) return user.sendTo(this.room, `You need at least 2 players to start.`);\r\n\t\tif (this.phase === 'IDEAlocked') {\r\n\t\t\tfor (const p in this.playerTable) {\r\n\t\t\t\tif (!this.playerTable[p].role) return user.sendTo(this.room, `|error|Not all players have a role.`);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (!Object.keys(this.roles).length) return user.sendTo(this.room, `You need to set the roles before starting.`);\r\n\t\t\tif (Object.keys(this.roles).length < this.playerCount) {\r\n\t\t\t\treturn user.sendTo(this.room, `You have not provided enough roles for the players.`);\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.started = true;\r\n\t\tthis.sendDeclare(`The game of ${this.title} is starting!`);\r\n\t\t// Mafia#played gets set in distributeRoles\r\n\t\tthis.distributeRoles();\r\n\t\tif (day) {\r\n\t\t\tthis.day(null, true);\r\n\t\t} else {\r\n\t\t\tthis.night(false, true);\r\n\t\t}\r\n\t\tif (this.IDEA.data && !this.IDEA.discardsHidden) {\r\n\t\t\tthis.room.add(`|html|
IDEA discards:${this.IDEA.discardsHTML}
`).update();\r\n\t\t}\r\n\t}\r\n\r\n\tdistributeRoles() {\r\n\t\tconst roles = Utils.shuffle(this.roles.slice());\r\n\t\tif (roles.length) {\r\n\t\t\tfor (const p in this.playerTable) {\r\n\t\t\t\tconst role = roles.shift()!;\r\n\t\t\t\tthis.playerTable[p].role = role;\r\n\t\t\t\tconst u = Users.get(p);\r\n\t\t\t\tthis.playerTable[p].revealed = '';\r\n\t\t\t\tif (u?.connected) {\r\n\t\t\t\t\tu.send(`>${this.room.roomid}\\n|notify|Your role is ${role.safeName}. For more details of your role, check your Role PM.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.dead = {};\r\n\t\tthis.played = [this.hostid, ...this.cohostids, ...(Object.keys(this.playerTable) as ID[])];\r\n\t\tthis.sendDeclare(`The roles have been distributed.`);\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\r\n\tgetPartners(alignment: string, player: MafiaPlayer) {\r\n\t\tif (!player?.role || ['town', 'solo', 'traitor'].includes(player.role.alignment)) return \"\";\r\n\t\tconst partners = [];\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tif (p === player.id) continue;\r\n\t\t\tconst role = this.playerTable[p].role;\r\n\t\t\tif (role && role.alignment === player.role.alignment) partners.push(this.playerTable[p].name);\r\n\t\t}\r\n\t\treturn partners.join(\", \");\r\n\t}\r\n\r\n\tday(extension: number | null = null, initial = false) {\r\n\t\tif (this.phase !== 'night' && !initial) return;\r\n\t\tif (this.dayNum === 0 && extension !== null) return this.sendUser(this.hostid, `|error|You cannot extend on day 0.`);\r\n\t\tif (this.timer) this.setDeadline(0);\r\n\t\tif (extension === null) {\r\n\t\t\tif (!isNaN(this.hammerCount)) this.hammerCount = Math.floor(Object.keys(this.playerTable).length / 2) + 1;\r\n\t\t\tthis.clearVotes();\r\n\t\t}\r\n\t\tthis.phase = 'day';\r\n\t\tif (extension !== null && !initial) {\r\n\t\t\t// Day stays same\r\n\t\t\tthis.setDeadline(extension);\r\n\t\t} else {\r\n\t\t\tthis.dayNum++;\r\n\t\t}\r\n\t\tif (isNaN(this.hammerCount)) {\r\n\t\t\tthis.sendDeclare(`Day ${this.dayNum}. Hammering is disabled.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`Day ${this.dayNum}. The hammer count is set at ${this.hammerCount}`);\r\n\t\t}\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tthis.playerTable[p].action = null;\r\n\t\t}\r\n\t\tthis.sendPlayerList();\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\r\n\tnight(early = false, initial = false) {\r\n\t\tif (this.phase !== 'day' && !initial) return;\r\n\t\tif (this.timer) this.setDeadline(0, true);\r\n\t\tthis.phase = 'night';\r\n\t\tfor (const hostid of [...this.cohostids, this.hostid]) {\r\n\t\t\tconst host = Users.get(hostid);\r\n\t\t\tif (host?.connected) host.send(`>${this.room.roomid}\\n|notify|It's night in your game of Mafia!`);\r\n\t\t}\r\n\t\tfor (const player of Object.values(this.playerTable)) {\r\n\t\t\tconst user = Users.get(player.id);\r\n\t\t\tif (user?.connected) {\r\n\t\t\t\tuser.sendTo(this.room.roomid, `|notify|It's night in the game of Mafia! Send in an action or idle.`);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (this.takeIdles) {\r\n\t\t\tthis.sendDeclare(`Night ${this.dayNum}. Submit whether you are using an action or idle. If you are using an action, DM your action to the host.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`Night ${this.dayNum}. PM the host your action, or idle.`);\r\n\t\t}\r\n\t\tconst hasPlurality = this.getPlurality();\r\n\t\tif (!early && hasPlurality) {\r\n\t\t\tthis.sendRoom(`Plurality is on ${this.playerTable[hasPlurality] ? this.playerTable[hasPlurality].name : 'No Vote'}`);\r\n\t\t}\r\n\t\tif (!early && !initial) this.sendRoom(`|raw|
${this.voteBox()}
`);\r\n\t\tif (initial && !isNaN(this.hammerCount)) this.hammerCount = Math.floor(Object.keys(this.playerTable).length / 2) + 1;\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\r\n\tvote(userid: ID, target: ID) {\r\n\t\tif (!this.votingAll) return this.sendUser(userid, `|error|Voting is not allowed.`);\r\n\t\tif (this.phase !== 'day') return this.sendUser(userid, `|error|You can only vote during the day.`);\r\n\t\tlet player = this.playerTable[userid];\r\n\t\tif (!player && this.dead[userid] && this.dead[userid].restless) player = this.dead[userid];\r\n\t\tif (!player) return;\r\n\t\tif (!(target in this.playerTable) && target !== 'novote') {\r\n\t\t\treturn this.sendUser(userid, `|error|${target} is not a valid player.`);\r\n\t\t}\r\n\t\tif (!this.enableNL && target === 'novote') return this.sendUser(userid, `|error|No Vote is not allowed.`);\r\n\t\tif (target === player.id && !this.selfEnabled) return this.sendUser(userid, `|error|Self voting is not allowed.`);\r\n\t\tif (this.voteLock && player.voting) {\r\n\t\t\treturn this.sendUser(userid, `|error|You cannot switch your vote because votes are locked.`);\r\n\t\t}\r\n\t\tconst hammering = this.hammerCount - 1 <= (this.votes[target] ? this.votes[target].count : 0);\r\n\t\tif (target === player.id && !hammering && this.selfEnabled === 'hammer') {\r\n\t\t\treturn this.sendUser(userid, `|error|You may only vote yourself when placing the hammer vote.`);\r\n\t\t}\r\n\t\tif (player.hammerRestriction !== null) {\r\n\t\t\tthis.sendUser(userid, `${this.hammerCount - 1} <= ${(this.votes[target] ? this.votes[target].count : 0)}`);\r\n\t\t\tif (player.hammerRestriction && !hammering) {\r\n\t\t\t\treturn this.sendUser(userid, `|error|You can only vote when placing the hammer vote.`);\r\n\t\t\t}\r\n\t\t\tif (!player.hammerRestriction && hammering) return this.sendUser(userid, `|error|You cannot place the hammer vote.`);\r\n\t\t}\r\n\t\tif (player.lastVote + 2000 >= Date.now()) {\r\n\t\t\treturn this.sendUser(\r\n\t\t\t\tuserid,\r\n\t\t\t\t`|error|You must wait another ${Chat.toDurationString((player.lastVote + 2000) - Date.now()) || '1 second'} before you can change your vote.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tconst previousVote = player.voting;\r\n\t\tif (previousVote) this.unvote(userid, true);\r\n\t\tlet vote = this.votes[target];\r\n\t\tif (!vote) {\r\n\t\t\tthis.votes[target] = {\r\n\t\t\t\tcount: 1, trueCount: this.getVoteValue(userid), lastVote: Date.now(), dir: 'up', voters: [userid],\r\n\t\t\t};\r\n\t\t\tvote = this.votes[target];\r\n\t\t} else {\r\n\t\t\tvote.count++;\r\n\t\t\tvote.trueCount += this.getVoteValue(userid);\r\n\t\t\tvote.lastVote = Date.now();\r\n\t\t\tvote.dir = 'up';\r\n\t\t\tvote.voters.push(userid);\r\n\t\t}\r\n\t\tplayer.voting = target;\r\n\t\tconst name = player.voting === 'novote' ? 'No Vote' : this.playerTable[player.voting].name;\r\n\t\tconst targetUser = Users.get(userid);\r\n\t\tif (previousVote) {\r\n\t\t\tthis.sendTimestamp(`${(targetUser ? targetUser.name : userid)} has shifted their vote from ${previousVote === 'novote' ? 'No Vote' : this.playerTable[previousVote].name} to ${name}`);\r\n\t\t} else {\r\n\t\t\tthis.sendTimestamp(\r\n\t\t\t\tname === 'No Vote' ?\r\n\t\t\t\t\t`${(targetUser ? targetUser.name : userid)} has abstained from voting.` :\r\n\t\t\t\t\t`${(targetUser ? targetUser.name : userid)} has voted ${name}.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tplayer.lastVote = Date.now();\r\n\t\tthis.hasPlurality = null;\r\n\t\tif (this.getHammerValue(target) <= vote.trueCount) {\r\n\t\t\t// HAMMER\r\n\t\t\tthis.sendDeclare(`Hammer! ${target === 'novote' ? 'Nobody' : Utils.escapeHTML(name)} was voted out!`);\r\n\t\t\tthis.sendRoom(`|raw|
${this.voteBox()}
`);\r\n\t\t\tif (target !== 'novote') this.eliminate(target, 'kill');\r\n\t\t\tthis.night(true);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.updatePlayersVotes();\r\n\t}\r\n\r\n\tunvote(userid: ID, force = false) {\r\n\t\tif (this.phase !== 'day' && !force) return this.sendUser(userid, `|error|You can only vote during the day.`);\r\n\t\tlet player = this.playerTable[userid];\r\n\r\n\t\t// autoselfvote blocking doesn't apply to restless spirits\r\n\t\tif (player && this.forceVote && !force) {\r\n\t\t\treturn this.sendUser(userid, `|error|You can only shift your vote, not unvote.`);\r\n\t\t}\r\n\r\n\t\tif (!player && this.dead[userid] && this.dead[userid].restless) player = this.dead[userid];\r\n\t\tif (!player?.voting) return this.sendUser(userid, `|error|You are not voting for anyone.`);\r\n\t\tif (this.voteLock && player?.voting) {\r\n\t\t\treturn this.sendUser(userid, `|error|You cannot unvote because votes are locked.`);\r\n\t\t}\r\n\t\tif (player.lastVote + 2000 >= Date.now() && !force) {\r\n\t\t\treturn this.sendUser(\r\n\t\t\t\tuserid,\r\n\t\t\t\t`|error|You must wait another ${Chat.toDurationString((player.lastVote + 2000) - Date.now()) || '1 second'} before you can change your vote.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tconst vote = this.votes[player.voting];\r\n\t\tvote.count--;\r\n\t\tvote.trueCount -= this.getVoteValue(userid);\r\n\t\tif (vote.count <= 0) {\r\n\t\t\tdelete this.votes[player.voting];\r\n\t\t} else {\r\n\t\t\tvote.lastVote = Date.now();\r\n\t\t\tvote.dir = 'down';\r\n\t\t\tvote.voters.splice(vote.voters.indexOf(userid), 1);\r\n\t\t}\r\n\t\tconst targetUser = Users.get(userid);\r\n\t\tif (!force) {\r\n\t\t\tthis.sendTimestamp(\r\n\t\t\t\tplayer.voting === 'novote' ?\r\n\t\t\t\t\t`${(targetUser ? targetUser.name : userid)} is no longer abstaining from voting.` :\r\n\t\t\t\t\t`${(targetUser ? targetUser.name : userid)} has unvoted ${this.playerTable[player.voting].name}.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tplayer.voting = '';\r\n\t\tplayer.lastVote = Date.now();\r\n\t\tthis.hasPlurality = null;\r\n\t\tthis.updatePlayersVotes();\r\n\t}\r\n\r\n\t/**\r\n\t * Returns HTML code that contains information about the current vote.\r\n\t */\r\n\tvoteBox() {\r\n\t\tif (!this.started) return `The game has not started yet.`;\r\n\t\tlet buf = `Votes (Hammer: ${this.hammerCount || \"Disabled\"})
`;\r\n\t\tconst plur = this.getPlurality();\r\n\t\tconst list = Utils.sortBy(Object.entries(this.votes), ([key, vote]) => [\r\n\t\t\tkey === plur,\r\n\t\t\t-vote.count,\r\n\t\t]);\r\n\t\tfor (const [key, vote] of list) {\r\n\t\t\tbuf += `${vote.count}${plur === key ? '*' : ''} ${this.playerTable[key]?.safeName || 'No Vote'} (${vote.voters.map(a => this.playerTable[a]?.safeName || a).join(', ')})
`;\r\n\t\t}\r\n\t\treturn buf;\r\n\t}\r\n\tvoteBoxFor(userid: ID) {\r\n\t\tlet buf = '';\r\n\t\tbuf += `

Votes (Hammer: ${this.hammerCount || 'Disabled'})

`;\r\n\t\tconst plur = this.getPlurality();\r\n\t\tfor (const key of Object.keys(this.playerTable).concat((this.enableNL ? ['novote'] : [])) as ID[]) {\r\n\t\t\tif (this.votes[key]) {\r\n\t\t\t\tbuf += `

${this.votes[key].count}${plur === key ? '*' : ''} ${this.playerTable[key] ? `${this.playerTable[key].safeName} ${this.playerTable[key].revealed ? `[${this.playerTable[key].revealed}]` : ''}` : 'No Vote'} (${this.votes[key].voters.map(a => this.playerTable[a] ? this.playerTable[a].safeName : a).join(', ')}) `;\r\n\t\t\t} else {\r\n\t\t\t\tbuf += `

0 ${this.playerTable[key] ? `${this.playerTable[key].safeName} ${this.playerTable[key].revealed ? `[${this.playerTable[key].revealed}]` : ''}` : 'No Vote'} `;\r\n\t\t\t}\r\n\t\t\tconst isPlayer = (this.playerTable[userid]);\r\n\t\t\tconst isSpirit = (this.dead[userid] && this.dead[userid].restless);\r\n\t\t\tif (this.votingAll && !(this.voteLock && (isPlayer?.voting || (isSpirit && this.dead[userid].voting))) &&\r\n\t\t\t(isPlayer || isSpirit)) {\r\n\t\t\t\tif (isPlayer && this.playerTable[userid].voting === key || isSpirit && this.dead[userid].voting === key) {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t} else if ((this.selfEnabled && !isSpirit) || userid !== key) {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t}\r\n\t\t\t} else if (userid === this.hostid || this.cohostids.includes(userid)) {\r\n\t\t\t\tconst vote = this.votes[key];\r\n\t\t\t\tif (vote && vote.count !== vote.trueCount) buf += `(${vote.trueCount})`;\r\n\t\t\t\tif (this.hammerModifiers[key]) buf += `(${this.getHammerValue(key)} to hammer)`;\r\n\t\t\t}\r\n\t\t\tbuf += `

`;\r\n\t\t}\r\n\t\treturn buf;\r\n\t}\r\n\tapplyVoteModifier(user: User, target: ID, mod: number) {\r\n\t\tconst targetPlayer = this.playerTable[target] || this.dead[target];\r\n\t\tif (!targetPlayer) return this.sendUser(user, `|error|${target} is not in the game of mafia.`);\r\n\t\tconst oldMod = this.voteModifiers[target];\r\n\t\tif (mod === oldMod || ((isNaN(mod) || mod === 1) && oldMod === undefined)) {\r\n\t\t\tif (isNaN(mod) || mod === 1) return this.sendUser(user, `|error|${target} already has no vote modifier.`);\r\n\t\t\treturn this.sendUser(user, `|error|${target} already has a vote modifier of ${mod}`);\r\n\t\t}\r\n\t\tconst newMod = isNaN(mod) ? 1 : mod;\r\n\t\tif (targetPlayer.voting) {\r\n\t\t\tthis.votes[targetPlayer.voting].trueCount += oldMod - newMod;\r\n\t\t\tif (this.getHammerValue(targetPlayer.voting) <= this.votes[targetPlayer.voting].trueCount) {\r\n\t\t\t\tthis.sendRoom(`${targetPlayer.voting} has been voted out due to a modifier change! They have not been eliminated.`);\r\n\t\t\t\tthis.night(true);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (newMod === 1) {\r\n\t\t\tdelete this.voteModifiers[target];\r\n\t\t\treturn this.sendUser(user, `${targetPlayer.name} has had their vote modifier removed.`);\r\n\t\t} else {\r\n\t\t\tthis.voteModifiers[target] = newMod;\r\n\t\t\treturn this.sendUser(user, `${targetPlayer.name} has been given a vote modifier of ${newMod}`);\r\n\t\t}\r\n\t}\r\n\tapplyHammerModifier(user: User, target: ID, mod: number) {\r\n\t\tif (!(target in this.playerTable || target === 'novote')) {\r\n\t\t\treturn this.sendUser(user, `|error|${target} is not in the game of mafia.`);\r\n\t\t}\r\n\t\tconst oldMod = this.hammerModifiers[target];\r\n\t\tif (mod === oldMod || ((isNaN(mod) || mod === 0) && oldMod === undefined)) {\r\n\t\t\tif (isNaN(mod) || mod === 0) return this.sendUser(user, `|error|${target} already has no hammer modifier.`);\r\n\t\t\treturn this.sendUser(user, `|error|${target} already has a hammer modifier of ${mod}`);\r\n\t\t}\r\n\t\tconst newMod = isNaN(mod) ? 0 : mod;\r\n\t\tif (this.votes[target]) {\r\n\t\t\t// do this manually since we havent actually changed the value yet\r\n\t\t\tif (this.hammerCount + newMod <= this.votes[target].trueCount) {\r\n\t\t\t\t// make sure these strings are the same\r\n\t\t\t\tthis.sendRoom(`${target} has been voted due to a modifier change! They have not been eliminated.`);\r\n\t\t\t\tthis.night(true);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (newMod === 0) {\r\n\t\t\tdelete this.hammerModifiers[target];\r\n\t\t\treturn this.sendUser(user, `${target} has had their hammer modifier removed.`);\r\n\t\t} else {\r\n\t\t\tthis.hammerModifiers[target] = newMod;\r\n\t\t\treturn this.sendUser(user, `${target} has been given a hammer modifier of ${newMod}`);\r\n\t\t}\r\n\t}\r\n\tclearVoteModifiers(user: User) {\r\n\t\tfor (const player of [...Object.keys(this.playerTable), ...Object.keys(this.dead)] as ID[]) {\r\n\t\t\tif (this.voteModifiers[player]) this.applyVoteModifier(user, player, 1);\r\n\t\t}\r\n\t}\r\n\tclearHammerModifiers(user: User) {\r\n\t\tfor (const player of ['novote', ...Object.keys(this.playerTable)] as ID[]) {\r\n\t\t\tif (this.hammerModifiers[player]) this.applyHammerModifier(user, player, 0);\r\n\t\t}\r\n\t}\r\n\r\n\tgetVoteValue(userid: ID) {\r\n\t\tconst mod = this.voteModifiers[userid];\r\n\t\treturn (mod === undefined ? 1 : mod);\r\n\t}\r\n\tgetHammerValue(userid: ID) {\r\n\t\tconst mod = this.hammerModifiers[userid];\r\n\t\treturn (mod === undefined ? this.hammerCount : this.hammerCount + mod);\r\n\t}\r\n\tresetHammer() {\r\n\t\tthis.setHammer(Math.floor(Object.keys(this.playerTable).length / 2) + 1);\r\n\t}\r\n\r\n\tsetHammer(count: number) {\r\n\t\tthis.hammerCount = count;\r\n\t\tif (isNaN(count)) {\r\n\t\t\tthis.sendDeclare(`Hammering has been disabled, and votes have been reset.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`The hammer count has been set at ${this.hammerCount}, and votes have been reset.`);\r\n\t\t}\r\n\t\tthis.clearVotes();\r\n\t}\r\n\r\n\tshiftHammer(count: number) {\r\n\t\tthis.hammerCount = count;\r\n\t\tif (isNaN(count)) {\r\n\t\t\tthis.sendDeclare(`Hammering has been disabled. Votes have not been reset.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`The hammer count has been shifted to ${this.hammerCount}. Votes have not been reset.`);\r\n\t\t}\r\n\t\tconst hammered = [];\r\n\t\tfor (const vote in this.votes) {\r\n\t\t\tif (this.votes[vote].trueCount >= this.getHammerValue(vote as ID)) {\r\n\t\t\t\thammered.push(vote === 'novote' ? 'Nobody' : vote);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (hammered.length) {\r\n\t\t\tthis.sendDeclare(`${Chat.count(hammered, \"players have\")} been hammered: ${hammered.join(', ')}. They have not been removed from the game.`);\r\n\t\t\tthis.night(true);\r\n\t\t}\r\n\t}\r\n\r\n\tgetPlurality() {\r\n\t\tif (this.hasPlurality) return this.hasPlurality;\r\n\t\tif (!Object.keys(this.votes).length) return null;\r\n\t\tlet max = 0;\r\n\t\tlet topVotes: [ID, MafiaVote][] = [];\r\n\t\tfor (const [key, vote] of Object.entries(this.votes)) {\r\n\t\t\tif (vote.count > max) {\r\n\t\t\t\tmax = vote.count;\r\n\t\t\t\ttopVotes = [[key as ID, vote]];\r\n\t\t\t} else if (vote.count === max) {\r\n\t\t\t\ttopVotes.push([key as ID, vote]);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (topVotes.length <= 1) {\r\n\t\t\t[this.hasPlurality] = topVotes[0];\r\n\t\t\treturn this.hasPlurality;\r\n\t\t}\r\n\t\ttopVotes = Utils.sortBy(topVotes, ([key, vote]) => [\r\n\t\t\tvote.dir === 'down',\r\n\t\t\tvote.dir === 'up' ? vote.lastVote : -vote.lastVote,\r\n\t\t]);\r\n\t\t[this.hasPlurality] = topVotes[0];\r\n\t\treturn this.hasPlurality;\r\n\t}\r\n\r\n\teliminate(toEliminate: string, ability: string) {\r\n\t\tif (!(toEliminate in this.playerTable || toEliminate in this.dead)) return;\r\n\t\tif (!this.started) {\r\n\t\t\t// Game has not started, simply kick the player\r\n\t\t\tconst player = this.playerTable[toEliminate];\r\n\t\t\tthis.sendDeclare(`${player.safeName} was kicked from the game!`);\r\n\t\t\tif (this.hostRequestedSub.includes(player.id)) {\r\n\t\t\t\tthis.hostRequestedSub.splice(this.hostRequestedSub.indexOf(player.id), 1);\r\n\t\t\t}\r\n\t\t\tif (this.requestedSub.includes(player.id)) {\r\n\t\t\t\tthis.requestedSub.splice(this.requestedSub.indexOf(player.id), 1);\r\n\t\t\t}\r\n\t\t\tdelete this.playerTable[player.id];\r\n\t\t\tthis.playerCount--;\r\n\t\t\tplayer.updateHtmlRoom();\r\n\t\t\tplayer.destroy();\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (toEliminate in this.playerTable) {\r\n\t\t\tthis.dead[toEliminate] = this.playerTable[toEliminate];\r\n\t\t} else {\r\n\t\t\tthis.playerCount++; // so that the playercount decrement later isn't unnecessary\r\n\t\t}\r\n\r\n\t\tconst player = this.dead[toEliminate];\r\n\t\tlet msg = `${player.safeName}`;\r\n\t\tswitch (ability) {\r\n\t\tcase 'treestump':\r\n\t\t\tthis.dead[player.id].treestump = true;\r\n\t\t\tthis.dead[player.id].restless = false;\r\n\t\t\tmsg += ` has been treestumped`;\r\n\t\t\tbreak;\r\n\t\tcase 'spirit':\r\n\t\t\tthis.dead[player.id].treestump = false;\r\n\t\t\tthis.dead[player.id].restless = true;\r\n\t\t\tmsg += ` became a restless spirit`;\r\n\t\t\tbreak;\r\n\t\tcase 'spiritstump':\r\n\t\t\tthis.dead[player.id].treestump = true;\r\n\t\t\tthis.dead[player.id].restless = true;\r\n\t\t\tmsg += ` became a restless treestump`;\r\n\t\t\tbreak;\r\n\t\tcase 'kick':\r\n\t\t\tthis.dead[player.id].treestump = false;\r\n\t\t\tthis.dead[player.id].restless = false;\r\n\t\t\tmsg += ` was kicked from the game`;\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tthis.dead[player.id].treestump = false;\r\n\t\t\tthis.dead[player.id].restless = false;\r\n\t\t\tmsg += ` was eliminated`;\r\n\t\t}\r\n\t\tif (player.voting) this.unvote(player.id, true);\r\n\t\tthis.sendDeclare(`${msg}! ${!this.noReveal && toID(ability) === 'kill' ? `${player.safeName}'s role was ${player.getRole()}.` : ''}`);\r\n\t\tif (player.role && !this.noReveal && toID(ability) === 'kill') player.revealed = player.getRole()!;\r\n\t\tconst targetRole = player.role;\r\n\t\tif (targetRole) {\r\n\t\t\tfor (const [roleIndex, role] of this.roles.entries()) {\r\n\t\t\t\tif (role.id === targetRole.id) {\r\n\t\t\t\t\tthis.roles.splice(roleIndex, 1);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.clearVotes(player.id);\r\n\t\tdelete this.playerTable[player.id];\r\n\t\tlet subIndex = this.requestedSub.indexOf(player.id);\r\n\t\tif (subIndex !== -1) this.requestedSub.splice(subIndex, 1);\r\n\t\tsubIndex = this.hostRequestedSub.indexOf(player.id);\r\n\t\tif (subIndex !== -1) this.hostRequestedSub.splice(subIndex, 1);\r\n\r\n\t\tthis.playerCount--;\r\n\t\tthis.updateRoleString();\r\n\t\tthis.updatePlayers();\r\n\t\tplayer.updateHtmlRoom();\r\n\t}\r\n\r\n\trevealRole(user: User, toReveal: MafiaPlayer, revealAs: string) {\r\n\t\tif (!this.started) {\r\n\t\t return user.sendTo(this.room, `|error|You may only reveal roles once the game has started.`);\r\n\t\t}\r\n\t\tif (!toReveal.role) {\r\n\t\t return user.sendTo(this.room, `|error|The user ${toReveal.id} is not assigned a role.`);\r\n\t\t}\r\n\t\ttoReveal.revealed = revealAs;\r\n\t\tthis.sendDeclare(`${toReveal.safeName}'s role ${toReveal.id in this.playerTable ? `is` : `was`} ${revealAs}.`);\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\r\n\trevive(user: User, toRevive: string, force = false) {\r\n\t\tif (this.phase === 'IDEApicking') {\r\n\t\t\treturn user.sendTo(this.room, `|error|You cannot add or remove players while IDEA roles are being picked.`);\r\n\t\t}\r\n\t\tif (toRevive in this.playerTable) {\r\n\t\t\tuser.sendTo(this.room, `|error|The user ${toRevive} is already a living player.`);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (toRevive in this.dead) {\r\n\t\t\tconst deadPlayer = this.dead[toRevive];\r\n\t\t\tif (deadPlayer.treestump) deadPlayer.treestump = false;\r\n\t\t\tif (deadPlayer.restless) deadPlayer.restless = false;\r\n\t\t\tthis.sendDeclare(`${deadPlayer.safeName} was revived!`);\r\n\t\t\tthis.playerTable[deadPlayer.id] = deadPlayer;\r\n\t\t\tconst targetRole = deadPlayer.role;\r\n\t\t\tif (targetRole) {\r\n\t\t\t\tthis.roles.push(targetRole);\r\n\t\t\t} else {\r\n\t\t\t\t// Should never happen\r\n\t\t\t\tdeadPlayer.role = {\r\n\t\t\t\t\tname: `Unknown`,\r\n\t\t\t\t\tsafeName: `Unknown`,\r\n\t\t\t\t\tid: `unknown`,\r\n\t\t\t\t\talignment: 'solo',\r\n\t\t\t\t\timage: '',\r\n\t\t\t\t\tmemo: [\r\n\t\t\t\t\t\t`You were revived, but had no role. Please let a Mafia Room Owner know this happened. To learn about your role, PM the host (${this.host}).`,\r\n\t\t\t\t\t],\r\n\t\t\t\t};\r\n\t\t\t\tthis.roles.push(deadPlayer.role);\r\n\t\t\t}\r\n\t\t\tUtils.sortBy(this.roles, r => [r.alignment, r.name]);\r\n\t\t\tdelete this.dead[deadPlayer.id];\r\n\t\t} else {\r\n\t\t\tconst targetUser = Users.get(toRevive);\r\n\t\t\tif (!targetUser) return;\r\n\t\t\tthis.canJoin(targetUser, false, force);\r\n\t\t\tconst player = this.makePlayer(targetUser);\r\n\t\t\tif (this.started) {\r\n\t\t\t\tplayer.role = {\r\n\t\t\t\t\tname: `Unknown`,\r\n\t\t\t\t\tsafeName: `Unknown`,\r\n\t\t\t\t\tid: `unknown`,\r\n\t\t\t\t\talignment: 'solo',\r\n\t\t\t\t\timage: '',\r\n\t\t\t\t\tmemo: [`You were added to the game after it had started. To learn about your role, PM the host (${this.host}).`],\r\n\t\t\t\t};\r\n\t\t\t\tthis.roles.push(player.role);\r\n\t\t\t\tthis.played.push(targetUser.id);\r\n\t\t\t} else {\r\n\t\t\t\tthis.originalRoles = [];\r\n\t\t\t\tthis.originalRoleString = '';\r\n\t\t\t\tthis.roles = [];\r\n\t\t\t\tthis.roleString = '';\r\n\t\t\t}\r\n\t\t\tif (this.subs.includes(targetUser.id)) this.subs.splice(this.subs.indexOf(targetUser.id), 1);\r\n\t\t\tthis.playerTable[targetUser.id] = player;\r\n\t\t\tthis.sendDeclare(Utils.html`${targetUser.name} has been added to the game by ${user.name}!`);\r\n\t\t}\r\n\t\tthis.playerCount++;\r\n\t\tthis.updateRoleString();\r\n\t\tthis.updatePlayers();\r\n\t\treturn true;\r\n\t}\r\n\r\n\tsetDeadline(minutes: number, silent = false) {\r\n\t\tif (isNaN(minutes)) return;\r\n\t\tif (!minutes) {\r\n\t\t\tif (!this.timer) return;\r\n\t\t\tclearTimeout(this.timer);\r\n\t\t\tthis.timer = null;\r\n\t\t\tthis.dlAt = 0;\r\n\t\t\tif (!silent) this.sendTimestamp(`**The deadline has been cleared.**`);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (minutes < 1 || minutes > 20) return;\r\n\t\tif (this.timer) clearTimeout(this.timer);\r\n\t\tthis.dlAt = Date.now() + (minutes * 60000);\r\n\t\tif (minutes > 3) {\r\n\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\tthis.sendTimestamp(`**3 minutes left!**`);\r\n\t\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\t\tthis.sendTimestamp(`**1 minute left!**`);\r\n\t\t\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\t\t\tthis.sendTimestamp(`**Time is up!**`);\r\n\t\t\t\t\t\tthis.night();\r\n\t\t\t\t\t}, 60000);\r\n\t\t\t\t}, 2 * 60000);\r\n\t\t\t}, (minutes - 3) * 60000);\r\n\t\t} else if (minutes > 1) {\r\n\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\tthis.sendTimestamp(`**1 minute left!**`);\r\n\t\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\t\tthis.sendTimestamp(`**Time is up!**`);\r\n\t\t\t\t\tif (this.phase === 'day') this.night();\r\n\t\t\t\t}, 60000);\r\n\t\t\t}, (minutes - 1) * 60000);\r\n\t\t} else {\r\n\t\t\tthis.timer = setTimeout(() => {\r\n\t\t\t\tthis.sendTimestamp(`**Time is up!**`);\r\n\t\t\t\tif (this.phase === 'day') this.night();\r\n\t\t\t}, minutes * 60000);\r\n\t\t}\r\n\t\tthis.sendTimestamp(`**The deadline has been set for ${minutes} minute${minutes === 1 ? '' : 's'}.**`);\r\n\t}\r\n\r\n\tsub(player: string, replacement: string) {\r\n\t\tconst oldPlayer = this.playerTable[player];\r\n\t\tif (!oldPlayer) return; // should never happen\r\n\r\n\t\tconst newUser = Users.get(replacement);\r\n\t\tif (!newUser) return; // should never happen\r\n\t\tconst newPlayer = this.makePlayer(newUser);\r\n\t\tnewPlayer.role = oldPlayer.role;\r\n\t\tnewPlayer.IDEA = oldPlayer.IDEA;\r\n\t\tif (oldPlayer.voting) {\r\n\t\t\t// Dont change plurality\r\n\t\t\tconst vote = this.votes[oldPlayer.voting];\r\n\t\t\tvote.voters.splice(vote.voters.indexOf(oldPlayer.id), 1);\r\n\t\t\tvote.voters.push(newPlayer.id);\r\n\t\t\tnewPlayer.voting = oldPlayer.voting;\r\n\t\t\toldPlayer.voting = '';\r\n\t\t}\r\n\t\tthis.playerTable[newPlayer.id] = newPlayer;\r\n\t\t// Transfer votes on the old player to the new one\r\n\t\tif (this.votes[oldPlayer.id]) {\r\n\t\t\tthis.votes[newPlayer.id] = this.votes[oldPlayer.id];\r\n\t\t\tdelete this.votes[oldPlayer.id];\r\n\t\t\tfor (const p in this.playerTable) {\r\n\t\t\t\tif (this.playerTable[p].voting === oldPlayer.id) this.playerTable[p].voting = newPlayer.id;\r\n\t\t\t}\r\n\t\t\tfor (const p in this.dead) {\r\n\t\t\t\tif (this.dead[p].restless && this.dead[p].voting === oldPlayer.id) this.dead[p].voting = newPlayer.id;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (this.hasPlurality === oldPlayer.id) this.hasPlurality = newPlayer.id;\r\n\t\tfor (let i = 1; i < this.dayNum; i++) {\r\n\t\t\tnewPlayer.actionArr[i] = oldPlayer.actionArr[i];\r\n\t\t}\r\n\t\tif (newUser?.connected) {\r\n\t\t\tfor (const conn of newUser.connections) {\r\n\t\t\t\tvoid Chat.resolvePage(`view-mafia-${this.room.roomid}`, newUser, conn);\r\n\t\t\t}\r\n\t\t\tnewUser.send(`>${this.room.roomid}\\n|notify|You have been substituted in the mafia game for ${oldPlayer.safeName}.`);\r\n\t\t}\r\n\t\tif (this.started) this.played.push(newPlayer.id);\r\n\t\tthis.sendDeclare(`${oldPlayer.safeName} has been subbed out. ${newPlayer.safeName} has joined the game.`);\r\n\t\tdelete this.playerTable[oldPlayer.id];\r\n\t\toldPlayer.destroy();\r\n\t\tthis.updatePlayers();\r\n\r\n\t\tif (this.room.roomid === 'mafia' && this.started) {\r\n\t\t\tconst month = new Date().toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\t\t\tif (!logs.leavers[month]) logs.leavers[month] = {};\r\n\t\t\tif (!logs.leavers[month][player]) logs.leavers[month][player] = 0;\r\n\t\t\tlogs.leavers[month][player]++;\r\n\t\t\twriteFile(LOGS_FILE, logs);\r\n\t\t}\r\n\t}\r\n\r\n\tnextSub(userid: ID | null = null) {\r\n\t\tif (!this.subs.length ||\r\n\t\t\t(!this.hostRequestedSub.length && ((!this.requestedSub.length || !this.autoSub)) && !userid)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst nextSub = this.subs.shift();\r\n\t\tif (!nextSub) return;\r\n\t\tconst sub = Users.get(nextSub, true);\r\n\t\tif (!sub?.connected || !sub.named || !this.room.users[sub.id]) return; // should never happen, just to be safe\r\n\t\tconst toSubOut = userid || this.hostRequestedSub.shift() || this.requestedSub.shift();\r\n\t\tif (!toSubOut) {\r\n\t\t\t// Should never happen\r\n\t\t\tthis.subs.unshift(nextSub);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this.hostRequestedSub.includes(toSubOut)) {\r\n\t\t\tthis.hostRequestedSub.splice(this.hostRequestedSub.indexOf(toSubOut), 1);\r\n\t\t}\r\n\t\tif (this.requestedSub.includes(toSubOut)) {\r\n\t\t\tthis.requestedSub.splice(this.requestedSub.indexOf(toSubOut), 1);\r\n\t\t}\r\n\t\tthis.sub(toSubOut, sub.id);\r\n\t}\r\n\r\n\tcustomIdeaInit(user: User, choices: number, picks: string[], rolesString: string) {\r\n\t\tthis.originalRoles = [];\r\n\t\tthis.originalRoleString = '';\r\n\t\tthis.roles = [];\r\n\t\tthis.roleString = '';\r\n\r\n\t\tconst roles = Utils.stripHTML(rolesString);\r\n\t\tlet roleList = roles.split('\\n');\r\n\t\tif (roleList.length === 1) {\r\n\t\t\troleList = roles.split(',').map(r => r.trim());\r\n\t\t}\r\n\r\n\t\tthis.IDEA.data = {\r\n\t\t\tname: `${this.host}'s custom IDEA`, // already escaped\r\n\t\t\tuntrusted: true,\r\n\t\t\troles: roleList,\r\n\t\t\tpicks,\r\n\t\t\tchoices,\r\n\t\t};\r\n\t\treturn this.ideaDistributeRoles(user);\r\n\t}\r\n\tideaInit(user: User, moduleID: ID) {\r\n\t\tthis.originalRoles = [];\r\n\t\tthis.originalRoleString = '';\r\n\t\tthis.roles = [];\r\n\t\tthis.roleString = '';\r\n\r\n\t\tif (moduleID in MafiaData.aliases) moduleID = MafiaData.aliases[moduleID];\r\n\t\tthis.IDEA.data = MafiaData.IDEAs[moduleID];\r\n\t\tif (!this.IDEA.data) return user.sendTo(this.room, `|error|${moduleID} is not a valid IDEA.`);\r\n\t\treturn this.ideaDistributeRoles(user);\r\n\t}\r\n\r\n\tideaDistributeRoles(user: User) {\r\n\t\tif (!this.IDEA.data) return user.sendTo(this.room, `|error|No IDEA module loaded`);\r\n\t\tif (this.phase !== 'locked' && this.phase !== 'IDEAlocked') {\r\n\t\t\treturn user.sendTo(this.room, `|error|The game must be in a locked state to distribute IDEA roles.`);\r\n\t\t}\r\n\r\n\t\tconst neededRoles = this.IDEA.data.choices * this.playerCount;\r\n\t\tif (neededRoles > this.IDEA.data.roles.length) {\r\n\t\t\treturn user.sendTo(this.room, `|error|Not enough roles in the IDEA module.`);\r\n\t\t}\r\n\r\n\t\tconst roles = [];\r\n\t\tconst selectedIndexes: number[] = [];\r\n\t\tfor (let i = 0; i < neededRoles; i++) {\r\n\t\t\tlet randomIndex;\r\n\t\t\tdo {\r\n\t\t\t\trandomIndex = Math.floor(Math.random() * this.IDEA.data.roles.length);\r\n\t\t\t} while (selectedIndexes.includes(randomIndex));\r\n\t\t\troles.push(this.IDEA.data.roles[randomIndex]);\r\n\t\t\tselectedIndexes.push(randomIndex);\r\n\t\t}\r\n\t\tUtils.shuffle(roles);\r\n\t\tthis.IDEA.waitingPick = [];\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tconst player = this.playerTable[p];\r\n\t\t\tplayer.role = null;\r\n\t\t\tplayer.IDEA = {\r\n\t\t\t\tchoices: roles.splice(0, this.IDEA.data.choices),\r\n\t\t\t\toriginalChoices: [], // MAKE SURE TO SET THIS\r\n\t\t\t\tpicks: {},\r\n\t\t\t};\r\n\t\t\tplayer.IDEA.originalChoices = player.IDEA.choices.slice();\r\n\t\t\tfor (const pick of this.IDEA.data.picks) {\r\n\t\t\t\tplayer.IDEA.picks[pick] = null;\r\n\t\t\t\tthis.IDEA.waitingPick.push(p);\r\n\t\t\t}\r\n\t\t\tconst u = Users.get(p);\r\n\t\t\tif (u?.connected) u.send(`>${this.room.roomid}\\n|notify|Pick your role in the IDEA module.`);\r\n\t\t}\r\n\r\n\t\tthis.phase = 'IDEApicking';\r\n\t\tthis.updatePlayers();\r\n\r\n\t\tthis.sendDeclare(`${this.IDEA.data.name} roles have been distributed. You will have ${IDEA_TIMER / 1000} seconds to make your picks.`);\r\n\t\tthis.IDEA.timer = setTimeout(() => { this.ideaFinalizePicks(); }, IDEA_TIMER);\r\n\r\n\t\treturn ``;\r\n\t}\r\n\r\n\tideaPick(user: User, selection: string[]) {\r\n\t\tlet buf = '';\r\n\t\tif (this.phase !== 'IDEApicking') return 'The game is not in the IDEA picking phase.';\r\n\t\tif (!this.IDEA?.data) {\r\n\t\t\treturn this.sendRoom(`Trying to pick an IDEA role with no module running, target: ${JSON.stringify(selection)}. Please report this to a mod.`);\r\n\t\t}\r\n\t\tconst player = this.playerTable[user.id];\r\n\t\tif (!player.IDEA) {\r\n\t\t\treturn this.sendRoom(`Trying to pick an IDEA role with no player IDEA object, user: ${user.id}. Please report this to a mod.`);\r\n\t\t}\r\n\t\tselection = selection.map(toID);\r\n\t\tif (selection.length === 1 && this.IDEA.data.picks.length === 1) selection = [this.IDEA.data.picks[0], selection[0]];\r\n\t\tif (selection.length !== 2) return user.sendTo(this.room, `|error|Invalid selection.`);\r\n\r\n\t\t// input is formatted as ['selection', 'role']\r\n\t\t// eg: ['role', 'bloodhound']\r\n\t\t// ['alignment', 'alien']\r\n\t\t// ['selection', ''] deselects\r\n\t\tif (selection[1]) {\r\n\t\t\tconst roleIndex = player.IDEA.choices.map(toID).indexOf(selection[1] as ID);\r\n\t\t\tif (roleIndex === -1) {\r\n\t\t\t\treturn user.sendTo(this.room, `|error|${selection[1]} is not an available role, perhaps it is already selected?`);\r\n\t\t\t}\r\n\t\t\tselection[1] = player.IDEA.choices.splice(roleIndex, 1)[0];\r\n\t\t} else {\r\n\t\t\tselection[1] = '';\r\n\t\t}\r\n\t\tconst selected = player.IDEA.picks[selection[0]];\r\n\t\tif (selected) {\r\n\t\t\tbuf += `You have deselected ${selected}. `;\r\n\t\t\tplayer.IDEA.choices.push(selected);\r\n\t\t}\r\n\r\n\t\tif (player.IDEA.picks[selection[0]] && !selection[1]) {\r\n\t\t\tthis.IDEA.waitingPick.push(player.id);\r\n\t\t} else if (!player.IDEA.picks[selection[0]] && selection[1]) {\r\n\t\t\tthis.IDEA.waitingPick.splice(this.IDEA.waitingPick.indexOf(player.id), 1);\r\n\t\t}\r\n\r\n\t\tplayer.IDEA.picks[selection[0]] = selection[1];\r\n\t\tif (selection[1]) buf += `You have selected ${selection[0]}: ${selection[1]}.`;\r\n\t\tplayer.updateHtmlRoom();\r\n\t\tif (!this.IDEA.waitingPick.length) {\r\n\t\t\tif (this.IDEA.timer) clearTimeout(this.IDEA.timer);\r\n\t\t\tthis.ideaFinalizePicks();\r\n\t\t\treturn;\r\n\t\t}\r\n\t\treturn user.sendTo(this.room, buf);\r\n\t}\r\n\r\n\tideaFinalizePicks() {\r\n\t\tif (!this.IDEA?.data) {\r\n\t\t\treturn this.sendRoom(`Tried to finalize IDEA picks with no IDEA module running, please report this to a mod.`);\r\n\t\t}\r\n\t\tconst randed = [];\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tconst player = this.playerTable[p];\r\n\t\t\tif (!player.IDEA) {\r\n\t\t\t\treturn this.sendRoom(`Trying to pick an IDEA role with no player IDEA object, user: ${player.id}. Please report this to a mod.`);\r\n\t\t\t}\r\n\t\t\tlet randPicked = false;\r\n\t\t\tconst role = [];\r\n\t\t\tfor (const choice of this.IDEA.data.picks) {\r\n\t\t\t\tif (!player.IDEA.picks[choice]) {\r\n\t\t\t\t\trandPicked = true;\r\n\t\t\t\t\tconst randomChoice = player.IDEA.choices.shift();\r\n\t\t\t\t\tif (randomChoice) {\r\n\t\t\t\t\t\tplayer.IDEA.picks[choice] = randomChoice;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthrow new Error(`No roles left to randomly assign from IDEA module choices.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.sendUser(player.id, `You were randomly assigned ${choice}: ${randomChoice}`);\r\n\t\t\t\t}\r\n\t\t\t\trole.push(`${choice}: ${player.IDEA.picks[choice]}`);\r\n\t\t\t}\r\n\t\t\tif (randPicked) randed.push(p);\r\n\t\t\t// if there's only one option, it's their role, parse it properly\r\n\t\t\tlet roleName = '';\r\n\t\t\tif (this.IDEA.data.picks.length === 1) {\r\n\t\t\t\tconst pick = player.IDEA.picks[this.IDEA.data.picks[0]];\r\n\t\t\t\tif (!pick) throw new Error('Pick not found when parsing role selected in IDEA module.');\r\n\t\t\t\tconst parsedRole = Mafia.parseRole(pick);\r\n\t\t\t\tif (parsedRole.problems.length) {\r\n\t\t\t\t\tthis.sendRoom(`Problems found when parsing IDEA role ${player.IDEA.picks[this.IDEA.data.picks[0]]}. Please report this to a mod.`);\r\n\t\t\t\t}\r\n\t\t\t\tplayer.role = parsedRole.role;\r\n\t\t\t} else {\r\n\t\t\t\troleName = role.join('; ');\r\n\t\t\t\tplayer.role = {\r\n\t\t\t\t\tname: roleName,\r\n\t\t\t\t\tsafeName: Utils.escapeHTML(roleName),\r\n\t\t\t\t\tid: toID(roleName),\r\n\t\t\t\t\talignment: 'solo',\r\n\t\t\t\t\tmemo: [`(Your role was set from an IDEA.)`],\r\n\t\t\t\t\timage: '',\r\n\t\t\t\t};\r\n\t\t\t\t// hardcoding this because it makes GestI so much nicer\r\n\t\t\t\tif (!this.IDEA.data.untrusted) {\r\n\t\t\t\t\tfor (const pick of role) {\r\n\t\t\t\t\t\tif (pick.substr(0, 10) === 'alignment:') {\r\n\t\t\t\t\t\t\tconst parsedRole = Mafia.parseRole(pick.substr(9));\r\n\t\t\t\t\t\t\tif (parsedRole.problems.length) {\r\n\t\t\t\t\t\t\t\tthis.sendRoom(`Problems found when parsing IDEA role ${pick}. Please report this to a mod.`);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tplayer.role.alignment = parsedRole.role.alignment;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// 'Innocent Discard' causes chosen role to become Town, when discarded.\r\n\t\t\tif (player.IDEA.choices.includes('Innocent Discard')) player.role.alignment = 'town';\r\n\t\t}\r\n\t\tthis.IDEA.discardsHTML = `Discards:
`;\r\n\t\tfor (const p of Object.keys(this.playerTable).sort()) {\r\n\t\t\tconst IDEA = this.playerTable[p].IDEA;\r\n\t\t\tif (!IDEA) return this.sendRoom(`No IDEA data for player ${p} when finalising IDEAs. Please report this to a mod.`);\r\n\t\t\tthis.IDEA.discardsHTML += `${this.playerTable[p].safeName}: ${IDEA.choices.join(', ')}
`;\r\n\t\t}\r\n\r\n\t\tthis.phase = 'IDEAlocked';\r\n\t\tif (randed.length) {\r\n\t\t\tthis.sendDeclare(`${randed.join(', ')} did not pick a role in time and were randomly assigned one.`);\r\n\t\t}\r\n\t\tthis.sendDeclare(`IDEA picks are locked!`);\r\n\t\tthis.sendRoom(`To start, use /mafia start, or to reroll use /mafia ideareroll`);\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\r\n\tsendPlayerList() {\r\n\t\tthis.room.add(`|c:|${(Math.floor(Date.now() / 1000))}|~|**Players (${this.playerCount})**: ${Object.values(this.playerTable).map(p => p.name).sort().join(', ')}`).update();\r\n\t}\r\n\r\n\tupdatePlayers() {\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tthis.playerTable[p].updateHtmlRoom();\r\n\t\t}\r\n\t\tfor (const p in this.dead) {\r\n\t\t\tif (this.dead[p].restless || this.dead[p].treestump) this.dead[p].updateHtmlRoom();\r\n\t\t}\r\n\t\t// Now do the host\r\n\t\tthis.updateHost();\r\n\t}\r\n\r\n\tupdatePlayersVotes() {\r\n\t\tfor (const p in this.playerTable) {\r\n\t\t\tthis.playerTable[p].updateHtmlVotes();\r\n\t\t}\r\n\t\tfor (const p in this.dead) {\r\n\t\t\tif (this.dead[p].restless || this.dead[p].treestump) this.dead[p].updateHtmlVotes();\r\n\t\t}\r\n\t}\r\n\r\n\tupdateHost(...hosts: ID[]) {\r\n\t\tif (!hosts.length) hosts = [...this.cohostids, this.hostid];\r\n\r\n\t\tfor (const hostid of hosts) {\r\n\t\t\tconst host = Users.get(hostid);\r\n\t\t\tif (!host?.connected) return;\r\n\t\t\tfor (const conn of host.connections) {\r\n\t\t\t\tvoid Chat.resolvePage(`view-mafia-${this.room.roomid}`, host, conn);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tupdateRoleString() {\r\n\t\tthis.roleString = this.roles.map(\r\n\t\t\tr => `${r.safeName}`\r\n\t\t).join(', ');\r\n\t}\r\n\r\n\tsendRoom(message: string) {\r\n\t\tthis.room.add(message).update();\r\n\t}\r\n\tsendHTML(message: string) {\r\n\t\tthis.room.add(`|uhtml|mafia|${message}`).update();\r\n\t}\r\n\tsendDeclare(message: string) {\r\n\t\tthis.room.add(`|raw|
${message}
`).update();\r\n\t}\r\n\tsendStrong(message: string) {\r\n\t\tthis.room.add(`|raw|${message}`).update();\r\n\t}\r\n\tsendTimestamp(message: string) {\r\n\t\tthis.room.add(`|c:|${(Math.floor(Date.now() / 1000))}|~|${message}`).update();\r\n\t}\r\n\tlogAction(user: User, message: string) {\r\n\t\tif (user.id === this.hostid || this.cohostids.includes(user.id)) return;\r\n\t\tthis.room.sendModsByUser(user, `(${user.name}: ${message})`);\r\n\t}\r\n\tsecretLogAction(user: User, message: string) {\r\n\t\tif (user.id === this.hostid || this.cohostids.includes(user.id)) return;\r\n\t\tthis.room.roomlog(`(${user.name}: ${message})`);\r\n\t}\r\n\troomWindow() {\r\n\t\tif (this.ended) return `
The game of ${this.title} has ended.
`;\r\n\t\tlet output = `
`;\r\n\t\tif (this.phase === 'signups') {\r\n\t\t\toutput += `

A game of ${this.title} was created

`;\r\n\t\t} else {\r\n\t\t\toutput += `

A game of ${this.title} is in progress.

`;\r\n\t\t}\r\n\t\toutput += `
`;\r\n\t\treturn output;\r\n\t}\r\n\r\n\tcanJoin(user: User, self = false, force = false) {\r\n\t\tif (!user?.connected) return `User not found.`;\r\n\t\tconst targetString = self ? `You are` : `${user.id} is`;\r\n\t\tif (!this.room.users[user.id]) return `${targetString} not in the room.`;\r\n\t\tfor (const id of [user.id, ...user.previousIDs]) {\r\n\t\t\tif (this.playerTable[id] || this.dead[id]) throw new Chat.ErrorMessage(`${targetString} already in the game.`);\r\n\t\t\tif (!force && this.played.includes(id)) {\r\n\t\t\t\tthrow new Chat.ErrorMessage(`${self ? `You were` : `${user.id} was`} already in the game.`);\r\n\t\t\t}\r\n\t\t\tif (Mafia.isGameBanned(this.room, user)) {\r\n\t\t\t\tthrow new Chat.ErrorMessage(`${self ? `You are` : `${user.id} is`} banned from joining mafia games.`);\r\n\t\t\t}\r\n\t\t\tif (this.hostid === id) throw new Chat.ErrorMessage(`${targetString} the host.`);\r\n\t\t\tif (this.cohostids.includes(id)) throw new Chat.ErrorMessage(`${targetString} a cohost.`);\r\n\t\t}\r\n\t\tif (!force) {\r\n\t\t\tfor (const alt of user.getAltUsers(true)) {\r\n\t\t\t\tif (this.playerTable[alt.id] || this.played.includes(alt.id)) {\r\n\t\t\t\t\tthrow new Chat.ErrorMessage(`${self ? `You already have` : `${user.id} already has`} an alt in the game.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (this.hostid === alt.id || this.cohostids.includes(alt.id)) {\r\n\t\t\t\t\tthrow new Chat.ErrorMessage(`${self ? `You have` : `${user.id} has`} an alt as a game host.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tsendUser(user: User | string | null, message: string) {\r\n\t\tconst userObject = (typeof user === 'string' ? Users.get(user) : user);\r\n\t\tif (!userObject?.connected) return;\r\n\t\tuserObject.sendTo(this.room, message);\r\n\t}\r\n\r\n\tsetSelfVote(user: User, setting: boolean | 'hammer') {\r\n\t\tconst from = this.selfEnabled;\r\n\t\tif (from === setting) {\r\n\t\t\treturn user.sendTo(\r\n\t\t\t\tthis.room,\r\n\t\t\t\t`|error|Selfvoting is already ${setting ? `set to Self${setting === 'hammer' ? 'hammering' : 'voting'}` : 'disabled'}.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (from) {\r\n\t\t\tthis.sendDeclare(`Self${from === 'hammer' ? 'hammering' : 'voting'} has been ${setting ? `changed to Self${setting === 'hammer' ? 'hammering' : 'voting'}` : 'disabled'}.`);\r\n\t\t} else {\r\n\t\t\tthis.sendDeclare(`Self${setting === 'hammer' ? 'hammering' : 'voting'} has been ${setting ? 'enabled' : 'disabled'}.`);\r\n\t\t}\r\n\t\tthis.selfEnabled = setting;\r\n\t\tif (!setting) {\r\n\t\t\tfor (const player of Object.values(this.playerTable)) {\r\n\t\t\t\tif (player.voting === player.id) this.unvote(player.id, true);\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\tsetNoVote(user: User, setting: boolean) {\r\n\t\tif (this.enableNL === setting) {\r\n\t\t\treturn user.sendTo(this.room, `|error|No Vote is already ${setting ? 'enabled' : 'disabled'}.`);\r\n\t\t}\r\n\t\tthis.enableNL = setting;\r\n\t\tthis.sendDeclare(`No Vote has been ${setting ? 'enabled' : 'disabled'}.`);\r\n\t\tif (!setting) this.clearVotes('novote');\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\tsetVotelock(user: User, setting: boolean) {\r\n\t\tif (!this.started) return user.sendTo(this.room, `The game has not started yet.`);\r\n\t\tif ((this.voteLock) === setting) {\r\n\t\t\treturn user.sendTo(this.room, `|error|Votes are already ${setting ? 'set to lock' : 'set to not lock'}.`);\r\n\t\t}\r\n\t\tthis.voteLock = setting;\r\n\t\tthis.clearVotes();\r\n\t\tthis.sendDeclare(`Votes are cleared and ${setting ? 'set to lock' : 'set to not lock'}.`);\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\tsetVoting(user: User, setting: boolean) {\r\n\t\tif (!this.started) return user.sendTo(this.room, `The game has not started yet.`);\r\n\t\tif (this.votingAll === setting) {\r\n\t\t\treturn user.sendTo(this.room, `|error|Voting is already ${setting ? 'allowed' : 'disallowed'}.`);\r\n\t\t}\r\n\t\tthis.votingAll = setting;\r\n\t\tthis.clearVotes();\r\n\t\tthis.sendDeclare(`Voting is now ${setting ? 'allowed' : 'disallowed'}.`);\r\n\t\tthis.updatePlayers();\r\n\t}\r\n\tclearVotes(target = '') {\r\n\t\tif (target) delete this.votes[target];\r\n\r\n\t\tif (!target) this.votes = Object.create(null);\r\n\r\n\t\tfor (const player of Object.values(this.playerTable)) {\r\n\t\t\tif (this.forceVote) {\r\n\t\t\t\tif (!target || (player.voting === target)) {\r\n\t\t\t\t\tplayer.voting = player.id;\r\n\t\t\t\t\tthis.votes[player.id] = {\r\n\t\t\t\t\t\tcount: 1, trueCount: this.getVoteValue(player.id), lastVote: Date.now(), dir: 'up', voters: [player.id],\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (!target || (player.voting === target)) player.voting = '';\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (const player of Object.values(this.dead)) {\r\n\t\t\tif (player.restless && (!target || player.voting === target)) player.voting = '';\r\n\t\t}\r\n\t\tthis.hasPlurality = null;\r\n\t}\r\n\r\n\tonChatMessage(message: string, user: User) {\r\n\t\tconst subIndex = this.hostRequestedSub.indexOf(user.id);\r\n\t\tif (subIndex !== -1) {\r\n\t\t\tthis.hostRequestedSub.splice(subIndex, 1);\r\n\t\t\tfor (const hostid of [...this.cohostids, this.hostid]) {\r\n\t\t\t\tthis.sendUser(hostid, `${user.id} has spoken and been removed from the host sublist.`);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Hosts can always talk\r\n\t\tif (this.hostid === user.id || this.cohostids.includes(user.id) || !this.started) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet dead = false;\r\n\t\tlet player = this.playerTable[user.id];\r\n\t\tif (!player) {\r\n\t\t\tplayer = this.dead[user.id];\r\n\t\t\tdead = !!player;\r\n\t\t}\r\n\r\n\t\tconst staff = user.can('mute', null, this.room);\r\n\r\n\t\tif (!player) {\r\n\t\t\tif (staff) {\r\n\t\t\t\t// Uninvolved staff can talk anytime\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\treturn `You cannot talk while a game of ${this.title} is going on.`;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (player.silenced) {\r\n\t\t\treturn `You are silenced and cannot speak.${staff ? \" You can remove this with /mafia unsilence.\" : ''}`;\r\n\t\t}\r\n\r\n\t\tif (dead) {\r\n\t\t\tif (!player.treestump) {\r\n\t\t\t\treturn `You are dead.${staff ? \" You can treestump yourself with /mafia treestump.\" : ''}`;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.phase === 'night') {\r\n\t\t\tif (!player.nighttalk) {\r\n\t\t\t\treturn `You cannot talk at night.${staff ? \" You can bypass this using /mafia nighttalk.\" : ''}`;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tonConnect(user: User) {\r\n\t\tuser.sendTo(this.room, `|uhtml|mafia|${this.roomWindow()}`);\r\n\t}\r\n\r\n\tonJoin(user: User) {\r\n\t\tif (user.id in this.playerTable) {\r\n\t\t\treturn this.playerTable[user.id].updateHtmlRoom();\r\n\t\t}\r\n\t\tif (user.id === this.hostid || this.cohostids.includes(user.id)) return this.updateHost(user.id);\r\n\t}\r\n\r\n\tremoveBannedUser(user: User) {\r\n\t\t// Player was banned, attempt to sub now\r\n\t\t// If we can't sub now, make subbing them out the top priority\r\n\t\tif (!(user.id in this.playerTable)) return;\r\n\t\tthis.requestedSub.unshift(user.id);\r\n\t\tthis.nextSub();\r\n\t}\r\n\r\n\tforfeit(user: User) {\r\n\t\t// Add the player to the sub list.\r\n\t\tif (!(user.id in this.playerTable)) return;\r\n\t\tthis.requestedSub.push(user.id);\r\n\t\tthis.nextSub();\r\n\t}\r\n\r\n\tend() {\r\n\t\tthis.ended = true;\r\n\t\tthis.sendHTML(this.roomWindow());\r\n\t\tthis.updatePlayers();\r\n\t\tif (this.room.roomid === 'mafia' && this.started) {\r\n\t\t\t// Intead of using this.played, which shows players who have subbed out as well\r\n\t\t\t// We check who played through to the end when recording playlogs\r\n\t\t\tconst played = Object.keys(this.playerTable).concat(Object.keys(this.dead));\r\n\t\t\tconst month = new Date().toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\t\t\tif (!logs.plays[month]) logs.plays[month] = {};\r\n\t\t\tfor (const player of played) {\r\n\t\t\t\tif (!logs.plays[month][player]) logs.plays[month][player] = 0;\r\n\t\t\t\tlogs.plays[month][player]++;\r\n\t\t\t}\r\n\t\t\tif (!logs.hosts[month]) logs.hosts[month] = {};\r\n\t\t\tfor (const hostid of [...this.cohostids, this.hostid]) {\r\n\t\t\t\tif (!logs.hosts[month][hostid]) logs.hosts[month][hostid] = 0;\r\n\t\t\t\tlogs.hosts[month][hostid]++;\r\n\t\t\t}\r\n\t\t\twriteFile(LOGS_FILE, logs);\r\n\t\t}\r\n\t\tif (this.timer) {\r\n\t\t\tclearTimeout(this.timer);\r\n\t\t\tthis.timer = null;\r\n\t\t}\r\n\t\tthis.destroy();\r\n\t}\r\n\r\n\tdestroy() {\r\n\t\t// Slightly modified to handle dead players\r\n\t\tif (this.timer) clearTimeout(this.timer);\r\n\t\tif (this.IDEA.timer) clearTimeout(this.IDEA.timer);\r\n\t\tthis.room.game = null;\r\n\t\t// @ts-ignore readonly\r\n\t\tthis.room = null;\r\n\t\tfor (const i in this.playerTable) {\r\n\t\t\tthis.playerTable[i].destroy();\r\n\t\t}\r\n\t\tfor (const i in this.dead) {\r\n\t\t\tthis.dead[i].destroy();\r\n\t\t}\r\n\t}\r\n}\r\n\r\nexport const pages: Chat.PageTable = {\r\n\tmafia(query, user) {\r\n\t\tif (!user.named) return Rooms.RETRY_AFTER_LOGIN;\r\n\t\tif (!query.length) return this.close();\r\n\t\tlet roomid = query.shift();\r\n\t\tif (roomid === 'groupchat') roomid += `-${query.shift()}-${query.shift()}`;\r\n\t\tconst room = Rooms.get(roomid);\r\n\t\tconst game = room?.getGame(Mafia);\r\n\t\tif (!room?.users[user.id] || !game || game.ended) {\r\n\t\t\treturn this.close();\r\n\t\t}\r\n\t\tconst isPlayer = user.id in game.playerTable;\r\n\t\tconst isHost = user.id === game.hostid || game.cohostids.includes(user.id);\r\n\t\tthis.title = game.title;\r\n\t\tlet buf = `
`;\r\n\t\tbuf += ``;\r\n\t\tbuf += `

${game.title}

Host: ${game.host}

${game.cohostids[0] ? `

Cohosts: ${game.cohosts.sort().join(', ')}

` : ''}`;\r\n\t\tbuf += `

Players (${game.playerCount}): ${Object.values(game.playerTable).map(p => p.safeName).sort().join(', ')}

`;\r\n\t\tif (game.started && Object.keys(game.dead).length > 0) {\r\n\t\t\tbuf += `

Dead Players`;\r\n\t\t\tfor (const d in game.dead) {\r\n\t\t\t\tconst dead = game.dead[d];\r\n\t\t\t\tbuf += `

${dead.safeName} ${dead.revealed ? '(' + dead.revealed + ')' : ''}`;\r\n\t\t\t\tif (dead.treestump) buf += ` (is a Treestump)`;\r\n\t\t\t\tif (dead.restless) buf += ` (is a Restless Spirit)`;\r\n\t\t\t\tif (isHost && !dead.revealed) {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t}\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t}\r\n\t\t\tbuf += `

`;\r\n\t\t}\r\n\t\tbuf += `
`;\r\n\t\tif (isPlayer && game.phase === 'IDEApicking') {\r\n\t\t\tbuf += `

IDEA information:
`;\r\n\t\t\tconst IDEA = game.playerTable[user.id].IDEA;\r\n\t\t\tif (!IDEA) {\r\n\t\t\t\treturn game.sendRoom(`IDEA picking phase but no IDEA object for user: ${user.id}. Please report this to a mod.`);\r\n\t\t\t}\r\n\t\t\tfor (const key in IDEA.picks) {\r\n\t\t\t\tconst pick = IDEA.picks[key];\r\n\t\t\t\tbuf += `${key}: `;\r\n\t\t\t\tif (!pick) {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t}\r\n\t\t\t\tconst selectedIndex = pick ? IDEA.originalChoices.indexOf(pick) : -1;\r\n\t\t\t\tfor (let i = 0; i < IDEA.originalChoices.length; i++) {\r\n\t\t\t\t\tconst choice = IDEA.originalChoices[i];\r\n\t\t\t\t\tif (i === selectedIndex) {\r\n\t\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbuf += `
`;\r\n\t\t\t}\r\n\t\t\tbuf += `

`;\r\n\t\t\tbuf += `

Role details:

`;\r\n\t\t\tfor (const role of IDEA.originalChoices) {\r\n\t\t\t\tconst roleObject = Mafia.parseRole(role);\r\n\t\t\t\tbuf += `

${role}`;\r\n\t\t\t\tbuf += `
    ${roleObject.role.memo.map(m => `
  • ${m}
  • `).join('')}
`;\r\n\t\t\t\tbuf += `
`;\r\n\t\t\t}\r\n\t\t\tbuf += `

`;\r\n\t\t}\r\n\t\tif (game.IDEA.data) {\r\n\t\t\tbuf += `

${game.IDEA.data.name} information`;\r\n\t\t\tif (game.IDEA.discardsHTML && (!game.IDEA.discardsHidden || isHost)) {\r\n\t\t\t\tbuf += `
Discards:

${game.IDEA.discardsHTML}

`;\r\n\t\t\t}\r\n\t\t\tbuf += `
Role list

${game.IDEA.data.roles.join('
')}

`;\r\n\t\t\tbuf += `

`;\r\n\t\t} else {\r\n\t\t\tif (!game.closedSetup || isHost) {\r\n\t\t\t\tif (game.theme) {\r\n\t\t\t\t\tbuf += `

Theme: ${game.theme.name}

`;\r\n\t\t\t\t\tbuf += `

${game.theme.desc}

`;\r\n\t\t\t\t}\r\n\t\t\t\tif (game.noReveal) {\r\n\t\t\t\t\tbuf += `

Original Rolelist${game.closedSetup ? ' (CS)' : ''}: ${game.originalRoleString}

`;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += `

Rolelist${game.closedSetup ? ' (CS)' : ''}: ${game.roleString}

`;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (isPlayer) {\r\n\t\t\tconst role = game.playerTable[user.id].role;\r\n\t\t\tlet previousActionsPL = `
`;\r\n\t\t\tif (role) {\r\n\t\t\t\tbuf += `

${game.playerTable[user.id].safeName}, you are a ${game.playerTable[user.id].getRole()}

`;\r\n\t\t\t\tif (!['town', 'solo'].includes(role.alignment)) {\r\n\t\t\t\t\tbuf += `

Partners: ${game.getPartners(role.alignment, game.playerTable[user.id])}

`;\r\n\t\t\t\t}\r\n\t\t\t\tbuf += `

Role Details`;\r\n\t\t\t\tbuf += `
    ${role.memo.map(m => `
  • ${m}
  • `).join('')}
`;\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t\tif (game.dayNum > 1) {\r\n\t\t\t\t\tfor (let i = 1; i < game.dayNum; i++) {\r\n\t\t\t\t\t\tpreviousActionsPL += `Night ${i}
`;\r\n\t\t\t\t\t\tpreviousActionsPL += `${game.playerTable[user.id].actionArr?.[i] ? `${game.playerTable[user.id].actionArr[i]}` : ''}
`;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbuf += `

Previous Actions${previousActionsPL}

`;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (game.phase === \"day\") {\r\n\t\t\tbuf += ``;\r\n\t\t\tbuf += game.voteBoxFor(user.id);\r\n\t\t\tbuf += ``;\r\n\t\t} else if (game.phase === \"night\" && isPlayer) {\r\n\t\t\tif (!game.takeIdles) {\r\n\t\t\t\tbuf += `

PM the host (${game.host}) the action you want to use tonight, and who you want to use it on. Or PM the host \"idle\".

`;\r\n\t\t\t} else {\r\n\t\t\t\tbuf += `Night Actions:`;\r\n\t\t\t\tif (game.playerTable[user.id].action === null) {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\tbuf += `
`;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\tif (game.playerTable[user.id].action) {\r\n\t\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\t\tif (game.playerTable[user.id].action === true) {\r\n\t\t\t\t\t\t\tbuf += `
`;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tbuf += `
`;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tbuf += ``;\r\n\t\t\t\t\t\tbuf += `
`;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (isHost) {\r\n\t\t\tif (game.phase === \"night\" && isHost && game.takeIdles) {\r\n\t\t\t\tbuf += `

Night Responses

`;\r\n\t\t\t\tlet actions = `
`;\r\n\t\t\t\tlet idles = `
`;\r\n\t\t\t\tlet noResponses = `
`;\r\n\t\t\t\tfor (const p in game.playerTable) {\r\n\t\t\t\t\tconst player = game.playerTable[p];\r\n\t\t\t\t\tif (player.action) {\r\n\t\t\t\t\t\tactions += `${player.safeName}${player.action === true ? '' : `: ${player.action}`}
`;\r\n\t\t\t\t\t} else if (player.action === false) {\r\n\t\t\t\t\t\tidles += `${player.safeName}
`;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tnoResponses += `${player.safeName}
`;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbuf += `

Idles${idles}

`;\r\n\t\t\t\tbuf += `

Actions${actions}

`;\r\n\t\t\t\tbuf += `

No Response${noResponses}

`;\r\n\t\t\t}\r\n\t\t\tlet previousActions = `
`;\r\n\t\t\tif (game.dayNum > 1) {\r\n\t\t\t\tfor (let i = 1; i < game.dayNum; i++) {\r\n\t\t\t\t\tpreviousActions += `Night ${i}
`;\r\n\t\t\t\t\tfor (const p in game.playerTable) {\r\n\t\t\t\t\t\tconst player = game.playerTable[p];\r\n\t\t\t\t\t\tpreviousActions += `${player.safeName}:${player.actionArr[i] ? `${player.actionArr[i]}` : ''}
`;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpreviousActions += `
`;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tbuf += `

Host options

`;\r\n\t\t\tbuf += `

General Options`;\r\n\t\t\tbuf += `

General Options

`;\r\n\t\t\tif (!game.started) {\r\n\t\t\t\tbuf += ``;\r\n\t\t\t\tif (game.phase === 'locked' || game.phase === 'IDEAlocked') {\r\n\t\t\t\t\tbuf += ` `;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += ` `;\r\n\t\t\t\t}\r\n\t\t\t} else if (game.phase === 'day') {\r\n\t\t\t\tbuf += ``;\r\n\t\t\t} else if (game.phase === 'night') {\r\n\t\t\t\tif (game.dayNum !== 0) {\r\n\t\t\t\t\tbuf += ` `;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += ``;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tbuf += ` `;\r\n\t\t\tbuf += ` `;\r\n\t\t\tbuf += ` `;\r\n\t\t\tbuf += ` `;\r\n\t\t\tbuf += ``;\r\n\t\t\tbuf += `

To set a deadline, use /mafia deadline [minutes].
To clear the deadline use /mafia deadline off.


`;\r\n\t\t\tbuf += `

Player Options`;\r\n\t\t\tbuf += `

Player Options

`;\r\n\t\t\tfor (const p in game.playerTable) {\r\n\t\t\t\tconst player = game.playerTable[p];\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t\tbuf += `${player.safeName} (${player.role ? player.getRole(true) : ''})`;\r\n\t\t\t\tbuf += game.voteModifiers[p] !== undefined ? `(votes worth ${game.getVoteValue(p as ID)})` : '';\r\n\t\t\t\tbuf += player.hammerRestriction !== null ? `(${player.hammerRestriction ? 'actor' : 'priest'})` : '';\r\n\t\t\t\tbuf += player.silenced ? '(silenced)' : '';\r\n\t\t\t\tbuf += player.nighttalk ? '(insomniac)' : '';\r\n\t\t\t\tbuf += ``;\r\n\t\t\t\tbuf += ` `;\r\n\t\t\t\tbuf += ` `;\r\n\t\t\t\tbuf += ` `;\r\n\t\t\t\tbuf += ` `;\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t}\r\n\t\t\tfor (const d in game.dead) {\r\n\t\t\t\tconst dead = game.dead[d];\r\n\t\t\t\tbuf += `

${dead.safeName} (${dead.role ? dead.getRole() : ''})`;\r\n\t\t\t\tif (dead.treestump) buf += ` (is a Treestump)`;\r\n\t\t\t\tif (dead.restless) buf += ` (is a Restless Spirit)`;\r\n\t\t\t\tif (game.voteModifiers[d] !== undefined) buf += ` (votes worth ${game.getVoteValue(d as ID)})`;\r\n\t\t\t\tbuf += dead.hammerRestriction !== null ? `(${dead.hammerRestriction ? 'actor' : 'priest'})` : '';\r\n\t\t\t\tbuf += dead.silenced ? '(silenced)' : '';\r\n\t\t\t\tbuf += dead.nighttalk ? '(insomniac)' : '';\r\n\t\t\t\tbuf += `:

`;\r\n\t\t\t}\r\n\t\t\tbuf += `

`;\r\n\t\t\tif (game.dayNum > 1) {\r\n\t\t\t\tbuf += `

Previous Night Actions${previousActions}

`;\r\n\t\t\t}\r\n\t\t\tbuf += `

How to setup roles`;\r\n\t\t\tbuf += `

Setting the roles

`;\r\n\t\t\tbuf += `

To set the roles, use /mafia setroles [comma seperated list of roles] OR /mafia setroles [theme] in ${room.title}.

`;\r\n\t\t\tbuf += `

If you set the roles from a theme, the role parser will get all the correct roles for you. (Not all themes are supported).

`;\r\n\t\t\tbuf += `

The following key words determine a role's alignment (If none are found, the default alignment is town):

`;\r\n\t\t\tbuf += `

${Object.values(MafiaData.alignments).map(a => `${a.name}`).join(', ')}

`;\r\n\t\t\tbuf += `

Please note that anything inside (parentheses) is ignored by the role parser.

`;\r\n\t\t\tbuf += `

If you have roles that have conflicting alignments or base roles, you can use /mafia forcesetroles [comma seperated list of roles] to forcibly set the roles.

`;\r\n\t\t\tbuf += `

Please note that you will have to PM all the players their alignment, partners (if any), and other information about their role because the server will not provide it.

`;\r\n\t\t\tbuf += `

`;\r\n\t\t\tbuf += `

Players who will be subbed unless they talk: ${game.hostRequestedSub.join(', ')}

`;\r\n\t\t\tbuf += `

Players who are requesting a sub: ${game.requestedSub.join(', ')}

`;\r\n\t\t}\r\n\t\tbuf += `

Sub List: ${game.subs.join(', ')}

`;\r\n\t\tif (!isHost) {\r\n\t\t\tif (game.phase === 'signups') {\r\n\t\t\t\tif (isPlayer) {\r\n\t\t\t\t\tbuf += `

`;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tbuf += `

`;\r\n\t\t\t\t}\r\n\t\t\t} else if ((!isPlayer && game.subs.includes(user.id)) || (isPlayer && !game.requestedSub.includes(user.id))) {\r\n\t\t\t\tbuf += `

${isPlayer ? 'Request to be subbed out' : 'Cancel sub request'}`;\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t} else {\r\n\t\t\t\tbuf += `

${isPlayer ? 'Cancel sub request' : 'Join the game as a sub'}`;\r\n\t\t\t\tbuf += `

`;\r\n\t\t\t}\r\n\t\t}\r\n\t\tbuf += `
`;\r\n\t\treturn buf;\r\n\t},\r\n\tmafialadder(query, user) {\r\n\t\tif (!user.named) return Rooms.RETRY_AFTER_LOGIN;\r\n\t\tconst mafiaRoom = Rooms.get('mafia');\r\n\t\tif (!query.length || !mafiaRoom) return this.close();\r\n\t\tconst headers: {[k: string]: {title: string, type: string, section: MafiaLogSection}} = {\r\n\t\t\tleaderboard: {title: 'Leaderboard', type: 'Points', section: 'leaderboard'},\r\n\t\t\tmvpladder: {title: 'MVP Ladder', type: 'MVPs', section: 'mvps'},\r\n\t\t\thostlogs: {title: 'Host Logs', type: 'Hosts', section: 'hosts'},\r\n\t\t\tplaylogs: {title: 'Play Logs', type: 'Plays', section: 'plays'},\r\n\t\t\tleaverlogs: {title: 'Leaver Logs', type: 'Leavers', section: 'leavers'},\r\n\t\t};\r\n\t\tconst date = new Date();\r\n\t\tif (query[1] === 'prev') date.setMonth(date.getMonth() - 1);\r\n\t\tconst month = date.toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\t\tconst ladder = headers[query[0]];\r\n\t\tif (!ladder) return this.close();\r\n\t\tif (['hosts', 'plays', 'leavers'].includes(ladder.section)) this.checkCan('mute', null, mafiaRoom);\r\n\t\tthis.title = `Mafia ${ladder.title} (${date.toLocaleString(\"en-us\", {month: 'long'})} ${date.getFullYear()})`;\r\n\t\tlet buf = `
`;\r\n\t\tbuf += `${query[1] === 'prev' ? '' : ` `}`;\r\n\t\tbuf += `

`;\r\n\t\tconst section = ladder.section;\r\n\t\tif (!logs[section][month] || !Object.keys(logs[section][month]).length) {\r\n\t\t\tbuf += `${ladder.title} for ${date.toLocaleString(\"en-us\", {month: 'long'})} ${date.getFullYear()} not found.
`;\r\n\t\t\treturn buf;\r\n\t\t}\r\n\t\tconst entries = Utils.sortBy(Object.entries(logs[section][month]), ([key, value]) => (\r\n\t\t\t-value\r\n\t\t));\r\n\t\tbuf += ``;\r\n\t\tbuf += ``;\r\n\t\tfor (const [key, value] of entries) {\r\n\t\t\tbuf += ``;\r\n\t\t}\r\n\t\treturn buf + `

Mafia ${ladder.title} for ${date.toLocaleString(\"en-us\", {month: 'long'})} ${date.getFullYear()}

User${ladder.type}
${key}${value}
`;\r\n\t},\r\n};\r\n\r\nexport const commands: Chat.ChatCommands = {\r\n\tmafia: {\r\n\t\t''(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = room.getGame(Mafia);\r\n\t\t\tif (game) {\r\n\t\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\t\treturn this.sendReply(`|html|${game.roomWindow()}`);\r\n\t\t\t}\r\n\t\t\treturn this.parse('/help mafia');\r\n\t\t},\r\n\r\n\t\tforcehost: 'host',\r\n\t\tnexthost: 'host',\r\n\t\thost(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tthis.checkChat();\r\n\t\t\tif (room.type !== 'chat') return this.errorReply(`This command is only meant to be used in chat rooms.`);\r\n\t\t\tif (room.game) return this.errorReply(`There is already a game of ${room.game.title} in progress in this room.`);\r\n\r\n\t\t\tconst nextHost = room.roomid === 'mafia' && cmd === 'nexthost';\r\n\t\t\tif (nextHost || !room.auth.has(user.id)) this.checkCan('show', null, room);\r\n\r\n\t\t\tlet targetUser!: User | null;\r\n\t\t\tlet targetUsername!: string;\r\n\t\t\tif (nextHost) {\r\n\t\t\t\tif (!hostQueue.length) return this.errorReply(`Nobody is on the host queue.`);\r\n\t\t\t\tconst skipped = [];\r\n\t\t\t\tlet hostid;\r\n\t\t\t\twhile ((hostid = hostQueue.shift())) {\r\n\t\t\t\t\t({targetUser, targetUsername} = this.splitUser(hostid, {exactName: true}));\r\n\t\t\t\t\tif (!targetUser?.connected ||\r\n\t\t\t\t\t\t!room.users[targetUser.id] || Mafia.isHostBanned(room, targetUser)) {\r\n\t\t\t\t\t\tskipped.push(hostid);\r\n\t\t\t\t\t\ttargetUser = null;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// found a host\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (skipped.length) {\r\n\t\t\t\t\tthis.sendReply(`${skipped.join(', ')} ${Chat.plural(skipped.length, 'were', 'was')} not online, not in the room, or are host banned and were removed from the host queue.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (!targetUser) return this.errorReply(`Nobody on the host queue could be hosted.`);\r\n\t\t\t} else {\r\n\t\t\t\t({targetUser, targetUsername} = this.splitUser(target, {exactName: true}));\r\n\t\t\t\tif (room.roomid === 'mafia' && hostQueue.length && toID(targetUsername) !== hostQueue[0]) {\r\n\t\t\t\t\tif (!cmd.includes('force')) {\r\n\t\t\t\t\t\treturn this.errorReply(`${targetUsername} isn't the next host on the queue. Use /mafia forcehost if you're sure.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (!targetUser?.connected) {\r\n\t\t\t\treturn this.errorReply(`The user \"${targetUsername}\" was not found.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (!nextHost && targetUser.id !== user.id) this.checkCan('mute', null, room);\r\n\r\n\t\t\tif (!room.users[targetUser.id]) {\r\n\t\t\t\treturn this.errorReply(`${targetUsername} is not in this room, and cannot be hosted.`);\r\n\t\t\t}\r\n\t\t\tif (Mafia.isHostBanned(room, targetUser)) {\r\n\t\t\t\treturn this.errorReply(`${targetUsername} is banned from hosting mafia games.`);\r\n\t\t\t}\r\n\r\n\t\t\troom.game = new Mafia(room, targetUser);\r\n\r\n\t\t\tfor (const conn of targetUser.connections) {\r\n\t\t\t\tvoid Chat.resolvePage(`view-mafia-${room.roomid}`, targetUser, conn);\r\n\t\t\t}\r\n\t\t\troom.addByUser(user, `${targetUser.name} was appointed the mafia host by ${user.name}.`);\r\n\t\t\tif (room.roomid === 'mafia') {\r\n\t\t\t\tconst queueIndex = hostQueue.indexOf(targetUser.id);\r\n\t\t\t\tif (queueIndex > -1) hostQueue.splice(queueIndex, 1);\r\n\t\t\t\troom.add(`|c:|${(Math.floor(Date.now() / 1000))}|~|**Mafiasignup!**`).update();\r\n\t\t\t}\r\n\t\t\tthis.modlog('MAFIAHOST', targetUser, null, {noalts: true, noip: true});\r\n\t\t},\r\n\t\thosthelp: [\r\n\t\t\t`/mafia host [user] - Create a game of Mafia with [user] as the host. Requires whitelist + % @ # &, drivers+ can host other people.`,\r\n\t\t],\r\n\r\n\t\tq: 'queue',\r\n\t\tqueue(target, room, user) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tif (room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tconst [command, targetUserID] = target.split(',').map(toID);\r\n\r\n\t\t\tswitch (command) {\r\n\t\t\tcase 'forceadd':\r\n\t\t\tcase 'add':\r\n\t\t\t\tthis.checkChat();\r\n\t\t\t\t// any rank can selfqueue\r\n\t\t\t\tif (targetUserID === user.id) {\r\n\t\t\t\t\tif (!room.auth.has(user.id)) this.checkCan('show', null, room);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\t\t}\r\n\t\t\t\tif (!targetUserID) return this.parse(`/help mafia queue`);\r\n\t\t\t\tconst targetUser = Users.get(targetUserID);\r\n\t\t\t\tif ((!targetUser?.connected) && !command.includes('force')) {\r\n\t\t\t\t\treturn this.errorReply(`User ${targetUserID} not found. To forcefully add the user to the queue, use /mafia queue forceadd, ${targetUserID}`);\r\n\t\t\t\t}\r\n\t\t\t\tif (hostQueue.includes(targetUserID)) return this.errorReply(`User ${targetUserID} is already on the host queue.`);\r\n\t\t\t\tif (targetUser && Mafia.isHostBanned(room, targetUser)) {\r\n\t\t\t\t\t return this.errorReply(`User ${targetUserID} is banned from hosting mafia games.`);\r\n\t\t\t\t}\r\n\t\t\t\thostQueue.push(targetUserID);\r\n\t\t\t\troom.add(`User ${targetUserID} has been added to the host queue by ${user.name}.`).update();\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'del':\r\n\t\t\tcase 'delete':\r\n\t\t\tcase 'remove':\r\n\t\t\t\t// anyone can self remove\r\n\t\t\t\tif (targetUserID !== user.id) this.checkCan('mute', null, room);\r\n\t\t\t\tconst index = hostQueue.indexOf(targetUserID);\r\n\t\t\t\tif (index === -1) return this.errorReply(`User ${targetUserID} is not on the host queue.`);\r\n\t\t\t\thostQueue.splice(index, 1);\r\n\t\t\t\troom.add(`User ${targetUserID} has been removed from the host queue by ${user.name}.`).update();\r\n\t\t\t\tbreak;\r\n\t\t\tcase '':\r\n\t\t\tcase 'show':\r\n\t\t\tcase 'view':\r\n\t\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\t\tthis.sendReplyBox(`Host Queue: ${hostQueue.join(', ')}`);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthis.parse('/help mafia queue');\r\n\t\t\t}\r\n\t\t},\r\n\t\tqueuehelp: [\r\n\t\t\t`/mafia queue - Shows the upcoming users who are going to host.`,\r\n\t\t\t`/mafia queue add, (user) - Adds the user to the hosting queue. Requires whitelist + % @ # &`,\r\n\t\t\t`/mafia queue remove, (user) - Removes the user from the hosting queue. Requires whitelist + % @ # &`,\r\n\t\t],\r\n\r\n\t\tqadd: 'queueadd',\r\n\t\tqforceadd: 'queueadd',\r\n\t\tqueueforceadd: 'queueadd',\r\n\t\tqueueadd(target, room, user, connection, cmd) {\r\n\t\t\tthis.parse(`/mafia queue ${cmd.includes('force') ? `forceadd` : `add`}, ${target}`);\r\n\t\t},\r\n\r\n\t\tqdel: 'queueremove',\r\n\t\tqdelete: 'queueremove',\r\n\t\tqremove: 'queueremove',\r\n\t\tqueueremove(target, room, user) {\r\n\t\t\tthis.parse(`/mafia queue remove, ${target}`);\r\n\t\t},\r\n\r\n\t\tjoin(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkChat(null, room);\r\n\t\t\tgame.join(user);\r\n\t\t},\r\n\t\tjoinhelp: [`/mafia join - Join the game.`],\r\n\r\n\t\tleave(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tgame.leave(user);\r\n\t\t},\r\n\t\tleavehelp: [`/mafia leave - Leave the game. Can only be done while signups are open.`],\r\n\r\n\t\tplayercap(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (game.phase !== 'signups') return this.errorReply(`Signups are already closed.`);\r\n\t\t\tif (toID(target) === 'none') target = '20';\r\n\t\t\tconst num = parseInt(target);\r\n\t\t\tif (isNaN(num) || num > 20 || num < 2) return this.parse('/help mafia playercap');\r\n\t\t\tif (num < game.playerCount) {\r\n\t\t\t\treturn this.errorReply(`Player cap has to be equal or more than the amount of players in game.`);\r\n\t\t\t}\r\n\t\t\tif (num === game.playerCap) return this.errorReply(`Player cap is already set at ${game.playerCap}.`);\r\n\t\t\tgame.playerCap = num;\r\n\t\t\tgame.sendDeclare(`Player cap has been set to ${game.playerCap}`);\r\n\t\t\tgame.logAction(user, `set playercap to ${num}`);\r\n\t\t},\r\n\t\tplayercaphelp: [\r\n\t\t\t`/mafia playercap [cap|none]- Limit the number of players being able to join the game. Player cap cannot be more than 20 or less than 2. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tclose(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (game.phase !== 'signups') return this.errorReply(`Signups are already closed.`);\r\n\t\t\tif (game.playerCount < 2) return this.errorReply(`You need at least 2 players to start.`);\r\n\t\t\tgame.phase = 'locked';\r\n\t\t\tgame.sendHTML(game.roomWindow());\r\n\t\t\tgame.updatePlayers();\r\n\t\t\tgame.logAction(user, `closed signups`);\r\n\t\t},\r\n\t\tclosehelp: [`/mafia close - Closes signups for the current game. Requires host % @ # &`],\r\n\r\n\t\tcs: 'closedsetup',\r\n\t\tclosedsetup(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (!['on', 'off'].includes(action)) return this.parse('/help mafia closedsetup');\r\n\t\t\tif (game.started) {\r\n\t\t\t\treturn this.errorReply(`You can't ${action === 'on' ? 'enable' : 'disable'} closed setup because the game has already started.`);\r\n\t\t\t}\r\n\t\t\tif ((action === 'on' && game.closedSetup) || (action === 'off' && !game.closedSetup)) {\r\n\t\t\t\treturn this.errorReply(`Closed setup is already ${game.closedSetup ? 'enabled' : 'disabled'}.`);\r\n\t\t\t}\r\n\t\t\tgame.closedSetup = action === 'on';\r\n\t\t\tgame.sendDeclare(`The game is ${action === 'on' ? 'now' : 'no longer'} a closed setup.`);\r\n\t\t\tgame.updateHost();\r\n\t\t\tgame.logAction(user, `${game.closedSetup ? 'enabled' : 'disabled'} closed setup`);\r\n\t\t},\r\n\t\tclosedsetuphelp: [\r\n\t\t\t`/mafia closedsetup [on|off] - Sets if the game is a closed setup. Closed setups don't show the role list to players. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\treveal(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (!['on', 'off'].includes(action)) return this.parse('/help mafia reveal');\r\n\t\t\tif ((action === 'off' && game.noReveal) || (action === 'on' && !game.noReveal)) {\r\n\t\t\t\treturn user.sendTo(\r\n\t\t\t\t\troom,\r\n\t\t\t\t\t`|error|Revealing of roles is already ${game.noReveal ? 'disabled' : 'enabled'}.`\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tgame.noReveal = action === 'off';\r\n\t\t\tgame.sendDeclare(`Revealing of roles has been ${action === 'off' ? 'disabled' : 'enabled'}.`);\r\n\t\t\tgame.updatePlayers();\r\n\t\t\tgame.logAction(user, `${game.noReveal ? 'disabled' : 'enabled'} reveals`);\r\n\t\t},\r\n\t\trevealhelp: [`/mafia reveal [on|off] - Sets if roles reveal on death or not. Requires host % @ # &`],\r\n\r\n\t\ttakeidles(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (!['on', 'off'].includes(action)) return this.parse('/help mafia takeidles');\r\n\t\t\tif ((action === 'off' && !game.takeIdles) || (action === 'on' && game.takeIdles)) {\r\n\t\t\t\treturn this.errorReply(`Actions and idles are already ${game.takeIdles ? '' : 'not '}being accepted.`);\r\n\t\t\t}\r\n\t\t\tgame.takeIdles = action === 'on';\r\n\t\t\tgame.sendDeclare(`Actions and idles are ${game.takeIdles ? 'now' : 'no longer'} being accepted.`);\r\n\t\t\tgame.updatePlayers();\r\n\t\t},\r\n\t\ttakeidleshelp: [`/mafia takeidles [on|off] - Sets if idles are accepted by the script or not. Requires host % @ # &`],\r\n\r\n\t\tresetroles: 'setroles',\r\n\t\tforceresetroles: 'setroles',\r\n\t\tforcesetroles: 'setroles',\r\n\t\tsetroles(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst reset = cmd.includes('reset');\r\n\t\t\tif (reset) {\r\n\t\t\t\tif (game.phase !== 'day' && game.phase !== 'night') return this.errorReply(`The game has not started yet.`);\r\n\t\t\t} else {\r\n\t\t\t\tif (game.phase !== 'locked' && game.phase !== 'IDEAlocked') {\r\n\t\t\t\t\treturn this.errorReply(game.phase === 'signups' ? `You need to close signups first.` : `The game has already started.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!target) return this.parse('/help mafia setroles');\r\n\r\n\t\t\tgame.setRoles(user, target, cmd.includes('force'), reset);\r\n\t\t\tgame.logAction(user, `${reset ? 're' : ''}set roles`);\r\n\t\t},\r\n\t\tsetroleshelp: [\r\n\t\t\t`/mafia setroles [comma separated roles] - Set the roles for a game of mafia. You need to provide one role per player.`,\r\n\t\t\t`/mafia forcesetroles [comma separated roles] - Forcibly set the roles for a game of mafia. No role PM information or alignment will be set.`,\r\n\t\t\t`/mafia resetroles [comma separated roles] - Reset the roles in an ongoing game.`,\r\n\t\t],\r\n\r\n\t\tresetgame: 'gamereset',\r\n\t\tforceresetgame: 'gamereset',\r\n\t\tgamereset(target, room, user, connection) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (target) return this.parse('/help mafia resetgame');\r\n\t\t\tif (game.phase !== 'day' && game.phase !== 'night') return this.errorReply(`The game has not started yet.`);\r\n\t\t\tif (game.IDEA.data) return this.errorReply(`You cannot use this command in IDEA.`);\r\n\t\t\tgame.resetGame();\r\n\t\t\tgame.logAction(user, 'reset the game state');\r\n\t\t},\r\n\t\tresetgamehelp: [\r\n\t\t\t`/mafia resetgame - Resets game data. Does not change settings from the host (besides deadlines) or add/remove any players. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tidea(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkCan('show', null, room);\r\n\t\t\tif (!user.can('mute', null, room) && game.hostid !== user.id && !game.cohostids.includes(user.id)) {\r\n\t\t\t\treturn this.errorReply(`/mafia idea - Access denied.`);\r\n\t\t\t}\r\n\t\t\tif (game.started) return this.errorReply(`You cannot start an IDEA after the game has started.`);\r\n\t\t\tif (game.phase !== 'locked' && game.phase !== 'IDEAlocked') {\r\n\t\t\t\treturn this.errorReply(`You need to close the signups first.`);\r\n\t\t\t}\r\n\t\t\tgame.ideaInit(user, toID(target));\r\n\t\t\tgame.logAction(user, `started an IDEA`);\r\n\t\t},\r\n\t\tideahelp: [\r\n\t\t\t`/mafia idea [idea] - starts the IDEA module [idea]. Requires + % @ # &, voices can only start for themselves`,\r\n\t\t\t`/mafia ideareroll - rerolls the IDEA module. Requires host % @ # &`,\r\n\t\t\t`/mafia ideapick [selection], [role] - selects a role`,\r\n\t\t\t`/mafia ideadiscards - shows the discarded roles`,\r\n\t\t],\r\n\r\n\t\tcustomidea(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.started) return this.errorReply(`You cannot start an IDEA after the game has started.`);\r\n\t\t\tif (game.phase !== 'locked' && game.phase !== 'IDEAlocked') {\r\n\t\t\t\treturn this.errorReply(`You need to close the signups first.`);\r\n\t\t\t}\r\n\t\t\tconst [options, roles] = Utils.splitFirst(target, '\\n');\r\n\t\t\tif (!options || !roles) return this.parse('/help mafia idea');\r\n\t\t\tconst [choicesStr, ...picks] = options.split(',').map(x => x.trim());\r\n\t\t\tconst choices = parseInt(choicesStr);\r\n\t\t\tif (!choices || choices <= picks.length) return this.errorReply(`You need to have more choices than picks.`);\r\n\t\t\tif (picks.some((value, index, arr) => arr.indexOf(value, index + 1) > 0)) {\r\n\t\t\t\treturn this.errorReply(`Your picks must be unique.`);\r\n\t\t\t}\r\n\t\t\tgame.customIdeaInit(user, choices, picks, roles);\r\n\t\t},\r\n\t\tcustomideahelp: [\r\n\t\t\t`/mafia customidea choices, picks (new line here, shift+enter)`,\r\n\t\t\t`(comma or newline separated rolelist) - Starts an IDEA module with custom roles. Requires % @ # &`,\r\n\t\t\t`choices refers to the number of roles you get to pick from. In GI, this is 2, in GestI, this is 3.`,\r\n\t\t\t`picks refers to what you choose. In GI, this should be 'role', in GestI, this should be 'role, alignment'`,\r\n\t\t],\r\n\t\tideapick(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst args = target.split(',');\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (!(user.id in game.playerTable)) {\r\n\t\t\t\treturn user.sendTo(room, '|error|You are not a player in the game.');\r\n\t\t\t}\r\n\t\t\tif (game.phase !== 'IDEApicking') {\r\n\t\t\t\treturn this.errorReply(`The game is not in the IDEA picking phase.`);\r\n\t\t\t}\r\n\t\t\tgame.ideaPick(user, args);\r\n\t\t},\r\n\r\n\t\tideareroll(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tgame.ideaDistributeRoles(user);\r\n\t\t\tgame.logAction(user, `rerolled an IDEA`);\r\n\t\t},\r\n\t\tidearerollhelp: [`/mafia ideareroll - rerolls the roles for the current IDEA module. Requires host % @ # &`],\r\n\r\n\t\tdiscards: 'ideadiscards',\r\n\t\tideadiscards(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (!game.IDEA.data) return this.errorReply(`There is no IDEA module in the mafia game.`);\r\n\t\t\tif (target) {\r\n\t\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\t\tif (this.meansNo(target)) {\r\n\t\t\t\t\tif (game.IDEA.discardsHidden) return this.errorReply(`IDEA discards are already hidden.`);\r\n\t\t\t\t\tgame.IDEA.discardsHidden = true;\r\n\t\t\t\t} else if (this.meansYes(target)) {\r\n\t\t\t\t\tif (!game.IDEA.discardsHidden) return this.errorReply(`IDEA discards are already visible.`);\r\n\t\t\t\t\tgame.IDEA.discardsHidden = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.parse('/help mafia ideadiscards');\r\n\t\t\t\t}\r\n\t\t\t\tgame.logAction(user, `${game.IDEA.discardsHidden ? 'hid' : 'unhid'} IDEA discards`);\r\n\t\t\t\treturn this.sendReply(`IDEA discards are now ${game.IDEA.discardsHidden ? 'hidden' : 'visible'}.`);\r\n\t\t\t}\r\n\t\t\tif (game.IDEA.discardsHidden) return this.errorReply(`Discards are not visible.`);\r\n\t\t\tif (!game.IDEA.discardsHTML) return this.errorReply(`The IDEA module does not have finalised discards yet.`);\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tthis.sendReplyBox(`
IDEA discards:${game.IDEA.discardsHTML}
`);\r\n\t\t},\r\n\t\tideadiscardshelp: [\r\n\t\t\t`/mafia ideadiscards - shows the discarded roles`,\r\n\t\t\t`/mafia ideadiscards off - hides discards from the players. Requires host % @ # &`,\r\n\t\t\t`/mafia ideadiscards on - shows discards to the players. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tdaystart: 'start',\r\n\t\tnightstart: 'start',\r\n\t\tstart(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (target) {\r\n\t\t\t\tthis.parse(`/mafia close`);\r\n\t\t\t\tthis.parse(`/mafia setroles ${target}`);\r\n\t\t\t\tthis.parse(`/mafia ${cmd}`);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tgame.start(user, cmd === 'daystart');\r\n\t\t\tgame.logAction(user, `started the game`);\r\n\t\t},\r\n\t\tstarthelp: [`/mafia start - Start the game of mafia. Signups must be closed. Requires host % @ # &`],\r\n\r\n\t\textend: 'day',\r\n\t\tnight: 'day',\r\n\t\tday(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (cmd === 'night') {\r\n\t\t\t\tgame.night();\r\n\t\t\t} else {\r\n\t\t\t\tlet extension = parseInt(toID(target));\r\n\t\t\t\tif (isNaN(extension)) {\r\n\t\t\t\t\textension = 0;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (extension < 1) extension = 1;\r\n\t\t\t\t\tif (extension > 10) extension = 10;\r\n\t\t\t\t}\r\n\t\t\t\tif (cmd === 'extend') {\r\n\t\t\t\t\tfor (const p in game.playerTable) {\r\n\t\t\t\t\t\tconst player = game.playerTable[p];\r\n\t\t\t\t\t\tplayer.actionArr[game.dayNum] = '';\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tgame.day(cmd === 'extend' ? extension : null);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `set day/night`);\r\n\t\t},\r\n\t\tdayhelp: [\r\n\t\t\t`/mafia day - Move to the next game day. Requires host % @ # &`,\r\n\t\t\t`/mafia night - Move to the next game night. Requires host % @ # &`,\r\n\t\t\t`/mafia extend (minutes) - Return to the previous game day. If (minutes) is provided, set the deadline for (minutes) minutes. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tprod(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (game.phase !== 'night') return;\r\n\t\t\tfor (const player of Object.values(game.playerTable)) {\r\n\t\t\t\tconst playerid = Users.get(player.id);\r\n\t\t\t\tif (playerid?.connected && player.action === null) {\r\n\t\t\t\t\tplayerid.sendTo(room, `|notify|Send in an action or idle!`);\r\n\t\t\t\t\tplayerid.sendTo(room, `Send in an action or idle, or else you will get subbed out!`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tgame.sendDeclare(`Unsubmitted players have been reminded to submit an action or idle.`);\r\n\t\t},\r\n\t\tprodhelp: [\r\n\t\t\t`/mafia prod - Notifies players that they must submit an action or idle if they haven't yet. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tv: 'vote',\r\n\t\tvote(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkChat(null, room);\r\n\t\t\tif (!(user.id in game.playerTable) &&\r\n\t\t\t\t(!(user.id in game.dead) || !game.dead[user.id].restless)) {\r\n\t\t\t\treturn this.errorReply(`You are not in the game of ${game.title}.`);\r\n\t\t\t}\r\n\t\t\tgame.vote(user.id, toID(target));\r\n\t\t},\r\n\t\tvotehelp: [`/mafia vote [player|novote] - Vote the specified player or abstain from voting.`],\r\n\r\n\t\tuv: 'unvote',\r\n\t\tunv: 'unvote',\r\n\t\tunnovote: 'unvote',\r\n\t\tunvote(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkChat(null, room);\r\n\t\t\tif (!(user.id in game.playerTable) &&\r\n\t\t\t\t(!(user.id in game.dead) || !game.dead[user.id].restless)) {\r\n\t\t\t\treturn this.errorReply(`You are not in the game of ${game.title}.`);\r\n\t\t\t}\r\n\t\t\tgame.unvote(user.id);\r\n\t\t},\r\n\t\tunvotehelp: [`/mafia unvote - Withdraw your vote. Fails if you're not voting anyone`],\r\n\r\n\t\tnv: 'novote',\r\n\t\tnovote() {\r\n\t\t\tthis.parse('/mafia vote novote');\r\n\t\t},\r\n\r\n\t\tenableself: 'selfvote',\r\n\t\tselfvote(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (!action) return this.parse(`/help mafia selfvote`);\r\n\t\t\tif (this.meansYes(action)) {\r\n\t\t\t\tgame.setSelfVote(user, true);\r\n\t\t\t} else if (this.meansNo(action)) {\r\n\t\t\t\tgame.setSelfVote(user, false);\r\n\t\t\t} else if (action === 'hammer') {\r\n\t\t\t\tgame.setSelfVote(user, 'hammer');\r\n\t\t\t} else {\r\n\t\t\t\treturn this.parse(`/help mafia selfvote`);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed selfvote`);\r\n\t\t},\r\n\t\tselfvotehelp: [\r\n\t\t\t`/mafia selfvote [on|hammer|off] - Allows players to self vote themselves either at hammer or anytime. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\ttreestump: 'kill',\r\n\t\tspirit: 'kill',\r\n\t\tspiritstump: 'kill',\r\n\t\tkick: 'kill',\r\n\t\tkill(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (game.phase === 'IDEApicking') {\r\n\t\t\t\treturn this.errorReply(`You cannot add or remove players while IDEA roles are being picked.`); // needs to be here since eliminate doesn't pass the user\r\n\t\t\t}\r\n\t\t\tif (!target) return this.parse('/help mafia kill');\r\n\t\t\tconst player = game.playerTable[toID(target)];\r\n\t\t\tconst dead = game.dead[toID(target)];\r\n\t\t\tlet repeat;\r\n\t\t\tif (dead) {\r\n\t\t\t\tswitch (cmd) {\r\n\t\t\t\tcase 'treestump':\r\n\t\t\t\t\trepeat = dead.treestump && !dead.restless;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'spirit':\r\n\t\t\t\t\trepeat = !dead.treestump && dead.restless;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'spiritstump':\r\n\t\t\t\t\trepeat = dead.treestump && dead.restless;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'kill': case 'kick':\r\n\t\t\t\t\trepeat = !dead.treestump && !dead.restless;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (dead && repeat) return this.errorReply(`${dead.safeName} has already been ${cmd}ed.`);\r\n\t\t\tif (player || dead) {\r\n\t\t\t\tgame.eliminate(toID(target), cmd);\r\n\t\t\t\tgame.logAction(user, `${cmd}ed ${(dead || player).safeName}`);\r\n\t\t\t} else {\r\n\t\t\t\tthis.errorReply(`${target.trim()} is not a player.`);\r\n\t\t\t}\r\n\t\t},\r\n\t\tkillhelp: [\r\n\t\t\t`/mafia kill [player] - Kill a player, eliminating them from the game. Requires host % @ # &`,\r\n\t\t\t`/mafia treestump [player] - Kills a player, but allows them to talk during the day still.`,\r\n\t\t\t`/mafia spirit [player] - Kills a player, but allows them to vote still.`,\r\n\t\t\t`/mafia spiritstump [player] Kills a player, but allows them to talk and vote during the day.`,\r\n\t\t],\r\n\r\n\t\trevealas: 'revealrole',\r\n\t\trevealrole(target, room, user, connection, cmd) {\r\n\t\t\tconst args = target.split(',');\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tlet revealAs = '';\r\n\t\t\tlet revealedRole = null;\r\n\t\t\tif (cmd === 'revealas') {\r\n\t\t\t\tif (!args[0]) {\r\n\t\t\t\t\treturn this.parse('/help mafia revealas');\r\n\t\t\t\t} else {\r\n\t\t\t\t\trevealedRole = Mafia.parseRole(args.pop()!);\r\n\t\t\t\t\tconst color = MafiaData.alignments[revealedRole.role.alignment].color;\r\n\t\t\t\t\trevealAs = `${revealedRole.role.safeName}`;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!args[0]) return this.parse('/help mafia revealas');\r\n\t\t\tfor (const targetUsername of args) {\r\n\t\t\t\tlet player = game.playerTable[toID(targetUsername)];\r\n\t\t\t\tif (!player) player = game.dead[toID(targetUsername)];\r\n\t\t\t\tif (player) {\r\n\t\t\t\t\tgame.revealRole(user, player, `${cmd === 'revealas' ? revealAs : player.getRole()}`);\r\n\t\t\t\t\tgame.logAction(user, `revealed ${player.name}`);\r\n\t\t\t\t\tif (cmd === 'revealas') {\r\n\t\t\t\t\t\tgame.secretLogAction(user, `fakerevealed ${player.name} as ${revealedRole!.role.name}`);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.errorReply(`${targetUsername} is not a player.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\trevealrolehelp: [\r\n\t\t\t`/mafia revealrole [player] - Reveals the role of a player. Requires host % @ # &`,\r\n\t\t\t`/mafia revealas [player], [role] - Fakereveals the role of a player as a certain role. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tunidle: 'idle',\r\n\t\tunaction: 'idle',\r\n\t\tnoresponse: 'idle',\r\n\t\taction: 'idle',\r\n\t\tidle(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tconst player = game.playerTable[user.id];\r\n\t\t\tif (!player) return this.errorReply(`You are not in the game of ${game.title}.`);\r\n\t\t\tif (game.phase !== 'night') return this.errorReply(`You can only submit an action or idle during the night phase.`);\r\n\t\t\tif (!game.takeIdles) {\r\n\t\t\t\treturn this.errorReply(`The host is not accepting idles through the script. Send your action or idle to the host.`);\r\n\t\t\t}\r\n\t\t\tswitch (cmd) {\r\n\t\t\tcase 'idle':\r\n\t\t\t\tplayer.action = false;\r\n\t\t\t\tuser.sendTo(room, `You have idled.`);\r\n\t\t\t\tplayer.actionArr[game.dayNum] = 'idle';\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'action':\r\n\t\t\t\tplayer.action = true;\r\n\t\t\t\tif (target) {\r\n\t\t\t\t\tplayer.action = target;\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.checkBanwords(room, target);\r\n\t\t\t\t\t} catch {\r\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Your action submission contained a word banned by this room.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tuser.sendTo(room, `You have decided to use an action, with the following details: ${target}`);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tuser.sendTo(room, `You have decided to use an action. Please submit details about your action.`);\r\n\t\t\t\t}\r\n\t\t\t\tplayer.actionArr[game.dayNum] = target;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'noresponse': case 'unidle': case 'unaction':\r\n\t\t\t\tplayer.action = null;\r\n\t\t\t\tuser.sendTo(room, `You are no longer submitting an action or idle.`);\r\n\t\t\t\tplayer.actionArr[game.dayNum] = '';\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tplayer.updateHtmlRoom();\r\n\t\t},\r\n\t\tactionhelp: 'idlehelp',\r\n\t\tidlehelp: [\r\n\t\t\t`/mafia idle - Tells the host if you are idling.`,\r\n\t\t\t`/mafia action [details] - Tells the host you are using an action with the given submission details.`,\r\n\t\t],\r\n\r\n\t\tforceadd: 'revive',\r\n\t\tadd: 'revive',\r\n\t\trevive(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!toID(target)) return this.parse('/help mafia revive');\r\n\t\t\tlet didSomething = false;\r\n\t\t\tif (game.revive(user, toID(target), cmd === 'forceadd')) {\r\n\t\t\t\tdidSomething = true;\r\n\t\t\t}\r\n\t\t\tif (didSomething) game.logAction(user, `added players`);\r\n\t\t},\r\n\t\trevivehelp: [\r\n\t\t\t`/mafia revive [player] - Revive a player who died or add a new player to the game. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tdl: 'deadline',\r\n\t\tdeadline(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\ttarget = toID(target);\r\n\t\t\tif (target && game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (target === 'off') {\r\n\t\t\t\tgame.setDeadline(0);\r\n\t\t\t} else {\r\n\t\t\t\tconst num = parseInt(target);\r\n\t\t\t\tif (isNaN(num)) {\r\n\t\t\t\t\t// hack to let hosts broadcast\r\n\t\t\t\t\tif (game.hostid === user.id || game.cohostids.includes(user.id)) {\r\n\t\t\t\t\t\tthis.broadcastMessage = this.message.toLowerCase().replace(/[^a-z0-9\\s!,]/g, '');\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!this.runBroadcast()) return false;\r\n\r\n\t\t\t\t\tif ((game.dlAt - Date.now()) > 0) {\r\n\t\t\t\t\t\treturn this.sendReply(`|raw|The deadline is in ${Chat.toDurationString(game.dlAt - Date.now()) || '0 seconds'}.`);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\treturn this.parse(`/help mafia deadline`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (num < 1 || num > 20) return this.errorReply(`The deadline must be between 1 and 20 minutes.`);\r\n\t\t\t\tgame.setDeadline(num);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed deadline`);\r\n\t\t},\r\n\t\tdeadlinehelp: [\r\n\t\t\t`/mafia deadline [minutes|off] - Sets or removes the deadline for the game. Cannot be more than 20 minutes.`,\r\n\t\t],\r\n\r\n\t\tapplyvotemodifier: 'applyhammermodifier',\r\n\t\tapplyhammermodifier(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\t\t\tconst [player, mod] = target.split(',');\r\n\t\t\tif (cmd === 'applyhammermodifier') {\r\n\t\t\t\tgame.applyHammerModifier(user, toID(player), parseInt(mod));\r\n\t\t\t\tgame.secretLogAction(user, `changed a hammer modifier`);\r\n\t\t\t} else {\r\n\t\t\t\tgame.applyVoteModifier(user, toID(player), parseInt(mod));\r\n\t\t\t\tgame.secretLogAction(user, `changed a vote modifier`);\r\n\t\t\t}\r\n\t\t},\r\n\t\tclearvotemodifiers: 'clearhammermodifiers',\r\n\t\tclearhammermodifiers(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\t\t\tif (cmd === 'clearhammermodifiers') {\r\n\t\t\t\tgame.clearHammerModifiers(user);\r\n\t\t\t\tgame.secretLogAction(user, `cleared hammer modifiers`);\r\n\t\t\t} else {\r\n\t\t\t\tgame.clearVoteModifiers(user);\r\n\t\t\t\tgame.secretLogAction(user, `cleared vote modifiers`);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\thate: 'love',\r\n\t\tunhate: 'love',\r\n\t\tunlove: 'love',\r\n\t\tremovehammermodifier: 'love',\r\n\t\tlove(target, room, user, connection, cmd) {\r\n\t\t\tlet mod;\r\n\t\t\tswitch (cmd) {\r\n\t\t\tcase 'hate':\r\n\t\t\t\tmod = -1;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'love':\r\n\t\t\t\tmod = 1;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'unhate': case 'unlove': case 'removehammermodifier':\r\n\t\t\t\tmod = 0;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tthis.parse(`/mafia applyhammermodifier ${target}, ${mod}`);\r\n\t\t},\r\n\t\tdoublevoter: 'mayor',\r\n\t\tvoteless: 'mayor',\r\n\t\tunvoteless: 'mayor',\r\n\t\tunmayor: 'mayor',\r\n\t\tremovevotemodifier: 'mayor',\r\n\t\tmayor(target, room, user, connection, cmd) {\r\n\t\t\tlet mod;\r\n\t\t\tswitch (cmd) {\r\n\t\t\tcase 'doublevoter': case 'mayor':\r\n\t\t\t\tmod = 2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'voteless':\r\n\t\t\t\tmod = 0;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'unvoteless': case 'unmayor': case 'removevotemodifier':\r\n\t\t\t\tmod = 1;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tthis.parse(`/mafia applyvotemodifier ${target}, ${mod}`);\r\n\t\t},\r\n\r\n\t\tunsilence: 'silence',\r\n\t\tsilence(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\r\n\t\t\ttarget = toID(target);\r\n\t\t\tconst targetPlayer = game.playerTable[target] || game.dead[target];\r\n\t\t\tconst silence = cmd === 'silence';\r\n\t\t\tif (!targetPlayer) return this.errorReply(`${target} is not in the game of mafia.`);\r\n\t\t\tif (silence === targetPlayer.silenced) {\r\n\t\t\t\treturn this.errorReply(`${targetPlayer.name} is already ${!silence ? 'not' : ''} silenced.`);\r\n\t\t\t}\r\n\t\t\ttargetPlayer.silenced = silence;\r\n\t\t\tthis.sendReply(`${targetPlayer.name} has been ${!silence ? 'un' : ''}silenced.`);\r\n\t\t\tgame.logAction(user, `${!silence ? 'un' : ''}silenced a player`);\r\n\t\t},\r\n\t\tsilencehelp: [\r\n\t\t\t`/mafia silence [player] - Silences [player], preventing them from talking at all. Requires host % @ # &`,\r\n\t\t\t`/mafia unsilence [player] - Removes a silence on [player], allowing them to talk again. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tinsomniac: 'nighttalk',\r\n\t\tuninsomniac: 'nighttalk',\r\n\t\tunnighttalk: 'nighttalk',\r\n\t\tnighttalk(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\r\n\t\t\ttarget = toID(target);\r\n\t\t\tconst targetPlayer = game.playerTable[target] || game.dead[target];\r\n\t\t\tconst nighttalk = !cmd.startsWith('un');\r\n\t\t\tif (!targetPlayer) return this.errorReply(`${target} is not in the game of mafia.`);\r\n\t\t\tif (nighttalk === targetPlayer.nighttalk) {\r\n\t\t\t\treturn this.errorReply(`${targetPlayer.name} is already ${!nighttalk ? 'not' : ''} able to talk during the night.`);\r\n\t\t\t}\r\n\t\t\ttargetPlayer.nighttalk = nighttalk;\r\n\t\t\tthis.sendReply(`${targetPlayer.name} can ${!nighttalk ? 'no longer' : 'now'} talk during the night.`);\r\n\t\t\tgame.logAction(user, `${!nighttalk ? 'un' : ''}insomniacd a player`);\r\n\t\t},\r\n\t\tnighttalkhelp: [\r\n\t\t\t`/mafia nighttalk [player] - Makes [player] an insomniac, allowing them to talk freely during the night. Requires host % @ # &`,\r\n\t\t\t`/mafia unnighttalk [player] - Removes [player] as an insomniac, preventing them from talking during the night. Requires host % @ # &`,\r\n\t\t],\r\n\t\tactor: 'priest',\r\n\t\tunactor: 'priest',\r\n\t\tunpriest: 'priest',\r\n\t\tpriest(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\r\n\t\t\ttarget = toID(target);\r\n\t\t\tconst targetPlayer = game.playerTable[target] || game.dead[target];\r\n\t\t\tif (!targetPlayer) return this.errorReply(`${target} is not in the game of mafia.`);\r\n\r\n\t\t\tconst actor = cmd.endsWith('actor');\r\n\t\t\tconst remove = cmd.startsWith('un');\r\n\t\t\tif (remove) {\r\n\t\t\t\tif (targetPlayer.hammerRestriction === null) {\r\n\t\t\t\t\treturn this.errorReply(`${targetPlayer.name} already has no voting restrictions.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (actor !== targetPlayer.hammerRestriction) {\r\n\t\t\t\t\treturn this.errorReply(`${targetPlayer.name} is ${targetPlayer.hammerRestriction ? 'an actor' : 'a priest'}.`);\r\n\t\t\t\t}\r\n\t\t\t\ttargetPlayer.hammerRestriction = null;\r\n\t\t\t\treturn this.sendReply(`${targetPlayer}'s hammer restriction was removed.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (actor === targetPlayer.hammerRestriction) {\r\n\t\t\t\treturn this.errorReply(`${targetPlayer.name} is already ${targetPlayer.hammerRestriction ? 'an actor' : 'a priest'}.`);\r\n\t\t\t}\r\n\t\t\ttargetPlayer.hammerRestriction = actor;\r\n\t\t\tthis.sendReply(`${targetPlayer.name} is now ${targetPlayer.hammerRestriction ? \"an actor (can only hammer)\" : \"a priest (can't hammer)\"}.`);\r\n\t\t\tif (actor) {\r\n\t\t\t\t// target is an actor, remove their vote because it's now impossible\r\n\t\t\t\tgame.unvote(targetPlayer.id, true);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `made a player actor/priest`);\r\n\t\t},\r\n\t\tpriesthelp: [\r\n\t\t\t`/mafia (un)priest [player] - Makes [player] a priest, preventing them from placing the hammer vote. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)actor [player] - Makes [player] an actor, preventing them from placing non-hammer votes. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tshifthammer: 'hammer',\r\n\t\tresethammer: 'hammer',\r\n\t\thammer(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started yet.`);\r\n\t\t\tconst hammer = parseInt(target);\r\n\t\t\tif (toID(cmd) !== `resethammer` && ((isNaN(hammer) && !this.meansNo(target)) || hammer < 1)) {\r\n\t\t\t\treturn this.errorReply(`${target} is not a valid hammer count.`);\r\n\t\t\t}\r\n\t\t\tswitch (cmd.toLowerCase()) {\r\n\t\t\tcase 'shifthammer':\r\n\t\t\t\tgame.shiftHammer(hammer);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'hammer':\r\n\t\t\t\tgame.setHammer(hammer);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tgame.resetHammer();\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed the hammer`);\r\n\t\t},\r\n\t\thammerhelp: [\r\n\t\t\t`/mafia hammer [hammer] - sets the hammer count to [hammer] and resets votes`,\r\n\t\t\t`/mafia hammer off - disables hammering`,\r\n\t\t\t`/mafia shifthammer [hammer] - sets the hammer count to [hammer] without resetting votes`,\r\n\t\t\t`/mafia resethammer - sets the hammer to the default, resetting votes`,\r\n\t\t],\r\n\r\n\t\tvl: 'votelock',\r\n\t\tvotelock(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (this.meansYes(action)) {\r\n\t\t\t\tgame.setVotelock(user, true);\r\n\t\t\t} else if (this.meansNo(action)) {\r\n\t\t\t\tgame.setVotelock(user, false);\r\n\t\t\t} else {\r\n\t\t\t\treturn this.parse('/help mafia votelock');\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed votelock status`);\r\n\t\t},\r\n\t\tvotelockhelp: [\r\n\t\t\t`/mafia votelock [on|off] - Allows or disallows players to change their vote. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tvoting: 'votesall',\r\n\t\tvotesall(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tconst action = toID(target);\r\n\t\t\tif (this.meansYes(action)) {\r\n\t\t\t\tgame.setVoting(user, true);\r\n\t\t\t} else if (this.meansNo(action)) {\r\n\t\t\t\tgame.setVoting(user, false);\r\n\t\t\t} else {\r\n\t\t\t\treturn this.parse('/help mafia voting');\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed voting status`);\r\n\t\t},\r\n\t\tvotinghelp: [\r\n\t\t\t`/mafia voting [on|off] - Allows or disallows players to vote. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tenablenv: 'enablenl',\r\n\t\tdisablenv: 'enablenl',\r\n\t\tdisablenl: 'enablenl',\r\n\t\tenablenl(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (cmd === 'enablenl' || cmd === 'enablenv') {\r\n\t\t\t\tgame.setNoVote(user, true);\r\n\t\t\t} else {\r\n\t\t\t\tgame.setNoVote(user, false);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed novote status`);\r\n\t\t},\r\n\t\tenablenlhelp: [\r\n\t\t\t`/mafia [enablenv|disablenv] - Allows or disallows players abstain from voting. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tforcevote(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\ttarget = toID(target);\r\n\t\t\tif (this.meansYes(target)) {\r\n\t\t\t\tif (game.forceVote) return this.errorReply(`Forcevoting is already enabled.`);\r\n\t\t\t\tgame.forceVote = true;\r\n\t\t\t\tif (game.started) game.resetHammer();\r\n\t\t\t\tgame.sendDeclare(`Forcevoting has been enabled. Your vote will start on yourself, and you cannot unvote!`);\r\n\t\t\t} else if (this.meansNo(target)) {\r\n\t\t\t\tif (!game.forceVote) return this.errorReply(`Forcevoting is already disabled.`);\r\n\t\t\t\tgame.forceVote = false;\r\n\t\t\t\tgame.sendDeclare(`Forcevoting has been disabled. You can vote normally now!`);\r\n\t\t\t} else {\r\n\t\t\t\tthis.parse('/help mafia forcevote');\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed forcevote status`);\r\n\t\t},\r\n\t\tforcevotehelp: [\r\n\t\t\t`/mafia forcevote [yes/no] - Forces players' votes onto themselves, and prevents unvoting. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tvotes(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (!game.started) return this.errorReply(`The game of mafia has not started yet.`);\r\n\r\n\t\t\t// hack to let hosts broadcast\r\n\t\t\tif (game.hostid === user.id || game.cohostids.includes(user.id)) {\r\n\t\t\t\tthis.broadcastMessage = this.message.toLowerCase().replace(/[^a-z0-9\\s!,]/g, '');\r\n\t\t\t}\r\n\t\t\tif (!this.runBroadcast()) return false;\r\n\r\n\t\t\tthis.sendReplyBox(game.voteBox());\r\n\t\t},\r\n\r\n\t\tpl: 'players',\r\n\t\tplayers(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\r\n\t\t\t// hack to let hosts broadcast\r\n\t\t\tif (game.hostid === user.id || game.cohostids.includes(user.id)) {\r\n\t\t\t\tthis.broadcastMessage = this.message.toLowerCase().replace(/[^a-z0-9\\s!,]/g, '');\r\n\t\t\t}\r\n\t\t\tif (!this.runBroadcast()) return false;\r\n\r\n\t\t\tif (this.broadcasting) {\r\n\t\t\t\tgame.sendPlayerList();\r\n\t\t\t} else {\r\n\t\t\t\tthis.sendReplyBox(`Players (${game.playerCount}): ${Object.values(game.playerTable).map(p => p.safeName).sort().join(', ')}`);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\toriginalrolelist: 'rolelist',\r\n\t\torl: 'rolelist',\r\n\t\trl: 'rolelist',\r\n\t\trolelist(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.closedSetup) return this.errorReply(`You cannot show roles in a closed setup.`);\r\n\t\t\tif (!this.runBroadcast()) return false;\r\n\t\t\tif (game.IDEA.data) {\r\n\t\t\t\tconst buf = `
IDEA roles:${game.IDEA.data.roles.join(`
`)}
`;\r\n\t\t\t\treturn this.sendReplyBox(buf);\r\n\t\t\t}\r\n\t\t\tconst showOrl = (['orl', 'originalrolelist'].includes(cmd) || game.noReveal);\r\n\t\t\tconst roleString = Utils.sortBy((showOrl ? game.originalRoles : game.roles), role => (\r\n\t\t\t\trole.alignment\r\n\t\t\t)).map(role => role.safeName).join(', ');\r\n\r\n\t\t\tthis.sendReplyBox(`${showOrl ? `Original Rolelist: ` : `Rolelist: `}${roleString}`);\r\n\t\t},\r\n\r\n\t\tplayerroles(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) {\r\n\t\t\t\treturn this.errorReply(`Only the host can view roles.`);\r\n\t\t\t}\r\n\t\t\tif (!game.started) return this.errorReply(`The game has not started.`);\r\n\t\t\tconst players = [...Object.values(game.playerTable), ...Object.values(game.dead)];\r\n\t\t\tthis.sendReplyBox(players.map(\r\n\t\t\t\tp => `${p.safeName}: ${p.role ? (p.role.alignment === 'solo' ? 'Solo ' : '') + p.role.safeName : 'No role'}`\r\n\t\t\t).join('
'));\r\n\t\t},\r\n\r\n\t\tspectate: 'view',\r\n\t\tview(target, room, user, connection) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.requireGame(Mafia);\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tif (this.broadcasting) {\r\n\t\t\t\treturn this.sendReplyBox(``);\r\n\t\t\t}\r\n\t\t\treturn this.parse(`/join view-mafia-${room.roomid}`);\r\n\t\t},\r\n\r\n\t\trefreshvotes(target, room, user, connection) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tconst votes = game.voteBoxFor(user.id);\r\n\t\t\tuser.send(`>view-mafia-${game.room.roomid}\\n|selectorhtml|#mafia-votes|` + votes);\r\n\t\t},\r\n\t\tforcesub: 'sub',\r\n\t\tsub(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tconst args = target.split(',');\r\n\t\t\tconst action = toID(args.shift());\r\n\t\t\tswitch (action) {\r\n\t\t\tcase 'in':\r\n\t\t\t\tif (user.id in game.playerTable) {\r\n\t\t\t\t\t// Check if they have requested to be subbed out.\r\n\t\t\t\t\tif (!game.requestedSub.includes(user.id)) {\r\n\t\t\t\t\t\treturn this.errorReply(`You have not requested to be subbed out.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tgame.requestedSub.splice(game.requestedSub.indexOf(user.id), 1);\r\n\t\t\t\t\tthis.errorReply(`You have cancelled your request to sub out.`);\r\n\t\t\t\t\tgame.playerTable[user.id].updateHtmlRoom();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.checkChat(null, room);\r\n\t\t\t\t\tif (game.subs.includes(user.id)) return this.errorReply(`You are already on the sub list.`);\r\n\t\t\t\t\tif (game.played.includes(user.id)) return this.errorReply(`You cannot sub back into the game.`);\r\n\t\t\t\t\t// Change this to game.canJoin(user, true, true) if you're trying to test something sub related locally.\r\n\t\t\t\t\tgame.canJoin(user, true);\r\n\t\t\t\t\tgame.subs.push(user.id);\r\n\t\t\t\t\tgame.nextSub();\r\n\t\t\t\t\t// Update spectator's view\r\n\t\t\t\t\tthis.parse(`/join view-mafia-${room.roomid}`);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'out':\r\n\t\t\t\tif (user.id in game.playerTable) {\r\n\t\t\t\t\tif (game.requestedSub.includes(user.id)) {\r\n\t\t\t\t\t\treturn this.errorReply(`You have already requested to be subbed out.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tgame.requestedSub.push(user.id);\r\n\t\t\t\t\tgame.playerTable[user.id].updateHtmlRoom();\r\n\t\t\t\t\tgame.nextSub();\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (game.hostid === user.id || game.cohostids.includes(user.id)) {\r\n\t\t\t\t\t\treturn this.errorReply(`The host cannot sub out of the game.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!game.subs.includes(user.id)) return this.errorReply(`You are not on the sub list.`);\r\n\t\t\t\t\tgame.subs.splice(game.subs.indexOf(user.id), 1);\r\n\t\t\t\t\t// Update spectator's view\r\n\t\t\t\t\tthis.parse(`/join view-mafia-${room.roomid}`);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'next':\r\n\t\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\t\tconst toSub = args.shift();\r\n\t\t\t\tif (!(toID(toSub) in game.playerTable)) return this.errorReply(`${toSub} is not in the game.`);\r\n\t\t\t\tif (!game.subs.length) {\r\n\t\t\t\t\tif (game.hostRequestedSub.includes(toID(toSub))) {\r\n\t\t\t\t\t\treturn this.errorReply(`${toSub} is already on the list to be subbed out.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tuser.sendTo(\r\n\t\t\t\t\t\troom,\r\n\t\t\t\t\t\t`|error|There are no subs to replace ${toSub}, they will be subbed if a sub is available before they speak next.`\r\n\t\t\t\t\t);\r\n\t\t\t\t\tgame.hostRequestedSub.unshift(toID(toSub));\r\n\t\t\t\t} else {\r\n\t\t\t\t\tgame.nextSub(toID(toSub));\r\n\t\t\t\t}\r\n\t\t\t\tgame.logAction(user, `requested a sub for a player`);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'remove':\r\n\t\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\t\tfor (const toRemove of args) {\r\n\t\t\t\t\tconst toRemoveIndex = game.subs.indexOf(toID(toRemove));\r\n\t\t\t\t\tif (toRemoveIndex === -1) {\r\n\t\t\t\t\t\tuser.sendTo(room, `|error|${toRemove} is not on the sub list.`);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tgame.subs.splice(toRemoveIndex, 1);\r\n\t\t\t\t\tuser.sendTo(room, `${toRemove} has been removed from the sublist`);\r\n\t\t\t\t\tgame.logAction(user, `removed a player from the sublist`);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'unrequest':\r\n\t\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\t\tconst toUnrequest = toID(args.shift());\r\n\t\t\t\tconst userIndex = game.requestedSub.indexOf(toUnrequest);\r\n\t\t\t\tconst hostIndex = game.hostRequestedSub.indexOf(toUnrequest);\r\n\t\t\t\tif (userIndex < 0 && hostIndex < 0) return user.sendTo(room, `|error|${toUnrequest} is not requesting a sub.`);\r\n\t\t\t\tif (userIndex > -1) {\r\n\t\t\t\t\tgame.requestedSub.splice(userIndex, 1);\r\n\t\t\t\t\tuser.sendTo(room, `${toUnrequest}'s sub request has been removed.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (hostIndex > -1) {\r\n\t\t\t\t\tgame.hostRequestedSub.splice(userIndex, 1);\r\n\t\t\t\t\tuser.sendTo(room, `${toUnrequest} has been removed from the host sublist.`);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\t\tconst toSubOut = action;\r\n\t\t\t\tconst toSubIn = toID(args.shift());\r\n\t\t\t\tif (!(toSubOut in game.playerTable)) return this.errorReply(`${toSubOut} is not in the game.`);\r\n\r\n\t\t\t\tconst targetUser = Users.get(toSubIn);\r\n\t\t\t\tif (!targetUser) return this.errorReply(`The user \"${toSubIn}\" was not found.`);\r\n\t\t\t\tgame.canJoin(targetUser, false, cmd === 'forcesub');\r\n\t\t\t\tif (game.subs.includes(targetUser.id)) {\r\n\t\t\t\t\tgame.subs.splice(game.subs.indexOf(targetUser.id), 1);\r\n\t\t\t\t}\r\n\t\t\t\tif (game.hostRequestedSub.includes(toSubOut)) {\r\n\t\t\t\t\tgame.hostRequestedSub.splice(game.hostRequestedSub.indexOf(toSubOut), 1);\r\n\t\t\t\t}\r\n\t\t\t\tif (game.requestedSub.includes(toSubOut)) {\r\n\t\t\t\t\tgame.requestedSub.splice(game.requestedSub.indexOf(toSubOut), 1);\r\n\t\t\t\t}\r\n\t\t\t\tgame.sub(toSubOut, toSubIn);\r\n\t\t\t\tgame.logAction(user, `substituted a player`);\r\n\t\t\t}\r\n\t\t},\r\n\t\tsubhelp: [\r\n\t\t\t`/mafia sub in - Request to sub into the game, or cancel a request to sub out.`,\r\n\t\t\t`/mafia sub out - Request to sub out of the game, or cancel a request to sub in.`,\r\n\t\t\t`/mafia sub next, [player] - Forcibly sub [player] out of the game. Requires host % @ # &`,\r\n\t\t\t`/mafia sub remove, [user] - Remove [user] from the sublist. Requres host % @ # &`,\r\n\t\t\t`/mafia sub unrequest, [player] - Remove's a player's request to sub out of the game. Requires host % @ # &`,\r\n\t\t\t`/mafia sub [player], [user] - Forcibly sub [player] for [user]. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tautosub(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('mute', null, room);\r\n\t\t\tif (this.meansYes(toID(target))) {\r\n\t\t\t\tif (game.autoSub) return this.errorReply(`Automatic subbing of players is already enabled.`);\r\n\t\t\t\tgame.autoSub = true;\r\n\t\t\t\tuser.sendTo(room, `Automatic subbing of players has been enabled.`);\r\n\t\t\t\tgame.nextSub();\r\n\t\t\t} else if (this.meansNo(toID(target))) {\r\n\t\t\t\tif (!game.autoSub) return this.errorReply(`Automatic subbing of players is already disabled.`);\r\n\t\t\t\tgame.autoSub = false;\r\n\t\t\t\tuser.sendTo(room, `Automatic subbing of players has been disabled.`);\r\n\t\t\t} else {\r\n\t\t\t\treturn this.parse(`/help mafia autosub`);\r\n\t\t\t}\r\n\t\t\tgame.logAction(user, `changed autosub status`);\r\n\t\t},\r\n\t\tautosubhelp: [\r\n\t\t\t`/mafia autosub [yes|no] - Sets if players will automatically sub out if a user is on the sublist. Requires host % @ # &`,\r\n\t\t],\r\n\r\n\t\tcohost: 'subhost',\r\n\t\tforcecohost: 'subhost',\r\n\t\tforcesubhost: 'subhost',\r\n\t\tsubhost(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkChat();\r\n\t\t\tif (!target) return this.parse(`/help mafia ${cmd}`);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst {targetUser} = this.requireUser(target);\r\n\t\t\tif (!room.users[targetUser.id]) return this.errorReply(`${targetUser.name} is not in this room, and cannot be hosted.`);\r\n\t\t\tif (game.hostid === targetUser.id) return this.errorReply(`${targetUser.name} is already the host.`);\r\n\t\t\tif (game.cohostids.includes(targetUser.id)) return this.errorReply(`${targetUser.name} is already a cohost.`);\r\n\t\t\tif (targetUser.id in game.playerTable) return this.errorReply(`The host cannot be ingame.`);\r\n\t\t\tif (targetUser.id in game.dead) {\r\n\t\t\t\tif (!cmd.includes('force')) {\r\n\t\t\t\t\treturn this.errorReply(`${targetUser.name} could potentially be revived. To continue anyway, use /mafia force${cmd} ${target}.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (game.dead[targetUser.id].voting) game.unvote(targetUser.id);\r\n\t\t\t\tgame.dead[targetUser.id].destroy();\r\n\t\t\t\tdelete game.dead[targetUser.id];\r\n\t\t\t}\r\n\t\t\tif (game.subs.includes(targetUser.id)) game.subs.splice(game.subs.indexOf(targetUser.id), 1);\r\n\t\t\tif (cmd.includes('cohost')) {\r\n\t\t\t\tgame.cohostids.push(targetUser.id);\r\n\t\t\t\tgame.cohosts.push(Utils.escapeHTML(targetUser.name));\r\n\t\t\t\tgame.sendDeclare(Utils.html`${targetUser.name} has been added as a cohost by ${user.name}`);\r\n\t\t\t\tfor (const conn of targetUser.connections) {\r\n\t\t\t\t\tvoid Chat.resolvePage(`view-mafia-${room.roomid}`, targetUser, conn);\r\n\t\t\t\t}\r\n\t\t\t\tthis.modlog('MAFIACOHOST', targetUser, null, {noalts: true, noip: true});\r\n\t\t\t} else {\r\n\t\t\t\tconst oldHostid = game.hostid;\r\n\t\t\t\tconst oldHost = Users.get(game.hostid);\r\n\t\t\t\tif (oldHost) oldHost.send(`>view-mafia-${room.roomid}\\n|deinit`);\r\n\t\t\t\tconst queueIndex = hostQueue.indexOf(targetUser.id);\r\n\t\t\t\tif (queueIndex > -1) hostQueue.splice(queueIndex, 1);\r\n\t\t\t\tgame.host = Utils.escapeHTML(targetUser.name);\r\n\t\t\t\tgame.hostid = targetUser.id;\r\n\t\t\t\tgame.played.push(targetUser.id);\r\n\t\t\t\tfor (const conn of targetUser.connections) {\r\n\t\t\t\t\tvoid Chat.resolvePage(`view-mafia-${room.roomid}`, targetUser, conn);\r\n\t\t\t\t}\r\n\t\t\t\tgame.sendDeclare(Utils.html`${targetUser.name} has been substituted as the new host, replacing ${oldHostid}.`);\r\n\t\t\t\tthis.modlog('MAFIASUBHOST', targetUser, `replacing ${oldHostid}`, {noalts: true, noip: true});\r\n\t\t\t}\r\n\t\t},\r\n\t\tsubhosthelp: [`/mafia subhost [user] - Substitues the user as the new game host.`],\r\n\t\tcohosthelp: [\r\n\t\t\t`/mafia cohost [user] - Adds the user as a cohost. Cohosts can talk during the game, as well as perform host actions.`,\r\n\t\t],\r\n\r\n\t\tuncohost: 'removecohost',\r\n\t\tremovecohost(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tthis.checkChat();\r\n\t\t\tif (!target) return this.parse('/help mafia subhost');\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst targetID = toID(target);\r\n\r\n\t\t\tconst cohostIndex = game.cohostids.indexOf(targetID);\r\n\t\t\tif (cohostIndex < 0) {\r\n\t\t\t\tif (game.hostid === targetID) {\r\n\t\t\t\t\treturn this.errorReply(`${target} is the host, not a cohost. Use /mafia subhost to replace them.`);\r\n\t\t\t\t}\r\n\t\t\t\treturn this.errorReply(`${target} is not a cohost.`);\r\n\t\t\t}\r\n\t\t\tgame.cohostids.splice(cohostIndex, 1);\r\n\t\t\tgame.sendDeclare(Utils.html`${target} was removed as a cohost by ${user.name}`);\r\n\t\t\tthis.modlog('MAFIAUNCOHOST', target, null, {noalts: true, noip: true});\r\n\t\t},\r\n\r\n\t\tend(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\tif (game.hostid !== user.id && !game.cohostids.includes(user.id)) this.checkCan('show', null, room);\r\n\t\t\tgame.end();\r\n\t\t\tthis.modlog('MAFIAEND', null);\r\n\t\t},\r\n\t\tendhelp: [`/mafia end - End the current game of mafia. Requires host + % @ # &`],\r\n\r\n\t\trole: 'data',\r\n\t\talignment: 'data',\r\n\t\ttheme: 'data',\r\n\t\tterm: 'data',\r\n\t\tdt: 'data',\r\n\t\tdata(target, room, user, connection, cmd) {\r\n\t\t\tif (room?.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tif (cmd === 'role' && !target && room) {\r\n\t\t\t\t// Support /mafia role showing your current role if you're in a game\r\n\t\t\t\tconst game = room.getGame(Mafia);\r\n\t\t\t\tif (!game) {\r\n\t\t\t\t\treturn this.errorReply(`There is no game of mafia running in this room. If you meant to display information about a role, use /mafia role [role name]`);\r\n\t\t\t\t}\r\n\t\t\t\tif (!(user.id in game.playerTable)) return this.errorReply(`You are not in the game of ${game.title}.`);\r\n\t\t\t\tconst role = game.playerTable[user.id].role;\r\n\t\t\t\tif (!role) return this.errorReply(`You do not have a role yet.`);\r\n\t\t\t\treturn this.sendReplyBox(`Your role is: ${role.safeName}`);\r\n\t\t\t}\r\n\r\n\t\t\t// hack to let hosts broadcast\r\n\t\t\tconst game = room?.getGame(Mafia);\r\n\t\t\tif (game && (game.hostid === user.id || game.cohostids.includes(user.id))) {\r\n\t\t\t\tthis.broadcastMessage = this.message.toLowerCase().replace(/[^a-z0-9\\s!,]/g, '');\r\n\t\t\t}\r\n\t\t\tif (!this.runBroadcast()) return false;\r\n\r\n\t\t\tif (!target) return this.parse(`/help mafia data`);\r\n\r\n\t\t\ttarget = toID(target);\r\n\t\t\tif (target in MafiaData.aliases) target = MafiaData.aliases[target];\r\n\r\n\t\t\tlet result: MafiaDataAlignment | MafiaDataRole | MafiaDataTheme | MafiaDataIDEA | MafiaDataTerm | null = null;\r\n\t\t\tlet dataType = cmd;\r\n\r\n\t\t\tconst cmdTypes: {[k: string]: keyof MafiaData} = {\r\n\t\t\t\trole: 'roles', alignment: 'alignments', theme: 'themes', term: 'terms', idea: 'IDEAs',\r\n\t\t\t};\r\n\r\n\t\t\tif (cmd in cmdTypes) {\r\n\t\t\t\tconst toSearch = MafiaData[cmdTypes[cmd]];\r\n\t\t\t\t// @ts-ignore guaranteed not an alias\r\n\t\t\t\tresult = toSearch[target];\r\n\t\t\t} else {\r\n\t\t\t\t// search everything\r\n\t\t\t\tfor (const [cmdType, dataKey] of Object.entries(cmdTypes)) {\r\n\t\t\t\t\tif (target in MafiaData[dataKey]) {\r\n\t\t\t\t\t\t// @ts-ignore guaranteed not an alias\r\n\t\t\t\t\t\tresult = MafiaData[dataKey][target];\r\n\t\t\t\t\t\tdataType = cmdType;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!result) return this.errorReply(`\"${target}\" is not a valid mafia alignment, role, theme, or IDEA.`);\r\n\r\n\t\t\t// @ts-ignore\r\n\t\t\tlet buf = `${result.name}Type: ${dataType}
`;\r\n\t\t\tif (dataType === 'theme') {\r\n\t\t\t\tif ((result as MafiaDataTheme).desc) {\r\n\t\t\t\t\tbuf += `Description: ${(result as MafiaDataTheme).desc}
Setups:`;\r\n\t\t\t\t}\r\n\t\t\t\tfor (const i in result) {\r\n\t\t\t\t\tconst num = parseInt(i);\r\n\t\t\t\t\tif (isNaN(num)) continue;\r\n\t\t\t\t\tbuf += `${i}: `;\r\n\t\t\t\t\tconst count: {[k: string]: number} = {};\r\n\t\t\t\t\tconst roles = [];\r\n\t\t\t\t\tfor (const role of (result as MafiaDataTheme)[num].split(',').map((x: string) => x.trim())) {\r\n\t\t\t\t\t\tcount[role] = count[role] ? count[role] + 1 : 1;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tfor (const role in count) {\r\n\t\t\t\t\t\troles.push(count[role] > 1 ? `${count[role]}x ${role}` : role);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbuf += `${roles.join(', ')}
`;\r\n\t\t\t\t}\r\n\t\t\t} else if (dataType === 'idea') {\r\n\t\t\t\tif ((result as MafiaDataIDEA).picks && (result as MafiaDataIDEA).choices) {\r\n\t\t\t\t\tbuf += `Number of Picks: ${(result as MafiaDataIDEA).picks.length} (${(result as MafiaDataIDEA).picks.join(', ')})
`;\r\n\t\t\t\t\tbuf += `Number of Choices: ${(result as MafiaDataIDEA).choices}
`;\r\n\t\t\t\t}\r\n\t\t\t\tbuf += `
Roles:`;\r\n\t\t\t\tfor (const idearole of (result as MafiaDataIDEA).roles) {\r\n\t\t\t\t\tbuf += `${idearole}
`;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// @ts-ignore\r\n\t\t\t\tif (result.memo) buf += `${result.memo.join('
')}`;\r\n\t\t\t}\r\n\t\t\treturn this.sendReplyBox(buf);\r\n\t\t},\r\n\t\tdatahelp: [\r\n\t\t\t`/mafia data [alignment|role|modifier|theme|term] - Get information on a mafia alignment, role, modifier, theme, or term.`,\r\n\t\t],\r\n\r\n\t\twinfaction: 'win',\r\n\t\tunwinfaction: 'win',\r\n\t\tunwin: 'win',\r\n\t\twin(target, room, user, connection, cmd) {\r\n\t\t\tconst isUnwin = cmd.startsWith('unwin');\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tif (!room || room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst args = target.split(',');\r\n\t\t\tlet points = parseInt(args[0]);\r\n\t\t\tif (isUnwin) {\r\n\t\t\t\tpoints *= -1;\r\n\t\t\t}\r\n\t\t\tif (isNaN(points)) {\r\n\t\t\t\tpoints = 10;\r\n\t\t\t\tif (isUnwin) {\r\n\t\t\t\t\tpoints *= -1;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (points > 100 || points < -100) {\r\n\t\t\t\t\treturn this.errorReply(`You cannot give or take more than 100 points at a time.`);\r\n\t\t\t\t}\r\n\t\t\t\t// shift out the point count\r\n\t\t\t\targs.shift();\r\n\t\t\t}\r\n\t\t\tif (!args.length) return this.parse('/help mafia win');\r\n\t\t\tconst month = new Date().toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\t\t\tif (!logs.leaderboard[month]) logs.leaderboard[month] = {};\r\n\r\n\t\t\tlet toGiveTo = [];\r\n\t\t\tlet buf = `${points < 0 ? points * -1 : points} point${Chat.plural(points, 's were', ' was')} ${points <= 0 ? 'taken from ' : 'awarded to '} `;\r\n\t\t\tif (cmd === 'winfaction' || cmd === 'unwinfaction') {\r\n\t\t\t\tconst game = this.requireGame(Mafia);\r\n\t\t\t\tfor (let faction of args) {\r\n\t\t\t\t\tfaction = toID(faction);\r\n\t\t\t\t\tconst inFaction = [];\r\n\t\t\t\t\tfor (const player of [...Object.values(game.playerTable), ...Object.values(game.dead)]) {\r\n\t\t\t\t\t\tif (player.role && toID(player.role.alignment) === faction) {\r\n\t\t\t\t\t\t\ttoGiveTo.push(player.id);\r\n\t\t\t\t\t\t\tinFaction.push(player.id);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (inFaction.length) buf += ` the ${faction} faction: ${inFaction.join(', ')};`;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\ttoGiveTo = args;\r\n\t\t\t\tbuf += toGiveTo.join(', ');\r\n\t\t\t}\r\n\t\t\tif (!toGiveTo.length) return this.parse('/help mafia win');\r\n\t\t\tlet gavePoints = false;\r\n\t\t\tfor (let u of toGiveTo) {\r\n\t\t\t\tu = toID(u);\r\n\t\t\t\tif (!u) continue;\r\n\t\t\t\tif (!gavePoints) gavePoints = true;\r\n\t\t\t\tif (!logs.leaderboard[month][u]) logs.leaderboard[month][u] = 0;\r\n\t\t\t\tlogs.leaderboard[month][u] += points;\r\n\t\t\t\tif (logs.leaderboard[month][u] === 0) delete logs.leaderboard[month][u];\r\n\t\t\t}\r\n\t\t\tif (!gavePoints) return this.parse('/help mafia win');\r\n\t\t\twriteFile(LOGS_FILE, logs);\r\n\t\t\tthis.modlog(`MAFIAPOINTS`, null, `${points < 0 ? points * -1 : points} points were ${points < 0 ? 'taken from' : 'awarded to'} ${Chat.toListString(toGiveTo)}`);\r\n\t\t\troom.add(buf).update();\r\n\t\t},\r\n\t\twinhelp: [\r\n\t\t\t`/mafia (un)win (points), [user1], [user2], [user3], ... - Award the specified users points to the mafia leaderboard for this month. The amount of points can be negative to take points. Defaults to 10 points.`,\r\n\t\t\t`/mafia (un)winfaction (points), [faction] - Award the specified points to all the players in the given faction.`,\r\n\t\t],\r\n\r\n\t\tunmvp: 'mvp',\r\n\t\tmvp(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tif (!room || room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst args = target.split(',');\r\n\t\t\tif (!args.length) return this.parse('/help mafia mvp');\r\n\t\t\tconst month = new Date().toLocaleString(\"en-us\", {month: \"numeric\", year: \"numeric\"});\r\n\t\t\tif (!logs.mvps[month]) logs.mvps[month] = {};\r\n\t\t\tif (!logs.leaderboard[month]) logs.leaderboard[month] = {};\r\n\t\t\tlet gavePoints = false;\r\n\t\t\tfor (let u of args) {\r\n\t\t\t\tu = toID(u);\r\n\t\t\t\tif (!u) continue;\r\n\t\t\t\tif (!gavePoints) gavePoints = true;\r\n\t\t\t\tif (!logs.leaderboard[month][u]) logs.leaderboard[month][u] = 0;\r\n\t\t\t\tif (!logs.mvps[month][u]) logs.mvps[month][u] = 0;\r\n\t\t\t\tif (cmd === 'unmvp') {\r\n\t\t\t\t\tlogs.mvps[month][u]--;\r\n\t\t\t\t\tlogs.leaderboard[month][u] -= 10;\r\n\t\t\t\t\tif (logs.mvps[month][u] === 0) delete logs.mvps[month][u];\r\n\t\t\t\t\tif (logs.leaderboard[month][u] === 0) delete logs.leaderboard[month][u];\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlogs.mvps[month][u]++;\r\n\t\t\t\t\tlogs.leaderboard[month][u] += 10;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!gavePoints) return this.parse('/help mafia mvp');\r\n\t\t\twriteFile(LOGS_FILE, logs);\r\n\t\t\tthis.modlog(`MAFIA${cmd.toUpperCase()}`, null, `MVP and 10 points were ${cmd === 'unmvp' ? 'taken from' : 'awarded to'} ${Chat.toListString(args)}`);\r\n\t\t\troom.add(`MVP and 10 points were ${cmd === 'unmvp' ? 'taken from' : 'awarded to'}: ${Chat.toListString(args)}`).update();\r\n\t\t},\r\n\t\tmvphelp: [\r\n\t\t\t`/mafia mvp [user1], [user2], ... - Gives a MVP point and 10 leaderboard points to the users specified.`,\r\n\t\t\t`/mafia unmvp [user1], [user2], ... - Takes away a MVP point and 10 leaderboard points from the users specified.`,\r\n\t\t],\r\n\r\n\t\thostlogs: 'leaderboard',\r\n\t\tplaylogs: 'leaderboard',\r\n\t\tleaverlogs: 'leaderboard',\r\n\t\tmvpladder: 'leaderboard',\r\n\t\tlb: 'leaderboard',\r\n\t\tleaderboard(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tif (!room || room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`);\r\n\t\t\tif (['hostlogs', 'playlogs', 'leaverlogs'].includes(cmd)) {\r\n\t\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\t} else {\r\n\t\t\t\t// Deny broadcasting host/playlogs\r\n\t\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\t}\r\n\t\t\tif (cmd === 'lb') cmd = 'leaderboard';\r\n\t\t\tif (this.broadcasting) {\r\n\t\t\t\treturn this.sendReplyBox(``);\r\n\t\t\t}\r\n\t\t\treturn this.parse(`/join view-mafialadder-${cmd}`);\r\n\t\t},\r\n\t\tleaderboardhelp: [\r\n\t\t\t`/mafia [leaderboard|mvpladder] - View the leaderboard or MVP ladder for the current or last month.`,\r\n\t\t\t`/mafia [hostlogs|playlogs|leaverlogs] - View the host, play, or leaver logs for the current or last month. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\tgameban: 'hostban',\r\n\t\thostban(target, room, user, connection, cmd) {\r\n\t\t\tif (!target) return this.parse('/help mafia hostban');\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('warn', null, room);\r\n\r\n\t\t\tconst {targetUser, rest} = this.requireUser(target);\r\n\t\t\tconst [string1, string2] = this.splitOne(rest);\r\n\t\t\tlet duration, reason;\r\n\t\t\tif (parseInt(string1)) {\r\n\t\t\t\tduration = parseInt(string1);\r\n\t\t\t\treason = string2;\r\n\t\t\t} else {\r\n\t\t\t\tduration = parseInt(string2);\r\n\t\t\t\treason = string1;\r\n\t\t\t}\r\n\r\n\t\t\tif (!duration) duration = 2;\r\n\t\t\tif (!reason) reason = '';\r\n\t\t\tif (reason.length > 300) {\r\n\t\t\t\treturn this.errorReply(\"The reason is too long. It cannot exceed 300 characters.\");\r\n\t\t\t}\r\n\r\n\t\t\tconst userid = toID(targetUser);\r\n\t\t\tif (Punishments.hasRoomPunishType(room, userid, `MAFIA${this.cmd.toUpperCase()}`)) {\r\n\t\t\t\treturn this.errorReply(`User '${targetUser.name}' is already ${this.cmd}ned in this room.`);\r\n\t\t\t} else if (Punishments.hasRoomPunishType(room, userid, `MAFIAGAMEBAN`)) {\r\n\t\t\t\treturn this.errorReply(`User '${targetUser.name}' is already gamebanned in this room, which also means they can't host.`);\r\n\t\t\t} else if (Punishments.hasRoomPunishType(room, userid, `MAFIAHOSTBAN`)) {\r\n\t\t\t\tuser.sendTo(room, `User '${targetUser.name}' is already hostbanned in this room, but they will now be gamebanned.`);\r\n\t\t\t\tthis.parse(`/mafia unhostban ${targetUser.name}`);\r\n\t\t\t}\r\n\r\n\t\t\tif (cmd === 'hostban') {\r\n\t\t\t\tMafia.hostBan(room, targetUser, reason, duration);\r\n\t\t\t} else {\r\n\t\t\t\tMafia.gameBan(room, targetUser, reason, duration);\r\n\t\t\t}\r\n\r\n\t\t\tthis.modlog(`MAFIA${cmd.toUpperCase()}`, targetUser, reason);\r\n\t\t\tthis.privateModAction(`${targetUser.name} was banned from ${cmd === 'hostban' ? 'hosting' : 'playing'} mafia games by ${user.name}.`);\r\n\t\t},\r\n\t\thostbanhelp: [\r\n\t\t\t`/mafia (un)hostban [user], [reason], [duration] - Ban a user from hosting games for [duration] days. Requires % @ # &`,\r\n\t\t\t`/mafia (un)gameban [user], [reason], [duration] - Ban a user from playing games for [duration] days. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\tban: 'gamebanhelp',\r\n\t\tbanhelp: 'gamebanhelp',\r\n\t\tgamebanhelp() {\r\n\t\t\tthis.parse('/mafia hostbanhelp');\r\n\t\t},\r\n\r\n\t\tungameban: 'unhostban',\r\n\t\tunhostban(target, room, user, connection, cmd) {\r\n\t\t\tif (!target) return this.parse('/help mafia hostban');\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('warn', null, room);\r\n\r\n\t\t\tconst {targetUser} = this.requireUser(target, {allowOffline: true});\r\n\t\t\tif (!Mafia.isGameBanned(room, targetUser) && cmd === 'ungameban') {\r\n\t\t\t\treturn this.errorReply(`User '${targetUser.name}' isn't banned from playing mafia games.`);\r\n\t\t\t} else if (!Mafia.isHostBanned(room, targetUser) && cmd === 'unhostban') {\r\n\t\t\t\treturn this.errorReply(`User '${targetUser.name}' isn't banned from hosting mafia games.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (cmd === 'unhostban') Mafia.unhostBan(room, targetUser);\r\n\t\t\telse Mafia.ungameBan(room, targetUser);\r\n\r\n\t\t\tthis.privateModAction(`${targetUser.name} was unbanned from ${cmd === 'unhostban' ? 'hosting' : 'playing'} mafia games by ${user.name}.`);\r\n\t\t\tthis.modlog(`MAFIA${cmd.toUpperCase()}`, targetUser, null, {noip: 1, noalts: 1});\r\n\t\t},\r\n\r\n\t\toverwriterole: 'addrole',\r\n\t\taddrole(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst overwrite = cmd === 'overwriterole';\r\n\r\n\t\t\tconst [name, alignment, image, ...memo] = target.split('|').map(e => e.trim());\r\n\t\t\tconst id = toID(name);\r\n\r\n\t\t\tif (!id || !memo.length) return this.parse(`/help mafia addrole`);\r\n\r\n\t\t\tif (alignment && !(alignment in MafiaData.alignments)) return this.errorReply(`${alignment} is not a valid alignment.`);\r\n\t\t\tif (image && !VALID_IMAGES.includes(image)) return this.errorReply(`${image} is not a valid image.`);\r\n\r\n\t\t\tif (!overwrite && id in MafiaData.roles) {\r\n\t\t\t\treturn this.errorReply(`${name} is already a role. Use /mafia overwriterole to overwrite.`);\r\n\t\t\t}\r\n\t\t\tif (id in MafiaData.alignments) return this.errorReply(`${name} is already an alignment.`);\r\n\t\t\tif (id in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alias (pointing to ${MafiaData.aliases[id]}).`);\r\n\t\t\t}\r\n\r\n\t\t\tconst role: MafiaDataRole = {name, memo};\r\n\t\t\tif (alignment) role.alignment = alignment;\r\n\t\t\tif (image) role.image = image;\r\n\r\n\t\t\tMafiaData.roles[id] = role;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDROLE`, null, id, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The role ${id} was added to the database.`);\r\n\t\t},\r\n\t\taddrolehelp: [\r\n\t\t\t`/mafia addrole name|alignment|image|memo1|memo2... - adds a role to the database. Name, memo are required. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\toverwritealignment: 'addalignment',\r\n\t\taddalignment(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst overwrite = cmd === 'overwritealignment';\r\n\r\n\t\t\tconst [name, plural, color, buttonColor, image, ...memo] = target.split('|').map(e => e.trim());\r\n\t\t\tconst id = toID(name);\r\n\r\n\t\t\tif (!id || !plural || !memo.length) return this.parse(`/help mafia addalignment`);\r\n\r\n\t\t\tif (image && !VALID_IMAGES.includes(image)) return this.errorReply(`${image} is not a valid image.`);\r\n\r\n\t\t\tif (!overwrite && id in MafiaData.alignments) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alignment. Use /mafia overwritealignment to overwrite.`);\r\n\t\t\t}\r\n\t\t\tif (id in MafiaData.roles) return this.errorReply(`${name} is already a role.`);\r\n\t\t\tif (id in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alias (pointing to ${MafiaData.aliases[id]})`);\r\n\t\t\t}\r\n\r\n\t\t\tconst alignment: MafiaDataAlignment = {name, plural, memo};\r\n\t\t\tif (color) alignment.color = color;\r\n\t\t\tif (buttonColor) alignment.buttonColor = buttonColor;\r\n\t\t\tif (image) alignment.image = image;\r\n\r\n\t\t\tMafiaData.alignments[id] = alignment;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDALIGNMENT`, null, id, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The alignment ${id} was added to the database.`);\r\n\t\t},\r\n\t\taddalignmenthelp: [\r\n\t\t\t`/mafia addalignment name|plural|color|button color|image|memo1|memo2... - adds a memo to the database. Name, plural, memo are required. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\toverwritetheme: 'addtheme',\r\n\t\taddtheme(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst overwrite = cmd === 'overwritetheme';\r\n\r\n\t\t\tconst [name, desc, ...rolelists] = target.split('|').map(e => e.trim());\r\n\t\t\tconst id = toID(name);\r\n\r\n\t\t\tif (!id || !desc || !rolelists.length) return this.parse(`/help mafia addtheme`);\r\n\r\n\t\t\tif (!overwrite && id in MafiaData.themes) {\r\n\t\t\t\treturn this.errorReply(`${name} is already a theme. Use /mafia overwritetheme to overwrite.`);\r\n\t\t\t}\r\n\t\t\tif (id in MafiaData.IDEAs) return this.errorReply(`${name} is already an IDEA.`);\r\n\t\t\tif (id in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alias (pointing to ${MafiaData.aliases[id]})`);\r\n\t\t\t}\r\n\r\n\t\t\tconst rolelistsMap: {[players: number]: string} = {};\r\n\t\t\tconst uniqueRoles = new Set();\r\n\r\n\t\t\tfor (const rolelist of rolelists) {\r\n\t\t\t\tconst [players, roles] = Utils.splitFirst(rolelist, ':', 2).map(e => e.trim());\r\n\t\t\t\tconst playersNum = parseInt(players);\r\n\r\n\t\t\t\tfor (const role of roles.split(',')) {\r\n\t\t\t\t\tuniqueRoles.add(role.trim());\r\n\t\t\t\t}\r\n\t\t\t\trolelistsMap[playersNum] = roles;\r\n\t\t\t}\r\n\t\t\tconst problems = [];\r\n\t\t\tfor (const role of uniqueRoles) {\r\n\t\t\t\tconst parsedRole = Mafia.parseRole(role);\r\n\t\t\t\tif (parsedRole.problems.length) problems.push(...parsedRole.problems);\r\n\t\t\t}\r\n\t\t\tif (problems.length) return this.errorReply(`Problems found when parsing roles:\\n${problems.join('\\n')}`);\r\n\r\n\t\t\tconst theme: MafiaDataTheme = {name, desc, ...rolelistsMap};\r\n\t\t\tMafiaData.themes[id] = theme;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDTHEME`, null, id, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The theme ${id} was added to the database.`);\r\n\t\t},\r\n\t\taddthemehelp: [\r\n\t\t\t`/mafia addtheme name|description|players:rolelist|players:rolelist... - adds a theme to the database. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\toverwriteidea: 'addidea',\r\n\t\taddidea(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst overwrite = cmd === 'overwriteidea';\r\n\r\n\t\t\tlet [meta, ...roles] = target.split('\\n');\r\n\t\t\troles = roles.map(e => e.trim());\r\n\t\t\tif (!meta || !roles.length) return this.parse(`/help mafia addidea`);\r\n\t\t\tconst [name, choicesStr, ...picks] = meta.split('|');\r\n\t\t\tconst id = toID(name);\r\n\t\t\tconst choices = parseInt(choicesStr);\r\n\r\n\t\t\tif (!id || !choices || !picks.length) return this.parse(`/help mafia addidea`);\r\n\t\t\tif (choices <= picks.length) return this.errorReply(`You need to have more choices than picks.`);\r\n\r\n\t\t\tif (!overwrite && id in MafiaData.IDEAs) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an IDEA. Use /mafia overwriteidea to overwrite.`);\r\n\t\t\t}\r\n\t\t\tif (id in MafiaData.themes) return this.errorReply(`${name} is already a theme.`);\r\n\t\t\tif (id in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alias (pointing to ${MafiaData.aliases[id]})`);\r\n\t\t\t}\r\n\r\n\t\t\tconst checkedRoles: string[] = [];\r\n\t\t\tconst problems = [];\r\n\t\t\tfor (const role of roles) {\r\n\t\t\t\tif (checkedRoles.includes(role)) continue;\r\n\t\t\t\tconst parsedRole = Mafia.parseRole(role);\r\n\t\t\t\tif (parsedRole.problems.length) problems.push(...parsedRole.problems);\r\n\t\t\t\tcheckedRoles.push(role);\r\n\t\t\t}\r\n\t\t\tif (problems.length) return this.errorReply(`Problems found when parsing roles:\\n${problems.join('\\n')}`);\r\n\r\n\t\t\tconst IDEA: MafiaDataIDEA = {name, choices, picks, roles};\r\n\t\t\tMafiaData.IDEAs[id] = IDEA;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDIDEA`, null, id, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The IDEA ${id} was added to the database.`);\r\n\t\t},\r\n\t\taddideahelp: [\r\n\t\t\t`/mafia addidea name|choices (number)|pick1|pick2... (new line here)`,\r\n\t\t\t`(newline separated rolelist) - Adds an IDEA to the database. Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\toverwriteterm: 'addterm',\r\n\t\taddterm(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tconst overwrite = cmd === 'overwriteterm';\r\n\r\n\t\t\tconst [name, ...memo] = target.split('|').map(e => e.trim());\r\n\t\t\tconst id = toID(name);\r\n\t\t\tif (!id || !memo.length) return this.parse(`/help mafia addterm`);\r\n\r\n\t\t\tif (!overwrite && id in MafiaData.terms) {\r\n\t\t\t\treturn this.errorReply(`${name} is already a term. Use /mafia overwriteterm to overwrite.`);\r\n\t\t\t}\r\n\t\t\tif (id in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${name} is already an alias (pointing to ${MafiaData.aliases[id]})`);\r\n\t\t\t}\r\n\r\n\t\t\tconst term: MafiaDataTerm = {name, memo};\r\n\t\t\tMafiaData.terms[id] = term;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDTERM`, null, id, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The term ${id} was added to the database.`);\r\n\t\t},\r\n\t\taddtermhelp: [`/mafia addterm name|memo1|memo2... - Adds a term to the database. Requires % @ # &`],\r\n\r\n\t\toverwritealias: 'addalias',\r\n\t\taddalias(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\r\n\t\t\tconst [from, to] = target.split(',').map(toID);\r\n\t\t\tif (!from || !to) return this.parse(`/help mafia addalias`);\r\n\r\n\t\t\tif (from in MafiaData.aliases) {\r\n\t\t\t\treturn this.errorReply(`${from} is already an alias (pointing to ${MafiaData.aliases[from]})`);\r\n\t\t\t}\r\n\t\t\tlet foundTarget = false;\r\n\t\t\tfor (const entry of ['alignments', 'roles', 'themes', 'IDEAs', 'terms'] as (keyof MafiaData)[]) {\r\n\t\t\t\tconst dataEntry = MafiaData[entry];\r\n\t\t\t\tif (from in dataEntry) return this.errorReply(`${from} is already a ${entry.slice(0, -1)}`);\r\n\t\t\t\tif (to in dataEntry) foundTarget = true;\r\n\t\t\t}\r\n\t\t\tif (!foundTarget) return this.errorReply(`No database entry exists with the key ${to}.`);\r\n\r\n\t\t\tMafiaData.aliases[from] = to;\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tthis.modlog(`MAFIAADDALIAS`, null, `${from}: ${to}`, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The alias ${from} was added, pointing to ${to}.`);\r\n\t\t},\r\n\t\taddaliashelp: [\r\n\t\t\t`/mafia addalias from,to - Adds an alias to the database, redirecting (from) to (to). Requires % @ # &`,\r\n\t\t],\r\n\r\n\t\tdeletedata(target, room, user) {\r\n\t\t\troom = this.requireRoom('mafia' as RoomID);\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\r\n\t\t\tlet [source, entry] = target.split(',');\r\n\t\t\tentry = toID(entry);\r\n\t\t\tif (!(source in MafiaData)) {\r\n\t\t\t\treturn this.errorReply(`Invalid source. Valid sources are ${Object.keys(MafiaData).join(', ')}`);\r\n\t\t\t}\r\n\t\t\t// @ts-ignore checked above\r\n\t\t\tconst dataSource = MafiaData[source];\r\n\t\t\tif (!(entry in dataSource)) return this.errorReply(`${entry} does not exist in ${source}.`);\r\n\r\n\t\t\tlet buf = '';\r\n\t\t\tif (dataSource === MafiaData.alignments) {\r\n\t\t\t\tif (entry === 'solo' || entry === 'town') return this.errorReply(`You cannot delete the solo or town alignments.`);\r\n\r\n\t\t\t\tfor (const key in MafiaData.roles) {\r\n\t\t\t\t\tif (MafiaData.roles[key].alignment === entry) {\r\n\t\t\t\t\t\tbuf += `Removed alignment of role ${key}.`;\r\n\t\t\t\t\t\tdelete MafiaData.roles[key].alignment;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (dataSource !== MafiaData.aliases) {\r\n\t\t\t\t// remove any aliases\r\n\t\t\t\tfor (const key in MafiaData.aliases) {\r\n\t\t\t\t\tif (MafiaData.aliases[key] === entry) {\r\n\t\t\t\t\t\tbuf += `Removed alias ${key}`;\r\n\t\t\t\t\t\tdelete MafiaData.aliases[key];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tdelete dataSource[entry];\r\n\r\n\t\t\twriteFile(DATA_FILE, MafiaData);\r\n\t\t\tif (buf) this.sendReply(buf);\r\n\t\t\tthis.modlog(`MAFIADELETEDATA`, null, `${entry} from ${source}`, {noalts: true, noip: true});\r\n\t\t\tthis.sendReply(`The entry ${entry} was deleted from the ${source} database.`);\r\n\t\t},\r\n\t\tdeletedatahelp: [`/mafia deletedata source,entry - Removes an entry from the database. Requires % @ # &`],\r\n\t\tlistdata(target, room, user) {\r\n\t\t\tif (!(target in MafiaData)) {\r\n\t\t\t\treturn this.errorReply(`Invalid source. Valid sources are ${Object.keys(MafiaData).join(', ')}`);\r\n\t\t\t}\r\n\t\t\tconst dataSource = MafiaData[target as keyof MafiaData];\r\n\t\t\tif (dataSource === MafiaData.aliases) {\r\n\t\t\t\tconst aliases = Object.entries(MafiaData.aliases)\r\n\t\t\t\t\t.map(([from, to]) => `${from}: ${to}`)\r\n\t\t\t\t\t.join('
');\r\n\t\t\t\treturn this.sendReplyBox(`Mafia aliases:
${aliases}`);\r\n\t\t\t} else {\r\n\t\t\t\tconst entries = Object.entries(dataSource)\r\n\t\t\t\t\t.map(([key, data]) => ``)\r\n\t\t\t\t\t.join('');\r\n\t\t\t\treturn this.sendReplyBox(`Mafia ${target}:
${entries}`);\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tdisable(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('gamemanagement', null, room);\r\n\t\t\tif (room.settings.mafiaDisabled) {\r\n\t\t\t\treturn this.errorReply(\"Mafia is already disabled.\");\r\n\t\t\t}\r\n\t\t\troom.settings.mafiaDisabled = true;\r\n\t\t\troom.saveSettings();\r\n\t\t\tthis.modlog('MAFIADISABLE', null);\r\n\t\t\treturn this.sendReply(\"Mafia has been disabled for this room.\");\r\n\t\t},\r\n\t\tdisablehelp: [`/mafia disable - Disables mafia in this room. Requires # &`],\r\n\r\n\t\tenable(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('gamemanagement', null, room);\r\n\t\t\tif (!room.settings.mafiaDisabled) {\r\n\t\t\t\treturn this.errorReply(\"Mafia is already enabled.\");\r\n\t\t\t}\r\n\t\t\troom.settings.mafiaDisabled = false;\r\n\t\t\troom.saveSettings();\r\n\t\t\tthis.modlog('MAFIAENABLE', null);\r\n\t\t\treturn this.sendReply(\"Mafia has been enabled for this room.\");\r\n\t\t},\r\n\t\tenablehelp: [`/mafia enable - Enables mafia in this room. Requires # &`],\r\n\t},\r\n\tmafiahelp(target, room, user) {\r\n\t\tif (!this.runBroadcast()) return;\r\n\t\tlet buf = `Commands for the Mafia Plugin
Most commands are used through buttons in the game screen.

`;\r\n\t\tbuf += `
General Commands`;\r\n\t\tbuf += [\r\n\t\t\t`
General Commands for the Mafia Plugin:
`,\r\n\t\t\t`/mafia host [user] - Create a game of Mafia with [user] as the host. Roomvoices can only host themselves. Requires + % @ # &`,\r\n\t\t\t`/mafia nexthost - Host the next user in the host queue. Only works in the Mafia Room. Requires + % @ # &`,\r\n\t\t\t`/mafia forcehost [user] - Bypass the host queue and host [user]. Only works in the Mafia Room. Requires % @ # &`,\r\n\t\t\t`/mafia sub [in|out] - Request to sub into the game, or cancel a request to sub out.`,\r\n\t\t\t`/mafia spectate - Spectate the game of mafia.`,\r\n\t\t\t`/mafia votes - Display the current vote count, and who's voting who.`,\r\n\t\t\t`/mafia players - Display the current list of players, will highlight players.`,\r\n\t\t\t`/mafia [rl|orl] - Display the role list or the original role list for the current game.`,\r\n\t\t\t`/mafia data [alignment|role|modifier|theme|term] - Get information on a mafia alignment, role, modifier, theme, or term.`,\r\n\t\t\t`/mafia subhost [user] - Substitues the user as the new game host. Requires % @ # &`,\r\n\t\t\t`/mafia (un)cohost [user] - Adds/removes the user as a cohost. Cohosts can talk during the game, as well as perform host actions. Requires % @ # &`,\r\n\t\t\t`/mafia [enable|disable] - Enables/disables mafia in this room. Requires # &`,\r\n\t\t].join('
');\r\n\t\tbuf += `
Player Commands`;\r\n\t\tbuf += [\r\n\t\t\t`
Commands that players can use:
`,\r\n\t\t\t`/mafia [join|leave] - Joins/leaves the game. Can only be done while signups are open.`,\r\n\t\t\t`/mafia vote [player|novote] - Vote the specified player or abstain from voting.`,\r\n\t\t\t`/mafia unvote - Withdraw your vote. Fails if you're not voting anyone`,\r\n\t\t\t`/mafia deadline - View the deadline for the current game.`,\r\n\t\t\t`/mafia sub in - Request to sub into the game, or cancel a request to sub out.`,\r\n\t\t\t`/mafia sub out - Request to sub out of the game, or cancel a request to sub in.`,\r\n\t\t\t`/mafia idle - Tells the host if you are idling.`,\r\n\t\t\t`/mafia action [details] - Tells the host you are using an action with the given submission details.`,\r\n\t\t].join('
');\r\n\t\tbuf += `
Host Commands`;\r\n\t\tbuf += [\r\n\t\t\t`
Commands for game hosts and Cohosts to use:
`,\r\n\t\t\t`/mafia playercap [cap|none]- Limit the number of players able to join the game. Player cap cannot be more than 20 or less than 2. Requires host % @ # &`,\r\n\t\t\t`/mafia close - Closes signups for the current game. Requires host % @ # &`,\r\n\t\t\t`/mafia closedsetup [on|off] - Sets if the game is a closed setup. Closed setups don't show the role list to players. Requires host % @ # &`,\r\n\t\t\t`/mafia takeidles [on|off] - Sets if idles are accepted by the script or not. Requires host % @ # &`,\r\n\t\t\t`/mafia prod - Notifies players that they must submit an action or idle if they haven't yet. Requires host % @ # &`,\r\n\t\t\t`/mafia reveal [on|off] - Sets if roles reveal on death or not. Requires host % @ # &`,\r\n\t\t\t`/mafia selfvote [on|hammer|off] - Allows players to self vote either at hammer or anytime. Requires host % @ # &`,\r\n\t\t\t`/mafia [enablenl|disablenl] - Allows or disallows players abstain from voting. Requires host % @ # &`,\r\n\t\t\t`/mafia votelock [on|off] - Allows or disallows players to change their vote. Requires host % @ # &`,\r\n\t\t\t`/mafia voting [on|off] - Allows or disallows voting. Requires host % @ # &`,\r\n\t\t\t`/mafia forcevote [yes/no] - Forces players' votes onto themselves, and prevents unvoting. Requires host % @ # &`,\r\n\t\t\t`/mafia setroles [comma seperated roles] - Set the roles for a game of mafia. You need to provide one role per player. Requires host % @ # &`,\r\n\t\t\t`/mafia forcesetroles [comma seperated roles] - Forcibly set the roles for a game of mafia. No role PM information or alignment will be set. Requires host % @ # &`,\r\n\t\t\t`/mafia start - Start the game of mafia. Signups must be closed. Requires host % @ # &`,\r\n\t\t\t`/mafia [day|night] - Move to the next game day or night. Requires host % @ # &`,\r\n\t\t\t`/mafia extend (minutes) - Return to the previous game day. If (minutes) is provided, set the deadline for (minutes) minutes. Requires host % @ # &`,\r\n\t\t\t`/mafia kill [player] - Kill a player, eliminating them from the game. Requires host % @ # &`,\r\n\t\t\t`/mafia treestump [player] - Kills a player, but allows them to talk during the day still. Requires host % @ # &`,\r\n\t\t\t`/mafia spirit [player] - Kills a player, but allows them to vote still. Requires host % @ # &`,\r\n\t\t\t`/mafia spiritstump [player] - Kills a player, but allows them to talk and vote during the day. Requires host % @ # &`,\r\n\t\t\t`/mafia kick [player] - Kicks a player from the game without revealing their role. Requires host % @ # &`,\r\n\t\t\t`/mafia revive [player] - Revive a player who died or add a new player to the game. Requires host % @ # &`,\r\n\t\t\t`/mafia revealrole [player] - Reveals the role of a player. Requires host % @ # &`,\r\n\t\t\t`/mafia revealas [player], [role] - Fakereveals the role of a player as a certain role. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)silence [player] - Silences [player], preventing them from talking at all. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)nighttalk [player] - Allows [player] to talk freely during the night. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)[priest|actor] [player] - Makes [player] a priest (can't hammer) or actor (can only hammer). Requires host % @ # &`,\r\n\t\t\t`/mafia deadline [minutes|off] - Sets or removes the deadline for the game. Cannot be more than 20 minutes.`,\r\n\t\t\t`/mafia sub next, [player] - Forcibly sub [player] out of the game. Requires host % @ # &`,\r\n\t\t\t`/mafia sub remove, [user] - Forcibly remove [user] from the sublist. Requres host % @ # &`,\r\n\t\t\t`/mafia sub unrequest, [player] - Remove's a player's request to sub out of the game. Requires host % @ # &`,\r\n\t\t\t`/mafia sub [player], [user] - Forcibly sub [player] for [user]. Requires host % @ # &`,\r\n\t\t\t`/mafia autosub [yes|no] - Sets if players will automatically sub out if a user is on the sublist. Defaults to yes. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)[love|hate] [player] - Makes it take 1 more (love) or less (hate) vote to hammer [player]. Requires host % @ # &`,\r\n\t\t\t`/mafia (un)[mayor|voteless] [player] - Makes [player]'s' vote worth 2 votes (mayor) or makes [player]'s vote worth 0 votes (voteless). Requires host % @ # &`,\r\n\t\t\t`/mafia hammer [hammer] - sets the hammer count to [hammer] and resets votes`,\r\n\t\t\t`/mafia hammer off - disables hammering`,\r\n\t\t\t`/mafia shifthammer [hammer] - sets the hammer count to [hammer] without resetting votes`,\r\n\t\t\t`/mafia resethammer - sets the hammer to the default, resetting votes`,\r\n\t\t\t`/mafia playerroles - View all the player's roles in chat. Requires host`,\r\n\t\t\t`/mafia resetgame - Resets game data. Does not change settings from the host besides deadlines or add/remove any players. Requires host % @ # &`,\r\n\t\t\t`/mafia end - End the current game of mafia. Requires host + % @ # &`,\r\n\t\t].join('
');\r\n\t\tbuf += `
IDEA Module Commands`;\r\n\t\tbuf += [\r\n\t\t\t`
Commands for using IDEA modules
`,\r\n\t\t\t`/mafia idea [idea] - starts the IDEA module [idea]. Requires + % @ # &, voices can only start for themselves`,\r\n\t\t\t`/mafia ideareroll - rerolls the IDEA module. Requires host % @ # &`,\r\n\t\t\t`/mafia ideapick [selection], [role] - selects a role`,\r\n\t\t\t`/mafia ideadiscards - shows the discarded roles`,\r\n\t\t\t`/mafia ideadiscards [off|on] - hides discards from the players. Requires host % @ # &`,\r\n\t\t\t`/mafia customidea choices, picks (new line here, shift+enter)`,\r\n\t\t\t`(comma or newline separated rolelist) - Starts an IDEA module with custom roles. Requires % @ # &`,\r\n\t\t].join('
');\r\n\t\tbuf += `
`;\r\n\t\tbuf += `
Mafia Room Specific Commands`;\r\n\t\tbuf += [\r\n\t\t\t`
Commands that are only useable in the Mafia Room:
`,\r\n\t\t\t`/mafia queue add, [user] - Adds the user to the host queue. Requires + % @ # &, voices can only add themselves.`,\r\n\t\t\t`/mafia queue remove, [user] - Removes the user from the queue. You can remove yourself regardless of rank. Requires % @ # &.`,\r\n\t\t\t`/mafia queue - Shows the list of users who are in queue to host.`,\r\n\t\t\t`/mafia win (points) [user1], [user2], [user3], ... - Award the specified users points to the mafia leaderboard for this month. The amount of points can be negative to take points. Defaults to 10 points.`,\r\n\t\t\t`/mafia winfaction (points), [faction] - Award the specified points to all the players in the given faction. Requires % @ # &`,\r\n\t\t\t`/mafia (un)mvp [user1], [user2], ... - Gives a MVP point and 10 leaderboard points to the users specified.`,\r\n\t\t\t`/mafia [leaderboard|mvpladder] - View the leaderboard or MVP ladder for the current or last month.`,\r\n\t\t\t`/mafia [hostlogs|playlogs] - View the host logs or play logs for the current or last month. Requires % @ # &`,\r\n\t\t\t`/mafia (un)hostban [user], [duration] - Ban a user from hosting games for [duration] days. Requires % @ # &`,\r\n\t\t\t`/mafia (un)gameban [user], [duration] - Ban a user from playing games for [duration] days. Requires % @ # &`,\r\n\t\t].join('
');\r\n\t\tbuf += `
`;\r\n\r\n\t\treturn this.sendReplyBox(buf);\r\n\t},\r\n};\r\n\r\nexport const roomSettings: Chat.SettingsHandler = room => ({\r\n\tlabel: \"Mafia\",\r\n\tpermission: 'editroom',\r\n\toptions: [\r\n\t\t[`disabled`, room.settings.mafiaDisabled || 'mafia disable'],\r\n\t\t[`enabled`, !room.settings.mafiaDisabled || 'mafia enable'],\r\n\t],\r\n});\r\n\r\nprocess.nextTick(() => {\r\n\tChat.multiLinePattern.register('/mafia (custom|add|overwrite)idea');\r\n});\r\n"], "mappings": "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", "names": ["player", "game"] }