From 491624e492bfdf0eef3af6516e5e7222e421a406 Mon Sep 17 00:00:00 2001 From: Hri7566 Date: Sat, 14 Jan 2023 19:48:04 -0500 Subject: [PATCH] fix bans --- mpp.hri7566.info | 2 +- package.json | 2 +- src/Channel.js | 39 +++++---- src/Client.js | 10 ++- src/ColorEncoder.js | 2 +- src/Cow.js | 4 +- src/Database.js | 3 +- src/InternalBot/Command.js | 89 +++++++++++++++++++- src/InternalBot/InternalBot.js | 147 ++++++++++++++++++--------------- src/InventoryModel.js | 6 ++ src/MOTDGenerator.js | 17 +++- src/Message.js | 57 +++++++------ src/Server.js | 14 +++- src/User.js | 10 +-- 14 files changed, 273 insertions(+), 129 deletions(-) create mode 100644 src/InventoryModel.js diff --git a/mpp.hri7566.info b/mpp.hri7566.info index b1dc90c..f8f6182 160000 --- a/mpp.hri7566.info +++ b/mpp.hri7566.info @@ -1 +1 @@ -Subproject commit b1dc90c9b890b6c0d2446ebf5d6c419cb75336a6 +Subproject commit f8f618278d6677e4687bd73efb390f145e79c20d diff --git a/package.json b/package.json index 66cc3b9..eb30cb2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mpp-server-master", - "version": "1.0.0", + "version": "1.1.0", "description": "Attempt at making a MPP Server.", "main": "index.js", "scripts": { diff --git a/src/Channel.js b/src/Channel.js index 70885cd..0173356 100644 --- a/src/Channel.js +++ b/src/Channel.js @@ -27,8 +27,13 @@ const LOGGER_PARTICIPANT = { } const LOGGING_CHANNEL = 'lolwutsecretloggingchannel'; +const BAN_CHANNEL = 'test/awkward'; class Channel extends EventEmitter { + static loggingChannel = LOGGING_CHANNEL; + static loggerParticipant = LOGGER_PARTICIPANT; + static banChannel = BAN_CHANNEL; + constructor(server, _id, settings, cl) { super(); this.logger = new Logger(`Room - ${_id}`); @@ -57,14 +62,14 @@ class Channel extends EventEmitter { this.logger.log('Created'); - if (this._id == LOGGING_CHANNEL) { + if (this._id == this.loggingChannel) { if (cl.user.hasFlag('admin')) { delete this.crown; Logger.buffer.forEach(str => { this.chatmsgs.push({ m: 'a', - p: LOGGER_PARTICIPANT, + p: this.loggerParticipant, a: str.replace(ansiRegex(), '') }); }); @@ -72,7 +77,7 @@ class Channel extends EventEmitter { Logger.on('buffer update', (str) => { this.chatmsgs.push({ m: 'a', - p: LOGGER_PARTICIPANT, + p: this.loggerParticipant, a: str.replace(ansiRegex(), '') }); @@ -80,17 +85,17 @@ class Channel extends EventEmitter { }); this.emit('update'); - let c = new Color(LOGGER_PARTICIPANT.color); + let c = new Color(this.loggerParticipant.color); c.add(-0x40, -0x40, -0x40); this.settings = RoomSettings.changeSettings({ color: c.toHexa(), chat: true, crownsolo: true, lobby: false, - owner_id: LOGGER_PARTICIPANT._id + owner_id: this.loggerParticipant._id }, true); } else { - cl.setChannel('test/awkward'); + cl.setChannel(Channel.banChannel); } } else { Database.getRoomSettings(this._id, (err, set) => { @@ -444,7 +449,7 @@ class Channel extends EventEmitter { return false; } } - } else if (_id.startsWith("test/") || _id.toLowerCase().includes("grant")) { + } else if (_id.startsWith("test/") /* || _id.toLowerCase().includes("grant") */) { if (_id == "test/") { return false; } else { @@ -611,7 +616,7 @@ class Channel extends EventEmitter { this.bans.set(user.user._id, user); //if (this.crown && (this.crown.userId)) { - u.setChannel("test/awkward", {}); + u.setChannel(Channel.banChannel, {}); if (asd) this.Notification(user.user._id, @@ -646,17 +651,17 @@ class Channel extends EventEmitter { } unban(_id) { - this.connections.filter((usr) => usr.participantId == user.participantId).forEach(u => { - if (user.bantime) { - delete user.bantime; - } + let ban = this.bans.get(_id); + if (!ban) return; + if (ban.bantime) { + delete ban.bantime; + } - if (user.bannedtime) { - delete user.bannedtime; - } + if (ban.bannedtime) { + delete ban.bannedtime; + } - this.bans.delete(user.user._id); - }); + this.bans.delete(ban.user._id); } Notification(who, title, text, html, duration, target, klass, id) { diff --git a/src/Client.js b/src/Client.js index 0bdbec9..ec3a1fa 100644 --- a/src/Client.js +++ b/src/Client.js @@ -83,7 +83,7 @@ class Client extends EventEmitter { "#room", "short" ); - this.setChannel("test/awkward", settings); + this.setChannel(Channel.banChannel, settings); return; } @@ -155,7 +155,8 @@ class Client extends EventEmitter { chown: new RateLimitChain(quotas.chown.amount, quotas.chown.time), userset: new RateLimitChain(quotas.userset.amount, quotas.userset.time), kickban: new RateLimitChain(quotas.kickban.amount, quotas.kickban.time), - note: new Quota(Quota.PARAMS_LOBBY), + // note: new Quota(Quota.PARAMS_LOBBY), + note: new RateLimitChain(5, 5000), chset: new Quota(Quota.PARAMS_USED_A_LOT), "+ls": new Quota(Quota.PARAMS_USED_A_LOT), "-ls": new Quota(Quota.PARAMS_USED_A_LOT) @@ -235,6 +236,7 @@ class Client extends EventEmitter { let users = []; this.server.connections.forEach(cl => { + if (!cl.user) return; let u = { p: { _id: cl.user._id, @@ -250,6 +252,8 @@ class Client extends EventEmitter { }); data.channelManager = { + loggingChannel: Channel.loggingChannel, + loggerParticipant: Channel.loggerParticipant, channels }; @@ -257,6 +261,8 @@ class Client extends EventEmitter { users } + data.uptime = Date.now() - this.server.startTime; + this.sendArray([data]); } diff --git a/src/ColorEncoder.js b/src/ColorEncoder.js index b590579..2f6b5b4 100644 --- a/src/ColorEncoder.js +++ b/src/ColorEncoder.js @@ -60,7 +60,7 @@ function getTimeColor(currentDate = new Date()) { let dayOfYear = Math.ceil(differenceInTime / oneDayInMS); dayOfYear %= 365; - console.log(dayOfYear); + // console.log(dayOfYear); // get hour let hours = currentDate.getHours(); diff --git a/src/Cow.js b/src/Cow.js index b150dee..fd1a124 100644 --- a/src/Cow.js +++ b/src/Cow.js @@ -12,7 +12,9 @@ class Cow { } constructor() { - this['🐄'] = Cow.generateRandomName(); + this['display_name'] = Cow.generateRandomName(); + this['emoji'] = '🐄' + this['count'] = 1; } } diff --git a/src/Database.js b/src/Database.js index a552f40..469f84c 100644 --- a/src/Database.js +++ b/src/Database.js @@ -5,7 +5,8 @@ const ColorEncoder = require('./ColorEncoder'); const UserModel = require('./UserModel'); const mongoose = require('mongoose'); const level = require('level'); -const { db } = require('./UserModel'); +const { users } = require('./UserModel'); +const { inventories } = require('./InventoryModel'); const Logger = require('./Logger'); var logger = new Logger("Database"); diff --git a/src/InternalBot/Command.js b/src/InternalBot/Command.js index 31c7fa4..1ba584f 100644 --- a/src/InternalBot/Command.js +++ b/src/InternalBot/Command.js @@ -1,14 +1,99 @@ +const Logger = require("../Logger"); +const Color = require('../Color'); + class Command { - constructor(id, args, desc, usage, func, permLevel) { + static commands = []; + + static logger = new Logger("Command Handler"); + + static handleCommand(cl, ch, c, usedPrefix, args, argcat, p, isAdmin) { + for (let cmd of this.commands) { + let aliasCheck = false; + + aliasLoop: + for (let alias of cmd.aliases) { + if (c.toLowerCase() == alias.toLowerCase()) { + aliasCheck = true; + break aliasLoop; + } + } + + if (!aliasCheck) continue; + if (!isAdmin && cmd.permLevel == 'admin') return ch.adminChat(`You don't have permission to use this command.`); + if (args.length - 1 < cmd.minargs) return ch.adminChat(`Not enough arguments. Usage: ${this.getUsage(cmd.usage, usedPrefix)}`); + + try { + const out = cmd.func(cl, ch, { + c, args, argcat, p, isAdmin, a: args.join(' ') + }); + console.log(out); + if (!out) return; + if (out !== '') { + ch.adminChat(out); + } + } catch (err) { + this.logger.error(err); + ch.adminChat(`An error has occurred whilst performing this command.`); + } + } + } + + static addCommand(cmd) { + this.commands.push(cmd); + } + + static getUsage(usa, pre) { + return usa.split('%P').join(pre); + } + + constructor(id, aliases, desc, usage, minargs, func, permLevel) { this.id = id; - this.args = args || [id]; + this.aliases = aliases || [id]; this.desc = desc || 'no description'; // brandon-like words this.usage = usage || 'no usage'; + this.minargs = minargs; this.func = func; this.permLevel = permLevel || 'admin'; // user / admin? } } +Command.addCommand(new Command('ping', ['ping'], undefined, `%Pping`, 0, (cl, ch, msg) => { + return `pong`; +}, 'user')); + +Command.addCommand(new Command('color', ['color', 'setcolor', 'colorset'], undefined, `%Pcolor [color] [userid]`, 0, (cl, ch, msg) => { + if (!msg.isAdmin) { + ch.adminChat("You do not have permission to use this command."); + return; + } + + let color = ch.verifyColor(msg.args[1]); + if (color) { + let c = new Color(color); + if (!msg.args[2]) { + cl.emit("color", { + color: c.toHexa(), + _id: cl.user._id + }, true); + ch.adminChat(`Your color is now ${c.getName().replace('A', 'a')} [${c.toHexa()}]`); + } else { + let winner = ch.server.getAllClientsByUserID(msg.args[2])[0]; + if (winner) { + cl.emit("color", { + color: c.toHexa(), + _id: winner.user._id + }, true); + ch.adminChat(`Friend ${winner.user.name}'s color is now ${c.getName().replace('A', 'a')}.`); + } else { + ch.adminChat("The friend you are looking for (" + msg.args[2] + ") is not around."); + } + } + } else { + ch.adminChat("Invalid color."); + } + ch.updateCh(); +}, 'user')); + module.exports = { Command } diff --git a/src/InternalBot/InternalBot.js b/src/InternalBot/InternalBot.js index 8969700..c61f9bf 100644 --- a/src/InternalBot/InternalBot.js +++ b/src/InternalBot/InternalBot.js @@ -9,6 +9,7 @@ class InternalBot { static once = EventEmitter.prototype.once; static prefix = '!'; + static commands = []; static bindEventListeners() { if (this.alreadyBound) return; @@ -32,75 +33,85 @@ class InternalBot { let p = cl; if (!args[0].startsWith(this.prefix)) return; + let prefix = this.prefix; + Command.handleCommand(cl, ch, cmd, prefix, args, argcat, p, isAdmin); - switch (cmd) { - case "ping": - ch.adminChat('pong'); - break; - case "setcolor": - case "color": - if (!isAdmin) { - ch.adminChat("You do not have permission to use this command."); - return; - } - let color = ch.verifyColor(args[1]); - if (color) { - let c = new Color(color); - if (!args[2]) { - p.emit("color", { - color: c.toHexa(), - _id: p.user._id - }, true); - ch.adminChat(`Your color is now ${c.getName().replace('A', 'a')} [${c.toHexa()}]`); - } else { - let winner = ch.server.getAllClientsByUserID(args[2])[0]; - if (winner) { - p.emit("color", { - color: c.toHexa(), - _id: winner.user._id - }, true); - ch.adminChat(`Friend ${winner.user.name}'s color is now ${c.getName().replace('A', 'a')}.`); - } else { - ch.adminChat("The friend you are looking for (" + args[2] + ") is not around."); - } - } - } else { - ch.adminChat("Invalid color."); - } - ch.updateCh(); - break; - case "users": - ch.adminChat(`There are ${ch.server.connections.size} users online.`); - break; - case "chown": - if (!isAdmin) return; - let id = p.participantId; - if (args[1]) { - id = args[1]; - } - if (ch.hasUser(id)) { - ch.chown(id); - } - break; - case "chlist": - case "channellist": - if (!isAdmin) return; - ch.adminChat("Channels:"); - for (let [_id] of ch.server.rooms) { - ch.adminChat(`- ${_id}`); - } - break; - case "restart": - if (!isAdmin) return; - cl.server.restart(); - break; - case "eval": - case "javascript": - case "js": - if (!isAdmin) return; - cl.server.ev(argcat); - break; - } + // switch (cmd) { + // case "ping": + // ch.adminChat('pong'); + // break; + // case "setcolor": + // case "color": + // if (!isAdmin) { + // ch.adminChat("You do not have permission to use this command."); + // return; + // } + // let color = ch.verifyColor(args[1]); + // if (color) { + // let c = new Color(color); + // if (!args[2]) { + // p.emit("color", { + // color: c.toHexa(), + // _id: p.user._id + // }, true); + // ch.adminChat(`Your color is now ${c.getName().replace('A', 'a')} [${c.toHexa()}]`); + // } else { + // let winner = ch.server.getAllClientsByUserID(args[2])[0]; + // if (winner) { + // p.emit("color", { + // color: c.toHexa(), + // _id: winner.user._id + // }, true); + // ch.adminChat(`Friend ${winner.user.name}'s color is now ${c.getName().replace('A', 'a')}.`); + // } else { + // ch.adminChat("The friend you are looking for (" + args[2] + ") is not around."); + // } + // } + // } else { + // ch.adminChat("Invalid color."); + // } + // ch.updateCh(); + // break; + // case "users": + // ch.adminChat(`There are ${ch.server.connections.size} users online.`); + // break; + // case "chown": + // if (!isAdmin) return; + // let id = p.participantId; + // if (args[1]) { + // id = args[1]; + // } + // if (ch.hasUser(id)) { + // ch.chown(id); + // } + // break; + // case "chlist": + // case "channellist": + // if (!isAdmin) return; + // ch.adminChat("Channels:"); + // for (let [_id] of ch.server.rooms) { + // ch.adminChat(`- ${_id}`); + // } + // break; + // case "restart": + // if (!isAdmin) return; + // cl.server.restart(); + // break; + // case "eval": + // case "javascript": + // case "js": + // if (!isAdmin) return; + // cl.server.ev(argcat); + // break; + // case "inventory": + // case "inv": + // if (cl.user.inventory) { + // ch.adminChat(`Inventory: ${Object.values(cl.user.inventory).map(it => `${it.display_name} (x${it.count})`)}`); + // } else { + // ch.adminChat(`Inventory: (empty)`); + // } + // break; + // } }); } } diff --git a/src/InventoryModel.js b/src/InventoryModel.js new file mode 100644 index 0000000..b18462f --- /dev/null +++ b/src/InventoryModel.js @@ -0,0 +1,6 @@ +const mongoose = require('mongoose'); + +module.exports = mongoose.model('Inventory', { + user_id: String, + items: Array +}); diff --git a/src/MOTDGenerator.js b/src/MOTDGenerator.js index b3268df..6ad864c 100644 --- a/src/MOTDGenerator.js +++ b/src/MOTDGenerator.js @@ -4,6 +4,16 @@ let hd = new Holidays(); hd.init('US'); +let dayOfTheWeekMOTD = [ + 'Happy Sunday!', + 'You can chat with that thing.', + 'I\'m tired...', + 'Don\'t forget to bring a towel!', + 'Never lick a pole in winter.', + 'Everyone loves a potato monkey!', + 'Dear Mario: Please come to the castle. I\'ve baked a cake for you. Yours truly-- Princess Toadstool' +] + class MOTDGenerator { static getDay() { let now = new Date(); @@ -18,10 +28,11 @@ class MOTDGenerator { let h = hd.isHoliday(Date.now()); if (h) { // maybe holiday - return `Happy ${h[0].name}`; + return `Happy ${h[0].name}!`; } else { - // no holiday - return 'cotton-headed ninnymuggins' + // no holiday, get day + let day = new Date().getDay(); + return dayOfTheWeekMOTD[day]; } } } diff --git a/src/Message.js b/src/Message.js index 8c1fd23..0d02d79 100644 --- a/src/Message.js +++ b/src/Message.js @@ -110,7 +110,7 @@ module.exports = (cl) => { if (msg.id == cl.user.id) { param = Quota.N_PARAMS_RIDICULOUS; param.m = "nq"; - cl.sendArray([param]) + cl.sendArray([param]); } } } else { @@ -118,7 +118,7 @@ module.exports = (cl) => { if (msg.id == cl.user.id) { param = Quota.N_PARAMS_RIDICULOUS; param.m = "nq"; - cl.sendArray([param]) + cl.sendArray([param]); } } } else { @@ -127,11 +127,11 @@ module.exports = (cl) => { cl.channel.chown(); param = Quota.N_PARAMS_NORMAL; param.m = "nq"; - cl.sendArray([param]) + cl.sendArray([param]); } } else { cl.channel.chown(); - param = Quota.N_PARAMS_NORMAL; + param = Quota.N_PARAMS_RIDICULOUS; param.m = "nq"; cl.sendArray([param]); } @@ -155,30 +155,39 @@ module.exports = (cl) => { if (!msg.hasOwnProperty('message')) return; if (typeof(msg.message) !== 'string') return; if (cl.channel.settings.chat) { - if (cl.channel.isLobby(cl.channel._id)) { - if (!cl.quotas.chat.lobby.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; - } else { - if (!(cl.user._id == cl.channel.crown.userId)) { - if (!cl.quotas.chat.normal.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; - } else { - if (!cl.quotas.chat.insane.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; - } - } - cl.channel.emit('a', cl, msg); + if (admin && msg.admin == true) { + cl.channel.adminChat(msg.message); + } else { + if (cl.channel.isLobby(cl.channel._id)) { + if (!cl.quotas.chat.lobby.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; + } else { + if (!(cl.user._id == cl.channel.crown.userId)) { + if (!cl.quotas.chat.normal.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; + } else { + if (!cl.quotas.chat.insane.attempt() && !admin && !cl.user.hasFlag('no chat rate limit', true)) return; + } + } + cl.channel.emit('a', cl, msg); + } } }); - cl.on('n', msg => { + cl.on('n', (msg, admin) => { if (!(cl.channel && cl.participantId)) return; if (!msg.hasOwnProperty('t') || !msg.hasOwnProperty('n')) return; if (typeof msg.t != 'number' || typeof msg.n != 'object') return; - if (cl.channel.settings.crownsolo) { - if ((cl.channel.crown.userId == cl.user._id) && !cl.channel.crowndropped) { - cl.channel.playNote(cl, msg); - } - } else { - cl.channel.playNote(cl, msg); - } + + if (cl.quotas.note && !admin) { + if (!cl.quotas.note.attempt()) return; + } + + if (cl.channel.settings.crownsolo) { + if ((cl.channel.crown.userId == cl.user._id) && !cl.channel.crowndropped) { + cl.channel.playNote(cl, msg); + } + } else { + cl.channel.playNote(cl, msg); + } }); cl.on('+ls', msg => { @@ -212,7 +221,7 @@ module.exports = (cl) => { } }); - cl.on('kickban', msg => { + cl.on('kickban', (msg, admin) => { if (!admin) { if (cl.channel.crown == null) return; if (!(cl.channel && cl.participantId)) return; @@ -222,7 +231,7 @@ module.exports = (cl) => { if (msg.hasOwnProperty('_id') && typeof msg._id == "string") { if (!cl.quotas.kickban.attempt() && !admin) return; let _id = msg._id; - let ms = msg.ms || 3600000; + let ms = msg.ms || 36e5; cl.channel.kickban(_id, ms); } }); diff --git a/src/Server.js b/src/Server.js index 319bb05..a4aaa53 100644 --- a/src/Server.js +++ b/src/Server.js @@ -13,6 +13,8 @@ class Server { static emit = EventEmitter.prototype.emit; static once = EventEmitter.prototype.once; + static startTime = Date.now(); + static start(config) { // super(); // EventEmitter.call(this); @@ -84,6 +86,7 @@ class Server { "userset", "chown", "kickban", + "unban", "admin message", "color", "eval", @@ -116,10 +119,19 @@ class Server { cl = undefined; return; } + + let newch = { + banned: typeof this.rooms.get(data.ch._id).bans.get(cl.user._id) !== 'undefined' + }; + + for (let key of Object.keys(data)) { + newch[key] = data.ch[key]; + } + cl.sendArray([{ "m": "ls", "c": false, - "u": [data.ch] + "u": [newch] }]); } } diff --git a/src/User.js b/src/User.js index 98735fe..005f972 100644 --- a/src/User.js +++ b/src/User.js @@ -1,4 +1,5 @@ const Database = require("./Database"); +const { Cow } = require('./Cow'); function hslToHex(h, s, l) { l /= 100; @@ -22,13 +23,8 @@ class User { "no chat rate limit": false, freeze_name: false } - - this.inventory = { - 'test': { - display_name: 'Test', - count: 1 - } - }; + + this.inventory = {}; } getPublicUser() {