From e537ce8778c16ad297121a153e224910c4e5b2b8 Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sun, 26 Mar 2023 16:43:51 -0400 Subject: [PATCH] Update bot to use command controller for interactions and calls --- Client/commands/join.js | 58 +----------- Client/commands/leave.js | 35 +------- Client/commands/status.js | 2 +- Client/controllers/botController.js | 35 +------- Client/controllers/commandController.js | 114 ++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 121 deletions(-) create mode 100644 Client/controllers/commandController.js diff --git a/Client/commands/join.js b/Client/commands/join.js index 850ecc3..f31f156 100644 --- a/Client/commands/join.js +++ b/Client/commands/join.js @@ -2,15 +2,8 @@ const { DebugBuilder } = require("../utilities/debugBuilder"); const log = new DebugBuilder("client", "ping"); // Modules -const { joinVoiceChannel, VoiceConnectionStatus } = require("@discordjs/voice"); -const {replyToInteraction} = require("../utilities/messageHandler.js"); const { SlashCommandBuilder } = require('discord.js'); -const {createAudioInstance} = require("../controllers/audioController.js"); -const OpusEncoderPkg = require("@discordjs/opus"); - -// Declare the encoder (module is incompatible modern import method) -const { OpusEncoder } = OpusEncoderPkg; -const encoder = new OpusEncoder(48000, 2); +const { join } = require("../controllers/commandController") module.exports = { data: new SlashCommandBuilder() @@ -19,53 +12,6 @@ module.exports = { example: "join", isPrivileged: false, async execute(interaction) { - await this.join({ interaction: interaction }); + await join({ interaction: interaction }); } -} - -/** - * Join the specified voice channel - * - * @param interaction Message interaction from discord - * @param {string||any} guildID The specified Guild ID if this function is run from the client instead of from an interaction in Discord - * @param {string||any} channelID The channel ID to join - * @param guild The guild object to be used to create a voice adapter - * @param {function} callback The callback that will be needed if this function is run with a Guild ID instead of an interaction - */ -exports.join = async function join({interaction= undefined, guildID= undefined, channelID = undefined, guildObj = undefined, callback = undefined}){ - if (interaction){ - const voiceChannel = interaction.options.getChannel('voicechannel'); - channelID = voiceChannel.id; - guildID = interaction.guildId; - guildObj = interaction.guild; - if (interaction) replyToInteraction(interaction, `Ok, Joining ${voiceChannel.name}`); - } - log.DEBUG("Channel ID: ", channelID) - log.DEBUG("Guild ID: ", guildID) - - const voiceConnection = joinVoiceChannel({ - channelId: channelID, - guildId: guildID, - adapterCreator: guildObj.voiceAdapterCreator, - selfMute: false, - selfDeaf: false, - }); - - const audioInstance = await createAudioInstance(); - - audioInstance.on('audio', (buffer) => { - buffer = Buffer.from(buffer); - log.DEBUG("Audio buffer: ", buffer); - const encoded = encoder.encode(buffer); - // TODO Add a function here to check the volume of either buffer and only play audio to discord when there is audio to be played - voiceConnection.playOpusPacket(encoded); - }) - - // Exit the audio handler when the bot disconnects - voiceConnection.on(VoiceConnectionStatus.Destroyed, () => { - audioInstance.quit(); - }) - - if (guildID && callback) callback(); - else return; } \ No newline at end of file diff --git a/Client/commands/leave.js b/Client/commands/leave.js index 2128949..cf61454 100644 --- a/Client/commands/leave.js +++ b/Client/commands/leave.js @@ -1,9 +1,9 @@ -const {getVoiceConnection} = require("@discordjs/voice"); -const {replyToInteraction} = require("../utilities/messageHandler.js"); -const { SlashCommandBuilder } = require('discord.js'); // Debug const { DebugBuilder } = require("../utilities/debugBuilder.js"); const log = new DebugBuilder("client-bot", "leave"); +// Modules +const { SlashCommandBuilder } = require('discord.js'); +const { leave } = require("../controllers/commandController") module.exports = { data: new SlashCommandBuilder() @@ -12,33 +12,6 @@ module.exports = { example: "leave", isPrivileged: false, async execute(interaction) { - await this.leave({ interaction: interaction }) + await leave({ interaction: interaction }) } } - - -/** - * If in a voice channel for the specified guild, leave - * - * @param interaction Message interaction from discord - * @param guildID - * @param callback - */ -exports.leave = async function leave({interaction = undefined, guildID= undefined, callback = undefined}) { - if(interaction) { - guildID = interaction.guild.id; - } - const voiceConnection = getVoiceConnection(guildID); - - let response; - if (!voiceConnection){ - response = "Not in a voice channel." - if (interaction) return replyToInteraction(interaction, response); - else callback(response); - } - voiceConnection.destroy(); - - response = "Goodbye" - if (interaction) return replyToInteraction(interaction, response); - else callback(response); -} \ No newline at end of file diff --git a/Client/commands/status.js b/Client/commands/status.js index 38f2d7e..f0046fd 100644 --- a/Client/commands/status.js +++ b/Client/commands/status.js @@ -2,7 +2,7 @@ const { DebugBuilder } = require("../utilities/debugBuilder.js"); const log = new DebugBuilder("client-bot", "status"); // Modules -const { status } = require('../controllers/botController'); +const { status } = require('../controllers/commandController'); // Utilities const { SlashCommandBuilder } = require('discord.js'); diff --git a/Client/controllers/botController.js b/Client/controllers/botController.js index d1093fe..4448bfb 100644 --- a/Client/controllers/botController.js +++ b/Client/controllers/botController.js @@ -2,15 +2,7 @@ const { DebugBuilder } = require("../utilities/debugBuilder.js"); const log = new DebugBuilder("client", "clientController"); // Modules -const path = require('path'); -const fork = require('child_process').fork; -const discordBotPath = path.resolve('discord-bot/app.js'); -const {getVoiceConnection} = require("@discordjs/voice"); -const {replyToInteraction} = require("../utilities/messageHandler.js"); -// Commands -const { ping } = require('../commands/ping.js'); -const { join } = require('../commands/join.js'); -const { leave } = require('../commands/leave.js'); +const { status, join, leave } = require("./commandController") /** * Get an object of client guilds @@ -30,7 +22,7 @@ exports.getStatus = (res, req) => { log.DEBUG("Guild IDs: ", guildIds); var guildStatuses = [] for (const guildID of guildIds){ - this.status({guildID: guildID, callback: (statusObj) => { + status({guildID: guildID, callback: (statusObj) => { log.DEBUG("Status Object string: ", statusObj); if (!statusObj.voiceConnection) guildStatuses.push({ guildID : 201 }); else guildStatuses.push({ guildID: 202 }) @@ -60,27 +52,4 @@ exports.leaveServer = (res, req) => { leave({guildID: guildID, callback: (response) => { return res.sendStatus(202); }}); -} - -exports.status = async function status({interaction= undefined, guildID= undefined, callback = undefined}) { - //if (!interaction && !guildID) // Need error of sorts - if (interaction){ - guildID = interaction.guild.id; - } - const voiceConnection = getVoiceConnection(guildID); - - const statusObj = { - "guildID": guildID, "voiceConnection": voiceConnection - } - - //log.DEBUG('Status Object: ', statusObj); - - // get the status and return it accordingly (message reply / module) - - if (interaction) { - return replyToInteraction(interaction, "Pong! I have Aids and now you do too!"); - } - else { - callback(statusObj); - } } \ No newline at end of file diff --git a/Client/controllers/commandController.js b/Client/controllers/commandController.js new file mode 100644 index 0000000..73df9de --- /dev/null +++ b/Client/controllers/commandController.js @@ -0,0 +1,114 @@ +// Debug +const { DebugBuilder } = require("../utilities/debugBuilder.js"); +const log = new DebugBuilder("client-bot", "commandController"); +// Modules +const {getVoiceConnection} = require("@discordjs/voice"); +const {replyToInteraction} = require("../utilities/messageHandler.js"); +const { joinVoiceChannel, VoiceConnectionStatus, getVoiceConnection } = require("@discordjs/voice"); +const {replyToInteraction} = require("../utilities/messageHandler.js"); +const {createAudioInstance} = require("../controllers/audioController.js"); +const { OpusEncoder } = require("@discordjs/opus"); + +// Declare the encoder +const encoder = new OpusEncoder(48000, 2); + +/** + * Join the specified voice channel + * + * @param interaction Message interaction from discord + * @param {string||any} guildID The specified Guild ID if this function is run from the client instead of from an interaction in Discord + * @param {string||any} channelID The channel ID to join + * @param guild The guild object to be used to create a voice adapter + * @param {function} callback The callback that will be needed if this function is run with a Guild ID instead of an interaction + */ +exports.join = async function join({interaction= undefined, guildID= undefined, channelID = undefined, guildObj = undefined, callback = undefined}){ + if (interaction){ + const voiceChannel = interaction.options.getChannel('voicechannel'); + channelID = voiceChannel.id; + guildID = interaction.guildId; + guildObj = interaction.guild; + if (interaction) replyToInteraction(interaction, `Ok, Joining ${voiceChannel.name}`); + } + log.DEBUG("Channel ID: ", channelID) + log.DEBUG("Guild ID: ", guildID) + + const voiceConnection = joinVoiceChannel({ + channelId: channelID, + guildId: guildID, + adapterCreator: guildObj.voiceAdapterCreator, + selfMute: false, + selfDeaf: false, + }); + + const audioInstance = await createAudioInstance(); + + audioInstance.on('audio', (buffer) => { + buffer = Buffer.from(buffer); + log.DEBUG("Audio buffer: ", buffer); + const encoded = encoder.encode(buffer); + // TODO Add a function here to check the volume of either buffer and only play audio to discord when there is audio to be played + voiceConnection.playOpusPacket(encoded); + }) + + // Exit the audio handler when the bot disconnects + voiceConnection.on(VoiceConnectionStatus.Destroyed, () => { + audioInstance.quit(); + }) + + if (guildID && callback) callback(); + else return; +} + +/** + * If in a voice channel for the specified guild, leave + * + * @param interaction Message interaction from discord + * @param guildID + * @param callback + */ +exports.leave = async function leave({interaction = undefined, guildID= undefined, callback = undefined}) { + if(interaction) { + guildID = interaction.guild.id; + } + const voiceConnection = getVoiceConnection(guildID); + + let response; + if (!voiceConnection){ + response = "Not in a voice channel." + if (interaction) return replyToInteraction(interaction, response); + else callback(response); + } + voiceConnection.destroy(); + + response = "Goodbye" + if (interaction) return replyToInteraction(interaction, response); + else callback(response); +} + +/** + * Get the voice status of the bots + * @param {*} param0 + * @returns + */ +exports.status = async function status({interaction= undefined, guildID= undefined, callback = undefined}) { + //if (!interaction && !guildID) // Need error of sorts + if (interaction){ + guildID = interaction.guild.id; + } + const voiceConnection = getVoiceConnection(guildID); + + const statusObj = { + "guildID": guildID, "voiceConnection": voiceConnection + } + + log.DEBUG('Status Object: ', statusObj); + + // get the status and return it accordingly (message reply / module) + + if (interaction) { + return replyToInteraction(interaction, "Pong! I have Aids and now you do too!"); + } + else { + callback(statusObj); + } +} \ No newline at end of file