mrmBot-Matrix/shard.js

146 lines
4.4 KiB
JavaScript

// shard base
import { BaseClusterWorker } from "eris-fleet";
// path stuff
import { readdir } from "fs/promises";
import { readFileSync } from "fs";
// fancy loggings
import { log, error } from "./utils/logger.js";
// initialize command loader
import { load } from "./utils/handler.js";
// lavalink stuff
import { checkStatus, connect, status, connected } from "./utils/soundplayer.js";
// database stuff
import database from "./utils/database.js";
// command collections
import { paths } from "./utils/collections.js";
// playing messages
const { messages } = JSON.parse(readFileSync(new URL("./messages.json", import.meta.url)));
// other stuff
import { random } from "./utils/misc.js";
// generate help page
import { generateList, createPage } from "./utils/help.js";
// whether a broadcast is currently in effect
let broadcast = false;
class Shard extends BaseClusterWorker {
constructor(bot) {
super(bot);
console.info = (str) => this.ipc.sendToAdmiral("info", str);
this.init();
}
async init() {
// register commands and their info
const soundStatus = await checkStatus();
log("info", "Attempting to load commands...");
for await (const commandFile of this.getFiles("./commands/")) {
log("log", `Loading command from ${commandFile}...`);
try {
await load(commandFile, soundStatus);
} catch (e) {
error(`Failed to register command from ${commandFile}: ${e}`);
}
}
log("info", "Finished loading commands.");
// register events
log("info", `Attempting to load events...`);
for await (const file of this.getFiles("./events/")) {
log("log", `Loading event from ${file}...`);
const eventArray = file.split("/");
const eventName = eventArray[eventArray.length - 1].split(".")[0];
const { default: event } = await import(`./${file}`);
this.bot.on(eventName, event.bind(null, this.bot, this.clusterID, this.workerID, this.ipc));
}
log("info", "Finished loading events.");
// generate docs
if (process.env.OUTPUT && process.env.OUTPUT !== "") {
await generateList();
if (this.clusterID === 0) {
await createPage(process.env.OUTPUT);
log("info", "The help docs have been generated.");
}
}
this.ipc.register("reload", async (message) => {
const path = paths.get(message);
if (!path) return this.ipc.broadcast("reloadFail", { result: "I couldn't find that command!" });
const result = await load(path, await checkStatus());
if (result) return this.ipc.broadcast("reloadFail", { result });
return this.ipc.broadcast("reloadSuccess");
});
this.bot.privateChannels.limit = 0;
this.ipc.register("soundreload", async () => {
const soundStatus = await checkStatus();
if (!soundStatus) {
const length = await connect(this.bot);
return this.ipc.broadcast("soundReloadSuccess", { length });
} else {
return this.ipc.broadcast("soundReloadFail");
}
});
this.ipc.register("playbroadcast", (message) => {
this.bot.editStatus("dnd", {
name: `${message} | @${this.bot.user.username} help`,
});
broadcast = true;
return this.ipc.broadcast("broadcastSuccess");
});
this.ipc.register("broadcastend", () => {
this.bot.editStatus("dnd", {
name: `${random(messages)} | @${this.bot.user.username} help`,
});
broadcast = false;
return this.ipc.broadcast("broadcastEnd");
});
// connect to lavalink
if (!status && !connected) connect(this.bot);
database.setup();
this.activityChanger();
log("info", `Started worker ${this.workerID}.`);
}
// set activity (a.k.a. the gamer code)
activityChanger() {
if (!broadcast) {
this.bot.editStatus("dnd", {
name: `${random(messages)} | @${this.bot.user.username} help`,
});
}
setTimeout(this.activityChanger.bind(this), 900000);
}
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 if (dirent.name.endsWith(".js")) {
yield dir + (dir.charAt(dir.length - 1) !== "/" ? "/" : "") + dirent.name;
}
}
}
shutdown(done) {
log("warn", "Shutting down...");
this.bot.editStatus("dnd", {
name: "Restarting/shutting down..."
});
database.stop();
done();
}
}
export default Shard;