Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
/*
* 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);
}
}