diff --git a/src/ts-protocol/client.ts b/src/ts-protocol/client.ts index 0638d90..15e6c88 100644 --- a/src/ts-protocol/client.ts +++ b/src/ts-protocol/client.ts @@ -49,6 +49,35 @@ export class TS3Client extends EventEmitter { port: options.port, }); + this.connection.on("error", (err) => { + this.logger.error({ err }, "TCP connection error"); + this.emit("error", err); + }); + + this.voice.on("error", (err) => { + this.logger.error({ err }, "UDP voice error"); + this.emit("error", err); + }); + + this.connection.on( + "notify:textmessage", + (data: Record) => { + const msg: TS3TextMessage = { + invokerName: data.invokername ?? "", + invokerId: data.invokerid ?? "", + invokerUid: data.invokeruid ?? "", + message: data.msg ?? "", + targetMode: parseInt(data.targetmode ?? "0", 10), + }; + this.emit("textMessage", msg); + } + ); + + this.connection.on("close", () => { + this.logger.warn("Connection closed"); + this.emit("disconnected"); + }); + if (options.identity) { this.identity = importIdentity(options.identity); } else { @@ -91,27 +120,8 @@ export class TS3Client extends EventEmitter { await this.sendCommand("servernotifyregister", { event: "textchannel" }); await this.sendCommand("servernotifyregister", { event: "textprivate" }); - this.connection.on( - "notify:textmessage", - (data: Record) => { - const msg: TS3TextMessage = { - invokerName: data.invokername ?? "", - invokerId: data.invokerid ?? "", - invokerUid: data.invokeruid ?? "", - message: data.msg ?? "", - targetMode: parseInt(data.targetmode ?? "0", 10), - }; - this.emit("textMessage", msg); - } - ); - this.keepAliveInterval = setInterval(() => { this.voice.sendKeepAlive(); - }, 5000); - - this.connection.on("close", () => { - this.logger.warn("Connection closed"); - this.emit("disconnected"); }); this.emit("connected"); diff --git a/src/ts-protocol/commands.ts b/src/ts-protocol/commands.ts index e89f2e3..698ab03 100644 --- a/src/ts-protocol/commands.ts +++ b/src/ts-protocol/commands.ts @@ -62,12 +62,6 @@ export function decodeResponse(raw: string): Record[] { }); } -export interface TS3Response { - errorId: number; - errorMessage: string; - data: Record[]; -} - export function parseErrorLine(line: string): { id: number; msg: string } { const decoded = decodeResponse(line.replace(/^error\s+/, ""))[0]; return { diff --git a/src/ts-protocol/connection.ts b/src/ts-protocol/connection.ts index 9ea5989..135453c 100644 --- a/src/ts-protocol/connection.ts +++ b/src/ts-protocol/connection.ts @@ -48,6 +48,7 @@ export class TS3Connection extends EventEmitter { }); this.socket.on("close", () => { this.connected = false; + this.drainCommandQueue(new Error("Connection closed")); this.emit("close"); }); }); @@ -126,6 +127,15 @@ export class TS3Connection extends EventEmitter { this.socket = null; this.connected = false; } + this.drainCommandQueue(new Error("Disconnected")); + } + + private drainCommandQueue(error: Error): void { + for (const pending of this.commandQueue) { + pending.reject(error); + } + this.commandQueue = []; + this.responseLines = []; } isConnected(): boolean {