Add more commands

This commit is contained in:
Myx
2023-07-02 01:54:47 +02:00
parent eccad8d147
commit 398382a7f1
18 changed files with 434 additions and 144 deletions

View File

@@ -32,5 +32,6 @@ module.exports = {
'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }],
'no-duplicate-imports': ['error', { includeExports: true }], 'no-duplicate-imports': ['error', { includeExports: true }],
'eol-last': ['error', 'never'], 'eol-last': ['error', 'never'],
'linebreak-style': 0,
}, },
}; };

30
commands/leave.js Normal file
View File

@@ -0,0 +1,30 @@
// leaveCommand.js
const { getVoiceConnection } = require('@discordjs/voice');
const { intervalMap } = require('../utils/nowPlayingMessage'); // Import the intervalMap from the nowPlayingMessage module
const ConsolerLogger = require('../utils/logger');
const logger = new ConsolerLogger();
async function leaveCommand(interaction) {
await interaction.deferReply();
try {
const guildId = interaction.guild.id;
const connection = getVoiceConnection(guildId);
if (!connection) {
return interaction.followUp('I am not currently in a voice channel.');
}
// Clear the interval for updating the progress bar
const interval = intervalMap.get(guildId);
clearInterval(interval);
connection.destroy();
return interaction.followUp('I have left the voice channel.');
} catch (error) {
logger.error(error);
return interaction.followUp('An error occurred while trying to leave the voice channel.');
}
}
module.exports.leaveCommand = leaveCommand;

View File

@@ -27,10 +27,11 @@ async function playCommand(interaction) {
if (musicQueue.getQueue(interaction.guild.id).length > 0) { if (musicQueue.getQueue(interaction.guild.id).length > 0) {
musicQueue.removeFromQueue(interaction.guild.id); musicQueue.removeFromQueue(interaction.guild.id);
musicQueue.addToQueue(interaction.guild.id, song, true);
} else {
musicQueue.addToQueue(interaction.guild.id, song);
} }
musicQueue.addToQueue(interaction.guild.id, song);
musicPlayer( musicPlayer(
interaction.guild.id, interaction.guild.id,
connection, connection,

39
commands/previous.js Normal file
View File

@@ -0,0 +1,39 @@
const { joinVoiceChannel } = require('@discordjs/voice');
const musicQueue = require('../musicQueue');
const { musicPlayer } = require('../utils/musicPlayer');
function previousCommand(interaction) {
// Get the server queue
const serverQueue = musicQueue.getQueue(interaction.guild.id);
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) {
return interaction.followUp(
'You must be in a voice channel to use this command.',
);
}
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false,
});
// Check if there is a previous song in the queue
if (serverQueue.previous === undefined) {
return interaction.reply('There is no previous song to go back to!');
}
// Add the previous song back to the front of the queue
musicQueue.addToQueue(interaction.guild.id, serverQueue.previous, true);
// Play the previous song
musicPlayer(interaction.guild.id, connection, interaction);
return interaction.reply('Went back to the previous song!');
}
module.exports.previousCommand = previousCommand;

40
commands/skip.js Normal file
View File

@@ -0,0 +1,40 @@
const { joinVoiceChannel } = require('@discordjs/voice');
const musicQueue = require('../musicQueue');
const { musicPlayer } = require('../utils/musicPlayer');
async function skipCommand(interaction) {
// Get the server queue
interaction.deferReply();
const serverQueue = musicQueue.getQueue(interaction.guild.id);
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) {
return interaction.followUp(
'You must be in a voice channel to use this command.',
);
}
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
selfDeaf: false,
selfMute: false,
});
// Check if there are any songs in the queue
if (serverQueue.length === 0) {
return interaction.reply('There are no songs in the queue to skip!');
}
// Remove the current song from the queue
musicQueue.removeFromQueue(interaction.guild.id);
// Play the next song
await musicPlayer(interaction.guild.id, connection, interaction);
return interaction.reply('Skipped to the next song!');
}
module.exports.skipCommand = skipCommand;

View File

@@ -7,12 +7,17 @@ const { queueCommand } = require('./commands/queue');
const { stopCommand } = require('./commands/stop'); const { stopCommand } = require('./commands/stop');
const { pauseCommand, unpauseCommand } = require('./commands/pauseResume'); const { pauseCommand, unpauseCommand } = require('./commands/pauseResume');
const { toggleLoopCommand } = require('./commands/loop'); const { toggleLoopCommand } = require('./commands/loop');
const { skipCommand } = require('./commands/skip');
const { leaveCommand } = require('./commands/leave');
const { previousCommand } = require('./commands/previous');
const { ReAuth } = require('./reAuthenticate'); const { ReAuth } = require('./reAuthenticate');
const ConsolerLogger = require('./utils/logger');
const { clientId } = process.parsed; const { clientId } = process.parsed;
const { token } = process.parsed; const { token } = process.parsed;
const client = new Client({ const logger = new ConsolerLogger();
const botClient = new Client({
intents: [ intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessages,
@@ -22,14 +27,14 @@ const client = new Client({
], ],
}); });
client.on('ready', async () => { botClient.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}!`); logger.info(`Logged in as ${botClient.user.tag}!`);
client.user.setActivity('Use /play to play music.'); botClient.user.setActivity('League of Legends', 0);
await registerCommands(clientId, token); await registerCommands(clientId, token);
}); });
client.on('voiceStateUpdate', (oldState) => { botClient.on('voiceStateUpdate', (oldState) => {
const voiceChannel = oldState.channel; const voiceChannel = oldState.channel;
if (voiceChannel && voiceChannel.members.size === 1) { if (voiceChannel && voiceChannel.members.size === 1) {
const connection = getVoiceConnection(voiceChannel.guild.id); const connection = getVoiceConnection(voiceChannel.guild.id);
@@ -40,13 +45,13 @@ client.on('voiceStateUpdate', (oldState) => {
} }
}); });
client.on('interactionCreate', async (interaction) => { botClient.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return; if (!interaction.isCommand()) return;
const { commandName } = interaction; const { commandName } = interaction;
if (commandName === 'play') { if (commandName === 'play') {
await playCommand(interaction, client); await playCommand(interaction, botClient);
} else if (commandName === 'queue') { } else if (commandName === 'queue') {
await queueCommand(interaction); await queueCommand(interaction);
} else if (commandName === 'pause') { } else if (commandName === 'pause') {
@@ -57,13 +62,21 @@ client.on('interactionCreate', async (interaction) => {
await toggleLoopCommand(interaction); await toggleLoopCommand(interaction);
} else if (commandName === 'stop') { } else if (commandName === 'stop') {
await stopCommand(interaction); await stopCommand(interaction);
} else if (commandName === 'leave') {
await leaveCommand(interaction);
} else if (commandName === 'skip') {
await skipCommand(interaction);
} else if (commandName === 'previous') {
await previousCommand(interaction);
} }
}); });
client.on('messageCreate', async (message) => { botClient.on('messageCreate', async (message) => {
if (message.content === 'reauth') { if (message.content === 'reauth') {
await ReAuth(); await ReAuth();
} }
}); });
client.login(token); botClient.login(token);
module.exports.botClient = { botClient };

View File

@@ -1,44 +1,47 @@
/* eslint-disable no-shadow */
const { exec } = require('child_process'); const { exec } = require('child_process');
const schedule = require('node-schedule'); const schedule = require('node-schedule');
const ConsolerLogger = require('./utils/logger');
const repoUrl = 'https://github.com/Myxelium/Lunaris/';
const localRepoPath = '/home/pi/Lunaris/'; const localRepoPath = '/home/pi/Lunaris/';
const processName = 'index.js'; const processName = 'index.js';
const logger = new ConsolerLogger();
schedule.scheduleJob('0 1 * * *', () => { schedule.scheduleJob('0 1 * * *', () => {
exec(`cd ${localRepoPath} && git fetch`, (error, stdout, stderr) => { exec(`cd ${localRepoPath} && git fetch`, (error) => {
if (error) { if (error) {
console.error(`exec error: ${error}`); logger.error(`exec error: ${error}`);
return; return;
} }
exec(`cd ${localRepoPath} && git rev-list HEAD...origin/master --count`, (error, stdout, stderr) => { exec(`cd ${localRepoPath} && git rev-list HEAD...origin/master --count`, (error, stdout) => {
if (error) { if (error) {
console.error(`exec error: ${error}`); logger.error(`exec error: ${error}`);
return; return;
} }
if (parseInt(stdout) > 0) { if (parseInt(stdout, 10) > 0) {
exec(`pm2 stop ${processName}`, (error, stdout, stderr) => { exec(`pm2 stop ${processName}`, (error) => {
if (error) { if (error) {
console.error(`exec error: ${error}`); logger.error(`exec error: ${error}`);
return; return;
} }
exec(`cd ${localRepoPath} && git pull`, (error, stdout, stderr) => { exec(`cd ${localRepoPath} && git pull`, (error) => {
if (error) { if (error) {
console.error(`exec error: ${error}`); logger.error(`exec error: ${error}`);
return; return;
} }
const now = new Date(); const now = new Date();
console.log(`Repository updated at ${now.toLocaleString()}`); logger.log(`Repository updated at ${now.toLocaleString()}`);
exec(`pm2 start ${processName}`, (error, stdout, stderr) => { exec(`pm2 start ${processName}`, (error) => {
if (error) { if (error) {
console.error(`exec error: ${error}`); logger.error(`exec error: ${error}`);
return; return;
} }
console.log(`${processName} started`); logger.log(`${processName} started`);
}); });
}); });
}); });
} }
}); });
}); });
}); });

View File

@@ -6,12 +6,18 @@ class MusicQueue {
this.looping = new Map(); this.looping = new Map();
} }
addToQueue(guildId, song) { addToQueue(guildId, song, front = false) {
if (!this.queue.has(guildId)) { if (!this.queue.has(guildId)) {
this.queue.set(guildId, []); this.queue.set(guildId, []);
} }
this.queue.get(guildId).push(song); if (front) {
// Add the song to the front of the queue
this.queue.get(guildId).unshift(song);
} else {
// Add the song to the end of the queue
this.queue.get(guildId).push(song);
}
} }
async removeFromQueue(guildId) { async removeFromQueue(guildId) {
@@ -38,6 +44,15 @@ class MusicQueue {
return this.queue.get(guildId); return this.queue.get(guildId);
} }
async addToQueueFirst(guildId, song) {
if (!this.queue.has(guildId)) {
this.queue.set(guildId, []);
}
this.removeFromQueue(guildId);
this.queue.get(guildId).unshift(song);
}
enableLooping(guildId) { enableLooping(guildId) {
this.looping.set(guildId, true); this.looping.set(guildId, true);
} }

View File

@@ -1,14 +1,44 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-await-in-loop */
// const playdl = require('play-dl');
// const youtube = require('./youtube');
const playdl = require('play-dl'); const playdl = require('play-dl');
// TODO ADD SPOTIFY SUPPORT const youtube = require('./youtube');
async function getStream(query) { const musicQueue = require('../musicQueue'); // Import the musicQueue module
async function getStream(query, guildId) {
// Check if the query is a Spotify playlist
if (playdl.sp_validate(query) === 'playlist') {
let firstTrack = {};
// Get the playlist information
const playlistInfo = await playdl.spotify(query);
// Loop through the tracks in the playlist
// Get the tracks from the fetched_tracks Map
const tracks = playlistInfo.fetched_tracks.get('1');
// Loop through the tracks in the playlist
for (const track of tracks) {
// save the first track in the queue
if (tracks.indexOf(track) === 0) {
firstTrack = await youtube.getStream(`${track.name} ${track.artists[0].name}`);
} else {
// Get a stream for the track using the youtube module
const song = await youtube.getStream(`${track.name} ${track.artists[0].name}`);
// Add the song to the music queue
musicQueue.addToQueue(guildId, song);
}
}
// Return null to indicate that a playlist was queued
return firstTrack;
}
// Handle single tracks as before
const trackInfo = await playdl.spotify(query); const trackInfo = await playdl.spotify(query);
return youtube.getStream(`${trackInfo.name} ${trackInfo.artists[0].name}`);
const searched = await play.search(`${trackInfo.name}`, {
limit: 1,
});
const stream = await play.stream(searched[0].url);
return stream;
} }
module.exports.getStream = getStream; module.exports.getStream = getStream;

View File

@@ -1,5 +1,8 @@
const ytsr = require('ytsr'); const ytsr = require('ytsr');
const playdl = require('play-dl'); const playdl = require('play-dl');
const ConsolerLogger = require('../utils/logger');
const logger = new ConsolerLogger();
async function getStream(query) { async function getStream(query) {
try { try {
@@ -35,7 +38,15 @@ async function getStream(query) {
: await playdl.video_info( : await playdl.video_info(
`https://www.youtube.com/watch?v=${videoId}`, `https://www.youtube.com/watch?v=${videoId}`,
); );
console.log('\x1b[36m', ' Id: ', videoId, 'Alternative search:', usingYtsr);
logger.info('Search request', { file: 'Youtube.JS',
Id: videoId,
alternativeSearch: usingYtsr,
length: usingYtsr
? infoResult.items[0].duration
: infoResult.video_details.durationInSec / 60,
SearchQuery: query });
return { return {
title: title:
(usingYtsr (usingYtsr
@@ -52,7 +63,7 @@ async function getStream(query) {
userInput: query, userInput: query,
}; };
} catch (error) { } catch (error) {
console.log('\x1b[31m', error); logger.error(error);
return null; return null;
} }
} }

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-console */
const play = require('play-dl'); const play = require('play-dl');
async function ReAuth() { async function ReAuth() {
@@ -8,7 +9,7 @@ async function ReAuth() {
}, },
}); });
console.log(`Soudncloud Client ID: ${clientID}`); console.log(`Soundcloud Client ID: ${clientID}`);
}); });
play.authorization(); play.authorization();

View File

@@ -14,7 +14,8 @@ async function getMusicStream(query) {
stream = await spotify.getStream(query); stream = await spotify.getStream(query);
songTitle = stream.title; songTitle = stream.title;
songDuration = stream.duration; songDuration = stream.duration;
stream = stream.stream; stream = stream?.stream;
type = StreamType.Opus;
} else if (query.includes('soundcloud.com')) { } else if (query.includes('soundcloud.com')) {
stream = await soundcloud.getStream(query); stream = await soundcloud.getStream(query);
songTitle = stream.title; songTitle = stream.title;

57
utils/logger.js Normal file
View File

@@ -0,0 +1,57 @@
/* eslint-disable no-console */
function loggerDate() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
class ConsolerLogger {
constructor() {
this.colors = {
info: '\x1b[36m%s\x1b[0m',
success: '\x1b[32m%s\x1b[0m',
warning: '\x1b[33m%s\x1b[0m',
error: '\x1b[31m%s\x1b[0m',
register: '\x1b[35m',
add: '\x1b[36m',
log: '\x1b[37m',
};
}
info(...messages) {
console.log(this.colors.info, loggerDate(), ...messages);
}
success(...messages) {
console.log(this.colors.success, loggerDate(), ...messages);
}
warning(...messages) {
console.log(this.colors.warning, loggerDate(), ...messages);
}
error(...messages) {
console.log(this.colors.error, loggerDate(), ...messages);
}
register(...messages) {
console.log(this.colors.register, loggerDate(), ...messages);
}
add(...messages) {
console.log(this.colors.add, loggerDate(), ...messages);
}
log(...messages) {
console.log(this.colors.log, loggerDate(), ...messages);
}
}
module.exports = ConsolerLogger;

View File

@@ -10,80 +10,23 @@ const process = require('dotenv').config();
const { clientId } = process.parsed; const { clientId } = process.parsed;
const { EmbedBuilder } = require('discord.js');
const musicQueue = require('../musicQueue'); const musicQueue = require('../musicQueue');
const { progressBar } = require('./progress'); const { nowPlayingMessage, intervalMap, currentInteractionIds } = require('./nowPlayingMessage');
const ConsolerLogger = require('./logger');
const currentInteractionIds = new Map();
const currentInteractions = new Map();
const oldConnections = []; const oldConnections = [];
const timeoutTimer = new Map(); const timeoutTimer = new Map();
const logger = new ConsolerLogger();
// TODO FIX THIS SHIT!!! ISSUES WITH DISPLAYING NAME AND STATUS WHEN UPDATING
function nowPLayingMessage(interaction, song, oldInteractionId) {
progressBar(0, 0, true);
if (interaction.commandName === 'play') {
interaction.followUp('~🎵~').then((message) => {
const songTitle = song.title;
// const embed = new EmbedBuilder()
// .setColor('#E0B0FF')
// .setTitle(`Now playing: ${songTitle}`)
// .setDescription(
// progressBar(song.duration, 10).progressBarString,
// );
const embed = new EmbedBuilder()
.setColor('#E0B0FF')
.setTitle(`Now playing: ${songTitle}`);
message.edit({
embeds: [embed],
});
const inter = setInterval(async () => {
const { progressBarString, isDone } = progressBar(
song.duration,
10,
);
if (isDone || message.id !== oldInteractionId) {
// clearInterval(inter);
return;
}
if (message.id != null && interaction.guild.id !== oldInteractionId) {
interaction.channel.messages.fetch().then(async (channel) => {
const filter = channel.filter((msg) => msg.author.id === clientId);
const latestMessage = await interaction.channel.messages.fetch(filter.first().id);
latestMessage.edit({
embeds: [embed.setTitle(`Now playing: ${songTitle}`)],
});
});
}
}, 2000);
currentInteractionIds.set(interaction.guild.id, interaction);
currentInteractions.set(interaction.guild.id, interaction.id);
});
}
}
async function musicPlayer(guildId, connection, interaction) { async function musicPlayer(guildId, connection, interaction) {
try { try {
const oldInteractions = await currentInteractions.get(interaction.guild.id);
const oldInteractionId = await currentInteractionIds.get(interaction.guild.id); const oldInteractionId = await currentInteractionIds.get(interaction.guild.id);
const serverQueue = musicQueue.getQueue(guildId); const serverQueue = musicQueue.getQueue(guildId);
const oldConnection = oldConnections const oldConnection = oldConnections
.find((guidConnection) => guidConnection[0] === interaction.guild.id); .find((guidConnection) => guidConnection[0] === interaction.guild.id);
if (serverQueue.length === 0) {
oldConnection[1].destroy();
}
const song = serverQueue[0]; const song = serverQueue[0];
if (song.stream === undefined) { if (!song || song.stream === undefined) {
musicQueue.removeFromQueue(guildId);
musicPlayer(guildId, connection);
return; return;
} }
@@ -97,30 +40,44 @@ async function musicPlayer(guildId, connection, interaction) {
}, },
}); });
player.play(resource); if (!resource.ended) {
player.play(resource);
} else {
logger.warning('Song ended prematurely.', song.title);
}
connection.subscribe(player); connection.subscribe(player);
nowPLayingMessage(interaction, song, oldInteractions); nowPlayingMessage(interaction, song);
oldConnections.push([interaction.guild.id, connection]); oldConnections.push([interaction.guild.id, connection]);
// Add an event listener for the Idle event of the audio player
player.on(AudioPlayerStatus.Idle, async () => { player.on(AudioPlayerStatus.Idle, async () => {
console.log('Song ended:', song.title); logger.info(`Song ended: ${song.title}`, 'Started by:', interaction.user.username);
if (serverQueue.length !== 1) { // Check if the audio resource has ended
await musicQueue.removeFromQueue(guildId); if (resource.ended) {
musicPlayer(guildId, connection, interaction); // If the audio resource has ended, play the next song
}
// timeoutTimer.set(guildId, setTimeout(async () => { if (serverQueue.length !== 0) {
// await musicQueue.removeFromQueue(guildId); await musicQueue.removeFromQueue(guildId);
// connection.destroy(); musicPlayer(guildId, connection, interaction);
// }, 10000)); logger.info(`Playing next song...${serverQueue}`);
} else {
// If there are no more songs in the queue, destroy the connection
connection.destroy();
logger.info('Connection destroyed.');
// Clear the interval for updating the progress bar
const interval = intervalMap.get(interaction.guild.id);
clearInterval(interval);
}
}
}); });
player.on(AudioPlayerStatus.Playing, () => { player.on(AudioPlayerStatus.Playing, () => {
console.log('pausing timer'); logger.info(`Playing: ${song.title}, Started by: ${interaction.user.username}`);
clearTimeout( clearTimeout(
logger.info('Previous song timer cleared.'),
timeoutTimer.get(guildId), timeoutTimer.get(guildId),
); );
}); });
@@ -130,13 +87,15 @@ async function musicPlayer(guildId, connection, interaction) {
const { lastMessage } = oldInteractionId.channel; const { lastMessage } = oldInteractionId.channel;
const filter = channel.filter((message) => message.author.id === clientId && message.id !== lastMessage.id); const filter = channel.filter((message) => message.author.id === clientId && message.id !== lastMessage.id);
setTimeout(() => { setTimeout(() => {
oldInteractionId.channel.bulkDelete(filter); logger.info('Removing old messages...');
oldInteractionId.channel.bulkDelete(filter)
.catch((error) => logger.error(error));
}, 1000); }, 1000);
}); });
} }
} catch (error) { } catch (error) {
console.error(error); logger.error(error);
interaction.followUp('There was an error playing the song.'); interaction.followUp('There was an error playing the song.', { ephemeral: true });
} }
} }

View File

@@ -0,0 +1,68 @@
const process = require('dotenv').config();
const { clientId } = process.parsed;
const { EmbedBuilder } = require('discord.js');
const { progressBar } = require('./progress');
const currentInteractionIds = new Map();
const currentInteractions = new Map();
const messageTimerMap = new Map();
const intervalMap = new Map(); // Add a new map to keep track of interval IDs
function nowPlayingMessage(interaction, song, prematureEnd = false) {
const timeoutIDs = messageTimerMap.get(interaction.guild.id);
if (timeoutIDs) {
timeoutIDs.forEach((timeoutID) => clearTimeout(timeoutID));
}
if (interaction.commandName === 'play') {
interaction.followUp('~🎵~').then((message) => {
const songTitle = song.title;
const embed = new EmbedBuilder()
.setColor('#E0B0FF')
.setTitle(`Now playing: ${songTitle}`)
.setDescription(
progressBar(song.duration, 10).progressBarString,
);
message.edit({
embeds: [embed],
});
const inter = setInterval(async () => {
const messageString = progressBar(
song.duration,
10,
);
if (message.id != null) {
interaction.channel.messages.fetch().then(async (channel) => {
const filter = channel.filter((msg) => msg.author.id === clientId);
const latestMessage = await interaction.channel.messages.fetch(filter.first().id);
latestMessage.edit({
embeds: [embed.setDescription(messageString.progressBarString)],
});
});
}
}, 1000);
// Store the interval ID in the intervalMap
intervalMap.set(interaction.guild.id, inter);
// Store the timeoutID in an array associated with the key
if (!messageTimerMap.has(interaction.guild.id) || !prematureEnd) {
messageTimerMap.set(interaction.guild.id, []);
}
messageTimerMap.get(interaction.guild.id).push(inter);
progressBar(0, 0, true);
currentInteractionIds.set(interaction.guild.id, interaction);
currentInteractions.set(interaction.guild.id, interaction.id);
});
}
}
module.exports.nowPlayingMessage = nowPlayingMessage;
module.exports.intervalMap = intervalMap;
module.exports.currentInteractionIds = currentInteractionIds;

View File

@@ -30,8 +30,9 @@ const progressBar = (totalInMilliseconds, size, reset = false) => {
totalTimeText = totalTimeText.slice(3); totalTimeText = totalTimeText.slice(3);
} }
const progressBarString = `${elapsedTimeText} \`\`\`${progressText}${emptyProgressText}\`\`\` ${totalTimeText}`; // Creating and returning the bar const progressBarString = `${elapsedTimeText} \`${progressText}${emptyProgressText}\` ${totalTimeText}`; // Creating and returning the bar
return { progressBarString, isDone: percentage === 1 }; return { progressBarString, isDone: percentage === 1 };
}; };
module.exports.progressBar = progressBar; module.exports.progressBar = progressBar;

View File

@@ -1,6 +1,9 @@
const { SlashCommandBuilder } = require('@discordjs/builders'); const { SlashCommandBuilder } = require('@discordjs/builders');
const { REST } = require('@discordjs/rest'); const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9'); const { Routes } = require('discord-api-types/v9');
const ConsolerLogger = require('./logger');
const logger = new ConsolerLogger();
async function registerCommands(clientId, token) { async function registerCommands(clientId, token) {
const commands = [ const commands = [
@@ -32,6 +35,15 @@ async function registerCommands(clientId, token) {
new SlashCommandBuilder() new SlashCommandBuilder()
.setName('stop') .setName('stop')
.setDescription('Stops the current song!'), .setDescription('Stops the current song!'),
new SlashCommandBuilder()
.setName('skip')
.setDescription('Skips the current song!'),
new SlashCommandBuilder()
.setName('leave')
.setDescription('Leaves the voice channel!'),
new SlashCommandBuilder()
.setName('previous')
.setDescription('Plays the previous song!'),
]; ];
const rest = new REST({ const rest = new REST({
@@ -40,15 +52,15 @@ async function registerCommands(clientId, token) {
.setToken(token); .setToken(token);
try { try {
console.log('\x1b[35m', 'Started refreshing application (/) commands.'); logger.register('Started refreshing application (/) commands.');
await rest.put(Routes.applicationCommands(clientId), { await rest.put(Routes.applicationCommands(clientId), {
body: commands, body: commands,
}); });
console.log('\x1b[35m', 'Successfully reloaded application (/) commands.'); logger.register('Successfully reloaded application (/) commands.');
} catch (error) { } catch (error) {
console.error(error); logger.error('Failed to reload application (/) commands.');
} }
} }

8
utils/setStatus.js Normal file
View File

@@ -0,0 +1,8 @@
const { botClient } = require('../index');
async function setStatus(status) {
await botClient.user.setActivity(status);
}
module.exports.setStatus = setStatus;
module.exports.setStatus = setStatus;