"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var room_events_exports = {}; __export(room_events_exports, { commands: () => commands }); module.exports = __toCommonJS(room_events_exports); var import_lib = require("../../lib"); /** * Room Events Plugin * Pokemon Showdown - http://pokemonshowdown.com/ * * This is a room-management system to keep track of upcoming room events. * * @license MIT license */ function convertAliasFormat(room) { if (!room.settings.events) return; for (const event of Object.values(room.settings.events)) { if (!event.aliases) continue; for (const alias of event.aliases) { room.settings.events[alias] = { eventID: toID(event.eventName) }; } delete event.aliases; } } function formatEvent(room, event, showAliases, showCategories) { const timeRemaining = new Date(event.date).getTime() - new Date().getTime(); let explanation = timeRemaining.toString(); if (!timeRemaining) explanation = "The time remaining for this event is not available"; if (timeRemaining < 0) explanation = "This event will start soon"; if (event.started) explanation = "This event has started"; if (!isNaN(timeRemaining)) { explanation = `This event will start in: ${Chat.toDurationString(timeRemaining, { precision: 2 })}`; } const eventID = toID(event.eventName); const aliases = getAliases(room, eventID); const categories = getAllCategories(room).filter( (category) => room.settings.events[category].events.includes(eventID) ); let ret = ``; ret += import_lib.Utils.html`${event.eventName}`; if (showAliases) ret += import_lib.Utils.html`${aliases.join(", ")}`; if (showCategories) ret += import_lib.Utils.html`${categories.join(", ")}`; ret += `${Chat.formatText(event.desc, true)}`; ret += import_lib.Utils.html``; return ret; } function getAliases(room, eventID) { if (!room.settings.events) return []; const aliases = []; for (const aliasID in room.settings.events) { if ("eventID" in room.settings.events[aliasID] && (!eventID || room.settings.events[aliasID].eventID === eventID)) aliases.push(aliasID); } return aliases; } function getAllCategories(room) { if (!room.settings.events) return []; const categories = []; for (const categoryID in room.settings.events) { if ("events" in room.settings.events[categoryID]) categories.push(categoryID); } return categories; } function getAllEvents(room) { if (!room.settings.events) return []; const events = []; for (const event of Object.values(room.settings.events)) { if ("eventName" in event) events.push(event); } return events; } function getEventID(nameOrAlias, room) { let id = toID(nameOrAlias); const event = room.settings.events?.[id]; if (event && "eventID" in event) { id = event.eventID; } return id; } const commands = { events: "roomevents", roomevent: "roomevents", roomevents: { ""(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); if (!room.settings.events || !Object.keys(room.settings.events).length) { return this.errorReply("There are currently no planned upcoming events for this room."); } if (!this.runBroadcast()) return; convertAliasFormat(room); const hasAliases = getAliases(room).length > 0; const hasCategories = getAllCategories(room).length > 0; let buff = ''; buff += ""; if (hasAliases) buff += ""; if (hasCategories) buff += ""; buff += ""; for (const event of getAllEvents(room)) { buff += formatEvent(room, event, hasAliases, hasCategories); } buff += "
Event Name:Event Aliases:Event Categories:Event Description:Event Date:
"; return this.sendReply(`|raw|
${buff}
`); }, new: "add", create: "add", edit: "add", add(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); if (!room.settings.events) room.settings.events = /* @__PURE__ */ Object.create(null); convertAliasFormat(room); const events = room.settings.events; const [eventName, date, ...desc] = target.split(target.includes("|") ? "|" : ","); if (!(eventName && date && desc)) { return this.errorReply("You're missing a command parameter - to see this command's syntax, use /help roomevents."); } const dateActual = date.trim(); const descString = desc.join(target.includes("|") ? "|" : ",").trim(); if (eventName.trim().length > 50) return this.errorReply("Event names should not exceed 50 characters."); if (dateActual.length > 150) return this.errorReply("Event dates should not exceed 150 characters."); if (descString.length > 1e3) return this.errorReply("Event descriptions should not exceed 1000 characters."); const eventId = getEventID(eventName, room); if (!eventId) return this.errorReply("Event names must contain at least one alphanumerical character."); const oldEvent = room.settings.events?.[eventId]; if (oldEvent && "events" in oldEvent) return this.errorReply(`"${eventId}" is already the name of a category.`); const eventNameActual = oldEvent ? oldEvent.eventName : eventName.trim(); this.privateModAction(`${user.name} ${oldEvent ? "edited the" : "added a"} roomevent titled "${eventNameActual}".`); this.modlog("ROOMEVENT", null, `${oldEvent ? "edited" : "added"} "${eventNameActual}"`); events[eventId] = { eventName: eventNameActual, date: dateActual, desc: descString, started: false }; room.saveSettings(); }, rename(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); let [oldName, newName] = target.split(target.includes("|") ? "|" : ","); if (!(oldName && newName)) return this.errorReply("Usage: /roomevents rename [old name], [new name]"); convertAliasFormat(room); newName = newName.trim(); const newID = toID(newName); const oldID = getAliases(room).includes(toID(oldName)) ? getEventID(oldName, room) : toID(oldName); if (newID === oldID) return this.errorReply("The new name must be different from the old one."); if (!newID) return this.errorReply("Event names must contain at least one alphanumeric character."); if (newName.length > 50) return this.errorReply("Event names should not exceed 50 characters."); const events = room.settings.events; const eventData = events?.[oldID]; if (!(eventData && "eventName" in eventData)) return this.errorReply(`There is no event titled "${oldName}".`); if (events?.[newID]) { return this.errorReply(`"${newName}" is already an event, alias, or category.`); } const originalName = eventData.eventName; eventData.eventName = newName; events[newID] = eventData; delete events[oldID]; this.privateModAction(`${user.name} renamed the roomevent titled "${originalName}" to "${newName}".`); this.modlog("ROOMEVENT", null, `renamed "${originalName}" to "${newName}"`); room.saveSettings(); }, begin: "start", start(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); if (!room.settings.events || !Object.keys(room.settings.events).length) { return this.errorReply("There are currently no planned upcoming events for this room to start."); } if (!target) return this.errorReply("Usage: /roomevents start [event name]"); convertAliasFormat(room); target = toID(target); const event = room.settings.events[getEventID(target, room)]; if (!(event && "eventName" in event)) return this.errorReply(`There is no event titled '${target}'. Check spelling?`); if (event.started) { return this.errorReply(`The event ${event.eventName} has already started.`); } for (const u in room.users) { const activeUser = Users.get(u); if (activeUser?.connected) { activeUser.sendTo( room, import_lib.Utils.html`|notify|A new roomevent in ${room.title} has started!|` + `The "${event.eventName}" roomevent has started!` ); } } this.add( import_lib.Utils.html`|raw|
The "${event.eventName}" roomevent has started!
` ); this.modlog("ROOMEVENT", null, `started "${toID(event.eventName)}"`); event.started = true; room.saveSettings(); }, delete: "remove", remove(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); if (!room.settings.events || Object.keys(room.settings.events).length === 0) { return this.errorReply("There are currently no planned upcoming events for this room to remove."); } if (!target) return this.errorReply("Usage: /roomevents remove [event name]"); const eventID = toID(target); convertAliasFormat(room); if (getAliases(room).includes(eventID)) return this.errorReply("To delete aliases, use /roomevents removealias."); if (!(room.settings.events[eventID] && "eventName" in room.settings.events[eventID])) { return this.errorReply(`There is no event titled '${target}'. Check spelling?`); } delete room.settings.events[eventID]; for (const alias of getAliases(room, eventID)) { delete room.settings.events[alias]; } for (const category of getAllCategories(room).map((cat) => room.settings.events?.[cat])) { category.events = category.events.filter((event) => event !== eventID); } this.privateModAction(`${user.name} removed a roomevent titled "${target}".`); this.modlog("ROOMEVENT", null, `removed "${target}"`); room.saveSettings(); }, view(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); if (!room.settings.events || !Object.keys(room.settings.events).length) { return this.errorReply("There are currently no planned upcoming events for this room."); } if (!target) return this.errorReply("Usage: /roomevents view [event name, alias, or category]"); convertAliasFormat(room); target = getEventID(target, room); let events = []; if (getAllCategories(room).includes(target)) { for (const categoryID of Object.keys(room.settings.events)) { const category = room.settings.events[categoryID]; if ("events" in category && categoryID === target) { events = category.events.map((e) => room.settings.events?.[e]).filter((e) => e); break; } } } else if (room.settings.events[target] && "eventName" in room.settings.events[target]) { events.push(room.settings.events[target]); } else { return this.errorReply(`There is no event or category titled '${target}'. Check spelling?`); } if (!this.runBroadcast()) return; let hasAliases = false; let hasCategories = false; for (const event of events) { if (getAliases(room, toID(event.eventName)).length) hasAliases = true; } for (const potentialCategory of getAllCategories(room)) { if (events.map((event) => toID(event.eventName)).filter((id) => (room.settings.events?.[potentialCategory]).events.includes(id)).length) hasCategories = true; break; } let buff = ''; buff += ""; if (hasAliases) buff += ""; if (hasCategories) buff += ""; buff += ""; for (const event of events) { buff += formatEvent(room, event, hasAliases, hasCategories); } buff += "
Event Name:Event Aliases:Event Categories:Event Description:Event Date:
"; this.sendReply(`|raw|
${buff}
`); if (!this.broadcasting && user.can("ban", null, room, "roomevents add") && events.length === 1) { const event = events[0]; this.sendReplyBox(import_lib.Utils.html`
Source/roomevents add ${event.eventName} | ${event.date} | ${event.desc}
`.replace(/\n/g, "
")); } }, alias: "addalias", addalias(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); const [alias, eventId] = target.split(target.includes("|") ? "|" : ",").map((argument) => toID(argument)); if (!(alias && eventId)) { return this.errorReply("Usage: /roomevents addalias [alias], [event name]. Aliases must contain at least one alphanumeric character."); } if (!room.settings.events || Object.keys(room.settings.events).length === 0) { return this.errorReply(`There are currently no scheduled events.`); } convertAliasFormat(room); const event = room.settings.events[eventId]; if (!(event && "eventName" in event)) return this.errorReply(`There is no event titled "${eventId}".`); if (room.settings.events[alias]) return this.errorReply(`"${alias}" is already an event, alias, or category.`); room.settings.events[alias] = { eventID: eventId }; this.privateModAction(`${user.name} added an alias "${alias}" for the roomevent "${eventId}".`); this.modlog("ROOMEVENT", null, `alias for "${eventId}": "${alias}"`); room.saveSettings(); }, deletealias: "removealias", removealias(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); target = toID(target); if (!target) return this.errorReply("Usage: /roomevents removealias "); if (!room.settings.events || Object.keys(room.settings.events).length === 0) { return this.errorReply(`There are currently no scheduled events.`); } convertAliasFormat(room); if (!(room.settings.events[target] && "eventID" in room.settings.events[target])) { return this.errorReply(`${target} isn't an alias.`); } delete room.settings.events[target]; this.privateModAction(`${user.name} removed the alias "${target}"`); this.modlog("ROOMEVENT", null, `removed the alias "${target}"`); room.saveSettings(); }, addtocategory(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); const [eventId, categoryId] = target.split(target.includes("|") ? "|" : ",").map((argument) => toID(argument)); if (!(eventId && categoryId)) return this.errorReply("Usage: /roomevents addtocategory [event name], [category]."); if (!room.settings.events || Object.keys(room.settings.events).length === 0) { return this.errorReply(`There are currently no scheduled events.`); } convertAliasFormat(room); const event = room.settings.events[getEventID(eventId, room)]; if (!(event && "eventName" in event)) return this.errorReply(`There is no event or alias titled "${eventId}".`); const category = room.settings.events[categoryId]; if (category && !("events" in category)) { return this.errorReply(`There is already an event or alias titled "${categoryId}".`); } if (!category) { return this.errorReply(`There is no category titled "${categoryId}". To create it, use /roomevents addcategory ${categoryId}.`); } if (category.events.includes(toID(event.eventName))) { return this.errorReply(`The event "${eventId}" is already in the "${categoryId}" category.`); } category.events.push(toID(event.eventName)); room.settings.events[categoryId] = category; this.privateModAction(`${user.name} added the roomevent "${eventId}" to the category "${categoryId}".`); this.modlog("ROOMEVENT", null, `category for "${eventId}": "${categoryId}"`); room.saveSettings(); }, removefromcategory(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); const [eventId, categoryId] = target.split(target.includes("|") ? "|" : ",").map((argument) => toID(argument)); if (!(eventId && categoryId)) { return this.errorReply("Usage: /roomevents removefromcategory [event name], [category]."); } if (!room.settings.events || Object.keys(room.settings.events).length === 0) { return this.errorReply(`There are currently no scheduled events.`); } convertAliasFormat(room); const event = room.settings.events[getEventID(eventId, room)]; if (!(event && "eventName" in event)) return this.errorReply(`There is no event or alias titled "${eventId}".`); const category = room.settings.events[categoryId]; if (category && !("events" in category)) { return this.errorReply(`There is already an event or alias titled "${categoryId}".`); } if (!category) return this.errorReply(`There is no category titled "${categoryId}".`); if (!category.events.includes(toID(event.eventName))) { return this.errorReply(`The event "${eventId}" isn't in the "${categoryId}" category.`); } category.events = category.events.filter((e) => e !== eventId); room.settings.events[categoryId] = category; this.privateModAction(`${user.name} removed the roomevent "${eventId}" from the category "${categoryId}".`); this.modlog("ROOMEVENT", null, `category for "${eventId}": removed "${categoryId}"`); room.saveSettings(); }, addcat: "addcategory", addcategory(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); const categoryId = toID(target); if (!target) { return this.errorReply("Usage: /roomevents addcategory [category name]. Categories must contain at least one alphanumeric character."); } convertAliasFormat(room); if (!room.settings.events) room.settings.events = /* @__PURE__ */ Object.create(null); if (room.settings.events?.[categoryId]) return this.errorReply(`The category "${target}" already exists.`); room.settings.events[categoryId] = { events: [] }; this.privateModAction(`${user.name} added the category "${categoryId}".`); this.modlog("ROOMEVENT", null, `category: added "${categoryId}"`); room.saveSettings(); }, deletecategory: "removecategory", deletecat: "removecategory", removecat: "removecategory", rmcat: "removecategory", removecategory(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.checkCan("ban", null, room); const categoryId = toID(target); if (!target) return this.errorReply("Usage: /roomevents removecategory [category name]."); convertAliasFormat(room); if (!room.settings.events) room.settings.events = /* @__PURE__ */ Object.create(null); if (!room.settings.events?.[categoryId]) return this.errorReply(`The category "${target}" doesn't exist.`); delete room.settings.events?.[categoryId]; this.privateModAction(`${user.name} removed the category "${categoryId}".`); this.modlog("ROOMEVENT", null, `category: removed "${categoryId}"`); room.saveSettings(); }, viewcategories: "categories", categories(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); this.runBroadcast(); const categoryButtons = getAllCategories(room).map( (category) => `` ); if (!categoryButtons.length) return this.errorReply(`There are no roomevent categories in ${room.title}.`); this.sendReplyBox(`Roomevent categories in ${room.title}: ${categoryButtons.join(" ")}`); }, help(target, room, user) { return this.parse("/help roomevents"); }, sortby(target, room, user) { room = this.requireRoom(); if (!room.persist) return this.errorReply("This command is unavailable in temporary rooms."); if (!room.settings.events || !Object.keys(room.settings.events).length) { return this.errorReply("There are currently no planned upcoming events for this room."); } this.checkCan("ban", null, room); let multiplier = 1; let columnName = ""; const delimited = target.split(target.includes("|") ? "|" : ","); const sortable = Object.values(room.settings.events).filter((event) => "eventName" in event).map((event) => event); if (delimited.length === 1) { columnName = target; } else { let order = ""; [columnName, order] = delimited; order = toID(order); multiplier = order === "desc" ? -1 : 1; } columnName = toID(columnName); switch (columnName) { case "date": case "eventdate": sortable.sort( (a, b) => toID(a.date) < toID(b.date) ? -1 * multiplier : toID(b.date) < toID(a.date) ? 1 * multiplier : 0 ); break; case "desc": case "description": case "eventdescription": sortable.sort( (a, b) => toID(a.desc) < toID(b.desc) ? -1 * multiplier : toID(b.desc) < toID(a.desc) ? 1 * multiplier : 0 ); break; case "eventname": case "name": sortable.sort( (a, b) => toID(a.eventName) < toID(b.eventName) ? -1 * multiplier : toID(b.eventName) < toID(a.eventName) ? 1 * multiplier : 0 ); break; default: return this.errorReply(`Invalid column name "${columnName}". Please use one of: date, desc, name.`); } for (const sortedObj of sortable) { const eventId = toID(sortedObj.eventName); delete room.settings.events[eventId]; room.settings.events[eventId] = sortedObj; } const resultString = `sorted by column: ${columnName} in ${multiplier === 1 ? "ascending" : "descending"} order${delimited.length === 1 ? " (by default)" : ""}`; this.modlog("ROOMEVENT", null, resultString); return this.sendReply(resultString); } }, roomeventshelp() { this.sendReply( `|html|
/roomevents: displays a list of upcoming room-specific events.
/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\xB1hh:mm will be displayed in user's timezone. Requires: @ # &
/roomevents start [event name]: declares to the room that the event has started. Requires: @ # &
/roomevents remove [event name]: deletes an event. Requires: @ # &
/roomevents rename [old event name] | [new name]: renames an event. Requires: @ # &
/roomevents addalias [alias] | [event name]: adds an alias for the event. Requires: @ # &
/roomevents removealias [alias]: removes an event alias. Requires: @ # &
/roomevents addcategory [category]: adds an event category. Requires: @ # &
/roomevents removecategory [category]: removes an event category. Requires: @ # &
/roomevents addtocategory [event name] | [category]: adds the event to a category. Requires: @ # &
/roomevents removefromcategory [event name] | [category]: removes the event from a category. Requires: @ # &
/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: @ # &
/roomevents view [event name or category]: displays information about a specific event or category of events.
/roomevents viewcategories: displays a list of event categories for that room.
` ); } }; //# sourceMappingURL=room-events.js.map