From 39d76be0b10024dcd59ecab03ebe365dbf682c2e Mon Sep 17 00:00:00 2001 From: Lucas-Meijer <33839844+Lucas-Meijer@users.noreply.github.com> Date: Sat, 28 Jan 2023 23:43:47 +0100 Subject: [PATCH 01/19] Mafia: Prevent incorrect alignment. A new theme includes a role that can change someone's alignment as a discard. Players should not be informed according to their old alignment. --- server/chat-plugins/mafia.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index e603979bdff2..2daaf18d0d6b 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -1480,6 +1480,8 @@ class Mafia extends Rooms.RoomGame { } } } + // 'Innocent Discard' causes chosen role to become Town, when discarded. + if (this.playerTable[p].IDEA.choices.includes('Innocent Discard')) player.role.alignment = 'town'; } this.IDEA.discardsHTML = `Discards:
`; for (const p of Object.keys(this.playerTable).sort()) { From 650970268a2110b8beb6aa291ba5861aaf0791e4 Mon Sep 17 00:00:00 2001 From: Lucas-Meijer <33839844+Lucas-Meijer@users.noreply.github.com> Date: Sun, 29 Jan 2023 00:51:23 +0100 Subject: [PATCH 02/19] Mafia: Update readability. Change a longer definition to a predefined variable. --- server/chat-plugins/mafia.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index 2daaf18d0d6b..8d5bfb0556f3 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -1481,7 +1481,7 @@ class Mafia extends Rooms.RoomGame { } } // 'Innocent Discard' causes chosen role to become Town, when discarded. - if (this.playerTable[p].IDEA.choices.includes('Innocent Discard')) player.role.alignment = 'town'; + if (player.IDEA.choices.includes('Innocent Discard')) player.role.alignment = 'town'; } this.IDEA.discardsHTML = `Discards:
`; for (const p of Object.keys(this.playerTable).sort()) { From b352d5ee624fbe3cb157efa4033fc1a688ebb750 Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Mon, 3 Jun 2024 11:15:32 +0200 Subject: [PATCH 03/19] Implement mafia search, mafia randomdata --- Brewfile | 27 +++++ package-lock.json | 101 ++++++------------- server/chat-plugins/mafia.ts | 187 +++++++++++++++++++++++++++++++++-- 3 files changed, 237 insertions(+), 78 deletions(-) create mode 100644 Brewfile diff --git a/Brewfile b/Brewfile new file mode 100644 index 000000000000..94e319938213 --- /dev/null +++ b/Brewfile @@ -0,0 +1,27 @@ +tap "caskroom/versions" +tap "homebrew/bundle" +tap "homebrew/cask" +tap "homebrew/core" +brew "freetype", args: ["universal"], link: false +brew "fontconfig", args: ["universal"], link: false +brew "libtiff", args: ["universal"], link: false +brew "webp", args: ["universal"], link: false +brew "gd", args: ["universal"], link: false +brew "glpk" +brew "gnutls", link: false +brew "gradle" +brew "haskell-stack", link: false +brew "jasper", args: ["universal"], link: false +brew "libusb", args: ["universal"], link: false +brew "libusb-compat", args: ["universal"], link: false +brew "libgphoto2", args: ["universal"], link: false +brew "libicns", args: ["universal"], link: false +brew "little-cms2", args: ["universal"], link: false +brew "makedepend", link: false +brew "openjdk" +brew "python@3.8", link: true +brew "sane-backends", args: ["universal"], link: false +cask "basictex" +cask "java8" +cask "miniforge" +cask "xquartz" diff --git a/package-lock.json b/package-lock.json index 059c0f423b8d..836076ae0722 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1921,18 +1921,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2179,9 +2167,9 @@ } }, "node_modules/mysql2": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", - "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.0.tgz", + "integrity": "sha512-qx0mfWYt1DpTPkw8mAcHW/OwqqyNqBLBHvY5IjN8+icIYTjt6znrgYJ+gxqNNRpVknb5Wc/gcCM4XjbCR0j5tw==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -2364,9 +2352,9 @@ } }, "node_modules/node-pre-gyp/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "optional": true, "bin": { "semver": "bin/semver" @@ -2390,9 +2378,9 @@ } }, "node_modules/nodemailer": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", - "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==", + "version": "6.9.13", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.13.tgz", + "integrity": "sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==", "optional": true, "engines": { "node": ">=6.0.0" @@ -3102,13 +3090,10 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "devOptional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -3698,9 +3683,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3785,12 +3770,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true - }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -5269,15 +5248,6 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, - "requires": { - "yallist": "^4.0.0" - } - }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5471,9 +5441,9 @@ } }, "mysql2": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", - "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.0.tgz", + "integrity": "sha512-qx0mfWYt1DpTPkw8mAcHW/OwqqyNqBLBHvY5IjN8+icIYTjt6znrgYJ+gxqNNRpVknb5Wc/gcCM4XjbCR0j5tw==", "requires": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -5619,9 +5589,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "optional": true } } @@ -5638,9 +5608,9 @@ } }, "nodemailer": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", - "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==", + "version": "6.9.13", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.13.tgz", + "integrity": "sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==", "optional": true }, "nopt": { @@ -6159,13 +6129,10 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "devOptional": true, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "devOptional": true }, "seq-queue": { "version": "0.0.5", @@ -6620,9 +6587,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { @@ -6685,12 +6652,6 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index 188c3d9f16d8..1f69b1594dd2 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -1,4 +1,4 @@ -import {Utils, FS} from '../../lib'; +import { Utils, FS } from '../../lib'; interface MafiaData { // keys for all of these are IDs @@ -3927,21 +3927,192 @@ export const commands: Chat.ChatCommands = { this.sendReply(`The entry ${entry} was deleted from the ${source} database.`); }, deletedatahelp: [`/mafia deletedata source,entry - Removes an entry from the database. Requires % @ # &`], - listdata(target, room, user) { - if (!(target in MafiaData)) { - return this.errorReply(`Invalid source. Valid sources are ${Object.keys(MafiaData).join(', ')}`); + + randtheme: 'listdata', + randrole: 'listdata', + randalignment: 'listdata', + randidea: 'listdata', + randterm: 'listdata', + randdata: 'listdata', + randomtheme: 'listdata', + randomrole: 'listdata', + randomalignment: 'listdata', + randomidea: 'listdata', + randomterm: 'listdata', + randomdata: 'listdata', + listthemes: 'listdata', + listroles: 'listdata', + listalignments: 'listdata', + listideas: 'listdata', + listterms: 'listdata', + themes: 'listdata', + roles: 'listdata', + alignments: 'listdata', + ideas: 'listdata', + terms: 'listdata', + ds: 'listdata', + search: 'listdata', + random: 'listdata', + list: 'listdata', + async listdata(target, room, user, connection, cmd, message) { + if (!this.runBroadcast()) return false; + + // Determine non-search targets first, afterwards searching is done with the remainder + let targets = target.split(',').map(x => x.trim()); + + // Determine search type + let searchType = null; + if (cmd === 'randtheme' || cmd === 'randomtheme' || cmd === 'listthemes' || cmd === 'themes' || targets.includes(`themes`)) { + searchType = `themes`; + if (targets.includes(`themes`)) targets.splice(targets.indexOf(`themes`), 1); + } + else if (cmd === 'randrole' || cmd === 'randomrole' || cmd === 'listroles' || cmd === 'roles' || targets.includes(`roles`)) { + searchType = `roles`; + if (targets.includes(`roles`)) targets.splice(targets.indexOf(`roles`), 1); + } + else if (cmd === 'randalignment' || cmd === 'randomalignment' || cmd === 'listalignments' || cmd === 'alignments' || targets.includes(`alignments`)) { + searchType = `alignments`; + if (targets.includes(`alignments`)) targets.splice(targets.indexOf(`alignments`), 1); + } + else if (cmd === 'randidea' || cmd === 'randomidea' || cmd === 'listideas' || cmd === 'ideas' || targets.includes(`ideas`)) { + searchType = `IDEAs`; + if (targets.includes(`ideas`)) targets.splice(targets.indexOf(`ideas`), 1); + } + else if (cmd === 'randterm' || cmd === 'randomterm' || cmd === 'listterms' || cmd === 'terms' || targets.includes(`terms`)) { + searchType = `terms`; + if (targets.includes(`terms`)) targets.splice(targets.indexOf(`terms`), 1); + } + else if (targets.includes(`aliases`)) { + searchType = `aliases`; + } + else if (targets.includes(`tags`)) { + searchType = `tags`; + } + else if (cmd === 'random' || cmd === 'randomdata' || cmd === 'randdata') { + searchType = [`themes`, `roles`, `alignments`, `IDEAs`, `terms`][Math.floor(Math.random() * 5)]; + } + else { + return this.errorReply(`Invalid source. Valid sources are ${Object.keys(MafiaData).filter(key => key != `aliases`).join(', ')}.`); + } + + const dataSource = MafiaData[searchType as keyof MafiaData]; + + const random = (cmd === 'random' || cmd === 'randdata' || cmd === 'randomdata' || cmd === 'randrole' || cmd === 'randomrole' || cmd === 'randalignment' || cmd === 'randomalignment' || cmd === 'randtheme' || cmd === 'randomtheme' || cmd === 'randterm' || cmd === 'randomterm' || cmd === 'randidea' || cmd === 'randomidea' || targets.includes(`random`)); + if (targets.includes(`random`)) targets.splice(targets.indexOf(`random`), 1); + + const hidden = (targets.includes(`hidden`)); + if (hidden) targets.splice(targets.indexOf(`hidden`), 1); + + let shuffle = function (array: any[]) { + for (let i = array.length - 1; i > 0; i--) { + let j = Math.floor(Math.random() * (i + 1)); + [array[j], array[i]] = [array[i], array[j]]; + } + return array; + } + + let search = function (entries: any[], searchTarget) { + if (searchTarget.length == 0) return entries; + const negation = searchTarget[0] == '!'; + + if (negation) searchTarget = searchTarget.substring(1).trim(); + let entriesCopy = entries.slice(); + + if (searchType == `themes` && searchTarget.includes(`players`)) { + const inequalities = ['<=', '>=', '=', '<', '>']; + const inequality = inequalities.find(x => searchTarget.includes(x)); + if (!inequality) return this.errorReply(`Please provide a valid inequality for the players.`); + + const players = searchTarget.split(inequality)[1].trim(); + if (((players != null) && + (players !== '') && + !isNaN(Number(players.toString())))) { + if (inequality == '=') entries = entries.filter(([key, data]) => players in (MafiaData[searchType][key])); + else if (inequality == '<' || inequality == '<=') entries = entries.filter(([key, data]) => ([...Array(+players + (inequality == '<=' ? +1 : +0)).keys()]).some(playerCount => playerCount in (MafiaData[searchType][key]))); + else if (inequality == '>' || inequality == '>=') entries = entries.filter(([key, data]) => ([...Array(30 - players).keys()].map(num => +num + +players + (inequality == '>=' ? +0 : +1))).some(playerCount => playerCount in (MafiaData[searchType][key]))); + } else { + return this.errorReply(`Please ensure the amount of players is numeric.`); + } + } + else if ((searchType == `roles`) && toID(searchTarget) in MafiaData[`themes`]) { + entries = entries.filter(([key, data]) => Object.keys(MafiaData[`themes`][toID(searchTarget)]).filter(newKey => toID((MafiaData[`themes`][toID(searchTarget)])[newKey].toString()).includes(key)).length > 0); + } + else if ((searchType == `roles`) && toID(searchTarget) in MafiaData[`IDEAs`]) { + entries = entries.filter(([key, data]) => Object.keys(MafiaData[`IDEAs`][toID(searchTarget)]).filter(newKey => toID((MafiaData[`IDEAs`][toID(searchTarget)])[newKey].toString()).includes(key)).length > 0); + } + else { + entries = entries.filter(([key, data]) => Object.keys((MafiaData[searchType][key])).filter(newKey => (MafiaData[searchType][key])[newKey].toString().toLowerCase().includes(searchTarget)).length > 0); + } + return negation ? entriesCopy.filter(element => !entries.includes(element)) : entries; } - const dataSource = MafiaData[target as keyof MafiaData]; + + // Number of results + let number = random ? 1 : 0; + for (let i = 0; i < targets.length; i++) { + if (((targets[i] != null) && + (targets[i] !== '') && + !isNaN(Number(targets[i].toString())))) { + number = Number(targets[i]); + targets.splice(i, 1); + break; + } + } + + // Convert to rows + let themeRow = function (theme, players = 0) { + return ` ${players > 0 ? theme[players] : theme.desc} `; + } + let ideaRow = function (idea) { + return ` `; + } + let row = function (role) { + return ` ${role.memo.join(' ')} `; + } + if (dataSource === MafiaData.aliases) { + this.checkCan('mute', null, room); const aliases = Object.entries(MafiaData.aliases) .map(([from, to]) => `${from}: ${to}`) .join('
'); return this.sendReplyBox(`Mafia aliases:
${aliases}`); + } else if (dataSource === MafiaData.tags) { + this.checkCan('mute', null, room); + const tags = Object.entries(MafiaData.tags) + .map(([key, data]) => `${key}: Alignments ${data.alignments}; Roles: ${data.roles}; Themes: ${data.themes}; IDEAs: ${data.ideas}; Terms: ${data.terms}`) + .join('
'); + return this.sendReplyBox(`Mafia tags:
${tags}`); } else { - const entries = Object.entries(dataSource) - .map(([key, data]) => ``) + let table = `
`; + let entries = Object.entries(dataSource).sort(); + + // Remove probably + entries.forEach(([key, data]) => { + if (!(MafiaData[searchType][key][`tags`])) MafiaData[searchType][key][`tags`] = []; + }); + + if (!hidden) entries = entries.filter(([key, data]) => !MafiaData[searchType][key][`tags`].includes(`hidden`)); + + for (let i = 0; i < targets.length; i++) { + entries = targets[i].split('|').map(x => x.trim()).map(searchTerm => search(entries.slice(), searchTerm)).reduce((aggregate, result) => [...new Set([...aggregate, ...result])]); + } + + if (random) entries = shuffle(entries); + if (number > 0) entries = entries.slice(0, number) + + if (entries.length == 0) { + return this.errorReply(`No ${searchType} found.`); + } + + if (entries.length == 1) { + this.target = entries[0][0]; + return this.run(Chat.commands.mafia.data); + } + + table += entries + .map(([key, data]) => searchType == `themes` ? themeRow(MafiaData[searchType][key]) : searchType == `IDEAs` ? ideaRow(MafiaData[searchType][key]) : row(MafiaData[searchType][key])) .join(''); - return this.sendReplyBox(`Mafia ${target}:
${entries}`); + table += `
` + return this.sendReplyBox(table); } }, From 6f2c74623b4362ab8f62c70be2192a502eb0e0cb Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Tue, 25 Jun 2024 23:48:28 +0200 Subject: [PATCH 04/19] Add Mafia Autohost --- package-lock.json | 87 ------------------------------------ package.json | 1 - server/chat-plugins/mafia.ts | 36 ++++++++++++--- 3 files changed, 30 insertions(+), 94 deletions(-) diff --git a/package-lock.json b/package-lock.json index 836076ae0722..1eaddc1e4a30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "esbuild": "^0.16.10", "mysql2": "^3.9.7", "preact": "^10.5.15", "preact-render-to-string": "^5.1.19", @@ -52,21 +51,6 @@ "sucrase": "^3.15.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.16.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.15.tgz", - "integrity": "sha512-t7/fOXBUKfigvhJLGKZ9TPHHgqNgpIpYaAbcXQk1X+fPeUG7x0tpAbXJ2wST9F/gJ02+CLETPMnhG7Tra2wqsQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -1033,42 +1017,6 @@ "node": ">=8.6" } }, - "node_modules/esbuild": { - "version": "0.16.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.15.tgz", - "integrity": "sha512-v+3ozjy9wyj8cOElzx3//Lsb4TCxPfZxRmdsfm0YaEkvZu7y6rKH7Zi1UpDx4JI7dSQui+U1Qxhfij9KBbHfrA==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.16.15", - "@esbuild/android-arm64": "0.16.15", - "@esbuild/android-x64": "0.16.15", - "@esbuild/darwin-arm64": "0.16.15", - "@esbuild/darwin-x64": "0.16.15", - "@esbuild/freebsd-arm64": "0.16.15", - "@esbuild/freebsd-x64": "0.16.15", - "@esbuild/linux-arm": "0.16.15", - "@esbuild/linux-arm64": "0.16.15", - "@esbuild/linux-ia32": "0.16.15", - "@esbuild/linux-loong64": "0.16.15", - "@esbuild/linux-mips64el": "0.16.15", - "@esbuild/linux-ppc64": "0.16.15", - "@esbuild/linux-riscv64": "0.16.15", - "@esbuild/linux-s390x": "0.16.15", - "@esbuild/linux-x64": "0.16.15", - "@esbuild/netbsd-x64": "0.16.15", - "@esbuild/openbsd-x64": "0.16.15", - "@esbuild/sunos-x64": "0.16.15", - "@esbuild/win32-arm64": "0.16.15", - "@esbuild/win32-ia32": "0.16.15", - "@esbuild/win32-x64": "0.16.15" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3849,12 +3797,6 @@ } }, "dependencies": { - "@esbuild/linux-x64": { - "version": "0.16.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.15.tgz", - "integrity": "sha512-t7/fOXBUKfigvhJLGKZ9TPHHgqNgpIpYaAbcXQk1X+fPeUG7x0tpAbXJ2wST9F/gJ02+CLETPMnhG7Tra2wqsQ==", - "optional": true - }, "@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -4561,35 +4503,6 @@ "strip-ansi": "^6.0.1" } }, - "esbuild": { - "version": "0.16.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.15.tgz", - "integrity": "sha512-v+3ozjy9wyj8cOElzx3//Lsb4TCxPfZxRmdsfm0YaEkvZu7y6rKH7Zi1UpDx4JI7dSQui+U1Qxhfij9KBbHfrA==", - "requires": { - "@esbuild/android-arm": "0.16.15", - "@esbuild/android-arm64": "0.16.15", - "@esbuild/android-x64": "0.16.15", - "@esbuild/darwin-arm64": "0.16.15", - "@esbuild/darwin-x64": "0.16.15", - "@esbuild/freebsd-arm64": "0.16.15", - "@esbuild/freebsd-x64": "0.16.15", - "@esbuild/linux-arm": "0.16.15", - "@esbuild/linux-arm64": "0.16.15", - "@esbuild/linux-ia32": "0.16.15", - "@esbuild/linux-loong64": "0.16.15", - "@esbuild/linux-mips64el": "0.16.15", - "@esbuild/linux-ppc64": "0.16.15", - "@esbuild/linux-riscv64": "0.16.15", - "@esbuild/linux-s390x": "0.16.15", - "@esbuild/linux-x64": "0.16.15", - "@esbuild/netbsd-x64": "0.16.15", - "@esbuild/openbsd-x64": "0.16.15", - "@esbuild/sunos-x64": "0.16.15", - "@esbuild/win32-arm64": "0.16.15", - "@esbuild/win32-ia32": "0.16.15", - "@esbuild/win32-x64": "0.16.15" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", diff --git a/package.json b/package.json index 7c30ade6fbad..88bed6e06643 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "version": "0.11.9", "main": "dist/sim/index.js", "dependencies": { - "esbuild": "^0.16.10", "mysql2": "^3.9.7", "preact": "^10.5.15", "preact-render-to-string": "^5.1.19", diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index 1f69b1594dd2..736464e3cadd 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -140,12 +140,26 @@ function writeFile(path: string, data: AnyObject) { MafiaData = readFile(DATA_FILE) || {alignments: {}, roles: {}, themes: {}, IDEAs: {}, terms: {}, aliases: {}}; if (!MafiaData.alignments.town) { MafiaData.alignments.town = { - name: 'town', plural: 'town', memo: [`This alignment is required for the script to function properly.`], + name: 'Town', + plural: 'Town', + memo: [`This alignment is required for the script to function properly.`], }; } if (!MafiaData.alignments.solo) { MafiaData.alignments.solo = { - name: 'solo', plural: 'solo', memo: [`This alignment is required for the script to function properly.`], + name: 'Solo', + plural: 'Solo', + memo: [`This alignment is required for the script to function properly.`], + }; +} +if (!MafiaData.themes.nominations) { + MafiaData.themes.nominations = { + name: `Nominations`, + desc: `Every odd night, the Mafia select three players. The next day, you can only vote for one of these three players.`, + 7: `Mafia Goon, Mafia Goon, Villager, Villager, Villager, Villager, Villager`, + 11: `Mafia Goon, Mafia Goon, Mafia Goon, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager`, + 15: `Mafia Goon, Mafia Goon, Mafia Goon, Mafia Goon, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager`, + 19: `Mafia Goon, Mafia Goon, Mafia Goon, Mafia Goon, Mafia Goon, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager, Villager`, }; } @@ -273,7 +287,8 @@ class Mafia extends Rooms.RoomGame { dlAt: number; IDEA: MafiaIDEAModule; - constructor(room: ChatRoom, host: User) { + + constructor(room: ChatRoom, host?: User) { super(room); this.title = 'Mafia'; @@ -282,9 +297,10 @@ class Mafia extends Rooms.RoomGame { this.started = false; this.theme = null; - - this.hostid = host.id; - this.host = Utils.escapeHTML(host.name); + if(host != undefined) { + this.hostid = host?.id; + this.host = Utils.escapeHTML(host?.name); + } this.cohostids = []; this.cohosts = []; @@ -2108,7 +2124,15 @@ export const commands: Chat.ChatCommands = { } return this.parse('/help mafia'); }, + autohost(target, room, user, cmd) { + room = this.requireRoom(); + if (room.settings.mafiaDisabled) return this.errorReply(`Mafia is disabled for this room.`); + this.checkChat(); + if (room.type !== 'chat') return this.errorReply(`This command is only meant to be used in chat rooms.`); + if (room.game) return this.errorReply(`There is already a game of ${room.game.title} in progress in this room.`); + room.game = new Mafia(room, null); + }, forcehost: 'host', nexthost: 'host', host(target, room, user, connection, cmd) { From 79933c582c9c06a1ae78778bff0459a12fe11672 Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Tue, 2 Jul 2024 23:10:26 +0200 Subject: [PATCH 05/19] setup autohost --- server/chat-plugins/mafia.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index 736464e3cadd..56a0d963100b 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -1815,6 +1815,18 @@ class Mafia extends Rooms.RoomGame { this.dead[i].destroy(); } } + + hostPregame() { + + } + + hostDay() { + + } + + hostNight() { + + } } export const pages: Chat.PageTable = { @@ -2132,6 +2144,13 @@ export const commands: Chat.ChatCommands = { if (room.game) return this.errorReply(`There is already a game of ${room.game.title} in progress in this room.`); room.game = new Mafia(room, null); + const game = this.requireGame(Mafia); + + // deadline for signups + game.phase = 'locked'; + game.sendHTML(game.roomWindow()); + game.updatePlayers(); + game.logAction(user, `closed signups`); }, forcehost: 'host', nexthost: 'host', From e100d211d78eb77665808a1c474024282231411b Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Sun, 7 Jul 2024 19:48:28 +0200 Subject: [PATCH 06/19] Test commit --- server/chat-plugins/mafia.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index 56a0d963100b..a3c137bf5cc3 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -1825,7 +1825,7 @@ class Mafia extends Rooms.RoomGame { } hostNight() { - + } } From 2c32677f3072953522aba2d54da2ffb9c16ad957 Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Wed, 10 Jul 2024 11:00:38 +0200 Subject: [PATCH 07/19] Scav and Mafia changes --- server/chat-plugins/mafia.ts | 18 +++++++-- server/chat-plugins/scavengers.ts | 66 ++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/server/chat-plugins/mafia.ts b/server/chat-plugins/mafia.ts index a3c137bf5cc3..3eb4018fac4b 100644 --- a/server/chat-plugins/mafia.ts +++ b/server/chat-plugins/mafia.ts @@ -4000,6 +4000,13 @@ export const commands: Chat.ChatCommands = { async listdata(target, room, user, connection, cmd, message) { if (!this.runBroadcast()) return false; + // Fix errors + // Fix searching on roles + // Fix random (do not pick empty) + + // Future: tags + // Future: or + // Determine non-search targets first, afterwards searching is done with the remainder let targets = target.split(',').map(x => x.trim()); @@ -4055,6 +4062,8 @@ export const commands: Chat.ChatCommands = { } let search = function (entries: any[], searchTarget) { + if(typeof(entries) == 'undefined') return entries; //Hotpatch + if (searchTarget.length == 0) return entries; const negation = searchTarget[0] == '!'; @@ -4064,7 +4073,7 @@ export const commands: Chat.ChatCommands = { if (searchType == `themes` && searchTarget.includes(`players`)) { const inequalities = ['<=', '>=', '=', '<', '>']; const inequality = inequalities.find(x => searchTarget.includes(x)); - if (!inequality) return this.errorReply(`Please provide a valid inequality for the players.`); + if (!inequality) return entries; // this.errorReply(`Please provide a valid inequality for the players.`); const players = searchTarget.split(inequality)[1].trim(); if (((players != null) && @@ -4074,7 +4083,7 @@ export const commands: Chat.ChatCommands = { else if (inequality == '<' || inequality == '<=') entries = entries.filter(([key, data]) => ([...Array(+players + (inequality == '<=' ? +1 : +0)).keys()]).some(playerCount => playerCount in (MafiaData[searchType][key]))); else if (inequality == '>' || inequality == '>=') entries = entries.filter(([key, data]) => ([...Array(30 - players).keys()].map(num => +num + +players + (inequality == '>=' ? +0 : +1))).some(playerCount => playerCount in (MafiaData[searchType][key]))); } else { - return this.errorReply(`Please ensure the amount of players is numeric.`); + return entries; // this.errorReply(`Please ensure the amount of players is numeric.`); } } else if ((searchType == `roles`) && toID(searchTarget) in MafiaData[`themes`]) { @@ -4136,9 +4145,12 @@ export const commands: Chat.ChatCommands = { if (!hidden) entries = entries.filter(([key, data]) => !MafiaData[searchType][key][`tags`].includes(`hidden`)); for (let i = 0; i < targets.length; i++) { - entries = targets[i].split('|').map(x => x.trim()).map(searchTerm => search(entries.slice(), searchTerm)).reduce((aggregate, result) => [...new Set([...aggregate, ...result])]); + entries = targets[i].split('|').map(x => x.trim()).map(searchTerm => search.call(this, entries.slice(), searchTerm)).reduce((aggregate, result) => [...new Set([...aggregate, ...result])]); } + console.log(typeof(entries)); + if(typeof(entries) == 'undefined') return; //Hotpatch + if (random) entries = shuffle(entries); if (number > 0) entries = entries.slice(0, number) diff --git a/server/chat-plugins/scavengers.ts b/server/chat-plugins/scavengers.ts index ece8db2d7861..d90fd55c77fe 100644 --- a/server/chat-plugins/scavengers.ts +++ b/server/chat-plugins/scavengers.ts @@ -17,6 +17,7 @@ type GameTypes = 'official' | 'regular' | 'mini' | 'unrated' | 'practice' | 'rec export interface QueuedHunt { hosts: {id: string, name: string, noUpdate?: boolean}[]; questions: (string | string[])[]; + isHTML: boolean; staffHostId: string; staffHostName: string; gameType: GameTypes; @@ -226,7 +227,7 @@ function formatQueue(queue: QueuedHunt[] | undefined, viewer: User, room: Room, return Utils.html`[${q.join(' / ')}]
`; } else { q = q as string; - return Utils.escapeHTML(q); + return item.isHTML ? q : Utils.escapeHTML(q); } } ).join(" "); @@ -327,6 +328,7 @@ export class ScavengerHunt extends Rooms.RoomGame { completed: AnyObject[]; leftHunt: {[userid: string]: 1 | undefined}; hosts: FakeUser[]; + isHTML: boolean; modsList: string[]; mods: {[k: string]: ModEvent[]}; staffHostId: string; @@ -344,6 +346,7 @@ export class ScavengerHunt extends Rooms.RoomGame { hosts: FakeUser[], gameType: GameTypes, questions: (string | string[])[], + isHTML? : boolean, mod?: string | string[] ) { super(room); @@ -362,6 +365,8 @@ export class ScavengerHunt extends Rooms.RoomGame { this.hosts = hosts; + this.isHTML = isHTML ? isHTML : false; + this.modsList = []; this.mods = {}; @@ -443,8 +448,8 @@ export class ScavengerHunt extends Rooms.RoomGame { const huntType = `${article} ${newHunt ? 'new ' : ''}${this.gameType}`; return `|raw|
${huntType} scavenger hunt by ${hosts} has been started${staffHost}.` + - `
` + - `Hint #1: ${Chat.formatText(this.questions[0].hint)}` + + `
` + + `Hint #1: ${this.isHTML ? this.questions[0].hint : Chat.formatText(this.questions[0].hint)}` + `
` + `(To answer, use /scavenge ANSWER)
`; } @@ -617,7 +622,7 @@ export class ScavengerHunt extends Rooms.RoomGame { return `|raw|
` + `` + ``; } - let template = `
${finalHint}Hint #${current.number}:${ - Chat.formatText(current.question.hint) + + this.isHTML ? current.question.hint : Chat.formatText(current.question.hint) + (showHints && current.question.spoilers.length ? `
Extra Hints:${ current.question.spoilers.map(p => `- ${p}`).join('
') @@ -660,7 +665,7 @@ export class ScavengerHunt extends Rooms.RoomGame { `
${ i + 1 }${ - Chat.formatText(q.hint) + + this.isHTML ? q.hint : Chat.formatText(q.hint) + (q.spoilers.length ? `
Extra Hints:${ q.spoilers.map(s => `- ${s}`).join('
') @@ -711,7 +716,7 @@ export class ScavengerHunt extends Rooms.RoomGame { `${this.completed.slice(0, sliceIndex).map((p, i) => `${Utils.formatOrder(i + 1)} place: ${Utils.escapeHTML(p.name)} [${p.time}].
`).join("")}` + `${this.completed.length > sliceIndex ? `Consolation Prize: ${this.completed.slice(sliceIndex).map(e => `${Utils.escapeHTML(e.name)} [${e.time}]`).join(', ')}
` : ''}
` + `
Solution:
` + - `${this.questions.map((q, i) => `${i + 1}) ${Chat.formatText(q.hint)} [${Utils.escapeHTML(q.answer.join(' / '))}]`).join("
")}` + + `${this.questions.map((q, i) => `${i + 1}) ${this.isHTML ? q.hint : Chat.formatText(q.hint)} [${Utils.escapeHTML(q.answer.join(' / '))}]`).join("
")}` + `
` ); } @@ -1016,7 +1021,7 @@ export class ScavengerHuntPlayer extends Rooms.RoomGamePlayer { onNotifyChange(num: number) { this.game.runEvent('NotifyChange', this, num); if (num === this.currentQuestion) { - this.sendRoom(`|raw|The hint has been changed to: ${Chat.formatText(this.game.questions[num].hint)}`); + this.sendRoom(`|raw|The hint has been changed to: ${this.game.isHTML ? this.game.questions[num].hint : Chat.formatText(this.game.questions[num].hint)}`); } } @@ -1339,6 +1344,20 @@ const ScavengerCommands: Chat.ChatCommands = { forcecreate: 'create', forcecreateunrated: 'create', createrecycled: 'create', + + createhtmltwist: 'create', + createhtmltwistofficial: 'create', + createhtmltwistmini: 'create', + createhtmltwistpractice: 'create', + createhtmltwistunrated: 'create', + createhtmlpractice: 'create', + createhtmlofficial: 'create', + createhtmlunrated: 'create', + createhtmlmini: 'create', + forcecreatehtml: 'create', + forcecreatehtmlunrated: 'create', + createhtmlrecycled: 'create', + createhtml: 'create', create(target, room, user, connection, cmd) { room = this.requireRoom(); if (!getScavsRoom(room)) { @@ -1359,6 +1378,8 @@ const ScavengerCommands: Chat.ChatCommands = { gameType = 'recycled'; } + let isHTML = cmd.includes('html'); + let mod; let questions = target; @@ -1410,7 +1431,7 @@ const ScavengerCommands: Chat.ChatCommands = { const res = ScavengerHunt.parseQuestions(params); if (res.err) return this.errorReply(res.err); - room.game = new ScavengerHunt(room, user, hosts, gameType, res.result, mod); + room.game = new ScavengerHunt(room, user, hosts, gameType, res.result, isHTML, mod); this.privateModAction(`A new scavenger hunt was created by ${user.name}.`); this.modlog('SCAV NEW', null, `${gameType.toUpperCase()}: creators - ${hosts.map(h => h.id)}`); @@ -1526,6 +1547,7 @@ const ScavengerCommands: Chat.ChatCommands = { const hunt: QueuedHunt = { hosts: game.hosts, questions: [], + isHTML: game.isHTML, staffHostId: game.staffHostId, staffHostName: game.StaffHostName, gameType: game.gameType, @@ -1699,6 +1721,10 @@ const ScavengerCommands: Chat.ChatCommands = { queueunrated: 'queue', queuerated: 'queue', queuerecycled: 'queue', + queuehtmlunrated: 'queue', + queuehtmlrated: 'queue', + queuehtmlrecycled: 'queue', + queuehtml: 'queue', queue(target, room, user) { room = this.requireRoom(); if (!getScavsRoom(room)) { @@ -1714,6 +1740,8 @@ const ScavengerCommands: Chat.ChatCommands = { return this.parse('/scavhelp staff'); } + let isHTML = this.cmd.includes('html'); + this.checkCan('mute', null, room); if (this.cmd === 'queuerecycled') { @@ -1736,6 +1764,7 @@ const ScavengerCommands: Chat.ChatCommands = { room.settings.scavQueue.push({ hosts: next.hosts, questions: correctlyFormattedQuestions, + isHTML: this.cmd.includes('html'), staffHostId: 'scavengermanager', staffHostName: 'Scavenger Manager', gameType: 'unrated', @@ -1755,6 +1784,7 @@ const ScavengerCommands: Chat.ChatCommands = { room.settings.scavQueue.push({ hosts: hosts, questions: results.result, + isHTML: isHTML, staffHostId: user.id, staffHostName: user.name, gameType: (this.cmd.includes('unrated') ? 'unrated' : 'regular'), @@ -1815,7 +1845,8 @@ const ScavengerCommands: Chat.ChatCommands = { {id: next.staffHostId, name: next.staffHostName}, next.hosts, next.gameType, - next.questions + next.questions, + next.isHTML ); if (huntId) this.sendReply(`|uhtmlchange|scav-queue|${formatQueue(room.settings.scavQueue, user, room)}`); @@ -2515,6 +2546,23 @@ export const commands: Chat.ChatCommands = { forcestartunrated: 'starthunt', forcestartpractice: 'starthunt', + starthtmlpracticehunt: 'starthunt', + starthtmlofficialhunt: 'starthunt', + starthtmlminihunt: 'starthunt', + starthtmlunratedhunt: 'starthunt', + starthtmlrecycledhunt: 'starthunt', + starthtmltwisthunt: 'starthunt', + starthtmltwistofficial: 'starthunt', + starthtmltwistpractice: 'starthunt', + starthtmltwistmini: 'starthunt', + starthtmltwistunrated: 'starthunt', + + forcehtmlstarthunt: 'starthunt', + forcehtmlstartunrated: 'starthunt', + forcehtmlstartpractice: 'starthunt', + + starthtmlhunt: 'starthunt', + starthunt: ScavengerCommands.create, joinhunt: ScavengerCommands.join, leavehunt: ScavengerCommands.leave, From e0ea6f161f2382104165a4065243116bcb3acaaa Mon Sep 17 00:00:00 2001 From: "Meijer,L. (Lucas)" Date: Thu, 11 Jul 2024 20:20:35 +0200 Subject: [PATCH 08/19] Scavengers fix image scroll --- server/chat-plugins/scavengers.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/server/chat-plugins/scavengers.ts b/server/chat-plugins/scavengers.ts index d90fd55c77fe..51c9541b766b 100644 --- a/server/chat-plugins/scavengers.ts +++ b/server/chat-plugins/scavengers.ts @@ -239,7 +239,7 @@ function formatQueue(queue: QueuedHunt[] | undefined, viewer: User, room: Room, } else { buffer = `
The scavenger queue is currently empty.
${showStaff ? buffer : buffer.replace(/.+?<\/button>/gi, '')}
ByQuestions
`; + let template = `
${showStaff ? buffer : buffer.replace(/.+?<\/button>/gi, '')}
ByQuestions
`; if (showStaff) { template += `
Auto Timer Duration: ${timerDuration} minutesAuto Dequeue: