Skip to content

Commit

Permalink
fix: bot disconnection on member move
Browse files Browse the repository at this point in the history
Co-authored-by: DanLop618 <[email protected]>
  • Loading branch information
twlite and DanLop618 committed Jan 12, 2023
1 parent 91835c7 commit 384db59
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
57 changes: 40 additions & 17 deletions src/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class Player extends EventEmitter<PlayerEvents> {
const queue = this.getQueue(oldState.guild.id);
if (!queue || !queue.connection) return;

this.emit("voiceStateUpdate", queue, oldState, newState);

if (oldState.channelId && !newState.channelId && newState.member.id === newState.guild.members.me.id) {
try {
queue.destroy();
Expand All @@ -126,7 +128,7 @@ class Player extends EventEmitter<PlayerEvents> {
}
}

if (queue.connection && !newState.channelId && oldState.channelId === queue.connection.channel.id) {
if (!newState.channelId && oldState.channelId === queue.connection.channel.id) {
if (!Util.isVoiceEmpty(queue.connection.channel)) return;
const timeout = setTimeout(() => {
if (!Util.isVoiceEmpty(queue.connection.channel)) return;
Expand All @@ -137,7 +139,7 @@ class Player extends EventEmitter<PlayerEvents> {
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
}

if (queue.connection && newState.channelId && newState.channelId === queue.connection.channel.id) {
if (newState.channelId && newState.channelId === queue.connection.channel.id) {
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
if (!channelEmpty && emptyTimeout) {
Expand All @@ -146,21 +148,42 @@ class Player extends EventEmitter<PlayerEvents> {
}
}

if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId && newState.member.id === newState.guild.members.me.id) {
if (queue.connection && newState.member.id === newState.guild.members.me.id) queue.connection.channel = newState.channel;
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
if (!channelEmpty && emptyTimeout) {
clearTimeout(emptyTimeout);
queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId) {
if (newState.member.id === newState.guild.members.me.id) {
if (queue.connection && newState.member.id === newState.guild.members.me.id) queue.connection.channel = newState.channel;
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
if (!channelEmpty && emptyTimeout) {
clearTimeout(emptyTimeout);
queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
} else {
const timeout = setTimeout(() => {
if (queue.connection && !Util.isVoiceEmpty(queue.connection.channel)) return;
if (!this.queues.has(queue.guild.id)) return;
if (queue.options.leaveOnEmpty) queue.destroy(true);
this.emit("channelEmpty", queue);
}, queue.options.leaveOnEmptyCooldown || 0).unref();
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
}
} else {
const timeout = setTimeout(() => {
if (queue.connection && !Util.isVoiceEmpty(queue.connection.channel)) return;
if (!this.queues.has(queue.guild.id)) return;
if (queue.options.leaveOnEmpty) queue.destroy(true);
this.emit("channelEmpty", queue);
}, queue.options.leaveOnEmptyCooldown || 0).unref();
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
if (newState.channelId !== queue.connection.channel.id) {
if (!Util.isVoiceEmpty(queue.connection.channel)) return;
if (queue._cooldownsTimeout.has(`empty_${oldState.guild.id}`)) return;
const timeout = setTimeout(() => {
if (!Util.isVoiceEmpty(queue.connection.channel)) return;
if (!this.queues.has(queue.guild.id)) return;
if (queue.options.leaveOnEmpty) queue.destroy(true);
this.emit("channelEmpty", queue);
}, queue.options.leaveOnEmptyCooldown || 0).unref();
queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
} else {
const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
if (!channelEmpty && emptyTimeout) {
clearTimeout(emptyTimeout);
queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
}
}
}
}
}
Expand Down Expand Up @@ -445,7 +468,7 @@ class Player extends EventEmitter<PlayerEvents> {
views: 0,
requestedBy: options.requestedBy as User,
playlist,
source: "spotify"
source: "spotify"
});
return data;
}) as Track[];
Expand Down
11 changes: 10 additions & 1 deletion src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Snowflake, User, UserResolvable } from "discord.js";
import { Snowflake, User, UserResolvable, VoiceState } from "discord.js";
import { Readable, Duplex } from "stream";
import { Queue } from "../Structures/Queue";
import Track from "../Structures/Track";
Expand Down Expand Up @@ -336,6 +336,14 @@ export enum QueryType {
* @param {Track} track The track
*/

/**
* Emitted when a track ends
* @event Player#voiceStateUpdate
* @param {Queue} queue The queue that this update belongs to
* @param {VoiceState} oldState The old voice state
* @param {VoiceState} newState The new voice state
*/

/* eslint-disable @typescript-eslint/no-explicit-any */
export interface PlayerEvents {
botDisconnect: (queue: Queue) => any;
Expand All @@ -349,6 +357,7 @@ export interface PlayerEvents {
tracksAdd: (queue: Queue, track: Track[]) => any;
trackStart: (queue: Queue, track: Track) => any;
trackEnd: (queue: Queue, track: Track) => any;
voiceStateUpdate: (queue: Queue, oldState: VoiceState, newState: VoiceState) => any;
}

/* eslint-enable @typescript-eslint/no-explicit-any */
Expand Down

0 comments on commit 384db59

Please sign in to comment.