bogos-binted-bot/src/Bot.js

750 lines
29 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const MidiPlayer = require('midi-player-js');
const minimist = require('minimist');
const fetch = require('node-fetch');
const EventEmitter = require('events');
const path = require('path');
const youtube = require('youtube-dl-exec');
const { writeFile } = require('fs');
const url = require('url');
const Color = require('./Color');
const { Cursor } = require('./Cursor');
const { CommandGroup, Prefix } = require('./CommandGroup');
const { Database, Item, User, ItemConsumable } = require('./Database');
const { PermissionGroup, Permission } = require('./PermissionGroup');
function getYoutubeLinkFromString(str) {
const regex = /(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?/;
return regex.exec(str);
}
function downloadFile(uri, filename, callback) {
return fetch(uri)
.then(res => res.body)
.then(body => {
writeFile(filename, body, err => {
if (err) {
callback(err);
} else {
callback(null, filename);
}
});
})
.catch(err => callback(err));
}
function retardify(str) {
const words = str.split(' ');
const ret = [];
for (let i = 0; i < words.length; i++) {
if (words[i].length > 0) {
// randomize every letter capitalization
const word = words[i].split('');
for (let j = 0; j < word.length; j++) {
if (Math.random() > 0.5) {
word[j] = word[j].toUpperCase();
} else {
word[j] = word[j].toLowerCase();
}
}
ret.push(word.join(''));
}
}
return ret.join(' ');
}
class Bot extends EventEmitter {
constructor (cl, ch) {
super();
this.client = cl;
this.client.ch = ch;
this.clients = new Map();
this.cursor = new Cursor();
this.c = []; // TODO chat history
this.player = new MidiPlayer.Player();
this.keys = require('./keys');
// this.commands = [];
// this.bindDefaultCommands();
this.commandGroups = [];
let GENERAL_COMMANDS = new CommandGroup('general', 'General commands');
GENERAL_COMMANDS.addPrefix(new Prefix('g!'));
GENERAL_COMMANDS.addPrefix(new Prefix('*'));
GENERAL_COMMANDS.addPrefix(new Prefix('7'));
GENERAL_COMMANDS.addPrefix(new Prefix('h!'));
GENERAL_COMMANDS.addPrefix(new Prefix('^'));
GENERAL_COMMANDS.addPermissionLevel('command.general');
this.commandGroups.push(GENERAL_COMMANDS);
this.bindGeneralCommands();
let FUN_COMMANDS = new CommandGroup('fun', 'Fun commands');
FUN_COMMANDS.addPrefix(new Prefix('f!'));
FUN_COMMANDS.addPrefix(new Prefix('*'));
FUN_COMMANDS.addPrefix(new Prefix('~'));
FUN_COMMANDS.addPermissionLevel('command.fun');
this.commandGroups.push(FUN_COMMANDS);
this.bindFunCommands();
let MOD_COMMANDS = new CommandGroup('mod', 'Moderator commands');
MOD_COMMANDS.addPrefix(new Prefix('m!'));
MOD_COMMANDS.addPrefix(new Prefix('*'));
MOD_COMMANDS.addPrefix(new Prefix('$'));
MOD_COMMANDS.addPermissionLevel('mod.command.*');
this.commandGroups.push(MOD_COMMANDS);
this.bindModCommands();
let ADMIN_COMMANDS = new CommandGroup('admin', 'Admin commands');
ADMIN_COMMANDS.addPrefix(new Prefix('a!'));
ADMIN_COMMANDS.addPrefix(new Prefix('*'));
ADMIN_COMMANDS.addPrefix(new Prefix('&'));
ADMIN_COMMANDS.addPermissionLevel('admin.command.*');
this.commandGroups.push(ADMIN_COMMANDS);
this.bindAdminCommands();
this.prefixes = []; // TODO prefixes
this.bindEventListeners();
this.startClientIfNotStarted() ? this.bindDefaultClientListeners() : console.log(this.error('WebSocket not supported'));
this.defaultName = 'pinkalicious';
this.currentPoll = {
question: 'Should ModernMPP style be released?',
options: ['Yes', 'No']
}
// database poll count create
Database.get('poll_yes').then(res => {
Database.set('poll_yes', JSON.stringify([]));
}, err => {
Database.set('poll_yes', JSON.stringify([]));
});
Database.get('poll_no').then(res => {
Database.set('poll_no', JSON.stringify([]));
}, err => {
Database.set('poll_no', JSON.stringify([]));
});
// Database.modifyUser("2ffc3744fbc1bc6c6ef4a330", user => {
// User.removePermissionGroup(user, 'admin');
// });
}
startClientIfNotStarted() {
if (!this.client.isConnected() && this.client.isSupported()) {
this.client.start();
return true;
}
return false;
}
// ANCHOR default listeners and objects
bindDefaultClientListeners() {
let cl = this.client;
cl.sendChat = str => {
cl.sendArray([{m:'a', message:`\u034f${str}`}]);
}
cl.sendArray([{m:'+custom'}]);
cl.on('hi', msg => {
console.log(`Online`);
cl.setChannel(cl.ch);
let u = msg.u;
// if (u.name !== 'fluoridated woolen conkerberry') {
// cl.setName('fluoridated woolen conkerberry');
// }
// if (u.name !== 'Cereal') {
// cl.setName('Cereal');
// }
if (u.name !== this.defaultName) {
cl.setName(this.defaultName);
}
// if (u.color !== '#fff0b2') {
// cl.setColor('#fff0b2');
// }
// set color to pinkalicous
if (u.color !== '#E684AE') {
cl.setColor('#E684AE');
}
});
cl.on("ch", msg => {
if (!msg.ch.crown) return;
let time = Date.now() - msg.ch.crown.time + 16000;
setTimeout(() => {
cl.sendArray([{m:"chown", id: cl.getOwnParticipant().id}]);
}, time);
});
cl.ws.on('error', (err) => {
this.error(err);
});
cl.on('a', msg => {
if (!msg) return;
if (!msg.a) return;
if (!msg.p) return;
if (!msg.p._id) return;
if (!msg.p.name) return;
if (typeof msg.a !== 'string') return;
if (msg.a.length < 1) return;
msg.args = msg.a.split(' ');
Database.getUser(msg.p._id, (err, user) => {
if (err) {
// console.error(err);
}
if (user == null || typeof user === 'undefined') {
// console.log('user is null');
Database.createUser(msg.p).then(value => {
console.log(`Created user ${value.name}`);
}, reason => {
console.error(reason);
});
} else {
Database.upgradeUser(user);
}
msg.user = user;
let found = false;
cmdgpLoop:
for (let cmdgp of this.commandGroups) {
prefixLoop:
for (let prefix of cmdgp.prefixes) {
let hasPermission = false;
permLoop:
for (let perm of cmdgp.permissionLevels) {
if (User.hasPermission(msg.user, perm)) {
hasPermission = true;
break permLoop;
}
}
// console.log('hasPermission: ', hasPermission);
if (!hasPermission) continue prefixLoop;
if (msg.args[0].startsWith(prefix.prefix)) {
msg.cmd = msg.args[0].substr(prefix.prefix.length);
msg.prefix = prefix;
msg.cmdGroup = cmdgp;
found = true;
break cmdgpLoop;
}
}
}
if (!found) return;
msg.argv = minimist(msg.args);
msg.argcat = msg.a.substr(msg.args[0].length).trim();
this.emit('command_input', msg, cl);
});
});
cl.on('a', msg => {
// this.c.push(msg);
let ytlink = getYoutubeLinkFromString(msg.a);
if (typeof ytlink == 'undefined') return;
if (ytlink == null) return;
});
// cl.on('c', msg => {
// this.c = msg.c;
// });
cl.on('custom', cu => {
let msg = cu.data;
switch (msg.m) {
case 'crown':
cl.sendArray([{m:'chown', id: cu.p}]);
}
});
cl.on('m', msg => {
if (!this.gayFollowing) return;
if (msg.id == this.gayId) {
cl.sendArray([{m:'m', x: (parseFloat(msg.x) - 4.71).toString(), y: msg.y}]);
}
});
}
bindEventListeners() {
this.on('command_input', (msg, cl) => {
for (let group of this.commandGroups) {
if (!group.hasPrefix(msg.prefix.prefix)) continue;
group.getAvailableCommands().forEach(command => {
if (group.commandIsDisabled(command)) cl.sendChat(`Command '${command.acc[0]}' is disabled.`);
command.acc.forEach(a => {
if (msg.cmd == a) {
let out = command.cb(msg, this, cl);
if (typeof out == 'undefined' || out == '') return;
cl.sendChat(out);
}
});
});
}
});
this.player.on('fileLoaded', () => {
setTimeout(() => {
this.player.sampleRate = 0;
this.player.play();
}, 5000);
});
this.player.on('midiEvent', evt => {
if (evt.channel == 10) return;
if (evt.velocity < 10) return;
if (evt.name == "Note off" || (evt.name == "Note on" && evt.velocity === 0)) {
this.client.stopNote(this.keys[evt.noteName]);
} else if (evt.name == "Note on") {
this.client.startNote(this.keys[evt.noteName], evt.velocity / 100);
} else if (evt.name == "Set Tempo") {
this.player.tempo = evt.data;
}
});
}
bindGeneralCommands() {
let gp = this.commandGroups.find(g => g.id === 'general');
gp.addCommand(new Command(['help', 'cmds', 'h'], '$PREFIXhelp (command)', 0, (msg, bot, cl) => {
this.commandGroups.forEach(group => {
let hasPermission = false;
group.permissionLevels.forEach(perm => {
if (User.hasPermission(msg.user, perm)) {
hasPermission = true;
return;
}
});
// console.log('hasPermission: ', hasPermission);
// console.log('group.id: ', group.id);
if (!hasPermission) return;
let cmds = group.availableCommands.map(cmd => {
if (!group.commandIsDisabled(cmd) && !cmd.hidden) return `${group.prefixes[0].prefix}${cmd.acc[0]}`;
}).filter(cmd => cmd);
cl.sendChat(`${group.name}: ${cmds.join(', ')}`);
});
}));
gp.addCommand(new Command(['color', 'c'], '$PREFIXcolor (color)', 0, msg => {
let col = msg.argv._.slice(1, msg.argv._.length).join(' ')
if (!msg.args[1]) col = msg.p.color;
let color = new Color(col); // TODO color command: ability to do color math?
if (msg.argv.verbose || msg.argv.v) {
let verbose = ` [${color.toHexa()}] (${color.r} ${color.g} ${color.b})`;
return `${color.getName()} ${verbose}`
} else {
return `${color.getName()}`;
}
}));
gp.addCommand(new Command(['id'], '$PREFIXid', 0, msg => {
return `${msg.p.name}'s ID: ${msg.p._id}`;
}));
gp.addCommand(new Command(['argcat'], '$PREFIXargcat', 1, msg => {
let args = msg.argv._.join(' ');
delete msg.argv._;
let keyvals = "";
for (let key of Object.keys(msg.argv)) {
keyvals += `${key}: ${msg.argv[key]} | `;
}
keyvals = keyvals.substr(0, keyvals.length - 2).trim();
return `argv: ${args} | opt: ${keyvals}`;
}, true));
gp.addCommand(new Command(['poll'],'$PREFIXpoll (yes/no)', 0, (msg, bot, cl) => {
if (!msg.args[1]) {
Database.get('poll_yes').then(yes => {
Database.get('poll_no').then(no => {
cl.sendChat(`Poll: ${this.currentPoll.question} | ${this.currentPoll.options[0]}: ${JSON.parse(yes).length} / ${this.currentPoll.options[1]}: ${JSON.parse(no).length}`);
});
});
} else {
if (this.currentPoll.options[0].toLowerCase().includes(msg.args[1].toLowerCase())) {
Database.get('poll_yes').then(yes => {
let arr = JSON.parse(yes);
if (arr.indexOf(msg.p._id) !== -1) arr.push(msg.p._id);
Database.set('poll_yes', JSON.stringify(arr));
cl.sendChat(`Your answer (${this.currentPoll.options[0]}) was counted.`);
});
} else if (this.currentPoll.options[1].toLowerCase().includes(msg.args[1].toLowerCase())) {
Database.get('poll_no').then(no => {
let arr = JSON.parse(no);
if (arr.indexOf(msg.p._id) !== -1) arr.push(msg.p._id);
Database.set('poll_no', JSON.stringify(arr));
cl.sendChat(`Your answer (${this.currentPoll.options[1]}) was counted.`);
});
}
}
}));
gp.addCommand(new Command(['data'], '$PREFIXdata', 0, msg => {
let out = `${msg.p._id}: { `;
for (let key of Object.keys(msg)) {
if (typeof(msg[key]) == 'object') {
out += `${key}: { `
for (let k of Object.keys(msg[key])) {
out += `${k}: ${msg[key][k]}, `;
}
out += ` }, `;
} else {
out += `${key}: ${msg[key]}, `;
}
}
out = out.substr(0, out.trim().length - 1).trim() + " }";
return out;
}, true));
gp.addCommand(new Command(['info'], '$PREFIXinfo', 0, msg => {
let pkg = require('../package.json');
let pkginfo = `${pkg.name} v${pkg.version}`;
let node = `Node ${process.version}`;
if (msg.argv.node || msg.argv.n) {
return `Using ${node}`;
}
if (msg.argv.pkginfo || msg.argv.p) {
return `Using ${pkginfo}`;
}
return `Bot package: ${pkginfo} | Running on ${node}`;
}));
gp.addCommand(new Command(['giveitemthatnobodyseesyet'], '$PREFIXgiveitemthatnobodyseesyet', 0, msg => {
Database.addItem(msg.user._id, new ItemConsumable('healthPotion', 'Health Potion', 'A potion that restores health', 10, 1, 'consumable_hp', 10, 5));
}, true));
gp.addCommand(new Command(['inventory', 'inv'], '$PREFIXinventory', 0, msg => {
let inv = msg.user.inventory;
let out = `${msg.user.name}'s Inventory: `;
let startLength = out.length;
for (let key of Object.keys(inv)) {
// out += `${key}: `;
for (let i of inv[key]) {
if (i.count > 1) {
out += `${i.name} (x${i.count}) | `;
} else {
out += `${i.name} | `;
}
}
}
// remove last |
if (out.length > startLength) out = out.substring(0, out.length - 2);
if (out.length <= startLength) {
out += "(Empty)";
}
return out;
}, true));
gp.disableCommand(gp.getCommandByName('inventory'));
gp.addCommand(new Command(['status', 'stats', 'stat', 'st'], '$PREFIXstatus', 0, msg => {
let user = msg.user;
if (msg.args[1]) {
user = Object.values(cl.ppl).find(p => p.name.toLowerCase().includes(msg.argcat.toLowerCase()) || p._id.toLowerCase().includes(msg.argcat.toLowerCase()));
if (!user) return `User ${msg.args[1]} not found`;
}
let out = `${msg.user.name}'s Stats: `;
for (let stat of Object.keys(user)) {
out += `${stat}: ${user[stat]} | `;
}
return out;
}, true));
gp.addCommand(new Command(['time'], '$PREFIXtime', 0, msg => {
// TODO timezone options
function calcTime(city, offset) {
// create Date object for current location
var d = new Date();
// convert to msec
// subtract local time zone offset
// get UTC time in msec
var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
// create new Date object for different city
// using supplied offset
var nd = new Date(utc + (3600000*offset));
// return time as a string
return nd.toLocaleString();
}
// if (msg.argv.city) {
// try {
// return `Date & Time in ${msg.argv.city}: ${calcTime(msg.argv.city)}`;
// } catch (err) {
// }
// }
return `Date & Time: ${new Date().toLocaleString()}`;
}));
gp.addCommand(new Command(['about'], '$PREFIXabout', 0, msg => {
return `This bot was made by Hri7566#3409.`;
}));
gp.addCommand(new Command(['say'], '$PREFIXsay (message)', 1, msg => {
let str = msg.argv._.join(' ').substr(msg.argv._[0].length).trim();
if (msg.argv.spooky1) {
str = str.replace(/[aeiou]/gi, 'o');
}
if (msg.argv.capital || msg.argv.uppercase) {
str = str.toUpperCase();
}
if (msg.argv.lowercase) {
str = str.toLowerCase();
}
return `${str}`;
}));
}
gayFollow(id, cl) {
if (!id) {
this.gayFollowing = false;
cl.setName(this.defaultName);
}
cl.setName('gay ----->');
this.gayFollowing = true;
this.gayId = id;
}
bindFunCommands() {
let gp = this.commandGroups.find(g => g.id === 'fun');
gp.addCommand(new Command(['kill'], `$PREFIXkill (user)`, 1, (msg, bot, cl) => {
let user = Object.values(cl.ppl).find(p => p.name.toLowerCase().includes(msg.argcat.toLowerCase()) || p._id.toLowerCase().includes(msg.argcat.toLowerCase()));
if (!user) return `User '${msg.argcat}' not found.`;
let kill = Math.floor(Math.random() * (5 - 1 + 1)) + 1;
if (kill == 1) {
return `${msg.p.name} tried to kill ${user.name}, but friend ${msg.p.name} missed by a few burritos.`;
} else if (kill == 2) {
return `${user.name} was killed by ${msg.p.name} by boiling them in chili.`;
} else if (kill == 3) {
return `${user.name} was killed by ${msg.p.name}. Hopefully, they will never steal the cookies again.`;
} else if (kill == 4) {
return `By sheer luck, ${user.name} had a heart attack thinking about ducks and ${msg.p.name} didn't have to get involved.`;
} else if (kill == 5) {
return `${msg.p.name} threw ${user.name} into the fire. Now we'll all be warm.`;
}
}));
gp.addCommand(new Command(['slap'], '$PREFIXslap (user)', 1, (msg, bot, cl) => {
let user = Object.values(cl.ppl).find(p => p.name.toLowerCase().includes(msg.argcat.toLowerCase()) || p._id.toLowerCase().includes(msg.argcat.toLowerCase()));
if (!user) return `User '${msg.argcat}' not found.`;
let slap = Math.floor(Math.random() * (5 - 1 + 1)) + 1;
if (slap == 1) {
return `${msg.p.name} tried to slap ${user.name}, but friend ${msg.p.name} missed by a few burritos.`;
} else if (slap == 2) {
return `${user.name} was slapped by ${msg.p.name} and it left a mark.`;
} else if (slap == 3) {
return `${user.name} was slapped by ${msg.p.name} and it left a bruise.`;
} else if (slap == 4) {
return `${user.name} was slapped by ${msg.p.name} so hard, it left a scar.`;
} else if (slap == 5) {
return `${user.name} was slapped by ${msg.p.name} and they flew across the room.`;
}
return `${msg.p.name} slapped ${user.name}`;
}));
gp.addCommand(new Command(['arrest'], '$PREFIXarrest (user)', 1, (msg, bot, cl) => {
return `${msg.argcat}, I'm arresting you because I can. Anything you say can and will be used against you in a court of law. This means that what they say can become evidence in a trial against them. There are other rights that the police usually read after that: You have the right to an attorney.`;
}, true));
gp.addCommand(new Command(['retardify'], '$PREFIXretardify (text)', 1, (msg, bot, cl) => {
return `${retardify(msg.argcat)}`;
}));
gp.addCommand(new Command(['reverse'], '$PREFIXreverse (text)', 1, (msg, bot, cl) => {
return `${msg.argcat.split('').reverse().join('')}`;
}));
gp.addCommand(new Command(['shrug'], '$PREFIXshrug', 0, (msg, bot, cl) => {
return `¯\\_(ツ)_/¯`;
}));
gp.addCommand(new Command(['tableflip'], '$PREFIXtableflip', 0, (msg, bot, cl) => {
return `(╯°□°)╯︵ ┻━┻`;
}));
gp.addCommand(new Command(['tableunflip'], '$PREFIXtableunflip', 0, (msg, bot, cl) => {
return `┬─┬ ( ゜-゜ノ)`;
}, true));
gp.addCommand(new Command(['coinflip'], '$PREFIXcoinflip', 0, (msg, bot, cl) => {
let coin = Math.floor(Math.random() * (2 - 1 + 1)) + 1;
if (coin == 1) {
return `Heads`;
} else {
return `Tails`;
}
}));
gp.addCommand(new Command(['fuck'], '$PREFIXfuck (user)', 1, (msg, bot, cl) => {
let user = Object.values(cl.ppl).find(p => p.name.toLowerCase().includes(msg.argcat.toLowerCase()) || p._id.toLowerCase().includes(msg.argcat.toLowerCase()));
if (!user) return `User '${msg.argcat}' not found.`;
let fuck = Math.floor(Math.random() * (5 - 1 + 1)) + 1;
if (fuck == 1) {
return `${msg.p.name} tried to fuck ${user.name}, but friend ${msg.p.name} missed by a few burritos.`;
} else if (fuck == 2) {
return `${user.name} was fucked by ${msg.p.name} right in the ass.`;
} else if (fuck == 3) {
return `${user.name} was fucked by ${msg.p.name}. Hopefully, they will never steal the cookies again.`;
} else if (fuck == 4) {
return `${msg.p.name} fucked ${user.name} in the face. They are now blind and deaf.`;
} else if (fuck == 5) {
return `${msg.p.name} fucked ${user.name}. You are now dead. Please take your receipt.`;
}
}, true));
gp.addCommand(new Command(['gayfollow', 'gayify', 'gay'], `$PREFIXgayfollow [user]`, 0, (msg, bot, cl) => {
if (msg.argv.stop || msg.argv.s) {
this.gayFollow(undefined, cl);
return `stopped gaying`;
}
let p = cl.getParticipant(msg.args[1]);
if (!p) {
return `could not gay ${msg.args[1]}`;
}
this.gayFollow(p, cl);
return `now gaying ${p.name}`
}, true))
}
bindModCommands() {
let gp = this.commandGroups.find(g => g.id === 'mod');
gp.addCommand(new Command(['play'], '$PREFIXplay (song)', 1, msg => {
try {
if (!msg.argcat.endsWith('.mid')) msg.argcat += '.mid';
this.client.sendChat(`Playing '${msg.argcat}'...`);
this.player.loadFile(path.join(__appdir, "midis", msg.argcat));
} catch (err) {
console.error(err);
return `Error playing ${msg.argcat}`;
}
}));
gp.addCommand(new Command(['stop'], '$PREFIXstop (song)', 0, msg => {
this.player.stop();
return `Stopped playing.`;
}));
}
bindAdminCommands() {
let gp = this.commandGroups.find(g => g.id === 'admin');
gp.addCommand(new Command(['download'], '$PREFIXdownload (song)', 0, msg => {
// TODO fix and test download
try {
let u = new url.URL(msg.argcat);
let filename = u.pathname.split('/').reverse()[0];
if (!filename.endsWith('.mid')) filename = filename + '.mid';
this.client.sendChat(`Downloading '${filename}'...`);
fetch(msg.argcat).then(x => {
x.arrayBuffer();
}).then(x => {
downloadFile(x, path.join(__appdir, "midis", filename), () => {
this.client.sendChat(`Downloaded '${filename}'!`);
});
// if (x[0] == 'M' && x[1] == 'T' && x[2] == 'h' && x[3] == 'd') {
// writeFile(path.join(__appdir, 'midis', filename), x);
// this.client.sendChat(`Download of '${msg.argcat}' finished and saved as '${filename}'.`);
// } else {
// this.client.sendChat(`Download of '${msg.argcat}' failed because the file has no MIDI header.`);
// }
});
} catch (err) {
return `Download of '${msg.argcat}' failed.`;
}
}, true));
gp.addCommand(new Command(['permissiongroups', 'groups'], '$PREFIXpermissiongroups', 0, msg => {
let groups = [];
for (let group of msg.user.permissionGroups) {
groups.push(PermissionGroup.findGroup(group).displayName);
}
groups = groups.join(', ');
return `Your permission groups: ${groups ? groups : "(None)"}`;
}));
gp.addCommand(new Command(['permtest'], '$PREFIXpermtest (permission)', 1, msg => {
return User.hasPermission(msg.user, msg.argv._[0]) ? true : false;
}, true));
gp.addCommand(new Command(['checkperm'], '$PREFIXcheckperm (permission)', 2, msg => {
if (!msg.args[1]) return `Usage: ${msg.argv._[0]} (permission) (permission)`;
return Permission.checkPermission(msg.args[1], msg.args[2]) == true ? true : false;
}, true));
gp.addCommand(new Command(['js'], '$PREFIXjs (code)', 1, msg => {
try {
let result = eval(msg.argcat);
return '✅ ' + result;
} catch (err) {
return '❌ ' + err;
}
}));
}
addCommand(cmd) {
this.commands.push(cmd);
}
getPublicData() {
return {
u: this.client.getOwnParticipant(),
ppl: this.client.ppl
}
}
getCursorData() {
return this.cursor;
}
error(...args) {
args.forEach(arg => console.error(`Bot error: ${arg}`));
}
}
class Command {
constructor (acc, usage, minargs, cb, hidden) {
this.acc = acc; // list of accessors
this.usage = usage; // command usage
// TODO command descriptions
this.minargs = minargs; // minimum required arguments
this.cb = cb; // callback
this.hidden = hidden || false;
}
getUsage(prefix) {
if (prefix) return this.usage.split('$PREFIX').join(prefix);
return this.usage.split('$PREFIX').join(this.defaultPrefix);
}
}
module.exports = {
Bot,
Command
}