Quotes: Move to a chat plugin (#7421)

This commit is contained in:
Mia 2020-09-26 10:11:42 -05:00 committed by GitHub
parent 3352e11b86
commit 78933408bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 157 additions and 106 deletions

View File

@ -6,6 +6,7 @@ server/chat-plugins/help.ts @mia-pi-git
server/chat-plugins/hosts.ts @AnnikaCodes
server/chat-plugins/mafia.ts @HoeenCoder
server/chat-plugins/othermetas.ts @KrisXV @TheImmortal
server/chat-plugins/quotes.ts @mia-pi-git @KrisXV
server/chat-plugins/random-battles.ts @KrisXV @TheImmortal
server/chat-plugins/scavenger*.ts @xfix @sparkychildcharlie
server/chat-plugins/trivia.ts @AnnikaCodes

View File

@ -2537,84 +2537,6 @@ export const commands: ChatCommands = {
},
denyshowhelp: [`/denyshow [user] - Denies the media display request of [user]. Requires: % @ # &`],
randquote(target, room, user) {
room = this.requireRoom();
if (!room.settings.quotes?.length) return this.errorReply(`This room has no quotes.`);
this.runBroadcast();
const {quote, date, userid} = room.settings.quotes[Math.floor(Math.random() * room.settings.quotes.length)];
const time = Chat.toTimestamp(new Date(date), {human: true});
const attribution = toID(target) === 'showauthor' ? `<br /><hr /><small>Added by ${userid} on ${time}</small>` : '';
return this.sendReplyBox(`${Chat.formatText(quote).replace(/\n/g, '<br />')}${attribution}`);
},
randquotehelp: [`/randquote [showauthor] - Show a random quote from the room. Add 'showauthor' to see who added it and when.`],
addquote: 'quote',
quote(target, room, user) {
room = this.requireRoom();
if (!room.persist) {
return this.errorReply("This command is unavailable in temporary rooms.");
}
target = target.trim();
this.checkCan('mute', null, room);
if (!target) {
return this.parse(`/help quote`);
}
if (!room.settings.quotes) room.settings.quotes = [];
if (this.filter(target) !== target) {
return this.errorReply(`Invalid quote.`);
}
if (room.settings.quotes.filter(item => item.quote === target).length) {
return this.errorReply(`"${target}" is already quoted in this room.`);
}
if (target.length > 8192) {
return this.errorReply(`Your quote cannot exceed 8192 characters.`);
}
if (room.settings.quotes.length >= 100) {
return this.errorReply(`This room already has 100 quotes, which is the maximum.`);
}
room.settings.quotes.push({userid: user.id, quote: target, date: Date.now()});
room.saveSettings();
const collapsedQuote = target.replace(/\n/g, ' ');
this.privateModAction(`${user.name} added a new quote: "${collapsedQuote}".`);
return this.modlog(`ADDQUOTE`, null, collapsedQuote);
},
quotehelp: [`/quote [quote] - Adds [quote] to the room's quotes. Requires: % @ # &`],
removequote(target, room, user) {
target = target.trim();
const [idx, roomid] = Utils.splitFirst(target, ',');
const targetRoom = roomid ? Rooms.search(roomid) : room;
if (!targetRoom) return this.errorReply(`Invalid room.`);
if (!targetRoom.persist) {
return this.errorReply("This command is unavailable in temporary rooms.");
}
this.room = targetRoom;
this.checkCan('mute', null, targetRoom);
if (!targetRoom.settings.quotes?.length) return this.errorReply(`This room has no quotes.`);
const index = parseInt(idx);
if (isNaN(index)) {
return this.errorReply(`Invalid index.`);
}
if (!targetRoom.settings.quotes[index - 1]) {
return this.errorReply(`Quote not found.`);
}
const [removed] = targetRoom.settings.quotes.splice(index - 1, 1);
const collapsedQuote = removed.quote.replace(/\n/g, ' ');
this.privateModAction(`${user.name} removed quote indexed at ${index}: "${collapsedQuote}" (originally added by ${removed.userid}).`);
this.modlog(`REMOVEQUOTE`, null, collapsedQuote);
targetRoom.saveSettings();
if (roomid) this.parse(`/join view-quotes-${targetRoom.roomid}`);
},
removequotehelp: [`/removequote [index] - Removes the quote from the room's quotes. Requires: % @ # &`],
viewquotes: 'quotes',
quotes(target, room) {
const targetRoom = target ? Rooms.search(target) : room;
if (!targetRoom) return this.errorReply(`Invalid room.`);
return this.parse(`/join view-quotes-${targetRoom.roomid}`);
},
quoteshelp: [`/quotes [room] - Shows all quotes for [room]. Defaults the room the command is used in.`],
approvallog(target, room, user) {
room = this.requireRoom();
return this.parse(`/sl approved showing media from, ${room.roomid}`);
@ -2788,33 +2710,6 @@ export const pages: PageTable = {
}
return buf;
},
quotes(args, user) {
const room = this.requireRoom();
this.title = `[Quotes]`;
// allow it for users if they can access the room
if (!room.checkModjoin(user)) {
return this.errorReply(`Access denied.`);
}
let buffer = `<div class="pad">`;
buffer += `<button style="float:right;" class="button" name="send" value="/join view-quotes-${room.roomid}"><i class="fa fa-refresh"></i> Refresh</button>`;
if (!room.settings.quotes?.length) {
return `${buffer}<h2>This room has no quotes.</h2></div>`;
}
buffer += `<h2>Quotes for ${room.title} (${room.settings.quotes.length}):</h2>`;
for (const [i, quoteObj] of room.settings.quotes.entries()) {
const index = i + 1;
const {quote, userid, date} = quoteObj;
buffer += `<div class="infobox">${index}: ${Chat.formatText(quote).replace(/\n/g, '<br />')}`;
buffer += `<br /><hr /><small>Added by ${userid} on ${Chat.toTimestamp(new Date(date), {human: true})}</small>`;
if (user.can('mute', null, room)) {
buffer += `<br /><hr /><button class="button" name="send" value="/removequote ${index},${room.roomid}">Remove</button>`;
}
buffer += `</div>`;
}
buffer += `</div>`;
return buffer;
},
};
process.nextTick(() => {

View File

@ -0,0 +1,156 @@
import {Utils} from '../../lib/utils';
import {FS} from '../../lib/fs';
const STORAGE_PATH = 'config/chat-plugins/quotes.json';
const MAX_QUOTES = 200;
interface Quote {
userid: string;
quote: string;
date: number;
}
let quotes: {[room: string]: Quote[]} = {};
try {
quotes = JSON.parse(FS(STORAGE_PATH).readIfExistsSync() || "{}");
} catch (e) {
if (e.code !== 'ENOENT') throw e;
}
// migrate quotes out of roomsettings
function convertOldQuotes() {
for (const room of Rooms.rooms.values()) {
// @ts-ignore
if (room.settings.quotes) {
// @ts-ignore
quotes[room.roomid] = room.settings.quotes;
// @ts-ignore
delete room.settings.quotes;
room.saveSettings();
saveQuotes();
}
}
}
function saveQuotes() {
FS(STORAGE_PATH).writeUpdate(() => JSON.stringify(quotes));
}
convertOldQuotes();
export const commands: ChatCommands = {
randquote(target, room, user) {
room = this.requireRoom();
const roomQuotes = quotes[room.roomid];
if (!roomQuotes?.length) return this.errorReply(`This room has no quotes.`);
this.runBroadcast();
const {quote, date, userid} = roomQuotes[Math.floor(Math.random() * roomQuotes.length)];
const time = Chat.toTimestamp(new Date(date), {human: true});
const attribution = toID(target) === 'showauthor' ? `<br /><hr /><small>Added by ${userid} on ${time}</small>` : '';
return this.sendReplyBox(`${Chat.formatText(quote).replace(/\n/g, '<br />')}${attribution}`);
},
randquotehelp: [`/randquote [showauthor] - Show a random quote from the room. Add 'showauthor' to see who added it and when.`],
addquote: 'quote',
quote(target, room, user) {
room = this.requireRoom();
if (!room.persist) {
return this.errorReply("This command is unavailable in temporary rooms.");
}
target = target.trim();
this.checkCan('mute', null, room);
if (!target) {
return this.parse(`/help quote`);
}
if (!quotes[room.roomid]) quotes[room.roomid] = [];
const roomQuotes = quotes[room.roomid];
if (this.filter(target) !== target) {
return this.errorReply(`Invalid quote.`);
}
if (roomQuotes.filter(item => item.quote === target).length) {
return this.errorReply(`"${target}" is already quoted in this room.`);
}
if (target.length > 8192) {
return this.errorReply(`Your quote cannot exceed 8192 characters.`);
}
if (room.settings.isPrivate !== undefined && roomQuotes.length >= MAX_QUOTES) {
return this.errorReply(`This room already has ${MAX_QUOTES} quotes, which is the maximum for private rooms.`);
}
roomQuotes.push({userid: user.id, quote: target, date: Date.now()});
saveQuotes();
const collapsedQuote = target.replace(/\n/g, ' ');
this.privateModAction(`${user.name} added a new quote: "${collapsedQuote}".`);
return this.modlog(`ADDQUOTE`, null, collapsedQuote);
},
quotehelp: [`/quote [quote] - Adds [quote] to the room's quotes. Requires: % @ # &`],
removequote(target, room, user) {
target = target.trim();
const [idx, roomid] = Utils.splitFirst(target, ',');
const targetRoom = roomid ? Rooms.search(roomid) : room;
if (!targetRoom) return this.errorReply(`Invalid room.`);
if (!targetRoom.persist) {
return this.errorReply("This command is unavailable in temporary rooms.");
}
this.room = targetRoom;
this.checkCan('mute', null, targetRoom);
if (!quotes[targetRoom.roomid]?.length) return this.errorReply(`This room has no quotes.`);
const index = parseInt(idx);
if (isNaN(index)) {
return this.errorReply(`Invalid index.`);
}
const roomQuotes = quotes[targetRoom.roomid];
if (!roomQuotes[index - 1]) {
return this.errorReply(`Quote not found.`);
}
const [removed] = roomQuotes.splice(index - 1, 1);
const collapsedQuote = removed.quote.replace(/\n/g, ' ');
this.privateModAction(`${user.name} removed quote indexed at ${index}: "${collapsedQuote}" (originally added by ${removed.userid}).`);
this.modlog(`REMOVEQUOTE`, null, collapsedQuote);
saveQuotes();
if (roomid) this.parse(`/join view-quotes-${targetRoom.roomid}`);
},
removequotehelp: [`/removequote [index] - Removes the quote from the room's quotes. Requires: % @ # &`],
viewquotes: 'quotes',
quotes(target, room) {
const targetRoom = target ? Rooms.search(target) : room;
if (!targetRoom) return this.errorReply(`Invalid room.`);
return this.parse(`/join view-quotes-${targetRoom.roomid}`);
},
quoteshelp: [`/quotes [room] - Shows all quotes for [room]. Defaults the room the command is used in.`],
};
export const pages: PageTable = {
quotes(args, user) {
const room = this.requireRoom();
this.title = `[Quotes]`;
// allow it for users if they can access the room
if (!room.checkModjoin(user)) {
return this.errorReply(`Access denied.`);
}
let buffer = `<div class="pad">`;
buffer += `<button style="float:right;" class="button" name="send" value="/join view-quotes-${room.roomid}"><i class="fa fa-refresh"></i> Refresh</button>`;
const roomQuotes = quotes[room.roomid];
if (!roomQuotes?.length) {
return `${buffer}<h2>This room has no quotes.</h2></div>`;
}
buffer += `<h2>Quotes for ${room.title} (${roomQuotes.length}):</h2>`;
for (const [i, quoteObj] of roomQuotes.entries()) {
const index = i + 1;
const {quote, userid, date} = quoteObj;
buffer += `<div class="infobox">${Chat.formatText(quote).replace(/\n/g, '<br />')}`;
buffer += `<br /><hr /><small>Added by ${userid} on ${Chat.toTimestamp(new Date(date), {human: true})}</small>`;
if (user.can('mute', null, room)) {
buffer += ` <button class="button" name="send" value="/removequote ${index},${room.roomid}">Remove</button>`;
}
buffer += `</div>`;
}
buffer += `</div>`;
return buffer;
},
};

View File

@ -111,7 +111,6 @@ export interface RoomSettings {
requestShowEnabled?: boolean | null;
showEnabled?: GroupSymbol | true;
permissions?: {[k: string]: GroupSymbol};
quotes?: {userid: string, quote: string, date: number}[];
scavSettings?: AnyObject;
scavQueue?: QueuedHunt[];