aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AudioBackend.js38
-rw-r--r--README.md2
-rw-r--r--bot.js5
-rw-r--r--commands/about.js6
-rw-r--r--commands/control.js178
-rw-r--r--commands/help.js4
-rw-r--r--commands/list.js4
-rw-r--r--commands/ping.js4
-rw-r--r--commands/play.js5
9 files changed, 141 insertions, 105 deletions
diff --git a/AudioBackend.js b/AudioBackend.js
index 53acc61..b5d5be6 100644
--- a/AudioBackend.js
+++ b/AudioBackend.js
@@ -29,12 +29,16 @@ import {
import { MessageEmbed } from 'discord.js'
import config from './config.json' assert {type: 'json'}
import { readdirSync, writeFile } from 'node:fs'
+import {controlEmbed} from "./commands/control.js";
export const player = createAudioPlayer();
export let audio;
export let files = readdirSync('music');
let fileData;
+export let playerState;
+let isAudioStatePaused;
+
export async function voiceInit(bot) {
bot.channels.fetch(config.voiceChannel).then(async channel => {
const connection = joinVoiceChannel({
@@ -52,7 +56,7 @@ export async function voiceInit(bot) {
});
player.on('idle', () => {
- console.log("Beat has finished playing, shuffling the beats...")
+ console.log("Beat has finished playing, shuffling the beats...");
searchAudio(bot);
})
@@ -76,14 +80,17 @@ export async function inputAudio(bot, integer) {
export async function playAudio(bot) {
let resource = createAudioResource('music/' + audio);
- await player.play(resource);
+ player.play(resource);
console.log('Now playing: ' + audio);
+ playerState = "Playing"
+ isAudioStatePaused = false
+
audio = audio.split('.').slice(0, -1).join('.');
if (config.txtFile === true) {
- fileData = "Now Playing: " + audio;
+ fileData = "Now Playing: " + audio
writeFile("./now-playing.txt", fileData, (err) => {
if (err)
console.log(err);
@@ -100,7 +107,7 @@ export async function playAudio(bot) {
}
-export function destroyAudio(interaction) {
+export async function destroyAudio(interaction) {
if (config.txtFile === true) {
fileData = "Now Playing: Nothing";
writeFile("now-playing.txt", fileData, (err) => {
@@ -109,10 +116,25 @@ export function destroyAudio(interaction) {
});
}
- audio = "Not Playing";
- player.stop();
+ audio = "Not Playing"
+ playerState = "Stopped"
+ isAudioStatePaused = true
+
const connection = getVoiceConnection(interaction.guild.id);
- return connection.destroy();
+ if (VoiceConnectionStatus.Ready) {
+ player.stop();
+ return connection.destroy();
+ }
+}
+
+export function audioState() {
+ if (isAudioStatePaused === false) {
+ isAudioStatePaused = true
+ playerState = "Paused"
+ } else if (isAudioStatePaused === true) {
+ isAudioStatePaused = false
+ playerState = "Playing"
+ }
}
export async function stopBot(bot, interaction) {
@@ -125,7 +147,7 @@ export async function stopBot(bot, interaction) {
await statusChannel.send({embeds: [statusEmbed]});
console.log('Powering off...');
- destroyAudio(interaction);
+ await destroyAudio(interaction);
bot.destroy();
return process.exit(0);
} \ No newline at end of file
diff --git a/README.md b/README.md
index b999af4..fa06e9d 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Make a new file called `config.json`.
"statusChannel": "channel_id",
"voiceChannel": "voice_channel_id"
"guildID": "guild_id",
- "clientID": "client_id",
+ "clientID": "client_id"
}
```
diff --git a/bot.js b/bot.js
index d14f50c..476138d 100644
--- a/bot.js
+++ b/bot.js
@@ -31,8 +31,9 @@ bot.login(config.token);
/**
* Project Ideas:
* New queue system
- * List MP3 files
* Shuffle or "Play by order" mode
+ * Audio streaming
+ * Attempt to disable buttons (for control command) for regular users
*/
// Slash Command Handler
@@ -93,7 +94,7 @@ bot.on('interactionCreate', async interaction => {
if (error == null) {
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
} else {
- await interaction.reply({ content: `There was an error while executing this command!\nShare this to the bot owner!\n\nDetails:\`\`\`${error}\`\`\``, ephemeral: true });
+ await interaction.reply({ content: `There was an error while executing this command! Share this to the bot owner!\n\nDetails:\`\`\`${error}\`\`\``, ephemeral: true });
}
}
});
diff --git a/commands/about.js b/commands/about.js
index bd54e25..36234a5 100644
--- a/commands/about.js
+++ b/commands/about.js
@@ -30,14 +30,14 @@ export default {
async execute(interaction, bot) {
const aboutEmbed = new MessageEmbed()
.setAuthor({name:`About ${bot.user.username}`, iconURL:bot.user.avatarURL()})
- .addField('Information', 'A Discord bot that plays local MP3 audio tracks.')
- .addField('Version', npmPackage.version)
+ .addField('Information', 'A Discord bot that plays local audio tracks.')
+ .addField('Version', `DLAP ${npmPackage.version}`)
.addField('Original Creator', 'Andrew Lee (Alee#4277)')
//.addField('Contributors', '[your name] (discord#0000)')
//.addField('Forked by', '[your name] (discord#0000)')
.addField('Frameworks', `Discord.JS ${version} + Voice`)
.addField('License', 'GNU General Public License v3.0')
- .setFooter({text:'© Copyright 2020-2022 Andrew Lee. Licensed with GPL-3.0.'})
+ .setFooter({text:'© Copyright 2020-2022 Andrew Lee'})
.setColor('#0066ff')
const srcOrig = new MessageActionRow()
diff --git a/commands/control.js b/commands/control.js
index 83f603f..bac86d0 100644
--- a/commands/control.js
+++ b/commands/control.js
@@ -21,10 +21,11 @@
import { SlashCommandBuilder } from '@discordjs/builders'
import { MessageEmbed, MessageActionRow, MessageButton } from 'discord.js'
-import { audio, player, destroyAudio, voiceInit, stopBot, searchAudio } from '../AudioBackend.js'
+import { audio, player, destroyAudio, voiceInit, stopBot, searchAudio, playerState, audioState } from '../AudioBackend.js'
import config from '../config.json' assert {type: 'json'}
export let controlEmbed
+let runOnce = false
export default {
data: new SlashCommandBuilder()
@@ -32,94 +33,105 @@ export default {
.setDescription('Controlling the music'),
async execute(interaction, bot) {
if (![config.botOwner].includes(interaction.user.id)) return await interaction.reply({ content: "You do not have permissions to execute this command.", ephemeral: true });
- controlEmbed = new MessageEmbed()
- .setAuthor({name: `${bot.user.username} Control Panel`, iconURL: bot.user.avatarURL()})
- .addField('State', 'Playing')
- .addField('Currently Playing', audio)
- //.addField('Next Music', '(a possible feature when queue system is implemented?)')
- .setColor('#0066ff')
+ if (runOnce === false) {
+ controlEmbed = new MessageEmbed()
+ .setAuthor({name: `${bot.user.username} Control Panel`, iconURL: bot.user.avatarURL()})
+ .addField('State', playerState)
+ .addField('Currently Playing', audio)
+ //.addField('Next Music', '(a possible feature when queue system is implemented?)')
+ .setColor('#0066ff')
- const controlButtons = new MessageActionRow()
- .addComponents(
- new MessageButton()
- .setStyle('SUCCESS')
- .setLabel('Join')
- .setCustomId('join'),
- new MessageButton()
- .setStyle('PRIMARY')
- .setLabel('Play')
- .setCustomId('play'),
- new MessageButton()
- .setStyle('PRIMARY')
- .setLabel('Pause')
- .setCustomId('pause'),
- new MessageButton()
- .setStyle('SECONDARY')
- .setLabel('Skip')
- .setCustomId('skip'),
- new MessageButton()
- .setStyle('SECONDARY')
- .setLabel('>>')
- .setCustomId('next'),
- );
+ const controlButtons = new MessageActionRow()
+ .addComponents(
+ new MessageButton()
+ .setStyle('SUCCESS')
+ .setLabel('Join')
+ .setCustomId('join'),
+ new MessageButton()
+ .setStyle('PRIMARY')
+ .setLabel('Play')
+ .setCustomId('play'),
+ new MessageButton()
+ .setStyle('PRIMARY')
+ .setLabel('Pause')
+ .setCustomId('pause'),
+ new MessageButton()
+ .setStyle('SECONDARY')
+ .setLabel('Skip')
+ .setCustomId('skip'),
+ new MessageButton()
+ .setStyle('SECONDARY')
+ .setLabel('>>')
+ .setCustomId('next'),
+ );
- const controlButtons2 = new MessageActionRow()
- .addComponents(
- new MessageButton()
- .setStyle('SECONDARY')
- .setLabel('<<')
- .setCustomId('back'),
- new MessageButton()
- .setStyle('DANGER')
- .setLabel('Leave')
- .setCustomId('leave'),
- new MessageButton()
- .setStyle('DANGER')
- .setLabel('Power Off')
- .setCustomId('stop')
- )
+ const controlButtons2 = new MessageActionRow()
+ .addComponents(
+ new MessageButton()
+ .setStyle('SECONDARY')
+ .setLabel('<<')
+ .setCustomId('back'),
+ new MessageButton()
+ .setStyle('DANGER')
+ .setLabel('Leave')
+ .setCustomId('leave'),
+ new MessageButton()
+ .setStyle('DANGER')
+ .setLabel('Power Off')
+ .setCustomId('stop')
+ )
- const filter = i => i.user.id === config.botOwner;
+ const filter = i => i.user.id === config.botOwner;
- const collector = interaction.channel.createMessageComponentCollector({filter});
+ const collector = interaction.channel.createMessageComponentCollector({filter});
- collector.on('collect', async ctlButton => {
- if (ctlButton.customId === 'join') {
- await ctlButton.reply({content:'Joining voice channel', ephemeral:true})
- return await voiceInit(bot);
- }
- if (ctlButton.customId === 'play') {
- await ctlButton.reply({content:'Resuming music', ephemeral:true})
- return player.unpause();
- }
- if (ctlButton.customId === 'pause') {
- await ctlButton.reply({content:'Pausing music', ephemeral:true})
- return player.pause();
- }
- if (ctlButton.customId === 'skip') {
- await ctlButton.reply({content:`Skipping \`${audio}\`...`, ephemeral:true})
- player.stop();
- return await searchAudio(bot);
- }
- if (ctlButton.customId === 'next') {
- return await interaction.editReply({ components: [controlButtons2] });
- }
- if (ctlButton.customId === 'back') {
- return await interaction.editReply({ components: [controlButtons] });
- }
- if (ctlButton.customId === 'leave') {
- await ctlButton.reply({content:'Leaving voice channel.', ephemeral:true})
- console.log('Leaving voice channel...');
- return destroyAudio(interaction);
- }
- if (ctlButton.customId === 'stop') {
- await ctlButton.reply({content:'Powering off...', ephemeral:true})
- return await stopBot(bot, interaction);
- }
- });
+ collector.on('collect', async ctlButton => {
+ if (ctlButton.customId === 'join') {
+ await ctlButton.reply({content:'Joining voice channel', ephemeral:true});
+ return await voiceInit(bot);
+ }
+ if (ctlButton.customId === 'play') {
+ await ctlButton.reply({content:'Resuming music', ephemeral:true});
+ audioState();
+ return player.unpause();
+ }
+ if (ctlButton.customId === 'pause') {
+ await ctlButton.reply({content:'Pausing music', ephemeral:true});
+ audioState();
+ return player.pause();
+ }
+ if (ctlButton.customId === 'skip') {
+ await ctlButton.reply({content:`Skipping ${audio}`, ephemeral:true});
+ player.stop();
+ return await searchAudio(bot, interaction);
+ }
+ if (ctlButton.customId === 'next') {
+ return await interaction.editReply({ components: [controlButtons2] }).then(ctlButton.deferUpdate());
+ }
+ if (ctlButton.customId === 'back') {
+ return await interaction.editReply({ components: [controlButtons] }).then(ctlButton.deferUpdate());
+ }
+ if (ctlButton.customId === 'leave') {
+ await ctlButton.reply({content:'Leaving voice channel', ephemeral:true});
+ console.log('Leaving voice channel...');
+ runOnce = false
+ await interaction.deleteReply();
+ return await destroyAudio(interaction);
+ }
+ if (ctlButton.customId === 'stop') {
+ await ctlButton.reply({content:`Powering off ${bot.user.username}...`, ephemeral:true});
+ runOnce = false
+ await interaction.deleteReply();
+ return await stopBot(bot, interaction);
+ }
+ });
- collector.on('end', collected => console.log(`Collected ${collected.size} items`));
+ collector.on('end', collected => console.log(`Collected ${collected.size} items`));
- return await interaction.reply({embeds:[controlEmbed], components:[controlButtons]});
+ runOnce = true
+ return await interaction.reply({embeds:[controlEmbed], components:[controlButtons]});
+ } else {
+ return await interaction.reply({content:'You already executed this command', ephemeral:true})
+ }
},
}; \ No newline at end of file
diff --git a/commands/help.js b/commands/help.js
index 291f5fe..11d9d60 100644
--- a/commands/help.js
+++ b/commands/help.js
@@ -20,7 +20,7 @@
***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders'
-import { MessageEmbed } from 'discord.js';
+import { MessageEmbed } from 'discord.js'
import { audio } from '../AudioBackend.js'
export default {
@@ -33,7 +33,7 @@ export default {
.setDescription(`Currently playing \`${audio}\``)
.addField('Public Commands', `/help\n/ping\n/about\n`, true)
.addField('Bot Owner Only', `/join\n/control\n/stop\n`, true)
- .setFooter({text:'© Copyright 2020-2022 Andrew Lee. Licensed with GPL-3.0.'})
+ .setFooter({text:'© Copyright 2020-2022 Andrew Lee'})
.setColor('#0066ff')
return await interaction.reply({ embeds: [helpEmbed]});
diff --git a/commands/list.js b/commands/list.js
index 247e060..2d7c5aa 100644
--- a/commands/list.js
+++ b/commands/list.js
@@ -29,7 +29,9 @@ export default {
.setName('list')
.setDescription('Lists the available audio tracks'),
async execute(interaction) {
+ //If someone figures out how to either split the list or make pages when the max character reaches, please do so and make a pull request.
+
const beats = readdirSync(musicFolder).join('\n');
- await interaction.reply(`Listing the available audio tracks...\`\`\`${beats}\`\`\``);
+ await interaction.reply(`Listing the available audio tracks...\n\`\`\`\n${beats}\n\`\`\``);
},
}; \ No newline at end of file
diff --git a/commands/ping.js b/commands/ping.js
index fc25135..3a77d08 100644
--- a/commands/ping.js
+++ b/commands/ping.js
@@ -25,7 +25,7 @@ export default {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Pong!'),
- async execute(interaction) {
- return await interaction.reply('Pong!');
+ async execute(interaction, bot) {
+ return await interaction.reply(`Pong! ${Math.round(bot.ws.ping)}ms`);
},
}; \ No newline at end of file
diff --git a/commands/play.js b/commands/play.js
index f53ac21..cc88bb3 100644
--- a/commands/play.js
+++ b/commands/play.js
@@ -31,13 +31,12 @@ export default {
.setDescription('Plays the audio by number')
.addIntegerOption(option =>
option.setName('int')
- .setDescription('Input a number for the selection for the audio file.')
- .setRequired(false),
+ .setDescription('Input a number for the selection for the audio file.'),
),
async execute(interaction, bot) {
if (![config.botOwner].includes(interaction.user.id)) return await interaction.reply({ content: "You do not have permissions to execute this command.", ephemeral: true });
integer = interaction.options.getInteger('int');
await inputAudio(bot, integer);
- return await interaction.reply({ content: `Now playing: ${audio}`, ephemeral: true});
+ return await interaction.reply({ content: `Now playing: ${audio}`, ephemeral: true });
},
}; \ No newline at end of file