mirror of
https://github.com/aydenjahola/discord-multipurpose-bot.git
synced 2025-09-21 06:41:35 +01:00
Some checks are pending
Docker / build (push) Waiting to run
* add simple music functionality * update workflow * update Dockerfile * update Dockerfile * update Dockerfile * update Dockerfile * add few more music commands * add lyrics command * update lyrics command * add loop, and add categories to all commands * change discord status * seperate distube and change startup console theme * Update README * UPDATE LICENSE file * fix docker compose image, add better error handling for distube and update tagging workflow * switch to node-alpine image for docker * switch to node-alpine image for docker * update ascii * music commands imporvements, implement live lyrics, some guards and bot leaving on empty * use ffmpeg package rather than ffmpeg-static
79 lines
2.5 KiB
JavaScript
79 lines
2.5 KiB
JavaScript
const { SlashCommandBuilder } = require("discord.js");
|
|
const { requireVC, requireQueue } = require("../../utils/musicGuards");
|
|
|
|
function fisherYates(arr) {
|
|
for (let i = arr.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName("shuffle")
|
|
.setDescription("Shuffles the up-next songs (keeps the current track).")
|
|
.addIntegerOption((o) =>
|
|
o
|
|
.setName("amount")
|
|
.setDescription(
|
|
"Only shuffle the first N upcoming songs (default: all)."
|
|
)
|
|
.setMinValue(2)
|
|
),
|
|
category: "Music",
|
|
|
|
async execute(interaction, client) {
|
|
try {
|
|
await interaction.deferReply();
|
|
|
|
requireVC(interaction);
|
|
const queue = requireQueue(client, interaction);
|
|
|
|
const total = queue.songs.length;
|
|
if (total <= 2) {
|
|
// 0 or 1 upcoming track is not worth shuffling
|
|
return interaction.followUp({
|
|
content: "❌ Not enough songs to shuffle.",
|
|
ephemeral: true,
|
|
});
|
|
}
|
|
|
|
const upcoming = queue.songs.slice(1); // exclude the currently playing track
|
|
const amountOpt = interaction.options.getInteger("amount");
|
|
const amount = Math.min(
|
|
Math.max(amountOpt ?? upcoming.length, 2),
|
|
upcoming.length
|
|
);
|
|
|
|
// If user didn't specify an amount, prefer DisTube's built-in shuffle
|
|
if (amountOpt == null && typeof queue.shuffle === "function") {
|
|
// DisTube's shuffle shuffles upcoming by default (keeps current)
|
|
queue.shuffle();
|
|
return interaction.followUp(
|
|
`🔀 Shuffled **${upcoming.length}** upcoming track(s)!`
|
|
);
|
|
}
|
|
|
|
// Manual partial shuffle (first N upcoming)
|
|
const head = upcoming.slice(0, amount);
|
|
const tail = upcoming.slice(amount);
|
|
fisherYates(head);
|
|
|
|
// Splice back into queue: [ current, ...shuffledHead, ...tail ]
|
|
queue.songs.splice(1, amount, ...head);
|
|
// tail is already in place so no need to modify if amount === upcoming.length
|
|
|
|
return interaction.followUp(
|
|
`🔀 Shuffled the next **${amount}** track(s).`
|
|
);
|
|
} catch (e) {
|
|
console.error("shuffle command failed:", e);
|
|
const msg = e?.message || "❌ Failed to shuffle the queue.";
|
|
if (interaction.deferred || interaction.replied) {
|
|
return interaction.followUp({ content: msg, ephemeral: true });
|
|
}
|
|
return interaction.reply({ content: msg, ephemeral: true });
|
|
}
|
|
},
|
|
};
|