Remove "requires" command field, overhaul Lavalink connection, fix message objects not being properly sent

This commit is contained in:
Essem 2022-10-11 10:46:10 -05:00
parent a274acd00c
commit e5fd71b388
No known key found for this signature in database
GPG Key ID: 7D497397CC3A2A8C
10 changed files with 51 additions and 84 deletions

14
app.js
View File

@ -35,7 +35,7 @@ import { paths } from "./utils/collections.js";
// database stuff // database stuff
import database from "./utils/database.js"; import database from "./utils/database.js";
// lavalink stuff // lavalink stuff
import { checkStatus, reload, connect, status, connected } from "./utils/soundplayer.js"; import { reload, connect, connected } from "./utils/soundplayer.js";
// events // events
import { endBroadcast, startBroadcast } from "./utils/misc.js"; import { endBroadcast, startBroadcast } from "./utils/misc.js";
import { parseThreshold } from "./utils/tempimages.js"; import { parseThreshold } from "./utils/tempimages.js";
@ -106,12 +106,11 @@ esmBot ${esmBotVersion} (${process.env.GIT_REV})
} }
// register commands and their info // register commands and their info
const soundStatus = await checkStatus();
logger.log("info", "Attempting to load commands..."); logger.log("info", "Attempting to load commands...");
for await (const commandFile of getFiles(resolve(dirname(fileURLToPath(import.meta.url)), "./commands/"))) { for await (const commandFile of getFiles(resolve(dirname(fileURLToPath(import.meta.url)), "./commands/"))) {
logger.log("main", `Loading command from ${commandFile}...`); logger.log("main", `Loading command from ${commandFile}...`);
try { try {
await load(null, commandFile, soundStatus); await load(null, commandFile);
} catch (e) { } catch (e) {
logger.error(`Failed to register command from ${commandFile}: ${e}`); logger.error(`Failed to register command from ${commandFile}: ${e}`);
} }
@ -175,13 +174,10 @@ esmBot ${esmBotVersion} (${process.env.GIT_REV})
switch (packet.data?.type) { switch (packet.data?.type) {
case "reload": case "reload":
var path = paths.get(packet.data.message); var path = paths.get(packet.data.message);
await load(client, path, await checkStatus(), true); await load(client, path, true);
break; break;
case "soundreload": case "soundreload":
var soundStatus = await checkStatus(); await reload(client);
if (!soundStatus) {
reload();
}
break; break;
case "imagereload": case "imagereload":
await reloadImageConnections(); await reloadImageConnections();
@ -212,7 +208,7 @@ esmBot ${esmBotVersion} (${process.env.GIT_REV})
} }
// connect to lavalink // connect to lavalink
if (!status && !connected) connect(client); if (!connected) connect(client);
client.connect(); client.connect();
} }

View File

@ -63,7 +63,6 @@ class Command {
static aliases = []; static aliases = [];
static arguments = []; static arguments = [];
static flags = []; static flags = [];
static requires = [];
static slashAllowed = true; static slashAllowed = true;
static directAllowed = true; static directAllowed = true;
static adminOnly = false; static adminOnly = false;

View File

@ -10,7 +10,6 @@ class MusicCommand extends Command {
} }
} }
static requires = ["sound"];
static slashAllowed = false; static slashAllowed = false;
static directAllowed = false; static directAllowed = false;
} }

View File

@ -4,10 +4,9 @@ import { play } from "../utils/soundplayer.js";
// only exists to sort the various soundboard commands // only exists to sort the various soundboard commands
class SoundboardCommand extends Command { class SoundboardCommand extends Command {
async run() { async run() {
return await play(this.client, this.constructor.file, { channel: this.channel, author: this.author, member: this.member, type: this.type, interaction: this.interaction }); return play(this.client, this.constructor.file, { channel: this.channel, author: this.author, member: this.member, type: this.type, interaction: this.interaction });
} }
static requires = ["sound"];
static slashAllowed = false; static slashAllowed = false;
static directAllowed = false; static directAllowed = false;
} }

View File

@ -1,5 +1,5 @@
import Command from "../../classes/command.js"; import Command from "../../classes/command.js";
import { checkStatus, reload } from "../../utils/soundplayer.js"; import { reload } from "../../utils/soundplayer.js";
class SoundReloadCommand extends Command { class SoundReloadCommand extends Command {
async run() { async run() {
@ -9,17 +9,16 @@ class SoundReloadCommand extends Command {
return "Only the bot owner can reload Lavalink!"; return "Only the bot owner can reload Lavalink!";
} }
await this.acknowledge(); await this.acknowledge();
const soundStatus = await checkStatus(); const length = await reload();
if (!soundStatus) { if (process.env.PM2_USAGE) {
const length = reload(); process.send({
if (process.env.PM2_USAGE) { type: "process:msg",
process.send({ data: {
type: "process:msg", type: "soundreload"
data: { }
type: "soundreload" });
} }
}); if (length) {
}
return `Successfully connected to ${length} Lavalink node(s).`; return `Successfully connected to ${length} Lavalink node(s).`;
} else { } else {
return "I couldn't connect to any Lavalink nodes!"; return "I couldn't connect to any Lavalink nodes!";

View File

@ -41,7 +41,6 @@ class MusicAIOCommand extends Command {
} }
static description = "Handles music playback"; static description = "Handles music playback";
static requires = ["sound"];
static aliases = ["m"]; static aliases = ["m"];
static directAllowed = false; static directAllowed = false;
} }

View File

@ -28,7 +28,6 @@ class SoundboardAIOCommand extends Command {
} }
static description = "Plays a sound effect"; static description = "Plays a sound effect";
static requires = ["sound"];
static aliases = ["sound", "sb"]; static aliases = ["sound", "sb"];
static directAllowed = false; static directAllowed = false;
} }

View File

@ -122,33 +122,35 @@ export default async (client, message) => {
await client.rest.channels.createMessage(message.channelID, Object.assign({ await client.rest.channels.createMessage(message.channelID, Object.assign({
content: result content: result
}, reference)); }, reference));
} else if (typeof result === "object" && result.embeds) { } else if (typeof result === "object") {
await client.rest.channels.createMessage(message.channelID, Object.assign(result, reference)); if (result.contents && result.name) {
} else if (typeof result === "object" && result.contents) { let fileSize = 8388119;
let fileSize = 8388119; if (message.guildID) {
if (message.guildID) { switch (message.guild.premiumTier) {
switch (message.guild.premiumTier) { case 2:
case 2: fileSize = 52428308;
fileSize = 52428308; break;
break; case 3:
case 3: fileSize = 104856616;
fileSize = 104856616; break;
break; }
} }
} if (result.contents.length > fileSize) {
if (result.contents.length > fileSize) { if (process.env.TEMPDIR && process.env.TEMPDIR !== "") {
if (process.env.TEMPDIR && process.env.TEMPDIR !== "") { await upload(client, result, message);
await upload(client, result, message); } else {
await client.rest.channels.createMessage(message.channelID, {
content: "The resulting image was more than 8MB in size, so I can't upload it."
});
}
} else { } else {
await client.rest.channels.createMessage(message.channelID, { await client.rest.channels.createMessage(message.channelID, Object.assign({
content: "The resulting image was more than 8MB in size, so I can't upload it." content: result.text ? result.text : undefined,
}); files: [result]
}, reference));
} }
} else { } else {
await client.rest.channels.createMessage(message.channelID, Object.assign({ await client.rest.channels.createMessage(message.channelID, Object.assign(result, reference));
content: result.text ? result.text : undefined,
files: [result]
}, reference));
} }
} }
} catch (error) { } catch (error) {

View File

@ -8,13 +8,9 @@ const { blacklist } = JSON.parse(readFileSync(new URL("../config/commands.json",
let queryValue = 0; let queryValue = 0;
// load command into memory // load command into memory
export async function load(client, command, soundStatus, slashReload = false) { export async function load(client, command, slashReload = false) {
const { default: props } = await import(`${command}?v=${queryValue}`); const { default: props } = await import(`${command}?v=${queryValue}`);
queryValue++; queryValue++;
if (props.requires.includes("sound") && soundStatus) {
log("warn", `Failed to connect to some Lavalink nodes, skipped loading command ${command}...`);
return;
}
const commandArray = command.split("/"); const commandArray = command.split("/");
let commandName = commandArray[commandArray.length - 1].split(".")[0]; let commandName = commandArray[commandArray.length - 1].split(".")[0];
const category = commandArray[commandArray.length - 2]; const category = commandArray[commandArray.length - 2];

View File

@ -1,5 +1,4 @@
import * as logger from "./logger.js"; import * as logger from "./logger.js";
import { request } from "undici";
import fs from "fs"; import fs from "fs";
import format from "format-duration"; import format from "format-duration";
import { Shoukaku, Connectors } from "shoukaku"; import { Shoukaku, Connectors } from "shoukaku";
@ -10,27 +9,9 @@ export const queues = new Map();
export const skipVotes = new Map(); export const skipVotes = new Map();
export let manager; export let manager;
export let nodes; export let nodes = JSON.parse(fs.readFileSync(new URL("../config/servers.json", import.meta.url), { encoding: "utf8" })).lava;
export let status = false;
export let connected = false; export let connected = false;
export async function checkStatus() {
const json = await fs.promises.readFile(new URL("../config/servers.json", import.meta.url), { encoding: "utf8" });
nodes = JSON.parse(json).lava;
const newNodes = [];
for (const node of nodes) {
try {
const response = await request(`http://${node.url}/version`, { headers: { authorization: node.auth } }).then(res => res.body.text());
if (response) newNodes.push(node);
} catch (e) {
logger.error(`Failed to get status of Lavalink node ${node.url}: ${e}`);
}
}
nodes = newNodes;
status = newNodes.length === 0 ? true : false;
return status;
}
export function connect(client) { export function connect(client) {
manager = new Shoukaku(new Connectors.OceanicJS(client), nodes, { moveOnDisconnect: true, resume: true, reconnectInterval: 500, reconnectTries: 1 }); manager = new Shoukaku(new Connectors.OceanicJS(client), nodes, { moveOnDisconnect: true, resume: true, reconnectInterval: 500, reconnectTries: 1 });
manager.on("error", (node, error) => { manager.on("error", (node, error) => {
@ -42,8 +23,11 @@ export function connect(client) {
}); });
} }
export function reload() { export async function reload(client) {
if (!manager) connect(client);
const activeNodes = manager.nodes; const activeNodes = manager.nodes;
const json = await fs.promises.readFile(new URL("../config/servers.json", import.meta.url), { encoding: "utf8" });
nodes = JSON.parse(json).lava;
const names = nodes.map((a) => a.name); const names = nodes.map((a) => a.name);
for (const name in activeNodes) { for (const name in activeNodes) {
if (!names.includes(name)) { if (!names.includes(name)) {
@ -55,10 +39,12 @@ export function reload() {
manager.addNode(node); manager.addNode(node);
} }
} }
if (!manager.nodes.size) connected = false;
return manager.nodes.size; return manager.nodes.size;
} }
export async function play(client, sound, options, music = false) { export async function play(client, sound, options, music = false) {
if (!connected) return { content: "I'm not connected to any audio servers!", flags: 64 };
if (!manager) return { content: "The sound commands are still starting up!", flags: 64 }; if (!manager) return { content: "The sound commands are still starting up!", flags: 64 };
if (!options.channel.guild) return { content: "This command only works in servers!", flags: 64 }; if (!options.channel.guild) return { content: "This command only works in servers!", flags: 64 };
if (!options.member.voiceState) return { content: "You need to be in a voice channel first!", flags: 64 }; if (!options.member.voiceState) return { content: "You need to be in a voice channel first!", flags: 64 };
@ -66,14 +52,7 @@ export async function play(client, sound, options, music = false) {
const voiceChannel = options.channel.guild.channels.get(options.member.voiceState.channelID); const voiceChannel = options.channel.guild.channels.get(options.member.voiceState.channelID);
if (!voiceChannel.permissionsOf(client.user.id.toString()).has("CONNECT")) return { content: "I don't have permission to join this voice channel!", flags: 64 }; if (!voiceChannel.permissionsOf(client.user.id.toString()).has("CONNECT")) return { content: "I don't have permission to join this voice channel!", flags: 64 };
if (!music && manager.players.has(options.channel.guildID)) return { content: "I can't play a sound effect while other audio is playing!", flags: 64 }; if (!music && manager.players.has(options.channel.guildID)) return { content: "I can't play a sound effect while other audio is playing!", flags: 64 };
let node = manager.getNode(); const node = manager.getNode();
if (!node) {
const status = await checkStatus();
if (!status) {
connect(client);
node = manager.getNode();
}
}
if (!music && !nodes.filter(obj => obj.name === node.name)[0].local) { if (!music && !nodes.filter(obj => obj.name === node.name)[0].local) {
sound = sound.replace(/\.\//, "https://raw.githubusercontent.com/esmBot/esmBot/master/"); sound = sound.replace(/\.\//, "https://raw.githubusercontent.com/esmBot/esmBot/master/");
} }