skick1234 / DisTube

A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.
https://distube.js.org
MIT License
422 stars 95 forks source link

<DisTube>.voices.join() not working properly with multi client! #246

Closed Majoramari closed 2 years ago

Majoramari commented 2 years ago

If you have 2 clients, fetched voice channel in client one and try to join it in client two, client one will join. <Player>.voices.join(voiceChannel) this is the result of using the channel object here: (commit)... Potential fix is to fetch the channel again internally or just accept channel id as an argument.

Further information:

skick1234 commented 2 years ago

You have to use multiple instances of DisTube. 1 per client

Majoramari commented 2 years ago

You have to use multiple instances of DisTube per client

I'm using one for each, how exactly? should I initialize all DisTube in one client or something?

skick1234 commented 2 years ago

You have to use multiple instances of DisTube per client

I'm using one for each, how exactly? should I initialize all DisTube in one client or something?

Hmmm... It's weird. I tested with 2 clients, one per client and it works normally. Make sure your voiceChannel passed to this method is from the correct client

Trigus42 commented 2 years ago

I was also just trying to get two instances of Distube running and I encountered the same issue.

Just passing the actual client user id doesn't work. This produces the same behavior as before:

(message.member.voice.channel.client.user as any).actual_id = client.user.id
await distube.play(message.member.voice.channel, args.join(" "))

In DisTubeVoice.js:

return (0, voice_1.joinVoiceChannel)({
        channelId: channel.id,
        guildId: this.id,
        group: channel.client.user?.actual_id,
        adapterCreator: channel.guild.voiceAdapterCreator || (0, __1.createDiscordJSAdapter)(channel),
    });

Replacing the user in the voice channel like this:

message.member.voice.channel.client.user = client.user
await distube.play(message.member.voice.channel, args.join(" "))

produces the following error:

DisTubeError [VOICE_MISSING_PERMS]: You do not have permission to join this voice channel
    at new DisTubeVoice (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/voice/DisTubeVoice.ts:35:18)
    at DisTubeVoiceManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/voice/DisTubeVoiceManager.ts:36:12)
    at QueueManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/manager/QueueManager.ts:30:31)
    at DisTube.play (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/DisTube.ts:299:48)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Client.<anonymous> (/home/user/Documents/Code/Projects/DiscordMusicBot/src/index.ts:335:13) {errorCode: 'VOICE_MISSING_PERMS', stack: 'DisTubeError [VOICE_MISSING_PERMS]: You do no…Projects/DiscordMusicBot/src/index.ts:335:13)', message: 'You do not have permission to join this voice channel'}
code: ƒ code() {\n        return this.errorCode;\n    }
errorCode: 'VOICE_MISSING_PERMS'
name: ƒ name() {\n        return `DisTubeError [${this.errorCode}]`;\n    }
message: 'You do not have permission to join this voice channel'
stack: 'DisTubeError [VOICE_MISSING_PERMS]: You do not have permission to join this voice channel\n    at new DisTubeVoice (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/voice/DisTubeVoice.ts:35:18)\n    at DisTubeVoiceManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/voice/DisTubeVoiceManager.ts:36:12)\n    at QueueManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/manager/QueueManager.ts:30:31)\n    at DisTube.play (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/DisTube.ts:299:48)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Client.<anonymous> (/home/user/Documents/Code/Projects/DiscordMusicBot/src/index.ts:335:13)'
[[Prototype]]: Error

Forcing channel.joinable to be true doesn't work either:

Object.defineProperty((message.member.voice.channel as any), "joinable", {get: function() {return true}})
message.member.voice.channel.client.user = client.user
await distube.play(message.member.voice.channel, args.join(" "))

This creates the following error:

DisTubeError [INVALID_TYPE]: Expected 'GuildMember' for '<VoiceChannel>.guild.me', but got null
    at /home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/struct/Queue.ts:100:15
    at new Queue (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/struct/Queue.ts:101:9)
    at QueueManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/manager/QueueManager.ts:31:19)
    at DisTube.play (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/DisTube.ts:299:48)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Client.<anonymous> (/home/user/Documents/Code/Projects/DiscordMusicBot/src/index.ts:335:13) {errorCode: 'INVALID_TYPE', stack: 'DisTubeError [INVALID_TYPE]: Expected 'GuildM…Projects/DiscordMusicBot/src/index.ts:335:13)', message: 'Expected 'GuildMember' for '<VoiceChannel>.guild.me', but got null'}
code: ƒ code() {\n        return this.errorCode;\n    }
errorCode: 'INVALID_TYPE'
name: ƒ name() {\n        return `DisTubeError [${this.errorCode}]`;\n    }
message: 'Expected 'GuildMember' for '<VoiceChannel>.guild.me', but got null'
stack: 'DisTubeError [INVALID_TYPE]: Expected 'GuildMember' for '<VoiceChannel>.guild.me', but got null\n    at /home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/struct/Queue.ts:100:15\n    at new Queue (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/struct/Queue.ts:101:9)\n    at QueueManager.create (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/core/manager/QueueManager.ts:31:19)\n    at DisTube.play (/home/user/Documents/Code/Projects/DiscordMusicBot/node_modules/distube/src/DisTube.ts:299:48)\n    at runMicrotasks (<anonymous>)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Client.<anonymous> (/home/user/Documents/Code/Projects/DiscordMusicBot/src/index.ts:335:13)'
[[Prototype]]: Error
skick1234 commented 2 years ago

@Trigus42 If you use 2 clients with one bot, you just need 1 DisTube instance. If you use mutiple bots, the client user ids must be different.

skick1234 commented 2 years ago

@Majoramari I forgot that multiple clients can be from 1 bot. Are you using 2 clients of 1 or 2 bots?

Trigus42 commented 2 years ago

Hmm ok just to clarify: I have one node app that uses two Discord clients (two bot tokens). If the first client is already in a voice channel, the second client should join the other voice channel. For this I created pairs of DisTube and DiscordJS Client instances.

I don't see how I would accomplish this with just one DisTube instace.

Majoramari commented 2 years ago

Hmmm... It's weird. I tested with 2 clients, one per client and it works normally. Make sure your voiceChannel passed to this method is from the correct client

You're absolutely right you can I can avoid this by fetching the channel using the client that will join the channel on my side and this is what I'm doing right now but this could lead to a lot of bugs because you always could pass a channel have a wrong client and you don't even know it...

I forgot that multiple clients can be from 1 bot. Are you using 2 clients of 1 or 2 bots?

It's one node app for each discord.js client there's a distube instance.

Majoramari commented 2 years ago

I already tried to pull-request this solution two maybe months ago but I'm not into open-source I couldn't figure out how I can test my fork.

skick1234 commented 2 years ago

this could lead to a lot of bugs because you always could pass a channel have a wrong client and you don't even know it...

Hmmm... I think people should handle the voice channel before joining it (reply interaction if it's full,...). Ofc I can make commit like your request and you can use try catch but the error is pre-determined and I don't recommended to do it. And DisTube still has to fetch the correct channel to check its permission before joining.

I will convert this to a discussion since the bug is "my feature" 🤣