{ "version": 3, "sources": ["../../../../server/chat-plugins/room-events.ts"], "sourcesContent": ["/**\r\n * Room Events Plugin\r\n * Pokemon Showdown - http://pokemonshowdown.com/\r\n *\r\n * This is a room-management system to keep track of upcoming room events.\r\n *\r\n * @license MIT license\r\n */\r\nimport {Utils} from '../../lib';\r\n\r\nexport interface RoomEvent {\r\n\teventName: string;\r\n\tdate: string;\r\n\tdesc: string;\r\n\tstarted: boolean;\r\n}\r\n\r\nexport interface RoomEventAlias {\r\n\teventID: ID;\r\n}\r\n\r\nexport interface RoomEventCategory {\r\n\tevents: ID[];\r\n}\r\n\r\nfunction convertAliasFormat(room: Room) {\r\n\tif (!room.settings.events) return;\r\n\tfor (const event of Object.values(room.settings.events) as AnyObject[]) {\r\n\t\tif (!event.aliases) continue;\r\n\t\tfor (const alias of event.aliases) {\r\n\t\t\troom.settings.events[alias] = {eventID: toID(event.eventName)};\r\n\t\t}\r\n\t\tdelete event.aliases;\r\n\t}\r\n}\r\n\r\nfunction formatEvent(room: Room, event: RoomEvent, showAliases?: boolean, showCategories?: boolean) {\r\n\tconst timeRemaining = new Date(event.date).getTime() - new Date().getTime();\r\n\tlet explanation = timeRemaining.toString();\r\n\tif (!timeRemaining) explanation = \"The time remaining for this event is not available\";\r\n\tif (timeRemaining < 0) explanation = \"This event will start soon\";\r\n\tif (event.started) explanation = \"This event has started\";\r\n\tif (!isNaN(timeRemaining)) {\r\n\t\texplanation = `This event will start in: ${Chat.toDurationString(timeRemaining, {precision: 2})}`;\r\n\t}\r\n\r\n\tconst eventID = toID(event.eventName);\r\n\tconst aliases = getAliases(room, eventID);\r\n\tconst categories = getAllCategories(room).filter(\r\n\t\tcategory => (room.settings.events![category] as RoomEventCategory).events.includes(eventID)\r\n\t);\r\n\r\n\tlet ret = ``;\r\n\tret += Utils.html`${event.eventName}`;\r\n\tif (showAliases) ret += Utils.html`${aliases.join(\", \")}`;\r\n\tif (showCategories) ret += Utils.html`${categories.join(\", \")}`;\r\n\tret += `${Chat.formatText(event.desc, true)}`;\r\n\tret += Utils.html``;\r\n\treturn ret;\r\n}\r\n\r\nfunction getAliases(room: Room, eventID?: ID) {\r\n\tif (!room.settings.events) return [];\r\n\tconst aliases: string[] = [];\r\n\tfor (const aliasID in room.settings.events) {\r\n\t\tif (\r\n\t\t\t'eventID' in room.settings.events[aliasID] &&\r\n\t\t\t(!eventID || (room.settings.events[aliasID] as RoomEventAlias).eventID === eventID)\r\n\t\t) aliases.push(aliasID);\r\n\t}\r\n\treturn aliases;\r\n}\r\n\r\nfunction getAllCategories(room: Room) {\r\n\tif (!room.settings.events) return [];\r\n\tconst categories: string[] = [];\r\n\tfor (const categoryID in room.settings.events) {\r\n\t\tif ('events' in room.settings.events[categoryID]) categories.push(categoryID);\r\n\t}\r\n\treturn categories;\r\n}\r\n\r\nfunction getAllEvents(room: Room) {\r\n\tif (!room.settings.events) return [];\r\n\tconst events: RoomEvent[] = [];\r\n\tfor (const event of Object.values(room.settings.events)) {\r\n\t\tif ('eventName' in event) events.push(event);\r\n\t}\r\n\treturn events;\r\n}\r\n\r\nfunction getEventID(nameOrAlias: string, room: Room): ID {\r\n\tlet id = toID(nameOrAlias);\r\n\tconst event = room.settings.events?.[id];\r\n\tif (event && 'eventID' in event) {\r\n\t\tid = event.eventID;\r\n\t}\r\n\treturn id;\r\n}\r\n\r\nexport const commands: Chat.ChatCommands = {\r\n\tevents: 'roomevents',\r\n\troomevent: 'roomevents',\r\n\troomevents: {\r\n\t\t''(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tif (!room.settings.events || !Object.keys(room.settings.events).length) {\r\n\t\t\t\treturn this.errorReply(\"There are currently no planned upcoming events for this room.\");\r\n\t\t\t}\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tconst hasAliases = getAliases(room).length > 0;\r\n\t\t\tconst hasCategories = getAllCategories(room).length > 0;\r\n\r\n\t\t\tlet buff = '';\r\n\t\t\tbuff += '';\r\n\t\t\tif (hasAliases) buff += '';\r\n\t\t\tif (hasCategories) buff += '';\r\n\t\t\tbuff += '';\r\n\r\n\t\t\tfor (const event of getAllEvents(room)) {\r\n\t\t\t\tbuff += formatEvent(room, event, hasAliases, hasCategories);\r\n\t\t\t}\r\n\t\t\tbuff += '
Event Name:Event Aliases:Event Categories:Event Description:Event Date:
';\r\n\t\t\treturn this.sendReply(`|raw|
${buff}
`);\r\n\t\t},\r\n\r\n\t\tnew: 'add',\r\n\t\tcreate: 'add',\r\n\t\tedit: 'add',\r\n\t\tadd(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tif (!room.settings.events) room.settings.events = Object.create(null);\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tconst events = room.settings.events!;\r\n\t\t\tconst [eventName, date, ...desc] = target.split(target.includes('|') ? '|' : ',');\r\n\r\n\t\t\tif (!(eventName && date && desc)) {\r\n\t\t\t\treturn this.errorReply(\"You're missing a command parameter - to see this command's syntax, use /help roomevents.\");\r\n\t\t\t}\r\n\r\n\t\t\tconst dateActual = date.trim();\r\n\t\t\tconst descString = desc.join(target.includes('|') ? '|' : ',').trim();\r\n\r\n\t\t\tif (eventName.trim().length > 50) return this.errorReply(\"Event names should not exceed 50 characters.\");\r\n\t\t\tif (dateActual.length > 150) return this.errorReply(\"Event dates should not exceed 150 characters.\");\r\n\t\t\tif (descString.length > 1000) return this.errorReply(\"Event descriptions should not exceed 1000 characters.\");\r\n\r\n\t\t\tconst eventId = getEventID(eventName, room);\r\n\t\t\tif (!eventId) return this.errorReply(\"Event names must contain at least one alphanumerical character.\");\r\n\r\n\t\t\tconst oldEvent = room.settings.events?.[eventId] as RoomEvent;\r\n\t\t\tif (oldEvent && 'events' in oldEvent) return this.errorReply(`\"${eventId}\" is already the name of a category.`);\r\n\r\n\t\t\tconst eventNameActual = (oldEvent ? oldEvent.eventName : eventName.trim());\r\n\t\t\tthis.privateModAction(`${user.name} ${oldEvent ? \"edited the\" : \"added a\"} roomevent titled \"${eventNameActual}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `${oldEvent ? \"edited\" : \"added\"} \"${eventNameActual}\"`);\r\n\t\t\tevents[eventId] = {\r\n\t\t\t\teventName: eventNameActual,\r\n\t\t\t\tdate: dateActual,\r\n\t\t\t\tdesc: descString,\r\n\t\t\t\tstarted: false,\r\n\t\t\t};\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\trename(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tlet [oldName, newName] = target.split(target.includes('|') ? '|' : ',');\r\n\t\t\tif (!(oldName && newName)) return this.errorReply(\"Usage: /roomevents rename [old name], [new name]\");\r\n\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tnewName = newName.trim();\r\n\t\t\tconst newID = toID(newName);\r\n\t\t\tconst oldID = (getAliases(room).includes(toID(oldName)) ? getEventID(oldName, room) : toID(oldName));\r\n\t\t\tif (newID === oldID) return this.errorReply(\"The new name must be different from the old one.\");\r\n\t\t\tif (!newID) return this.errorReply(\"Event names must contain at least one alphanumeric character.\");\r\n\t\t\tif (newName.length > 50) return this.errorReply(\"Event names should not exceed 50 characters.\");\r\n\r\n\t\t\tconst events = room.settings.events!;\r\n\t\t\tconst eventData = events?.[oldID];\r\n\t\t\tif (!(eventData && 'eventName' in eventData)) return this.errorReply(`There is no event titled \"${oldName}\".`);\r\n\t\t\tif (events?.[newID]) {\r\n\t\t\t\treturn this.errorReply(`\"${newName}\" is already an event, alias, or category.`);\r\n\t\t\t}\r\n\r\n\t\t\tconst originalName = eventData.eventName;\r\n\t\t\teventData.eventName = newName;\r\n\t\t\tevents[newID] = eventData;\r\n\t\t\tdelete events[oldID];\r\n\r\n\t\t\tthis.privateModAction(`${user.name} renamed the roomevent titled \"${originalName}\" to \"${newName}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `renamed \"${originalName}\" to \"${newName}\"`);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tbegin: 'start',\r\n\t\tstart(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tif (!room.settings.events || !Object.keys(room.settings.events).length) {\r\n\t\t\t\treturn this.errorReply(\"There are currently no planned upcoming events for this room to start.\");\r\n\t\t\t}\r\n\t\t\tif (!target) return this.errorReply(\"Usage: /roomevents start [event name]\");\r\n\t\t\tconvertAliasFormat(room);\r\n\r\n\t\t\ttarget = toID(target);\r\n\t\t\tconst event = room.settings.events[getEventID(target, room)];\r\n\t\t\tif (!(event && 'eventName' in event)) return this.errorReply(`There is no event titled '${target}'. Check spelling?`);\r\n\t\t\tif (event.started) {\r\n\t\t\t\treturn this.errorReply(`The event ${event.eventName} has already started.`);\r\n\t\t\t}\r\n\t\t\tfor (const u in room.users) {\r\n\t\t\t\tconst activeUser = Users.get(u);\r\n\t\t\t\tif (activeUser?.connected) {\r\n\t\t\t\t\tactiveUser.sendTo(\r\n\t\t\t\t\t\troom,\r\n\t\t\t\t\t\tUtils.html`|notify|A new roomevent in ${room.title} has started!|` +\r\n\t\t\t\t\t\t`The \"${event.eventName}\" roomevent has started!`\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.add(\r\n\t\t\t\tUtils.html`|raw|
The \"${event.eventName}\" roomevent has started!
`\r\n\t\t\t);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `started \"${toID(event.eventName)}\"`);\r\n\t\t\tevent.started = true;\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tdelete: 'remove',\r\n\t\tremove(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tif (!room.settings.events || Object.keys(room.settings.events).length === 0) {\r\n\t\t\t\treturn this.errorReply(\"There are currently no planned upcoming events for this room to remove.\");\r\n\t\t\t}\r\n\t\t\tif (!target) return this.errorReply(\"Usage: /roomevents remove [event name]\");\r\n\t\t\tconst eventID = toID(target);\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tif (getAliases(room).includes(eventID)) return this.errorReply(\"To delete aliases, use /roomevents removealias.\");\r\n\t\t\tif (!(room.settings.events[eventID] && 'eventName' in room.settings.events[eventID])) {\r\n\t\t\t\treturn this.errorReply(`There is no event titled '${target}'. Check spelling?`);\r\n\t\t\t}\r\n\r\n\t\t\tdelete room.settings.events[eventID];\r\n\t\t\tfor (const alias of getAliases(room, eventID)) {\r\n\t\t\t\tdelete room.settings.events[alias];\r\n\t\t\t}\r\n\t\t\tfor (const category of getAllCategories(room).map(cat => room!.settings.events?.[cat] as RoomEventCategory)) {\r\n\t\t\t\tcategory.events = category.events.filter(event => event !== eventID);\r\n\t\t\t}\r\n\r\n\t\t\tthis.privateModAction(`${user.name} removed a roomevent titled \"${target}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `removed \"${target}\"`);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tview(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tif (!room.settings.events || !Object.keys(room.settings.events).length) {\r\n\t\t\t\treturn this.errorReply(\"There are currently no planned upcoming events for this room.\");\r\n\t\t\t}\r\n\r\n\t\t\tif (!target) return this.errorReply(\"Usage: /roomevents view [event name, alias, or category]\");\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\ttarget = getEventID(target, room);\r\n\r\n\t\t\tlet events: RoomEvent[] = [];\r\n\t\t\tif (getAllCategories(room).includes(target)) {\r\n\t\t\t\tfor (const categoryID of Object.keys(room.settings.events)) {\r\n\t\t\t\t\tconst category = room.settings.events[categoryID];\r\n\t\t\t\t\tif ('events' in category && categoryID === target) {\r\n\t\t\t\t\t\tevents = category.events\r\n\t\t\t\t\t\t\t.map(e => room!.settings.events?.[e] as RoomEvent)\r\n\t\t\t\t\t\t\t.filter(e => e);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (room.settings.events[target] && 'eventName' in room.settings.events[target]) {\r\n\t\t\t\tevents.push(room.settings.events[target] as RoomEvent);\r\n\t\t\t} else {\r\n\t\t\t\treturn this.errorReply(`There is no event or category titled '${target}'. Check spelling?`);\r\n\t\t\t}\r\n\t\t\tif (!this.runBroadcast()) return;\r\n\t\t\tlet hasAliases = false;\r\n\t\t\tlet hasCategories = false;\r\n\r\n\t\t\tfor (const event of events) {\r\n\t\t\t\tif (getAliases(room, toID(event.eventName)).length) hasAliases = true;\r\n\t\t\t}\r\n\r\n\t\t\tfor (const potentialCategory of getAllCategories(room)) {\r\n\t\t\t\tif (\r\n\t\t\t\t\tevents.map(event => toID(event.eventName))\r\n\t\t\t\t\t\t.filter(id => (room!.settings.events?.[potentialCategory] as RoomEventCategory).events.includes(id)).length\r\n\t\t\t\t) hasCategories = true; break;\r\n\t\t\t}\r\n\r\n\t\t\tlet buff = '';\r\n\t\t\tbuff += '';\r\n\t\t\tif (hasAliases) buff += '';\r\n\t\t\tif (hasCategories) buff += '';\r\n\t\t\tbuff += '';\r\n\t\t\tfor (const event of events) {\r\n\t\t\t\tbuff += formatEvent(room, event, hasAliases, hasCategories);\r\n\t\t\t}\r\n\t\t\tbuff += '
Event Name:Event Aliases:Event Categories:Event Description:Event Date:
';\r\n\r\n\t\t\tthis.sendReply(`|raw|
${buff}
`);\r\n\t\t\tif (!this.broadcasting && user.can('ban', null, room, 'roomevents add') && events.length === 1) {\r\n\t\t\t\tconst event = events[0];\r\n\t\t\t\tthis.sendReplyBox(Utils.html`
Source/roomevents add ${event.eventName} | ${event.date} | ${event.desc}
`.replace(/\\n/g, '
'));\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\talias: 'addalias',\r\n\t\taddalias(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tconst [alias, eventId] = target.split(target.includes('|') ? '|' : ',').map(argument => toID(argument));\r\n\t\t\tif (!(alias && eventId)) {\r\n\t\t\t\treturn this.errorReply(\"Usage: /roomevents addalias [alias], [event name]. Aliases must contain at least one alphanumeric character.\");\r\n\t\t\t}\r\n\t\t\tif (!room.settings.events || Object.keys(room.settings.events).length === 0) {\r\n\t\t\t\treturn this.errorReply(`There are currently no scheduled events.`);\r\n\t\t\t}\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tconst event = room.settings.events[eventId];\r\n\t\t\tif (!(event && 'eventName' in event)) return this.errorReply(`There is no event titled \"${eventId}\".`);\r\n\t\t\tif (room.settings.events[alias]) return this.errorReply(`\"${alias}\" is already an event, alias, or category.`);\r\n\r\n\t\t\troom.settings.events[alias] = {eventID: eventId};\r\n\t\t\tthis.privateModAction(`${user.name} added an alias \"${alias}\" for the roomevent \"${eventId}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `alias for \"${eventId}\": \"${alias}\"`);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tdeletealias: 'removealias',\r\n\t\tremovealias(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\ttarget = toID(target);\r\n\t\t\tif (!target) return this.errorReply(\"Usage: /roomevents removealias \");\r\n\t\t\tif (!room.settings.events || Object.keys(room.settings.events).length === 0) {\r\n\t\t\t\treturn this.errorReply(`There are currently no scheduled events.`);\r\n\t\t\t}\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tif (!(room.settings.events[target] && 'eventID' in room.settings.events[target])) {\r\n\t\t\t\treturn this.errorReply(`${target} isn't an alias.`);\r\n\t\t\t}\r\n\t\t\tdelete room.settings.events[target];\r\n\r\n\t\t\tthis.privateModAction(`${user.name} removed the alias \"${target}\"`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `removed the alias \"${target}\"`);\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\taddtocategory(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tconst [eventId, categoryId] = target.split(target.includes('|') ? '|' : ',').map(argument => toID(argument));\r\n\t\t\tif (!(eventId && categoryId)) return this.errorReply(\"Usage: /roomevents addtocategory [event name], [category].\");\r\n\t\t\tif (!room.settings.events || Object.keys(room.settings.events).length === 0) {\r\n\t\t\t\treturn this.errorReply(`There are currently no scheduled events.`);\r\n\t\t\t}\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tconst event = room.settings.events[getEventID(eventId, room)];\r\n\t\t\tif (!(event && 'eventName' in event)) return this.errorReply(`There is no event or alias titled \"${eventId}\".`);\r\n\t\t\tconst category = room.settings.events[categoryId];\r\n\t\t\tif (category && !('events' in category)) {\r\n\t\t\t\treturn this.errorReply(`There is already an event or alias titled \"${categoryId}\".`);\r\n\t\t\t}\r\n\t\t\tif (!category) {\r\n\t\t\t\treturn this.errorReply(`There is no category titled \"${categoryId}\". To create it, use /roomevents addcategory ${categoryId}.`);\r\n\t\t\t}\r\n\t\t\tif (category.events.includes(toID(event.eventName))) {\r\n\t\t\t\treturn this.errorReply(`The event \"${eventId}\" is already in the \"${categoryId}\" category.`);\r\n\t\t\t}\r\n\t\t\tcategory.events.push(toID(event.eventName));\r\n\t\t\troom.settings.events[categoryId] = category;\r\n\r\n\t\t\tthis.privateModAction(`${user.name} added the roomevent \"${eventId}\" to the category \"${categoryId}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `category for \"${eventId}\": \"${categoryId}\"`);\r\n\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tremovefromcategory(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tconst [eventId, categoryId] = target.split(target.includes('|') ? '|' : ',').map(argument => toID(argument));\r\n\t\t\tif (!(eventId && categoryId)) {\r\n\t\t\t\treturn this.errorReply(\"Usage: /roomevents removefromcategory [event name], [category].\");\r\n\t\t\t}\r\n\t\t\tif (!room.settings.events || Object.keys(room.settings.events).length === 0) {\r\n\t\t\t\treturn this.errorReply(`There are currently no scheduled events.`);\r\n\t\t\t}\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tconst event = room.settings.events[getEventID(eventId, room)];\r\n\t\t\tif (!(event && 'eventName' in event)) return this.errorReply(`There is no event or alias titled \"${eventId}\".`);\r\n\r\n\t\t\tconst category = room.settings.events[categoryId];\r\n\t\t\tif (category && !('events' in category)) {\r\n\t\t\t\treturn this.errorReply(`There is already an event or alias titled \"${categoryId}\".`);\r\n\t\t\t}\r\n\t\t\tif (!category) return this.errorReply(`There is no category titled \"${categoryId}\".`);\r\n\r\n\t\t\tif (!category.events.includes(toID(event.eventName))) {\r\n\t\t\t\treturn this.errorReply(`The event \"${eventId}\" isn't in the \"${categoryId}\" category.`);\r\n\t\t\t}\r\n\t\t\tcategory.events = category.events.filter(e => e !== eventId);\r\n\t\t\troom.settings.events[categoryId] = category;\r\n\r\n\t\t\tthis.privateModAction(`${user.name} removed the roomevent \"${eventId}\" from the category \"${categoryId}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `category for \"${eventId}\": removed \"${categoryId}\"`);\r\n\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\taddcat: 'addcategory',\r\n\t\taddcategory(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tconst categoryId = toID(target);\r\n\t\t\tif (!target) {\r\n\t\t\t\treturn this.errorReply(\"Usage: /roomevents addcategory [category name]. Categories must contain at least one alphanumeric character.\");\r\n\t\t\t}\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tif (!room.settings.events) room.settings.events = Object.create(null);\r\n\t\t\tif (room.settings.events?.[categoryId]) return this.errorReply(`The category \"${target}\" already exists.`);\r\n\r\n\t\t\troom.settings.events![categoryId] = {events: []};\r\n\r\n\t\t\tthis.privateModAction(`${user.name} added the category \"${categoryId}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `category: added \"${categoryId}\"`);\r\n\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tdeletecategory: 'removecategory',\r\n\t\tdeletecat: 'removecategory',\r\n\t\tremovecat: 'removecategory',\r\n\t\trmcat: 'removecategory',\r\n\t\tremovecategory(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\t\t\tconst categoryId = toID(target);\r\n\t\t\tif (!target) return this.errorReply(\"Usage: /roomevents removecategory [category name].\");\r\n\t\t\tconvertAliasFormat(room);\r\n\t\t\tif (!room.settings.events) room.settings.events = Object.create(null);\r\n\t\t\tif (!room.settings.events?.[categoryId]) return this.errorReply(`The category \"${target}\" doesn't exist.`);\r\n\r\n\t\t\tdelete room.settings.events?.[categoryId];\r\n\r\n\t\t\tthis.privateModAction(`${user.name} removed the category \"${categoryId}\".`);\r\n\t\t\tthis.modlog('ROOMEVENT', null, `category: removed \"${categoryId}\"`);\r\n\r\n\t\t\troom.saveSettings();\r\n\t\t},\r\n\r\n\t\tviewcategories: 'categories',\r\n\t\tcategories(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tthis.runBroadcast();\r\n\r\n\t\t\tconst categoryButtons = getAllCategories(room).map(\r\n\t\t\t\tcategory => ``\r\n\t\t\t);\r\n\t\t\tif (!categoryButtons.length) return this.errorReply(`There are no roomevent categories in ${room.title}.`);\r\n\t\t\tthis.sendReplyBox(`Roomevent categories in ${room.title}: ${categoryButtons.join(' ')}`);\r\n\t\t},\r\n\r\n\t\thelp(target, room, user) {\r\n\t\t\treturn this.parse('/help roomevents');\r\n\t\t},\r\n\r\n\t\tsortby(target, room, user) {\r\n\t\t\troom = this.requireRoom();\r\n\t\t\t// preconditions\r\n\t\t\tif (!room.persist) return this.errorReply(\"This command is unavailable in temporary rooms.\");\r\n\t\t\tif (!room.settings.events || !Object.keys(room.settings.events).length) {\r\n\t\t\t\treturn this.errorReply(\"There are currently no planned upcoming events for this room.\");\r\n\t\t\t}\r\n\t\t\tthis.checkCan('ban', null, room);\r\n\r\n\t\t\t// declare variables\r\n\t\t\tlet multiplier = 1;\r\n\t\t\tlet columnName = \"\";\r\n\t\t\tconst delimited = target.split(target.includes('|') ? '|' : ',');\r\n\t\t\tconst sortable = Object.values(room.settings.events)\r\n\t\t\t\t.filter(event => 'eventName' in event)\r\n\t\t\t\t.map(event => event as RoomEvent);\r\n\r\n\t\t\t// id tokens\r\n\t\t\tif (delimited.length === 1) {\r\n\t\t\t\tcolumnName = target;\r\n\t\t\t} else {\r\n\t\t\t\tlet order = \"\";\r\n\t\t\t\t[columnName, order] = delimited;\r\n\t\t\t\torder = toID(order);\r\n\t\t\t\tmultiplier = (order === 'desc') ? -1 : 1;\r\n\t\t\t}\r\n\r\n\t\t\t// sort the array by the appropriate column name\r\n\t\t\tcolumnName = toID(columnName);\r\n\t\t\tswitch (columnName) {\r\n\t\t\tcase \"date\":\r\n\t\t\tcase \"eventdate\":\r\n\t\t\t\tsortable.sort(\r\n\t\t\t\t\t(a, b) =>\r\n\t\t\t\t\t\t(toID(a.date) < toID(b.date)) ? -1 * multiplier :\r\n\t\t\t\t\t\t(toID(b.date) < toID(a.date)) ? 1 * multiplier : 0\r\n\t\t\t\t);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"desc\":\r\n\t\t\tcase \"description\":\r\n\t\t\tcase \"eventdescription\":\r\n\t\t\t\tsortable.sort(\r\n\t\t\t\t\t(a, b) =>\r\n\t\t\t\t\t\t(toID(a.desc) < toID(b.desc)) ? -1 * multiplier :\r\n\t\t\t\t\t\t(toID(b.desc) < toID(a.desc)) ? 1 * multiplier : 0\r\n\t\t\t\t);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"eventname\":\r\n\t\t\tcase \"name\":\r\n\t\t\t\tsortable.sort(\r\n\t\t\t\t\t(a, b) =>\r\n\t\t\t\t\t\t(toID(a.eventName) < toID(b.eventName)) ? -1 * multiplier :\r\n\t\t\t\t\t\t(toID(b.eventName) < toID(a.eventName)) ? 1 * multiplier : 0\r\n\t\t\t\t);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\treturn this.errorReply(`Invalid column name \"${columnName}\". Please use one of: date, desc, name.`);\r\n\t\t\t}\r\n\r\n\t\t\t// rebuild the room.settings.events object\r\n\t\t\tfor (const sortedObj of sortable) {\r\n\t\t\t\tconst eventId = toID(sortedObj.eventName);\r\n\t\t\t\tdelete room.settings.events[eventId];\r\n\t\t\t\troom.settings.events[eventId] = sortedObj;\r\n\t\t\t}\r\n\r\n\t\t\t// build communication string\r\n\t\t\tconst resultString = `sorted by column: ${columnName}` +\r\n\t\t\t\t` in ${multiplier === 1 ? \"ascending\" : \"descending\"} order` +\r\n\t\t\t\t`${delimited.length === 1 ? \" (by default)\" : \"\"}`;\r\n\t\t\tthis.modlog('ROOMEVENT', null, resultString);\r\n\t\t\treturn this.sendReply(resultString);\r\n\t\t},\r\n\t},\r\n\troomeventshelp() {\r\n\t\tthis.sendReply(\r\n\t\t\t`|html|
/roomevents: displays a list of upcoming room-specific events.
` +\r\n\t\t\t`/roomevents add [event name] | [event date/time] | [event description]: adds a room event. A timestamp in event date/time field like YYYY-MM-DD HH:MM\u00B1hh:mm will be displayed in user's timezone. Requires: @ # &
` +\r\n\t\t\t`/roomevents start [event name]: declares to the room that the event has started. Requires: @ # &
` +\r\n\t\t\t`/roomevents remove [event name]: deletes an event. Requires: @ # &
` +\r\n\t\t\t`/roomevents rename [old event name] | [new name]: renames an event. Requires: @ # &
` +\r\n\t\t\t`/roomevents addalias [alias] | [event name]: adds an alias for the event. Requires: @ # &
` +\r\n\t\t\t`/roomevents removealias [alias]: removes an event alias. Requires: @ # &
` +\r\n\t\t\t`/roomevents addcategory [category]: adds an event category. Requires: @ # &
` +\r\n\t\t\t`/roomevents removecategory [category]: removes an event category. Requires: @ # &
` +\r\n\t\t\t`/roomevents addtocategory [event name] | [category]: adds the event to a category. Requires: @ # &
` +\r\n\t\t\t`/roomevents removefromcategory [event name] | [category]: removes the event from a category. Requires: @ # &
` +\r\n\t\t\t`/roomevents sortby [column name] | [asc/desc (optional)] sorts events table by column name and an optional argument to ascending or descending order. Ascending order is default. Requires: @ # &
` +\r\n\t\t\t`/roomevents view [event name or category]: displays information about a specific event or category of events.
` +\r\n\t\t\t`/roomevents viewcategories: displays a list of event categories for that room.` +\r\n\t\t\t`
`\r\n\t\t);\r\n\t},\r\n};\r\n"], "mappings": "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", "names": [] }