This commit is contained in:
Andrew Lee 2022-07-09 22:14:38 -04:00
parent 4c26fbcb7e
commit d7e4cf29e6
Signed by: andrew
GPG key ID: 4DCE67C47836D125
16 changed files with 327 additions and 302 deletions

16
.eslintrc.json Normal file
View file

@ -0,0 +1,16 @@
{
"env": {
"browser": true,
"es2022": true
},
"extends": [
"standard"
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"semi": [2, "always"]
}
}

View file

@ -25,14 +25,15 @@ import {
getVoiceConnection, getVoiceConnection,
joinVoiceChannel, joinVoiceChannel,
VoiceConnectionStatus VoiceConnectionStatus
} from '@discordjs/voice' } from '@discordjs/voice';
import { MessageEmbed } from 'discord.js' import { MessageEmbed } from 'discord.js';
import config from './config.json' assert {type: 'json'} import { readdirSync, readFileSync, writeFile } from 'node:fs';
import { readdirSync, writeFile } from 'node:fs' // import config from './config.json' assert {type: 'json'}
const config = JSON.parse(readFileSync('./config.json'));
export const player = createAudioPlayer(); export const player = createAudioPlayer();
export let audio; export let audio;
export let files = readdirSync('music'); export const files = readdirSync('music');
let fileData; let fileData;
export let audioArray; export let audioArray;
export let currentTrack; export let currentTrack;
@ -40,117 +41,114 @@ export let currentTrack;
export let playerState; export let playerState;
export let isAudioStatePaused; export let isAudioStatePaused;
export async function voiceInit(bot) { export async function voiceInit (bot) {
bot.channels.fetch(config.voiceChannel).then(async channel => { bot.channels.fetch(config.voiceChannel).then(async channel => {
const connection = joinVoiceChannel({ const connection = joinVoiceChannel({
channelId: channel.id, channelId: channel.id,
guildId: channel.guild.id, guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator adapterCreator: channel.guild.voiceAdapterCreator
}); });
connection.on(VoiceConnectionStatus.Ready, async () => { connection.on(VoiceConnectionStatus.Ready, async () => {
console.log('Ready to blast some beats!'); console.log('Ready to blast some beats!');
await shufflePlaylist(bot); await shufflePlaylist(bot);
}); });
connection.on(VoiceConnectionStatus.Destroyed, () => { connection.on(VoiceConnectionStatus.Destroyed, () => {
console.log('Destroyed the beats...'); console.log('Destroyed the beats...');
}); });
player.on('error', error => { player.on('error', error => {
console.error(error); console.error(error);
nextAudio(bot); nextAudio(bot);
}); });
player.on('idle', () => { player.on('idle', () => {
console.log("Beat has finished playing, now to the next beat..."); console.log('Beat has finished playing, now to the next beat...');
nextAudio(bot); nextAudio(bot);
}) });
return connection.subscribe(player); return connection.subscribe(player);
}).catch(e => { console.error(e) }) }).catch(e => { console.error(e); });
} }
function shuffleArray(array) { function shuffleArray (array) {
for (let i = array.length - 1; i > 0; i--) { for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1)); const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; [array[i], array[j]] = [array[j], array[i]];
} }
} }
export async function shufflePlaylist(bot) { export async function shufflePlaylist (bot) {
console.log('Shuffling beats...'); console.log('Shuffling beats...');
currentTrack = 0 currentTrack = 0;
audioArray = files; audioArray = files;
shuffleArray(audioArray); shuffleArray(audioArray);
console.log(audioArray); console.log(audioArray);
audio = audioArray[currentTrack] audio = audioArray[currentTrack];
return await playAudio(bot); return await playAudio(bot);
} }
export async function nextAudio(bot) { export async function nextAudio (bot) {
let totalTrack = files.length let totalTrack = files.length;
totalTrack-- totalTrack--;
if (currentTrack >= totalTrack) { if (currentTrack >= totalTrack) {
console.log('All beats in the playlist has finished, reshuffling...'); console.log('All beats in the playlist has finished, reshuffling...');
await shufflePlaylist(bot); await shufflePlaylist(bot);
} else { } else {
currentTrack++ currentTrack++;
audio = audioArray[currentTrack]; audio = audioArray[currentTrack];
} }
return await playAudio(bot); return await playAudio(bot);
} }
export async function inputAudio(bot, integer) { export async function inputAudio (bot, integer) {
let inputFiles = readdirSync('music'); const inputFiles = readdirSync('music');
audio = inputFiles[integer]; audio = inputFiles[integer];
return await playAudio(bot); return await playAudio(bot);
} }
export async function playAudio(bot) { export async function playAudio (bot) {
let resource = createAudioResource('music/' + audio); const resource = createAudioResource('music/' + audio);
player.play(resource); player.play(resource);
console.log('Now playing: ' + audio); console.log('Now playing: ' + audio);
playerState = "Playing" playerState = 'Playing';
isAudioStatePaused = false isAudioStatePaused = false;
audio = audio.split('.').slice(0, -1).join('.'); audio = audio.split('.').slice(0, -1).join('.');
if (config.txtFile === true) {
fileData = "Now Playing: " + audio
writeFile("./now-playing.txt", fileData, (err) => {
if (err)
console.log(err);
});
}
const statusEmbed = new MessageEmbed()
.addField('Now Playing', `${audio}`)
.setColor('#0066ff')
let statusChannel = bot.channels.cache.get(config.statusChannel);
if (!statusChannel) return console.error('The status channel does not exist! Skipping.');
return await statusChannel.send({embeds: [statusEmbed]});
}
export async function destroyAudio(interaction) {
if (config.txtFile === true) { if (config.txtFile === true) {
fileData = "Now Playing: Nothing"; fileData = 'Now Playing: ' + audio;
writeFile("now-playing.txt", fileData, (err) => { writeFile('./now-playing.txt', fileData, (err) => {
if (err) if (err) { console.log(err); }
console.log(err);
}); });
} }
audio = "Not Playing" const statusEmbed = new MessageEmbed()
playerState = "Stopped" .addField('Now Playing', `${audio}`)
isAudioStatePaused = true .setColor('#0066ff');
const statusChannel = bot.channels.cache.get(config.statusChannel);
if (!statusChannel) return console.error('The status channel does not exist! Skipping.');
return await statusChannel.send({ embeds: [statusEmbed] });
}
export async function destroyAudio (interaction) {
if (config.txtFile === true) {
fileData = 'Now Playing: Nothing';
writeFile('now-playing.txt', fileData, (err) => {
if (err) { console.log(err); }
});
}
audio = 'Not Playing';
playerState = 'Stopped';
isAudioStatePaused = true;
const connection = getVoiceConnection(interaction.guild.id); const connection = getVoiceConnection(interaction.guild.id);
if (VoiceConnectionStatus.Ready) { if (VoiceConnectionStatus.Ready) {
@ -159,24 +157,24 @@ export async function destroyAudio(interaction) {
} }
} }
export function audioState() { export function audioState () {
if (isAudioStatePaused === false) { if (isAudioStatePaused === false) {
isAudioStatePaused = true isAudioStatePaused = true;
playerState = "Paused" playerState = 'Paused';
} else if (isAudioStatePaused === true) { } else if (isAudioStatePaused === true) {
isAudioStatePaused = false isAudioStatePaused = false;
playerState = "Playing" playerState = 'Playing';
} }
} }
export async function stopBot(bot, interaction) { export async function stopBot (bot, interaction) {
const statusEmbed = new MessageEmbed() const statusEmbed = new MessageEmbed()
.setAuthor({name: bot.user.username, iconURL: bot.user.avatarURL()}) .setAuthor({ name: bot.user.username, iconURL: bot.user.avatarURL() })
.setDescription(`That\'s all folks! Powering down ${bot.user.username}...`) .setDescription(`That's all folks! Powering down ${bot.user.username}...`)
.setColor('#0066ff') .setColor('#0066ff');
let statusChannel = bot.channels.cache.get(config.statusChannel); const statusChannel = bot.channels.cache.get(config.statusChannel);
if (!statusChannel) return console.error('The status channel does not exist! Skipping.'); if (!statusChannel) return console.error('The status channel does not exist! Skipping.');
await statusChannel.send({embeds: [statusEmbed]}); await statusChannel.send({ embeds: [statusEmbed] });
console.log(`Powering off ${bot.user.username}...`); console.log(`Powering off ${bot.user.username}...`);
await destroyAudio(interaction); await destroyAudio(interaction);

27
bot.js
View file

@ -18,16 +18,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
***************************************************************************/ ***************************************************************************/
import { Client, MessageEmbed, Collection, version } from 'discord.js' import { Client, MessageEmbed, Collection, version } from 'discord.js';
import { voiceInit } from './AudioBackend.js' import { voiceInit } from './AudioBackend.js';
import { readdirSync } from 'node:fs' import { readdirSync, readFileSync } from 'node:fs';
import config from './config.json' assert { type: 'json' } // import config from './config.json' assert { type: 'json' } Not in ECMAScript yet
const config = JSON.parse(readFileSync('./config.json'));
const bot = new Client({intents: ['GUILDS', 'GUILD_MESSAGES', 'GUILD_VOICE_STATES']}); const bot = new Client({ intents: ['GUILDS', 'GUILD_MESSAGES', 'GUILD_VOICE_STATES'] });
bot.login(config.token); bot.login(config.token);
/** /**
* Project Ideas: * Project Ideas:
* Shuffle or "Play by order" mode * Shuffle or "Play by order" mode
@ -47,7 +47,7 @@ for (const file of commandFiles) {
bot.once('ready', async () => { bot.once('ready', async () => {
console.log('Bot is ready!'); console.log('Bot is ready!');
console.log(`Logged in as ${bot.user.tag}!`); console.log(`Logged in as ${bot.user.tag}!`);
console.log(`Running on Discord.JS ${version}`) console.log(`Running on Discord.JS ${version}`);
console.log(`Voice Channel: ${config.voiceChannel}`); console.log(`Voice Channel: ${config.voiceChannel}`);
console.log(`Status Channel: ${config.statusChannel}`); console.log(`Status Channel: ${config.statusChannel}`);
@ -57,7 +57,7 @@ bot.once('ready', async () => {
name: 'some beats', name: 'some beats',
type: 'LISTENING' type: 'LISTENING'
}], }],
status: 'online', status: 'online'
}); });
const activity = bot.presence.activities[0]; const activity = bot.presence.activities[0];
@ -65,16 +65,15 @@ bot.once('ready', async () => {
// Send bots' status to channel // Send bots' status to channel
const readyEmbed = new MessageEmbed() const readyEmbed = new MessageEmbed()
.setAuthor({name: bot.user.username, iconURL: bot.user.avatarURL()}) .setAuthor({ name: bot.user.username, iconURL: bot.user.avatarURL() })
.setDescription('Starting bot...') .setDescription('Starting bot...')
.setColor('#0066ff') .setColor('#0066ff');
let statusChannel = bot.channels.cache.get(config.statusChannel); const statusChannel = bot.channels.cache.get(config.statusChannel);
if (!statusChannel) return console.error('The status channel does not exist! Skipping.'); if (!statusChannel) return console.error('The status channel does not exist! Skipping.');
await statusChannel.send({embeds: [readyEmbed]}); await statusChannel.send({ embeds: [readyEmbed] });
await voiceInit(bot); await voiceInit(bot);
}); });
bot.on('interactionCreate', async interaction => { bot.on('interactionCreate', async interaction => {

View file

@ -19,35 +19,37 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed, version, MessageActionRow, MessageButton } from 'discord.js' import { MessageEmbed, version, MessageActionRow, MessageButton } from 'discord.js';
import npmPackage from '../package.json' assert { type:'json' } // import npmPackage from '../package.json' assert { type:'json' }
import { readFileSync } from 'node:fs';
const npmPackage = JSON.parse(readFileSync('./package.json'));
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('about') .setName('about')
.setDescription('Information about the bot'), .setDescription('Information about the bot'),
async execute(interaction, bot) { async execute (interaction, bot) {
const aboutEmbed = new MessageEmbed() const aboutEmbed = new MessageEmbed()
.setAuthor({name:`About ${bot.user.username}`, iconURL:bot.user.avatarURL()}) .setAuthor({ name: `About ${bot.user.username}`, iconURL: bot.user.avatarURL() })
.addField('Information', 'A Discord bot that plays local audio tracks.') .addField('Information', 'A Discord bot that plays local audio tracks.')
.addField('Version', `DLAP ${npmPackage.version}`) .addField('Version', `DLAP ${npmPackage.version}`)
.addField('Original Creator', 'Andrew Lee (Alee#4277)') // Do not remove this since I created this :) .addField('Original Creator', 'Andrew Lee (Alee#4277)') // Do not remove this since I created this :)
//.addField('Contributors', '[your name] (discord#0000)') // .addField('Contributors', '[your name] (discord#0000)')
//.addField('Forked by', '[your name] (discord#0000)') // .addField('Forked by', '[your name] (discord#0000)')
.addField('Frameworks', `Discord.JS ${version} + Voice`) .addField('Frameworks', `Discord.JS ${version} + Voice`)
.addField('License', 'GNU General Public License v3.0') .addField('License', 'GNU General Public License v3.0')
.setFooter({text:'© Copyright 2020-2022 Andrew Lee'}) .setFooter({ text: '© Copyright 2020-2022 Andrew Lee' })
.setColor('#0066ff') .setColor('#0066ff');
const srcOrig = new MessageActionRow() const srcOrig = new MessageActionRow()
.addComponents( .addComponents(
new MessageButton() new MessageButton()
.setStyle('LINK') .setStyle('LINK')
.setLabel('Original Source Code') .setLabel('Original Source Code')
.setURL('https://github.com/Alee14/DLMP3'), .setURL('https://github.com/Alee14/DLMP3')
); );
return await interaction.reply({ embeds:[aboutEmbed], components:[srcOrig] }); return await interaction.reply({ embeds: [aboutEmbed], components: [srcOrig] });
}, }
}; };

View file

@ -19,17 +19,17 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { voiceInit } from '../AudioBackend.js' import { voiceInit } from '../AudioBackend.js';
import { PermissionFlagsBits } from 'discord-api-types/v10' import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('join') .setName('join')
.setDescription('Joins voice chat') .setDescription('Joins voice chat')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction, bot) { async execute (interaction, bot) {
await interaction.reply({ content: 'Joining voice channel', ephemeral: true }) await interaction.reply({ content: 'Joining voice channel', ephemeral: true });
return await voiceInit(bot); return await voiceInit(bot);
}, }
}; };

View file

@ -19,18 +19,18 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { destroyAudio } from "../AudioBackend.js" import { destroyAudio } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('leave') .setName('leave')
.setDescription('Leaves the voice chat') .setDescription('Leaves the voice chat')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction) { async execute (interaction) {
console.log('Leaving voice channel...'); console.log('Leaving voice channel...');
await destroyAudio(interaction); await destroyAudio(interaction);
return await interaction.reply({content:'Leaving voice channel', ephemeral:true}); return await interaction.reply({ content: 'Leaving voice channel', ephemeral: true });
}, }
}; };

View file

@ -19,21 +19,26 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { readdirSync, readdir } from 'fs' import { readdirSync, readdir } from 'fs';
const musicFolder = './music'; const musicFolder = './music';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('list') .setName('list')
.setDescription('Lists the available audio tracks'), .setDescription('Lists the available audio tracks'),
async execute(interaction) { 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. // 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'); const beats = readdirSync(musicFolder).join('\n');
readdir(musicFolder, async (err, files) => { readdir(musicFolder, async (err, files) => {
await interaction.reply(`Listing ${files.length} audio tracks...\n\`\`\`\n${beats}\n\`\`\``); await interaction.reply(
}); `Listing ${files.length} audio tracks...\n\`\`\`\n${beats}\n\`\`\``
}, );
if (err) {
console.error(err);
}
});
}
}; };

View file

@ -19,22 +19,22 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { audioState, isAudioStatePaused, player } from "../AudioBackend.js" import { audioState, isAudioStatePaused, player } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('pause') .setName('pause')
.setDescription('Pauses music') .setDescription('Pauses music')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction) { async execute (interaction) {
if (isAudioStatePaused === false) { if (isAudioStatePaused === false) {
audioState(); audioState();
player.pause(); player.pause();
return await interaction.reply({content:'Pausing music', ephemeral:true}); return await interaction.reply({ content: 'Pausing music', ephemeral: true });
} else { } else {
return await interaction.reply({content:"Music is already paused", ephemeral:true}) return await interaction.reply({ content: 'Music is already paused', ephemeral: true });
} }
}, }
}; };

View file

@ -19,13 +19,13 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('ping') .setName('ping')
.setDescription('Pong!'), .setDescription('Pong!'),
async execute(interaction, bot) { async execute (interaction, bot) {
return await interaction.reply(`Pong! ${Math.round(bot.ws.ping)}ms`); return await interaction.reply(`Pong! ${Math.round(bot.ws.ping)}ms`);
}, }
}; };

View file

@ -19,38 +19,38 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { isAudioStatePaused, inputAudio, audio, audioState, player, files } from '../AudioBackend.js' import { isAudioStatePaused, inputAudio, audio, audioState, player, files } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export let integer; export let integer;
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('play') .setName('play')
.setDescription('Resumes music') .setDescription('Resumes music')
.addIntegerOption(option => .addIntegerOption(option =>
option.setName('int') option.setName('int')
.setDescription('Input a number for the selection for the audio file.'), .setDescription('Input a number for the selection for the audio file.')
) )
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction, bot) { async execute (interaction, bot) {
integer = interaction.options.getInteger('int'); integer = interaction.options.getInteger('int');
if (integer) { if (integer) {
if (integer < files.length) { if (integer < files.length) {
await inputAudio(bot, integer); await inputAudio(bot, integer);
return await interaction.reply({content:`Now playing: ${audio}`, ephemeral:true}); return await interaction.reply({ content: `Now playing: ${audio}`, ephemeral: true });
} else { } else {
return await interaction.reply({content:'Number is too big, choose a number that\'s less than ' + files.length + '.', ephemeral:true}) return await interaction.reply({ content: 'Number is too big, choose a number that\'s less than ' + files.length + '.', ephemeral: true });
} }
} }
if (isAudioStatePaused === true) { if (isAudioStatePaused === true) {
audioState(); audioState();
player.unpause(); player.unpause();
return await interaction.reply({content:'Resuming music', ephemeral:true}); return await interaction.reply({ content: 'Resuming music', ephemeral: true });
} else { } else {
return await interaction.reply({content:"Music is already playing", ephemeral:true}) return await interaction.reply({ content: 'Music is already playing', ephemeral: true });
} }
}, }
}; };

View file

@ -19,19 +19,19 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { player, shufflePlaylist } from "../AudioBackend.js" import { player, shufflePlaylist } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('reshuffle') .setName('reshuffle')
.setDescription('Reshuffles the playlist') .setDescription('Reshuffles the playlist')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction, bot) { async execute (interaction, bot) {
// Command not fully functional yet // Command not fully functional yet
await interaction.reply({content:`Reshuffling the playlist...`, ephemeral:true}); await interaction.reply({ content: 'Reshuffling the playlist...', ephemeral: true });
player.stop(); player.stop();
return await shufflePlaylist(bot); return await shufflePlaylist(bot);
}, }
}; };

View file

@ -19,17 +19,17 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { stopBot } from "../AudioBackend.js" import { stopBot } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('shutdown') .setName('shutdown')
.setDescription('Powers off the bot') .setDescription('Powers off the bot')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction, bot) { async execute (interaction, bot) {
await interaction.reply({ content: 'Powering off...', ephemeral: true}) await interaction.reply({ content: 'Powering off...', ephemeral: true });
return await stopBot(bot, interaction); return await stopBot(bot, interaction);
}, }
}; };

View file

@ -19,18 +19,18 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { audio, player, nextAudio } from "../AudioBackend.js" import { audio, player, nextAudio } from '../AudioBackend.js';
import { PermissionFlagsBits } from "discord-api-types/v10" import { PermissionFlagsBits } from 'discord-api-types/v10';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('skip') .setName('skip')
.setDescription('Skips the audio track') .setDescription('Skips the audio track')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator), .setDefaultMemberPermissions(PermissionFlagsBits.Administrator),
async execute(interaction, bot) { async execute (interaction, bot) {
await interaction.reply({content:`Skipping ${audio}`, ephemeral:true}); await interaction.reply({ content: `Skipping ${audio}`, ephemeral: true });
player.stop(); player.stop();
return await nextAudio(bot, interaction); return await nextAudio(bot, interaction);
}, }
}; };

View file

@ -19,28 +19,27 @@
* *
***************************************************************************/ ***************************************************************************/
import { SlashCommandBuilder } from '@discordjs/builders' import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed } from "discord.js" import { MessageEmbed } from 'discord.js';
import {audio, audioArray, currentTrack, playerState} from "../AudioBackend.js" import { audio, audioArray, currentTrack, playerState } from '../AudioBackend.js';
export default { export default {
data: new SlashCommandBuilder() data: new SlashCommandBuilder()
.setName('status') .setName('status')
.setDescription('Checks what audio file is playing currently'), .setDescription('Checks what audio file is playing currently'),
async execute(interaction, bot) { async execute (interaction, bot) {
let audioID = currentTrack;
audioID++;
let audioID = currentTrack let audioName = audioArray[audioID];
audioID++ audioName = audioName.split('.').slice(0, -1).join('.');
let audioName = audioArray[audioID] const controlEmbed = new MessageEmbed()
audioName = audioName.split('.').slice(0, -1).join('.'); .setAuthor({ name: `${bot.user.username} Status`, iconURL: bot.user.avatarURL() })
.addField('State', playerState)
let controlEmbed = new MessageEmbed() .addField('Currently Playing', audio)
.setAuthor({name: `${bot.user.username} Status`, iconURL: bot.user.avatarURL()}) .addField('Up Next', audioName)
.addField('State', playerState) .setColor('#0066ff');
.addField('Currently Playing', audio) interaction.reply({ embeds: [controlEmbed], ephemeral: true });
.addField('Up Next', audioName) }
.setColor('#0066ff')
interaction.reply({embeds:[controlEmbed], ephemeral:true})
},
}; };

View file

@ -1,18 +1,19 @@
import fs from 'node:fs' import fs, { readFileSync } from 'node:fs';
import { REST } from '@discordjs/rest' import { REST } from '@discordjs/rest';
import { Routes } from 'discord-api-types/v10' import { Routes } from 'discord-api-types/v10';
import config from './config.json' assert {type: 'json'} // import config from './config.json' assert {type: 'json'}
const config = JSON.parse(readFileSync('./config.json'));
const commands = []; 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) { for (const file of commandFiles) {
const { default: command } = await import(`./commands/${file}`); const { default: command } = await import(`./commands/${file}`);
commands.push(command.data.toJSON()); commands.push(command.data.toJSON());
} }
const rest = new REST({ version: '10' }).setToken(config.token); const rest = new REST({ version: '10' }).setToken(config.token);
rest.put(Routes.applicationGuildCommands(config.clientID, config.guildID), { body: commands }) rest.put(Routes.applicationGuildCommands(config.clientID, config.guildID), { body: commands })
.then(() => console.log('Successfully registered application commands.')) .then(() => console.log('Successfully registered application commands.'))
.catch(console.error); .catch(console.error);

View file

@ -18,6 +18,11 @@
"libsodium-wrappers": "^0.7.10" "libsodium-wrappers": "^0.7.10"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.0.1",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0",
"nodemon": "^2.0.15" "nodemon": "^2.0.15"
} }
} }