Spaces:
Running
Running
/* | |
* Announcements chat plugin | |
* By Spandamn | |
*/ | |
export interface AnnouncementOptions { | |
activityNumber?: number; | |
source: string; | |
timeoutMins?: number; | |
timerEnd?: number; | |
} | |
export interface AnnouncementData extends AnnouncementOptions { | |
readonly activityid: 'announcement'; | |
} | |
export class Announcement extends Rooms.MinorActivity { | |
readonly activityid = 'announcement' as ID; | |
name = 'Announcement'; | |
activityNumber: number; | |
source: string; | |
constructor(room: Room, options: AnnouncementOptions) { | |
super(room); | |
this.activityNumber = options.activityNumber || room.nextGameNumber(); | |
this.source = options.source; | |
this.setTimer(options); | |
} | |
generateAnnouncement() { | |
return `<div class="broadcast-blue"><p style="margin: 2px 0 5px 0"><strong style="font-size:11pt">${this.source}</strong></p></div>`; | |
} | |
displayTo(user: User, connection: Connection | null = null) { | |
const recipient = connection || user; | |
recipient.sendTo(this.room, `|uhtml|announcement${this.activityNumber}|${this.generateAnnouncement()}`); | |
} | |
display() { | |
const announcement = this.generateAnnouncement(); | |
for (const id in this.room.users) { | |
const thisUser = this.room.users[id]; | |
thisUser.sendTo(this.room, `|uhtml|announcement${this.activityNumber}|${announcement}`); | |
} | |
} | |
onConnect(user: User, connection: Connection | null = null) { | |
this.displayTo(user, connection); | |
} | |
destroy() { | |
this.room.send(`|uhtmlchange|announcement${this.activityNumber}|<div class="infobox">(${this.room.tr`The announcement has ended.`})</div>`); | |
this.room.setMinorActivity(null); | |
} | |
toJSON(): AnnouncementData { | |
return { | |
source: this.source, | |
activityNumber: this.activityNumber, | |
timeoutMins: this.timeoutMins, | |
timerEnd: this.timerEnd, | |
activityid: 'announcement', | |
}; | |
} | |
save() { | |
this.room.settings.minorActivity = this.toJSON(); | |
this.room.saveSettings(); | |
} | |
} | |
export const commands: Chat.ChatCommands = { | |
announcement: { | |
htmlcreate: 'new', | |
create: 'new', | |
new(target, room, user, connection, cmd, message) { | |
room = this.requireRoom(); | |
if (!target) return this.parse('/help announcement new'); | |
target = target.trim(); | |
if (room.battle) return this.errorReply(this.tr`Battles do not support announcements.`); | |
const text = this.filter(target); | |
if (target !== text) return this.errorReply(this.tr`You are not allowed to use filtered words in announcements.`); | |
const supportHTML = cmd === 'htmlcreate'; | |
this.checkCan('minigame', null, room); | |
if (supportHTML) this.checkCan('declare', null, room); | |
this.checkChat(); | |
if (room.minorActivity) { | |
return this.errorReply(this.tr`There is already a poll or announcement in progress in this room.`); | |
} | |
const source = supportHTML ? this.checkHTML(Chat.collapseLineBreaksHTML(target)) : Chat.formatText(target, true); | |
room.setMinorActivity(new Announcement(room, { source })); | |
this.roomlog(`${user.name} used ${message}`); | |
this.modlog('ANNOUNCEMENT'); | |
return this.privateModAction(room.tr`An announcement was started by ${user.name}.`); | |
}, | |
newhelp: [`/announcement create [announcement] - Creates an announcement. Requires: % @ # ~`], | |
htmledit: 'edit', | |
edit(target, room, user, connection, cmd, message) { | |
room = this.requireRoom(); | |
const announcement = this.requireMinorActivity(Announcement); | |
if (!target) return this.parse('/help announcement edit'); | |
target = target.trim(); | |
const text = this.filter(target); | |
if (target !== text) return this.errorReply(this.tr`You are not allowed to use filtered words in announcements.`); | |
const supportHTML = cmd === 'htmledit'; | |
this.checkCan('minigame', null, room); | |
if (supportHTML) this.checkCan('declare', null, room); | |
this.checkChat(); | |
const source = supportHTML ? this.checkHTML(Chat.collapseLineBreaksHTML(target)) : Chat.formatText(target, true); | |
announcement.source = source; | |
announcement.save(); | |
this.roomlog(`${user.name} used ${message}`); | |
this.modlog('ANNOUNCEMENT EDIT'); | |
this.privateModAction(room.tr`The announcement was edited by ${user.name}.`); | |
this.parse('/announcement display'); | |
}, | |
edithelp: [`/announcement edit [announcement] - Edits the announcement. Requires: % @ # ~`], | |
timer(target, room, user) { | |
room = this.requireRoom(); | |
const announcement = this.requireMinorActivity(Announcement); | |
if (target) { | |
this.checkCan('minigame', null, room); | |
if (target === 'clear') { | |
if (!announcement.endTimer()) return this.errorReply(this.tr`There is no timer to clear.`); | |
return this.add(this.tr`The announcement timer was turned off.`); | |
} | |
const timeoutMins = parseFloat(target); | |
if (isNaN(timeoutMins) || timeoutMins <= 0 || timeoutMins > 7 * 24 * 60) { | |
return this.errorReply(this.tr`Time should be a number of minutes less than one week.`); | |
} | |
announcement.setTimer({ timeoutMins }); | |
room.add(`The announcement timer was turned on: the announcement will end in ${timeoutMins} minute${Chat.plural(timeoutMins)}.`); | |
this.modlog('ANNOUNCEMENT TIMER', null, `${timeoutMins} minutes`); | |
return this.privateModAction(`The announcement timer was set to ${timeoutMins} minute${Chat.plural(timeoutMins)} by ${user.name}.`); | |
} else { | |
if (!this.runBroadcast()) return; | |
if (announcement.timeout) { | |
return this.sendReply(`The announcement timer is on and will end in ${announcement.timeoutMins} minute${Chat.plural(announcement.timeoutMins)}.`); | |
} else { | |
return this.sendReply(this.tr`The announcement timer is off.`); | |
} | |
} | |
}, | |
timerhelp: [ | |
`/announcement timer [minutes] - Sets the announcement to automatically end after [minutes] minutes. Requires: % @ # ~`, | |
`/announcement timer clear - Clears the announcement's timer. Requires: % @ # ~`, | |
], | |
close: 'end', | |
stop: 'end', | |
end(target, room, user) { | |
room = this.requireRoom(); | |
this.checkCan('minigame', null, room); | |
this.checkChat(); | |
const announcement = this.requireMinorActivity(Announcement); | |
announcement.end(room); | |
this.modlog('ANNOUNCEMENT END'); | |
this.privateModAction(room.tr`The announcement was ended by ${user.name}.`); | |
}, | |
endhelp: [`/announcement end - Ends a announcement and displays the results. Requires: % @ # ~`], | |
show: '', | |
display: '', | |
''(target, room, user, connection) { | |
room = this.requireRoom(); | |
const announcement = this.requireMinorActivity(Announcement); | |
if (!this.runBroadcast()) return; | |
room.update(); | |
if (this.broadcasting) { | |
announcement.display(); | |
} else { | |
announcement.displayTo(user, connection); | |
} | |
}, | |
displayhelp: [`/announcement display - Displays the announcement`], | |
}, | |
announcementhelp: [ | |
`/announcement allows rooms to run their own announcements. These announcements are limited to one announcement at a time per room.`, | |
`Accepts the following commands:`, | |
`/announcement create [announcement] - Creates a announcement. Requires: % @ # ~`, | |
`/announcement htmlcreate [announcement] - Creates a announcement, with HTML allowed. Requires: # ~`, | |
`/announcement edit [announcement] - Edits the announcement. Requires: % @ # ~`, | |
`/announcement htmledit [announcement] - Edits the announcement, with HTML allowed. Requires: # ~`, | |
`/announcement timer [minutes] - Sets the announcement to automatically end after [minutes]. Requires: % @ # ~`, | |
`/announcement display - Displays the announcement`, | |
`/announcement end - Ends a announcement. Requires: % @ # ~`, | |
], | |
}; | |
process.nextTick(() => { | |
Chat.multiLinePattern.register('/announcement (new|create|htmlcreate|edit|htmledit) '); | |
}); | |
// should handle restarts and also hotpatches | |
for (const room of Rooms.rooms.values()) { | |
if (room.settings.minorActivity?.activityid === 'announcement') { | |
room.setMinorActivity(new Announcement(room, room.settings.minorActivity), true); | |
} | |
} | |