diff --git a/index.js b/index.js index 765e6e6..e7657bf 100644 --- a/index.js +++ b/index.js @@ -15,6 +15,14 @@ const MAX_NONCE = 2 ** 32 - 1 const MAX_TIMESTAMP = 2 ** 32 const MAX_SEQUENCE = 2 ** 16 const ENCRYPTION_MODE = 'xsalsa20_poly1305_lite' +const DISCORD_CLOSE_CODES = { + 4004: { message: 'Authentication failed.' }, + 4006: { message: 'Session no longer valid.' }, + 4009: { message: 'Session timeout.' }, + 4011: { message: 'Server not found.' }, + 4014: { message: 'Disconnected.', error: false }, + 4015: { message: 'Voice server crashed.', reconnect: true }, +} const ssrcs = {} @@ -269,12 +277,22 @@ class Connection extends EventEmitter { this.ws.on('close', (code) => { if (!this.ws) return; - this._destroy({ status: 'disconnected', reason: 'websocketClose', code }) + const closeCode = DISCORD_CLOSE_CODES[code] + + if (closeCode.reconnect) { + this._updateState({ status: 'disconnected', reason: 'websocketClose', code }) + this._updatePlayerState({ status: 'idle' }) + + this.emit('reconnecting', closeCode.message) - if (code == 4015) { - this.connect(null, true) + this.connect(() => this.unpause(), true) } else { - this.emit('error', new Error(`WebSocket closed unexpectadly: ${code}`)) + this._destroy({ status: 'disconnected', reason: 'websocketClose', code }) + + if (closeCode.error !== false) + this.emit('error', new Error(closeCode.message)) + + return; } }) diff --git a/package-lock.json b/package-lock.json index 9089c2c..ba5fda7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@performanc/voice", - "version": "1.0.0", + "version": "1.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@performanc/voice", - "version": "1.0.0", + "version": "1.0.3", "license": "SEE LICENSE IN LICENSE", "optionalDependencies": { "libsodium-wrappers": "^0.7.13", diff --git a/package.json b/package.json index cb5a888..ad9a810 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@performanc/voice", - "version": "1.0.2", + "version": "1.0.3", "description": "Performant Discord voice API client for ES6 Node.js", "main": "index.js", "type": "module", diff --git a/ws.js b/ws.js index d86f7e7..7d48286 100644 --- a/ws.js +++ b/ws.js @@ -138,6 +138,7 @@ class WebSocket extends EventEmitter { const reason = headers.buffer.subarray(2).toString('utf-8') this.emit('close', code, reason) + socket.removeAllListeners('close') } socket.end()