aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--backend/AudioControl.js19
-rw-r--r--backend/PlayAudio.js2
-rw-r--r--backend/VoiceInitialization.js2
-rw-r--r--bot.js9
-rw-r--r--commands/next.js12
-rw-r--r--commands/pause.js2
-rw-r--r--commands/previous.js8
-rw-r--r--commands/reshuffle.js2
-rw-r--r--commands/status.js4
-rw-r--r--package.json1
-rw-r--r--yarn.lock19
12 files changed, 60 insertions, 22 deletions
diff --git a/README.md b/README.md
index 6f46bb5..4dcd8aa 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,10 @@ Make a new file called `config.json`.
"token": "token_here",
"txtFile": true/false,
"shuffle": true/false,
+ "repeat": true/false,
"statusChannel": "channel_id",
"voiceChannel": "voice_channel_id",
+ "presenceActivity": "activity_here",
"clientID": "client_id"
}
```
diff --git a/backend/AudioControl.js b/backend/AudioControl.js
index 71952c1..2b314d2 100644
--- a/backend/AudioControl.js
+++ b/backend/AudioControl.js
@@ -22,20 +22,31 @@ import { readdirSync, readFileSync } from 'node:fs';
import { shufflePlaylist, orderPlaylist } from './QueueSystem.js';
import { playAudio, currentTrack, updatePlaylist } from './PlayAudio.js';
import { player } from './VoiceInitialization.js';
+import { destroyAudio } from './Shutdown.js';
-const { shuffle } = JSON.parse(readFileSync('./config.json', 'utf-8'));
+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) {
totalTrack--;
if (currentTrack >= totalTrack) {
- console.log('All beats in the playlist has finished, repeating beats...');
- totalTrack = files.length;
- return (shuffle === true) ? await shufflePlaylist(bot) : await orderPlaylist(bot);
+ await repeatCheck(bot);
} else {
updatePlaylist('next');
return await playAudio(bot);
diff --git a/backend/PlayAudio.js b/backend/PlayAudio.js
index 3ae2b91..d698798 100644
--- a/backend/PlayAudio.js
+++ b/backend/PlayAudio.js
@@ -77,7 +77,7 @@ export async function playAudio(bot) {
}
const statusEmbed = new EmbedBuilder();
- if (metadataEmpty === true) {
+ if (metadataEmpty) {
statusEmbed.setTitle('Now Playing');
statusEmbed.addFields(
{ name: 'Title', value: audio },
diff --git a/backend/VoiceInitialization.js b/backend/VoiceInitialization.js
index d95bfa6..a9e1149 100644
--- a/backend/VoiceInitialization.js
+++ b/backend/VoiceInitialization.js
@@ -39,7 +39,7 @@ export async function voiceInit(bot) {
connection.on(VoiceConnectionStatus.Ready, async() => {
console.log('Ready to blast some beats!');
- return (shuffle === true) ? await shufflePlaylist(bot) : await orderPlaylist(bot);
+ return (shuffle) ? await shufflePlaylist(bot) : await orderPlaylist(bot);
});
connection.on(VoiceConnectionStatus.Destroyed, () => {
diff --git a/bot.js b/bot.js
index c53d40f..ef01d55 100644
--- a/bot.js
+++ b/bot.js
@@ -22,7 +22,7 @@ import { Client, GatewayIntentBits, EmbedBuilder, Collection, version, Interacti
import { voiceInit } from './backend/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, presenceActivity } = JSON.parse(readFileSync('./config.json', 'utf-8'));
+const { token, statusChannel, voiceChannel, shuffle, repeat, presenceActivity } = JSON.parse(readFileSync('./config.json', 'utf-8'));
const bot = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates] });
bot.login(token);
@@ -49,6 +49,7 @@ bot.once('ready', async() => {
console.log(`Voice Channel: ${voiceChannel}`);
console.log(`Status Channel: ${statusChannel}`);
console.log(`Shuffle Enabled: ${shuffle}`);
+ console.log(`Repeat Enabled: ${repeat}`);
// Set bots' presence
bot.user.setPresence({
@@ -86,10 +87,6 @@ bot.on('interactionCreate', async interaction => {
await command.execute(interaction, bot);
} catch (e) {
console.error(e);
- if (e == null) {
- await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
- } else {
- await interaction.reply({ content: `There was an error while executing this command!\nShare this to the bot owner!\n\nDetails:\`\`\`${e}\`\`\``, ephemeral: true });
- }
+ await interaction.reply({ content: `There was an error while executing this command!\nShare this to the bot owner!\n\nDetails:\`\`\`${e}\`\`\``, ephemeral: true });
}
});
diff --git a/commands/next.js b/commands/next.js
index 88dac40..759c5bb 100644
--- a/commands/next.js
+++ b/commands/next.js
@@ -21,7 +21,7 @@
import { SlashCommandBuilder } from 'discord.js';
import { player } from '../backend/VoiceInitialization.js';
-import { nextAudio } from '../backend/AudioControl.js';
+import { nextAudio, playerState } from '../backend/AudioControl.js';
import { PermissionFlagsBits } from 'discord-api-types/v10';
export default {
@@ -31,8 +31,12 @@ export default {
.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: 'Playing next music', ephemeral: true });
- player.stop();
- return await nextAudio(bot);
+ 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
index c467675..61b9e21 100644
--- a/commands/pause.js
+++ b/commands/pause.js
@@ -30,7 +30,7 @@ export default {
.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 === false) {
+ if (!isAudioStatePaused) {
toggleAudioState();
return await interaction.reply({ content: 'Pausing music', ephemeral: true });
} else {
diff --git a/commands/previous.js b/commands/previous.js
index 66c1930..ebedbb6 100644
--- a/commands/previous.js
+++ b/commands/previous.js
@@ -20,7 +20,7 @@
***************************************************************************/
import { SlashCommandBuilder } from 'discord.js';
-import { previousAudio } from '../backend/AudioControl.js';
+import { playerState, previousAudio } from '../backend/AudioControl.js';
import { PermissionFlagsBits } from 'discord-api-types/v10';
export default {
@@ -30,6 +30,10 @@ export default {
.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 });
- return await previousAudio(bot, interaction);
+ 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
index f60bb1c..e1d37d0 100644
--- a/commands/reshuffle.js
+++ b/commands/reshuffle.js
@@ -39,6 +39,6 @@ export default {
await audioState(2);
await shufflePlaylist(bot);
}
- return (shuffle === true) ? await shuffleDetected(bot) : await interaction.reply({ content: 'Shuffle mode is disabled, enable it in the configuration file to access this command.', ephemeral: true });
+ 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/status.js b/commands/status.js
index cf49509..d19e4ac 100644
--- a/commands/status.js
+++ b/commands/status.js
@@ -38,7 +38,7 @@ export default {
if (audioName === undefined) {
audioName = 'Playlist Finished';
} else {
- if (metadataEmpty === false) {
+ if (!metadataEmpty) {
try {
const { common } = await parseFile('music/' + audioName);
audioName = common.title;
@@ -59,7 +59,7 @@ export default {
)
.setColor('#0066ff');
- if (metadataEmpty === true) {
+ if (metadataEmpty) {
controlEmbed.addFields(
{ name: 'Currently Playing', value: audio },
{ name: 'Up Next', value: audioName }
diff --git a/package.json b/package.json
index 71ad367..aeb0672 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"discord-api-types": "^0.37.15",
"discord.js": "^14.6.0",
"ffmpeg-static": "^5.1.0",
+ "i18next": "^22.0.6",
"music-metadata": "^8.1.0",
"sodium": "^3.0.2"
},
diff --git a/yarn.lock b/yarn.lock
index 1d37b27..20807be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,13 @@
# yarn lockfile v1
+"@babel/runtime@^7.17.2":
+ version "7.20.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3"
+ integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
+ dependencies:
+ regenerator-runtime "^0.13.11"
+
"@derhuerst/http-basic@^8.2.0":
version "8.2.4"
resolved "https://registry.yarnpkg.com/@derhuerst/http-basic/-/http-basic-8.2.4.tgz#d021ebb8f65d54bea681ae6f4a8733ce89e7f59b"
@@ -981,6 +988,13 @@ 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==
+ dependencies:
+ "@babel/runtime" "^7.17.2"
+
ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
@@ -1526,6 +1540,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
+regenerator-runtime@^0.13.11:
+ version "0.13.11"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
+ integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
+
regexp.prototype.flags@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"