750 lines
29 KiB
JavaScript
750 lines
29 KiB
JavaScript
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
|
||
}
|