From 98450be22171805131c38fbae07ceda87d760efb Mon Sep 17 00:00:00 2001 From: March 7th <71698422+aiko-chan-ai@users.noreply.github.com> Date: Tue, 20 Dec 2022 22:20:09 +0700 Subject: [PATCH] fix: #449 --- src/structures/VoiceState.js | 18 +- src/util/Voice.js | 1347 +++++++++++++++++----------------- typings/index.d.ts | 4 +- 3 files changed, 671 insertions(+), 698 deletions(-) diff --git a/src/structures/VoiceState.js b/src/structures/VoiceState.js index c3a546e..db32a51 100644 --- a/src/structures/VoiceState.js +++ b/src/structures/VoiceState.js @@ -63,16 +63,6 @@ class VoiceState extends Base { this.selfMute ??= null; } - if ('self_stream' in data) { - /** - * Whether this member is streaming using "Go Live" - * @type {?boolean} - */ - this.streaming = data.self_stream; - } else { - this.streaming ??= null; - } - if ('self_video' in data) { /** * Whether this member's camera is enabled @@ -93,6 +83,14 @@ class VoiceState extends Base { this.sessionId ??= null; } + // The self_stream is property is omitted if false, check for another property + // here to avoid incorrectly clearing this when partial data is specified + /** + * Whether this member is streaming using "Screen Share" + * @type {boolean} + */ + this.streaming = data.self_stream ?? false; + if ('channel_id' in data) { /** * The {@link VoiceChannel} or {@link StageChannel} id the member is in diff --git a/src/util/Voice.js b/src/util/Voice.js index 9dfe9c8..3683296 100644 --- a/src/util/Voice.js +++ b/src/util/Voice.js @@ -1,31 +1,39 @@ -"use strict"; +'use strict'; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; -var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); +var __defNormalProp = (obj, key, value) => + key in obj + ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) + : (obj[key] = value); +var __name = (target, value) => __defProp(target, 'name', { value, configurable: true }); var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); + for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { + if ((from && typeof from === 'object') || typeof from === 'function') { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + __defProp(to, key, { + get: () => from[key], + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable, + }); } return to; }; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var __toESM = (mod, isNodeMode, target) => ( + (target = mod != null ? __create(__getProtoOf(mod)) : {}), + __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, 'default', { value: mod, enumerable: true }) : target, + mod, + ) +); +var __toCommonJS = mod => __copyProps(__defProp({}, '__esModule', { value: true }), mod); var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + __defNormalProp(obj, typeof key !== 'symbol' ? key + '' : key, value); return value; }; @@ -58,15 +66,15 @@ __export(src_exports, { getVoiceConnections: () => getVoiceConnections, joinVoiceChannel: () => joinVoiceChannel, validateDiscordOpusHead: () => validateDiscordOpusHead, - version: () => version2 + version: () => version2, }); module.exports = __toCommonJS(src_exports); // src/VoiceConnection.ts -var import_node_events7 = require("events"); +var import_node_events7 = require('events'); // src/DataStore.ts -var import_v10 = require("discord-api-types/v10"); +var import_v10 = require('discord-api-types/v10'); function createJoinVoiceChannelPayload(config) { return { op: import_v10.GatewayOpcodes.VoiceStateUpdate, @@ -74,57 +82,55 @@ function createJoinVoiceChannelPayload(config) { guild_id: config.guildId, channel_id: config.channelId, self_deaf: config.selfDeaf, - self_mute: config.selfMute - } + self_mute: config.selfMute, + }, }; } -__name(createJoinVoiceChannelPayload, "createJoinVoiceChannelPayload"); +__name(createJoinVoiceChannelPayload, 'createJoinVoiceChannelPayload'); var groups = /* @__PURE__ */ new Map(); -groups.set("default", /* @__PURE__ */ new Map()); +groups.set('default', /* @__PURE__ */ new Map()); function getOrCreateGroup(group) { const existing = groups.get(group); - if (existing) - return existing; + if (existing) return existing; const map = /* @__PURE__ */ new Map(); groups.set(group, map); return map; } -__name(getOrCreateGroup, "getOrCreateGroup"); +__name(getOrCreateGroup, 'getOrCreateGroup'); function getGroups() { return groups; } -__name(getGroups, "getGroups"); -function getVoiceConnections(group = "default") { +__name(getGroups, 'getGroups'); +function getVoiceConnections(group = 'default') { return groups.get(group); } -__name(getVoiceConnections, "getVoiceConnections"); -function getVoiceConnection(guildId, group = "default") { +__name(getVoiceConnections, 'getVoiceConnections'); +function getVoiceConnection(guildId, group = 'default') { return getVoiceConnections(group)?.get(guildId); } -__name(getVoiceConnection, "getVoiceConnection"); +__name(getVoiceConnection, 'getVoiceConnection'); function untrackVoiceConnection(voiceConnection) { return getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId); } -__name(untrackVoiceConnection, "untrackVoiceConnection"); +__name(untrackVoiceConnection, 'untrackVoiceConnection'); function trackVoiceConnection(voiceConnection) { return getOrCreateGroup(voiceConnection.joinConfig.group).set(voiceConnection.joinConfig.guildId, voiceConnection); } -__name(trackVoiceConnection, "trackVoiceConnection"); +__name(trackVoiceConnection, 'trackVoiceConnection'); var FRAME_LENGTH = 20; var audioCycleInterval; var nextTime = -1; var audioPlayers = []; function audioCycleStep() { - if (nextTime === -1) - return; + if (nextTime === -1) return; nextTime += FRAME_LENGTH; - const available = audioPlayers.filter((player) => player.checkPlayable()); + const available = audioPlayers.filter(player => player.checkPlayable()); for (const player of available) { - player["_stepDispatch"](); + player['_stepDispatch'](); } prepareNextAudioFrame(available); } -__name(audioCycleStep, "audioCycleStep"); +__name(audioCycleStep, 'audioCycleStep'); function prepareNextAudioFrame(players) { const nextPlayer = players.shift(); if (!nextPlayer) { @@ -133,17 +139,16 @@ function prepareNextAudioFrame(players) { } return; } - nextPlayer["_stepPrepare"](); + nextPlayer['_stepPrepare'](); setImmediate(() => prepareNextAudioFrame(players)); } -__name(prepareNextAudioFrame, "prepareNextAudioFrame"); +__name(prepareNextAudioFrame, 'prepareNextAudioFrame'); function hasAudioPlayer(target) { return audioPlayers.includes(target); } -__name(hasAudioPlayer, "hasAudioPlayer"); +__name(hasAudioPlayer, 'hasAudioPlayer'); function addAudioPlayer(player) { - if (hasAudioPlayer(player)) - return player; + if (hasAudioPlayer(player)) return player; audioPlayers.push(player); if (audioPlayers.length === 1) { nextTime = Date.now(); @@ -151,34 +156,31 @@ function addAudioPlayer(player) { } return player; } -__name(addAudioPlayer, "addAudioPlayer"); +__name(addAudioPlayer, 'addAudioPlayer'); function deleteAudioPlayer(player) { const index = audioPlayers.indexOf(player); - if (index === -1) - return; + if (index === -1) return; audioPlayers.splice(index, 1); if (audioPlayers.length === 0) { nextTime = -1; - if (typeof audioCycleInterval !== "undefined") - clearTimeout(audioCycleInterval); + if (typeof audioCycleInterval !== 'undefined') clearTimeout(audioCycleInterval); } } -__name(deleteAudioPlayer, "deleteAudioPlayer"); +__name(deleteAudioPlayer, 'deleteAudioPlayer'); // src/networking/Networking.ts -var import_node_buffer3 = require("buffer"); -var import_node_events3 = require("events"); -var import_v42 = require("discord-api-types/voice/v4"); +var import_node_buffer3 = require('buffer'); +var import_node_events3 = require('events'); +var import_v42 = require('discord-api-types/voice/v4'); // src/util/Secretbox.ts -var import_node_buffer = require("buffer"); +var import_node_buffer = require('buffer'); var libs = { - "sodium-native": (sodium) => ({ + 'sodium-native': sodium => ({ open: (buffer, nonce2, secretKey) => { if (buffer) { const output = import_node_buffer.Buffer.allocUnsafe(buffer.length - sodium.crypto_box_MACBYTES); - if (sodium.crypto_secretbox_open_easy(output, buffer, nonce2, secretKey)) - return output; + if (sodium.crypto_secretbox_open_easy(output, buffer, nonce2, secretKey)) return output; } return null; }, @@ -190,72 +192,69 @@ var libs = { random: (num, buffer = import_node_buffer.Buffer.allocUnsafe(num)) => { sodium.randombytes_buf(buffer); return buffer; - } + }, }), - sodium: (sodium) => ({ + sodium: sodium => ({ open: sodium.api.crypto_secretbox_open_easy, close: sodium.api.crypto_secretbox_easy, random: (num, buffer = import_node_buffer.Buffer.allocUnsafe(num)) => { sodium.api.randombytes_buf(buffer); return buffer; - } + }, }), - "libsodium-wrappers": (sodium) => ({ + 'libsodium-wrappers': sodium => ({ open: sodium.crypto_secretbox_open_easy, close: sodium.crypto_secretbox_easy, - random: sodium.randombytes_buf + random: sodium.randombytes_buf, }), - tweetnacl: (tweetnacl) => ({ + tweetnacl: tweetnacl => ({ open: tweetnacl.secretbox.open, close: tweetnacl.secretbox, - random: tweetnacl.randomBytes - }) + random: tweetnacl.randomBytes, + }), }; var fallbackError = /* @__PURE__ */ __name(() => { throw new Error( `Cannot play audio as no valid encryption package is installed. - Install sodium, libsodium-wrappers, or tweetnacl. - Use the generateDependencyReport() function for more information. -` +`, ); -}, "fallbackError"); +}, 'fallbackError'); var methods = { open: fallbackError, close: fallbackError, - random: fallbackError + random: fallbackError, }; void (async () => { for (const libName of Object.keys(libs)) { try { const lib = require(libName); - if (libName === "libsodium-wrappers" && lib.ready) - await lib.ready; + if (libName === 'libsodium-wrappers' && lib.ready) await lib.ready; Object.assign(methods, libs[libName](lib)); break; - } catch { - } + } catch {} } })(); // src/util/util.ts -var noop = /* @__PURE__ */ __name(() => { -}, "noop"); +var noop = /* @__PURE__ */ __name(() => {}, 'noop'); // src/networking/VoiceUDPSocket.ts -var import_node_buffer2 = require("buffer"); -var import_node_dgram = require("dgram"); -var import_node_events = require("events"); -var import_node_net = require("net"); +var import_node_buffer2 = require('buffer'); +var import_node_dgram = require('dgram'); +var import_node_events = require('events'); +var import_node_net = require('net'); function parseLocalPacket(message) { const packet = import_node_buffer2.Buffer.from(message); - const ip = packet.slice(8, packet.indexOf(0, 8)).toString("utf8"); + const ip = packet.slice(8, packet.indexOf(0, 8)).toString('utf8'); if (!(0, import_node_net.isIPv4)(ip)) { - throw new Error("Malformed IP address"); + throw new Error('Malformed IP address'); } const port = packet.readUInt16BE(packet.length - 2); return { ip, port }; } -__name(parseLocalPacket, "parseLocalPacket"); +__name(parseLocalPacket, 'parseLocalPacket'); var KEEP_ALIVE_INTERVAL = 5e3; var KEEP_ALIVE_LIMIT = 12; var MAX_COUNTER_VALUE = 2 ** 32 - 1; @@ -270,31 +269,30 @@ var VoiceUDPSocket = class extends import_node_events.EventEmitter { debug; constructor(remote, debug = false) { super(); - this.socket = (0, import_node_dgram.createSocket)("udp4"); - this.socket.on("error", (error) => this.emit("error", error)); - this.socket.on("message", (buffer) => this.onMessage(buffer)); - this.socket.on("close", () => this.emit("close")); + this.socket = (0, import_node_dgram.createSocket)('udp4'); + this.socket.on('error', error => this.emit('error', error)); + this.socket.on('message', buffer => this.onMessage(buffer)); + this.socket.on('close', () => this.emit('close')); this.remote = remote; this.keepAlives = []; this.keepAliveBuffer = import_node_buffer2.Buffer.alloc(8); this.keepAliveInterval = setInterval(() => this.keepAlive(), KEEP_ALIVE_INTERVAL); setImmediate(() => this.keepAlive()); - this.debug = debug ? (message) => this.emit("debug", message) : null; + this.debug = debug ? message => this.emit('debug', message) : null; } onMessage(buffer) { if (buffer.length === 8) { const counter = buffer.readUInt32LE(0); const index = this.keepAlives.findIndex(({ value }) => value === counter); - if (index === -1) - return; + if (index === -1) return; this.ping = Date.now() - this.keepAlives[index].timestamp; this.keepAlives.splice(0, index); } - this.emit("message", buffer); + this.emit('message', buffer); } keepAlive() { if (this.keepAlives.length >= KEEP_ALIVE_LIMIT) { - this.debug?.("UDP socket has not received enough responses from Discord - closing socket"); + this.debug?.('UDP socket has not received enough responses from Discord - closing socket'); this.destroy(); return; } @@ -302,7 +300,7 @@ var VoiceUDPSocket = class extends import_node_events.EventEmitter { this.send(this.keepAliveBuffer); this.keepAlives.push({ value: this.keepAliveCounter, - timestamp: Date.now() + timestamp: Date.now(), }); this.keepAliveCounter++; if (this.keepAliveCounter > MAX_COUNTER_VALUE) { @@ -315,24 +313,21 @@ var VoiceUDPSocket = class extends import_node_events.EventEmitter { destroy() { try { this.socket.close(); - } catch { - } + } catch {} clearInterval(this.keepAliveInterval); } async performIPDiscovery(ssrc) { return new Promise((resolve2, reject) => { - const listener = /* @__PURE__ */ __name((message) => { + const listener = /* @__PURE__ */ __name(message => { try { - if (message.readUInt16BE(0) !== 2) - return; + if (message.readUInt16BE(0) !== 2) return; const packet = parseLocalPacket(message); - this.socket.off("message", listener); + this.socket.off('message', listener); resolve2(packet); - } catch { - } - }, "listener"); - this.socket.on("message", listener); - this.socket.once("close", () => reject(new Error("Cannot perform IP discovery - socket closed"))); + } catch {} + }, 'listener'); + this.socket.on('message', listener); + this.socket.once('close', () => reject(new Error('Cannot perform IP discovery - socket closed'))); const discoveryBuffer = import_node_buffer2.Buffer.alloc(74); discoveryBuffer.writeUInt16BE(1, 0); discoveryBuffer.writeUInt16BE(70, 2); @@ -341,12 +336,12 @@ var VoiceUDPSocket = class extends import_node_events.EventEmitter { }); } }; -__name(VoiceUDPSocket, "VoiceUDPSocket"); +__name(VoiceUDPSocket, 'VoiceUDPSocket'); // src/networking/VoiceWebSocket.ts -var import_node_events2 = require("events"); -var import_v4 = require("discord-api-types/voice/v4"); -var import_ws = __toESM(require("ws")); +var import_node_events2 = require('events'); +var import_v4 = require('discord-api-types/voice/v4'); +var import_ws = __toESM(require('ws')); var VoiceWebSocket = class extends import_node_events2.EventEmitter { heartbeatInterval; lastHeartbeatAck; @@ -358,34 +353,33 @@ var VoiceWebSocket = class extends import_node_events2.EventEmitter { constructor(address, debug) { super(); this.ws = new import_ws.default(address); - this.ws.onmessage = (err) => this.onMessage(err); - this.ws.onopen = (err) => this.emit("open", err); - this.ws.onerror = (err) => this.emit("error", err instanceof Error ? err : err.error); - this.ws.onclose = (err) => this.emit("close", err); + this.ws.onmessage = err => this.onMessage(err); + this.ws.onopen = err => this.emit('open', err); + this.ws.onerror = err => this.emit('error', err instanceof Error ? err : err.error); + this.ws.onclose = err => this.emit('close', err); this.lastHeartbeatAck = 0; this.lastHeartbeatSend = 0; - this.debug = debug ? (message) => this.emit("debug", message) : null; + this.debug = debug ? message => this.emit('debug', message) : null; } destroy() { try { - this.debug?.("destroyed"); + this.debug?.('destroyed'); this.setHeartbeatInterval(-1); this.ws.close(1e3); } catch (error) { const err = error; - this.emit("error", err); + this.emit('error', err); } } onMessage(event) { - if (typeof event.data !== "string") - return; + if (typeof event.data !== 'string') return; this.debug?.(`<< ${event.data}`); let packet; try { packet = JSON.parse(event.data); } catch (error) { const err = error; - this.emit("error", err); + this.emit('error', err); return; } if (packet.op === import_v4.VoiceOpcodes.HeartbeatAck) { @@ -393,7 +387,7 @@ var VoiceWebSocket = class extends import_node_events2.EventEmitter { this.missedHeartbeats = 0; this.ping = this.lastHeartbeatAck - this.lastHeartbeatSend; } - this.emit("packet", packet); + this.emit('packet', packet); } sendPacket(packet) { try { @@ -403,7 +397,7 @@ var VoiceWebSocket = class extends import_node_events2.EventEmitter { return; } catch (error) { const err = error; - this.emit("error", err); + this.emit('error', err); } } sendHeartbeat() { @@ -412,12 +406,11 @@ var VoiceWebSocket = class extends import_node_events2.EventEmitter { const nonce2 = this.lastHeartbeatSend; this.sendPacket({ op: import_v4.VoiceOpcodes.Heartbeat, - d: nonce2 + d: nonce2, }); } setHeartbeatInterval(ms) { - if (typeof this.heartbeatInterval !== "undefined") - clearInterval(this.heartbeatInterval); + if (typeof this.heartbeatInterval !== 'undefined') clearInterval(this.heartbeatInterval); if (ms > 0) { this.heartbeatInterval = setInterval(() => { if (this.lastHeartbeatSend !== 0 && this.missedHeartbeats >= 3) { @@ -429,34 +422,34 @@ var VoiceWebSocket = class extends import_node_events2.EventEmitter { } } }; -__name(VoiceWebSocket, "VoiceWebSocket"); +__name(VoiceWebSocket, 'VoiceWebSocket'); // src/networking/Networking.ts var CHANNELS = 2; -var TIMESTAMP_INC = 48e3 / 100 * CHANNELS; +var TIMESTAMP_INC = (48e3 / 100) * CHANNELS; var MAX_NONCE_SIZE = 2 ** 32 - 1; -var SUPPORTED_ENCRYPTION_MODES = ["xsalsa20_poly1305_lite", "xsalsa20_poly1305_suffix", "xsalsa20_poly1305"]; +var SUPPORTED_ENCRYPTION_MODES = ['xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305']; var nonce = import_node_buffer3.Buffer.alloc(24); function stringifyState(state) { return JSON.stringify({ ...state, - ws: Reflect.has(state, "ws"), - udp: Reflect.has(state, "udp") + ws: Reflect.has(state, 'ws'), + udp: Reflect.has(state, 'udp'), }); } -__name(stringifyState, "stringifyState"); +__name(stringifyState, 'stringifyState'); function chooseEncryptionMode(options) { - const option = options.find((option2) => SUPPORTED_ENCRYPTION_MODES.includes(option2)); + const option = options.find(option2 => SUPPORTED_ENCRYPTION_MODES.includes(option2)); if (!option) { - throw new Error(`No compatible encryption modes. Available include: ${options.join(", ")}`); + throw new Error(`No compatible encryption modes. Available include: ${options.join(', ')}`); } return option; } -__name(chooseEncryptionMode, "chooseEncryptionMode"); +__name(chooseEncryptionMode, 'chooseEncryptionMode'); function randomNBit(numberOfBits) { return Math.floor(Math.random() * 2 ** numberOfBits); } -__name(randomNBit, "randomNBit"); +__name(randomNBit, 'randomNBit'); var Networking = class extends import_node_events3.EventEmitter { _state; debug; @@ -469,60 +462,60 @@ var Networking = class extends import_node_events3.EventEmitter { this.onWsDebug = this.onWsDebug.bind(this); this.onUdpDebug = this.onUdpDebug.bind(this); this.onUdpClose = this.onUdpClose.bind(this); - this.debug = debug ? (message) => this.emit("debug", message) : null; + this.debug = debug ? message => this.emit('debug', message) : null; this._state = { code: 0 /* OpeningWs */, ws: this.createWebSocket(options.endpoint), - connectionOptions: options + connectionOptions: options, }; } destroy() { this.state = { - code: 6 /* Closed */ + code: 6 /* Closed */, }; } get state() { return this._state; } set state(newState) { - const oldWs = Reflect.get(this._state, "ws"); - const newWs = Reflect.get(newState, "ws"); + const oldWs = Reflect.get(this._state, 'ws'); + const newWs = Reflect.get(newState, 'ws'); if (oldWs && oldWs !== newWs) { - oldWs.off("debug", this.onWsDebug); - oldWs.on("error", noop); - oldWs.off("error", this.onChildError); - oldWs.off("open", this.onWsOpen); - oldWs.off("packet", this.onWsPacket); - oldWs.off("close", this.onWsClose); + oldWs.off('debug', this.onWsDebug); + oldWs.on('error', noop); + oldWs.off('error', this.onChildError); + oldWs.off('open', this.onWsOpen); + oldWs.off('packet', this.onWsPacket); + oldWs.off('close', this.onWsClose); oldWs.destroy(); } - const oldUdp = Reflect.get(this._state, "udp"); - const newUdp = Reflect.get(newState, "udp"); + const oldUdp = Reflect.get(this._state, 'udp'); + const newUdp = Reflect.get(newState, 'udp'); if (oldUdp && oldUdp !== newUdp) { - oldUdp.on("error", noop); - oldUdp.off("error", this.onChildError); - oldUdp.off("close", this.onUdpClose); - oldUdp.off("debug", this.onUdpDebug); + oldUdp.on('error', noop); + oldUdp.off('error', this.onChildError); + oldUdp.off('close', this.onUdpClose); + oldUdp.off('debug', this.onUdpDebug); oldUdp.destroy(); } const oldState = this._state; this._state = newState; - this.emit("stateChange", oldState, newState); + this.emit('stateChange', oldState, newState); this.debug?.(`state change: from ${stringifyState(oldState)} to ${stringifyState(newState)}`); } createWebSocket(endpoint) { const ws = new VoiceWebSocket(`wss://${endpoint}?v=4`, Boolean(this.debug)); - ws.on("error", this.onChildError); - ws.once("open", this.onWsOpen); - ws.on("packet", this.onWsPacket); - ws.once("close", this.onWsClose); - ws.on("debug", this.onWsDebug); + ws.on('error', this.onChildError); + ws.once('open', this.onWsOpen); + ws.on('packet', this.onWsPacket); + ws.once('close', this.onWsClose); + ws.on('debug', this.onWsDebug); return ws; } onChildError(error) { - this.emit("error", error); + this.emit('error', error); } onWsOpen() { if (this.state.code === 0 /* OpeningWs */) { @@ -532,13 +525,13 @@ to ${stringifyState(newState)}`); server_id: this.state.connectionOptions.serverId, user_id: this.state.connectionOptions.userId, session_id: this.state.connectionOptions.sessionId, - token: this.state.connectionOptions.token - } + token: this.state.connectionOptions.token, + }, }; this.state.ws.sendPacket(packet); this.state = { ...this.state, - code: 1 /* Identifying */ + code: 1 /* Identifying */, }; } else if (this.state.code === 5 /* Resuming */) { const packet = { @@ -546,8 +539,8 @@ to ${stringifyState(newState)}`); d: { server_id: this.state.connectionOptions.serverId, session_id: this.state.connectionOptions.sessionId, - token: this.state.connectionOptions.token - } + token: this.state.connectionOptions.token, + }, }; this.state.ws.sendPacket(packet); } @@ -558,11 +551,11 @@ to ${stringifyState(newState)}`); this.state = { ...this.state, code: 5 /* Resuming */, - ws: this.createWebSocket(this.state.connectionOptions.endpoint) + ws: this.createWebSocket(this.state.connectionOptions.endpoint), }; } else if (this.state.code !== 6 /* Closed */) { this.destroy(); - this.emit("close", code); + this.emit('close', code); } } onUdpClose() { @@ -570,7 +563,7 @@ to ${stringifyState(newState)}`); this.state = { ...this.state, code: 5 /* Resuming */, - ws: this.createWebSocket(this.state.connectionOptions.endpoint) + ws: this.createWebSocket(this.state.connectionOptions.endpoint), }; } } @@ -580,37 +573,42 @@ to ${stringifyState(newState)}`); } else if (packet.op === import_v42.VoiceOpcodes.Ready && this.state.code === 1 /* Identifying */) { const { ip, port, ssrc, modes } = packet.d; const udp = new VoiceUDPSocket({ ip, port }); - udp.on("error", this.onChildError); - udp.on("debug", this.onUdpDebug); - udp.once("close", this.onUdpClose); - udp.performIPDiscovery(ssrc).then((localConfig) => { - if (this.state.code !== 2 /* UdpHandshaking */) - return; - this.state.ws.sendPacket({ - op: import_v42.VoiceOpcodes.SelectProtocol, - d: { - protocol: "udp", - data: { - address: localConfig.ip, - port: localConfig.port, - mode: chooseEncryptionMode(modes) - } - } - }); - this.state = { - ...this.state, - code: 3 /* SelectingProtocol */ - }; - }).catch((error) => this.emit("error", error)); + udp.on('error', this.onChildError); + udp.on('debug', this.onUdpDebug); + udp.once('close', this.onUdpClose); + udp + .performIPDiscovery(ssrc) + .then(localConfig => { + if (this.state.code !== 2 /* UdpHandshaking */) return; + this.state.ws.sendPacket({ + op: import_v42.VoiceOpcodes.SelectProtocol, + d: { + protocol: 'udp', + data: { + address: localConfig.ip, + port: localConfig.port, + mode: chooseEncryptionMode(modes), + }, + }, + }); + this.state = { + ...this.state, + code: 3 /* SelectingProtocol */, + }; + }) + .catch(error => this.emit('error', error)); this.state = { ...this.state, code: 2 /* UdpHandshaking */, udp, connectionData: { - ssrc - } + ssrc, + }, }; - } else if (packet.op === import_v42.VoiceOpcodes.SessionDescription && this.state.code === 3 /* SelectingProtocol */) { + } else if ( + packet.op === import_v42.VoiceOpcodes.SessionDescription && + this.state.code === 3 /* SelectingProtocol */ + ) { const { mode: encryptionMode, secret_key: secretKey } = packet.d; this.state = { ...this.state, @@ -624,13 +622,13 @@ to ${stringifyState(newState)}`); nonce: 0, nonceBuffer: import_node_buffer3.Buffer.alloc(24), speaking: false, - packetsPlayed: 0 - } + packetsPlayed: 0, + }, }; } else if (packet.op === import_v42.VoiceOpcodes.Resumed && this.state.code === 5 /* Resuming */) { this.state = { ...this.state, - code: 4 /* Ready */ + code: 4 /* Ready */, }; this.state.connectionData.speaking = false; } @@ -643,16 +641,14 @@ to ${stringifyState(newState)}`); } prepareAudioPacket(opusPacket) { const state = this.state; - if (state.code !== 4 /* Ready */) - return; + if (state.code !== 4 /* Ready */) return; state.preparedPacket = this.createAudioPacket(opusPacket, state.connectionData); return state.preparedPacket; } dispatchAudio() { const state = this.state; - if (state.code !== 4 /* Ready */) - return false; - if (typeof state.preparedPacket !== "undefined") { + if (state.code !== 4 /* Ready */) return false; + if (typeof state.preparedPacket !== 'undefined') { this.playAudioPacket(state.preparedPacket); state.preparedPacket = void 0; return true; @@ -661,33 +657,28 @@ to ${stringifyState(newState)}`); } playAudioPacket(audioPacket) { const state = this.state; - if (state.code !== 4 /* Ready */) - return; + if (state.code !== 4 /* Ready */) return; const { connectionData } = state; connectionData.packetsPlayed++; connectionData.sequence++; connectionData.timestamp += TIMESTAMP_INC; - if (connectionData.sequence >= 2 ** 16) - connectionData.sequence = 0; - if (connectionData.timestamp >= 2 ** 32) - connectionData.timestamp = 0; + if (connectionData.sequence >= 2 ** 16) connectionData.sequence = 0; + if (connectionData.timestamp >= 2 ** 32) connectionData.timestamp = 0; this.setSpeaking(true); state.udp.send(audioPacket); } setSpeaking(speaking) { const state = this.state; - if (state.code !== 4 /* Ready */) - return; - if (state.connectionData.speaking === speaking) - return; + if (state.code !== 4 /* Ready */) return; + if (state.connectionData.speaking === speaking) return; state.connectionData.speaking = speaking; state.ws.sendPacket({ op: import_v42.VoiceOpcodes.Speaking, d: { speaking: speaking ? 1 : 0, delay: 0, - ssrc: state.connectionData.ssrc - } + ssrc: state.connectionData.ssrc, + }, }); } createAudioPacket(opusPacket, connectionData) { @@ -703,34 +694,30 @@ to ${stringifyState(newState)}`); } encryptOpusPacket(opusPacket, connectionData) { const { secretKey, encryptionMode } = connectionData; - if (encryptionMode === "xsalsa20_poly1305_lite") { + if (encryptionMode === 'xsalsa20_poly1305_lite') { connectionData.nonce++; - if (connectionData.nonce > MAX_NONCE_SIZE) - connectionData.nonce = 0; + if (connectionData.nonce > MAX_NONCE_SIZE) connectionData.nonce = 0; connectionData.nonceBuffer.writeUInt32BE(connectionData.nonce, 0); - return [ - methods.close(opusPacket, connectionData.nonceBuffer, secretKey), - connectionData.nonceBuffer.slice(0, 4) - ]; - } else if (encryptionMode === "xsalsa20_poly1305_suffix") { + return [methods.close(opusPacket, connectionData.nonceBuffer, secretKey), connectionData.nonceBuffer.slice(0, 4)]; + } else if (encryptionMode === 'xsalsa20_poly1305_suffix') { const random = methods.random(24, connectionData.nonceBuffer); return [methods.close(opusPacket, random, secretKey), random]; } return [methods.close(opusPacket, nonce, secretKey)]; } }; -__name(Networking, "Networking"); +__name(Networking, 'Networking'); // src/receive/VoiceReceiver.ts -var import_node_buffer5 = require("buffer"); -var import_v43 = require("discord-api-types/voice/v4"); +var import_node_buffer5 = require('buffer'); +var import_v43 = require('discord-api-types/voice/v4'); // src/receive/AudioReceiveStream.ts -var import_node_stream = require("stream"); +var import_node_stream = require('stream'); // src/audio/AudioPlayer.ts -var import_node_buffer4 = require("buffer"); -var import_node_events4 = require("events"); +var import_node_buffer4 = require('buffer'); +var import_node_events4 = require('events'); // src/audio/AudioPlayerError.ts var AudioPlayerError = class extends Error { @@ -742,7 +729,7 @@ var AudioPlayerError = class extends Error { this.stack = error.stack; } }; -__name(AudioPlayerError, "AudioPlayerError"); +__name(AudioPlayerError, 'AudioPlayerError'); // src/audio/PlayerSubscription.ts var PlayerSubscription = class { @@ -753,36 +740,36 @@ var PlayerSubscription = class { this.player = player; } unsubscribe() { - this.connection["onSubscriptionRemoved"](this); - this.player["unsubscribe"](this); + this.connection['onSubscriptionRemoved'](this); + this.player['unsubscribe'](this); } }; -__name(PlayerSubscription, "PlayerSubscription"); +__name(PlayerSubscription, 'PlayerSubscription'); // src/audio/AudioPlayer.ts var SILENCE_FRAME = import_node_buffer4.Buffer.from([248, 255, 254]); -var NoSubscriberBehavior = /* @__PURE__ */ ((NoSubscriberBehavior2) => { - NoSubscriberBehavior2["Pause"] = "pause"; - NoSubscriberBehavior2["Play"] = "play"; - NoSubscriberBehavior2["Stop"] = "stop"; +var NoSubscriberBehavior = /* @__PURE__ */ (NoSubscriberBehavior2 => { + NoSubscriberBehavior2['Pause'] = 'pause'; + NoSubscriberBehavior2['Play'] = 'play'; + NoSubscriberBehavior2['Stop'] = 'stop'; return NoSubscriberBehavior2; })(NoSubscriberBehavior || {}); -var AudioPlayerStatus = /* @__PURE__ */ ((AudioPlayerStatus2) => { - AudioPlayerStatus2["AutoPaused"] = "autopaused"; - AudioPlayerStatus2["Buffering"] = "buffering"; - AudioPlayerStatus2["Idle"] = "idle"; - AudioPlayerStatus2["Paused"] = "paused"; - AudioPlayerStatus2["Playing"] = "playing"; +var AudioPlayerStatus = /* @__PURE__ */ (AudioPlayerStatus2 => { + AudioPlayerStatus2['AutoPaused'] = 'autopaused'; + AudioPlayerStatus2['Buffering'] = 'buffering'; + AudioPlayerStatus2['Idle'] = 'idle'; + AudioPlayerStatus2['Paused'] = 'paused'; + AudioPlayerStatus2['Playing'] = 'playing'; return AudioPlayerStatus2; })(AudioPlayerStatus || {}); function stringifyState2(state) { return JSON.stringify({ ...state, - resource: Reflect.has(state, "resource"), - stepTimeout: Reflect.has(state, "stepTimeout") + resource: Reflect.has(state, 'resource'), + stepTimeout: Reflect.has(state, 'stepTimeout'), }); } -__name(stringifyState2, "stringifyState"); +__name(stringifyState2, 'stringifyState'); var AudioPlayer = class extends import_node_events4.EventEmitter { _state; subscribers = []; @@ -790,23 +777,25 @@ var AudioPlayer = class extends import_node_events4.EventEmitter { debug; constructor(options = {}) { super(); - this._state = { status: "idle" /* Idle */ }; + this._state = { status: 'idle' /* Idle */ }; this.behaviors = { - noSubscriber: "pause" /* Pause */, + noSubscriber: 'pause' /* Pause */, maxMissedFrames: 5, - ...options.behaviors + ...options.behaviors, }; - this.debug = options.debug === false ? null : (message) => this.emit("debug", message); + this.debug = options.debug === false ? null : message => this.emit('debug', message); } get playable() { - return this.subscribers.filter(({ connection }) => connection.state.status === "ready" /* Ready */).map(({ connection }) => connection); + return this.subscribers + .filter(({ connection }) => connection.state.status === 'ready' /* Ready */) + .map(({ connection }) => connection); } subscribe(connection) { - const existingSubscription = this.subscribers.find((subscription) => subscription.connection === connection); + const existingSubscription = this.subscribers.find(subscription => subscription.connection === connection); if (!existingSubscription) { const subscription = new PlayerSubscription(connection, this); this.subscribers.push(subscription); - setImmediate(() => this.emit("subscribe", subscription)); + setImmediate(() => this.emit('subscribe', subscription)); return subscription; } return existingSubscription; @@ -817,7 +806,7 @@ var AudioPlayer = class extends import_node_events4.EventEmitter { if (exists) { this.subscribers.splice(index, 1); subscription.connection.setSpeaking(false); - this.emit("unsubscribe", subscription); + this.emit('unsubscribe', subscription); } return exists; } @@ -826,30 +815,36 @@ var AudioPlayer = class extends import_node_events4.EventEmitter { } set state(newState) { const oldState = this._state; - const newResource = Reflect.get(newState, "resource"); - if (oldState.status !== "idle" /* Idle */ && oldState.resource !== newResource) { - oldState.resource.playStream.on("error", noop); - oldState.resource.playStream.off("error", oldState.onStreamError); + const newResource = Reflect.get(newState, 'resource'); + if (oldState.status !== 'idle' /* Idle */ && oldState.resource !== newResource) { + oldState.resource.playStream.on('error', noop); + oldState.resource.playStream.off('error', oldState.onStreamError); oldState.resource.audioPlayer = void 0; oldState.resource.playStream.destroy(); oldState.resource.playStream.read(); } - if (oldState.status === "buffering" /* Buffering */ && (newState.status !== "buffering" /* Buffering */ || newState.resource !== oldState.resource)) { - oldState.resource.playStream.off("end", oldState.onFailureCallback); - oldState.resource.playStream.off("close", oldState.onFailureCallback); - oldState.resource.playStream.off("finish", oldState.onFailureCallback); - oldState.resource.playStream.off("readable", oldState.onReadableCallback); + if ( + oldState.status === 'buffering' /* Buffering */ && + (newState.status !== 'buffering' /* Buffering */ || newState.resource !== oldState.resource) + ) { + oldState.resource.playStream.off('end', oldState.onFailureCallback); + oldState.resource.playStream.off('close', oldState.onFailureCallback); + oldState.resource.playStream.off('finish', oldState.onFailureCallback); + oldState.resource.playStream.off('readable', oldState.onReadableCallback); } - if (newState.status === "idle" /* Idle */) { + if (newState.status === 'idle' /* Idle */) { this._signalStopSpeaking(); deleteAudioPlayer(this); } if (newResource) { addAudioPlayer(this); } - const didChangeResources = oldState.status !== "idle" /* Idle */ && newState.status === "playing" /* Playing */ && oldState.resource !== newState.resource; + const didChangeResources = + oldState.status !== 'idle' /* Idle */ && + newState.status === 'playing' /* Playing */ && + oldState.resource !== newState.resource; this._state = newState; - this.emit("stateChange", oldState, this._state); + this.emit('stateChange', oldState, this._state); if (oldState.status !== newState.status || didChangeResources) { this.emit(newState.status, oldState, this._state); } @@ -859,92 +854,89 @@ to ${stringifyState2(newState)}`); } play(resource) { if (resource.ended) { - throw new Error("Cannot play a resource that has already ended."); + throw new Error('Cannot play a resource that has already ended.'); } if (resource.audioPlayer) { if (resource.audioPlayer === this) { return; } - throw new Error("Resource is already being played by another audio player."); + throw new Error('Resource is already being played by another audio player.'); } resource.audioPlayer = this; - const onStreamError = /* @__PURE__ */ __name((error) => { - if (this.state.status !== "idle" /* Idle */) { - this.emit("error", new AudioPlayerError(error, this.state.resource)); + const onStreamError = /* @__PURE__ */ __name(error => { + if (this.state.status !== 'idle' /* Idle */) { + this.emit('error', new AudioPlayerError(error, this.state.resource)); } - if (this.state.status !== "idle" /* Idle */ && this.state.resource === resource) { + if (this.state.status !== 'idle' /* Idle */ && this.state.resource === resource) { this.state = { - status: "idle" /* Idle */ + status: 'idle' /* Idle */, }; } - }, "onStreamError"); - resource.playStream.once("error", onStreamError); + }, 'onStreamError'); + resource.playStream.once('error', onStreamError); if (resource.started) { this.state = { - status: "playing" /* Playing */, + status: 'playing' /* Playing */, missedFrames: 0, playbackDuration: 0, resource, - onStreamError + onStreamError, }; } else { const onReadableCallback = /* @__PURE__ */ __name(() => { - if (this.state.status === "buffering" /* Buffering */ && this.state.resource === resource) { + if (this.state.status === 'buffering' /* Buffering */ && this.state.resource === resource) { this.state = { - status: "playing" /* Playing */, + status: 'playing' /* Playing */, missedFrames: 0, playbackDuration: 0, resource, - onStreamError + onStreamError, }; } - }, "onReadableCallback"); + }, 'onReadableCallback'); const onFailureCallback = /* @__PURE__ */ __name(() => { - if (this.state.status === "buffering" /* Buffering */ && this.state.resource === resource) { + if (this.state.status === 'buffering' /* Buffering */ && this.state.resource === resource) { this.state = { - status: "idle" /* Idle */ + status: 'idle' /* Idle */, }; } - }, "onFailureCallback"); - resource.playStream.once("readable", onReadableCallback); - resource.playStream.once("end", onFailureCallback); - resource.playStream.once("close", onFailureCallback); - resource.playStream.once("finish", onFailureCallback); + }, 'onFailureCallback'); + resource.playStream.once('readable', onReadableCallback); + resource.playStream.once('end', onFailureCallback); + resource.playStream.once('close', onFailureCallback); + resource.playStream.once('finish', onFailureCallback); this.state = { - status: "buffering" /* Buffering */, + status: 'buffering' /* Buffering */, resource, onReadableCallback, onFailureCallback, - onStreamError + onStreamError, }; } } pause(interpolateSilence = true) { - if (this.state.status !== "playing" /* Playing */) - return false; + if (this.state.status !== 'playing' /* Playing */) return false; this.state = { ...this.state, - status: "paused" /* Paused */, - silencePacketsRemaining: interpolateSilence ? 5 : 0 + status: 'paused' /* Paused */, + silencePacketsRemaining: interpolateSilence ? 5 : 0, }; return true; } unpause() { - if (this.state.status !== "paused" /* Paused */) - return false; + if (this.state.status !== 'paused' /* Paused */) return false; this.state = { ...this.state, - status: "playing" /* Playing */, - missedFrames: 0 + status: 'playing' /* Playing */, + missedFrames: 0, }; return true; } stop(force = false) { - if (this.state.status === "idle" /* Idle */) - return false; + if (this.state.status === 'idle' /* Idle */) return false; if (force || this.state.resource.silencePaddingFrames === 0) { this.state = { - status: "idle" /* Idle */ + status: 'idle' /* Idle */, }; } else if (this.state.resource.silenceRemaining === -1) { this.state.resource.silenceRemaining = this.state.resource.silencePaddingFrames; @@ -953,11 +945,10 @@ to ${stringifyState2(newState)}`); } checkPlayable() { const state = this._state; - if (state.status === "idle" /* Idle */ || state.status === "buffering" /* Buffering */) - return false; + if (state.status === 'idle' /* Idle */ || state.status === 'buffering' /* Buffering */) return false; if (!state.resource.readable) { this.state = { - status: "idle" /* Idle */ + status: 'idle' /* Idle */, }; return false; } @@ -965,25 +956,23 @@ to ${stringifyState2(newState)}`); } _stepDispatch() { const state = this._state; - if (state.status === "idle" /* Idle */ || state.status === "buffering" /* Buffering */) - return; + if (state.status === 'idle' /* Idle */ || state.status === 'buffering' /* Buffering */) return; for (const connection of this.playable) { connection.dispatchAudio(); } } _stepPrepare() { const state = this._state; - if (state.status === "idle" /* Idle */ || state.status === "buffering" /* Buffering */) - return; + if (state.status === 'idle' /* Idle */ || state.status === 'buffering' /* Buffering */) return; const playable = this.playable; - if (state.status === "autopaused" /* AutoPaused */ && playable.length > 0) { + if (state.status === 'autopaused' /* AutoPaused */ && playable.length > 0) { this.state = { ...state, - status: "playing" /* Playing */, - missedFrames: 0 + status: 'playing' /* Playing */, + missedFrames: 0, }; } - if (state.status === "paused" /* Paused */ || state.status === "autopaused" /* AutoPaused */) { + if (state.status === 'paused' /* Paused */ || state.status === 'autopaused' /* AutoPaused */) { if (state.silencePacketsRemaining > 0) { state.silencePacketsRemaining--; this._preparePacket(SILENCE_FRAME, playable, state); @@ -994,19 +983,19 @@ to ${stringifyState2(newState)}`); return; } if (playable.length === 0) { - if (this.behaviors.noSubscriber === "pause" /* Pause */) { + if (this.behaviors.noSubscriber === 'pause' /* Pause */) { this.state = { ...state, - status: "autopaused" /* AutoPaused */, - silencePacketsRemaining: 5 + status: 'autopaused' /* AutoPaused */, + silencePacketsRemaining: 5, }; return; - } else if (this.behaviors.noSubscriber === "stop" /* Stop */) { + } else if (this.behaviors.noSubscriber === 'stop' /* Stop */) { this.stop(true); } } const packet = state.resource.read(); - if (state.status === "playing" /* Playing */) { + if (state.status === 'playing' /* Playing */) { if (packet) { this._preparePacket(packet, playable, state); state.missedFrames = 0; @@ -1031,39 +1020,44 @@ to ${stringifyState2(newState)}`); } } }; -__name(AudioPlayer, "AudioPlayer"); +__name(AudioPlayer, 'AudioPlayer'); function createAudioPlayer(options) { return new AudioPlayer(options); } -__name(createAudioPlayer, "createAudioPlayer"); +__name(createAudioPlayer, 'createAudioPlayer'); // src/receive/AudioReceiveStream.ts -var EndBehaviorType = /* @__PURE__ */ ((EndBehaviorType2) => { - EndBehaviorType2[EndBehaviorType2["Manual"] = 0] = "Manual"; - EndBehaviorType2[EndBehaviorType2["AfterSilence"] = 1] = "AfterSilence"; - EndBehaviorType2[EndBehaviorType2["AfterInactivity"] = 2] = "AfterInactivity"; +var EndBehaviorType = /* @__PURE__ */ (EndBehaviorType2 => { + EndBehaviorType2[(EndBehaviorType2['Manual'] = 0)] = 'Manual'; + EndBehaviorType2[(EndBehaviorType2['AfterSilence'] = 1)] = 'AfterSilence'; + EndBehaviorType2[(EndBehaviorType2['AfterInactivity'] = 2)] = 'AfterInactivity'; return EndBehaviorType2; })(EndBehaviorType || {}); function createDefaultAudioReceiveStreamOptions() { return { end: { - behavior: 0 /* Manual */ - } + behavior: 0 /* Manual */, + }, }; } -__name(createDefaultAudioReceiveStreamOptions, "createDefaultAudioReceiveStreamOptions"); +__name(createDefaultAudioReceiveStreamOptions, 'createDefaultAudioReceiveStreamOptions'); var AudioReceiveStream = class extends import_node_stream.Readable { end; endTimeout; constructor({ end, ...options }) { super({ ...options, - objectMode: true + objectMode: true, }); this.end = end; } push(buffer) { - if (buffer && (this.end.behavior === 2 /* AfterInactivity */ || this.end.behavior === 1 /* AfterSilence */ && (buffer.compare(SILENCE_FRAME) !== 0 || typeof this.endTimeout === "undefined"))) { + if ( + buffer && + (this.end.behavior === 2 /* AfterInactivity */ || + (this.end.behavior === 1 /* AfterSilence */ && + (buffer.compare(SILENCE_FRAME) !== 0 || typeof this.endTimeout === 'undefined'))) + ) { this.renewEndTimeout(this.end); } return super.push(buffer); @@ -1074,13 +1068,12 @@ var AudioReceiveStream = class extends import_node_stream.Readable { } this.endTimeout = setTimeout(() => this.push(null), end.duration); } - _read() { - } + _read() {} }; -__name(AudioReceiveStream, "AudioReceiveStream"); +__name(AudioReceiveStream, 'AudioReceiveStream'); // src/receive/SSRCMap.ts -var import_node_events5 = require("events"); +var import_node_events5 = require('events'); var SSRCMap = class extends import_node_events5.EventEmitter { map; constructor() { @@ -1091,15 +1084,14 @@ var SSRCMap = class extends import_node_events5.EventEmitter { const existing = this.map.get(data.audioSSRC); const newValue = { ...this.map.get(data.audioSSRC), - ...data + ...data, }; this.map.set(data.audioSSRC, newValue); - if (!existing) - this.emit("create", newValue); - this.emit("update", existing, newValue); + if (!existing) this.emit('create', newValue); + this.emit('update', existing, newValue); } get(target) { - if (typeof target === "number") { + if (typeof target === 'number') { return this.map.get(target); } for (const data of this.map.values()) { @@ -1110,28 +1102,28 @@ var SSRCMap = class extends import_node_events5.EventEmitter { return void 0; } delete(target) { - if (typeof target === "number") { + if (typeof target === 'number') { const existing = this.map.get(target); if (existing) { this.map.delete(target); - this.emit("delete", existing); + this.emit('delete', existing); } return existing; } for (const [audioSSRC, data] of this.map.entries()) { if (data.userId === target) { this.map.delete(audioSSRC); - this.emit("delete", data); + this.emit('delete', data); return data; } } return void 0; } }; -__name(SSRCMap, "SSRCMap"); +__name(SSRCMap, 'SSRCMap'); // src/receive/SpeakingMap.ts -var import_node_events6 = require("events"); +var import_node_events6 = require('events'); var _SpeakingMap = class extends import_node_events6.EventEmitter { users; speakingTimeouts; @@ -1146,7 +1138,7 @@ var _SpeakingMap = class extends import_node_events6.EventEmitter { clearTimeout(timeout); } else { this.users.set(userId, Date.now()); - this.emit("start", userId); + this.emit('start', userId); } this.startTimeout(userId); } @@ -1154,16 +1146,16 @@ var _SpeakingMap = class extends import_node_events6.EventEmitter { this.speakingTimeouts.set( userId, setTimeout(() => { - this.emit("end", userId); + this.emit('end', userId); this.speakingTimeouts.delete(userId); this.users.delete(userId); - }, _SpeakingMap.DELAY) + }, _SpeakingMap.DELAY), ); } }; var SpeakingMap = _SpeakingMap; -__name(SpeakingMap, "SpeakingMap"); -__publicField(SpeakingMap, "DELAY", 100); +__name(SpeakingMap, 'SpeakingMap'); +__publicField(SpeakingMap, 'DELAY', 100); // src/receive/VoiceReceiver.ts var VoiceReceiver = class { @@ -1182,38 +1174,44 @@ var VoiceReceiver = class { this.onUdpMessage = this.onUdpMessage.bind(this); } onWsPacket(packet) { - if (packet.op === import_v43.VoiceOpcodes.ClientDisconnect && typeof packet.d?.user_id === "string") { + if (packet.op === import_v43.VoiceOpcodes.ClientDisconnect && typeof packet.d?.user_id === 'string') { this.ssrcMap.delete(packet.d.user_id); - } else if (packet.op === import_v43.VoiceOpcodes.Speaking && typeof packet.d?.user_id === "string" && typeof packet.d?.ssrc === "number") { + } else if ( + packet.op === import_v43.VoiceOpcodes.Speaking && + typeof packet.d?.user_id === 'string' && + typeof packet.d?.ssrc === 'number' + ) { this.ssrcMap.update({ userId: packet.d.user_id, audioSSRC: packet.d.ssrc }); - } else if (packet.op === import_v43.VoiceOpcodes.ClientConnect && typeof packet.d?.user_id === "string" && typeof packet.d?.audio_ssrc === "number") { + } else if ( + packet.op === import_v43.VoiceOpcodes.ClientConnect && + typeof packet.d?.user_id === 'string' && + typeof packet.d?.audio_ssrc === 'number' + ) { this.ssrcMap.update({ userId: packet.d.user_id, audioSSRC: packet.d.audio_ssrc, - videoSSRC: packet.d.video_ssrc === 0 ? void 0 : packet.d.video_ssrc + videoSSRC: packet.d.video_ssrc === 0 ? void 0 : packet.d.video_ssrc, }); } } decrypt(buffer, mode, nonce2, secretKey) { let end; - if (mode === "xsalsa20_poly1305_lite") { + if (mode === 'xsalsa20_poly1305_lite') { buffer.copy(nonce2, 0, buffer.length - 4); end = buffer.length - 4; - } else if (mode === "xsalsa20_poly1305_suffix") { + } else if (mode === 'xsalsa20_poly1305_suffix') { buffer.copy(nonce2, 0, buffer.length - 24); end = buffer.length - 24; } else { buffer.copy(nonce2, 0, 0, 12); } const decrypted = methods.open(buffer.slice(12, end), nonce2, secretKey); - if (!decrypted) - return; + if (!decrypted) return; return import_node_buffer5.Buffer.from(decrypted); } parsePacket(buffer, mode, nonce2, secretKey) { let packet = this.decrypt(buffer, mode, nonce2, secretKey); - if (!packet) - return; + if (!packet) return; if (packet[0] === 190 && packet[1] === 222) { const headerExtensionLength = packet.readUInt16BE(2); packet = packet.subarray(4 + 4 * headerExtensionLength); @@ -1221,59 +1219,55 @@ var VoiceReceiver = class { return packet; } onUdpMessage(msg) { - if (msg.length <= 8) - return; + if (msg.length <= 8) return; const ssrc = msg.readUInt32BE(8); const userData = this.ssrcMap.get(ssrc); - if (!userData) - return; + if (!userData) return; this.speaking.onPacket(userData.userId); const stream = this.subscriptions.get(userData.userId); - if (!stream) - return; + if (!stream) return; if (this.connectionData.encryptionMode && this.connectionData.nonceBuffer && this.connectionData.secretKey) { const packet = this.parsePacket( msg, this.connectionData.encryptionMode, this.connectionData.nonceBuffer, - this.connectionData.secretKey + this.connectionData.secretKey, ); if (packet) { stream.push(packet); } else { - stream.destroy(new Error("Failed to parse packet")); + stream.destroy(new Error('Failed to parse packet')); } } } subscribe(userId, options) { const existing = this.subscriptions.get(userId); - if (existing) - return existing; + if (existing) return existing; const stream = new AudioReceiveStream({ ...createDefaultAudioReceiveStreamOptions(), - ...options + ...options, }); - stream.once("close", () => this.subscriptions.delete(userId)); + stream.once('close', () => this.subscriptions.delete(userId)); this.subscriptions.set(userId, stream); return stream; } }; -__name(VoiceReceiver, "VoiceReceiver"); +__name(VoiceReceiver, 'VoiceReceiver'); // src/VoiceConnection.ts -var VoiceConnectionStatus = /* @__PURE__ */ ((VoiceConnectionStatus2) => { - VoiceConnectionStatus2["Connecting"] = "connecting"; - VoiceConnectionStatus2["Destroyed"] = "destroyed"; - VoiceConnectionStatus2["Disconnected"] = "disconnected"; - VoiceConnectionStatus2["Ready"] = "ready"; - VoiceConnectionStatus2["Signalling"] = "signalling"; +var VoiceConnectionStatus = /* @__PURE__ */ (VoiceConnectionStatus2 => { + VoiceConnectionStatus2['Connecting'] = 'connecting'; + VoiceConnectionStatus2['Destroyed'] = 'destroyed'; + VoiceConnectionStatus2['Disconnected'] = 'disconnected'; + VoiceConnectionStatus2['Ready'] = 'ready'; + VoiceConnectionStatus2['Signalling'] = 'signalling'; return VoiceConnectionStatus2; })(VoiceConnectionStatus || {}); -var VoiceConnectionDisconnectReason = /* @__PURE__ */ ((VoiceConnectionDisconnectReason2) => { - VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["WebSocketClose"] = 0] = "WebSocketClose"; - VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["AdapterUnavailable"] = 1] = "AdapterUnavailable"; - VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["EndpointRemoved"] = 2] = "EndpointRemoved"; - VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["Manual"] = 3] = "Manual"; +var VoiceConnectionDisconnectReason = /* @__PURE__ */ (VoiceConnectionDisconnectReason2 => { + VoiceConnectionDisconnectReason2[(VoiceConnectionDisconnectReason2['WebSocketClose'] = 0)] = 'WebSocketClose'; + VoiceConnectionDisconnectReason2[(VoiceConnectionDisconnectReason2['AdapterUnavailable'] = 1)] = 'AdapterUnavailable'; + VoiceConnectionDisconnectReason2[(VoiceConnectionDisconnectReason2['EndpointRemoved'] = 2)] = 'EndpointRemoved'; + VoiceConnectionDisconnectReason2[(VoiceConnectionDisconnectReason2['Manual'] = 3)] = 'Manual'; return VoiceConnectionDisconnectReason2; })(VoiceConnectionDisconnectReason || {}); var VoiceConnection = class extends import_node_events7.EventEmitter { @@ -1285,7 +1279,7 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { debug; constructor(joinConfig, options) { super(); - this.debug = options.debug ? (message) => this.emit("debug", message) : null; + this.debug = options.debug ? message => this.emit('debug', message) : null; this.rejoinAttempts = 0; this.receiver = new VoiceReceiver(this); this.onNetworkingClose = this.onNetworkingClose.bind(this); @@ -1293,14 +1287,14 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { this.onNetworkingError = this.onNetworkingError.bind(this); this.onNetworkingDebug = this.onNetworkingDebug.bind(this); const adapter = options.adapterCreator({ - onVoiceServerUpdate: (data) => this.addServerPacket(data), - onVoiceStateUpdate: (data) => this.addStatePacket(data), - destroy: () => this.destroy(false) + onVoiceServerUpdate: data => this.addServerPacket(data), + onVoiceStateUpdate: data => this.addStatePacket(data), + destroy: () => this.destroy(false), }); - this._state = { status: "signalling" /* Signalling */, adapter }; + this._state = { status: 'signalling' /* Signalling */, adapter }; this.packets = { server: void 0, - state: void 0 + state: void 0, }; this.joinConfig = joinConfig; } @@ -1309,38 +1303,36 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { } set state(newState) { const oldState = this._state; - const oldNetworking = Reflect.get(oldState, "networking"); - const newNetworking = Reflect.get(newState, "networking"); - const oldSubscription = Reflect.get(oldState, "subscription"); - const newSubscription = Reflect.get(newState, "subscription"); + const oldNetworking = Reflect.get(oldState, 'networking'); + const newNetworking = Reflect.get(newState, 'networking'); + const oldSubscription = Reflect.get(oldState, 'subscription'); + const newSubscription = Reflect.get(newState, 'subscription'); if (oldNetworking !== newNetworking) { if (oldNetworking) { - oldNetworking.on("error", noop); - oldNetworking.off("debug", this.onNetworkingDebug); - oldNetworking.off("error", this.onNetworkingError); - oldNetworking.off("close", this.onNetworkingClose); - oldNetworking.off("stateChange", this.onNetworkingStateChange); + oldNetworking.on('error', noop); + oldNetworking.off('debug', this.onNetworkingDebug); + oldNetworking.off('error', this.onNetworkingError); + oldNetworking.off('close', this.onNetworkingClose); + oldNetworking.off('stateChange', this.onNetworkingStateChange); oldNetworking.destroy(); } - if (newNetworking) - this.updateReceiveBindings(newNetworking.state, oldNetworking?.state); + if (newNetworking) this.updateReceiveBindings(newNetworking.state, oldNetworking?.state); } - if (newState.status === "ready" /* Ready */) { + if (newState.status === 'ready' /* Ready */) { this.rejoinAttempts = 0; - } else if (newState.status === "destroyed" /* Destroyed */) { + } else if (newState.status === 'destroyed' /* Destroyed */) { for (const stream of this.receiver.subscriptions.values()) { - if (!stream.destroyed) - stream.destroy(); + if (!stream.destroyed) stream.destroy(); } } - if (oldState.status !== "destroyed" /* Destroyed */ && newState.status === "destroyed" /* Destroyed */) { + if (oldState.status !== 'destroyed' /* Destroyed */ && newState.status === 'destroyed' /* Destroyed */) { oldState.adapter.destroy(); } this._state = newState; if (oldSubscription && oldSubscription !== newSubscription) { oldSubscription.unsubscribe(); } - this.emit("stateChange", oldState, newState); + this.emit('stateChange', oldState, newState); if (oldState.status !== newState.status) { this.emit(newState.status, oldState, newState); } @@ -1349,133 +1341,123 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { this.packets.server = packet; if (packet.endpoint) { this.configureNetworking(); - } else if (this.state.status !== "destroyed" /* Destroyed */) { + } else if (this.state.status !== 'destroyed' /* Destroyed */) { this.state = { ...this.state, - status: "disconnected" /* Disconnected */, - reason: 2 /* EndpointRemoved */ + status: 'disconnected' /* Disconnected */, + reason: 2 /* EndpointRemoved */, }; } } addStatePacket(packet) { this.packets.state = packet; - if (typeof packet.self_deaf !== "undefined") - this.joinConfig.selfDeaf = packet.self_deaf; - if (typeof packet.self_mute !== "undefined") - this.joinConfig.selfMute = packet.self_mute; - if (packet.channel_id) - this.joinConfig.channelId = packet.channel_id; + if (typeof packet.self_deaf !== 'undefined') this.joinConfig.selfDeaf = packet.self_deaf; + if (typeof packet.self_mute !== 'undefined') this.joinConfig.selfMute = packet.self_mute; + if (packet.channel_id) this.joinConfig.channelId = packet.channel_id; } updateReceiveBindings(newState, oldState) { - const oldWs = Reflect.get(oldState ?? {}, "ws"); - const newWs = Reflect.get(newState, "ws"); - const oldUdp = Reflect.get(oldState ?? {}, "udp"); - const newUdp = Reflect.get(newState, "udp"); + const oldWs = Reflect.get(oldState ?? {}, 'ws'); + const newWs = Reflect.get(newState, 'ws'); + const oldUdp = Reflect.get(oldState ?? {}, 'udp'); + const newUdp = Reflect.get(newState, 'udp'); if (oldWs !== newWs) { - oldWs?.off("packet", this.receiver.onWsPacket); - newWs?.on("packet", this.receiver.onWsPacket); + oldWs?.off('packet', this.receiver.onWsPacket); + newWs?.on('packet', this.receiver.onWsPacket); } if (oldUdp !== newUdp) { - oldUdp?.off("message", this.receiver.onUdpMessage); - newUdp?.on("message", this.receiver.onUdpMessage); + oldUdp?.off('message', this.receiver.onUdpMessage); + newUdp?.on('message', this.receiver.onUdpMessage); } - this.receiver.connectionData = Reflect.get(newState, "connectionData") ?? {}; + this.receiver.connectionData = Reflect.get(newState, 'connectionData') ?? {}; } configureNetworking() { const { server, state } = this.packets; - if (!server || !state || this.state.status === "destroyed" /* Destroyed */ || !server.endpoint) - return; + if (!server || !state || this.state.status === 'destroyed' /* Destroyed */ || !server.endpoint) return; const networking = new Networking( { endpoint: server.endpoint, serverId: server.guild_id ?? server.channel_id, token: server.token, sessionId: state.session_id, - userId: state.user_id + userId: state.user_id, }, - Boolean(this.debug) + Boolean(this.debug), ); - networking.once("close", this.onNetworkingClose); - networking.on("stateChange", this.onNetworkingStateChange); - networking.on("error", this.onNetworkingError); - networking.on("debug", this.onNetworkingDebug); + networking.once('close', this.onNetworkingClose); + networking.on('stateChange', this.onNetworkingStateChange); + networking.on('error', this.onNetworkingError); + networking.on('debug', this.onNetworkingDebug); this.state = { ...this.state, - status: "connecting" /* Connecting */, - networking + status: 'connecting' /* Connecting */, + networking, }; } onNetworkingClose(code) { - if (this.state.status === "destroyed" /* Destroyed */) - return; + if (this.state.status === 'destroyed' /* Destroyed */) return; if (code === 4014) { this.state = { ...this.state, - status: "disconnected" /* Disconnected */, + status: 'disconnected' /* Disconnected */, reason: 0 /* WebSocketClose */, - closeCode: code + closeCode: code, }; } else { this.state = { ...this.state, - status: "signalling" /* Signalling */ + status: 'signalling' /* Signalling */, }; this.rejoinAttempts++; if (!this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) { this.state = { ...this.state, - status: "disconnected" /* Disconnected */, - reason: 1 /* AdapterUnavailable */ + status: 'disconnected' /* Disconnected */, + reason: 1 /* AdapterUnavailable */, }; } } } onNetworkingStateChange(oldState, newState) { this.updateReceiveBindings(newState, oldState); - if (oldState.code === newState.code) - return; - if (this.state.status !== "connecting" /* Connecting */ && this.state.status !== "ready" /* Ready */) - return; + if (oldState.code === newState.code) return; + if (this.state.status !== 'connecting' /* Connecting */ && this.state.status !== 'ready' /* Ready */) return; if (newState.code === 4 /* Ready */) { this.state = { ...this.state, - status: "ready" /* Ready */ + status: 'ready' /* Ready */, }; } else if (newState.code !== 6 /* Closed */) { this.state = { ...this.state, - status: "connecting" /* Connecting */ + status: 'connecting' /* Connecting */, }; } } onNetworkingError(error) { - this.emit("error", error); + this.emit('error', error); } onNetworkingDebug(message) { this.debug?.(`[NW] ${message}`); } prepareAudioPacket(buffer) { const state = this.state; - if (state.status !== "ready" /* Ready */) - return; + if (state.status !== 'ready' /* Ready */) return; return state.networking.prepareAudioPacket(buffer); } dispatchAudio() { const state = this.state; - if (state.status !== "ready" /* Ready */) - return; + if (state.status !== 'ready' /* Ready */) return; return state.networking.dispatchAudio(); } playOpusPacket(buffer) { const state = this.state; - if (state.status !== "ready" /* Ready */) - return; + if (state.status !== 'ready' /* Ready */) return; state.networking.prepareAudioPacket(buffer); return state.networking.dispatchAudio(); } destroy(adapterAvailable = true) { - if (this.state.status === "destroyed" /* Destroyed */) { - throw new Error("Cannot destroy VoiceConnection - it has already been destroyed"); + if (this.state.status === 'destroyed' /* Destroyed */) { + throw new Error('Cannot destroy VoiceConnection - it has already been destroyed'); } if (getVoiceConnection(this.joinConfig.guildId, this.joinConfig.group) === this) { untrackVoiceConnection(this); @@ -1484,11 +1466,11 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { this.state.adapter.sendPayload(createJoinVoiceChannelPayload({ ...this.joinConfig, channelId: null })); } this.state = { - status: "destroyed" /* Destroyed */ + status: 'destroyed' /* Destroyed */, }; } disconnect() { - if (this.state.status === "destroyed" /* Destroyed */ || this.state.status === "signalling" /* Signalling */) { + if (this.state.status === 'destroyed' /* Destroyed */ || this.state.status === 'signalling' /* Signalling */) { return false; } this.joinConfig.channelId = null; @@ -1496,31 +1478,30 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { this.state = { adapter: this.state.adapter, subscription: this.state.subscription, - status: "disconnected" /* Disconnected */, - reason: 1 /* AdapterUnavailable */ + status: 'disconnected' /* Disconnected */, + reason: 1 /* AdapterUnavailable */, }; return false; } this.state = { adapter: this.state.adapter, reason: 3 /* Manual */, - status: "disconnected" /* Disconnected */ + status: 'disconnected' /* Disconnected */, }; return true; } rejoin(joinConfig) { - if (this.state.status === "destroyed" /* Destroyed */) { + if (this.state.status === 'destroyed' /* Destroyed */) { return false; } - const notReady = this.state.status !== "ready" /* Ready */; - if (notReady) - this.rejoinAttempts++; + const notReady = this.state.status !== 'ready'; /* Ready */ + if (notReady) this.rejoinAttempts++; Object.assign(this.joinConfig, joinConfig); if (this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) { if (notReady) { this.state = { ...this.state, - status: "signalling" /* Signalling */ + status: 'signalling' /* Signalling */, }; } return true; @@ -1528,122 +1509,123 @@ var VoiceConnection = class extends import_node_events7.EventEmitter { this.state = { adapter: this.state.adapter, subscription: this.state.subscription, - status: "disconnected" /* Disconnected */, - reason: 1 /* AdapterUnavailable */ + status: 'disconnected' /* Disconnected */, + reason: 1 /* AdapterUnavailable */, }; return false; } setSpeaking(enabled) { - if (this.state.status !== "ready" /* Ready */) - return false; + if (this.state.status !== 'ready' /* Ready */) return false; return this.state.networking.setSpeaking(enabled); } subscribe(player) { - if (this.state.status === "destroyed" /* Destroyed */) - return; - const subscription = player["subscribe"](this); + if (this.state.status === 'destroyed' /* Destroyed */) return; + const subscription = player['subscribe'](this); this.state = { ...this.state, - subscription + subscription, }; return subscription; } get ping() { - if (this.state.status === "ready" /* Ready */ && this.state.networking.state.code === 4 /* Ready */) { + if (this.state.status === 'ready' /* Ready */ && this.state.networking.state.code === 4 /* Ready */) { return { ws: this.state.networking.state.ws.ping, - udp: this.state.networking.state.udp.ping + udp: this.state.networking.state.udp.ping, }; } return { ws: void 0, - udp: void 0 + udp: void 0, }; } onSubscriptionRemoved(subscription) { - if (this.state.status !== "destroyed" /* Destroyed */ && this.state.subscription === subscription) { + if (this.state.status !== 'destroyed' /* Destroyed */ && this.state.subscription === subscription) { this.state = { ...this.state, - subscription: void 0 + subscription: void 0, }; } } }; -__name(VoiceConnection, "VoiceConnection"); +__name(VoiceConnection, 'VoiceConnection'); function createVoiceConnection(joinConfig, options) { const payload = createJoinVoiceChannelPayload(joinConfig); const existing = getVoiceConnection(joinConfig.guildId, joinConfig.group); - if (existing && existing.state.status !== "destroyed" /* Destroyed */) { - if (existing.state.status === "disconnected" /* Disconnected */) { + if (existing && existing.state.status !== 'destroyed' /* Destroyed */) { + if (existing.state.status === 'disconnected' /* Disconnected */) { existing.rejoin({ channelId: joinConfig.channelId, selfDeaf: joinConfig.selfDeaf, - selfMute: joinConfig.selfMute + selfMute: joinConfig.selfMute, }); } else if (!existing.state.adapter.sendPayload(payload)) { existing.state = { ...existing.state, - status: "disconnected" /* Disconnected */, - reason: 1 /* AdapterUnavailable */ + status: 'disconnected' /* Disconnected */, + reason: 1 /* AdapterUnavailable */, }; } return existing; } const voiceConnection = new VoiceConnection(joinConfig, options); trackVoiceConnection(voiceConnection); - if (voiceConnection.state.status !== "destroyed" /* Destroyed */ && !voiceConnection.state.adapter.sendPayload(payload)) { + if ( + voiceConnection.state.status !== 'destroyed' /* Destroyed */ && + !voiceConnection.state.adapter.sendPayload(payload) + ) { voiceConnection.state = { ...voiceConnection.state, - status: "disconnected" /* Disconnected */, - reason: 1 /* AdapterUnavailable */ + status: 'disconnected' /* Disconnected */, + reason: 1 /* AdapterUnavailable */, }; } return voiceConnection; } -__name(createVoiceConnection, "createVoiceConnection"); +__name(createVoiceConnection, 'createVoiceConnection'); // src/joinVoiceChannel.ts function joinVoiceChannel(options) { const joinConfig = { selfDeaf: true, selfMute: false, - group: "default", - ...options + group: 'default', + ...options, }; return createVoiceConnection(joinConfig, { adapterCreator: options.adapterCreator, - debug: options.debug + debug: options.debug, }); } -__name(joinVoiceChannel, "joinVoiceChannel"); +__name(joinVoiceChannel, 'joinVoiceChannel'); // src/audio/AudioResource.ts -var import_node_stream2 = require("stream"); -var import_prism_media2 = __toESM(require("prism-media")); +var import_node_stream2 = require('stream'); +var import_prism_media2 = __toESM(require('prism-media')); // src/audio/TransformerGraph.ts -var import_prism_media = __toESM(require("prism-media")); -var FFMPEG_PCM_ARGUMENTS = ["-analyzeduration", "0", "-loglevel", "0", "-f", "s16le", "-ar", "48000", "-ac", "2"]; +var import_prism_media = __toESM(require('prism-media')); +var FFMPEG_PCM_ARGUMENTS = ['-analyzeduration', '0', '-loglevel', '0', '-f', 's16le', '-ar', '48000', '-ac', '2']; var FFMPEG_OPUS_ARGUMENTS = [ - "-analyzeduration", - "0", - "-loglevel", - "0", - "-acodec", - "libopus", - "-f", - "opus", - "-ar", - "48000", - "-ac", - "2" + '-analyzeduration', + '0', + '-loglevel', + '0', + '-acodec', + 'libopus', + '-f', + 'opus', + '-ar', + '48000', + '-ac', + '2', ]; -var StreamType = /* @__PURE__ */ ((StreamType2) => { - StreamType2["Arbitrary"] = "arbitrary"; - StreamType2["OggOpus"] = "ogg/opus"; - StreamType2["Opus"] = "opus"; - StreamType2["Raw"] = "raw"; - StreamType2["WebmOpus"] = "webm/opus"; +var StreamType = /* @__PURE__ */ (StreamType2 => { + StreamType2['Arbitrary'] = 'arbitrary'; + StreamType2['OggOpus'] = 'ogg/opus'; + StreamType2['Opus'] = 'opus'; + StreamType2['Raw'] = 'raw'; + StreamType2['WebmOpus'] = 'webm/opus'; return StreamType2; })(StreamType || {}); var Node = class { @@ -1656,81 +1638,81 @@ var Node = class { this.edges.push({ ...edge, from: this }); } }; -__name(Node, "Node"); +__name(Node, 'Node'); var NODES = /* @__PURE__ */ new Map(); for (const streamType of Object.values(StreamType)) { NODES.set(streamType, new Node(streamType)); } function getNode(type) { const node = NODES.get(type); - if (!node) - throw new Error(`Node type '${type}' does not exist!`); + if (!node) throw new Error(`Node type '${type}' does not exist!`); return node; } -__name(getNode, "getNode"); -getNode("raw" /* Raw */).addEdge({ - type: "opus encoder" /* OpusEncoder */, - to: getNode("opus" /* Opus */), +__name(getNode, 'getNode'); +getNode('raw' /* Raw */).addEdge({ + type: 'opus encoder' /* OpusEncoder */, + to: getNode('opus' /* Opus */), cost: 1.5, - transformer: () => new import_prism_media.default.opus.Encoder({ rate: 48e3, channels: 2, frameSize: 960 }) + transformer: () => new import_prism_media.default.opus.Encoder({ rate: 48e3, channels: 2, frameSize: 960 }), }); -getNode("opus" /* Opus */).addEdge({ - type: "opus decoder" /* OpusDecoder */, - to: getNode("raw" /* Raw */), +getNode('opus' /* Opus */).addEdge({ + type: 'opus decoder' /* OpusDecoder */, + to: getNode('raw' /* Raw */), cost: 1.5, - transformer: () => new import_prism_media.default.opus.Decoder({ rate: 48e3, channels: 2, frameSize: 960 }) + transformer: () => new import_prism_media.default.opus.Decoder({ rate: 48e3, channels: 2, frameSize: 960 }), }); -getNode("ogg/opus" /* OggOpus */).addEdge({ - type: "ogg/opus demuxer" /* OggOpusDemuxer */, - to: getNode("opus" /* Opus */), +getNode('ogg/opus' /* OggOpus */).addEdge({ + type: 'ogg/opus demuxer' /* OggOpusDemuxer */, + to: getNode('opus' /* Opus */), cost: 1, - transformer: () => new import_prism_media.default.opus.OggDemuxer() + transformer: () => new import_prism_media.default.opus.OggDemuxer(), }); -getNode("webm/opus" /* WebmOpus */).addEdge({ - type: "webm/opus demuxer" /* WebmOpusDemuxer */, - to: getNode("opus" /* Opus */), +getNode('webm/opus' /* WebmOpus */).addEdge({ + type: 'webm/opus demuxer' /* WebmOpusDemuxer */, + to: getNode('opus' /* Opus */), cost: 1, - transformer: () => new import_prism_media.default.opus.WebmDemuxer() + transformer: () => new import_prism_media.default.opus.WebmDemuxer(), }); var FFMPEG_PCM_EDGE = { - type: "ffmpeg pcm" /* FFmpegPCM */, - to: getNode("raw" /* Raw */), + type: 'ffmpeg pcm' /* FFmpegPCM */, + to: getNode('raw' /* Raw */), cost: 2, - transformer: (input) => new import_prism_media.default.FFmpeg({ - args: typeof input === "string" ? ["-i", input, ...FFMPEG_PCM_ARGUMENTS] : FFMPEG_PCM_ARGUMENTS - }) + transformer: input => + new import_prism_media.default.FFmpeg({ + args: typeof input === 'string' ? ['-i', input, ...FFMPEG_PCM_ARGUMENTS] : FFMPEG_PCM_ARGUMENTS, + }), }; -getNode("arbitrary" /* Arbitrary */).addEdge(FFMPEG_PCM_EDGE); -getNode("ogg/opus" /* OggOpus */).addEdge(FFMPEG_PCM_EDGE); -getNode("webm/opus" /* WebmOpus */).addEdge(FFMPEG_PCM_EDGE); -getNode("raw" /* Raw */).addEdge({ - type: "volume transformer" /* InlineVolume */, - to: getNode("raw" /* Raw */), +getNode('arbitrary' /* Arbitrary */).addEdge(FFMPEG_PCM_EDGE); +getNode('ogg/opus' /* OggOpus */).addEdge(FFMPEG_PCM_EDGE); +getNode('webm/opus' /* WebmOpus */).addEdge(FFMPEG_PCM_EDGE); +getNode('raw' /* Raw */).addEdge({ + type: 'volume transformer' /* InlineVolume */, + to: getNode('raw' /* Raw */), cost: 0.5, - transformer: () => new import_prism_media.default.VolumeTransformer({ type: "s16le" }) + transformer: () => new import_prism_media.default.VolumeTransformer({ type: 's16le' }), }); function canEnableFFmpegOptimizations() { try { - return import_prism_media.default.FFmpeg.getInfo().output.includes("--enable-libopus"); - } catch { - } + return import_prism_media.default.FFmpeg.getInfo().output.includes('--enable-libopus'); + } catch {} return false; } -__name(canEnableFFmpegOptimizations, "canEnableFFmpegOptimizations"); +__name(canEnableFFmpegOptimizations, 'canEnableFFmpegOptimizations'); if (canEnableFFmpegOptimizations()) { const FFMPEG_OGG_EDGE = { - type: "ffmpeg ogg" /* FFmpegOgg */, - to: getNode("ogg/opus" /* OggOpus */), + type: 'ffmpeg ogg' /* FFmpegOgg */, + to: getNode('ogg/opus' /* OggOpus */), cost: 2, - transformer: (input) => new import_prism_media.default.FFmpeg({ - args: typeof input === "string" ? ["-i", input, ...FFMPEG_OPUS_ARGUMENTS] : FFMPEG_OPUS_ARGUMENTS - }) + transformer: input => + new import_prism_media.default.FFmpeg({ + args: typeof input === 'string' ? ['-i', input, ...FFMPEG_OPUS_ARGUMENTS] : FFMPEG_OPUS_ARGUMENTS, + }), }; - getNode("arbitrary" /* Arbitrary */).addEdge(FFMPEG_OGG_EDGE); - getNode("ogg/opus" /* OggOpus */).addEdge(FFMPEG_OGG_EDGE); - getNode("webm/opus" /* WebmOpus */).addEdge(FFMPEG_OGG_EDGE); + getNode('arbitrary' /* Arbitrary */).addEdge(FFMPEG_OGG_EDGE); + getNode('ogg/opus' /* OggOpus */).addEdge(FFMPEG_OGG_EDGE); + getNode('webm/opus' /* WebmOpus */).addEdge(FFMPEG_OGG_EDGE); } -function findPath(from, constraints, goal = getNode("opus" /* Opus */), path = [], depth = 5) { +function findPath(from, constraints, goal = getNode('opus' /* Opus */), path = [], depth = 5) { if (from === goal && constraints(path)) { return { cost: 0 }; } else if (depth === 0) { @@ -1738,8 +1720,7 @@ function findPath(from, constraints, goal = getNode("opus" /* Opus */), path = [ } let currentBest; for (const edge of from.edges) { - if (currentBest && edge.cost > currentBest.cost) - continue; + if (currentBest && edge.cost > currentBest.cost) continue; const next = findPath(edge.to, constraints, goal, [...path, edge], depth - 1); const cost = edge.cost + next.cost; if (!currentBest || cost < currentBest.cost) { @@ -1748,7 +1729,7 @@ function findPath(from, constraints, goal = getNode("opus" /* Opus */), path = [ } return currentBest ?? { cost: Number.POSITIVE_INFINITY }; } -__name(findPath, "findPath"); +__name(findPath, 'findPath'); function constructPipeline(step) { const edges = []; let current = step; @@ -1758,11 +1739,11 @@ function constructPipeline(step) { } return edges; } -__name(constructPipeline, "constructPipeline"); +__name(constructPipeline, 'constructPipeline'); function findPipeline(from, constraint) { return constructPipeline(findPath(getNode(from), constraint)); } -__name(findPipeline, "findPipeline"); +__name(findPipeline, 'findPipeline'); // src/audio/AudioResource.ts var AudioResource = class { @@ -1788,15 +1769,13 @@ var AudioResource = class { this.encoder = stream; } } - this.playStream.once("readable", () => this.started = true); + this.playStream.once('readable', () => (this.started = true)); } get readable() { - if (this.silenceRemaining === 0) - return false; + if (this.silenceRemaining === 0) return false; const real = this.playStream.readable; if (!real) { - if (this.silenceRemaining === -1) - this.silenceRemaining = this.silencePaddingFrames; + if (this.silenceRemaining === -1) this.silenceRemaining = this.silencePaddingFrames; return this.silenceRemaining !== 0; } return real; @@ -1818,126 +1797,120 @@ var AudioResource = class { return packet; } }; -__name(AudioResource, "AudioResource"); -var VOLUME_CONSTRAINT = /* @__PURE__ */ __name((path) => path.some((edge) => edge.type === "volume transformer" /* InlineVolume */), "VOLUME_CONSTRAINT"); -var NO_CONSTRAINT = /* @__PURE__ */ __name(() => true, "NO_CONSTRAINT"); +__name(AudioResource, 'AudioResource'); +var VOLUME_CONSTRAINT = /* @__PURE__ */ __name( + path => path.some(edge => edge.type === 'volume transformer' /* InlineVolume */), + 'VOLUME_CONSTRAINT', +); +var NO_CONSTRAINT = /* @__PURE__ */ __name(() => true, 'NO_CONSTRAINT'); function inferStreamType(stream) { if (stream instanceof import_prism_media2.default.opus.Encoder) { - return { streamType: "opus" /* Opus */, hasVolume: false }; + return { streamType: 'opus' /* Opus */, hasVolume: false }; } else if (stream instanceof import_prism_media2.default.opus.Decoder) { - return { streamType: "raw" /* Raw */, hasVolume: false }; + return { streamType: 'raw' /* Raw */, hasVolume: false }; } else if (stream instanceof import_prism_media2.default.VolumeTransformer) { - return { streamType: "raw" /* Raw */, hasVolume: true }; + return { streamType: 'raw' /* Raw */, hasVolume: true }; } else if (stream instanceof import_prism_media2.default.opus.OggDemuxer) { - return { streamType: "opus" /* Opus */, hasVolume: false }; + return { streamType: 'opus' /* Opus */, hasVolume: false }; } else if (stream instanceof import_prism_media2.default.opus.WebmDemuxer) { - return { streamType: "opus" /* Opus */, hasVolume: false }; + return { streamType: 'opus' /* Opus */, hasVolume: false }; } - return { streamType: "arbitrary" /* Arbitrary */, hasVolume: false }; + return { streamType: 'arbitrary' /* Arbitrary */, hasVolume: false }; } -__name(inferStreamType, "inferStreamType"); +__name(inferStreamType, 'inferStreamType'); function createAudioResource(input, options = {}) { let inputType = options.inputType; let needsInlineVolume = Boolean(options.inlineVolume); - if (typeof input === "string") { - inputType = "arbitrary" /* Arbitrary */; - } else if (typeof inputType === "undefined") { + if (typeof input === 'string') { + inputType = 'arbitrary' /* Arbitrary */; + } else if (typeof inputType === 'undefined') { const analysis = inferStreamType(input); inputType = analysis.streamType; needsInlineVolume = needsInlineVolume && !analysis.hasVolume; } const transformerPipeline = findPipeline(inputType, needsInlineVolume ? VOLUME_CONSTRAINT : NO_CONSTRAINT); if (transformerPipeline.length === 0) { - if (typeof input === "string") - throw new Error(`Invalid pipeline constructed for string resource '${input}'`); + if (typeof input === 'string') throw new Error(`Invalid pipeline constructed for string resource '${input}'`); return new AudioResource([], [input], options.metadata ?? null, options.silencePaddingFrames ?? 5); } - const streams = transformerPipeline.map((edge) => edge.transformer(input)); - if (typeof input !== "string") - streams.unshift(input); - return new AudioResource( - transformerPipeline, - streams, - options.metadata ?? null, - options.silencePaddingFrames ?? 5 - ); + const streams = transformerPipeline.map(edge => edge.transformer(input)); + if (typeof input !== 'string') streams.unshift(input); + return new AudioResource(transformerPipeline, streams, options.metadata ?? null, options.silencePaddingFrames ?? 5); } -__name(createAudioResource, "createAudioResource"); +__name(createAudioResource, 'createAudioResource'); // src/util/generateDependencyReport.ts -var import_node_path = require("path"); -var import_prism_media3 = __toESM(require("prism-media")); +var import_node_path = require('path'); +var import_prism_media3 = __toESM(require('prism-media')); function findPackageJSON(dir, packageName, depth) { - if (depth === 0) - return void 0; - const attemptedPath = (0, import_node_path.resolve)(dir, "./package.json"); + if (depth === 0) return void 0; + const attemptedPath = (0, import_node_path.resolve)(dir, './package.json'); try { const pkg = require(attemptedPath); - if (pkg.name !== packageName) - throw new Error("package.json does not match"); + if (pkg.name !== packageName) throw new Error('package.json does not match'); return pkg; } catch { - return findPackageJSON((0, import_node_path.resolve)(dir, ".."), packageName, depth - 1); + return findPackageJSON((0, import_node_path.resolve)(dir, '..'), packageName, depth - 1); } } -__name(findPackageJSON, "findPackageJSON"); +__name(findPackageJSON, 'findPackageJSON'); function version(name) { try { - if (name === "@discordjs/voice") { - return "0.14.0"; + if (name === '@discordjs/voice') { + return '0.14.0'; } const pkg = findPackageJSON((0, import_node_path.dirname)(require.resolve(name)), name, 3); - return pkg?.version ?? "not found"; + return pkg?.version ?? 'not found'; } catch { - return "not found"; + return 'not found'; } } -__name(version, "version"); +__name(version, 'version'); function generateDependencyReport() { const report = []; - const addVersion = /* @__PURE__ */ __name((name) => report.push(`- ${name}: ${version(name)}`), "addVersion"); - report.push("Core Dependencies"); - addVersion("@discordjs/voice"); - addVersion("prism-media"); - report.push(""); - report.push("Opus Libraries"); - addVersion("@discordjs/opus"); - addVersion("opusscript"); - report.push(""); - report.push("Encryption Libraries"); - addVersion("sodium-native"); - addVersion("sodium"); - addVersion("libsodium-wrappers"); - addVersion("tweetnacl"); - report.push(""); - report.push("FFmpeg"); + const addVersion = /* @__PURE__ */ __name(name => report.push(`- ${name}: ${version(name)}`), 'addVersion'); + report.push('Core Dependencies'); + addVersion('@discordjs/voice'); + addVersion('prism-media'); + report.push(''); + report.push('Opus Libraries'); + addVersion('@discordjs/opus'); + addVersion('opusscript'); + report.push(''); + report.push('Encryption Libraries'); + addVersion('sodium-native'); + addVersion('sodium'); + addVersion('libsodium-wrappers'); + addVersion('tweetnacl'); + report.push(''); + report.push('FFmpeg'); try { const info = import_prism_media3.default.FFmpeg.getInfo(); report.push(`- version: ${info.version}`); - report.push(`- libopus: ${info.output.includes("--enable-libopus") ? "yes" : "no"}`); + report.push(`- libopus: ${info.output.includes('--enable-libopus') ? 'yes' : 'no'}`); } catch { - report.push("- not found"); + report.push('- not found'); } - return ["-".repeat(50), ...report, "-".repeat(50)].join("\n"); + return ['-'.repeat(50), ...report, '-'.repeat(50)].join('\n'); } -__name(generateDependencyReport, "generateDependencyReport"); +__name(generateDependencyReport, 'generateDependencyReport'); // src/util/entersState.ts -var import_node_events8 = require("events"); +var import_node_events8 = require('events'); // src/util/abortAfter.ts function abortAfter(delay) { const ac = new AbortController(); const timeout = setTimeout(() => ac.abort(), delay); - ac.signal.addEventListener("abort", () => clearTimeout(timeout)); + ac.signal.addEventListener('abort', () => clearTimeout(timeout)); return [ac, ac.signal]; } -__name(abortAfter, "abortAfter"); +__name(abortAfter, 'abortAfter'); // src/util/entersState.ts async function entersState(target, status, timeoutOrSignal) { if (target.state.status !== status) { - const [ac, signal] = typeof timeoutOrSignal === "number" ? abortAfter(timeoutOrSignal) : [void 0, timeoutOrSignal]; + const [ac, signal] = typeof timeoutOrSignal === 'number' ? abortAfter(timeoutOrSignal) : [void 0, timeoutOrSignal]; try { await (0, import_node_events8.once)(target, status, { signal }); } finally { @@ -1946,41 +1919,41 @@ async function entersState(target, status, timeoutOrSignal) { } return target; } -__name(entersState, "entersState"); +__name(entersState, 'entersState'); // src/util/demuxProbe.ts -var import_node_buffer6 = require("buffer"); -var import_node_process = __toESM(require("process")); -var import_node_stream3 = require("stream"); -var import_prism_media4 = __toESM(require("prism-media")); +var import_node_buffer6 = require('buffer'); +var import_node_process = __toESM(require('process')); +var import_node_stream3 = require('stream'); +var import_prism_media4 = __toESM(require('prism-media')); function validateDiscordOpusHead(opusHead) { const channels = opusHead.readUInt8(9); const sampleRate = opusHead.readUInt32LE(12); return channels === 2 && sampleRate === 48e3; } -__name(validateDiscordOpusHead, "validateDiscordOpusHead"); +__name(validateDiscordOpusHead, 'validateDiscordOpusHead'); async function demuxProbe(stream, probeSize = 1024, validator = validateDiscordOpusHead) { return new Promise((resolve2, reject) => { if (stream.readableObjectMode) { - reject(new Error("Cannot probe a readable stream in object mode")); + reject(new Error('Cannot probe a readable stream in object mode')); return; } if (stream.readableEnded) { - reject(new Error("Cannot probe a stream that has ended")); + reject(new Error('Cannot probe a stream that has ended')); return; } let readBuffer = import_node_buffer6.Buffer.alloc(0); let resolved; - const finish = /* @__PURE__ */ __name((type) => { - stream.off("data", onData); - stream.off("close", onClose); - stream.off("end", onClose); + const finish = /* @__PURE__ */ __name(type => { + stream.off('data', onData); + stream.off('close', onClose); + stream.off('end', onClose); stream.pause(); resolved = type; if (stream.readableEnded) { resolve2({ stream: import_node_stream3.Readable.from(readBuffer), - type + type, }); } else { if (readBuffer.length > 0) { @@ -1988,74 +1961,78 @@ async function demuxProbe(stream, probeSize = 1024, validator = validateDiscordO } resolve2({ stream, - type + type, }); } - }, "finish"); - const foundHead = /* @__PURE__ */ __name((type) => (head) => { - if (validator(head)) { - finish(type); - } - }, "foundHead"); + }, 'finish'); + const foundHead = /* @__PURE__ */ __name( + type => head => { + if (validator(head)) { + finish(type); + } + }, + 'foundHead', + ); const webm = new import_prism_media4.default.opus.WebmDemuxer(); - webm.once("error", noop); - webm.on("head", foundHead("webm/opus" /* WebmOpus */)); + webm.once('error', noop); + webm.on('head', foundHead('webm/opus' /* WebmOpus */)); const ogg = new import_prism_media4.default.opus.OggDemuxer(); - ogg.once("error", noop); - ogg.on("head", foundHead("ogg/opus" /* OggOpus */)); + ogg.once('error', noop); + ogg.on('head', foundHead('ogg/opus' /* OggOpus */)); const onClose = /* @__PURE__ */ __name(() => { if (!resolved) { - finish("arbitrary" /* Arbitrary */); + finish('arbitrary' /* Arbitrary */); } - }, "onClose"); - const onData = /* @__PURE__ */ __name((buffer) => { + }, 'onClose'); + const onData = /* @__PURE__ */ __name(buffer => { readBuffer = import_node_buffer6.Buffer.concat([readBuffer, buffer]); webm.write(buffer); ogg.write(buffer); if (readBuffer.length >= probeSize) { - stream.off("data", onData); + stream.off('data', onData); stream.pause(); import_node_process.default.nextTick(onClose); } - }, "onData"); - stream.once("error", reject); - stream.on("data", onData); - stream.once("close", onClose); - stream.once("end", onClose); + }, 'onData'); + stream.once('error', reject); + stream.on('data', onData); + stream.once('close', onClose); + stream.once('end', onClose); }); } -__name(demuxProbe, "demuxProbe"); +__name(demuxProbe, 'demuxProbe'); // src/index.ts -var version2 = "0.14.0"; +var version2 = '0.14.0'; // Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - AudioPlayer, - AudioPlayerError, - AudioPlayerStatus, - AudioReceiveStream, - AudioResource, - EndBehaviorType, - NoSubscriberBehavior, - PlayerSubscription, - SSRCMap, - SpeakingMap, - StreamType, - VoiceConnection, - VoiceConnectionDisconnectReason, - VoiceConnectionStatus, - VoiceReceiver, - createAudioPlayer, - createAudioResource, - createDefaultAudioReceiveStreamOptions, - demuxProbe, - entersState, - generateDependencyReport, - getGroups, - getVoiceConnection, - getVoiceConnections, - joinVoiceChannel, - validateDiscordOpusHead, - version -}); -//# sourceMappingURL=index.js.map \ No newline at end of file +0 && + (module.exports = { + AudioPlayer, + AudioPlayerError, + AudioPlayerStatus, + AudioReceiveStream, + AudioResource, + EndBehaviorType, + NoSubscriberBehavior, + PlayerSubscription, + SSRCMap, + SpeakingMap, + StreamType, + VoiceConnection, + VoiceConnectionDisconnectReason, + VoiceConnectionStatus, + VoiceReceiver, + createAudioPlayer, + createAudioResource, + createDefaultAudioReceiveStreamOptions, + demuxProbe, + entersState, + generateDependencyReport, + getGroups, + getVoiceConnection, + getVoiceConnections, + joinVoiceChannel, + validateDiscordOpusHead, + version, + }); +//# sourceMappingURL=index.js.map diff --git a/typings/index.d.ts b/typings/index.d.ts index 7befd44..a7254dc 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -6301,9 +6301,7 @@ export interface BaseMessageSelectMenuOptions { placeholder?: string; } export interface StringMessageSelectMenuOptions extends BaseMessageSelectMenuOptions { - type?: - | 'STRING_SELECT' - | SelectMenuComponentTypes.STRING_SELECT; + type?: 'STRING_SELECT' | SelectMenuComponentTypes.STRING_SELECT; options?: MessageSelectOptionData[]; }