提问者:小点点

Discord.jsvoiceStateUpdate客户端语音通道在机器人移动或断开连接时不更新?


我正在使用 voiceStateUpdate 事件来跟踪我的不和谐机器人正在哪个语音频道中播放音乐。如果机器人单独放置 5 分钟,它应该断开连接并销毁音乐播放器。这主要工作了最长的时间。

最近,主持人断开了机器人与语音通道的连接。我注意到机器人继续发布它正在播放新歌曲。经过测试,我发现不仅断开机器人的连接会导致这种情况,而且将机器人拖到新通道也是如此。

通过一些控制台日志记录,我发现将机器人拖动到新通道不会更新无效通道 ID。 断开机器人与语音通道的连接显示为机器人“移动”通道,但语音通道 ID 是相同的。

const { getVoiceConnection } = require('@discordjs/voice');

module.exports = (client, voiceStateStart, voiceStateEnd) => {
    const startChannel = voiceStateStart.channelId;
    const endChannel = voiceStateEnd.channelId;
    const guildID = voiceStateEnd.guild.id;

    if (!startChannel && endChannel) {                              //If user joins a channel
        if (voiceStateEnd.id == client.user.id) {                   //If the user is the bot
            console.log(`Bot join: ${startChannel}\n${endChannel}`)
            if (!channelFind(endChannel))                           //Check if VC is in voiceChannels array
                voiceChannels.push({ channelID: endChannel, users: getSize(client, endChannel) }); //Push VC to voiceChannels array
        } else {                                                    //If user is not the bot
            console.log(`User join: \n${startChannel}\n${endChannel}`)
            if (channelFind(endChannel))                            //Check if joined VC is in voiceChannels array
                channelFind(endChannel).users += 1;                 //Update user count
        }
    } else if (startChannel && !endChannel) {                       //If user disconnects
        if (voiceStateStart.id == client.user.id) {                 //If the user is the bot
            console.log(`Bot left: \n${startChannel}\n${endChannel}`)
            const player = client.music.players.get(guildID);       //Find guild player
            if (player) client.music.players.get(guildID).destroy();//Destroy player
            if (channelFind(startChannel))                          //Check if VC is in voiceChannels array
                channelsSplice(startChannel)                        //Splice out VC from voiceChannels array                                                
        } else {
            console.log(`User left: \n${startChannel}\n${endChannel}`)
            if (channelFind(startChannel))                          //Check if VC is in voiceChannels array
                channelFind(startChannel).users -= 1;               //Update user count
        }
    } else if (startChannel && endChannel) {                        //If user moves
        if (voiceStateStart.id == client.user.id && startChannel) { //If the user is the bot
            const player = client.music.players.get(guildID);       //Find guild player
            if (player && !player.playing)                          //If player is paused
                player.pause(player.playing);                       //Resume player
            if (channelFind(startChannel)) {                        //Check if VC is in voiceChannels array
                console.log(`Bot moved: \n${startChannel}\n${endChannel}`);
                channelsSplice(startChannel);                       //Splice out VC from voiceChannels array
            }
            voiceChannels.push({ channelID: endChannel, users: getSize(client, endChannel) })//Push VC to voiceChannels array
        } else {                                                    //Update user count on both start and end channel
            console.log(`User moved: \n${startChannel}\n${endChannel}`);
            if (channelFind(startChannel))
                channelFind(startChannel).users = getSize(client, startChannel);//Update startChannel user count in voiceChannels array
            else if (channelFind(endChannel))
                channelFind(endChannel).users = getSize(client, endChannel);    //Update endChannel user count in voiceChannels array
        }
    }
    checkUsers(client); //Start check for if bot is left inactive
}

//Get size of voice channel
function getSize(client, channel) {
    if (client.channels.cache.get(channel)) {
        return client.channels.cache.get(channel).members.size;
    } else return 0;
}

//Find voice channel in voiceChannels array
function channelFind(channelID) {
    return voiceChannels.filter(channel => channel.channelID == channelID)
}

//Remove voice channel from Channels array
function channelsSplice(channelID) {
    voiceChannels.splice(voiceChannels.findIndex(channel => channel.channelID === channelID), 1)
}

//Check for if 0 user
function checkUsers(client) {
    voiceChannels.forEach(channel => {
        if (channel.users <= 1)
            checkDisconnect(client, channel.channelID);
    });
}

//Recheck after interval for 0 users, if user joins back, restart time, else disconnect bot and player
function checkDisconnect(client, channelID) {
    let disconnectChannel = setTimeout(() => {
        clearInterval(intervalCheck);
        disconnect(client, channelID);
    }, 300000); //5 minutes == 300000
    let intervalCheck = setInterval(() => {
        var size = getSize(client, channelID)
        if (size > 1) {
            clearInterval(intervalCheck);
            clearTimeout(disconnectChannel)
        }
    }, 1000);
}

//Disconnect bot and player
function disconnect(client, channelID) {
    if (voiceChannels.filter(channel => channel.channelID == channelID)) {
        if (voiceChannels.filter(channel => channel.channelID == channelID).users <= 1) {
            const player = client.music.players.get(guildID);
            if (player) client.music.players.get(guildID).destroy();
            else getVoiceConnection(guildID).disconnect();
            if (channelsSome(channelID)) channelsSplice(channelID)
        }
    }
}
User join: 
null - Start Channel ID
1025940884321206302 - End Channel ID
Bot join: null - Start Channel ID
1025940884321206302 - End Channel ID
User moved: 
1025940884321206302 - Start Channel ID
1026191047937773690 - End Channel ID
Bot moved: 
1025940884321206302 - Start Channel ID
1025940884321206302 - End Channel ID
User moved: 
1026191047937773690 - Start Channel ID
1025940884321206302 - End Channel ID
Bot moved: 
1025940884321206302 - Start Channel ID
1025940884321206302 - End Channel ID
User left: 
1025940884321206302 - Start Channel ID
null - End Channel ID
Bot moved: 
1025940884321206302 - Start Channel ID
1025940884321206302 - End Channel ID

上述日志记录中的操作:

User joins VC
Bot joins VC
User moves VC
Bot dragged into VC (first error, no voice channel ID change)
User moves VC
Bot dragged into VC (second error, no voice channel ID change)
User disconnects VC
Bot disconnected from VC (third error, End Channel ID should be null)

共1个答案

匿名用户

奇怪的是,我以前从未见过这个…package.json显示我使用的是最新的erela.js版本^2.4.0(我一直在确保这一点,因为我看到了许多类似的错误,但已修复了较新版本)。在挖掘之后,不知何故,软件包安装损坏了。重复文件,新代码/文件和过时的代码/文件……简单删除node-模块文件夹并清理npm install解决了这个问题。