mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
Fix corner cases in connect/disconnect lifecycle and resource cleanup
1. Move TS6 handler patch to after client.connect() — the library's connect() internally replaces handler via #S(), discarding any patch applied beforehand. Patching after connect() is safe because clientinit is sent in async message callbacks after Init1 round-trips. 2. Preserve detectedProtocol across reconnect — disconnect() resets it to "unknown", causing the TS6 patch to be skipped on reconnect. 3. Prevent double "disconnected" event in BotInstance — disconnect() emitted it directly AND the async TS3Client disconnect triggered another through the event chain. 4. Guard playNext() against running after disconnect — check connected flag to avoid ghost queue processing. 5. Fix UDP error timer leak — clear previous timer before setting a new one to prevent accumulation. 6. Fix isPortFree() FD leak — close the test server on error path. https://claude.ai/code/session_01QzvMLUT3UkhsffShcY1qzD
This commit is contained in:
3 files changed
+51
-28
No files matched your search
+8
-3
@@ -105,6 +105,9 @@ export class BotInstance extends EventEmitter {
|
||||
});
|
||||
|
||||
this.tsClient.on("disconnected", () => {
|
||||
// Avoid duplicate event if disconnect() was called explicitly
|
||||
// (it already set connected = false and emitted "disconnected").
|
||||
if (!this.connected) return;
|
||||
this.connected = false;
|
||||
this.player.stop();
|
||||
this.emit("disconnected");
|
||||
@@ -119,8 +122,10 @@ export class BotInstance extends EventEmitter {
|
||||
|
||||
disconnect(): void {
|
||||
this.player.stop();
|
||||
this.tsClient.disconnect();
|
||||
// Set connected = false BEFORE tsClient.disconnect() so that the
|
||||
// "disconnected" event handler (setupTsEvents) won't emit a duplicate.
|
||||
this.connected = false;
|
||||
this.tsClient.disconnect();
|
||||
this.emit("disconnected");
|
||||
}
|
||||
|
||||
@@ -488,7 +493,7 @@ export class BotInstance extends EventEmitter {
|
||||
}
|
||||
|
||||
private async playNext(): Promise<void> {
|
||||
if (this.isAdvancing) return;
|
||||
if (this.isAdvancing || !this.connected) return;
|
||||
this.isAdvancing = true;
|
||||
try {
|
||||
this.voteSkipUsers.clear();
|
||||
@@ -497,7 +502,7 @@ export class BotInstance extends EventEmitter {
|
||||
let started = await this.resolveAndPlay(next);
|
||||
if (!started) {
|
||||
// Skip to next if URL resolve fails (up to 3 retries)
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let i = 0; i < 3 && this.connected; i++) {
|
||||
const retry = this.queue.next();
|
||||
if (!retry) break;
|
||||
if (await this.resolveAndPlay(retry)) {
|
||||
|
||||
Reference in new issue
Block a user