diff options
| author | Andrew Lee <alee14498@protonmail.com> | 2022-12-20 17:54:56 -0500 |
|---|---|---|
| committer | Andrew Lee <alee14498@protonmail.com> | 2022-12-20 18:05:51 -0500 |
| commit | e5c86859e4c6a9a6829bcc2e3cf626b05a873ff7 (patch) | |
| tree | 96c04baa3f064a160a595a0faf73696cc5cf8eaa /Commands | |
| parent | 239b254760381946f57d6cbccb077f5341ca2f30 (diff) | |
| download | DLAP-e5c86859e4c6a9a6829bcc2e3cf626b05a873ff7.tar.gz DLAP-e5c86859e4c6a9a6829bcc2e3cf626b05a873ff7.tar.bz2 DLAP-e5c86859e4c6a9a6829bcc2e3cf626b05a873ff7.zip | |
Revamped next/previous cmds (Voting system); Basic i18n support;
Diffstat (limited to 'Commands')
| -rw-r--r-- | Commands/join.js | 7 | ||||
| -rw-r--r-- | Commands/leave.js | 9 | ||||
| -rw-r--r-- | Commands/list.js | 3 | ||||
| -rw-r--r-- | Commands/next.js | 20 | ||||
| -rw-r--r-- | Commands/pause.js | 10 | ||||
| -rw-r--r-- | Commands/play.js | 10 | ||||
| -rw-r--r-- | Commands/previous.js | 16 | ||||
| -rw-r--r-- | Commands/reshuffle.js | 7 | ||||
| -rw-r--r-- | Commands/shutdown.js | 8 | ||||
| -rw-r--r-- | Commands/status.js | 27 |
10 files changed, 70 insertions, 47 deletions
diff --git a/Commands/join.js b/Commands/join.js index 739ebba..2649784 100644 --- a/Commands/join.js +++ b/Commands/join.js @@ -22,14 +22,17 @@ import { SlashCommandBuilder } from 'discord.js'; import { voiceInit } from '../AudioBackend/VoiceInitialization.js'; import { PermissionFlagsBits } from 'discord-api-types/v10'; +import { readFileSync } from 'node:fs'; +const { djRole, ownerID } = JSON.parse(readFileSync('./config.json', 'utf-8')); export default { data: new SlashCommandBuilder() .setName('join') - .setDescription('Joins voice chat') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + .setDescription('Joins voice chat'), 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 (!interaction.member.roles.cache.has(djRole) && interaction.user.id !== ownerID && !interaction.member.permission.has(PermissionFlagsBits.ManageGuild)) return interaction.reply({ content: 'You need a specific role to execute 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 index cea791a..5d01822 100644 --- a/Commands/leave.js +++ b/Commands/leave.js @@ -22,14 +22,17 @@ import { SlashCommandBuilder } from 'discord.js'; import { destroyAudio } from '../AudioBackend/Shutdown.js'; import { PermissionFlagsBits } from 'discord-api-types/v10'; +import { readFileSync } from 'node:fs'; +const { djRole, ownerID } = JSON.parse(readFileSync('./config.json', 'utf-8')); export default { data: new SlashCommandBuilder() .setName('leave') - .setDescription('Leaves the voice chat') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction) { + .setDescription('Leaves the voice chat'), + 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 (!interaction.member.roles.cache.has(djRole) && interaction.user.id !== ownerID && !interaction.member.permission.has(PermissionFlagsBits.ManageGuild)) return interaction.reply({ content: 'You need a specific role to execute 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 index 176ae61..90d3cc6 100644 --- a/Commands/list.js +++ b/Commands/list.js @@ -18,6 +18,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. * ***************************************************************************/ + import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import { readdir } from 'node:fs'; @@ -38,7 +39,7 @@ export default { 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 pageSize = 20; // 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 }); diff --git a/Commands/next.js b/Commands/next.js index d3240cf..f082c89 100644 --- a/Commands/next.js +++ b/Commands/next.js @@ -20,23 +20,21 @@ ***************************************************************************/ 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'; +import { voteSkip } from '../Utilities/Voting.js'; export default { data: new SlashCommandBuilder() .setName('next') .setDescription('Goes to next music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + .addSubcommand(subcommand => + subcommand.setName('vote') + .setDescription('Voting to skip this audio track')) + .addSubcommand(subcommand => + subcommand.setName('force') + .setDescription('Forces skip this audio track')), + 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 }); - } + await voteSkip(interaction, bot); } }; diff --git a/Commands/pause.js b/Commands/pause.js index e461a4c..51376cd 100644 --- a/Commands/pause.js +++ b/Commands/pause.js @@ -22,14 +22,16 @@ import { SlashCommandBuilder } from 'discord.js'; import { toggleAudioState, isAudioStatePaused } from '../AudioBackend/AudioControl.js'; import { PermissionFlagsBits } from 'discord-api-types/v10'; - +import { readFileSync } from 'node:fs'; +const { djRole } = JSON.parse(readFileSync('./config.json', 'utf-8')); export default { data: new SlashCommandBuilder() .setName('pause') - .setDescription('Pauses music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), - async execute(interaction) { + .setDescription('Pauses music'), + 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 (!interaction.member.roles.cache.has(djRole) && interaction.user.id !== ownerID && !interaction.member.permission.has(PermissionFlagsBits.ManageGuild)) return interaction.reply({ content: 'You need a specific role to execute this command', ephemeral: true }); + if (!isAudioStatePaused) { toggleAudioState(); return await interaction.reply({ content: 'Pausing music', ephemeral: true }); diff --git a/Commands/play.js b/Commands/play.js index a0af3f3..49f0d3e 100644 --- a/Commands/play.js +++ b/Commands/play.js @@ -24,6 +24,10 @@ 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'; +import { readFileSync } from 'node:fs'; +import { votes } from '../Utilities/Voting.js'; + +const { djRole, ownerID } = JSON.parse(readFileSync('./config.json', 'utf-8')); export let integer; @@ -34,15 +38,17 @@ export default { .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 }); + if (!interaction.member.roles.cache.has(djRole) && interaction.user.id !== ownerID && !interaction.member.permission.has(PermissionFlagsBits.ManageGuild)) return interaction.reply({ content: 'You need a specific role to execute this command', ephemeral: true }); + integer = interaction.options.getInteger('int'); if (integer) { if (integer < files.length) { await inputAudio(bot, integer); + await votes.clear(); 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 }); diff --git a/Commands/previous.js b/Commands/previous.js index dd79a98..aa732b2 100644 --- a/Commands/previous.js +++ b/Commands/previous.js @@ -20,20 +20,20 @@ ***************************************************************************/ import { SlashCommandBuilder } from 'discord.js'; -import { playerState, previousAudio } from '../AudioBackend/AudioControl.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; +import { voteSkip } from '../Utilities/Voting.js'; export default { data: new SlashCommandBuilder() .setName('previous') .setDescription('Goes to previous music') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + .addSubcommand(subcommand => + subcommand.setName('vote') + .setDescription('Voting to skip this audio track')) + .addSubcommand(subcommand => + subcommand.setName('force') + .setDescription('Forces skip this audio track')), 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 }); - } + await voteSkip(interaction, bot); } }; diff --git a/Commands/reshuffle.js b/Commands/reshuffle.js index f3e70c2..340c91b 100644 --- a/Commands/reshuffle.js +++ b/Commands/reshuffle.js @@ -25,15 +25,16 @@ 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')); +const { shuffle, djRole, ownerID } = JSON.parse(readFileSync('./config.json', 'utf-8')); export default { data: new SlashCommandBuilder() .setName('reshuffle') - .setDescription('Reshuffles the playlist') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + .setDescription('Reshuffles the playlist'), 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 (!interaction.member.roles.cache.has(djRole) && interaction.user.id !== ownerID && !interaction.member.permission.has(PermissionFlagsBits.ManageGuild)) return interaction.reply({ content: 'You need a specific role to execute this command', ephemeral: true }); + async function shuffleDetected(bot) { await interaction.reply({ content: 'Reshuffling the playlist...', ephemeral: true }); await audioState(2); diff --git a/Commands/shutdown.js b/Commands/shutdown.js index d97922c..eefbab3 100644 --- a/Commands/shutdown.js +++ b/Commands/shutdown.js @@ -21,14 +21,14 @@ import { SlashCommandBuilder } from 'discord.js'; import { stopBot } from '../AudioBackend/Shutdown.js'; -import { PermissionFlagsBits } from 'discord-api-types/v10'; - +import { readFileSync } from 'node:fs'; +const { ownerID } = JSON.parse(readFileSync('./config.json', 'utf-8')); export default { data: new SlashCommandBuilder() .setName('shutdown') - .setDescription('Powers off the bot') - .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), + .setDescription('Powers off the bot'), async execute(interaction, bot) { + if (interaction.user.id !== ownerID) return interaction.reply({ content: 'You need to be the creator of this bot to execute this command', ephemeral: true }); await interaction.reply({ content: 'Powering off...', ephemeral: true }); return await stopBot(bot, interaction); } diff --git a/Commands/status.js b/Commands/status.js index fc1229d..bf88772 100644 --- a/Commands/status.js +++ b/Commands/status.js @@ -23,6 +23,7 @@ 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'; +import { votes } from '../Utilities/Voting.js'; export default { data: new SlashCommandBuilder() @@ -33,11 +34,19 @@ export default { let audioID = currentTrack; audioID++; - let audioName = files[audioID]; + let audioName; - if (audioName === undefined) { + // Get the members of the voice channel who have not voted yet + const voiceChannel = interaction.member.voice.channel; + const members = voiceChannel.members.filter(m => !votes.has(m.id)); + + // Calculate the number of votes required to skip the audio track + const votesRequired = Math.ceil(members.size / 2); + + if (audioID >= files.length) { audioName = 'Playlist Finished'; } else { + audioName = files[audioID]; if (!metadataEmpty) { try { const { common } = await parseFile('music/' + audioName); @@ -53,22 +62,22 @@ export default { const controlEmbed = new EmbedBuilder() .setAuthor({ name: `${bot.user.username} Status`, iconURL: bot.user.avatarURL() }) .addFields( - { name: 'State', value: playerState }, + { name: 'State', value: `${playerState}` }, { name: 'Tracks', value: `${audioID}/${files.length}` }, - { name: 'Duration', value: duration } - // { name: 'Session Uptime', value: `` } + { name: 'Duration', value: `${duration}` }, + { name: 'Votes Needed', value: `${votesRequired}` } ) .setColor('#0066ff'); if (metadataEmpty) { controlEmbed.addFields( - { name: 'Currently Playing', value: audio }, - { name: 'Up Next', value: audioName } + { name: 'Currently Playing', value: `${audio}` }, + { name: 'Up Next', value: `${audioName}` } ); } else { controlEmbed.addFields( - { name: 'Currently Playing', value: audioTitle }, - { name: 'Up Next', value: audioName } + { name: 'Currently Playing', value: `${audioTitle}` }, + { name: 'Up Next', value: `${audioName}` } ); } interaction.reply({ embeds: [controlEmbed] }); |
