mrmBot-Matrix/shard.js
Essem 40223ec8b5
Class commands, improved sharding, and many other changes (#88)
* Load commands recursively

* Sort commands

* Missed a couple of spots

* missed even more spots apparently

* Ported commands in "fun" category to new class-based format, added babel eslint plugin

* Ported general commands, removed old/unneeded stuff, replaced moment with day, many more fixes I lost track of

* Missed a spot

* Removed unnecessary abort-controller package, add deprecation warning for mongo database

* Added imagereload, clarified premature end message

* Fixed docker-compose path issue, added total bot uptime to stats, more fixes for various parts

* Converted image commands into classes, fixed reload, ignore another WS event, cleaned up command handler and image runner

* Converted music/soundboard commands to class format

* Cleanup unnecessary logs

* awful tag command class port

* I literally somehow just learned that you can leave out the constructor in classes

* Pass client directly to commands/events, cleaned up command handler

* Migrated bot to eris-sharder, fixed some error handling stuff

* Remove unused modules

* Fixed type returning

* Switched back to Eris stable

* Some fixes and cleanup

* might wanna correct this

* Implement image command ratelimiting

* Added Bot token prefix, added imagestats, added running endpoint to API
2021-04-12 11:16:12 -05:00

130 lines
No EOL
3.8 KiB
JavaScript

// shard base
const { Base } = require("eris-sharder");
// path stuff
const { readdir } = require("fs").promises;
// fancy loggings
const logger = require("./utils/logger.js");
// initialize command loader
const handler = require("./utils/handler.js");
// lavalink stuff
const sound = require("./utils/soundplayer.js");
// image processing stuff
const image = require("./utils/image.js");
// database stuff
const database = require("./utils/database.js");
// dbl posting
const poster = require("topgg-autoposter");
// command collections
const collections = require("./utils/collections.js");
// playing messages
const messages = require("./messages.json");
// other stuff
const misc = require("./utils/misc.js");
// generate help page
const helpGenerator =
process.env.OUTPUT !== "" ? require("./utils/help.js") : null;
class Shard extends Base {
constructor(bot) {
super(bot);
}
async init() {
// register commands and their info
const soundStatus = await sound.checkStatus();
logger.log("info", "Attempting to load commands...");
for await (const commandFile of this.getFiles("./commands/")) {
logger.log("log", `Loading command from ${commandFile}...`);
try {
await handler.load(commandFile, soundStatus);
} catch (e) {
logger.error(`Failed to register command from ${commandFile}: ${e}`);
}
}
// register events
const events = await readdir("./events/");
logger.log("info", `Attempting to load ${events.length} events...`);
for (const file of events) {
logger.log("log", `Loading event from ${file}...`);
const eventName = file.split(".")[0];
const event = require(`./events/${file}`);
this.bot.on(eventName, event.bind(null, this.bot));
}
// connect to image api if enabled
if (process.env.API === "true") {
for (const server of image.servers) {
try {
await image.connect(server);
} catch (e) {
logger.error(e);
}
}
// generate docs
if (this.clusterID === 0 && helpGenerator) {
helpGenerator.generateList().then(() => helpGenerator.createPage(process.env.OUTPUT)).then(() => logger.log("info", "The help docs have been generated."));
}
}
// dbl posting
if (process.env.NODE_ENV === "production" && process.env.DBL !== "") {
const dbl = poster(process.env.DBL, this.bot);
dbl.on("posted", () => {
logger.log("Posted stats to top.gg");
});
dbl.on("error", e => {
logger.error(e);
});
}
// handle process stop
process.on("SIGINT", () => {
logger.log("warn", "SIGINT detected, shutting down...");
this.bot.editStatus("dnd", {
name: "Restarting/shutting down..."
});
for (const command in collections.commands) {
handler.unload(command);
}
this.bot.disconnect();
require("./utils/database.js").stop();
process.exit(0);
});
return;
}
async* getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
if (dirent.isDirectory()) {
yield* this.getFiles(dir + dirent.name);
} else {
yield dir + (dir.charAt(dir.length - 1) !== "/" ? "/" : "") + dirent.name;
}
}
}
async launch() {
await this.init();
// connect to lavalink
if (!sound.status && !sound.connected) await sound.connect(this.bot);
await database.setup();
// set activity (a.k.a. the gamer code)
(async function activityChanger() {
this.bot.editStatus("dnd", {
name: `${misc.random(messages)} | @${this.bot.user.username} help`,
});
setTimeout(activityChanger.bind(this), 900000);
}).bind(this)();
if (process.env.PMTWO === "true") process.send("ready");
logger.log("info", `Started cluster ${this.clusterID}.`);
}
}
module.exports = Shard;