From c55e480e4d8dbf9d3c11cb7a13c69f9f1ab730db Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sun, 18 Dec 2022 22:31:04 -0500 Subject: Improved list command; Directory name change; Fixed ActivityType --- AudioBackend/AudioControl.js | 92 ++++++++++++++++++++++++++ AudioBackend/PlayAudio.js | 124 ++++++++++++++++++++++++++++++++++++ AudioBackend/QueueSystem.js | 50 +++++++++++++++ AudioBackend/Shutdown.js | 60 +++++++++++++++++ AudioBackend/VoiceInitialization.js | 61 ++++++++++++++++++ Commands/about.js | 56 ++++++++++++++++ Commands/join.js | 36 +++++++++++ Commands/leave.js | 37 +++++++++++ Commands/list.js | 63 ++++++++++++++++++ Commands/next.js | 42 ++++++++++++ Commands/pause.js | 40 ++++++++++++ Commands/ping.js | 31 +++++++++ Commands/play.js | 58 +++++++++++++++++ Commands/previous.js | 39 ++++++++++++ Commands/reshuffle.js | 44 +++++++++++++ Commands/shutdown.js | 35 ++++++++++ Commands/status.js | 76 ++++++++++++++++++++++ README.md | 5 +- backend/AudioControl.js | 92 -------------------------- backend/PlayAudio.js | 124 ------------------------------------ backend/QueueSystem.js | 50 --------------- backend/Shutdown.js | 60 ----------------- backend/VoiceInitialization.js | 61 ------------------ bot.js | 10 +-- commands/about.js | 56 ---------------- commands/join.js | 36 ----------- commands/leave.js | 37 ----------- commands/list.js | 42 ------------ commands/next.js | 42 ------------ commands/pause.js | 40 ------------ commands/ping.js | 31 --------- commands/play.js | 58 ----------------- commands/previous.js | 39 ------------ commands/reshuffle.js | 44 ------------- commands/shutdown.js | 35 ---------- commands/status.js | 75 ---------------------- deploy-command.js | 4 +- package.json | 2 +- yarn.lock | 12 ++-- 39 files changed, 962 insertions(+), 937 deletions(-) create mode 100644 AudioBackend/AudioControl.js create mode 100644 AudioBackend/PlayAudio.js create mode 100644 AudioBackend/QueueSystem.js create mode 100644 AudioBackend/Shutdown.js create mode 100644 AudioBackend/VoiceInitialization.js create mode 100644 Commands/about.js create mode 100644 Commands/join.js create mode 100644 Commands/leave.js create mode 100644 Commands/list.js create mode 100644 Commands/next.js create mode 100644 Commands/pause.js create mode 100644 Commands/ping.js create mode 100644 Commands/play.js create mode 100644 Commands/previous.js create mode 100644 Commands/reshuffle.js create mode 100644 Commands/shutdown.js create mode 100644 Commands/status.js delete mode 100644 backend/AudioControl.js delete mode 100644 backend/PlayAudio.js delete mode 100644 backend/QueueSystem.js delete mode 100644 backend/Shutdown.js delete mode 100644 backend/VoiceInitialization.js delete mode 100644 commands/about.js delete mode 100644 commands/join.js delete mode 100644 commands/leave.js delete mode 100644 commands/list.js delete mode 100644 commands/next.js delete mode 100644 commands/pause.js delete mode 100644 commands/ping.js delete mode 100644 commands/play.js delete mode 100644 commands/previous.js delete mode 100644 commands/reshuffle.js delete mode 100644 commands/shutdown.js delete mode 100644 commands/status.js diff --git a/AudioBackend/AudioControl.js b/AudioBackend/AudioControl.js new file mode 100644 index 0000000..447e040 --- /dev/null +++ b/AudioBackend/AudioControl.js @@ -0,0 +1,92 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { readdirSync, readFileSync } from 'node:fs'; +import { shufflePlaylist, orderPlaylist } from './QueueSystem.js'; +import { playAudio, currentTrack, updatePlaylist } from './PlayAudio.js'; +import { player } from './VoiceInitialization.js'; + +const { shuffle, repeat } = JSON.parse(readFileSync('./config.json', 'utf-8')); +export const files = readdirSync('music'); +export let playerState; +export let isAudioStatePaused; + +let totalTrack = files.length; + +async function repeatCheck(bot) { + if (repeat) { + console.log('All beats in the playlist has finished, repeating beats...'); + totalTrack = files.length; + return (shuffle) ? await shufflePlaylist(bot) : await orderPlaylist(bot); + } else { + console.log('All beats in the playlist has finished.'); + updatePlaylist('stop'); + audioState(2); + } +} + +export async function nextAudio(bot) { + if (currentTrack >= totalTrack - 1) { + await repeatCheck(bot); + } else { + updatePlaylist('next'); + return await playAudio(bot); + } +} + +export async function previousAudio(bot, interaction) { + if (currentTrack <= 0) { + return await interaction.reply({ content: 'You are at the beginning of the playlist, cannot go further than this', ephemeral: true }); + } else { + await interaction.reply({ content: 'Playing previous music', ephemeral: true }); + player.stop(); + updatePlaylist('back'); + return await playAudio(bot); + } +} + +export function toggleAudioState() { + if (isAudioStatePaused) { + audioState(0); + } else { + audioState(1); + } +} + +export function audioState(state) { + switch (state) { + case 0: + playerState = 'Playing'; + isAudioStatePaused = false; + player.unpause(); + break; + case 1: + playerState = 'Paused'; + isAudioStatePaused = true; + player.pause(); + break; + case 2: + playerState = 'Stopped'; + totalTrack = files.length; + isAudioStatePaused = true; + player.stop(); + break; + } +} diff --git a/AudioBackend/PlayAudio.js b/AudioBackend/PlayAudio.js new file mode 100644 index 0000000..5d18534 --- /dev/null +++ b/AudioBackend/PlayAudio.js @@ -0,0 +1,124 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { createAudioResource } from '@discordjs/voice'; +import { parseFile } from 'music-metadata'; +import { readdirSync, readFileSync, writeFile } from 'node:fs'; +import { EmbedBuilder } from 'discord.js'; +import { player } from './VoiceInitialization.js'; +import { audioState, files } from './AudioControl.js'; +import { integer } from '../Commands/play.js'; +const { statusChannel, txtFile } = JSON.parse(readFileSync('./config.json', 'utf-8')); + +let fileData; + +export let audio; +export let currentTrack; + +export let metadataEmpty; + +export let audioTitle; +export let audioArtist; +export let audioYear; +export let audioAlbum; +export let duration; + +const inputFiles = readdirSync('music'); +export async function playAudio(bot) { + const resource = createAudioResource('music/' + audio); + player.play(resource); + + console.log('Now playing: ' + audio); + + audioState(0); + + const audioFile = audio; + + try { + const { common, format } = await parseFile('music/' + audio); + metadataEmpty = false; + if (common.title && common.artist && common.year && common.album) { + audioTitle = common.title; + audioArtist = common.artist; + audioYear = common.year; + audioAlbum = common.album; + } else { + metadataEmpty = true; + } + duration = new Date(format.duration * 1000).toISOString().slice(11, 19); + } catch (e) { + console.error(e); + } + + audio = audio.split('.').slice(0, -1).join('.'); + + if (txtFile) { + fileData = 'Now Playing: ' + audio; + writeFile('./now-playing.txt', fileData, (err) => { + if (err) { console.log(err); } + }); + } + + const statusEmbed = new EmbedBuilder(); + if (metadataEmpty) { + statusEmbed.setTitle('Now Playing'); + statusEmbed.addFields( + { name: 'Title', value: audio }, + { name: 'Duration', value: duration } + ); + statusEmbed.setColor('#0066ff'); + } else { + statusEmbed.setTitle('Now Playing'); + statusEmbed.addFields( + { name: 'Title', value: audioTitle, inline: true }, + { name: 'Artist', value: audioArtist, inline: true }, + { name: 'Year', value: `${audioYear}` }, + { name: 'Duration', value: duration } + ); + statusEmbed.setFooter({ text: `Album: ${audioAlbum}\nFilename: ${audioFile}` }); + statusEmbed.setColor('#0066ff'); + } + const channel = bot.channels.cache.get(statusChannel); + if (!channel) return console.error('The status channel does not exist! Skipping.'); + return await channel.send({ embeds: [statusEmbed] }); +} + +export function updatePlaylist(option) { + switch (option) { + case 'next': + currentTrack++; + audio = files[currentTrack]; + break; + case 'back': + currentTrack--; + audio = files[currentTrack]; + break; + case 'reset': + currentTrack = 0; + audio = files[currentTrack]; + break; + case 'input': + audio = inputFiles[integer]; + break; + case 'stop': + audio = 'Not Playing'; + break; + } +} diff --git a/AudioBackend/QueueSystem.js b/AudioBackend/QueueSystem.js new file mode 100644 index 0000000..0cd6ded --- /dev/null +++ b/AudioBackend/QueueSystem.js @@ -0,0 +1,50 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { playAudio, updatePlaylist } from './PlayAudio.js'; +import { files } from './AudioControl.js'; + +function shuffleArray(array) { + // Durstenfeld Shuffle + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } +} +export async function orderPlaylist(bot) { + console.log('Playing beats by order...'); + updatePlaylist('reset'); + console.log(files); + return await playAudio(bot); +} + +export async function shufflePlaylist(bot) { + console.log('Shuffling beats...'); + shuffleArray(files); + console.log('Playing beats by shuffle...'); + updatePlaylist('reset'); + console.log(files); + return await playAudio(bot); +} + +export async function inputAudio(bot) { + updatePlaylist('input'); + return await playAudio(bot); +} diff --git a/AudioBackend/Shutdown.js b/AudioBackend/Shutdown.js new file mode 100644 index 0000000..fb89505 --- /dev/null +++ b/AudioBackend/Shutdown.js @@ -0,0 +1,60 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { EmbedBuilder } from 'discord.js'; +import { player } from './VoiceInitialization.js'; +import { updatePlaylist } from './PlayAudio.js'; +import { audioState } from './AudioControl.js'; +import { readFileSync, writeFile } from 'node:fs'; +import { getVoiceConnection, VoiceConnectionStatus } from '@discordjs/voice'; +const { statusChannel, txtFile } = JSON.parse(readFileSync('./config.json', 'utf-8')); +let fileData; + +export async function destroyAudio(interaction) { + if (txtFile) { + fileData = 'Now Playing: Nothing'; + writeFile('now-playing.txt', fileData, (err) => { + if (err) { console.log(err); } + }); + } + + updatePlaylist('stop'); + audioState(2); + + const connection = getVoiceConnection(interaction.guild.id); + if (VoiceConnectionStatus.Ready) { + player.stop(); + return connection.destroy(); + } +} +export async function stopBot(bot, interaction) { + const statusEmbed = new EmbedBuilder() + .setAuthor({ name: bot.user.username, iconURL: bot.user.avatarURL() }) + .setDescription(`That's all folks! Powering down ${bot.user.username}...`) + .setColor('#0066ff'); + const channel = bot.channels.cache.get(statusChannel); + if (!channel) return console.error('The status channel does not exist! Skipping.'); + await channel.send({ embeds: [statusEmbed] }); + + console.log(`Powering off ${bot.user.username}...`); + await destroyAudio(interaction); + await bot.destroy(); + return process.exit(0); +} diff --git a/AudioBackend/VoiceInitialization.js b/AudioBackend/VoiceInitialization.js new file mode 100644 index 0000000..a9e1149 --- /dev/null +++ b/AudioBackend/VoiceInitialization.js @@ -0,0 +1,61 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { readFileSync } from 'node:fs'; +import { createAudioPlayer, joinVoiceChannel, VoiceConnectionStatus } from '@discordjs/voice'; +import { nextAudio } from './AudioControl.js'; +import { shufflePlaylist, orderPlaylist } from './QueueSystem.js'; + +const { voiceChannel, shuffle } = JSON.parse(readFileSync('./config.json', 'utf-8')); +export const player = createAudioPlayer(); +export async function voiceInit(bot) { + bot.channels.fetch(voiceChannel).then(async channel => { + const connection = joinVoiceChannel({ + channelId: channel.id, + guildId: channel.guild.id, + adapterCreator: channel.guild.voiceAdapterCreator + }); + + connection.on(VoiceConnectionStatus.Connecting, () => { + console.log(`Connecting to ${channel.name}...`); + }); + + connection.on(VoiceConnectionStatus.Ready, async() => { + console.log('Ready to blast some beats!'); + return (shuffle) ? await shufflePlaylist(bot) : await orderPlaylist(bot); + }); + + connection.on(VoiceConnectionStatus.Destroyed, () => { + console.log('Destroyed the beats...'); + }); + + player.on('error', error => { + console.error(error); + nextAudio(bot); + }); + + player.on('idle', () => { + console.log('Beat has finished playing, now playing next beat...'); + nextAudio(bot); + }); + + return connection.subscribe(player); + }).catch(e => { console.error(e); }); +} diff --git a/Commands/about.js b/Commands/about.js new file mode 100644 index 0000000..23c750e --- /dev/null +++ b/Commands/about.js @@ -0,0 +1,56 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { EmbedBuilder, version, ActionRowBuilder, ButtonBuilder, ButtonStyle, SlashCommandBuilder } from 'discord.js'; +// import npmPackage from '../package.json' assert { type:'json' } +import { readFileSync } from 'node:fs'; +const npmPackage = JSON.parse(readFileSync('./package.json', 'utf-8')); + +export default { + data: new SlashCommandBuilder() + .setName('about') + .setDescription('Information about the bot'), + async execute(interaction, bot) { + const aboutEmbed = new EmbedBuilder() + .setAuthor({ name: `About ${bot.user.username}`, iconURL: bot.user.avatarURL() }) + .addFields( + { name: 'Information', value: 'A Discord bot that plays local audio tracks.' }, + { name: 'Version', value: `DLAP ${npmPackage.version}` }, + { name: 'Original Creator', value: 'Andrew Lee (Alee#4277)' }, // Do not remove this since I created this :) + // { name: 'Contributors', value: '[your name] (discord#0000)' }, + // { name: 'Forked by', value: '[your name] (discord#0000)' }, + { name: 'Frameworks', value: `Discord.JS ${version} + Voice` }, + { name: 'License', value: 'GNU General Public License v3.0' } + ) + .setFooter({ text: '© Copyright 2020-2022 Andrew Lee' }) + .setColor('#0066ff'); + + const srcOrig = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setStyle(ButtonStyle.Link) + .setLabel('Original Source Code') + .setURL('https://github.com/Alee14/DLAP') + ); + + return await interaction.reply({ embeds: [aboutEmbed], components: [srcOrig] }); + } +}; diff --git a/Commands/join.js b/Commands/join.js new file mode 100644 index 0000000..739ebba --- /dev/null +++ b/Commands/join.js @@ -0,0 +1,36 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { voiceInit } from '../AudioBackend/VoiceInitialization.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('join') + .setDescription('Joins voice chat') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + await interaction.reply({ content: 'Joining voice channel', ephemeral: true }); + return await voiceInit(bot); + } +}; diff --git a/Commands/leave.js b/Commands/leave.js new file mode 100644 index 0000000..cea791a --- /dev/null +++ b/Commands/leave.js @@ -0,0 +1,37 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { destroyAudio } from '../AudioBackend/Shutdown.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('leave') + .setDescription('Leaves the voice chat') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + console.log('Leaving voice channel...'); + await destroyAudio(interaction); + return await interaction.reply({ content: 'Leaving voice channel', ephemeral: true }); + } +}; diff --git a/Commands/list.js b/Commands/list.js new file mode 100644 index 0000000..176ae61 --- /dev/null +++ b/Commands/list.js @@ -0,0 +1,63 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { readdir } from 'node:fs'; + +const musicFolder = './music'; + +export default { + data: new SlashCommandBuilder() + .setName('list') + .setDescription('Lists the available audio tracks') + .addIntegerOption(option => + option.setName('page') + .setDescription('Input a number to change the page of the list') + ), + async execute(interaction, bot) { + const page = interaction.options.getInteger('page') || 1; // If no page is specified, default to page 1 + readdir(musicFolder, async(err, files) => { + if (err) { + console.error(err); + } else { + const trackList = files.map((file, i) => `${i}: ${file}`); // Create an array of track names + const pageSize = 10; // Number of tracks per page + const numPages = Math.ceil(trackList.length / pageSize); // Total number of pages + if (page < 1 || page > numPages) { // Check if the page number is valid + return await interaction.reply({ content: `Invalid page number. Please specify a number between 1 and ${numPages}.`, ephemeral: true }); + } + // Split the track list into pages + const pages = []; + for (let i = 0; i < numPages; i++) { + const start = i * pageSize; + const end = start + pageSize; + pages.push(trackList.slice(start, end)); + } + // Send the specified page with the page number and total number of pages + const listEmbed = new EmbedBuilder(); + listEmbed.setAuthor({ name: `${bot.user.username} List`, iconURL: bot.user.avatarURL() }); + listEmbed.addFields({ name: `Listing ${trackList.length} audio tracks...`, value: `\`\`\`\n${pages[page - 1].join('\n')}\n\`\`\`` }); + listEmbed.setFooter({ text: `Page ${page}/${numPages}` }); + listEmbed.setColor('#0066ff'); + await interaction.reply({ embeds: [listEmbed] }); + } + }); + } +}; diff --git a/Commands/next.js b/Commands/next.js new file mode 100644 index 0000000..d3240cf --- /dev/null +++ b/Commands/next.js @@ -0,0 +1,42 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { player } from '../AudioBackend/VoiceInitialization.js'; +import { nextAudio, playerState } from '../AudioBackend/AudioControl.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('next') + .setDescription('Goes to next music') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + if (playerState === 'Playing' || playerState === 'Paused') { + await interaction.reply({ content: 'Playing next music', ephemeral: true }); + player.stop(); + return await nextAudio(bot); + } else if (playerState === 'Stopped') { + return await interaction.reply({ content: 'Cannot play next music. Player is currently stopped...', ephemeral: true }); + } + } +}; diff --git a/Commands/pause.js b/Commands/pause.js new file mode 100644 index 0000000..e461a4c --- /dev/null +++ b/Commands/pause.js @@ -0,0 +1,40 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { toggleAudioState, isAudioStatePaused } from '../AudioBackend/AudioControl.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('pause') + .setDescription('Pauses music') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + if (!isAudioStatePaused) { + toggleAudioState(); + return await interaction.reply({ content: 'Pausing music', ephemeral: true }); + } else { + return await interaction.reply({ content: 'Music is already paused', ephemeral: true }); + } + } +}; diff --git a/Commands/ping.js b/Commands/ping.js new file mode 100644 index 0000000..72ef024 --- /dev/null +++ b/Commands/ping.js @@ -0,0 +1,31 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; + +export default { + data: new SlashCommandBuilder() + .setName('ping') + .setDescription('Pong!'), + async execute(interaction, bot) { + return await interaction.reply(`Pong! ${Math.round(bot.ws.ping)}ms`); + } +}; diff --git a/Commands/play.js b/Commands/play.js new file mode 100644 index 0000000..a0af3f3 --- /dev/null +++ b/Commands/play.js @@ -0,0 +1,58 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { inputAudio } from '../AudioBackend/QueueSystem.js'; +import { files, isAudioStatePaused, toggleAudioState } from '../AudioBackend/AudioControl.js'; +import { audio } from '../AudioBackend/PlayAudio.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export let integer; + +export default { + data: new SlashCommandBuilder() + .setName('play') + .setDescription('Resumes music') + .addIntegerOption(option => + option.setName('int') + .setDescription('Input a number for the selection for the audio file.') + ) + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + integer = interaction.options.getInteger('int'); + if (integer) { + if (integer < files.length) { + await inputAudio(bot, integer); + return await interaction.reply({ content: `Now playing: ${audio}`, ephemeral: true }); + } else { + return await interaction.reply({ content: 'Number is too big, choose a number that\'s less than ' + files.length + '.', ephemeral: true }); + } + } + if (isAudioStatePaused) { + toggleAudioState(); + return await interaction.reply({ content: 'Resuming music', ephemeral: true }); + } else { + return await interaction.reply({ content: 'Music is already playing', ephemeral: true }); + } + } +}; diff --git a/Commands/previous.js b/Commands/previous.js new file mode 100644 index 0000000..dd79a98 --- /dev/null +++ b/Commands/previous.js @@ -0,0 +1,39 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { playerState, previousAudio } from '../AudioBackend/AudioControl.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('previous') + .setDescription('Goes to previous music') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + if (playerState === 'Playing' || playerState === 'Paused') { + return await previousAudio(bot, interaction); + } else if (playerState === 'Stopped') { + return await interaction.reply({ content: 'Cannot play next music. Player is currently stopped...', ephemeral: true }); + } + } +}; diff --git a/Commands/reshuffle.js b/Commands/reshuffle.js new file mode 100644 index 0000000..f3e70c2 --- /dev/null +++ b/Commands/reshuffle.js @@ -0,0 +1,44 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { shufflePlaylist } from '../AudioBackend/QueueSystem.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; +import { readFileSync } from 'node:fs'; +import { audioState } from '../AudioBackend/AudioControl.js'; +// import config from './config.json' assert {type: 'json'} +const { shuffle } = JSON.parse(readFileSync('./config.json', 'utf-8')); + +export default { + data: new SlashCommandBuilder() + .setName('reshuffle') + .setDescription('Reshuffles the playlist') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + async function shuffleDetected(bot) { + await interaction.reply({ content: 'Reshuffling the playlist...', ephemeral: true }); + await audioState(2); + await shufflePlaylist(bot); + } + return (shuffle) ? await shuffleDetected(bot) : await interaction.reply({ content: 'Shuffle mode is disabled, enable it in the configuration file to access this command.', ephemeral: true }); + } +}; diff --git a/Commands/shutdown.js b/Commands/shutdown.js new file mode 100644 index 0000000..d97922c --- /dev/null +++ b/Commands/shutdown.js @@ -0,0 +1,35 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { SlashCommandBuilder } from 'discord.js'; +import { stopBot } from '../AudioBackend/Shutdown.js'; +import { PermissionFlagsBits } from 'discord-api-types/v10'; + +export default { + data: new SlashCommandBuilder() + .setName('shutdown') + .setDescription('Powers off the bot') + .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + async execute(interaction, bot) { + await interaction.reply({ content: 'Powering off...', ephemeral: true }); + return await stopBot(bot, interaction); + } +}; diff --git a/Commands/status.js b/Commands/status.js new file mode 100644 index 0000000..fc1229d --- /dev/null +++ b/Commands/status.js @@ -0,0 +1,76 @@ +/************************************************************************** + * + * DLAP Bot: A Discord bot that plays local audio tracks. + * (C) Copyright 2022 + * Programmed by Andrew Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + ***************************************************************************/ + +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { parseFile } from 'music-metadata'; +import { audio, metadataEmpty, duration, audioTitle, currentTrack } from '../AudioBackend/PlayAudio.js'; +import { files, playerState } from '../AudioBackend/AudioControl.js'; + +export default { + data: new SlashCommandBuilder() + .setName('status') + .setDescription('Checks what audio file is playing currently'), + async execute(interaction, bot) { + if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); + let audioID = currentTrack; + audioID++; + + let audioName = files[audioID]; + + if (audioName === undefined) { + audioName = 'Playlist Finished'; + } else { + if (!metadataEmpty) { + try { + const { common } = await parseFile('music/' + audioName); + audioName = common.title; + } catch (error) { + console.error(error.message); + } + } else { + audioName = audioName.split('.').slice(0, -1).join('.'); + } + } + + const controlEmbed = new EmbedBuilder() + .setAuthor({ name: `${bot.user.username} Status`, iconURL: bot.user.avatarURL() }) + .addFields( + { name: 'State', value: playerState }, + { name: 'Tracks', value: `${audioID}/${files.length}` }, + { name: 'Duration', value: duration } + // { name: 'Session Uptime', value: `` } + ) + .setColor('#0066ff'); + + if (metadataEmpty) { + controlEmbed.addFields( + { name: 'Currently Playing', value: audio }, + { name: 'Up Next', value: audioName } + ); + } else { + controlEmbed.addFields( + { name: 'Currently Playing', value: audioTitle }, + { name: 'Up Next', value: audioName } + ); + } + interaction.reply({ embeds: [controlEmbed] }); + } +}; diff --git a/README.md b/README.md index d4356f5..bb11674 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Make a new file called `config.json`. "statusChannel": "channel_id", "voiceChannel": "voice_channel_id", "presenceActivity": "activity_here", + "activityType": [0 (Playing)/1 (Streaming)/2 (Listening)/3 (Watching)/4 (Custom)/5 (Competing)], "clientID": "client_id" } ``` @@ -41,6 +42,8 @@ Public Only ping - Pong! status - Checks what audio file is playing currently. about - Information about the bot. +list - Lists the available audio tracks. +list (page) - Input a number to change the page of the list. Bot Owner Only -------------- @@ -50,7 +53,7 @@ play (int) - Input a number for the selection for the audio file. pause - Pauses music. next - Goes to next music. previous - Goes to previous music. -reshuffle - Reshuffles the playlist +reshuffle - Reshuffles the playlist. leave - Leaves voice chat. shutdown - Powers off the bot. ``` diff --git a/backend/AudioControl.js b/backend/AudioControl.js deleted file mode 100644 index 447e040..0000000 --- a/backend/AudioControl.js +++ /dev/null @@ -1,92 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ -import { readdirSync, readFileSync } from 'node:fs'; -import { shufflePlaylist, orderPlaylist } from './QueueSystem.js'; -import { playAudio, currentTrack, updatePlaylist } from './PlayAudio.js'; -import { player } from './VoiceInitialization.js'; - -const { shuffle, repeat } = JSON.parse(readFileSync('./config.json', 'utf-8')); -export const files = readdirSync('music'); -export let playerState; -export let isAudioStatePaused; - -let totalTrack = files.length; - -async function repeatCheck(bot) { - if (repeat) { - console.log('All beats in the playlist has finished, repeating beats...'); - totalTrack = files.length; - return (shuffle) ? await shufflePlaylist(bot) : await orderPlaylist(bot); - } else { - console.log('All beats in the playlist has finished.'); - updatePlaylist('stop'); - audioState(2); - } -} - -export async function nextAudio(bot) { - if (currentTrack >= totalTrack - 1) { - await repeatCheck(bot); - } else { - updatePlaylist('next'); - return await playAudio(bot); - } -} - -export async function previousAudio(bot, interaction) { - if (currentTrack <= 0) { - return await interaction.reply({ content: 'You are at the beginning of the playlist, cannot go further than this', ephemeral: true }); - } else { - await interaction.reply({ content: 'Playing previous music', ephemeral: true }); - player.stop(); - updatePlaylist('back'); - return await playAudio(bot); - } -} - -export function toggleAudioState() { - if (isAudioStatePaused) { - audioState(0); - } else { - audioState(1); - } -} - -export function audioState(state) { - switch (state) { - case 0: - playerState = 'Playing'; - isAudioStatePaused = false; - player.unpause(); - break; - case 1: - playerState = 'Paused'; - isAudioStatePaused = true; - player.pause(); - break; - case 2: - playerState = 'Stopped'; - totalTrack = files.length; - isAudioStatePaused = true; - player.stop(); - break; - } -} diff --git a/backend/PlayAudio.js b/backend/PlayAudio.js deleted file mode 100644 index fea4b3d..0000000 --- a/backend/PlayAudio.js +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ -import { createAudioResource } from '@discordjs/voice'; -import { parseFile } from 'music-metadata'; -import { readdirSync, readFileSync, writeFile } from 'node:fs'; -import { EmbedBuilder } from 'discord.js'; -import { player } from './VoiceInitialization.js'; -import { audioState, files } from './AudioControl.js'; -import { integer } from '../commands/play.js'; -const { statusChannel, txtFile } = JSON.parse(readFileSync('./config.json', 'utf-8')); - -let fileData; - -export let audio; -export let currentTrack; - -export let metadataEmpty; - -export let audioTitle; -export let audioArtist; -export let audioYear; -export let audioAlbum; -export let duration; - -const inputFiles = readdirSync('music'); -export async function playAudio(bot) { - const resource = createAudioResource('music/' + audio); - player.play(resource); - - console.log('Now playing: ' + audio); - - audioState(0); - - const audioFile = audio; - - try { - const { common, format } = await parseFile('music/' + audio); - metadataEmpty = false; - if (common.title && common.artist && common.year && common.album) { - audioTitle = common.title; - audioArtist = common.artist; - audioYear = common.year; - audioAlbum = common.album; - } else { - metadataEmpty = true; - } - duration = new Date(format.duration * 1000).toISOString().slice(11, 19); - } catch (e) { - console.error(e); - } - - audio = audio.split('.').slice(0, -1).join('.'); - - if (txtFile) { - fileData = 'Now Playing: ' + audio; - writeFile('./now-playing.txt', fileData, (err) => { - if (err) { console.log(err); } - }); - } - - const statusEmbed = new EmbedBuilder(); - if (metadataEmpty) { - statusEmbed.setTitle('Now Playing'); - statusEmbed.addFields( - { name: 'Title', value: audio }, - { name: 'Duration', value: duration } - ); - statusEmbed.setColor('#0066ff'); - } else { - statusEmbed.setTitle('Now Playing'); - statusEmbed.addFields( - { name: 'Title', value: audioTitle, inline: true }, - { name: 'Artist', value: audioArtist, inline: true }, - { name: 'Year', value: `${audioYear}` }, - { name: 'Duration', value: duration } - ); - statusEmbed.setFooter({ text: `Album: ${audioAlbum}\nFilename: ${audioFile}` }); - statusEmbed.setColor('#0066ff'); - } - const channel = bot.channels.cache.get(statusChannel); - if (!channel) return console.error('The status channel does not exist! Skipping.'); - return await channel.send({ embeds: [statusEmbed] }); -} - -export function updatePlaylist(option) { - switch (option) { - case 'next': - currentTrack++; - audio = files[currentTrack]; - break; - case 'back': - currentTrack--; - audio = files[currentTrack]; - break; - case 'reset': - currentTrack = 0; - audio = files[currentTrack]; - break; - case 'input': - audio = inputFiles[integer]; - break; - case 'stop': - audio = 'Not Playing'; - break; - } -} diff --git a/backend/QueueSystem.js b/backend/QueueSystem.js deleted file mode 100644 index 0cd6ded..0000000 --- a/backend/QueueSystem.js +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ -import { playAudio, updatePlaylist } from './PlayAudio.js'; -import { files } from './AudioControl.js'; - -function shuffleArray(array) { - // Durstenfeld Shuffle - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } -} -export async function orderPlaylist(bot) { - console.log('Playing beats by order...'); - updatePlaylist('reset'); - console.log(files); - return await playAudio(bot); -} - -export async function shufflePlaylist(bot) { - console.log('Shuffling beats...'); - shuffleArray(files); - console.log('Playing beats by shuffle...'); - updatePlaylist('reset'); - console.log(files); - return await playAudio(bot); -} - -export async function inputAudio(bot) { - updatePlaylist('input'); - return await playAudio(bot); -} diff --git a/backend/Shutdown.js b/backend/Shutdown.js deleted file mode 100644 index fb89505..0000000 --- a/backend/Shutdown.js +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ -import { EmbedBuilder } from 'discord.js'; -import { player } from './VoiceInitialization.js'; -import { updatePlaylist } from './PlayAudio.js'; -import { audioState } from './AudioControl.js'; -import { readFileSync, writeFile } from 'node:fs'; -import { getVoiceConnection, VoiceConnectionStatus } from '@discordjs/voice'; -const { statusChannel, txtFile } = JSON.parse(readFileSync('./config.json', 'utf-8')); -let fileData; - -export async function destroyAudio(interaction) { - if (txtFile) { - fileData = 'Now Playing: Nothing'; - writeFile('now-playing.txt', fileData, (err) => { - if (err) { console.log(err); } - }); - } - - updatePlaylist('stop'); - audioState(2); - - const connection = getVoiceConnection(interaction.guild.id); - if (VoiceConnectionStatus.Ready) { - player.stop(); - return connection.destroy(); - } -} -export async function stopBot(bot, interaction) { - const statusEmbed = new EmbedBuilder() - .setAuthor({ name: bot.user.username, iconURL: bot.user.avatarURL() }) - .setDescription(`That's all folks! Powering down ${bot.user.username}...`) - .setColor('#0066ff'); - const channel = bot.channels.cache.get(statusChannel); - if (!channel) return console.error('The status channel does not exist! Skipping.'); - await channel.send({ embeds: [statusEmbed] }); - - console.log(`Powering off ${bot.user.username}...`); - await destroyAudio(interaction); - await bot.destroy(); - return process.exit(0); -} diff --git a/backend/VoiceInitialization.js b/backend/VoiceInitialization.js deleted file mode 100644 index a9e1149..0000000 --- a/backend/VoiceInitialization.js +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ -import { readFileSync } from 'node:fs'; -import { createAudioPlayer, joinVoiceChannel, VoiceConnectionStatus } from '@discordjs/voice'; -import { nextAudio } from './AudioControl.js'; -import { shufflePlaylist, orderPlaylist } from './QueueSystem.js'; - -const { voiceChannel, shuffle } = JSON.parse(readFileSync('./config.json', 'utf-8')); -export const player = createAudioPlayer(); -export async function voiceInit(bot) { - bot.channels.fetch(voiceChannel).then(async channel => { - const connection = joinVoiceChannel({ - channelId: channel.id, - guildId: channel.guild.id, - adapterCreator: channel.guild.voiceAdapterCreator - }); - - connection.on(VoiceConnectionStatus.Connecting, () => { - console.log(`Connecting to ${channel.name}...`); - }); - - connection.on(VoiceConnectionStatus.Ready, async() => { - console.log('Ready to blast some beats!'); - return (shuffle) ? await shufflePlaylist(bot) : await orderPlaylist(bot); - }); - - connection.on(VoiceConnectionStatus.Destroyed, () => { - console.log('Destroyed the beats...'); - }); - - player.on('error', error => { - console.error(error); - nextAudio(bot); - }); - - player.on('idle', () => { - console.log('Beat has finished playing, now playing next beat...'); - nextAudio(bot); - }); - - return connection.subscribe(player); - }).catch(e => { console.error(e); }); -} diff --git a/bot.js b/bot.js index 9944f24..53c5cb1 100644 --- a/bot.js +++ b/bot.js @@ -19,10 +19,10 @@ * ***************************************************************************/ import { Client, GatewayIntentBits, EmbedBuilder, Collection, version, InteractionType } from 'discord.js'; -import { voiceInit } from './backend/VoiceInitialization.js'; +import { voiceInit } from './AudioBackend/VoiceInitialization.js'; import { readdirSync, readFileSync } from 'node:fs'; // import config from './config.json' assert { type: 'json' } Not supported by ESLint yet -const { token, statusChannel, voiceChannel, shuffle, repeat, presenceActivity } = JSON.parse(readFileSync('./config.json', 'utf-8')); +const { token, statusChannel, voiceChannel, shuffle, repeat, presenceActivity, activityType } = JSON.parse(readFileSync('./config.json', 'utf-8')); const bot = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates] }); bot.login(token); @@ -34,10 +34,10 @@ bot.login(token); // Slash Command Handler bot.commands = new Collection(); -const commandFiles = readdirSync('./commands').filter(file => file.endsWith('.js')); +const commandFiles = readdirSync('./Commands').filter(file => file.endsWith('.js')); for (const file of commandFiles) { - const { default: command } = await import(`./commands/${file}`); + const { default: command } = await import(`./Commands/${file}`); bot.commands.set(command.data.name, command); } @@ -54,7 +54,7 @@ bot.once('ready', async() => { bot.user.setPresence({ activities: [{ name: presenceActivity, - type: 'LISTENING' + type: activityType }], status: 'online' }); diff --git a/commands/about.js b/commands/about.js deleted file mode 100644 index 23c750e..0000000 --- a/commands/about.js +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { EmbedBuilder, version, ActionRowBuilder, ButtonBuilder, ButtonStyle, SlashCommandBuilder } from 'discord.js'; -// import npmPackage from '../package.json' assert { type:'json' } -import { readFileSync } from 'node:fs'; -const npmPackage = JSON.parse(readFileSync('./package.json', 'utf-8')); - -export default { - data: new SlashCommandBuilder() - .setName('about') - .setDescription('Information about the bot'), - async execute(interaction, bot) { - const aboutEmbed = new EmbedBuilder() - .setAuthor({ name: `About ${bot.user.username}`, iconURL: bot.user.avatarURL() }) - .addFields( - { name: 'Information', value: 'A Discord bot that plays local audio tracks.' }, - { name: 'Version', value: `DLAP ${npmPackage.version}` }, - { name: 'Original Creator', value: 'Andrew Lee (Alee#4277)' }, // Do not remove this since I created this :) - // { name: 'Contributors', value: '[your name] (discord#0000)' }, - // { name: 'Forked by', value: '[your name] (discord#0000)' }, - { name: 'Frameworks', value: `Discord.JS ${version} + Voice` }, - { name: 'License', value: 'GNU General Public License v3.0' } - ) - .setFooter({ text: '© Copyright 2020-2022 Andrew Lee' }) - .setColor('#0066ff'); - - const srcOrig = new ActionRowBuilder() - .addComponents( - new ButtonBuilder() - .setStyle(ButtonStyle.Link) - .setLabel('Original Source Code') - .setURL('https://github.com/Alee14/DLAP') - ); - - return await interaction.reply({ embeds: [aboutEmbed], components: [srcOrig] }); - } -}; diff --git a/commands/join.js b/commands/join.js deleted file mode 100644 index aa3eb66..0000000 --- a/commands/join.js +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { voiceInit } from '../backend/VoiceInitialization.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('join') - .setDescription('Joins voice chat') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - await interaction.reply({ content: 'Joining voice channel', ephemeral: true }); - return await voiceInit(bot); - } -}; diff --git a/commands/leave.js b/commands/leave.js deleted file mode 100644 index 1577baa..0000000 --- a/commands/leave.js +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { destroyAudio } from '../backend/Shutdown.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('leave') - .setDescription('Leaves the voice chat') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - console.log('Leaving voice channel...'); - await destroyAudio(interaction); - return await interaction.reply({ content: 'Leaving voice channel', ephemeral: true }); - } -}; diff --git a/commands/list.js b/commands/list.js deleted file mode 100644 index 8eddcda..0000000 --- a/commands/list.js +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { readdirSync, readdir } from 'node:fs'; - -const musicFolder = './music'; - -export default { - data: new SlashCommandBuilder() - .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'); - readdir(musicFolder, async(err, files) => { - await interaction.reply(`Listing ${files.length} audio tracks...\n\`\`\`\n${beats}\n\`\`\``); - if (err) { - console.error(err); - } - }); - } -}; diff --git a/commands/next.js b/commands/next.js deleted file mode 100644 index 759c5bb..0000000 --- a/commands/next.js +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { player } from '../backend/VoiceInitialization.js'; -import { nextAudio, playerState } from '../backend/AudioControl.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('next') - .setDescription('Goes to next music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - if (playerState === 'Playing' || playerState === 'Paused') { - await interaction.reply({ content: 'Playing next music', ephemeral: true }); - player.stop(); - return await nextAudio(bot); - } else if (playerState === 'Stopped') { - return await interaction.reply({ content: 'Cannot play next music. Player is currently stopped...', ephemeral: true }); - } - } -}; diff --git a/commands/pause.js b/commands/pause.js deleted file mode 100644 index 61b9e21..0000000 --- a/commands/pause.js +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { toggleAudioState, isAudioStatePaused } from '../backend/AudioControl.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('pause') - .setDescription('Pauses music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - if (!isAudioStatePaused) { - toggleAudioState(); - return await interaction.reply({ content: 'Pausing music', ephemeral: true }); - } else { - return await interaction.reply({ content: 'Music is already paused', ephemeral: true }); - } - } -}; diff --git a/commands/ping.js b/commands/ping.js deleted file mode 100644 index 72ef024..0000000 --- a/commands/ping.js +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; - -export default { - data: new SlashCommandBuilder() - .setName('ping') - .setDescription('Pong!'), - async execute(interaction, bot) { - return await interaction.reply(`Pong! ${Math.round(bot.ws.ping)}ms`); - } -}; diff --git a/commands/play.js b/commands/play.js deleted file mode 100644 index 4c95ab8..0000000 --- a/commands/play.js +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { inputAudio } from '../backend/QueueSystem.js'; -import { files, isAudioStatePaused, toggleAudioState } from '../backend/AudioControl.js'; -import { audio } from '../backend/PlayAudio.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export let integer; - -export default { - data: new SlashCommandBuilder() - .setName('play') - .setDescription('Resumes music') - .addIntegerOption(option => - option.setName('int') - .setDescription('Input a number for the selection for the audio file.') - ) - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - integer = interaction.options.getInteger('int'); - if (integer) { - if (integer < files.length) { - await inputAudio(bot, integer); - return await interaction.reply({ content: `Now playing: ${audio}`, ephemeral: true }); - } else { - return await interaction.reply({ content: 'Number is too big, choose a number that\'s less than ' + files.length + '.', ephemeral: true }); - } - } - if (isAudioStatePaused) { - toggleAudioState(); - return await interaction.reply({ content: 'Resuming music', ephemeral: true }); - } else { - return await interaction.reply({ content: 'Music is already playing', ephemeral: true }); - } - } -}; diff --git a/commands/previous.js b/commands/previous.js deleted file mode 100644 index ebedbb6..0000000 --- a/commands/previous.js +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { playerState, previousAudio } from '../backend/AudioControl.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('previous') - .setDescription('Goes to previous music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - if (playerState === 'Playing' || playerState === 'Paused') { - return await previousAudio(bot, interaction); - } else if (playerState === 'Stopped') { - return await interaction.reply({ content: 'Cannot play next music. Player is currently stopped...', ephemeral: true }); - } - } -}; diff --git a/commands/reshuffle.js b/commands/reshuffle.js deleted file mode 100644 index e1d37d0..0000000 --- a/commands/reshuffle.js +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { shufflePlaylist } from '../backend/QueueSystem.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; -import { readFileSync } from 'node:fs'; -import { audioState } from '../backend/AudioControl.js'; -// import config from './config.json' assert {type: 'json'} -const { shuffle } = JSON.parse(readFileSync('./config.json', 'utf-8')); - -export default { - data: new SlashCommandBuilder() - .setName('reshuffle') - .setDescription('Reshuffles the playlist') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - async function shuffleDetected(bot) { - await interaction.reply({ content: 'Reshuffling the playlist...', ephemeral: true }); - await audioState(2); - await shufflePlaylist(bot); - } - return (shuffle) ? await shuffleDetected(bot) : await interaction.reply({ content: 'Shuffle mode is disabled, enable it in the configuration file to access this command.', ephemeral: true }); - } -}; diff --git a/commands/shutdown.js b/commands/shutdown.js deleted file mode 100644 index 313866b..0000000 --- a/commands/shutdown.js +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { SlashCommandBuilder } from 'discord.js'; -import { stopBot } from '../backend/Shutdown.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - -export default { - data: new SlashCommandBuilder() - .setName('shutdown') - .setDescription('Powers off the bot') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction, bot) { - await interaction.reply({ content: 'Powering off...', ephemeral: true }); - return await stopBot(bot, interaction); - } -}; diff --git a/commands/status.js b/commands/status.js deleted file mode 100644 index d19e4ac..0000000 --- a/commands/status.js +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************** - * - * DLAP Bot: A Discord bot that plays local audio tracks. - * (C) Copyright 2022 - * Programmed by Andrew Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - ***************************************************************************/ - -import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; -import { parseFile } from 'music-metadata'; -import { audio, metadataEmpty, duration, audioTitle, currentTrack } from '../backend/PlayAudio.js'; -import { files, playerState } from '../backend/AudioControl.js'; - -export default { - data: new SlashCommandBuilder() - .setName('status') - .setDescription('Checks what audio file is playing currently'), - async execute(interaction, bot) { - if (!interaction.member.voice.channel) return await interaction.reply({ content: 'You need to be in a voice channel to use this command.', ephemeral: true }); - let audioID = currentTrack; - audioID++; - - let audioName = files[audioID]; - - if (audioName === undefined) { - audioName = 'Playlist Finished'; - } else { - if (!metadataEmpty) { - try { - const { common } = await parseFile('music/' + audioName); - audioName = common.title; - } catch (error) { - console.error(error.message); - } - } else { - audioName = audioName.split('.').slice(0, -1).join('.'); - } - } - - const controlEmbed = new EmbedBuilder() - .setAuthor({ name: `${bot.user.username} Status`, iconURL: bot.user.avatarURL() }) - .addFields( - { name: 'State', value: playerState }, - { name: 'Tracks', value: `${audioID}/${files.length}` }, - { name: 'Duration', value: duration } - ) - .setColor('#0066ff'); - - if (metadataEmpty) { - controlEmbed.addFields( - { name: 'Currently Playing', value: audio }, - { name: 'Up Next', value: audioName } - ); - } else { - controlEmbed.addFields( - { name: 'Currently Playing', value: audioTitle }, - { name: 'Up Next', value: audioName } - ); - } - interaction.reply({ embeds: [controlEmbed] }); - } -}; diff --git a/deploy-command.js b/deploy-command.js index cd698ee..fd9de7a 100644 --- a/deploy-command.js +++ b/deploy-command.js @@ -5,10 +5,10 @@ import { Routes } from 'discord-api-types/v10'; const { clientID, token } = JSON.parse(readFileSync('./config.json')); const commands = []; -const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js')); +const commandFiles = fs.readdirSync('./Commands').filter(file => file.endsWith('.js')); for (const file of commandFiles) { - const { default: command } = await import(`./commands/${file}`); + const { default: command } = await import(`./Commands/${file}`); commands.push(command.data.toJSON()); } diff --git a/package.json b/package.json index aeb0672..5757d02 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "discord-api-types": "^0.37.15", "discord.js": "^14.6.0", "ffmpeg-static": "^5.1.0", - "i18next": "^22.0.6", + "i18next": "^22.4.5", "music-metadata": "^8.1.0", "sodium": "^3.0.2" }, diff --git a/yarn.lock b/yarn.lock index 20807be..e33fdcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/runtime@^7.17.2": +"@babel/runtime@^7.20.6": version "7.20.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3" integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA== @@ -988,12 +988,12 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -i18next@^22.0.6: - version "22.0.6" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.0.6.tgz#d7029912f8aa74ff295c0d9afd1b7dea45859b49" - integrity sha512-RlreNGoPIdDP4QG+qSA9PxZKGwlzmcozbI9ObI6+OyUa/Rp0EjZZA9ubyBjw887zVNZsC+7FI3sXX8oiTzAfig== +i18next@^22.4.5: + version "22.4.5" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.5.tgz#7324e4946c2facbe743ca25bca8980af05b0a109" + integrity sha512-Kc+Ow0guRetUq+kv02tj0Yof9zveROPBAmJ8UxxNODLVBRSwsM4iD0Gw3BEieOmkWemF6clU3K1fbnCuTqiN2Q== dependencies: - "@babel/runtime" "^7.17.2" + "@babel/runtime" "^7.20.6" ieee754@^1.2.1: version "1.2.1" -- cgit v1.2.3