summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksa Vuckovic <aleksa@vuckovic.cc>2026-06-10 22:06:29 +0200
committerAleksa Vuckovic <aleksa@vuckovic.cc>2026-06-10 22:06:29 +0200
commit3088fbfaa419df909908e00d2c9af9dec62d6206 (patch)
tree0dfe9dc16a30bf6e1f56c04b2055d65853fb2290
parent16333d663bbaa59c76f753a761b3f2aa21b2211e (diff)
Reject /play early when voice channel is fullHEADmaster
Discord silently drops the bot's op 4 join when the channel user limit is reached and the bot lacks Move Members, causing a 30s AbortError timeout. Check voiceChannel.full upfront and return a clear error to the user. Also revert the voice-join diagnostic logging added while investigating. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
-rw-r--r--src/bot.js12
-rw-r--r--src/handlers/playCommand.js35
-rw-r--r--src/utils/helpers.js5
3 files changed, 7 insertions, 45 deletions
diff --git a/src/bot.js b/src/bot.js
index 21eadf5..3ec9aa1 100644
--- a/src/bot.js
+++ b/src/bot.js
@@ -110,16 +110,4 @@ client.on('warn', (info) => {
console.warn(`[WARN] ${new Date().toISOString()} - ${info}`);
});
-client.on('debug', (info) => {
- if (info.includes('VOICE') || info.includes('Voice') || info.includes('voice')) {
- console.log(`[DJS DEBUG] ${info}`);
- }
-});
-
-client.on('raw', (packet) => {
- if (packet.t === 'VOICE_STATE_UPDATE' || packet.t === 'VOICE_SERVER_UPDATE') {
- console.log(`[RAW ${packet.t}]`, JSON.stringify(packet.d));
- }
-});
-
client.login(process.env.DISCORD_TOKEN); \ No newline at end of file
diff --git a/src/handlers/playCommand.js b/src/handlers/playCommand.js
index 365f4f6..c61e009 100644
--- a/src/handlers/playCommand.js
+++ b/src/handlers/playCommand.js
@@ -129,50 +129,19 @@ async function createVoiceConnection(voiceChannel, interaction) {
const maxAttempts = 2;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
- const guild = voiceChannel.guild;
- const botMember = guild.members.me;
- const botVoiceState = botMember?.voice;
- console.log(`[JOIN ATTEMPT ${attempt}] Guild: ${guildId}, Channel: ${voiceChannel.id}, Shard status: ${guild.shard?.status}, Shard id: ${guild.shardId}`);
- console.log(`[BOT INFO] id: ${guild.client.user?.id}, voice channelId: ${botVoiceState?.channelId ?? 'null'}, sessionId: ${botVoiceState?.sessionId ?? 'null'}, serverDeaf: ${botVoiceState?.serverDeaf}, serverMute: ${botVoiceState?.serverMute}, selfDeaf: ${botVoiceState?.selfDeaf}, selfMute: ${botVoiceState?.selfMute}`);
- console.log(`[CHANNEL INFO] name: ${voiceChannel.name}, type: ${voiceChannel.type}, userLimit: ${voiceChannel.userLimit}, full: ${voiceChannel.full}, joinable: ${voiceChannel.joinable}, members: ${voiceChannel.members?.size}, rtcRegion: ${voiceChannel.rtcRegion}`);
-
- const baseAdapterCreator = guild.voiceAdapterCreator;
- const adapterCreator = (methods) => {
- const adapter = baseAdapterCreator(methods);
- const originalSendPayload = adapter.sendPayload;
- adapter.sendPayload = (data) => {
- const result = originalSendPayload(data);
- console.log(`[ADAPTER sendPayload] op=${data?.op}, sent=${result}, shard=${guild.shard?.status}, payload=${JSON.stringify(data?.d)}`);
- return result;
- };
- const originalDestroy = adapter.destroy;
- adapter.destroy = () => {
- console.log(`[ADAPTER destroy]`);
- return originalDestroy();
- };
- return adapter;
- };
-
const connection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId,
- adapterCreator,
+ adapterCreator: voiceChannel.guild.voiceAdapterCreator,
selfDeaf: true,
});
- const stateLogger = (oldState, newState) => {
- console.log(`[VOICE STATE] Guild: ${guildId}, ${oldState.status} -> ${newState.status}${newState.reason ? ` (reason: ${newState.reason})` : ''}${newState.closeCode ? ` (closeCode: ${newState.closeCode})` : ''}`);
- };
- connection.on('stateChange', stateLogger);
-
try {
await entersState(connection, VoiceConnectionStatus.Ready, 30000);
- connection.off('stateChange', stateLogger);
return connection;
} catch (error) {
lastError = error;
- console.error(`Failed to join voice channel (attempt ${attempt}/${maxAttempts}), last state: ${connection.state?.status}:`, error);
- connection.off('stateChange', stateLogger);
+ console.error(`Failed to join voice channel (attempt ${attempt}/${maxAttempts}):`, error);
try {
connection.destroy();
} catch (e) {
diff --git a/src/utils/helpers.js b/src/utils/helpers.js
index 0362528..b407fb0 100644
--- a/src/utils/helpers.js
+++ b/src/utils/helpers.js
@@ -37,6 +37,11 @@ function requireVoiceChannel(interaction) {
return null;
}
+ if (voiceChannel.full && !perms.has(PermissionsBitField.Flags.MoveMembers)) {
+ interaction.editReply(`That voice channel is full (limit: ${voiceChannel.userLimit}). Raise the user limit or give me Move Members permission.`);
+ return null;
+ }
+
return voiceChannel;
}