diff --git a/package-lock.json b/package-lock.json index d2be082..0efbaeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@aikochan2k6/qrcode-terminal": "^0.12.0", "@discordjs/builders": "^1.0.0", - "@discordjs/collection": "^0.7.0", - "@discordjs/voice": "^0.10.0", + "@discordjs/collection": "^1.0.0", + "@discordjs/voice": "^0.11.0", "@sapphire/async-queue": "^1.3.1", "@types/node-fetch": "^2.6.2", "@types/ws": "^8.5.3", @@ -25,7 +25,7 @@ "node-fetch": "^2.6.1", "safe-base64": "^2.0.1-0", "string_decoder": "^1.3.0", - "ws": "^8.8.0" + "ws": "^8.8.1" }, "devDependencies": { "@commitlint/cli": "^16.0.1", @@ -35,7 +35,7 @@ "@types/node": "^16.11.12", "conventional-changelog-cli": "^2.2.2", "dtslint": "^4.2.1", - "eslint": "^8.15.0", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", @@ -1023,7 +1023,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.0.0.tgz", "integrity": "sha512-8y91ZfpOHubiGJu5tVyGI9tQCEyHZDTeqUWVcJd0dq7B96xIf84S0L4fwmD1k9zTe1eqEFSk0gc7BpY+FKn7Ww==", - "deprecated": "no longer supported", "dependencies": { "@sapphire/shapeshift": "^3.5.1", "discord-api-types": "^0.36.2", @@ -1036,9 +1035,9 @@ } }, "node_modules/@discordjs/collection": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", - "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.0.0.tgz", + "integrity": "sha512-nAxDQYE5dNAzEGQ7HU20sujDsG5vLowUKCEqZkKUIlrXERZFTt/60zKUj/g4+AVCGeq+pXC5hivMaNtiC+PY5Q==", "engines": { "node": ">=16.9.0" } @@ -1666,26 +1665,20 @@ } }, "node_modules/@discordjs/voice": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.10.0.tgz", - "integrity": "sha512-tChDKRRbKwWHcyq1dSEzrnuCMJyLtKXcFhgQpqcS2YjZ1TLlXboc/mhrR8jA1Yb1rB81u8dgj/lPkkHsk0ItEg==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.11.0.tgz", + "integrity": "sha512-6+9cj1dxzBJm7WJ9qyG2XZZQ8rcLl6x2caW0C0OxuTtMLAaEDntpb6lqMTFiBg/rDc4Rd59g1w0gJmib33CuHw==", "dependencies": { "@types/ws": "^8.5.3", - "discord-api-types": "^0.33.3", - "prism-media": "^1.3.2", - "tiny-typed-emitter": "^2.1.0", + "discord-api-types": "^0.36.2", + "prism-media": "^1.3.4", "tslib": "^2.4.0", - "ws": "^8.7.0" + "ws": "^8.8.1" }, "engines": { "node": ">=16.9.0" } }, - "node_modules/@discordjs/voice/node_modules/discord-api-types": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", - "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" - }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -9788,12 +9781,12 @@ } }, "node_modules/prism-media": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.2.tgz", - "integrity": "sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.4.tgz", + "integrity": "sha512-eW7LXORkTCQznZs+eqe9VjGOrLBxcBPXgNyHXMTSRVhphvd/RrxgIR7WaWt4fkLuhshcdT5KHL88LAfcvS3f5g==", "peerDependencies": { - "@discordjs/opus": "^0.5.0", - "ffmpeg-static": "^4.2.7 || ^3.0.0 || ^2.4.0", + "@discordjs/opus": "^0.8.0", + "ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0", "node-opus": "^0.3.3", "opusscript": "^0.0.8" }, @@ -11288,11 +11281,6 @@ "readable-stream": "3" } }, - "node_modules/tiny-typed-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -13188,9 +13176,9 @@ } }, "@discordjs/collection": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", - "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.0.0.tgz", + "integrity": "sha512-nAxDQYE5dNAzEGQ7HU20sujDsG5vLowUKCEqZkKUIlrXERZFTt/60zKUj/g4+AVCGeq+pXC5hivMaNtiC+PY5Q==" }, "@discordjs/docgen": { "version": "0.11.1", @@ -13675,23 +13663,15 @@ } }, "@discordjs/voice": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.10.0.tgz", - "integrity": "sha512-tChDKRRbKwWHcyq1dSEzrnuCMJyLtKXcFhgQpqcS2YjZ1TLlXboc/mhrR8jA1Yb1rB81u8dgj/lPkkHsk0ItEg==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.11.0.tgz", + "integrity": "sha512-6+9cj1dxzBJm7WJ9qyG2XZZQ8rcLl6x2caW0C0OxuTtMLAaEDntpb6lqMTFiBg/rDc4Rd59g1w0gJmib33CuHw==", "requires": { "@types/ws": "^8.5.3", - "discord-api-types": "^0.33.3", - "prism-media": "^1.3.2", - "tiny-typed-emitter": "^2.1.0", + "discord-api-types": "^0.36.2", + "prism-media": "^1.3.4", "tslib": "^2.4.0", - "ws": "^8.7.0" - }, - "dependencies": { - "discord-api-types": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", - "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" - } + "ws": "^8.8.1" } }, "@eslint/eslintrc": { @@ -19949,9 +19929,9 @@ } }, "prism-media": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.2.tgz", - "integrity": "sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.4.tgz", + "integrity": "sha512-eW7LXORkTCQznZs+eqe9VjGOrLBxcBPXgNyHXMTSRVhphvd/RrxgIR7WaWt4fkLuhshcdT5KHL88LAfcvS3f5g==", "requires": {} }, "process-nextick-args": { @@ -21078,11 +21058,6 @@ "readable-stream": "3" } }, - "tiny-typed-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", diff --git a/package.json b/package.json index cbf00ad..0562484 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,8 @@ "dependencies": { "@aikochan2k6/qrcode-terminal": "^0.12.0", "@discordjs/builders": "^1.0.0", - "@discordjs/collection": "^0.7.0", - "@discordjs/voice": "^0.10.0", + "@discordjs/collection": "^1.0.0", + "@discordjs/voice": "^0.11.0", "@sapphire/async-queue": "^1.3.1", "@types/node-fetch": "^2.6.2", "@types/ws": "^8.5.3", @@ -67,7 +67,7 @@ "node-fetch": "^2.6.1", "safe-base64": "^2.0.1-0", "string_decoder": "^1.3.0", - "ws": "^8.8.0" + "ws": "^8.8.1" }, "engines": { "node": ">=16.6.0", @@ -81,7 +81,7 @@ "@types/node": "^16.11.12", "conventional-changelog-cli": "^2.2.2", "dtslint": "^4.2.1", - "eslint": "^8.15.0", + "eslint": "^8.20.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", diff --git a/src/util/Voice.js b/src/util/Voice.js index 77ee2c4..7110c36 100644 --- a/src/util/Voice.js +++ b/src/util/Voice.js @@ -6,126 +6,125 @@ 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 __commonJS = (cb, mod) => - function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; -var __export = (target, all) => { - for (var name in all) __defProp(target, name, { get: all[name], enumerable: 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 __commonJS = (cb, mod) => function __require() +{ + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; -var __copyProps = (to, from, except, desc) => { - if ((from && typeof from === 'object') || typeof from === 'function') { +var __export = (target, all) => +{ + 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") + { 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 __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== 'symbol' ? key + '' : key, value); +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); return value; }; // package.json var require_package = __commonJS({ - 'package.json'(exports, module2) { + "package.json"(exports, module2) + { module2.exports = { - name: '@discordjs/voice', - version: '0.10.0-dev', - description: 'Implementation of the Discord Voice API for node.js', + name: "@discordjs/voice", + version: "0.11.0", + description: "Implementation of the Discord Voice API for node.js", scripts: { - build: 'tsup && node scripts/postbuild.mjs', - test: 'jest --pass-with-no-tests --collect-coverage', - lint: 'prettier --check . && eslint src __tests__ --ext mjs,js,ts', - format: 'prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix', - docs: 'typedoc --json docs/typedoc-out.json src/index.ts && node scripts/docs.mjs', - prepublishOnly: 'yarn build && yarn lint && yarn test', - changelog: "git cliff --prepend ./CHANGELOG.md -l -c ./cliff.toml -r ../../ --include-path 'packages/voice/*'", + build: "tsup && node scripts/postbuild.mjs", + test: "jest --coverage", + lint: "prettier --check . && eslint src __tests__ --ext mjs,js,ts", + format: "prettier --write . && eslint src __tests__ --ext mjs,js,ts --fix", + docs: "docgen -i src/index.ts -c docs/index.json -o docs/docs.json --typescript && api-extractor run --local", + prepack: "yarn build && yarn lint && yarn test", + changelog: "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r ../../ --include-path 'packages/voice/*'", + release: "cliff-jumper" }, - main: './dist/index.js', - module: './dist/index.mjs', - typings: './dist/index.d.ts', + main: "./dist/index.js", + module: "./dist/index.mjs", + typings: "./dist/index.d.ts", exports: { - import: './dist/index.mjs', - require: './dist/index.js', - types: './dist/index.d.ts', + import: "./dist/index.mjs", + require: "./dist/index.js", + types: "./dist/index.d.ts" }, directories: { - lib: 'src', - test: '__tests__', + lib: "src", + test: "__tests__" }, - files: ['dist'], - contributors: [ - 'Crawl ', - 'Amish Shah ', - 'SpaceEEC ', - 'Vlad Frangu ', - 'Antonio Roman ', + files: [ + "dist" + ], + contributors: [ + "Crawl ", + "Amish Shah ", + "SpaceEEC ", + "Vlad Frangu ", + "Antonio Roman " + ], + license: "Apache-2.0", + keywords: [ + "discord", + "discord.js", + "audio", + "voice", + "streaming" ], - license: 'Apache-2.0', - keywords: ['discord', 'discord.js', 'audio', 'voice', 'streaming'], repository: { - type: 'git', - url: 'git+https://github.com/discordjs/discord.js.git', + type: "git", + url: "git+https://github.com/discordjs/discord.js.git" }, bugs: { - url: 'https://github.com/discordjs/discord.js/issues', + url: "https://github.com/discordjs/discord.js/issues" }, - homepage: 'https://discord.js.org', + homepage: "https://discord.js.org", dependencies: { - '@types/ws': '^8.5.3', - 'discord-api-types': '^0.33.3', - 'prism-media': '^1.3.2', - 'tiny-typed-emitter': '^2.1.0', - tslib: '^2.4.0', - ws: '^8.7.0', + "@types/ws": "^8.5.3", + "discord-api-types": "^0.36.2", + "prism-media": "^1.3.4", + tslib: "^2.4.0", + ws: "^8.8.1" }, devDependencies: { - '@babel/core': '^7.18.2', - '@babel/preset-env': '^7.18.2', - '@babel/preset-typescript': '^7.17.12', - '@discordjs/ts-docgen': '^0.4.1', - '@types/jest': '^28.1.0', - '@types/node': '^16.11.38', - '@typescript-eslint/eslint-plugin': '^5.27.0', - '@typescript-eslint/parser': '^5.27.0', - eslint: '^8.17.0', - 'eslint-config-marine': '^9.4.1', - 'eslint-config-prettier': '^8.5.0', - 'eslint-plugin-import': '^2.26.0', - jest: '^28.1.0', - 'jest-websocket-mock': '^2.3.0', - 'mock-socket': '^9.1.4', - prettier: '^2.6.2', - tsup: '^6.0.1', - tweetnacl: '^1.0.3', - typedoc: '^0.22.17', - typescript: '^4.7.3', + "@babel/core": "^7.18.6", + "@babel/preset-env": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@discordjs/docgen": "workspace:^", + "@discordjs/scripts": "workspace:^", + "@favware/cliff-jumper": "^1.8.5", + "@microsoft/api-extractor": "^7.28.4", + "@types/jest": "^28.1.6", + "@types/node": "^16.11.45", + eslint: "^8.20.0", + jest: "^28.1.3", + "jest-websocket-mock": "^2.3.0", + "mock-socket": "^9.1.5", + prettier: "^2.7.1", + tsup: "^6.1.3", + tweetnacl: "^1.0.3", + typescript: "^4.7.4" }, engines: { - node: '>=16.9.0', + node: ">=16.9.0" }, publishConfig: { - access: 'public', - }, + access: "public" + } }; - }, + } }); // src/index.ts @@ -162,157 +161,187 @@ __export(src_exports, { module.exports = __toCommonJS(src_exports); // src/VoiceConnection.ts -var import_tiny_typed_emitter7 = require('tiny-typed-emitter'); +var import_node_events7 = require("events"); // src/DataStore.ts -var import_v10 = require('discord-api-types/v10'); -function createJoinVoiceChannelPayload(config) { +var import_v10 = require("discord-api-types/v10"); +function createJoinVoiceChannelPayload(config) +{ return { op: import_v10.GatewayOpcodes.VoiceStateUpdate, d: { 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()); -function getOrCreateGroup(group) { +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'); -function getGroups() { +__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'); -function untrackVoiceConnection(voiceConnection) { +__name(getVoiceConnection, "getVoiceConnection"); +function untrackVoiceConnection(voiceConnection) +{ return getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId); } -__name(untrackVoiceConnection, 'untrackVoiceConnection'); -function trackVoiceConnection(voiceConnection) { +__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; +function audioCycleStep() +{ + if (nextTime === -1) + return; nextTime += FRAME_LENGTH; - const available = audioPlayers.filter(player => player.checkPlayable()); - available.forEach(player => player['_stepDispatch']()); + const available = audioPlayers.filter((player) => player.checkPlayable()); + available.forEach((player) => player["_stepDispatch"]()); prepareNextAudioFrame(available); } -__name(audioCycleStep, 'audioCycleStep'); -function prepareNextAudioFrame(players) { +__name(audioCycleStep, "audioCycleStep"); +function prepareNextAudioFrame(players) +{ const nextPlayer = players.shift(); - if (!nextPlayer) { - if (nextTime !== -1) { + if (!nextPlayer) + { + if (nextTime !== -1) + { audioCycleInterval = setTimeout(() => audioCycleStep(), nextTime - Date.now()); } return; } - nextPlayer['_stepPrepare'](); + nextPlayer["_stepPrepare"](); setImmediate(() => prepareNextAudioFrame(players)); } -__name(prepareNextAudioFrame, 'prepareNextAudioFrame'); -function hasAudioPlayer(target) { +__name(prepareNextAudioFrame, "prepareNextAudioFrame"); +function hasAudioPlayer(target) +{ return audioPlayers.includes(target); } -__name(hasAudioPlayer, 'hasAudioPlayer'); -function addAudioPlayer(player) { - if (hasAudioPlayer(player)) return player; +__name(hasAudioPlayer, "hasAudioPlayer"); +function addAudioPlayer(player) +{ + if (hasAudioPlayer(player)) + return player; audioPlayers.push(player); - if (audioPlayers.length === 1) { + if (audioPlayers.length === 1) + { nextTime = Date.now(); setImmediate(() => audioCycleStep()); } return player; } -__name(addAudioPlayer, 'addAudioPlayer'); -function deleteAudioPlayer(player) { +__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) { + 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_v42 = require('discord-api-types/voice/v4'); -var import_tiny_typed_emitter3 = require('tiny-typed-emitter'); +var import_node_events3 = require("events"); +var import_v42 = require("discord-api-types/voice/v4"); // src/networking/VoiceUDPSocket.ts -var import_node_dgram = require('dgram'); -var import_node_net = require('net'); -var import_tiny_typed_emitter = require('tiny-typed-emitter'); -function parseLocalPacket(message) { +var import_node_dgram = require("dgram"); +var import_node_events = require("events"); +var import_node_net = require("net"); +function parseLocalPacket(message) +{ const packet = Buffer.from(message); - const ip = packet.slice(8, packet.indexOf(0, 8)).toString('utf-8'); - if (!(0, import_node_net.isIPv4)(ip)) { - throw new Error('Malformed IP address'); + const ip = packet.slice(8, packet.indexOf(0, 8)).toString("utf-8"); + if (!(0, import_node_net.isIPv4)(ip)) + { + 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; -var VoiceUDPSocket = class extends import_tiny_typed_emitter.TypedEmitter { - constructor(remote, debug = false) { +var VoiceUDPSocket = class extends import_node_events.EventEmitter +{ + constructor(remote, debug = false) + { super(); - __publicField(this, 'socket'); - __publicField(this, 'remote'); - __publicField(this, 'keepAlives'); - __publicField(this, 'keepAliveCounter', 0); - __publicField(this, 'keepAliveBuffer'); - __publicField(this, 'keepAliveInterval'); - __publicField(this, 'ping'); - __publicField(this, 'debug'); - 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')); + __publicField(this, "socket"); + __publicField(this, "remote"); + __publicField(this, "keepAlives"); + __publicField(this, "keepAliveCounter", 0); + __publicField(this, "keepAliveBuffer"); + __publicField(this, "keepAliveInterval"); + __publicField(this, "ping"); + __publicField(this, "debug"); + 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 = 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) { + 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'); + keepAlive() + { + if (this.keepAlives.length >= KEEP_ALIVE_LIMIT) + { + this.debug?.("UDP socket has not received enough responses from Discord - closing socket"); this.destroy(); return; } @@ -320,34 +349,45 @@ var VoiceUDPSocket = class extends import_tiny_typed_emitter.TypedEmitter { this.send(this.keepAliveBuffer); this.keepAlives.push({ value: this.keepAliveCounter, - timestamp: Date.now(), + timestamp: Date.now() }); this.keepAliveCounter++; - if (this.keepAliveCounter > MAX_COUNTER_VALUE) { + if (this.keepAliveCounter > MAX_COUNTER_VALUE) + { this.keepAliveCounter = 0; } } - send(buffer) { + send(buffer) + { return this.socket.send(buffer, this.remote.port, this.remote.ip); } - destroy() { - try { + destroy() + { + try + { this.socket.close(); - } catch {} + } catch { + } clearInterval(this.keepAliveInterval); } - performIPDiscovery(ssrc) { - return new Promise((resolve2, reject) => { - const listener = /* @__PURE__ */ __name(message => { - try { - if (message.readUInt16BE(0) !== 2) return; + performIPDiscovery(ssrc) + { + return new Promise((resolve2, reject) => + { + const listener = /* @__PURE__ */ __name((message) => + { + try + { + 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 = Buffer.alloc(74); discoveryBuffer.writeUInt16BE(1, 0); discoveryBuffer.writeUInt16BE(70, 2); @@ -356,83 +396,102 @@ var VoiceUDPSocket = class extends import_tiny_typed_emitter.TypedEmitter { }); } }; -__name(VoiceUDPSocket, 'VoiceUDPSocket'); +__name(VoiceUDPSocket, "VoiceUDPSocket"); // src/networking/VoiceWebSocket.ts -var import_v4 = require('discord-api-types/voice/v4'); -var import_tiny_typed_emitter2 = require('tiny-typed-emitter'); -var import_ws = __toESM(require('ws')); -var VoiceWebSocket = class extends import_tiny_typed_emitter2.TypedEmitter { - constructor(address, debug) { +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 +{ + constructor(address, debug) + { super(); - __publicField(this, 'heartbeatInterval'); - __publicField(this, 'lastHeartbeatAck'); - __publicField(this, 'lastHeartbeatSend'); - __publicField(this, 'missedHeartbeats', 0); - __publicField(this, 'ping'); - __publicField(this, 'debug'); - __publicField(this, 'ws'); + __publicField(this, "heartbeatInterval"); + __publicField(this, "lastHeartbeatAck"); + __publicField(this, "lastHeartbeatSend"); + __publicField(this, "missedHeartbeats", 0); + __publicField(this, "ping"); + __publicField(this, "debug"); + __publicField(this, "ws"); this.ws = new import_ws.default(address); - this.ws.onmessage = e => this.onMessage(e); - this.ws.onopen = e => this.emit('open', e); - this.ws.onerror = e => this.emit('error', e instanceof Error ? e : e.error); - this.ws.onclose = e => this.emit('close', e); + this.ws.onmessage = (e) => this.onMessage(e); + this.ws.onopen = (e) => this.emit("open", e); + this.ws.onerror = (e) => this.emit("error", e instanceof Error ? e : e.error); + this.ws.onclose = (e) => this.emit("close", e); 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'); + destroy() + { + try + { + this.debug?.("destroyed"); this.setHeartbeatInterval(-1); this.ws.close(1e3); - } catch (error) { + } catch (error) + { const e = error; - this.emit('error', e); + this.emit("error", e); } } - onMessage(event) { - if (typeof event.data !== 'string') return; + onMessage(event) + { + if (typeof event.data !== "string") + return; this.debug?.(`<< ${event.data}`); let packet; - try { + try + { packet = JSON.parse(event.data); - } catch (error) { + } catch (error) + { const e = error; - this.emit('error', e); + this.emit("error", e); return; } - if (packet.op === import_v4.VoiceOpcodes.HeartbeatAck) { + if (packet.op === import_v4.VoiceOpcodes.HeartbeatAck) + { this.lastHeartbeatAck = Date.now(); this.missedHeartbeats = 0; this.ping = this.lastHeartbeatAck - this.lastHeartbeatSend; } - this.emit('packet', packet); + this.emit("packet", packet); } - sendPacket(packet) { - try { + sendPacket(packet) + { + try + { const stringified = JSON.stringify(packet); this.debug?.(`>> ${stringified}`); return this.ws.send(stringified); - } catch (error) { + } catch (error) + { const e = error; - this.emit('error', e); + this.emit("error", e); } } - sendHeartbeat() { + sendHeartbeat() + { this.lastHeartbeatSend = Date.now(); this.missedHeartbeats++; const nonce2 = this.lastHeartbeatSend; return this.sendPacket({ op: import_v4.VoiceOpcodes.Heartbeat, - d: nonce2, + d: nonce2 }); } - setHeartbeatInterval(ms) { - if (typeof this.heartbeatInterval !== 'undefined') clearInterval(this.heartbeatInterval); - if (ms > 0) { - this.heartbeatInterval = setInterval(() => { - if (this.lastHeartbeatSend !== 0 && this.missedHeartbeats >= 3) { + setHeartbeatInterval(ms) + { + if (typeof this.heartbeatInterval !== "undefined") + clearInterval(this.heartbeatInterval); + if (ms > 0) + { + this.heartbeatInterval = setInterval(() => + { + if (this.lastHeartbeatSend !== 0 && this.missedHeartbeats >= 3) + { this.ws.close(); this.setHeartbeatInterval(-1); } @@ -441,103 +500,123 @@ var VoiceWebSocket = class extends import_tiny_typed_emitter2.TypedEmitter { } } }; -__name(VoiceWebSocket, 'VoiceWebSocket'); +__name(VoiceWebSocket, "VoiceWebSocket"); // src/util/Secretbox.ts var libs = { - 'sodium-native': sodium => ({ - open: (buffer, nonce2, secretKey) => { - if (buffer) { + "sodium-native": (sodium) => ({ + open: (buffer, nonce2, secretKey) => + { + if (buffer) + { const output = 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; }, - close: (opusPacket, nonce2, secretKey) => { + close: (opusPacket, nonce2, secretKey) => + { const output = Buffer.allocUnsafe(opusPacket.length + sodium.crypto_box_MACBYTES); sodium.crypto_secretbox_easy(output, opusPacket, nonce2, secretKey); return output; }, - random: (n, buffer = Buffer.allocUnsafe(n)) => { + random: (n, buffer = Buffer.allocUnsafe(n)) => + { sodium.randombytes_buf(buffer); return buffer; - }, + } }), - sodium: sodium => ({ + sodium: (sodium) => ({ open: sodium.api.crypto_secretbox_open_easy, close: sodium.api.crypto_secretbox_easy, - random: (n, buffer = Buffer.allocUnsafe(n)) => { + random: (n, buffer = Buffer.allocUnsafe(n)) => + { 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(() => { +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 { +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/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 = Buffer.alloc(24); -function stringifyState(state) { +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'); -function chooseEncryptionMode(options) { - const option = options.find(option2 => SUPPORTED_ENCRYPTION_MODES.includes(option2)); - if (!option) { - throw new Error(`No compatible encryption modes. Available include: ${options.join(', ')}`); +__name(stringifyState, "stringifyState"); +function chooseEncryptionMode(options) +{ + const option = options.find((option2) => SUPPORTED_ENCRYPTION_MODES.includes(option2)); + if (!option) + { + throw new Error(`No compatible encryption modes. Available include: ${options.join(", ")}`); } return option; } -__name(chooseEncryptionMode, 'chooseEncryptionMode'); -function randomNBit(n) { +__name(chooseEncryptionMode, "chooseEncryptionMode"); +function randomNBit(n) +{ return Math.floor(Math.random() * 2 ** n); } -__name(randomNBit, 'randomNBit'); -var Networking = class extends import_tiny_typed_emitter3.TypedEmitter { - constructor(options, debug) { +__name(randomNBit, "randomNBit"); +var Networking = class extends import_node_events3.EventEmitter +{ + constructor(options, debug) + { super(); - __publicField(this, '_state'); - __publicField(this, 'debug'); + __publicField(this, "_state"); + __publicField(this, "debug"); this.onWsOpen = this.onWsOpen.bind(this); this.onChildError = this.onChildError.bind(this); this.onWsPacket = this.onWsPacket.bind(this); @@ -545,153 +624,168 @@ var Networking = class extends import_tiny_typed_emitter3.TypedEmitter { 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() { + destroy() + { this.state = { - code: 6 /* Closed */, + code: 6 /* Closed */ }; } - get state() { + get state() + { return this._state; } - set state(newState) { - 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); + set state(newState) + { + 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.destroy(); } - 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); + 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.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) { + 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); + onChildError(error) + { + this.emit("error", error); } - onWsOpen() { - if (this.state.code === 0 /* OpeningWs */) { + onWsOpen() + { + if (this.state.code === 0 /* OpeningWs */) + { const packet = { op: import_v42.VoiceOpcodes.Identify, d: { 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 */) { + } else if (this.state.code === 5 /* Resuming */) + { const packet = { op: import_v42.VoiceOpcodes.Resume, 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); } } - onWsClose({ code }) { + onWsClose({ code }) + { const canResume = code === 4015 || code < 4e3; - if (canResume && this.state.code === 4 /* Ready */) { + if (canResume && this.state.code === 4 /* Ready */) + { 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 */) { + } else if (this.state.code !== 6 /* Closed */) + { this.destroy(); - this.emit('close', code); + this.emit("close", code); } } - onUdpClose() { - if (this.state.code === 4 /* Ready */) { + onUdpClose() + { + if (this.state.code === 4 /* Ready */) + { this.state = { ...this.state, code: 5 /* Resuming */, - ws: this.createWebSocket(this.state.connectionOptions.endpoint), + ws: this.createWebSocket(this.state.connectionOptions.endpoint) }; } } - onWsPacket(packet) { - if (packet.op === import_v42.VoiceOpcodes.Hello && this.state.code !== 6 /* Closed */) { + onWsPacket(packet) + { + if (packet.op === import_v42.VoiceOpcodes.Hello && this.state.code !== 6 /* Closed */) + { this.state.ws.setHeartbeatInterval(packet.d.heartbeat_interval); - } else if (packet.op === import_v42.VoiceOpcodes.Ready && this.state.code === 1 /* Identifying */) { + } 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, @@ -705,66 +799,82 @@ to ${stringifyState(newState)}`); nonce: 0, nonceBuffer: Buffer.alloc(24), speaking: false, - packetsPlayed: 0, - }, + packetsPlayed: 0 + } }; - } else if (packet.op === import_v42.VoiceOpcodes.Resumed && this.state.code === 5 /* Resuming */) { + } 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; } } - onWsDebug(message) { + onWsDebug(message) + { this.debug?.(`[WS] ${message}`); } - onUdpDebug(message) { + onUdpDebug(message) + { this.debug?.(`[UDP] ${message}`); } - prepareAudioPacket(opusPacket) { + 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() { + 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; } return false; } - playAudioPacket(audioPacket) { + 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) { + 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) { + createAudioPacket(opusPacket, connectionData) + { const packetBuffer = Buffer.alloc(12); packetBuffer[0] = 128; packetBuffer[1] = 120; @@ -775,472 +885,561 @@ to ${stringifyState(newState)}`); packetBuffer.copy(nonce, 0, 0, 12); return Buffer.concat([packetBuffer, ...this.encryptOpusPacket(opusPacket, connectionData)]); } - encryptOpusPacket(opusPacket, connectionData) { + 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_v43 = require('discord-api-types/voice/v4'); +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_tiny_typed_emitter4 = require('tiny-typed-emitter'); +var import_node_events4 = __toESM(require("events")); // src/audio/AudioPlayerError.ts -var AudioPlayerError = class extends Error { - constructor(error, resource) { +var AudioPlayerError = class extends Error +{ + constructor(error, resource) + { super(error.message); - __publicField(this, 'resource'); + __publicField(this, "resource"); this.resource = resource; this.name = error.name; this.stack = error.stack; } }; -__name(AudioPlayerError, 'AudioPlayerError'); +__name(AudioPlayerError, "AudioPlayerError"); // src/audio/PlayerSubscription.ts -var PlayerSubscription = class { - constructor(connection, player) { - __publicField(this, 'connection'); - __publicField(this, 'player'); +var PlayerSubscription = class +{ + constructor(connection, player) + { + __publicField(this, "connection"); + __publicField(this, "player"); this.connection = connection; this.player = player; } - unsubscribe() { - this.connection['onSubscriptionRemoved'](this); - this.player['unsubscribe'](this); + unsubscribe() + { + this.connection["onSubscriptionRemoved"](this); + this.player["unsubscribe"](this); } }; -__name(PlayerSubscription, 'PlayerSubscription'); +__name(PlayerSubscription, "PlayerSubscription"); // src/audio/AudioPlayer.ts var SILENCE_FRAME = 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['Idle'] = 'idle'; - AudioPlayerStatus2['Buffering'] = 'buffering'; - AudioPlayerStatus2['Paused'] = 'paused'; - AudioPlayerStatus2['Playing'] = 'playing'; - AudioPlayerStatus2['AutoPaused'] = 'autopaused'; +var AudioPlayerStatus = /* @__PURE__ */ ((AudioPlayerStatus2) => +{ + AudioPlayerStatus2["Idle"] = "idle"; + AudioPlayerStatus2["Buffering"] = "buffering"; + AudioPlayerStatus2["Paused"] = "paused"; + AudioPlayerStatus2["Playing"] = "playing"; + AudioPlayerStatus2["AutoPaused"] = "autopaused"; return AudioPlayerStatus2; })(AudioPlayerStatus || {}); -function stringifyState2(state) { +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'); -var AudioPlayer = class extends import_tiny_typed_emitter4.TypedEmitter { - constructor(options = {}) { +__name(stringifyState2, "stringifyState"); +var AudioPlayer = class extends import_node_events4.default +{ + constructor(options = {}) + { super(); - __publicField(this, '_state'); - __publicField(this, 'subscribers', []); - __publicField(this, 'behaviors'); - __publicField(this, 'debug'); - this._state = { status: 'idle' /* Idle */ }; + __publicField(this, "_state"); + __publicField(this, "subscribers", []); + __publicField(this, "behaviors"); + __publicField(this, "debug"); + 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); + get playable() + { + return this.subscribers.filter(({ connection }) => connection.state.status === "ready" /* Ready */).map(({ connection }) => connection); } - subscribe(connection) { - const existingSubscription = this.subscribers.find(subscription => subscription.connection === connection); - if (!existingSubscription) { + subscribe(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; } - unsubscribe(subscription) { + unsubscribe(subscription) + { const index = this.subscribers.indexOf(subscription); const exists = index !== -1; - if (exists) { + if (exists) + { this.subscribers.splice(index, 1); subscription.connection.setSpeaking(false); - this.emit('unsubscribe', subscription); + this.emit("unsubscribe", subscription); } return exists; } - get state() { + get state() + { return this._state; } - set state(newState) { + 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) { + 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); - if (oldState.status !== newState.status || didChangeResources) { + this.emit("stateChange", oldState, this._state); + if (oldState.status !== newState.status || didChangeResources) + { this.emit(newState.status, oldState, this._state); } this.debug?.(`state change: from ${stringifyState2(oldState)} to ${stringifyState2(newState)}`); } - play(resource) { - if (resource.ended) { - throw new Error('Cannot play a resource that has already ended.'); + play(resource) + { + if (resource.ended) + { + throw new Error("Cannot play a resource that has already ended."); } - if (resource.audioPlayer) { - if (resource.audioPlayer === this) { + 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); - if (resource.started) { + }, "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) { + } else + { + const onReadableCallback = /* @__PURE__ */ __name(() => + { + 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'); - const onFailureCallback = /* @__PURE__ */ __name(() => { - if (this.state.status === 'buffering' /* Buffering */ && this.state.resource === resource) { + }, "onReadableCallback"); + const onFailureCallback = /* @__PURE__ */ __name(() => + { + 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; + pause(interpolateSilence = true) + { + 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; + unpause() + { + 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 (force || this.state.resource.silencePaddingFrames === 0) { + stop(force = 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) { + } else if (this.state.resource.silenceRemaining === -1) + { this.state.resource.silenceRemaining = this.state.resource.silencePaddingFrames; } return true; } - checkPlayable() { + checkPlayable() + { const state = this._state; - if (state.status === 'idle' /* Idle */ || state.status === 'buffering' /* Buffering */) return false; - if (!state.resource.readable) { + 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; } return true; } - _stepDispatch() { + _stepDispatch() + { const state = this._state; - if (state.status === 'idle' /* Idle */ || state.status === 'buffering' /* Buffering */) return; - this.playable.forEach(connection => connection.dispatchAudio()); + if (state.status === "idle" /* Idle */ || state.status === "buffering" /* Buffering */) + return; + this.playable.forEach((connection) => connection.dispatchAudio()); } - _stepPrepare() { + _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.silencePacketsRemaining > 0) { + if (state.status === "paused" /* Paused */ || state.status === "autopaused" /* AutoPaused */) + { + if (state.silencePacketsRemaining > 0) + { state.silencePacketsRemaining--; this._preparePacket(SILENCE_FRAME, playable, state); - if (state.silencePacketsRemaining === 0) { + if (state.silencePacketsRemaining === 0) + { this._signalStopSpeaking(); } } return; } - if (playable.length === 0) { - if (this.behaviors.noSubscriber === 'pause' /* Pause */) { + if (playable.length === 0) + { + 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 (packet) { + if (state.status === "playing" /* Playing */) + { + if (packet) + { this._preparePacket(packet, playable, state); state.missedFrames = 0; - } else { + } else + { this._preparePacket(SILENCE_FRAME, playable, state); state.missedFrames++; - if (state.missedFrames >= this.behaviors.maxMissedFrames) { + if (state.missedFrames >= this.behaviors.maxMissedFrames) + { this.stop(); } } } } - _signalStopSpeaking() { + _signalStopSpeaking() + { return this.subscribers.forEach(({ connection }) => connection.setSpeaking(false)); } - _preparePacket(packet, receivers, state) { + _preparePacket(packet, receivers, state) + { state.playbackDuration += 20; - receivers.forEach(connection => connection.prepareAudioPacket(packet)); + receivers.forEach((connection) => connection.prepareAudioPacket(packet)); } }; -__name(AudioPlayer, 'AudioPlayer'); -function createAudioPlayer(options) { +__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() { +function createDefaultAudioReceiveStreamOptions() +{ return { end: { - behavior: 0 /* Manual */, - }, + behavior: 0 /* Manual */ + } }; } -__name(createDefaultAudioReceiveStreamOptions, 'createDefaultAudioReceiveStreamOptions'); -var AudioReceiveStream = class extends import_node_stream.Readable { - constructor({ end, ...options }) { +__name(createDefaultAudioReceiveStreamOptions, "createDefaultAudioReceiveStreamOptions"); +var AudioReceiveStream = class extends import_node_stream.Readable +{ + constructor({ end, ...options }) + { super({ ...options, - objectMode: true, + objectMode: true }); - __publicField(this, 'end'); - __publicField(this, 'endTimeout'); + __publicField(this, "end"); + __publicField(this, "endTimeout"); this.end = end; } - push(buffer) { - if (buffer) { - if ( - this.end.behavior === 2 /* AfterInactivity */ || - (this.end.behavior === 1 /* AfterSilence */ && - (buffer.compare(SILENCE_FRAME) !== 0 || typeof this.endTimeout === 'undefined')) - ) { + push(buffer) + { + if (buffer) + { + if (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); } - renewEndTimeout(end) { - if (this.endTimeout) { + renewEndTimeout(end) + { + if (this.endTimeout) + { clearTimeout(this.endTimeout); } this.endTimeout = setTimeout(() => this.push(null), end.duration); } - _read() {} + _read() + { + } }; -__name(AudioReceiveStream, 'AudioReceiveStream'); +__name(AudioReceiveStream, "AudioReceiveStream"); // src/receive/SSRCMap.ts -var import_tiny_typed_emitter5 = require('tiny-typed-emitter'); -var SSRCMap = class extends import_tiny_typed_emitter5.TypedEmitter { - constructor() { +var import_node_events5 = require("events"); +var SSRCMap = class extends import_node_events5.EventEmitter +{ + constructor() + { super(); - __publicField(this, 'map'); + __publicField(this, "map"); this.map = /* @__PURE__ */ new Map(); } - update(data) { + update(data) + { 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') { + get(target) + { + if (typeof target === "number") + { return this.map.get(target); } - for (const data of this.map.values()) { - if (data.userId === target) { + for (const data of this.map.values()) + { + if (data.userId === target) + { return data; } } return void 0; } - delete(target) { - if (typeof target === 'number') { + delete(target) + { + if (typeof target === "number") + { const existing = this.map.get(target); - if (existing) { + 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) { + 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_tiny_typed_emitter6 = require('tiny-typed-emitter'); -var _SpeakingMap = class extends import_tiny_typed_emitter6.TypedEmitter { - constructor() { +var import_node_events6 = require("events"); +var _SpeakingMap = class extends import_node_events6.EventEmitter +{ + constructor() + { super(); - __publicField(this, 'users'); - __publicField(this, 'speakingTimeouts'); + __publicField(this, "users"); + __publicField(this, "speakingTimeouts"); this.users = /* @__PURE__ */ new Map(); this.speakingTimeouts = /* @__PURE__ */ new Map(); } - onPacket(userId) { + onPacket(userId) + { const timeout = this.speakingTimeouts.get(userId); - if (timeout) { + if (timeout) + { clearTimeout(timeout); - } else { + } else + { this.users.set(userId, Date.now()); - this.emit('start', userId); + this.emit("start", userId); } this.startTimeout(userId); } - startTimeout(userId) { - this.speakingTimeouts.set( - userId, - setTimeout(() => { - this.emit('end', userId); - this.speakingTimeouts.delete(userId); - this.users.delete(userId); - }, _SpeakingMap.DELAY), - ); + startTimeout(userId) + { + this.speakingTimeouts.set(userId, setTimeout(() => + { + this.emit("end", userId); + this.speakingTimeouts.delete(userId); + this.users.delete(userId); + }, _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 { - constructor(voiceConnection) { - __publicField(this, 'voiceConnection'); - __publicField(this, 'ssrcMap'); - __publicField(this, 'subscriptions'); - __publicField(this, 'connectionData'); - __publicField(this, 'speaking'); +var VoiceReceiver = class +{ + constructor(voiceConnection) + { + __publicField(this, "voiceConnection"); + __publicField(this, "ssrcMap"); + __publicField(this, "subscriptions"); + __publicField(this, "connectionData"); + __publicField(this, "speaking"); this.voiceConnection = voiceConnection; this.ssrcMap = new SSRCMap(); this.speaking = new SpeakingMap(); @@ -1249,122 +1448,125 @@ var VoiceReceiver = class { this.onWsPacket = this.onWsPacket.bind(this); this.onUdpMessage = this.onUdpMessage.bind(this); } - onWsPacket(packet) { - if (packet.op === import_v43.VoiceOpcodes.ClientDisconnect && typeof packet.d?.user_id === 'string') { + onWsPacket(packet) + { + 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) { + 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 { + } else + { buffer.copy(nonce2, 0, 0, 12); } const decrypted = methods.open(buffer.slice(12, end), nonce2, secretKey); - if (!decrypted) return; + if (!decrypted) + return; return Buffer.from(decrypted); } - parsePacket(buffer, mode, nonce2, secretKey) { + parsePacket(buffer, mode, nonce2, secretKey) + { let packet = this.decrypt(buffer, mode, nonce2, secretKey); - if (!packet) return; - if (packet[0] === 190 && packet[1] === 222 && packet.length > 4) { + if (!packet) + return; + if (packet[0] === 190 && packet[1] === 222) + { const headerExtensionLength = packet.readUInt16BE(2); - let offset = 4; - for (let i = 0; i < headerExtensionLength; i++) { - const byte2 = packet[offset]; - offset++; - if (byte2 === 0) continue; - offset += 1 + (byte2 >> 4); - } - const byte = packet.readUInt8(offset); - if (byte === 0 || byte === 2) offset++; - packet = packet.slice(offset); + packet = packet.subarray(4 + 4 * headerExtensionLength); } return packet; } - onUdpMessage(msg) { - if (msg.length <= 8) return; + onUdpMessage(msg) + { + 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 (this.connectionData.encryptionMode && this.connectionData.nonceBuffer && this.connectionData.secretKey) { - const packet = this.parsePacket( - msg, - this.connectionData.encryptionMode, - this.connectionData.nonceBuffer, - this.connectionData.secretKey, - ); - if (packet) { + 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); + if (packet) + { stream.push(packet); - } else { - stream.destroy(new Error('Failed to parse packet')); + } else + { + stream.destroy(new Error("Failed to parse packet")); } } } - subscribe(userId, options) { + 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['Signalling'] = 'signalling'; - VoiceConnectionStatus2['Connecting'] = 'connecting'; - VoiceConnectionStatus2['Ready'] = 'ready'; - VoiceConnectionStatus2['Disconnected'] = 'disconnected'; - VoiceConnectionStatus2['Destroyed'] = 'destroyed'; +var VoiceConnectionStatus = /* @__PURE__ */ ((VoiceConnectionStatus2) => +{ + VoiceConnectionStatus2["Signalling"] = "signalling"; + VoiceConnectionStatus2["Connecting"] = "connecting"; + VoiceConnectionStatus2["Ready"] = "ready"; + VoiceConnectionStatus2["Disconnected"] = "disconnected"; + VoiceConnectionStatus2["Destroyed"] = "destroyed"; 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 VoiceConnection2 = class extends import_tiny_typed_emitter7.TypedEmitter { - constructor(joinConfig, { debug, adapterCreator }) { +var VoiceConnection2 = class extends import_node_events7.EventEmitter +{ + constructor(joinConfig, { debug, adapterCreator }) + { super(); - __publicField(this, 'rejoinAttempts'); - __publicField(this, '_state'); - __publicField(this, 'joinConfig'); - __publicField(this, 'packets'); - __publicField(this, 'receiver'); - __publicField(this, 'debug'); - this.debug = debug ? message => this.emit('debug', message) : null; + __publicField(this, "rejoinAttempts"); + __publicField(this, "_state"); + __publicField(this, "joinConfig"); + __publicField(this, "packets"); + __publicField(this, "receiver"); + __publicField(this, "debug"); + this.debug = debug ? (message) => this.emit("debug", message) : null; this.rejoinAttempts = 0; this.receiver = new VoiceReceiver(this); this.onNetworkingClose = this.onNetworkingClose.bind(this); @@ -1372,221 +1574,272 @@ var VoiceConnection2 = class extends import_tiny_typed_emitter7.TypedEmitter { this.onNetworkingError = this.onNetworkingError.bind(this); this.onNetworkingDebug = this.onNetworkingDebug.bind(this); const adapter = 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; } - get state() { + get state() + { return this._state; } - set state(newState) { + 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'); - 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); + 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.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 */) { - for (const stream of this.receiver.subscriptions.values()) { - if (!stream.destroyed) stream.destroy(); + } else if (newState.status === "destroyed" /* Destroyed */) + { + for (const stream of this.receiver.subscriptions.values()) + { + 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) { + if (oldSubscription && oldSubscription !== newSubscription) + { oldSubscription.unsubscribe(); } - this.emit('stateChange', oldState, newState); - if (oldState.status !== newState.status) { + this.emit("stateChange", oldState, newState); + if (oldState.status !== newState.status) + { this.emit(newState.status, oldState, newState); } } - addServerPacket(packet) { + addServerPacket(packet) + { this.packets.server = packet; - if (packet.endpoint) { + 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) { + 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'); - if (oldWs !== newWs) { - oldWs?.off('packet', this.receiver.onWsPacket); - newWs?.on('packet', this.receiver.onWsPacket); + 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"); + if (oldWs !== newWs) + { + 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); + if (oldUdp !== newUdp) + { + 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() { + configureNetworking() + { const { server, state } = this.packets; - 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, - }, - Boolean(this.debug), - ); - networking.once('close', this.onNetworkingClose); - networking.on('stateChange', this.onNetworkingStateChange); - networking.on('error', this.onNetworkingError); - networking.on('debug', this.onNetworkingDebug); + if (!server || !state || this.state.status === "destroyed" /* Destroyed */ || !server.endpoint) + return; + const networking = new Networking({ + endpoint: server.endpoint, + serverId: server.guild_id, + token: server.token, + sessionId: state.session_id, + userId: state.user_id + }, Boolean(this.debug)); + 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 (code === 4014) { + onNetworkingClose(code) + { + 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 { + } else + { this.state = { ...this.state, - status: 'signalling' /* Signalling */, + status: "signalling" /* Signalling */ }; this.rejoinAttempts++; - if (!this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) { + 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) { + 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 (newState.code === 4 /* Ready */) { + 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 */) { + } else if (newState.code !== 6 /* Closed */) + { this.state = { ...this.state, - status: 'connecting' /* Connecting */, + status: "connecting" /* Connecting */ }; } } - onNetworkingError(error) { - this.emit('error', error); + onNetworkingError(error) + { + this.emit("error", error); } - onNetworkingDebug(message) { + onNetworkingDebug(message) + { this.debug?.(`[NW] ${message}`); } - prepareAudioPacket(buffer) { + prepareAudioPacket(buffer) + { const state = this.state; - if (state.status !== 'ready' /* Ready */) return; + if (state.status !== "ready" /* Ready */) + return; return state.networking.prepareAudioPacket(buffer); } - dispatchAudio() { + dispatchAudio() + { const state = this.state; - if (state.status !== 'ready' /* Ready */) return; + if (state.status !== "ready" /* Ready */) + return; return state.networking.dispatchAudio(); } - playOpusPacket(buffer) { + 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'); + destroy(adapterAvailable = true) + { + 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) { + if (getVoiceConnection(this.joinConfig.guildId, this.joinConfig.group) === this) + { untrackVoiceConnection(this); } - if (adapterAvailable) { + if (adapterAvailable) + { 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 */) { + disconnect() + { + if (this.state.status === "destroyed" /* Destroyed */ || this.state.status === "signalling" /* Signalling */) + { return false; } this.joinConfig.channelId = null; - if (!this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) { + if (!this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) + { 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 */) { + rejoin(joinConfig) + { + 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) { + if (this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) + { + if (notReady) + { this.state = { ...this.state, - status: 'signalling' /* Signalling */, + status: "signalling" /* Signalling */ }; } return true; @@ -1594,518 +1847,598 @@ var VoiceConnection2 = class extends import_tiny_typed_emitter7.TypedEmitter { 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; + setSpeaking(enabled) + { + 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); + subscribe(player) + { + 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 */) { + get ping() + { + 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) { + onSubscriptionRemoved(subscription) + { + if (this.state.status !== "destroyed" /* Destroyed */ && this.state.subscription === subscription) + { this.state = { ...this.state, - subscription: void 0, + subscription: void 0 }; } } }; -__name(VoiceConnection2, 'VoiceConnection'); -function createVoiceConnection(joinConfig, options) { +__name(VoiceConnection2, "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)) { + } 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 VoiceConnection2(joinConfig, options); trackVoiceConnection(voiceConnection); - if (voiceConnection.state.status !== 'destroyed' /* Destroyed */) { - if (!voiceConnection.state.adapter.sendPayload(payload)) { + if (voiceConnection.state.status !== "destroyed" /* Destroyed */) + { + if (!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) { +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['Raw'] = 'raw'; - StreamType2['OggOpus'] = 'ogg/opus'; - StreamType2['WebmOpus'] = 'webm/opus'; - StreamType2['Opus'] = 'opus'; +var StreamType = /* @__PURE__ */ ((StreamType2) => +{ + StreamType2["Arbitrary"] = "arbitrary"; + StreamType2["Raw"] = "raw"; + StreamType2["OggOpus"] = "ogg/opus"; + StreamType2["WebmOpus"] = "webm/opus"; + StreamType2["Opus"] = "opus"; return StreamType2; })(StreamType || {}); -var Node = class { - constructor(type) { - __publicField(this, 'edges', []); - __publicField(this, 'type'); +var Node = class +{ + constructor(type) + { + __publicField(this, "edges", []); + __publicField(this, "type"); this.type = type; } - addEdge(edge) { + addEdge(edge) + { this.edges.push({ ...edge, from: this }); } }; -__name(Node, 'Node'); +__name(Node, "Node"); var NODES = /* @__PURE__ */ new Map(); -for (const streamType of Object.values(StreamType)) { +for (const streamType of Object.values(StreamType)) +{ NODES.set(streamType, new Node(streamType)); } -function getNode(type) { +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 {} +function canEnableFFmpegOptimizations() +{ + try + { + return import_prism_media.default.FFmpeg.getInfo().output.includes("--enable-libopus"); + } catch { + } return false; } -__name(canEnableFFmpegOptimizations, 'canEnableFFmpegOptimizations'); -if (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) { - if (from === goal && constraints(path)) { +function findPath(from, constraints, goal = getNode("opus" /* Opus */), path = [], depth = 5) +{ + if (from === goal && constraints(path)) + { return { cost: 0 }; - } else if (depth === 0) { + } else if (depth === 0) + { return { cost: Infinity }; } let currentBest = void 0; - for (const edge of from.edges) { - if (currentBest && edge.cost > currentBest.cost) continue; + for (const edge of from.edges) + { + 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) { + if (!currentBest || cost < currentBest.cost) + { currentBest = { cost, edge, next }; } } return currentBest ?? { cost: Infinity }; } -__name(findPath, 'findPath'); -function constructPipeline(step) { +__name(findPath, "findPath"); +function constructPipeline(step) +{ const edges = []; let current = step; - while (current?.edge) { + while (current?.edge) + { edges.push(current.edge); current = current.next; } return edges; } -__name(constructPipeline, 'constructPipeline'); -function findPipeline(from, constraint) { +__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 { - constructor(edges, streams, metadata, silencePaddingFrames) { - __publicField(this, 'playStream'); - __publicField(this, 'edges'); - __publicField(this, 'metadata'); - __publicField(this, 'volume'); - __publicField(this, 'encoder'); - __publicField(this, 'audioPlayer'); - __publicField(this, 'playbackDuration', 0); - __publicField(this, 'started', false); - __publicField(this, 'silencePaddingFrames'); - __publicField(this, 'silenceRemaining', -1); +var AudioResource = class +{ + constructor(edges, streams, metadata, silencePaddingFrames) + { + __publicField(this, "playStream"); + __publicField(this, "edges"); + __publicField(this, "metadata"); + __publicField(this, "volume"); + __publicField(this, "encoder"); + __publicField(this, "audioPlayer"); + __publicField(this, "playbackDuration", 0); + __publicField(this, "started", false); + __publicField(this, "silencePaddingFrames"); + __publicField(this, "silenceRemaining", -1); this.edges = edges; this.playStream = streams.length > 1 ? (0, import_node_stream2.pipeline)(streams, noop) : streams[0]; this.metadata = metadata; this.silencePaddingFrames = silencePaddingFrames; - for (const stream of streams) { - if (stream instanceof import_prism_media2.default.VolumeTransformer) { + for (const stream of streams) + { + if (stream instanceof import_prism_media2.default.VolumeTransformer) + { this.volume = stream; - } else if (stream instanceof import_prism_media2.default.opus.Encoder) { + } else if (stream instanceof import_prism_media2.default.opus.Encoder) + { 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; + get readable() + { + if (this.silenceRemaining === 0) + return false; const real = this.playStream.readable; - if (!real) { - if (this.silenceRemaining === -1) this.silenceRemaining = this.silencePaddingFrames; + if (!real) + { + if (this.silenceRemaining === -1) + this.silenceRemaining = this.silencePaddingFrames; return this.silenceRemaining !== 0; } return real; } - get ended() { + get ended() + { return this.playStream.readableEnded || this.playStream.destroyed || this.silenceRemaining === 0; } - read() { - if (this.silenceRemaining === 0) { + read() + { + if (this.silenceRemaining === 0) + { return null; - } else if (this.silenceRemaining > 0) { + } else if (this.silenceRemaining > 0) + { this.silenceRemaining--; return SILENCE_FRAME; } const packet = this.playStream.read(); - if (packet) { + if (packet) + { this.playbackDuration += 20; } 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'); -function inferStreamType(stream) { - if (stream instanceof import_prism_media2.default.opus.Encoder) { - return { streamType: 'opus' /* Opus */, hasVolume: false }; - } else if (stream instanceof import_prism_media2.default.opus.Decoder) { - return { streamType: 'raw' /* Raw */, hasVolume: false }; - } else if (stream instanceof import_prism_media2.default.VolumeTransformer) { - return { streamType: 'raw' /* Raw */, hasVolume: true }; - } else if (stream instanceof import_prism_media2.default.opus.OggDemuxer) { - return { streamType: 'opus' /* Opus */, hasVolume: false }; - } else if (stream instanceof import_prism_media2.default.opus.WebmDemuxer) { - return { streamType: 'opus' /* Opus */, hasVolume: false }; +__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 }; + } else if (stream instanceof import_prism_media2.default.opus.Decoder) + { + return { streamType: "raw" /* Raw */, hasVolume: false }; + } else if (stream instanceof import_prism_media2.default.VolumeTransformer) + { + return { streamType: "raw" /* Raw */, hasVolume: true }; + } else if (stream instanceof import_prism_media2.default.opus.OggDemuxer) + { + return { streamType: "opus" /* Opus */, hasVolume: false }; + } else if (stream instanceof import_prism_media2.default.opus.WebmDemuxer) + { + return { streamType: "opus" /* Opus */, hasVolume: false }; } - return { streamType: 'arbitrary' /* Arbitrary */, hasVolume: false }; + return { streamType: "arbitrary" /* Arbitrary */, hasVolume: false }; } -__name(inferStreamType, 'inferStreamType'); -function createAudioResource(input, options = {}) { +__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 (transformerPipeline.length === 0) + { + 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); + 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')); -function findPackageJSON(dir, packageName, depth) { - if (depth === 0) return void 0; - const attemptedPath = (0, import_node_path.resolve)(dir, './package.json'); - try { +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"); + 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 (err) { - return findPackageJSON((0, import_node_path.resolve)(dir, '..'), packageName, depth - 1); + } catch (err) + { + return findPackageJSON((0, import_node_path.resolve)(dir, ".."), packageName, depth - 1); } } -__name(findPackageJSON, 'findPackageJSON'); -function version(name) { - try { - const pkg = - name === '@discordjs/voice' - ? require_package() - : findPackageJSON((0, import_node_path.dirname)(require.resolve(name)), name, 3); - return pkg?.version ?? 'not found'; - } catch (err) { - return 'not found'; +__name(findPackageJSON, "findPackageJSON"); +function version(name) +{ + try + { + const pkg = name === "@discordjs/voice" ? require_package() : findPackageJSON((0, import_node_path.dirname)(require.resolve(name)), name, 3); + return pkg?.version ?? "not found"; + } catch (err) + { + return "not found"; } } -__name(version, 'version'); -function generateDependencyReport() { +__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'); - try { + 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'}`); - } catch (err) { - report.push('- not found'); + report.push(`- libopus: ${info.output.includes("--enable-libopus") ? "yes" : "no"}`); + } catch (err) + { + 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_events = require('events'); +var import_node_events8 = require("events"); // src/util/abortAfter.ts -function abortAfter(delay) { +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]; - try { - await (0, import_node_events.once)(target, status, { signal }); - } finally { +async function entersState(target, status, timeoutOrSignal) +{ + if (target.state.status !== status) + { + const [ac, signal] = typeof timeoutOrSignal === "number" ? abortAfter(timeoutOrSignal) : [void 0, timeoutOrSignal]; + try + { + await (0, import_node_events8.once)(target, status, { signal }); + } finally + { ac?.abort(); } } return target; } -__name(entersState, 'entersState'); +__name(entersState, "entersState"); // src/util/demuxProbe.ts -var import_node_stream3 = require('stream'); -var import_prism_media4 = __toESM(require('prism-media')); -function validateDiscordOpusHead(opusHead) { +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'); -function demuxProbe(stream, probeSize = 1024, validator = validateDiscordOpusHead) { - return new Promise((resolve2, reject) => { - if (stream.readableObjectMode) return reject(new Error('Cannot probe a readable stream in object mode')); - if (stream.readableEnded) return reject(new Error('Cannot probe a stream that has ended')); +__name(validateDiscordOpusHead, "validateDiscordOpusHead"); +function demuxProbe(stream, probeSize = 1024, validator = validateDiscordOpusHead) +{ + return new Promise((resolve2, reject) => + { + if (stream.readableObjectMode) + return reject(new Error("Cannot probe a readable stream in object mode")); + if (stream.readableEnded) + return reject(new Error("Cannot probe a stream that has ended")); let readBuffer = Buffer.alloc(0); let resolved = void 0; - 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) { + if (stream.readableEnded) + { resolve2({ stream: import_node_stream3.Readable.from(readBuffer), - type, + type }); - } else { - if (readBuffer.length > 0) { + } else + { + if (readBuffer.length > 0) + { stream.push(readBuffer); } resolve2({ stream, - type, + type }); } - }, '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 */)); - const ogg = new import_prism_media4.default.opus.OggDemuxer(); - ogg.once('error', noop); - ogg.on('head', foundHead('ogg/opus' /* OggOpus */)); - const onClose = /* @__PURE__ */ __name(() => { - if (!resolved) { - finish('arbitrary' /* Arbitrary */); + }, "finish"); + const foundHead = /* @__PURE__ */ __name((type) => (head) => + { + if (validator(head)) + { + finish(type); } - }, 'onClose'); - const onData = /* @__PURE__ */ __name(buffer => { + }, "foundHead"); + const webm = new import_prism_media4.default.opus.WebmDemuxer(); + 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 */)); + const onClose = /* @__PURE__ */ __name(() => + { + if (!resolved) + { + finish("arbitrary" /* Arbitrary */); + } + }, "onClose"); + const onData = /* @__PURE__ */ __name((buffer) => + { readBuffer = Buffer.concat([readBuffer, buffer]); webm.write(buffer); ogg.write(buffer); - if (readBuffer.length >= probeSize) { - stream.off('data', onData); + if (readBuffer.length >= probeSize) + { + stream.off("data", onData); stream.pause(); process.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"); // 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, - Networking, - createAudioPlayer, - createAudioResource, - createDefaultAudioReceiveStreamOptions, - demuxProbe, - entersState, - generateDependencyReport, - getGroups, - getVoiceConnection, - getVoiceConnections, - joinVoiceChannel, - validateDiscordOpusHead, - }); -//# sourceMappingURL=index.js.map +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, + Networking, +}); +//# sourceMappingURL=index.js.map \ No newline at end of file