{ "version": 3, "sources": ["../../../../server/chat-commands/room-settings.ts"], "sourcesContent": ["/**\r\n * Room settings commands\r\n * Pokemon Showdown - http://pokemonshowdown.com/\r\n *\r\n * Commands for settings relating to room setting filtering.\r\n *\r\n * @license MIT\r\n */\r\nimport {Utils} from '../../lib';\r\nimport type {EffectiveGroupSymbol, RoomPermission} from '../user-groups';\r\n\r\nconst RANKS = Config.groupsranking;\r\n\r\nconst SLOWCHAT_MINIMUM = 2;\r\nconst SLOWCHAT_MAXIMUM = 60;\r\nconst SLOWCHAT_USER_REQUIREMENT = 10;\r\n\r\nexport const sections = [\r\n\t'official', 'battleformats', 'languages', 'entertainment', 'gaming', 'lifehobbies', 'onsitegames',\r\n] as const;\r\n\r\nexport type RoomSection = typeof sections[number];\r\n\r\nexport const RoomSections: {sectionNames: {[k in RoomSection]: string}, sections: readonly RoomSection[]} = {\r\n\tsectionNames: {\r\n\t\tofficial: 'Official',\r\n\t\tbattleformats: 'Battle formats',\r\n\t\tlanguages: 'Languages',\r\n\t\tentertainment: 'Entertainment',\r\n\t\tgaming: 'Gaming',\r\n\t\tlifehobbies: 'Life & hobbies',\r\n\t\tonsitegames: 'On-site games',\r\n\t},\r\n\tsections,\r\n};\r\n\r\nexport const commands: Chat.ChatCommands = {\r\n\troomsetting: 'roomsettings',\r\n\troomsettings(target, room, user, connection) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (room.battle) return this.errorReply(\"This command cannot be used in battle rooms.\");\r\n\t\tlet uhtml = 'uhtml';\r\n\r\n\t\tif (!target) {\r\n\t\t\troom.update();\r\n\t\t} else {\r\n\t\t\tvoid this.parse(`/${target}`);\r\n\t\t\tuhtml = 'uhtmlchange';\r\n\t\t}\r\n\r\n\t\tlet output = Utils.html`
Room Settings for ${room.title}
`;\r\n\t\tfor (const handler of Chat.roomSettings) {\r\n\t\t\tconst setting = handler(room, user, connection);\r\n\t\t\tif (typeof setting.permission === 'string') setting.permission = user.can(setting.permission, null, room);\r\n\r\n\t\t\toutput += `${setting.label}:
`;\r\n\r\n\t\t\tfor (const option of setting.options) {\r\n\t\t\t\t// disabled button\r\n\t\t\t\tif (option[1] === true) {\r\n\t\t\t\t\toutput += Utils.html` `;\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// only show proper buttons if we have the permissions to use them\r\n\t\t\t\t\tif (!setting.permission) continue;\r\n\r\n\t\t\t\t\toutput += Utils.html` `;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\toutput += `
`;\r\n\t\t}\r\n\t\toutput += '
';\r\n\t\tuser.sendTo(room, `|${uhtml}|roomsettings|${output}`);\r\n\t},\r\n\troomsettingshelp: [`/roomsettings - Shows current room settings with buttons to change them (if you can).`],\r\n\r\n\tmodchat(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst modchatSetting = (room.settings.modchat || \"OFF\");\r\n\t\t\treturn this.sendReply(`Moderated chat is currently set to: ${modchatSetting}`);\r\n\t\t}\r\n\t\tif (user.locked) { // would put this below but it behaves weird if there's no modchat set\r\n\t\t\treturn this.errorReply(`/modchat - Access denied.`);\r\n\t\t} else {\r\n\t\t\tthis.checkCan('modchat', null, room);\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\troom.settings.modchat && room.settings.modchat.length <= 1 &&\r\n\t\t\t!room.auth.atLeast(user, room.settings.modchat) &&\r\n\t\t\t// Upper Staff should probably be able to set /modchat & in secret rooms\r\n\t\t\t!user.can('bypassall')\r\n\t\t) {\r\n\t\t\treturn this.errorReply(`/modchat - Access denied for changing a setting currently at ${room.settings.modchat}.`);\r\n\t\t}\r\n\t\tif ((room as any).requestModchat) {\r\n\t\t\tconst error = (room as GameRoom).requestModchat(user);\r\n\t\t\tif (error) return this.errorReply(error);\r\n\t\t}\r\n\r\n\t\t// only admins can force modchat on a forced public battle\r\n\t\tif (room.battle?.forcedSettings.modchat && !user.can('rangeban')) {\r\n\t\t\treturn this.errorReply(\r\n\t\t\t\t`This battle is required to have modchat on due to one of the players having a username that starts with ` +\r\n\t\t\t\t`${room.battle.forcedSettings.modchat}.`\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\ttarget = target.toLowerCase().trim();\r\n\t\tconst currentModchat = room.settings.modchat;\r\n\t\tswitch (target) {\r\n\t\tcase 'off':\r\n\t\tcase 'false':\r\n\t\tcase 'no':\r\n\t\tcase 'disable':\r\n\t\t\troom.settings.modchat = null;\r\n\t\t\tbreak;\r\n\t\tcase 'ac':\r\n\t\tcase 'autoconfirmed':\r\n\t\t\troom.settings.modchat = 'autoconfirmed';\r\n\t\t\tbreak;\r\n\t\tcase 'trusted':\r\n\t\t\troom.settings.modchat = 'trusted';\r\n\t\t\tbreak;\r\n\t\tcase 'player':\r\n\t\t\ttarget = Users.PLAYER_SYMBOL;\r\n\t\t\t/* falls through */\r\n\t\tdefault:\r\n\t\t\tif (!Users.Auth.isAuthLevel(target) || ['\u203D', '!'].includes(target)) {\r\n\t\t\t\tthis.errorReply(`The rank '${target}' was unrecognized as a modchat level.`);\r\n\t\t\t\treturn this.parse('/help modchat');\r\n\t\t\t}\r\n\t\t\t// Users shouldn't be able to set modchat above their own rank (except for ROs who are also Upper Staff)\r\n\t\t\tconst modchatLevelHigherThanUserRank = !room.auth.atLeast(user, target) && !user.can('bypassall');\r\n\t\t\tif (modchatLevelHigherThanUserRank || !Users.Auth.hasPermission(user, 'modchat', target as GroupSymbol, room)) {\r\n\t\t\t\treturn this.errorReply(`/modchat - Access denied for setting to ${target}.`);\r\n\t\t\t}\r\n\t\t\troom.settings.modchat = target;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (currentModchat === room.settings.modchat) {\r\n\t\t\treturn this.errorReply(`Modchat is already set to ${currentModchat || 'off'}.`);\r\n\t\t}\r\n\t\tif (!room.settings.modchat) {\r\n\t\t\tthis.add(\"|raw|
Moderated chat was disabled!
Anyone may talk now.
\");\r\n\t\t} else {\r\n\t\t\tconst modchatSetting = Utils.escapeHTML(room.settings.modchat);\r\n\t\t\tthis.add(`|raw|
Moderated chat was set to ${modchatSetting}!
Only users of rank ${modchatSetting} and higher can talk.
`);\r\n\t\t}\r\n\t\tif ((room as GameRoom).requestModchat && !room.settings.modchat) (room as GameRoom).requestModchat(null);\r\n\t\tthis.privateModAction(`${user.name} set modchat to ${room.settings.modchat || \"off\"}`);\r\n\t\tthis.modlog('MODCHAT', null, `to ${room.settings.modchat || \"false\"}`);\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\tmodchathelp: [\r\n\t\t`/modchat [off/autoconfirmed/trusted/+/%/@/*/player/#/&] - Set the level of moderated chat. Requires: % \\u2606 for off/autoconfirmed/+ options, * @ # & for all the options`,\r\n\t],\r\n\r\n\tautomodchat(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tif (!room.settings.autoModchat) return this.sendReply(`This room has automodchat OFF.`);\r\n\t\t\tconst {rank: curRank, time: curTime} = room.settings.autoModchat;\r\n\t\t\treturn this.sendReply(`Automodchat is currently set to set modchat to ${curRank} after ${curTime} minutes.`);\r\n\t\t}\r\n\t\tthis.checkCan('declare', null, room);\r\n\t\tif (this.meansNo(toID(target))) {\r\n\t\t\tif (!room.settings.autoModchat) return this.errorReply(`Auto modchat is not set.`);\r\n\t\t\tdelete room.settings.autoModchat;\r\n\t\t\troom.saveSettings();\r\n\t\t\tif (room.modchatTimer) clearTimeout(room.modchatTimer); // fallback just in case (should never happen)\r\n\t\t\tthis.privateModAction(`${user.name} turned off automatic modchat.`);\r\n\t\t\treturn this.modlog(`AUTOMODCHAT`, null, 'OFF');\r\n\t\t}\r\n\t\tlet [rawTime, rank] = Utils.splitFirst(target, ',').map(i => i.trim()) as [string, GroupSymbol];\r\n\t\tif (!rawTime) {\r\n\t\t\treturn this.parse(`/help automodchat`);\r\n\t\t}\r\n\t\tif (!rank) {\r\n\t\t\tif (room.settings.autoModchat) {\r\n\t\t\t\trank = room.settings.autoModchat.rank;\r\n\t\t\t} else {\r\n\t\t\t\treturn this.parse(`/help automodchat`);\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst validGroups = [...Config.groupsranking as string[], 'trusted'];\r\n\t\tif (!validGroups.includes(rank)) {\r\n\t\t\treturn this.errorReply(`Invalid rank.`);\r\n\t\t}\r\n\t\tconst time = parseInt(rawTime);\r\n\t\tif (isNaN(time) || time > 480 || time < 5) {\r\n\t\t\treturn this.errorReply(\"Invalid duration. Choose a number under 480 (in minutes) and over 5 minutes.\");\r\n\t\t}\r\n\t\troom.settings.autoModchat = {\r\n\t\t\trank, time, active: false,\r\n\t\t};\r\n\t\tthis.privateModAction(`${user.name} set automodchat to rank ${rank} and timeout ${time} minutes.`);\r\n\t\tthis.modlog(`AUTOMODCHAT`, null, `${rank}: ${time} minutes`);\r\n\t\troom.saveSettings();\r\n\t},\r\n\tautomodchathelp: [\r\n\t\t`/automodchat [number], [rank] - Sets modchat [rank] to automatically turn on after [number] minutes with no staff.`,\r\n\t\t`[number] must be between 5 and 480. Requires: # &`,\r\n\t\t`/automodchat off - Turns off automodchat.`,\r\n\t],\r\n\r\n\tionext() {\r\n\t\tthis.errorReply(`\"ionext\" is an outdated feature. Hidden battles now have password-protected URLs, making them fully secure against eavesdroppers.`);\r\n\t\tthis.errorReply(`You probably want to switch from /ionext to /hidenext, and from /ioo to /hideroom`);\r\n\t},\r\n\tioo() {\r\n\t\tthis.errorReply(`\"ioo\" is an outdated feature. Hidden battles now have password-protected URLs, making them fully secure against eavesdroppers.`);\r\n\t\tthis.errorReply(`You probably want to switch from /ioo to /hideroom`);\r\n\t},\r\n\r\n\tinviteonlynext(target, room, user) {\r\n\t\tconst groupConfig = Config.groups[Users.PLAYER_SYMBOL];\r\n\t\tif (!groupConfig?.editprivacy) return this.errorReply(`/ionext - Access denied.`);\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tuser.battleSettings.inviteOnly = false;\r\n\t\t\tuser.update();\r\n\t\t\tthis.sendReply(\"Your next battle will be publicly visible.\");\r\n\t\t} else {\r\n\t\t\tuser.battleSettings.inviteOnly = true;\r\n\t\t\tuser.update();\r\n\t\t\tthis.sendReply(`Your next battle will be invite-only${Rooms.RoomBattle.battleForcedSetting(user, 'privacy') ? `, unless it is rated` : ``}.`);\r\n\t\t}\r\n\t},\r\n\tinviteonlynexthelp: [\r\n\t\t`/inviteonlynext - Sets your next battle to be invite-only.`,\r\n\t\t`/inviteonlynext off - Sets your next battle to be publicly visible.`,\r\n\t],\r\n\r\n\tinviteonly(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) return this.parse('/help inviteonly');\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\treturn this.parse(\"/modjoin %\");\r\n\t\t} else {\r\n\t\t\treturn this.parse(`/modjoin ${target}`);\r\n\t\t}\r\n\t},\r\n\tinviteonlyhelp: [\r\n\t\t`/inviteonly [on|off] - Sets modjoin %. Users can't join unless invited with /invite. Requires: # &`,\r\n\t\t`/ioo - Shortcut for /inviteonly on`,\r\n\t\t`/inviteonlynext OR /ionext - Sets your next battle to be invite-only.`,\r\n\t\t`/ionext off - Sets your next battle to be publicly visible.`,\r\n\t],\r\n\r\n\tmodjoin(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst modjoinSetting = room.settings.modjoin === true ? \"SYNC\" : room.settings.modjoin || \"OFF\";\r\n\t\t\treturn this.sendReply(`Modjoin is currently set to: ${modjoinSetting}`);\r\n\t\t}\r\n\t\tif (room.battle) {\r\n\t\t\tthis.checkCan('editprivacy', null, room);\r\n\t\t\tif (room.battle.forcedSettings.privacy) {\r\n\t\t\t\treturn this.errorReply(\r\n\t\t\t\t\t`This battle is required to be public due to a player having a name prefixed by '${room.battle.forcedSettings.privacy}'.`\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tif (room.battle.inviteOnlySetter && !user.can('mute', null, room) && room.battle.inviteOnlySetter !== user.id) {\r\n\t\t\t\treturn this.errorReply(`Only the person who set this battle to be invite-only can turn it off.`);\r\n\t\t\t}\r\n\t\t\troom.battle.inviteOnlySetter = user.id;\r\n\t\t} else if (room.settings.isPersonal) {\r\n\t\t\tthis.checkCan('editroom', null, room);\r\n\t\t} else {\r\n\t\t\tthis.checkCan('makeroom');\r\n\t\t}\r\n\t\tif (room.tour && !room.tour.allowModjoin) {\r\n\t\t\treturn this.errorReply(`You can't do this in tournaments where modjoin is prohibited.`);\r\n\t\t}\r\n\t\tif (target === 'player') target = Users.PLAYER_SYMBOL;\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.modjoin) return this.errorReply(`Modjoin is already turned off in this room.`);\r\n\t\t\troom.settings.modjoin = null;\r\n\t\t\tthis.add(`|raw|
This room is no longer invite only!
Anyone may now join.
`);\r\n\t\t\tthis.addModAction(`${user.name} turned off modjoin.`);\r\n\t\t\tthis.modlog('MODJOIN', null, 'OFF');\r\n\t\t\tif (room.battle) room.battle.inviteOnlySetter = null;\r\n\t\t\troom.saveSettings();\r\n\t\t\treturn;\r\n\t\t} else if (target === 'sync') {\r\n\t\t\tif (room.settings.modjoin === true) return this.errorReply(`Modjoin is already set to sync modchat in this room.`);\r\n\t\t\troom.settings.modjoin = true;\r\n\t\t\tthis.add(`|raw|
Moderated join is set to sync with modchat!
Only users who can speak in modchat can join.
`);\r\n\t\t\tthis.addModAction(`${user.name} set modjoin to sync with modchat.`);\r\n\t\t\tthis.modlog('MODJOIN SYNC');\r\n\t\t} else if (target === 'ac' || target === 'autoconfirmed') {\r\n\t\t\tif (room.settings.modjoin === 'autoconfirmed') return this.errorReply(`Modjoin is already set to autoconfirmed.`);\r\n\t\t\troom.settings.modjoin = 'autoconfirmed';\r\n\t\t\tthis.add(`|raw|
Moderated join is set to autoconfirmed!
Users must be rank autoconfirmed or invited with /invite to join
`);\r\n\t\t\tthis.addModAction(`${user.name} set modjoin to autoconfirmed.`);\r\n\t\t\tthis.modlog('MODJOIN', null, 'autoconfirmed');\r\n\t\t} else if (Users.Auth.isAuthLevel(target) && !['\u203D', '!'].includes(target)) {\r\n\t\t\tif (room.battle && !user.can('makeroom') && !'+%'.includes(target)) {\r\n\t\t\t\treturn this.errorReply(`/modjoin - Access denied from setting modjoin past % in battles.`);\r\n\t\t\t}\r\n\t\t\tif (room.settings.isPersonal && !user.can('makeroom') && !'+%'.includes(target)) {\r\n\t\t\t\treturn this.errorReply(`/modjoin - Access denied from setting modjoin past % in group chats.`);\r\n\t\t\t}\r\n\t\t\tif (room.settings.modjoin === target) return this.errorReply(`Modjoin is already set to ${target} in this room.`);\r\n\t\t\troom.settings.modjoin = target;\r\n\t\t\tthis.add(`|raw|
This room is now invite only!
Users must be rank ${target} or invited with /invite to join
`);\r\n\t\t\tthis.addModAction(`${user.name} set modjoin to ${target}.`);\r\n\t\t\tthis.modlog('MODJOIN', null, target);\r\n\t\t} else {\r\n\t\t\tthis.errorReply(`Unrecognized modjoin setting.`);\r\n\t\t\tvoid this.parse('/help modjoin');\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\troom.saveSettings();\r\n\t\tif (target === 'sync' && !room.settings.modchat) {\r\n\t\t\tconst lowestGroup = Config.groupsranking.filter(group => {\r\n\t\t\t\tconst groupInfo = Users.Auth.getGroup(group);\r\n\t\t\t\treturn (\r\n\t\t\t\t\tgroupInfo.symbol !== Users.Auth.defaultSymbol() &&\r\n\t\t\t\t\troom!.auth.atLeast(user, group) &&\r\n\t\t\t\t\tUsers.Auth.isValidSymbol(groupInfo.symbol)\r\n\t\t\t\t);\r\n\t\t\t})[0];\r\n\t\t\tif (lowestGroup) void this.parse(`/modchat ${lowestGroup}`);\r\n\t\t}\r\n\t\tif (!room.settings.isPrivate) return this.parse('/hiddenroom');\r\n\t},\r\n\tmodjoinhelp: [\r\n\t\t`/modjoin [+|%|@|*|player|&|#|off] - Sets modjoin. Users lower than the specified rank can't join this room unless they have a room rank. Requires: \\u2606 # &`,\r\n\t\t`/modjoin [sync|off] - Sets modjoin. Only users who can speak in modchat can join this room. Requires: \\u2606 # &`,\r\n\t],\r\n\r\n\troomlanguage(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\treturn this.sendReply(`This room's primary language is ${Chat.languages.get(room.settings.language || '') || 'English'}`);\r\n\t\t}\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tconst targetLanguage = toID(target);\r\n\t\tif (!Chat.languages.has(targetLanguage)) return this.errorReply(`\"${target}\" is not a supported language.`);\r\n\r\n\t\troom.settings.language = targetLanguage === 'english' ? false : targetLanguage;\r\n\r\n\t\troom.saveSettings();\r\n\t\tthis.modlog(`LANGUAGE`, null, Chat.languages.get(targetLanguage));\r\n\t\tthis.sendReply(`The room's language has been set to ${Chat.languages.get(targetLanguage)}`);\r\n\t},\r\n\troomlanguagehelp: [\r\n\t\t`/roomlanguage [language] - Sets the the language for the room, which changes language of a few commands. Requires # &`,\r\n\t\t`Supported Languages: English, Spanish, Italian, French, Simplified Chinese, Traditional Chinese, Japanese, Hindi, Turkish, Dutch, German.`,\r\n\t],\r\n\r\n\tslowchat(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst slowchatSetting = (room.settings.slowchat || \"OFF\");\r\n\t\t\treturn this.sendReply(`Slow chat is currently set to: ${slowchatSetting}`);\r\n\t\t}\r\n\t\tthis.checkChat();\r\n\t\tthis.checkCan('modchat', null, room);\r\n\r\n\t\tlet targetInt = parseInt(target);\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.slowchat) return this.errorReply(`Slow chat is already disabled in this room.`);\r\n\t\t\troom.settings.slowchat = false;\r\n\t\t} else if (targetInt) {\r\n\t\t\tif (!user.can('bypassall') && room.userCount < SLOWCHAT_USER_REQUIREMENT) {\r\n\t\t\t\treturn this.errorReply(`This room must have at least ${SLOWCHAT_USER_REQUIREMENT} users to set slowchat; it only has ${room.userCount} right now.`);\r\n\t\t\t}\r\n\t\t\tif (room.settings.slowchat === targetInt) {\r\n\t\t\t\treturn this.errorReply(`Slow chat is already set to ${room.settings.slowchat} seconds in this room.`);\r\n\t\t\t}\r\n\t\t\tif (targetInt < SLOWCHAT_MINIMUM) targetInt = SLOWCHAT_MINIMUM;\r\n\t\t\tif (targetInt > SLOWCHAT_MAXIMUM) targetInt = SLOWCHAT_MAXIMUM;\r\n\t\t\troom.settings.slowchat = targetInt;\r\n\t\t} else {\r\n\t\t\treturn this.parse(\"/help slowchat\");\r\n\t\t}\r\n\t\tconst slowchatSetting = (room.settings.slowchat || \"OFF\");\r\n\t\tthis.privateModAction(`${user.name} set slowchat to ${slowchatSetting}`);\r\n\t\tthis.modlog('SLOWCHAT', null, '' + slowchatSetting);\r\n\t\troom.saveSettings();\r\n\t},\r\n\tslowchathelp: [\r\n\t\t`/slowchat [number] - Sets a limit on how often users in the room can send messages, between 2 and 60 seconds. Requires @ # &`,\r\n\t\t`/slowchat off - Disables slowchat in the room. Requires @ # &`,\r\n\t],\r\n\tpermission: 'permissions',\r\n\tpermissions: {\r\n\t\tclear: 'set',\r\n\t\tset(target, room, user) {\r\n\t\t\tlet [perm, rank] = this.splitOne(target);\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (rank === 'default') rank = '';\r\n\t\t\tif (!room.persist) return this.errorReply(`This room does not allow customizing permissions.`);\r\n\t\t\tif (!target || !perm) return this.parse(`/permissions help`);\r\n\t\t\tif (rank && rank !== 'whitelist' && !Config.groupsranking.includes(rank as EffectiveGroupSymbol)) {\r\n\t\t\t\treturn this.errorReply(`${rank} is not a valid rank.`);\r\n\t\t\t}\r\n\t\t\tconst validPerms = Users.Auth.supportedRoomPermissions(room);\r\n\t\t\tif (!validPerms.some(p => p === perm || p.startsWith(`${perm} `))) {\r\n\t\t\t\treturn this.errorReply(`${perm} is not a valid room permission.`);\r\n\t\t\t}\r\n\t\t\tif (!room.auth.atLeast(user, '#')) {\r\n\t\t\t\treturn this.errorReply(`/permissions set - You must be at least a Room Owner to set permissions.`);\r\n\t\t\t}\r\n\t\t\tif (\r\n\t\t\t\tUsers.Auth.ROOM_PERMISSIONS.includes(perm as RoomPermission) &&\r\n\t\t\t\t!Users.Auth.hasPermission(user, perm, null, room)\r\n\t\t\t) {\r\n\t\t\t\treturn this.errorReply(`/permissions set - You can't set the permission \"${perm}\" because you don't have it.`);\r\n\t\t\t}\r\n\r\n\t\t\tconst currentPermissions = room.settings.permissions || {};\r\n\t\t\tif (currentPermissions[perm] === (rank || undefined)) {\r\n\t\t\t\treturn this.errorReply(`${perm} is already set to ${rank || 'default'}.`);\r\n\t\t\t}\r\n\r\n\t\t\tif (rank) {\r\n\t\t\t\tcurrentPermissions[perm] = rank as GroupSymbol;\r\n\t\t\t\troom.settings.permissions = currentPermissions;\r\n\t\t\t} else {\r\n\t\t\t\tdelete currentPermissions[perm];\r\n\t\t\t\tif (!Object.keys(currentPermissions).length) delete room.settings.permissions;\r\n\t\t\t}\r\n\t\t\troom.saveSettings();\r\n\r\n\t\t\tif (!rank) rank = `default`;\r\n\t\t\tthis.modlog(`SETPERMISSION`, null, `${perm}: ${rank}`);\r\n\t\t\tthis.refreshPage(`permissions-${room.roomid}`);\r\n\t\t\treturn this.privateModAction(`${user.name} set the required rank for ${perm} to ${rank}.`);\r\n\t\t},\r\n\t\tsethelp: [\r\n\t\t\t`/permissions set [command], [rank symbol] - sets the required permission to use the command [command] to [rank]. Requires: # &`,\r\n\t\t\t`/permissions clear [command] - resets the required permission to use the command [command] to the default. Requires: # &`,\r\n\t\t],\r\n\t\tview(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\treturn this.parse(`/join view-permissions-${room.roomid}`);\r\n\t\t},\r\n\r\n\t\thelp: '',\r\n\t\t''(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\r\n\t\t\tconst allPermissions = Users.Auth.supportedRoomPermissions(room);\r\n\t\t\tconst permissionGroups = allPermissions.filter(perm => !perm.startsWith('/'));\r\n\t\t\tconst permissions = allPermissions.filter(perm => {\r\n\t\t\t\tconst handler = Chat.parseCommand(perm)?.handler;\r\n\t\t\t\tif (handler?.isPrivate && !user.can('lock')) return false;\r\n\t\t\t\treturn perm.startsWith('/') && !perm.includes(' ');\r\n\t\t\t});\r\n\t\t\tconst subPermissions = allPermissions.filter(perm => perm.startsWith('/') && perm.includes(' ')).filter(perm => {\r\n\t\t\t\tconst handler = Chat.parseCommand(perm)?.handler;\r\n\t\t\t\tif (handler?.isPrivate && !user.can('lock')) return false;\r\n\t\t\t\treturn perm.startsWith('/') && perm.includes(' ');\r\n\t\t\t});\r\n\t\t\tconst subPermissionsByNamespace: {[k: string]: string[]} = {};\r\n\t\t\tfor (const perm of subPermissions) {\r\n\t\t\t\tconst [namespace] = perm.split(' ', 1);\r\n\t\t\t\tif (!subPermissionsByNamespace[namespace]) subPermissionsByNamespace[namespace] = [];\r\n\t\t\t\tsubPermissionsByNamespace[namespace].push(perm);\r\n\t\t\t}\r\n\r\n\t\t\tlet buffer = `Room permissions help:
`;\r\n\t\t\tbuffer += `

Usage:
`;\r\n\t\t\tbuffer += `/permissions set [permission], [rank symbol]
`;\r\n\t\t\tbuffer += `/permissions clear [permission]
`;\r\n\t\t\tbuffer += `/permissions view

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

Group permissions: (will affect multiple commands or part of one command)
`;\r\n\t\t\tbuffer += `` + permissionGroups.join(` `) + `

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

Single-command permissions: (will affect one command)`;\r\n\t\t\tbuffer += `` + permissions.join(` `) + `

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

Sub-commands: (will affect one sub-command, like /roomevents view)`;\r\n\t\t\tfor (const subPerms of Object.values(subPermissionsByNamespace)) {\r\n\t\t\t\tbuffer += `
` + subPerms.join(` `) + `
`;\r\n\t\t\t}\r\n\t\t\tbuffer += `

`;\r\n\t\t\treturn this.sendReplyBox(buffer);\r\n\t\t},\r\n\t},\r\n\tstretching: 'stretchfilter',\r\n\tstretchingfilter: 'stretchfilter',\r\n\tstretchfilter(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst stretchSetting = (room.settings.filterStretching ? \"ON\" : \"OFF\");\r\n\t\t\treturn this.sendReply(`This room's stretch filter is currently: ${stretchSetting}`);\r\n\t\t}\r\n\t\tthis.checkChat();\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\tif (room.settings.filterStretching) return this.errorReply(`This room's stretch filter is already ON`);\r\n\t\t\troom.settings.filterStretching = true;\r\n\t\t} else if (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.filterStretching) return this.errorReply(`This room's stretch filter is already OFF`);\r\n\t\t\troom.settings.filterStretching = false;\r\n\t\t} else {\r\n\t\t\treturn this.parse(\"/help stretchfilter\");\r\n\t\t}\r\n\t\tconst stretchSetting = (room.settings.filterStretching ? \"ON\" : \"OFF\");\r\n\t\tthis.privateModAction(`${user.name} turned the stretch filter ${stretchSetting}`);\r\n\t\tthis.modlog('STRETCH FILTER', null, stretchSetting);\r\n\t\troom.saveSettings();\r\n\t},\r\n\tstretchfilterhelp: [\r\n\t\t`/stretchfilter [on/off] - Toggles filtering messages in the room for stretchingggggggg. Requires # &`,\r\n\t],\r\n\r\n\tcapitals: 'capsfilter',\r\n\tcapitalsfilter: 'capsfilter',\r\n\tcapsfilter(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst capsSetting = (room.settings.filterCaps ? \"ON\" : \"OFF\");\r\n\t\t\treturn this.sendReply(`This room's caps filter is currently: ${capsSetting}`);\r\n\t\t}\r\n\t\tthis.checkChat();\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\tif (room.settings.filterCaps) return this.errorReply(`This room's caps filter is already ON`);\r\n\t\t\troom.settings.filterCaps = true;\r\n\t\t} else if (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.filterCaps) return this.errorReply(`This room's caps filter is already OFF`);\r\n\t\t\troom.settings.filterCaps = false;\r\n\t\t} else {\r\n\t\t\treturn this.parse(\"/help capsfilter\");\r\n\t\t}\r\n\t\tconst capsSetting = (room.settings.filterCaps ? \"ON\" : \"OFF\");\r\n\t\tthis.privateModAction(`${user.name} turned the caps filter ${capsSetting}`);\r\n\t\tthis.modlog('CAPS FILTER', null, capsSetting);\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\tcapsfilterhelp: [`/capsfilter [on/off] - Toggles filtering messages in the room for EXCESSIVE CAPS. Requires # &`],\r\n\r\n\temojis: 'emojifilter',\r\n\temoji: 'emojifilter',\r\n\temojifilter(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tconst emojiSetting = (room.settings.filterEmojis ? \"ON\" : \"OFF\");\r\n\t\t\treturn this.sendReply(`This room's emoji filter is currently: ${emojiSetting}`);\r\n\t\t}\r\n\t\tthis.checkChat();\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\tif (room.settings.filterEmojis) return this.errorReply(`This room's emoji filter is already ON`);\r\n\t\t\troom.settings.filterEmojis = true;\r\n\t\t} else if (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.filterEmojis) return this.errorReply(`This room's emoji filter is already OFF`);\r\n\t\t\troom.settings.filterEmojis = false;\r\n\t\t} else {\r\n\t\t\treturn this.parse(\"/help emojifilter\");\r\n\t\t}\r\n\t\tconst emojiSetting = (room.settings.filterEmojis ? \"ON\" : \"OFF\");\r\n\t\tthis.privateModAction(`${user.name} turned the emoji filter ${emojiSetting}`);\r\n\t\tthis.modlog('EMOJI FILTER', null, emojiSetting);\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\temojifilterhelp: [`/emojifilter [on/off] - Toggles filtering messages in the room for emojis. Requires # &`],\r\n\r\n\tlinkfilter(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\treturn this.sendReply(\r\n\t\t\t\t`This room's link filter is currently: ${room.settings.filterEmojis ? \"ON\" : \"OFF\"}`\r\n\t\t\t);\r\n\t\t}\r\n\t\tthis.checkChat();\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\tif (room.settings.filterLinks) return this.errorReply(`This room's link filter is already ON`);\r\n\t\t\troom.settings.filterLinks = true;\r\n\t\t} else if (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.filterLinks) return this.errorReply(`This room's link filter is already OFF`);\r\n\t\t\troom.settings.filterLinks = false;\r\n\t\t} else {\r\n\t\t\treturn this.parse(\"/help linkfilter\");\r\n\t\t}\r\n\t\tconst setting = (room.settings.filterLinks ? \"ON\" : \"OFF\");\r\n\t\tthis.privateModAction(`${user.name} turned the link filter ${setting}`);\r\n\t\tthis.modlog('LINK FILTER', null, setting);\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\tlinkfilterhelp: [`/linkfilter [on/off] - Toggles filtering messages in the room for links. Requires # &`],\r\n\r\n\tbanwords: 'banword',\r\n\tbanword: {\r\n\t\tregexadd: 'add',\r\n\t\taddregex: 'add',\r\n\t\tadd(target, room, user, connection, cmd) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!target || target === ' ') return this.parse('/help banword');\r\n\t\t\tthis.checkCan('declare', null, room);\r\n\r\n\t\t\tconst regex = cmd.includes('regex');\r\n\t\t\tif (regex && !user.can('makeroom')) return this.errorReply(\"Regex banwords are only allowed for administrators.\");\r\n\t\t\tif (!room.settings.banwords) room.settings.banwords = [];\r\n\t\t\t// Most of the regex code is copied from the client. TODO: unify them?\r\n\t\t\t// Regex banwords can have commas in the {1,5} pattern\r\n\t\t\tlet words = (regex ? target.match(/[^,]+(,\\d*}[^,]*)?/g)! : target.split(','))\r\n\t\t\t\t.map(word => word.replace(/\\n/g, '').trim()).filter(word => word.length > 0);\r\n\t\t\tif (!words || words.length === 0) return this.parse('/help banword');\r\n\r\n\t\t\t// Escape any character with a special meaning in regex\r\n\t\t\tif (!regex) {\r\n\t\t\t\twords = words.map(word => {\r\n\t\t\t\t\tif (/[\\\\^$*+?()|{}[\\]]/.test(word) && user.can('rangeban')) {\r\n\t\t\t\t\t\tthis.errorReply(`\"${word}\" might be a regular expression, did you mean \"/banword addregex\"?`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn Utils.escapeRegex(word);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\t// PS adds a preamble to the banword regex that's 32 chars long\r\n\t\t\tlet banwordRegexLen = (room.banwordRegex instanceof RegExp) ? room.banwordRegex.source.length : 32;\r\n\t\t\tfor (const word of words) {\r\n\t\t\t\tChat.validateRegex(word);\r\n\t\t\t\tif (room.settings.banwords.includes(word)) return this.errorReply(`${word} is already a banned phrase.`);\r\n\r\n\t\t\t\t// Banword strings are joined, so account for the first string not having the prefix\r\n\t\t\t\tbanwordRegexLen += (banwordRegexLen === 32) ? word.length : `|${word}`.length;\r\n\t\t\t\t// RegExp instances whose source is greater than or equal to\r\n\t\t\t\t// v8's RegExpMacroAssembler::kMaxRegister in length will crash\r\n\t\t\t\t// the server on compile. In this case, that would happen each\r\n\t\t\t\t// time a chat message gets tested for any banned phrases.\r\n\t\t\t\tif (banwordRegexLen >= (1 << 16 - 1)) {\r\n\t\t\t\t\treturn this.errorReply(\"This room has too many banned phrases to add the ones given.\");\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tfor (const word of words) {\r\n\t\t\t\troom.settings.banwords.push(word);\r\n\t\t\t}\r\n\t\t\troom.banwordRegex = null;\r\n\t\t\tif (words.length > 1) {\r\n\t\t\t\tthis.privateModAction(`The banwords ${words.map(w => `'${w}'`).join(', ')} were added by ${user.name}.`);\r\n\t\t\t\tthis.modlog('BANWORD', null, words.map(w => `'${w}'`).join(', '));\r\n\t\t\t\tthis.sendReply(`Banned phrases successfully added.`);\r\n\t\t\t} else {\r\n\t\t\t\tthis.privateModAction(`The banword '${words[0]}' was added by ${user.name}.`);\r\n\t\t\t\tthis.modlog('BANWORD', null, words[0]);\r\n\t\t\t\tthis.sendReply(`Banned phrase successfully added.`);\r\n\t\t\t}\r\n\t\t\tthis.sendReply(`The list is currently: ${room.settings.banwords.join(', ')}`);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tdelete(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!target) return this.parse('/help banword');\r\n\t\t\tthis.checkCan('declare', null, room);\r\n\r\n\t\t\tif (!room.settings.banwords) return this.errorReply(\"This room has no banned phrases.\");\r\n\r\n\t\t\tconst regexMatch = target.match(/[^,]+(,\\d*}[^,]*)?/g);\r\n\t\t\tif (!regexMatch) return this.parse('/help banword');\r\n\r\n\t\t\tconst words = regexMatch.map(word => word.replace(/\\n/g, '').trim()).filter(word => word.length > 0);\r\n\r\n\t\t\tfor (const word of words) {\r\n\t\t\t\tif (!room.settings.banwords.includes(word)) return this.errorReply(`${word} is not a banned phrase in this room.`);\r\n\t\t\t}\r\n\r\n\t\t\troom.settings.banwords = room.settings.banwords.filter(w => !words.includes(w));\r\n\t\t\troom.banwordRegex = null;\r\n\t\t\tif (words.length > 1) {\r\n\t\t\t\tthis.privateModAction(`The banwords ${words.map(w => `'${w}'`).join(', ')} were removed by ${user.name}.`);\r\n\t\t\t\tthis.modlog('UNBANWORD', null, words.map(w => `'${w}'`).join(', '));\r\n\t\t\t\tthis.sendReply(`Banned phrases successfully deleted.`);\r\n\t\t\t} else {\r\n\t\t\t\tthis.privateModAction(`The banword '${words[0]}' was removed by ${user.name}.`);\r\n\t\t\t\tthis.modlog('UNBANWORD', null, words[0]);\r\n\t\t\t\tthis.sendReply(`Banned phrase successfully deleted.`);\r\n\t\t\t}\r\n\t\t\tif (!room.settings.banwords.length) room.settings.banwords = undefined;\r\n\t\t\tthis.sendReply(\r\n\t\t\t\troom.settings.banwords ?\r\n\t\t\t\t\t`The list is now: ${room.settings.banwords.join(', ')}` :\r\n\t\t\t\t\t`The list is now empty.`\r\n\t\t\t);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tlist(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\r\n\t\t\tif (!room.settings.banwords?.length) {\r\n\t\t\t\treturn this.sendReply(\"This room has no banned phrases.\");\r\n\t\t\t}\r\n\t\t\treturn this.sendReply(`Banned phrases in room ${room.roomid}: ${room.settings.banwords.join(', ')}`);\r\n\t\t},\r\n\r\n\t\t\"\"(target, room, user) {\r\n\t\t\treturn this.parse(\"/help banword\");\r\n\t\t},\r\n\t},\r\n\tbanwordhelp: [\r\n\t\t`/banword add [words] - Adds the comma-separated list of phrases to the banword list of the current room. Requires: # &`,\r\n\t\t`/banword addregex [words] - Adds the comma-separated list of regular expressions to the banword list of the current room. Requires &`,\r\n\t\t`/banword delete [words] - Removes the comma-separated list of phrases from the banword list. Requires: # &`,\r\n\t\t`/banword list - Shows the list of banned words in the current room. Requires: % @ # &`,\r\n\t],\r\n\r\n\tshowapprovals(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('declare', null, room);\r\n\t\ttarget = toID(target);\r\n\t\tif (!target) {\r\n\t\t\treturn this.sendReply(`Approvals are currently ${room.settings.requestShowEnabled ? `ENABLED` : `DISABLED`} for ${room}.`);\r\n\t\t}\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.requestShowEnabled) return this.errorReply(`Approvals are already disabled.`);\r\n\t\t\troom.settings.requestShowEnabled = undefined;\r\n\t\t\tthis.privateModAction(`${user.name} disabled approvals in this room.`);\r\n\t\t} else if (this.meansYes(target)) {\r\n\t\t\tif (room.settings.requestShowEnabled) return this.errorReply(`Approvals are already enabled.`);\r\n\t\t\troom.settings.requestShowEnabled = true;\r\n\t\t\tthis.privateModAction(`${user.name} enabled the use of media approvals in this room.`);\r\n\t\t\tif (!room.settings.permissions || room.settings.permissions['/show'] === '@') {\r\n\t\t\t\tthis.privateModAction(\r\n\t\t\t\t\t`Note: Due to this room's settings, Drivers aren't allowed to use /show directly, ` +\r\n\t\t\t\t\t`but will be able to request and approve each other's /requestshow`\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\treturn this.errorReply(`Unrecognized setting for approvals. Use 'on' or 'off'.`);\r\n\t\t}\r\n\t\troom.saveSettings();\r\n\t\treturn this.modlog(`SHOWAPPROVALS`, null, `${this.meansYes(target) ? `ON` : `OFF`}`);\r\n\t},\r\n\tshowapprovalshelp: [\r\n\t\t`/showapprovals [setting] - Enable or disable the use of media approvals in the current room.`,\r\n\t\t`Requires: # &`,\r\n\t],\r\n\r\n\tshowmedia(target, room, user) {\r\n\t\tthis.errorReply(`/showmedia has been deprecated. Use /permissions instead.`);\r\n\t\treturn this.parse(`/help permissions`);\r\n\t},\r\n\r\n\thightraffic(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\treturn this.sendReply(`This room is: ${room.settings.highTraffic ? 'high traffic' : 'low traffic'}`);\r\n\t\t}\r\n\t\tthis.checkCan('makeroom');\r\n\r\n\t\tif (this.meansYes(target)) {\r\n\t\t\troom.settings.highTraffic = true;\r\n\t\t} else if (this.meansNo(target)) {\r\n\t\t\troom.settings.highTraffic = undefined;\r\n\t\t} else {\r\n\t\t\treturn this.parse('/help hightraffic');\r\n\t\t}\r\n\t\troom.saveSettings();\r\n\t\tthis.modlog(`HIGHTRAFFIC`, null, `${!!room.settings.highTraffic}`);\r\n\t\tthis.addModAction(`This room was marked as high traffic by ${user.name}.`);\r\n\t},\r\n\thightraffichelp: [\r\n\t\t`/hightraffic [on|off] - (Un)marks a room as a high traffic room. Requires &`,\r\n\t\t`When a room is marked as high-traffic, PS requires all messages sent to that room to contain at least 2 letters.`,\r\n\t],\r\n\r\n\t/*********************************************************\r\n\t * Room management\r\n\t *********************************************************/\r\n\r\n\tmakeprivatechatroom: 'makechatroom',\r\n\tmakepublicchatroom: 'makechatroom',\r\n\tmakechatroom(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('makeroom');\r\n\t\tconst id = toID(target);\r\n\t\tif (!id || this.cmd === 'makechatroom') return this.parse('/help makechatroom');\r\n\t\tif (!Rooms.global.addChatRoom(target)) {\r\n\t\t\treturn this.errorReply(`An error occurred while trying to create the room '${target}'.`);\r\n\t\t}\r\n\r\n\t\tconst targetRoom = Rooms.search(target);\r\n\t\tif (!targetRoom) throw new Error(`Error in room creation.`);\r\n\t\tif (cmd === 'makeprivatechatroom') {\r\n\t\t\tif (!targetRoom.persist) throw new Error(`Private chat room created without settings.`);\r\n\t\t\ttargetRoom.setPrivate(true);\r\n\t\t\tconst upperStaffRoom = Rooms.get('upperstaff');\r\n\t\t\tif (upperStaffRoom) {\r\n\t\t\t\tupperStaffRoom.add(`|raw|
Private chat room created: ${Utils.escapeHTML(target)}
`).update();\r\n\t\t\t}\r\n\t\t\tthis.sendReply(`The private chat room '${target}' was created.`);\r\n\t\t} else {\r\n\t\t\tconst staffRoom = Rooms.get('staff');\r\n\t\t\tif (staffRoom) {\r\n\t\t\t\tstaffRoom.add(`|raw|
Public chat room created: ${Utils.escapeHTML(target)}
`).update();\r\n\t\t\t}\r\n\t\t\tconst upperStaffRoom = Rooms.get('upperstaff');\r\n\t\t\tif (upperStaffRoom) {\r\n\t\t\t\tupperStaffRoom.add(`|raw|
Public chat room created: ${Utils.escapeHTML(target)}
`).update();\r\n\t\t\t}\r\n\t\t\tthis.sendReply(`The chat room '${target}' was created.`);\r\n\t\t}\r\n\t},\r\n\tmakechatroomhelp: [\r\n\t\t`/makeprivatechatroom [roomname] - Creates a new private room named [roomname]. Requires: &`,\r\n\t\t`/makepublicchatroom [roomname] - Creates a new public room named [roomname]. Requires: &`,\r\n\t],\r\n\r\n\tsubroomgroupchat: 'makegroupchat',\r\n\tsrgc: 'makegroupchat',\r\n\tmgc: 'makegroupchat',\r\n\tmakegroupchat(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkChat();\r\n\t\tif (!user.trusted) {\r\n\t\t\treturn this.errorReply(\"You must be trusted (public room driver or global voice) to make a groupchat.\");\r\n\t\t}\r\n\r\n\t\tconst groupchatbanned = Punishments.isGroupchatBanned(user);\r\n\t\tif (groupchatbanned) {\r\n\t\t\tconst expireText = Punishments.checkPunishmentExpiration(groupchatbanned);\r\n\t\t\treturn this.errorReply(`You are banned from using groupchats ${expireText}.`);\r\n\t\t}\r\n\r\n\t\tif (cmd === 'subroomgroupchat' || cmd === 'srgc') {\r\n\t\t\tif (!user.can('mute', null, room)) {\r\n\t\t\t\treturn this.errorReply(\"You can only create subroom groupchats for rooms you're staff in.\");\r\n\t\t\t}\r\n\t\t\tif (room.battle) return this.errorReply(\"You cannot create a subroom of a battle.\");\r\n\t\t\tif (room.settings.isPersonal) return this.errorReply(\"You cannot create a subroom of a groupchat.\");\r\n\t\t}\r\n\t\tconst parent = cmd === 'subroomgroupchat' || cmd === 'srgc' ? room.roomid : null;\r\n\t\t// this.checkCan('makegroupchat');\r\n\r\n\t\t// Title defaults to a random 8-digit number.\r\n\t\tlet title = target.trim();\r\n\t\tif (title.length >= 32) {\r\n\t\t\treturn this.errorReply(\"Title must be under 32 characters long.\");\r\n\t\t} else if (!title) {\r\n\t\t\ttitle = (`${Math.floor(Math.random() * 100000000)}`);\r\n\t\t} else if (this.filter(title) !== title) {\r\n\t\t\treturn this.errorReply(\"Invalid title.\");\r\n\t\t}\r\n\t\t// `,` is a delimiter used by a lot of /commands\r\n\t\t// `|` and `[` are delimiters used by the protocol\r\n\t\t// `-` has special meaning in roomids\r\n\t\tif (title.includes(',') || title.includes('|') || title.includes('[') || title.includes('-')) {\r\n\t\t\treturn this.errorReply(\"Room titles can't contain any of: ,|[-\");\r\n\t\t}\r\n\r\n\t\t// Even though they're different namespaces, to cut down on confusion, you\r\n\t\t// can't share names with registered chatrooms.\r\n\t\tconst existingRoom = Rooms.search(toID(title));\r\n\t\tif (existingRoom && !existingRoom.settings.modjoin) {\r\n\t\t\treturn this.errorReply(`Your group chat name is too similar to existing chat room '${title}'.`);\r\n\t\t}\r\n\t\t// Room IDs for groupchats are groupchat-TITLEID\r\n\t\tlet titleid = toID(title);\r\n\t\tif (!titleid) {\r\n\t\t\ttitleid = `${Math.floor(Math.random() * 100000000)}` as ID;\r\n\t\t}\r\n\t\tconst roomid = `groupchat-${parent || user.id}-${titleid}` as RoomID;\r\n\t\t// Titles must be unique.\r\n\t\tif (Rooms.search(roomid)) return this.errorReply(`A group chat named '${title}' already exists.`);\r\n\t\t// Tab title is prefixed with '[G]' to distinguish groupchats from\r\n\t\t// registered chatrooms\r\n\r\n\t\tif (Monitor.countGroupChat(connection.ip)) {\r\n\t\t\tthis.errorReply(\"Due to high load, you are limited to creating 4 group chats every hour.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst titleMsg = Utils.html`Welcome to ${parent ? room.title : user.name}'s` +\r\n\t\t\tUtils.html`${!/^[0-9]+$/.test(title) ? ` ${title}` : ''}${parent ? ' subroom' : ''} groupchat!`;\r\n\t\tconst targetRoom = Rooms.createChatRoom(roomid, `[G] ${title}`, {\r\n\t\t\tisPersonal: true,\r\n\t\t\tisPrivate: 'hidden',\r\n\t\t\tcreationTime: Date.now(),\r\n\t\t\tmodjoin: parent ? null : '+',\r\n\t\t\tparentid: parent,\r\n\t\t\tauth: {},\r\n\t\t\tintroMessage: `` +\r\n\t\t\t\t`

${titleMsg}

Follow the Pok\u00E9mon Showdown Global Rules!
Don't be disruptive to the rest of the site.

`,\r\n\t\t\tstaffMessage: `` +\r\n\t\t\t\t`

Groupchats are temporary rooms, and will expire if there hasn't been any activity in 40 minutes.

You can invite new users using /invite. Be careful with who you invite!

Commands: | |

As creator of this groupchat, you are entirely responsible for what occurs in this chatroom. Global rules apply at all times.

If this room is used to break global rules or disrupt other areas of the server, you as the creator will be held accountable and punished.

`,\r\n\t\t});\r\n\t\tif (!targetRoom) {\r\n\t\t\treturn this.errorReply(`An unknown error occurred while trying to create the room '${title}'.`);\r\n\t\t}\r\n\t\t// The creator is a Room Owner in subroom groupchats and a Host otherwise..\r\n\t\ttargetRoom.auth.set(user.id, parent ? '#' : Users.HOST_SYMBOL);\r\n\t\t// Join after creating room. No other response is given.\r\n\t\tuser.joinRoom(targetRoom.roomid);\r\n\t\tuser.popup(`You've just made a groupchat; it is now your responsibility, regardless of whether or not you actively partake in the room. For more info, read your groupchat's staff intro.`);\r\n\t\tif (parent) this.modlog('SUBROOMGROUPCHAT', null, title);\r\n\t},\r\n\tmakegroupchathelp: [\r\n\t\t`/makegroupchat [roomname] - Creates an invite-only group chat named [roomname].`,\r\n\t\t`/subroomgroupchat [roomname] - Creates a subroom groupchat of the current room. Can only be used in a public room you have staff in.`,\r\n\t\t`Only users who are staff in a public room or global auth can make groupchats.`,\r\n\t],\r\n\tgroupchatuptime: 'roomuptime',\r\n\troomuptime(target, room, user, connection, cmd) {\r\n\t\tif (!this.runBroadcast()) return;\r\n\t\tif (!room) return this.errorReply(`Can only be used in a room.`);\r\n\r\n\t\t// for hotpatching\r\n\t\tif (!room.settings.creationTime) room.settings.creationTime = Date.now();\r\n\t\tconst uptime = Chat.toDurationString(Date.now() - room.settings.creationTime);\r\n\t\tthis.sendReplyBox(`Room uptime: ${uptime}`);\r\n\t},\r\n\troomuptimehelp: [`/roomuptime - Displays the uptime of the room.`],\r\n\r\n\tderegisterchatroom(target, room, user) {\r\n\t\tthis.checkCan('makeroom');\r\n\t\tthis.errorReply(\"NOTE: You probably want to use `/deleteroom` now that it exists.\");\r\n\t\tconst id = toID(target);\r\n\t\tif (!id) return this.parse('/help deregisterchatroom');\r\n\t\tconst targetRoom = Rooms.search(id);\r\n\t\tif (!targetRoom) return this.errorReply(`The room '${target}' doesn't exist.`);\r\n\t\ttarget = targetRoom.title || targetRoom.roomid;\r\n\t\tconst isPrivate = targetRoom.settings.isPrivate;\r\n\t\tconst staffRoom = Rooms.get('staff');\r\n\t\tconst upperStaffRoom = Rooms.get('upperstaff');\r\n\t\tif (Rooms.global.deregisterChatRoom(id)) {\r\n\t\t\tthis.sendReply(`The room '${target}' was deregistered.`);\r\n\t\t\tthis.sendReply(\"It will be deleted as of the next server restart.\");\r\n\t\t\ttarget = Utils.escapeHTML(target);\r\n\t\t\tif (isPrivate) {\r\n\t\t\t\tif (upperStaffRoom) {\r\n\t\t\t\t\tupperStaffRoom.add(`|raw|
Private chat room deregistered by ${user.id}: ${target}
`).update();\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (staffRoom) {\r\n\t\t\t\t\tstaffRoom.add(`|raw|
Public chat room deregistered: ${target}
`).update();\r\n\t\t\t\t}\r\n\t\t\t\tif (upperStaffRoom) {\r\n\t\t\t\t\tupperStaffRoom.add(`|raw|
Public chat room deregistered by ${user.id}: ${target}
`).update();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\treturn this.errorReply(`The room \"${target}\" isn't registered.`);\r\n\t},\r\n\tderegisterchatroomhelp: [\r\n\t\t`/deregisterchatroom [roomname] - Deletes room [roomname] after the next server restart. Requires: &`,\r\n\t],\r\n\r\n\tdeletechatroom: 'deleteroom',\r\n\tdeletegroupchat: 'deleteroom',\r\n\tdgc: 'deleteroom',\r\n\tdeleteroom(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tconst roomid = target.trim();\r\n\t\tif (!roomid) {\r\n\t\t\t// allow deleting personal rooms without typing out the room name\r\n\t\t\tif (!room.settings.isPersonal || !['deletegroupchat', 'dgc'].includes(cmd)) {\r\n\t\t\t\treturn this.parse(`/help deleteroom`);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tconst targetRoom = Rooms.search(roomid);\r\n\t\t\tif (targetRoom !== room) {\r\n\t\t\t\treturn this.parse(`/help deleteroom`);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (room.roomid.startsWith('groupchat-')) {\r\n\t\t\tthis.checkCan('gamemanagement', null, room);\r\n\t\t} else {\r\n\t\t\tthis.checkCan('makeroom');\r\n\t\t}\r\n\r\n\t\tconst title = room.title || room.roomid;\r\n\r\n\t\tif (room.persist) {\r\n\t\t\tif (room.settings.isPrivate) {\r\n\t\t\t\tconst upperStaffRoom = Rooms.get('upperstaff');\r\n\t\t\t\tif (upperStaffRoom) {\r\n\t\t\t\t\tupperStaffRoom.add(\r\n\t\t\t\t\t\tUtils.html`|raw|
Private chat room ` +\r\n\t\t\t\t\t\t`deleted by ${user.id}: ${title}
`\r\n\t\t\t\t\t).update();\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tconst staffRoom = Rooms.get('staff');\r\n\t\t\t\tif (staffRoom) {\r\n\t\t\t\t\tstaffRoom.add(Utils.html`|raw|
Public chat room deleted: ${title}
`).update();\r\n\t\t\t\t}\r\n\t\t\t\tconst upperStaffRoom = Rooms.get('upperstaff');\r\n\t\t\t\tif (upperStaffRoom) {\r\n\t\t\t\t\tupperStaffRoom.add(\r\n\t\t\t\t\t\tUtils.html`|raw|
Public chat ` +\r\n\t\t\t\t\t\t`room deleted by ${user.id}: ${title}
`\r\n\t\t\t\t\t).update();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\troom.add(`|raw|
This room has been deleted.
`);\r\n\t\troom.update();\r\n\t\troom.send(`|expire|This room has been deleted.`);\r\n\t\troom.destroy();\r\n\t},\r\n\tdeleteroomhelp: [\r\n\t\t`/deleteroom [roomname] - Deletes room [roomname]. Must be typed in the room to delete. Requires: &`,\r\n\t\t`/deletegroupchat - Deletes the current room, if it's a groupchat. Requires: \u2605 # &`,\r\n\t],\r\n\r\n\trename() {\r\n\t\tthis.errorReply(\"Did you mean /renameroom?\");\r\n\t},\r\n\trenamegroupchat: 'renameroom',\r\n\trenameroom(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (room.game || room.minorActivity || room.tour) {\r\n\t\t\treturn this.errorReply(\"Cannot rename room while a tour/poll/game is running.\");\r\n\t\t}\r\n\t\tif (room.battle) {\r\n\t\t\treturn this.errorReply(\"Cannot rename battle rooms.\");\r\n\t\t}\r\n\t\tconst oldTitle = room.title;\r\n\t\tconst isGroupchat = cmd === 'renamegroupchat';\r\n\t\tif (!toID(target)) return this.parse(\"/help renameroom\");\r\n\t\tif (room.persist && isGroupchat) return this.errorReply(`This isn't a groupchat.`);\r\n\t\tif (!room.persist && !isGroupchat) return this.errorReply(`Use /renamegroupchat instead.`);\r\n\t\tif (isGroupchat) {\r\n\t\t\tif (!user.can('lock')) this.checkCan('declare', null, room);\r\n\t\t\tconst existingRoom = Rooms.search(toID(target));\r\n\t\t\tif (existingRoom && !existingRoom.settings.modjoin) {\r\n\t\t\t\treturn this.errorReply(`Your groupchat name is too similar to existing chat room '${existingRoom.title}'.`);\r\n\t\t\t}\r\n\t\t\tif (this.filter(target) !== target) {\r\n\t\t\t\treturn this.errorReply(\"Invalid title.\");\r\n\t\t\t}\r\n\t\t\t// `,` is a delimiter used by a lot of /commands\r\n\t\t\t// `|` and `[` are delimiters used by the protocol\r\n\t\t\t// `-` has special meaning in roomids\r\n\t\t\tif (target.includes(',') || target.includes('|') || target.includes('[') || target.includes('-')) {\r\n\t\t\t\treturn this.errorReply(\"Room titles can't contain any of: ,|[-\");\r\n\t\t\t}\r\n\t\t\ttarget = `[G] ${target}`;\r\n\t\t} else {\r\n\t\t\tthis.checkCan('makeroom');\r\n\t\t}\r\n\t\tconst creatorID = room.roomid.split('-')[1];\r\n\t\tconst id = isGroupchat ? `groupchat-${creatorID}-${toID(target)}` as RoomID : undefined;\r\n\t\tconst oldID = room.roomid;\r\n\r\n\t\troom.rename(target, id);\r\n\r\n\t\tChat.handleRoomRename(oldID, id || toID(target) as RoomID, room);\r\n\r\n\t\tthis.modlog(`RENAME${isGroupchat ? 'GROUPCHAT' : 'ROOM'}`, null, `from ${oldTitle}`);\r\n\t\tconst privacy = room.settings.isPrivate === true ? \"Private\" :\r\n\t\t\t!room.settings.isPrivate ? \"Public\" :\r\n\t\t\t`${room.settings.isPrivate.charAt(0).toUpperCase()}${room.settings.isPrivate.slice(1)}`;\r\n\t\tif (!isGroupchat) {\r\n\t\t\tRooms.global.notifyRooms(\r\n\t\t\t\troom.settings.isPrivate === true ? ['upperstaff'] : ['upperstaff', 'staff'],\r\n\t\t\t\tUtils.html`|raw|
${privacy} chat room ${oldTitle} renamed to ${target}
`\r\n\t\t );\r\n\t\t}\r\n\t\troom.add(Utils.html`|raw|
The room has been renamed to ${target}
`).update();\r\n\t},\r\n\trenameroomhelp: [`/renameroom [new title] - Renames the current room to [new title]. Case-sensitive. Requires &`],\r\n\r\n\thideroom: 'privateroom',\r\n\thiddenroom: 'privateroom',\r\n\tsecretroom: 'privateroom',\r\n\tpublicroom: 'privateroom',\r\n\tunlistroom: 'privateroom',\r\n\tprivateroom(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (room.battle) {\r\n\t\t\tthis.checkCan('editprivacy', null, room);\r\n\t\t\tif (room.battle.forcedSettings.privacy) {\r\n\t\t\t\treturn this.errorReply(`This battle is required to be public because a player has a name prefixed by '${room.battle.forcedSettings.privacy}'.`);\r\n\t\t\t}\r\n\t\t\tif (room.tour?.forcePublic) {\r\n\t\t\t\treturn this.errorReply(`This battle can't be hidden, because the tournament is set to be forced public.`);\r\n\t\t\t}\r\n\t\t} else if (room.settings.isPersonal) {\r\n\t\t\tthis.checkCan('editroom', null, room);\r\n\t\t} else {\r\n\t\t\t// registered chatrooms show up on the room list and so require\r\n\t\t\t// higher permissions to modify privacy settings\r\n\t\t\tthis.checkCan('makeroom');\r\n\t\t}\r\n\t\tlet setting: boolean | 'hidden' | 'unlisted';\r\n\t\tswitch (cmd) {\r\n\t\tcase 'privateroom':\r\n\t\t\treturn this.parse('/help privateroom');\r\n\t\tcase 'publicroom':\r\n\t\t\tsetting = false;\r\n\t\t\tbreak;\r\n\t\tcase 'secretroom':\r\n\t\t\tthis.checkCan('rangeban');\r\n\t\t\tsetting = true;\r\n\t\t\tbreak;\r\n\t\tcase 'unlistroom':\r\n\t\t\tthis.checkCan('rangeban');\r\n\t\t\tsetting = 'unlisted';\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tif (room.settings.isPrivate === true && target !== 'force') {\r\n\t\t\t\treturn this.sendReply(`This room is a secret room. Use \"/publicroom\" to make it public, or \"/hiddenroom force\" to force it hidden.`);\r\n\t\t\t}\r\n\t\t\tsetting = 'hidden';\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\treturn this.errorReply(`Please specify what privacy setting you want for this room: /hiddenroom, /secretroom, or /publicroom`);\r\n\t\t}\r\n\r\n\t\tif (!setting) {\r\n\t\t\tif (!room.settings.isPrivate) {\r\n\t\t\t\treturn this.errorReply(`This room is already public.`);\r\n\t\t\t}\r\n\t\t\tif (room.parent && room.parent.settings.isPrivate) {\r\n\t\t\t\treturn this.errorReply(`This room's parent ${room.parent.title} must be public for this room to be public.`);\r\n\t\t\t}\r\n\t\t\tif (room.settings.isPersonal && !room.battle) {\r\n\t\t\t\treturn this.errorReply(`This room can't be made public.`);\r\n\t\t\t}\r\n\t\t\tif (room.privacySetter && user.can('nooverride', null, room) && !user.can('makeroom')) {\r\n\t\t\t\tif (!room.privacySetter.has(user.id)) {\r\n\t\t\t\t\tconst privacySetters = [...room.privacySetter].join(', ');\r\n\t\t\t\t\treturn this.errorReply(`You can't make the room public since you didn't make it private - only ${privacySetters} can.`);\r\n\t\t\t\t}\r\n\t\t\t\troom.privacySetter.delete(user.id);\r\n\t\t\t\tif (room.privacySetter.size) {\r\n\t\t\t\t\tconst privacySetters = [...room.privacySetter].join(', ');\r\n\t\t\t\t\treturn this.sendReply(`You are no longer forcing the room to stay private, but ${privacySetters} also need${Chat.plural(room.privacySetter, \"\", \"s\")} to use /publicroom to make the room public.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\troom.privacySetter = null;\r\n\t\t\tthis.addModAction(`${user.name} made this room public.`);\r\n\t\t\tthis.modlog('PUBLICROOM');\r\n\t\t\troom.setPrivate(false);\r\n\t\t} else {\r\n\t\t\tconst settingName = (setting === true ? 'secret' : setting);\r\n\t\t\tif (room.subRooms) {\r\n\t\t\t\tif (settingName === 'secret') return this.errorReply(\"Secret rooms cannot have subrooms.\");\r\n\t\t\t\tfor (const subRoom of room.subRooms.values()) {\r\n\t\t\t\t\tif (!subRoom.settings.isPrivate) {\r\n\t\t\t\t\t\treturn this.errorReply(`Subroom ${subRoom.title} must be private to make this room private.`);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (room.settings.isPrivate === setting) {\r\n\t\t\t\tif (room.privacySetter && !room.privacySetter.has(user.id)) {\r\n\t\t\t\t\troom.privacySetter.add(user.id);\r\n\t\t\t\t\treturn this.sendReply(`This room is already ${settingName}, but is now forced to stay that way until you use /publicroom.`);\r\n\t\t\t\t}\r\n\t\t\t\treturn this.errorReply(`This room is already ${settingName}.`);\r\n\t\t\t}\r\n\t\t\tthis.addModAction(`${user.name} made this room ${settingName}.`);\r\n\t\t\tthis.modlog(`${settingName.toUpperCase()}ROOM`);\r\n\t\t\tif (!room.settings.isPersonal && !room.battle) room.setSection();\r\n\t\t\troom.setPrivate(setting);\r\n\t\t\troom.privacySetter = new Set([user.id]);\r\n\t\t}\r\n\t},\r\n\tprivateroomhelp: [\r\n\t\t`/secretroom - Makes a room secret. Secret rooms are visible to & and up. Requires: &`,\r\n\t\t`/hiddenroom [on/off] - Makes a room hidden. Hidden rooms are visible to % and up, and inherit global ranks. Requires: \\u2606 &`,\r\n\t\t`/publicroom - Makes a room public. Requires: \\u2606 &`,\r\n\t],\r\n\r\n\thidenext(target, room, user) {\r\n\t\tconst groupConfig = Config.groups[Users.PLAYER_SYMBOL];\r\n\t\tif (!groupConfig?.editprivacy) return this.errorReply(`/hidenext - Access denied.`);\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tuser.battleSettings.hidden = false;\r\n\t\t\tuser.update();\r\n\t\t\tthis.sendReply(\"Your next battle will be publicly visible.\");\r\n\t\t} else {\r\n\t\t\tuser.battleSettings.hidden = true;\r\n\t\t\tuser.update();\r\n\t\t\tthis.sendReply(`Your next battle will be hidden${Rooms.RoomBattle.battleForcedSetting(user, 'privacy') ? `, unless it is rated` : ``}.`);\r\n\t\t}\r\n\t},\r\n\thidenexthelp: [\r\n\t\t`/hidenext - Sets your next battle to be hidden.`,\r\n\t\t`/hidenext off - Sets your next battle to be publicly visible.`,\r\n\t],\r\n\r\n\tofficialchatroom: 'officialroom',\r\n\tofficialroom() {\r\n\t\tthis.parse(`/setroomsection official`);\r\n\t},\r\n\r\n\troomspotlight(target, room, user) {\r\n\t\tthis.checkCan('makeroom');\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) return this.parse(`/help roomspotlight`);\r\n\t\tif (!room.persist) {\r\n\t\t\treturn this.errorReply(`/roomspotlight - You can't spotlight this room.`);\r\n\t\t}\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tif (!room.settings.spotlight) return this.errorReply(`This chatroom is not being spotlighted.`);\r\n\t\t\tthis.addModAction(`${user.name} removed this chatroom from the spotlight.`);\r\n\t\t\tthis.globalModlog('UNSPOTLIGHT');\r\n\t\t\tdelete room.settings.spotlight;\r\n\t\t\troom.saveSettings();\r\n\t\t} else {\r\n\t\t\tif (room.settings.spotlight === target) return this.errorReply(\"This chat room is already spotlighted.\");\r\n\t\t\tthis.addModAction(`${user.name} spotlighted this room with the message \"${target}\".`);\r\n\t\t\tthis.globalModlog('SPOTLIGHT');\r\n\t\t\troom.settings.spotlight = target;\r\n\t\t\troom.saveSettings();\r\n\t\t}\r\n\t},\r\n\troomspotlighthelp: [\r\n\t\t`/roomspotlight [spotlight] - Makes the room this command is used in a spotlight room for the [spotlight] category on the roomlist. Requires: &`,\r\n\t\t`/roomspotlight off - Removes the room this command is used in from the list of spotlight rooms. Requires: &`,\r\n\t],\r\n\r\n\tsetsubroom: 'subroom',\r\n\tsubroom(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!user.can('makeroom')) return this.errorReply(`/subroom - Access denied. Did you mean /subrooms?`);\r\n\t\tif (!target) return this.parse('/help subroom');\r\n\r\n\t\tif (!room.persist) return this.errorReply(`Temporary rooms cannot be subrooms.`);\r\n\t\tif (room.parent) {\r\n\t\t\treturn this.errorReply(`This room is already a subroom. To change which room this subroom belongs to, remove the subroom first.`);\r\n\t\t}\r\n\t\tif (room.subRooms) {\r\n\t\t\treturn this.errorReply(`This room is already a parent room, and a parent room cannot be made as a subroom.`);\r\n\t\t}\r\n\r\n\t\tconst parent = Rooms.search(target);\r\n\r\n\t\tif (!parent) return this.errorReply(`The room '${target}' does not exist.`);\r\n\t\tif (parent.type !== 'chat') return this.errorReply(`Parent room '${target}' must be a chat room.`);\r\n\t\tif (parent.parent) return this.errorReply(`Subrooms cannot have subrooms.`);\r\n\t\tif (parent.settings.isPrivate === true) return this.errorReply(`Only public and hidden rooms can have subrooms.`);\r\n\t\tif (parent.settings.isPrivate && !room.settings.isPrivate) {\r\n\t\t\treturn this.errorReply(`Private rooms cannot have public subrooms.`);\r\n\t\t}\r\n\t\tif (!parent.persist) return this.errorReply(`Temporary rooms cannot be parent rooms.`);\r\n\t\tif (room === parent) return this.errorReply(`You cannot set a room to be a subroom of itself.`);\r\n\r\n\t\tconst settingsList = Rooms.global.settingsList;\r\n\r\n\t\tconst parentIndex = settingsList.findIndex(r => r.title === parent.title);\r\n\t\tconst index = settingsList.findIndex(r => r.title === room!.title);\r\n\r\n\t\t// Ensure that the parent room gets loaded before the subroom.\r\n\t\tif (parentIndex > index) {\r\n\t\t\t[settingsList[parentIndex], settingsList[index]] = [settingsList[index], settingsList[parentIndex]];\r\n\t\t}\r\n\r\n\t\troom.setParent(parent);\r\n\r\n\t\tthis.modlog('SUBROOM', null, `of ${parent.title}`);\r\n\t\treturn this.addModAction(`This room was set as a subroom of ${parent.title} by ${user.name}.`);\r\n\t},\r\n\r\n\tremovesubroom: 'unsubroom',\r\n\tdesubroom: 'unsubroom',\r\n\tunsubroom(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('makeroom');\r\n\t\tif (!room.parent || !room.persist) {\r\n\t\t\treturn this.errorReply(`This room is not currently a subroom of a public room.`);\r\n\t\t}\r\n\r\n\t\troom.setParent(null);\r\n\r\n\t\tthis.modlog('UNSUBROOM');\r\n\t\treturn this.addModAction(`This room was unset as a subroom by ${user.name}.`);\r\n\t},\r\n\tunsubroomhelp: [`/unsubroom - Unmarks the current room as a subroom. Requires: &`],\r\n\r\n\tparentroom: 'subrooms',\r\n\tsubrooms(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (cmd === 'parentroom') {\r\n\t\t\tif (!room.parent) return this.errorReply(`This room is not a subroom.`);\r\n\t\t\treturn this.sendReply(`This is a subroom of ${room.parent.title}.`);\r\n\t\t}\r\n\t\tif (!room.persist) return this.errorReply(`Temporary rooms cannot have subrooms.`);\r\n\r\n\t\tif (!this.runBroadcast()) return;\r\n\r\n\t\tconst showSecret = !this.broadcasting && user.can('mute', null, room);\r\n\r\n\t\tconst subRooms = room.getSubRooms(showSecret);\r\n\r\n\t\tif (!subRooms.length) return this.sendReply(`This room doesn't have any subrooms.`);\r\n\r\n\t\tconst subRoomText = subRooms.map(\r\n\t\t\tsubRoom =>\r\n\t\t\t\tUtils.html`${subRoom.title}
${subRoom.settings.desc}`\r\n\t\t);\r\n\r\n\t\treturn this.sendReplyBox(`

${Utils.escapeHTML(room.title)}'s subroom${Chat.plural(subRooms)}:

`);\r\n\t},\r\n\r\n\tsubroomhelp: [\r\n\t\t`/subroom [room] - Marks the current room as a subroom of [room]. Requires: &`,\r\n\t\t`/unsubroom - Unmarks the current room as a subroom. Requires: &`,\r\n\t\t`/subrooms - Displays the current room's subrooms.`,\r\n\t\t`/parentroom - Displays the current room's parent room.`,\r\n\t],\r\n\r\n\troomdesc(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tif (!room.settings.desc) return this.sendReply(`This room does not have a description set.`);\r\n\t\t\tthis.sendReplyBox(Utils.html`The room description is: ${room.settings.desc}`);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.checkCan('makeroom');\r\n\t\tif (target.length > 80) {\r\n\t\t\treturn this.errorReply(`Error: Room description is too long (must be at most 80 characters).`);\r\n\t\t}\r\n\t\tconst normalizedTarget = ' ' + target.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim() + ' ';\r\n\r\n\t\tif (normalizedTarget.includes(' welcome ')) {\r\n\t\t\treturn this.errorReply(`Error: Room description must not contain the word \"welcome\".`);\r\n\t\t}\r\n\t\tif (normalizedTarget.startsWith(' discuss ')) {\r\n\t\t\treturn this.errorReply(`Error: Room description must not start with the word \"discuss\".`);\r\n\t\t}\r\n\t\tif (normalizedTarget.startsWith(' talk about ') || normalizedTarget.startsWith(' talk here about ')) {\r\n\t\t\treturn this.errorReply(`Error: Room description must not start with the phrase \"talk about\".`);\r\n\t\t}\r\n\r\n\t\troom.settings.desc = target;\r\n\t\tthis.sendReply(`(The room description is now: ${target})`);\r\n\r\n\t\tthis.privateModAction(`${user.name} changed the roomdesc to: \"${target}\".`);\r\n\t\tthis.modlog('ROOMDESC', null, `to \"${target}\"`);\r\n\t\troom.saveSettings();\r\n\t},\r\n\troomdeschelp: [`/roomdesc [description] - Sets the [description] of the current room. Requires: &`],\r\n\r\n\ttopic: 'roomintro',\r\n\troomintro(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tif (!room.settings.introMessage) return this.sendReply(\"This room does not have an introduction set.\");\r\n\t\t\tthis.sendReply('|raw|
' + room.settings.introMessage.replace(/\\n/g, '') + '
');\r\n\t\t\tif (!this.broadcasting && user.can('declare', null, room, 'roomintro') && cmd !== 'topic') {\r\n\t\t\t\tconst code = Utils.escapeHTML(room.settings.introMessage).replace(/\\n/g, '
');\r\n\t\t\t\tthis.sendReplyBox(`
Source:/roomintro ${code}
`);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.checkCan('editroom', null, room);\r\n\t\tif (this.meansNo(target) || target === 'delete') return this.errorReply('Did you mean \"/deleteroomintro\"?');\r\n\t\tthis.checkHTML(target);\r\n\t\tif (!target.includes(\"<\")) {\r\n\t\t\t// not HTML, do some simple URL linking\r\n\t\t\tconst re = /(https?:\\/\\/(([\\w.-]+)+(:\\d+)?(\\/([\\w/_.]*(\\?\\S+)?)?)?))/g;\r\n\t\t\ttarget = target.replace(re, '$1');\r\n\t\t}\r\n\t\tif (target.substr(0, 11) === '/roomintro ') target = target.substr(11);\r\n\r\n\t\troom.settings.introMessage = target.replace(/\\r/g, '');\r\n\t\tthis.sendReply(\"(The room introduction has been changed to:)\");\r\n\t\tthis.sendReply(`|raw|
${room.settings.introMessage.replace(/\\n/g, '')}
`);\r\n\r\n\t\tthis.privateModAction(`${user.name} changed the roomintro.`);\r\n\t\tthis.modlog('ROOMINTRO');\r\n\t\tthis.roomlog(room.settings.introMessage.replace(/\\n/g, ''));\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\troomintrohelp: [\r\n\t\t`/roomintro - Display the room introduction of the current room.`,\r\n\t\t`/roomintro [content] - Set an introduction for the room. Requires: # &`,\r\n\t],\r\n\r\n\tdeletetopic: 'deleteroomintro',\r\n\tdeleteroomintro(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('declare', null, room);\r\n\t\tif (!room.settings.introMessage) return this.errorReply(\"This room does not have a introduction set.\");\r\n\r\n\t\tthis.privateModAction(`${user.name} deleted the roomintro.`);\r\n\t\tthis.modlog('DELETEROOMINTRO');\r\n\t\tthis.roomlog(target);\r\n\t\tdelete room.settings.introMessage;\r\n\t\troom.saveSettings();\r\n\t},\r\n\tdeleteroomintrohelp: [`/deleteroomintro - Deletes the current room's introduction. Requires: # &`],\r\n\r\n\tstafftopic: 'staffintro',\r\n\tstaffintro(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tthis.checkCan('mute', null, room);\r\n\t\t\tif (!room.settings.staffMessage) return this.sendReply(\"This room does not have a staff introduction set.\");\r\n\t\t\tthis.sendReply(`|raw|
${room.settings.staffMessage.replace(/\\n/g, ``)}
`);\r\n\t\t\tif (user.can('ban', null, room, 'staffintro') && cmd !== 'stafftopic') {\r\n\t\t\t\tconst code = Utils.escapeHTML(room.settings.staffMessage).replace(/\\n/g, '
');\r\n\t\t\t\tthis.sendReplyBox(`
Source:/staffintro ${code}
`);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.checkCan('ban', null, room);\r\n\t\tthis.checkChat();\r\n\t\tif (this.meansNo(target) || target === 'delete') return this.errorReply('Did you mean \"/deletestaffintro\"?');\r\n\t\tthis.checkHTML(target);\r\n\t\tif (!target.includes(\"<\")) {\r\n\t\t\t// not HTML, do some simple URL linking\r\n\t\t\tconst re = /(https?:\\/\\/(([\\w.-]+)+(:\\d+)?(\\/([\\w/_.]*(\\?\\S+)?)?)?))/g;\r\n\t\t\ttarget = target.replace(re, '$1');\r\n\t\t}\r\n\t\tif (target.substr(0, 12) === '/staffintro ') target = target.substr(12);\r\n\r\n\t\troom.settings.staffMessage = target.replace(/\\r/g, '');\r\n\t\tthis.sendReply(\"(The staff introduction has been changed to:)\");\r\n\t\tthis.sendReply(`|raw|
${target.replace(/\\n/g, ``)}
`);\r\n\r\n\t\tthis.privateModAction(`${user.name} changed the staffintro.`);\r\n\t\tthis.modlog('STAFFINTRO');\r\n\t\tthis.roomlog(room.settings.staffMessage.replace(/\\n/g, ``));\r\n\t\troom.saveSettings();\r\n\t},\r\n\tstaffintrohelp: [`/staffintro [content] - Set an introduction for staff members. Requires: @ # &`],\r\n\r\n\tdeletestafftopic: 'deletestaffintro',\r\n\tdeletestaffintro(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('ban', null, room);\r\n\t\tif (!room.settings.staffMessage) return this.errorReply(\"This room does not have a staff introduction set.\");\r\n\r\n\t\tthis.privateModAction(`${user.name} deleted the staffintro.`);\r\n\t\tthis.modlog('DELETESTAFFINTRO');\r\n\t\tthis.roomlog(target);\r\n\t\tdelete room.settings.staffMessage;\r\n\t\troom.saveSettings();\r\n\t},\r\n\tdeletestaffintrohelp: [`/deletestaffintro - Deletes the current room's staff introduction. Requires: @ # &`],\r\n\r\n\troomalias(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!target) {\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tif (!room.settings.aliases) return this.sendReplyBox(\"This room does not have any aliases.\");\r\n\t\t\treturn this.sendReplyBox(`This room has the following aliases: ${room.settings.aliases.join(\", \")}`);\r\n\t\t}\r\n\t\tthis.checkCan('makeroom');\r\n\t\tif (target.includes(',')) {\r\n\t\t\tthis.errorReply(`Invalid room alias: ${target.trim()}`);\r\n\t\t\treturn this.parse('/help roomalias');\r\n\t\t}\r\n\r\n\t\tconst alias = toID(target);\r\n\t\tif (!alias.length) return this.errorReply(\"Only alphanumeric characters are valid in an alias.\");\r\n\t\tif (Rooms.get(alias) || Rooms.aliases.has(alias)) {\r\n\t\t\treturn this.errorReply(\"You cannot set an alias to an existing room or alias.\");\r\n\t\t}\r\n\t\tif (room.settings.isPersonal) return this.errorReply(\"Personal rooms can't have aliases.\");\r\n\r\n\t\tRooms.aliases.set(alias, room.roomid);\r\n\t\tthis.privateModAction(`${user.name} added the room alias '${alias}'.`);\r\n\t\tthis.modlog('ROOMALIAS', null, alias);\r\n\r\n\t\tif (!room.settings.aliases) room.settings.aliases = [];\r\n\t\troom.settings.aliases.push(alias);\r\n\t\troom.saveSettings();\r\n\t},\r\n\troomaliashelp: [\r\n\t\t`/roomalias - displays a list of all room aliases of the room the command was entered in.`,\r\n\t\t`/roomalias [alias] - adds the given room alias to the room the command was entered in. Requires: &`,\r\n\t\t`/removeroomalias [alias] - removes the given room alias of the room the command was entered in. Requires: &`,\r\n\t],\r\n\r\n\tdeleteroomalias: 'removeroomalias',\r\n\tderoomalias: 'removeroomalias',\r\n\tunroomalias: 'removeroomalias',\r\n\tremoveroomalias(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tif (!room.settings.aliases) return this.errorReply(\"This room does not have any aliases.\");\r\n\t\tthis.checkCan('makeroom');\r\n\t\tif (target.includes(',')) {\r\n\t\t\tthis.errorReply(`Invalid room alias: ${target.trim()}`);\r\n\t\t\treturn this.parse('/help removeroomalias');\r\n\t\t}\r\n\r\n\t\tconst alias = toID(target);\r\n\t\tif (!alias || !Rooms.aliases.has(alias)) return this.errorReply(\"Please specify an existing alias.\");\r\n\t\tif (Rooms.aliases.get(alias) !== room.roomid) {\r\n\t\t\treturn this.errorReply(\"You may only remove an alias from the current room.\");\r\n\t\t}\r\n\r\n\t\tthis.privateModAction(`${user.name} removed the room alias '${alias}'.`);\r\n\t\tthis.modlog('REMOVEALIAS', null, alias);\r\n\r\n\t\tconst aliasIndex = room.settings.aliases.indexOf(alias);\r\n\t\tif (aliasIndex >= 0) {\r\n\t\t\troom.settings.aliases.splice(aliasIndex, 1);\r\n\t\t\tif (!room.settings.aliases.length) room.settings.aliases = undefined;\r\n\t\t\tRooms.aliases.delete(alias);\r\n\t\t\troom.saveSettings();\r\n\t\t}\r\n\t},\r\n\tremoveroomaliashelp: [\r\n\t\t`/removeroomalias [alias] - removes the given room alias of the room the command was entered in. Requires: &`,\r\n\t],\r\n\r\n\tresettierdisplay: 'roomtierdisplay',\r\n\troomtierdisplay(target, room, user, connection, cmd) {\r\n\t\troom = this.requireRoom();\r\n\t\tconst resetTier = cmd === 'resettierdisplay';\r\n\t\tif (!target) {\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\treturn this.sendReplyBox(\r\n\t\t\t\t`This room is currently displaying ${room.settings.dataCommandTierDisplay} as the tier when using /data.`\r\n\t\t\t);\r\n\t\t}\r\n\t\tthis.checkCan('declare', null, room);\r\n\r\n\t\tconst displayIDToName: {[k: string]: Room['settings']['dataCommandTierDisplay']} = {\r\n\t\t\ttiers: 'tiers',\r\n\t\t\tdoublestiers: 'doubles tiers',\r\n\t\t\tnationaldextiers: 'National Dex tiers',\r\n\t\t\tnumbers: 'numbers',\r\n\t\t};\r\n\r\n\t\tif (!resetTier) {\r\n\t\t\tif (!(toID(target) in displayIDToName)) {\r\n\t\t\t\tthis.errorReply(`Invalid tier display: ${target.trim()}`);\r\n\t\t\t\treturn this.parse(`/help roomtierdisplay`);\r\n\t\t\t}\r\n\r\n\t\t\troom.settings.dataCommandTierDisplay = displayIDToName[toID(target)];\r\n\t\t\tthis.sendReply(`(The room's tier display is now: ${displayIDToName[toID(target)]})`);\r\n\r\n\t\t\tthis.privateModAction(`${user.name} changed the room's tier display to: ${displayIDToName[toID(target)]}.`);\r\n\t\t\tthis.modlog('ROOMTIERDISPLAY', null, `to ${displayIDToName[toID(target)]}`);\r\n\t\t} else {\r\n\t\t\troom.settings.dataCommandTierDisplay = 'tiers';\r\n\t\t\tthis.sendReply(`(The room's tier display is now: tiers)`);\r\n\r\n\t\t\tthis.privateModAction(`${user.name} reset the room's tier display.`);\r\n\t\t\tthis.modlog('RESETTIERDISPLAY', null, `to tiers`);\r\n\t\t}\r\n\r\n\t\troom.saveSettings();\r\n\t},\r\n\troomtierdisplayhelp: [\r\n\t\t`/roomtierdisplay - displays the current room's display.`,\r\n\t\t`/roomtierdisplay [option] - changes the current room's tier display. Valid options are: tiers, doubles tiers, numbers. Requires: # &`,\r\n\t\t`/resettierdisplay - resets the current room's tier display. Requires: # &`,\r\n\t],\r\n\r\n\tsetroomsection: 'roomsection',\r\n\troomsection(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tconst sectionNames = RoomSections.sectionNames;\r\n\t\tif (!target) {\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tthis.sendReplyBox(Utils.html`This room is ${room.settings.section ? `in the ${sectionNames[room.settings.section]} section` : `not in a section`}.`);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.checkCan('gdeclare');\r\n\t\tconst section = room.setSection(target);\r\n\t\tthis.sendReply(`The room section is now: ${section ? sectionNames[section] : 'none'}`);\r\n\r\n\t\tthis.privateGlobalModAction(`${user.name} changed the room section of ${room.title} to ${section ? sectionNames[section] : 'none'}.`);\r\n\t\tthis.globalModlog('ROOMSECTION', null, section || 'none');\r\n\t},\r\n\troomsectionhelp: [\r\n\t\t`/roomsection [section] - Sets the room this is used in to the specified [section]. Requires: &`,\r\n\t\t`Valid sections: ${sections.join(', ')}`,\r\n\t],\r\n\r\n\troomdefaultformat(target, room, user) {\r\n\t\troom = this.requireRoom();\r\n\t\tthis.checkCan('editroom', null, room);\r\n\r\n\t\tif (!target) {\r\n\t\t\tthis.checkBroadcast();\r\n\t\t\tif (room.settings.defaultFormat) {\r\n\t\t\t\tthis.sendReply(`This room's default format is ${room.settings.defaultFormat}.`);\r\n\t\t\t} else {\r\n\t\t\t\tthis.sendReply(`This room has no default format.`);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (this.meansNo(target)) {\r\n\t\t\tdelete room.settings.defaultFormat;\r\n\t\t\troom.saveSettings();\r\n\t\t\tthis.modlog(`DEFAULTFORMAT`, null, 'off');\r\n\t\t\tthis.privateModAction(`${user.name} removed this room's default format.`);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\ttarget = toID(target);\r\n\t\tconst format = Dex.formats.get(target);\r\n\t\tif (format.exists) {\r\n\t\t\ttarget = format.name;\r\n\t\t}\r\n\t\tconst {isMatch} = this.extractFormat(target);\r\n\t\tif (!isMatch) throw new Chat.ErrorMessage(`Unrecognized format or mod \"${target}\"`);\r\n\r\n\t\troom.settings.defaultFormat = target;\r\n\t\troom.saveSettings();\r\n\t\tthis.modlog(`DEFAULTFORMAT`, null, target);\r\n\t\tthis.privateModAction(`${user.name} set this room's default format to ${target}.`);\r\n\t},\r\n\troomdefaultformathelp: [\r\n\t\t`/roomdefaultformat [format] or [mod] or gen[number] - Sets this room's default format/mod. Requires: # &`,\r\n\t\t`/roomdefaultformat off - Clears this room's default format/mod. Requires: # &`,\r\n\t\t`Affected commands: /details, /coverage, /effectiveness, /weakness, /learn`,\r\n\t],\r\n};\r\n\r\nexport const roomSettings: Chat.SettingsHandler[] = [\r\n\t// modchat\r\n\t(room, user) => ({\r\n\t\tlabel: \"Modchat\",\r\n\t\tpermission: 'modchat',\r\n\t\toptions: [\r\n\t\t\t'off',\r\n\t\t\t'autoconfirmed',\r\n\t\t\t'trusted',\r\n\t\t\t...RANKS.slice(1).filter(symbol => Users.Auth.hasPermission(user, 'modchat', symbol, room)),\r\n\t\t].map(rank => [rank, rank === (room.settings.modchat || 'off') || `modchat ${rank || 'off'}`]),\r\n\t}),\r\n\t(room, user) => ({\r\n\t\tlabel: \"Modjoin\",\r\n\t\tpermission: room.settings.isPersonal ? user.can('editroom', null, room) : user.can('makeroom'),\r\n\t\toptions: [\r\n\t\t\t'off',\r\n\t\t\t'autoconfirmed',\r\n\t\t\t// groupchat ROs can set modjoin, but only to +\r\n\t\t\t// first rank is for modjoin off\r\n\t\t\t...RANKS.slice(1, room.settings.isPersonal && !user.can('makeroom') ? 2 : undefined),\r\n\t\t].map(rank => [rank, rank === (room.settings.modjoin || 'off') || `modjoin ${rank || 'off'}`]),\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Language\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [...Chat.languages].map(\r\n\t\t\t([id, name]) => [name, id === (room.settings.language || 'english') || `roomlanguage ${id || 'off'}`]\r\n\t\t),\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Stretch filter\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [\r\n\t\t\t[`off`, !room.settings.filterStretching || 'stretchfilter off'],\r\n\t\t\t[`on`, room.settings.filterStretching || 'stretchfilter on'],\r\n\t\t],\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Caps filter\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [\r\n\t\t\t[`off`, !room.settings.filterCaps || 'capsfilter off'],\r\n\t\t\t[`on`, room.settings.filterCaps || 'capsfilter on'],\r\n\t\t],\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Emoji filter\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [\r\n\t\t\t[`off`, !room.settings.filterEmojis || 'emojifilter off'],\r\n\t\t\t[`on`, room.settings.filterEmojis || 'emojifilter on'],\r\n\t\t],\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Link filter\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [\r\n\t\t\t[`off`, !room.settings.filterLinks || 'linkfilter off'],\r\n\t\t\t[`on`, room.settings.filterLinks || 'linkfilter on'],\r\n\t\t],\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"Slowchat\",\r\n\t\tpermission: room.userCount < SLOWCHAT_USER_REQUIREMENT ? 'bypassall' as any : 'editroom',\r\n\t\toptions: ['off', 5, 10, 20, 30, 60].map(\r\n\t\t\ttime => [`${time}`, time === (room.settings.slowchat || 'off') || `slowchat ${time || 'off'}`]\r\n\t\t),\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"/data Tier display\",\r\n\t\tpermission: 'editroom',\r\n\t\toptions: [\r\n\t\t\t[`tiers`, (room.settings.dataCommandTierDisplay ?? 'tiers') === 'tiers' || `roomtierdisplay tiers`],\r\n\t\t\t[`doubles tiers`, room.settings.dataCommandTierDisplay === 'doubles tiers' || `roomtierdisplay doubles tiers`],\r\n\t\t\t[\r\n\t\t\t\t`National Dex tiers`,\r\n\t\t\t\troom.settings.dataCommandTierDisplay === 'National Dex tiers' || `roomtierdisplay National Dex tiers`,\r\n\t\t\t],\r\n\t\t\t[`numbers`, room.settings.dataCommandTierDisplay === 'numbers' || `roomtierdisplay numbers`],\r\n\t\t],\r\n\t}),\r\n\troom => ({\r\n\t\tlabel: \"/requestshow\",\r\n\t\tpermission: 'declare',\r\n\t\toptions: [\r\n\t\t\t[`off`, !room.settings.requestShowEnabled || `showapprovals off`],\r\n\t\t\t[`on`, room.settings.requestShowEnabled || `showapprovals on`],\r\n\t\t],\r\n\t}),\r\n];\r\n\r\nexport const pages: Chat.PageTable = {\r\n\tpermissions(args, user, connection) {\r\n\t\tthis.title = `[Permissions]`;\r\n\t\tconst room = this.requireRoom();\r\n\t\tthis.checkCan('mute', null, room);\r\n\r\n\t\tconst roomGroups = ['default', ...Config.groupsranking.slice(1)];\r\n\t\tconst permissions = room.settings.permissions || {};\r\n\r\n\t\tlet buf = `

Command permissions for ${room.title}

`;\r\n\t\tbuf += `
`;\r\n\t\tbuf += ``;\r\n\t\tlet atLeastOne = false;\r\n\t\tfor (const permission in permissions) {\r\n\t\t\tconst requiredRank = permissions[permission];\r\n\t\t\tatLeastOne = true;\r\n\t\t\tbuf += ``;\r\n\t\t}\r\n\t\tif (!atLeastOne) {\r\n\t\t\tbuf += ``;\r\n\t\t}\r\n\t\tbuf += `
PermissionRequired rank
${permission}`;\r\n\t\t\tif (room.auth.atLeast(user, '#')) {\r\n\t\t\t\tbuf += roomGroups.filter(group => group !== Users.SECTIONLEADER_SYMBOL).map(group => (\r\n\t\t\t\t\trequiredRank === group ?\r\n\t\t\t\t\t\tUtils.html`` :\r\n\t\t\t\t\t\tUtils.html``\r\n\t\t\t\t)).join(' ');\r\n\t\t\t} else {\r\n\t\t\t\tbuf += Utils.html``;\r\n\t\t\t}\r\n\t\t\tbuf += `
You don't have any permissions configured.
`;\r\n\t\tbuf += `

Use /permissions to add new permissions

`;\r\n\t\treturn buf;\r\n\t},\r\n};\r\n"], "mappings": "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", "names": ["slowchatSetting", "stretchSetting", "capsSetting", "emojiSetting"] }