DZ-Musicbot/utils/queueManager.js

124 lines
3.6 KiB
JavaScript

const { createAudioPlayer, createAudioResource, AudioPlayerStatus, joinVoiceChannel } = require('@discordjs/voice');
const fs = require('fs');
const queueMap = new Map();
const playerMap = new Map();
const currentTrackMap = new Map();
const repeatMap = new Map();
function addToQueue(guildId, filePath, title) {
if (!queueMap.has(guildId)) {
queueMap.set(guildId, []);
}
queueMap.get(guildId).push({ filePath, title });
}
function getQueue(guildId) {
return queueMap.get(guildId) || [];
}
function getCurrentTrack(guildId) {
return currentTrackMap.get(guildId) || null;
}
function toggleRepeat(guildId) {
const currentRepeat = repeatMap.get(guildId) || false;
repeatMap.set(guildId, !currentRepeat);
return !currentRepeat;
}
function playNextInQueue(guildId, voiceChannel) {
const queue = getQueue(guildId);
let currentTrack = getCurrentTrack(guildId);
const repeat = repeatMap.get(guildId);
if (currentTrack && repeat) {
playTrack(guildId, voiceChannel, currentTrack);
return;
}
if (queue.length === 0 && !repeat) {
const connection = playerMap.get(guildId)?._state?.subscription?.connection;
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
return false;
}
if (queue.length > 0) {
currentTrack = queue.shift();
currentTrackMap.set(guildId, currentTrack);
playTrack(guildId, voiceChannel, currentTrack);
}
}
function playTrack(guildId, voiceChannel, track) {
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: guildId,
adapterCreator: voiceChannel.guild.voiceAdapterCreator,
});
const audioPlayer = playerMap.get(guildId) || createAudioPlayer();
playerMap.set(guildId, audioPlayer);
if (!fs.existsSync(track.filePath)) {
console.error('Audio file not found:', track.filePath);
return false;
}
const resource = createAudioResource(track.filePath);
audioPlayer.play(resource);
connection.subscribe(audioPlayer);
audioPlayer.on(AudioPlayerStatus.Idle, () => {
if (!repeatMap.get(guildId)) {
currentTrackMap.delete(guildId);
fs.unlink(track.filePath, (err) => {
if (err) console.error('Error deleting file:', track.filePath, err);
});
}
const queue = getQueue(guildId);
if (queue.length > 0 || repeatMap.get(guildId)) {
playNextInQueue(guildId, voiceChannel);
} else {
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
}
});
audioPlayer.on('error', (err) => {
console.error('AudioPlayer error:', err);
currentTrackMap.delete(guildId);
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
});
}
function skipTrack(guildId, voiceChannel) {
const player = playerMap.get(guildId);
const queue = getQueue(guildId);
if (!player) {
console.error('No player found for this guild.');
return;
}
currentTrackMap.delete(guildId);
player.stop();
if (queue.length > 0) {
playNextInQueue(guildId, voiceChannel);
} else {
const connection = playerMap.get(guildId)?._state?.subscription?.connection;
if (connection && connection.state.status !== 'destroyed') {
connection.destroy();
}
}
}
module.exports = { addToQueue, getQueue, getCurrentTrack, playNextInQueue, skipTrack, toggleRepeat };