Spaces:
Paused
Paused
| /** | |
| * Minor activities | |
| * Pokemon Showdown - http://pokemonshowdown.com/ | |
| * | |
| * Minor activities are representations of non-game activities that rooms | |
| * regularly use, such as polls and announcements. Rooms are limited to | |
| * one minor activity at a time. | |
| * | |
| * Minor activities keep track of users in the form of userids and IPs. | |
| * If a player votes for a poll under one IP, they cannot vote for the same | |
| * poll again. | |
| * | |
| * The user-tracking system is not implemented at the base level: Announcements | |
| * do not have a reason to keep track of users' IPs/IDs because they're just used | |
| * to broadcast a message to a room. | |
| * | |
| * @license MIT | |
| */ | |
| export interface MinorActivityData { | |
| readonly activityid: 'announcement' | 'poll'; | |
| activityNumber?: number; | |
| source?: string; | |
| timeoutMins?: number; | |
| timerEnd?: number; | |
| question: string; | |
| supportHTML: boolean; | |
| multiPoll: boolean; | |
| pendingVotes?: { [userid: string]: number[] }; | |
| voters?: { [k: string]: number[] }; | |
| voterIps?: { [k: string]: number[] }; | |
| totalVotes?: number; | |
| isQuiz?: boolean; | |
| answers: string[] | { name: string, votes: number, correct?: boolean }[]; | |
| } | |
| // globally Rooms.MinorActivity | |
| export abstract class MinorActivity { | |
| abstract activityid: ID; | |
| abstract name: string; | |
| timeout: NodeJS.Timeout | null; | |
| timeoutMins: number; | |
| timerEnd: number; | |
| roomid: RoomID; | |
| room: Room; | |
| supportHTML: boolean; | |
| constructor(room: Room) { | |
| this.timeout = null; | |
| this.timeoutMins = 0; | |
| this.timerEnd = 0; | |
| this.roomid = room.roomid; | |
| this.room = room; | |
| this.supportHTML = false; | |
| } | |
| setTimer(options: { timeoutMins?: number, timerEnd?: number }) { | |
| if (this.timeout) clearTimeout(this.timeout); | |
| this.timeoutMins = options.timeoutMins || 0; | |
| if (!this.timeoutMins) { | |
| this.timerEnd = 0; | |
| this.timeout = null; | |
| return; | |
| } | |
| const now = Date.now(); | |
| this.timerEnd = options.timerEnd || now + this.timeoutMins * 60000; | |
| this.timeout = setTimeout(() => { | |
| const room = this.room; | |
| if (!room) return; // someone forgot to `.destroy()` | |
| this.end(room); | |
| }, this.timerEnd - now); | |
| this.save(); | |
| } | |
| end(room: Room, MinorActivityClass?: new (...args: any[]) => any) { | |
| room.minorActivity?.destroy(); | |
| if (room.minorActivityQueue?.length) { | |
| const pollData = room.minorActivityQueue.shift()!; | |
| if (!room.minorActivityQueue.length) room.clearMinorActivityQueue(); | |
| if (!room.settings.minorActivityQueue?.length) { | |
| delete room.settings.minorActivityQueue; | |
| room.saveSettings(); | |
| } | |
| if (pollData.activityid !== 'poll') throw new Error(`Unexpected Minor Activity (${pollData.activityid}) in queue`); | |
| room.add(`|c|~|/log ${room.tr`The queued poll was started.`}`).update(); | |
| room.modlog({ | |
| action: 'POLL', | |
| note: '(queued)', | |
| }); | |
| if (!MinorActivityClass) { | |
| if (pollData.activityid === 'poll') { | |
| const { Poll } = require('./chat-plugins/poll'); | |
| room.setMinorActivity(new Poll(room, pollData)); | |
| } | |
| } else { | |
| room.setMinorActivity(new MinorActivityClass(room, pollData)); | |
| } | |
| } | |
| } | |
| endTimer() { | |
| if (!this.timeout) return false; | |
| clearTimeout(this.timeout); | |
| this.timeoutMins = 0; | |
| this.timerEnd = 0; | |
| return true; | |
| } | |
| abstract destroy(): void; | |
| abstract display(): void; | |
| onConnect?(user: User, connection: Connection | null): void; | |
| onRename?(user: User, oldid: ID, joining: boolean): void; | |
| abstract toJSON(): AnyObject; | |
| abstract save(): void; | |
| } | |