@discordjs/voice 0.11.0 → 0.12.1-dev.1658330951-a05386a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +4 -1
  2. package/dist/DataStore.cjs +100 -0
  3. package/dist/DataStore.cjs.map +1 -0
  4. package/dist/DataStore.d.ts +78 -0
  5. package/dist/DataStore.d.ts.map +1 -0
  6. package/dist/DataStore.mjs +88 -0
  7. package/dist/DataStore.mjs.map +1 -0
  8. package/dist/VoiceConnection.cjs +350 -0
  9. package/dist/VoiceConnection.cjs.map +1 -0
  10. package/dist/VoiceConnection.d.ts +349 -0
  11. package/dist/VoiceConnection.d.ts.map +1 -0
  12. package/dist/VoiceConnection.mjs +343 -0
  13. package/dist/VoiceConnection.mjs.map +1 -0
  14. package/dist/audio/AudioPlayer.cjs +286 -0
  15. package/dist/audio/AudioPlayer.cjs.map +1 -0
  16. package/dist/audio/AudioPlayer.d.ts +296 -0
  17. package/dist/audio/AudioPlayer.d.ts.map +1 -0
  18. package/dist/audio/AudioPlayer.mjs +274 -0
  19. package/dist/audio/AudioPlayer.mjs.map +1 -0
  20. package/dist/audio/AudioPlayerError.cjs +15 -0
  21. package/dist/audio/AudioPlayerError.cjs.map +1 -0
  22. package/dist/audio/AudioPlayerError.d.ts +13 -0
  23. package/dist/audio/AudioPlayerError.d.ts.map +1 -0
  24. package/dist/audio/AudioPlayerError.mjs +11 -0
  25. package/dist/audio/AudioPlayerError.mjs.map +1 -0
  26. package/dist/audio/AudioResource.cjs +104 -0
  27. package/dist/audio/AudioResource.cjs.map +1 -0
  28. package/dist/audio/AudioResource.d.ts +155 -0
  29. package/dist/audio/AudioResource.d.ts.map +1 -0
  30. package/dist/audio/AudioResource.mjs +92 -0
  31. package/dist/audio/AudioResource.mjs.map +1 -0
  32. package/dist/audio/PlayerSubscription.cjs +17 -0
  33. package/dist/audio/PlayerSubscription.cjs.map +1 -0
  34. package/dist/audio/PlayerSubscription.d.ts +23 -0
  35. package/dist/audio/PlayerSubscription.d.ts.map +1 -0
  36. package/dist/audio/PlayerSubscription.mjs +13 -0
  37. package/dist/audio/PlayerSubscription.mjs.map +1 -0
  38. package/dist/audio/TransformerGraph.cjs +160 -0
  39. package/dist/audio/TransformerGraph.cjs.map +1 -0
  40. package/dist/audio/TransformerGraph.d.ts +75 -0
  41. package/dist/audio/TransformerGraph.d.ts.map +1 -0
  42. package/dist/audio/TransformerGraph.mjs +148 -0
  43. package/dist/audio/TransformerGraph.mjs.map +1 -0
  44. package/dist/audio/index.d.ts +6 -0
  45. package/dist/audio/index.d.ts.map +1 -0
  46. package/dist/index.cjs +49 -0
  47. package/dist/index.cjs.map +1 -0
  48. package/dist/index.d.ts +7 -1653
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.mjs +16 -2066
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/joinVoiceChannel.cjs +21 -0
  53. package/dist/joinVoiceChannel.cjs.map +1 -0
  54. package/dist/joinVoiceChannel.d.ts +45 -0
  55. package/dist/joinVoiceChannel.d.ts.map +1 -0
  56. package/dist/joinVoiceChannel.mjs +17 -0
  57. package/dist/joinVoiceChannel.mjs.map +1 -0
  58. package/dist/networking/Networking.cjs +308 -0
  59. package/dist/networking/Networking.cjs.map +1 -0
  60. package/dist/networking/Networking.d.ts +253 -0
  61. package/dist/networking/Networking.d.ts.map +1 -0
  62. package/dist/networking/Networking.mjs +302 -0
  63. package/dist/networking/Networking.mjs.map +1 -0
  64. package/dist/networking/VoiceUDPSocket.cjs +99 -0
  65. package/dist/networking/VoiceUDPSocket.cjs.map +1 -0
  66. package/dist/networking/VoiceUDPSocket.d.ts +93 -0
  67. package/dist/networking/VoiceUDPSocket.d.ts.map +1 -0
  68. package/dist/networking/VoiceUDPSocket.mjs +94 -0
  69. package/dist/networking/VoiceUDPSocket.mjs.map +1 -0
  70. package/dist/networking/VoiceWebSocket.cjs +90 -0
  71. package/dist/networking/VoiceWebSocket.cjs.map +1 -0
  72. package/dist/networking/VoiceWebSocket.d.ts +90 -0
  73. package/dist/networking/VoiceWebSocket.d.ts.map +1 -0
  74. package/dist/networking/VoiceWebSocket.mjs +82 -0
  75. package/dist/networking/VoiceWebSocket.mjs.map +1 -0
  76. package/dist/networking/index.d.ts +4 -0
  77. package/dist/networking/index.d.ts.map +1 -0
  78. package/dist/receive/AudioReceiveStream.cjs +50 -0
  79. package/dist/receive/AudioReceiveStream.cjs.map +1 -0
  80. package/dist/receive/AudioReceiveStream.d.ts +46 -0
  81. package/dist/receive/AudioReceiveStream.d.ts.map +1 -0
  82. package/dist/receive/AudioReceiveStream.mjs +44 -0
  83. package/dist/receive/AudioReceiveStream.mjs.map +1 -0
  84. package/dist/receive/SSRCMap.cjs +55 -0
  85. package/dist/receive/SSRCMap.cjs.map +1 -0
  86. package/dist/receive/SSRCMap.d.ts +56 -0
  87. package/dist/receive/SSRCMap.d.ts.map +1 -0
  88. package/dist/receive/SSRCMap.mjs +51 -0
  89. package/dist/receive/SSRCMap.mjs.map +1 -0
  90. package/dist/receive/SpeakingMap.cjs +35 -0
  91. package/dist/receive/SpeakingMap.cjs.map +1 -0
  92. package/dist/receive/SpeakingMap.d.ts +32 -0
  93. package/dist/receive/SpeakingMap.d.ts.map +1 -0
  94. package/dist/receive/SpeakingMap.mjs +31 -0
  95. package/dist/receive/SpeakingMap.mjs.map +1 -0
  96. package/dist/receive/VoiceReceiver.cjs +95 -0
  97. package/dist/receive/VoiceReceiver.cjs.map +1 -0
  98. package/dist/receive/VoiceReceiver.d.ts +74 -0
  99. package/dist/receive/VoiceReceiver.d.ts.map +1 -0
  100. package/dist/receive/VoiceReceiver.mjs +91 -0
  101. package/dist/receive/VoiceReceiver.mjs.map +1 -0
  102. package/dist/receive/index.d.ts +5 -0
  103. package/dist/receive/index.d.ts.map +1 -0
  104. package/dist/util/Secretbox.cjs +69 -0
  105. package/dist/util/Secretbox.cjs.map +1 -0
  106. package/dist/util/Secretbox.d.ts +9 -0
  107. package/dist/util/Secretbox.d.ts.map +1 -0
  108. package/dist/util/Secretbox.mjs +74 -0
  109. package/dist/util/Secretbox.mjs.map +1 -0
  110. package/dist/util/abortAfter.cjs +13 -0
  111. package/dist/util/abortAfter.cjs.map +1 -0
  112. package/dist/util/abortAfter.d.ts +8 -0
  113. package/dist/util/abortAfter.d.ts.map +1 -0
  114. package/dist/util/abortAfter.mjs +9 -0
  115. package/dist/util/abortAfter.mjs.map +1 -0
  116. package/dist/util/adapter.d.ts +49 -0
  117. package/dist/util/adapter.d.ts.map +1 -0
  118. package/dist/util/demuxProbe.cjs +91 -0
  119. package/dist/util/demuxProbe.cjs.map +1 -0
  120. package/dist/util/demuxProbe.d.ts +37 -0
  121. package/dist/util/demuxProbe.d.ts.map +1 -0
  122. package/dist/util/demuxProbe.mjs +82 -0
  123. package/dist/util/demuxProbe.mjs.map +1 -0
  124. package/dist/util/entersState.cjs +21 -0
  125. package/dist/util/entersState.cjs.map +1 -0
  126. package/dist/util/entersState.d.ts +20 -0
  127. package/dist/util/entersState.d.ts.map +1 -0
  128. package/dist/util/entersState.mjs +17 -0
  129. package/dist/util/entersState.mjs.map +1 -0
  130. package/dist/util/generateDependencyReport.cjs +62 -0
  131. package/dist/util/generateDependencyReport.cjs.map +1 -0
  132. package/dist/util/generateDependencyReport.d.ts +6 -0
  133. package/dist/util/generateDependencyReport.d.ts.map +1 -0
  134. package/dist/util/generateDependencyReport.mjs +63 -0
  135. package/dist/util/generateDependencyReport.mjs.map +1 -0
  136. package/dist/util/index.d.ts +5 -0
  137. package/dist/util/index.d.ts.map +1 -0
  138. package/dist/util/util.cjs +9 -0
  139. package/dist/util/util.cjs.map +1 -0
  140. package/dist/util/util.d.ts +2 -0
  141. package/dist/util/util.d.ts.map +1 -0
  142. package/dist/util/util.mjs +5 -0
  143. package/dist/util/util.mjs.map +1 -0
  144. package/package.json +14 -10
  145. package/dist/index.js +0 -2111
  146. package/dist/index.js.map +0 -1
package/README.md CHANGED
@@ -4,13 +4,16 @@
4
4
  <a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
5
5
  </p>
6
6
  <br />
7
- <p>
7
+ <p>
8
8
  <a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
9
9
  <a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/v/@discordjs/voice.svg?maxAge=3600" alt="npm version" /></a>
10
10
  <a href="https://www.npmjs.com/package/@discordjs/voice"><img src="https://img.shields.io/npm/dt/@discordjs/voice.svg?maxAge=3600" alt="npm downloads" /></a>
11
11
  <a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
12
12
  <a href="https://codecov.io/gh/discordjs/discord.js" ><img src="https://codecov.io/gh/discordjs/discord.js/branch/main/graph/badge.svg?precision=2&flag=voice" alt="Code coverage" /></a>
13
13
  </p>
14
+ <p>
15
+ <a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://github.com/discordjs/discord.js/blob/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
16
+ </p>
14
17
  </div>
15
18
 
16
19
  ## About
@@ -0,0 +1,100 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const v10 = require('discord-api-types/v10');
6
+
7
+ function createJoinVoiceChannelPayload(config) {
8
+ return {
9
+ op: v10.GatewayOpcodes.VoiceStateUpdate,
10
+ d: {
11
+ guild_id: config.guildId,
12
+ channel_id: config.channelId,
13
+ self_deaf: config.selfDeaf,
14
+ self_mute: config.selfMute
15
+ }
16
+ };
17
+ }
18
+ const groups = /* @__PURE__ */ new Map();
19
+ groups.set("default", /* @__PURE__ */ new Map());
20
+ function getOrCreateGroup(group) {
21
+ const existing = groups.get(group);
22
+ if (existing)
23
+ return existing;
24
+ const map = /* @__PURE__ */ new Map();
25
+ groups.set(group, map);
26
+ return map;
27
+ }
28
+ function getGroups() {
29
+ return groups;
30
+ }
31
+ function getVoiceConnections(group = "default") {
32
+ return groups.get(group);
33
+ }
34
+ function getVoiceConnection(guildId, group = "default") {
35
+ return getVoiceConnections(group)?.get(guildId);
36
+ }
37
+ function untrackVoiceConnection(voiceConnection) {
38
+ return getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId);
39
+ }
40
+ function trackVoiceConnection(voiceConnection) {
41
+ return getOrCreateGroup(voiceConnection.joinConfig.group).set(voiceConnection.joinConfig.guildId, voiceConnection);
42
+ }
43
+ const FRAME_LENGTH = 20;
44
+ let audioCycleInterval;
45
+ let nextTime = -1;
46
+ const audioPlayers = [];
47
+ function audioCycleStep() {
48
+ if (nextTime === -1)
49
+ return;
50
+ nextTime += FRAME_LENGTH;
51
+ const available = audioPlayers.filter((player) => player.checkPlayable());
52
+ available.forEach((player) => player["_stepDispatch"]());
53
+ prepareNextAudioFrame(available);
54
+ }
55
+ function prepareNextAudioFrame(players) {
56
+ const nextPlayer = players.shift();
57
+ if (!nextPlayer) {
58
+ if (nextTime !== -1) {
59
+ audioCycleInterval = setTimeout(() => audioCycleStep(), nextTime - Date.now());
60
+ }
61
+ return;
62
+ }
63
+ nextPlayer["_stepPrepare"]();
64
+ setImmediate(() => prepareNextAudioFrame(players));
65
+ }
66
+ function hasAudioPlayer(target) {
67
+ return audioPlayers.includes(target);
68
+ }
69
+ function addAudioPlayer(player) {
70
+ if (hasAudioPlayer(player))
71
+ return player;
72
+ audioPlayers.push(player);
73
+ if (audioPlayers.length === 1) {
74
+ nextTime = Date.now();
75
+ setImmediate(() => audioCycleStep());
76
+ }
77
+ return player;
78
+ }
79
+ function deleteAudioPlayer(player) {
80
+ const index = audioPlayers.indexOf(player);
81
+ if (index === -1)
82
+ return;
83
+ audioPlayers.splice(index, 1);
84
+ if (audioPlayers.length === 0) {
85
+ nextTime = -1;
86
+ if (typeof audioCycleInterval !== "undefined")
87
+ clearTimeout(audioCycleInterval);
88
+ }
89
+ }
90
+
91
+ exports.addAudioPlayer = addAudioPlayer;
92
+ exports.createJoinVoiceChannelPayload = createJoinVoiceChannelPayload;
93
+ exports.deleteAudioPlayer = deleteAudioPlayer;
94
+ exports.getGroups = getGroups;
95
+ exports.getVoiceConnection = getVoiceConnection;
96
+ exports.getVoiceConnections = getVoiceConnections;
97
+ exports.hasAudioPlayer = hasAudioPlayer;
98
+ exports.trackVoiceConnection = trackVoiceConnection;
99
+ exports.untrackVoiceConnection = untrackVoiceConnection;
100
+ //# sourceMappingURL=DataStore.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataStore.cjs","sources":["../src/DataStore.ts"],"sourcesContent":["import { GatewayOpcodes } from 'discord-api-types/v10';\nimport type { VoiceConnection } from './VoiceConnection';\nimport type { AudioPlayer } from './audio';\n\nexport interface JoinConfig {\n\tguildId: string;\n\tchannelId: string | null;\n\tselfDeaf: boolean;\n\tselfMute: boolean;\n\tgroup: string;\n}\n\n/**\n * Sends a voice state update to the main websocket shard of a guild, to indicate joining/leaving/moving across\n * voice channels.\n *\n * @param config - The configuration to use when joining the voice channel\n */\nexport function createJoinVoiceChannelPayload(config: JoinConfig) {\n\treturn {\n\t\top: GatewayOpcodes.VoiceStateUpdate,\n\t\td: {\n\t\t\tguild_id: config.guildId,\n\t\t\tchannel_id: config.channelId,\n\t\t\tself_deaf: config.selfDeaf,\n\t\t\tself_mute: config.selfMute,\n\t\t},\n\t};\n}\n\n// Voice Connections\nconst groups = new Map<string, Map<string, VoiceConnection>>();\ngroups.set('default', new Map());\n\nfunction getOrCreateGroup(group: string) {\n\tconst existing = groups.get(group);\n\tif (existing) return existing;\n\tconst map = new Map<string, VoiceConnection>();\n\tgroups.set(group, map);\n\treturn map;\n}\n\n/**\n * Retrieves the map of group names to maps of voice connections. By default, all voice connections\n * are created under the 'default' group.\n *\n * @returns The group map\n */\nexport function getGroups() {\n\treturn groups;\n}\n\n/**\n * Retrieves all the voice connections under the 'default' group.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group?: 'default'): Map<string, VoiceConnection>;\n\n/**\n * Retrieves all the voice connections under the given group name.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group: string): Map<string, VoiceConnection> | undefined;\n\n/**\n * Retrieves all the voice connections under the given group name. Defaults to the 'default' group.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group = 'default') {\n\treturn groups.get(group);\n}\n\n/**\n * Finds a voice connection with the given guild id and group. Defaults to the 'default' group.\n *\n * @param guildId - The guild id of the voice connection\n * @param group - the group that the voice connection was registered with\n *\n * @returns The voice connection, if it exists\n */\nexport function getVoiceConnection(guildId: string, group = 'default') {\n\treturn getVoiceConnections(group)?.get(guildId);\n}\n\nexport function untrackVoiceConnection(voiceConnection: VoiceConnection) {\n\treturn getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId);\n}\n\nexport function trackVoiceConnection(voiceConnection: VoiceConnection) {\n\treturn getOrCreateGroup(voiceConnection.joinConfig.group).set(voiceConnection.joinConfig.guildId, voiceConnection);\n}\n\n// Audio Players\n\n// Each audio packet is 20ms long\nconst FRAME_LENGTH = 20;\n\nlet audioCycleInterval: NodeJS.Timeout | undefined;\nlet nextTime = -1;\n\n/**\n * A list of created audio players that are still active and haven't been destroyed.\n */\nconst audioPlayers: AudioPlayer[] = [];\n\n/**\n * Called roughly every 20 milliseconds. Dispatches audio from all players, and then gets the players to prepare\n * the next audio frame.\n */\nfunction audioCycleStep() {\n\tif (nextTime === -1) return;\n\n\tnextTime += FRAME_LENGTH;\n\tconst available = audioPlayers.filter((player) => player.checkPlayable());\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tavailable.forEach((player) => player['_stepDispatch']());\n\n\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\tprepareNextAudioFrame(available);\n}\n\n/**\n * Recursively gets the players that have been passed as parameters to prepare audio frames that can be played\n * at the start of the next cycle.\n */\nfunction prepareNextAudioFrame(players: AudioPlayer[]) {\n\tconst nextPlayer = players.shift();\n\n\tif (!nextPlayer) {\n\t\tif (nextTime !== -1) {\n\t\t\taudioCycleInterval = setTimeout(() => audioCycleStep(), nextTime - Date.now());\n\t\t}\n\t\treturn;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tnextPlayer['_stepPrepare']();\n\n\t// setImmediate to avoid long audio player chains blocking other scheduled tasks\n\tsetImmediate(() => prepareNextAudioFrame(players));\n}\n\n/**\n * Checks whether or not the given audio player is being driven by the data store clock.\n *\n * @param target - The target to test for\n *\n * @returns `true` if it is being tracked, `false` otherwise\n */\nexport function hasAudioPlayer(target: AudioPlayer) {\n\treturn audioPlayers.includes(target);\n}\n\n/**\n * Adds an audio player to the data store tracking list, if it isn't already there.\n *\n * @param player - The player to track\n */\nexport function addAudioPlayer(player: AudioPlayer) {\n\tif (hasAudioPlayer(player)) return player;\n\taudioPlayers.push(player);\n\tif (audioPlayers.length === 1) {\n\t\tnextTime = Date.now();\n\t\tsetImmediate(() => audioCycleStep());\n\t}\n\treturn player;\n}\n\n/**\n * Removes an audio player from the data store tracking list, if it is present there.\n */\nexport function deleteAudioPlayer(player: AudioPlayer) {\n\tconst index = audioPlayers.indexOf(player);\n\tif (index === -1) return;\n\taudioPlayers.splice(index, 1);\n\tif (audioPlayers.length === 0) {\n\t\tnextTime = -1;\n\t\tif (typeof audioCycleInterval !== 'undefined') clearTimeout(audioCycleInterval);\n\t}\n}\n"],"names":["GatewayOpcodes"],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { GatewayOpcodes } from 'discord-api-types/v10';
2
+ import type { VoiceConnection } from './VoiceConnection';
3
+ import type { AudioPlayer } from './audio';
4
+ export interface JoinConfig {
5
+ guildId: string;
6
+ channelId: string | null;
7
+ selfDeaf: boolean;
8
+ selfMute: boolean;
9
+ group: string;
10
+ }
11
+ /**
12
+ * Sends a voice state update to the main websocket shard of a guild, to indicate joining/leaving/moving across
13
+ * voice channels.
14
+ *
15
+ * @param config - The configuration to use when joining the voice channel
16
+ */
17
+ export declare function createJoinVoiceChannelPayload(config: JoinConfig): {
18
+ op: GatewayOpcodes;
19
+ d: {
20
+ guild_id: string;
21
+ channel_id: string | null;
22
+ self_deaf: boolean;
23
+ self_mute: boolean;
24
+ };
25
+ };
26
+ /**
27
+ * Retrieves the map of group names to maps of voice connections. By default, all voice connections
28
+ * are created under the 'default' group.
29
+ *
30
+ * @returns The group map
31
+ */
32
+ export declare function getGroups(): Map<string, Map<string, VoiceConnection>>;
33
+ /**
34
+ * Retrieves all the voice connections under the 'default' group.
35
+ *
36
+ * @param group - The group to look up
37
+ *
38
+ * @returns The map of voice connections
39
+ */
40
+ export declare function getVoiceConnections(group?: 'default'): Map<string, VoiceConnection>;
41
+ /**
42
+ * Retrieves all the voice connections under the given group name.
43
+ *
44
+ * @param group - The group to look up
45
+ *
46
+ * @returns The map of voice connections
47
+ */
48
+ export declare function getVoiceConnections(group: string): Map<string, VoiceConnection> | undefined;
49
+ /**
50
+ * Finds a voice connection with the given guild id and group. Defaults to the 'default' group.
51
+ *
52
+ * @param guildId - The guild id of the voice connection
53
+ * @param group - the group that the voice connection was registered with
54
+ *
55
+ * @returns The voice connection, if it exists
56
+ */
57
+ export declare function getVoiceConnection(guildId: string, group?: string): VoiceConnection | undefined;
58
+ export declare function untrackVoiceConnection(voiceConnection: VoiceConnection): boolean | undefined;
59
+ export declare function trackVoiceConnection(voiceConnection: VoiceConnection): Map<string, VoiceConnection>;
60
+ /**
61
+ * Checks whether or not the given audio player is being driven by the data store clock.
62
+ *
63
+ * @param target - The target to test for
64
+ *
65
+ * @returns `true` if it is being tracked, `false` otherwise
66
+ */
67
+ export declare function hasAudioPlayer(target: AudioPlayer): boolean;
68
+ /**
69
+ * Adds an audio player to the data store tracking list, if it isn't already there.
70
+ *
71
+ * @param player - The player to track
72
+ */
73
+ export declare function addAudioPlayer(player: AudioPlayer): AudioPlayer;
74
+ /**
75
+ * Removes an audio player from the data store tracking list, if it is present there.
76
+ */
77
+ export declare function deleteAudioPlayer(player: AudioPlayer): void;
78
+ //# sourceMappingURL=DataStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataStore.d.ts","sourceRoot":"","sources":["../src/DataStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU;;;;;;;;EAU/D;AAcD;;;;;GAKG;AACH,wBAAgB,SAAS,8CAExB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAErF;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,CAAC;AAa7F;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAY,+BAEpE;AAED,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,eAAe,uBAEtE;AAED,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,eAAe,gCAEpE;AAqDD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,WAEjD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,eAQjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,QAQpD"}
@@ -0,0 +1,88 @@
1
+ import { GatewayOpcodes } from 'discord-api-types/v10';
2
+
3
+ function createJoinVoiceChannelPayload(config) {
4
+ return {
5
+ op: GatewayOpcodes.VoiceStateUpdate,
6
+ d: {
7
+ guild_id: config.guildId,
8
+ channel_id: config.channelId,
9
+ self_deaf: config.selfDeaf,
10
+ self_mute: config.selfMute
11
+ }
12
+ };
13
+ }
14
+ const groups = /* @__PURE__ */ new Map();
15
+ groups.set("default", /* @__PURE__ */ new Map());
16
+ function getOrCreateGroup(group) {
17
+ const existing = groups.get(group);
18
+ if (existing)
19
+ return existing;
20
+ const map = /* @__PURE__ */ new Map();
21
+ groups.set(group, map);
22
+ return map;
23
+ }
24
+ function getGroups() {
25
+ return groups;
26
+ }
27
+ function getVoiceConnections(group = "default") {
28
+ return groups.get(group);
29
+ }
30
+ function getVoiceConnection(guildId, group = "default") {
31
+ return getVoiceConnections(group)?.get(guildId);
32
+ }
33
+ function untrackVoiceConnection(voiceConnection) {
34
+ return getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId);
35
+ }
36
+ function trackVoiceConnection(voiceConnection) {
37
+ return getOrCreateGroup(voiceConnection.joinConfig.group).set(voiceConnection.joinConfig.guildId, voiceConnection);
38
+ }
39
+ const FRAME_LENGTH = 20;
40
+ let audioCycleInterval;
41
+ let nextTime = -1;
42
+ const audioPlayers = [];
43
+ function audioCycleStep() {
44
+ if (nextTime === -1)
45
+ return;
46
+ nextTime += FRAME_LENGTH;
47
+ const available = audioPlayers.filter((player) => player.checkPlayable());
48
+ available.forEach((player) => player["_stepDispatch"]());
49
+ prepareNextAudioFrame(available);
50
+ }
51
+ function prepareNextAudioFrame(players) {
52
+ const nextPlayer = players.shift();
53
+ if (!nextPlayer) {
54
+ if (nextTime !== -1) {
55
+ audioCycleInterval = setTimeout(() => audioCycleStep(), nextTime - Date.now());
56
+ }
57
+ return;
58
+ }
59
+ nextPlayer["_stepPrepare"]();
60
+ setImmediate(() => prepareNextAudioFrame(players));
61
+ }
62
+ function hasAudioPlayer(target) {
63
+ return audioPlayers.includes(target);
64
+ }
65
+ function addAudioPlayer(player) {
66
+ if (hasAudioPlayer(player))
67
+ return player;
68
+ audioPlayers.push(player);
69
+ if (audioPlayers.length === 1) {
70
+ nextTime = Date.now();
71
+ setImmediate(() => audioCycleStep());
72
+ }
73
+ return player;
74
+ }
75
+ function deleteAudioPlayer(player) {
76
+ const index = audioPlayers.indexOf(player);
77
+ if (index === -1)
78
+ return;
79
+ audioPlayers.splice(index, 1);
80
+ if (audioPlayers.length === 0) {
81
+ nextTime = -1;
82
+ if (typeof audioCycleInterval !== "undefined")
83
+ clearTimeout(audioCycleInterval);
84
+ }
85
+ }
86
+
87
+ export { addAudioPlayer, createJoinVoiceChannelPayload, deleteAudioPlayer, getGroups, getVoiceConnection, getVoiceConnections, hasAudioPlayer, trackVoiceConnection, untrackVoiceConnection };
88
+ //# sourceMappingURL=DataStore.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataStore.mjs","sources":["../src/DataStore.ts"],"sourcesContent":["import { GatewayOpcodes } from 'discord-api-types/v10';\nimport type { VoiceConnection } from './VoiceConnection';\nimport type { AudioPlayer } from './audio';\n\nexport interface JoinConfig {\n\tguildId: string;\n\tchannelId: string | null;\n\tselfDeaf: boolean;\n\tselfMute: boolean;\n\tgroup: string;\n}\n\n/**\n * Sends a voice state update to the main websocket shard of a guild, to indicate joining/leaving/moving across\n * voice channels.\n *\n * @param config - The configuration to use when joining the voice channel\n */\nexport function createJoinVoiceChannelPayload(config: JoinConfig) {\n\treturn {\n\t\top: GatewayOpcodes.VoiceStateUpdate,\n\t\td: {\n\t\t\tguild_id: config.guildId,\n\t\t\tchannel_id: config.channelId,\n\t\t\tself_deaf: config.selfDeaf,\n\t\t\tself_mute: config.selfMute,\n\t\t},\n\t};\n}\n\n// Voice Connections\nconst groups = new Map<string, Map<string, VoiceConnection>>();\ngroups.set('default', new Map());\n\nfunction getOrCreateGroup(group: string) {\n\tconst existing = groups.get(group);\n\tif (existing) return existing;\n\tconst map = new Map<string, VoiceConnection>();\n\tgroups.set(group, map);\n\treturn map;\n}\n\n/**\n * Retrieves the map of group names to maps of voice connections. By default, all voice connections\n * are created under the 'default' group.\n *\n * @returns The group map\n */\nexport function getGroups() {\n\treturn groups;\n}\n\n/**\n * Retrieves all the voice connections under the 'default' group.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group?: 'default'): Map<string, VoiceConnection>;\n\n/**\n * Retrieves all the voice connections under the given group name.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group: string): Map<string, VoiceConnection> | undefined;\n\n/**\n * Retrieves all the voice connections under the given group name. Defaults to the 'default' group.\n *\n * @param group - The group to look up\n *\n * @returns The map of voice connections\n */\nexport function getVoiceConnections(group = 'default') {\n\treturn groups.get(group);\n}\n\n/**\n * Finds a voice connection with the given guild id and group. Defaults to the 'default' group.\n *\n * @param guildId - The guild id of the voice connection\n * @param group - the group that the voice connection was registered with\n *\n * @returns The voice connection, if it exists\n */\nexport function getVoiceConnection(guildId: string, group = 'default') {\n\treturn getVoiceConnections(group)?.get(guildId);\n}\n\nexport function untrackVoiceConnection(voiceConnection: VoiceConnection) {\n\treturn getVoiceConnections(voiceConnection.joinConfig.group)?.delete(voiceConnection.joinConfig.guildId);\n}\n\nexport function trackVoiceConnection(voiceConnection: VoiceConnection) {\n\treturn getOrCreateGroup(voiceConnection.joinConfig.group).set(voiceConnection.joinConfig.guildId, voiceConnection);\n}\n\n// Audio Players\n\n// Each audio packet is 20ms long\nconst FRAME_LENGTH = 20;\n\nlet audioCycleInterval: NodeJS.Timeout | undefined;\nlet nextTime = -1;\n\n/**\n * A list of created audio players that are still active and haven't been destroyed.\n */\nconst audioPlayers: AudioPlayer[] = [];\n\n/**\n * Called roughly every 20 milliseconds. Dispatches audio from all players, and then gets the players to prepare\n * the next audio frame.\n */\nfunction audioCycleStep() {\n\tif (nextTime === -1) return;\n\n\tnextTime += FRAME_LENGTH;\n\tconst available = audioPlayers.filter((player) => player.checkPlayable());\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tavailable.forEach((player) => player['_stepDispatch']());\n\n\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\tprepareNextAudioFrame(available);\n}\n\n/**\n * Recursively gets the players that have been passed as parameters to prepare audio frames that can be played\n * at the start of the next cycle.\n */\nfunction prepareNextAudioFrame(players: AudioPlayer[]) {\n\tconst nextPlayer = players.shift();\n\n\tif (!nextPlayer) {\n\t\tif (nextTime !== -1) {\n\t\t\taudioCycleInterval = setTimeout(() => audioCycleStep(), nextTime - Date.now());\n\t\t}\n\t\treturn;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tnextPlayer['_stepPrepare']();\n\n\t// setImmediate to avoid long audio player chains blocking other scheduled tasks\n\tsetImmediate(() => prepareNextAudioFrame(players));\n}\n\n/**\n * Checks whether or not the given audio player is being driven by the data store clock.\n *\n * @param target - The target to test for\n *\n * @returns `true` if it is being tracked, `false` otherwise\n */\nexport function hasAudioPlayer(target: AudioPlayer) {\n\treturn audioPlayers.includes(target);\n}\n\n/**\n * Adds an audio player to the data store tracking list, if it isn't already there.\n *\n * @param player - The player to track\n */\nexport function addAudioPlayer(player: AudioPlayer) {\n\tif (hasAudioPlayer(player)) return player;\n\taudioPlayers.push(player);\n\tif (audioPlayers.length === 1) {\n\t\tnextTime = Date.now();\n\t\tsetImmediate(() => audioCycleStep());\n\t}\n\treturn player;\n}\n\n/**\n * Removes an audio player from the data store tracking list, if it is present there.\n */\nexport function deleteAudioPlayer(player: AudioPlayer) {\n\tconst index = audioPlayers.indexOf(player);\n\tif (index === -1) return;\n\taudioPlayers.splice(index, 1);\n\tif (audioPlayers.length === 0) {\n\t\tnextTime = -1;\n\t\tif (typeof audioCycleInterval !== 'undefined') clearTimeout(audioCycleInterval);\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,350 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const EventEmitter = require('node:events');
6
+ const DataStore = require('./DataStore.cjs');
7
+ const Networking = require('./networking/Networking.cjs');
8
+ const VoiceReceiver = require('./receive/VoiceReceiver.cjs');
9
+ require('node:stream');
10
+ require('./audio/AudioPlayer.cjs');
11
+ require('./receive/SpeakingMap.cjs');
12
+ const util = require('./util/util.cjs');
13
+
14
+ var VoiceConnectionStatus = /* @__PURE__ */ ((VoiceConnectionStatus2) => {
15
+ VoiceConnectionStatus2["Signalling"] = "signalling";
16
+ VoiceConnectionStatus2["Connecting"] = "connecting";
17
+ VoiceConnectionStatus2["Ready"] = "ready";
18
+ VoiceConnectionStatus2["Disconnected"] = "disconnected";
19
+ VoiceConnectionStatus2["Destroyed"] = "destroyed";
20
+ return VoiceConnectionStatus2;
21
+ })(VoiceConnectionStatus || {});
22
+ var VoiceConnectionDisconnectReason = /* @__PURE__ */ ((VoiceConnectionDisconnectReason2) => {
23
+ VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["WebSocketClose"] = 0] = "WebSocketClose";
24
+ VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["AdapterUnavailable"] = 1] = "AdapterUnavailable";
25
+ VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["EndpointRemoved"] = 2] = "EndpointRemoved";
26
+ VoiceConnectionDisconnectReason2[VoiceConnectionDisconnectReason2["Manual"] = 3] = "Manual";
27
+ return VoiceConnectionDisconnectReason2;
28
+ })(VoiceConnectionDisconnectReason || {});
29
+ class VoiceConnection extends EventEmitter.EventEmitter {
30
+ constructor(joinConfig, { debug, adapterCreator }) {
31
+ super();
32
+ this.debug = debug ? (message) => this.emit("debug", message) : null;
33
+ this.rejoinAttempts = 0;
34
+ this.receiver = new VoiceReceiver.VoiceReceiver(this);
35
+ this.onNetworkingClose = this.onNetworkingClose.bind(this);
36
+ this.onNetworkingStateChange = this.onNetworkingStateChange.bind(this);
37
+ this.onNetworkingError = this.onNetworkingError.bind(this);
38
+ this.onNetworkingDebug = this.onNetworkingDebug.bind(this);
39
+ const adapter = adapterCreator({
40
+ onVoiceServerUpdate: (data) => this.addServerPacket(data),
41
+ onVoiceStateUpdate: (data) => this.addStatePacket(data),
42
+ destroy: () => this.destroy(false)
43
+ });
44
+ this._state = { status: "signalling" /* Signalling */, adapter };
45
+ this.packets = {
46
+ server: void 0,
47
+ state: void 0
48
+ };
49
+ this.joinConfig = joinConfig;
50
+ }
51
+ get state() {
52
+ return this._state;
53
+ }
54
+ set state(newState) {
55
+ const oldState = this._state;
56
+ const oldNetworking = Reflect.get(oldState, "networking");
57
+ const newNetworking = Reflect.get(newState, "networking");
58
+ const oldSubscription = Reflect.get(oldState, "subscription");
59
+ const newSubscription = Reflect.get(newState, "subscription");
60
+ if (oldNetworking !== newNetworking) {
61
+ if (oldNetworking) {
62
+ oldNetworking.on("error", util.noop);
63
+ oldNetworking.off("debug", this.onNetworkingDebug);
64
+ oldNetworking.off("error", this.onNetworkingError);
65
+ oldNetworking.off("close", this.onNetworkingClose);
66
+ oldNetworking.off("stateChange", this.onNetworkingStateChange);
67
+ oldNetworking.destroy();
68
+ }
69
+ if (newNetworking)
70
+ this.updateReceiveBindings(newNetworking.state, oldNetworking?.state);
71
+ }
72
+ if (newState.status === "ready" /* Ready */) {
73
+ this.rejoinAttempts = 0;
74
+ } else if (newState.status === "destroyed" /* Destroyed */) {
75
+ for (const stream of this.receiver.subscriptions.values()) {
76
+ if (!stream.destroyed)
77
+ stream.destroy();
78
+ }
79
+ }
80
+ if (oldState.status !== "destroyed" /* Destroyed */ && newState.status === "destroyed" /* Destroyed */) {
81
+ oldState.adapter.destroy();
82
+ }
83
+ this._state = newState;
84
+ if (oldSubscription && oldSubscription !== newSubscription) {
85
+ oldSubscription.unsubscribe();
86
+ }
87
+ this.emit("stateChange", oldState, newState);
88
+ if (oldState.status !== newState.status) {
89
+ this.emit(newState.status, oldState, newState);
90
+ }
91
+ }
92
+ addServerPacket(packet) {
93
+ this.packets.server = packet;
94
+ if (packet.endpoint) {
95
+ this.configureNetworking();
96
+ } else if (this.state.status !== "destroyed" /* Destroyed */) {
97
+ this.state = {
98
+ ...this.state,
99
+ status: "disconnected" /* Disconnected */,
100
+ reason: 2 /* EndpointRemoved */
101
+ };
102
+ }
103
+ }
104
+ addStatePacket(packet) {
105
+ this.packets.state = packet;
106
+ if (typeof packet.self_deaf !== "undefined")
107
+ this.joinConfig.selfDeaf = packet.self_deaf;
108
+ if (typeof packet.self_mute !== "undefined")
109
+ this.joinConfig.selfMute = packet.self_mute;
110
+ if (packet.channel_id)
111
+ this.joinConfig.channelId = packet.channel_id;
112
+ }
113
+ updateReceiveBindings(newState, oldState) {
114
+ const oldWs = Reflect.get(oldState ?? {}, "ws");
115
+ const newWs = Reflect.get(newState, "ws");
116
+ const oldUdp = Reflect.get(oldState ?? {}, "udp");
117
+ const newUdp = Reflect.get(newState, "udp");
118
+ if (oldWs !== newWs) {
119
+ oldWs?.off("packet", this.receiver.onWsPacket);
120
+ newWs?.on("packet", this.receiver.onWsPacket);
121
+ }
122
+ if (oldUdp !== newUdp) {
123
+ oldUdp?.off("message", this.receiver.onUdpMessage);
124
+ newUdp?.on("message", this.receiver.onUdpMessage);
125
+ }
126
+ this.receiver.connectionData = Reflect.get(newState, "connectionData") ?? {};
127
+ }
128
+ configureNetworking() {
129
+ const { server, state } = this.packets;
130
+ if (!server || !state || this.state.status === "destroyed" /* Destroyed */ || !server.endpoint)
131
+ return;
132
+ const networking = new Networking.Networking({
133
+ endpoint: server.endpoint,
134
+ serverId: server.guild_id,
135
+ token: server.token,
136
+ sessionId: state.session_id,
137
+ userId: state.user_id
138
+ }, Boolean(this.debug));
139
+ networking.once("close", this.onNetworkingClose);
140
+ networking.on("stateChange", this.onNetworkingStateChange);
141
+ networking.on("error", this.onNetworkingError);
142
+ networking.on("debug", this.onNetworkingDebug);
143
+ this.state = {
144
+ ...this.state,
145
+ status: "connecting" /* Connecting */,
146
+ networking
147
+ };
148
+ }
149
+ onNetworkingClose(code) {
150
+ if (this.state.status === "destroyed" /* Destroyed */)
151
+ return;
152
+ if (code === 4014) {
153
+ this.state = {
154
+ ...this.state,
155
+ status: "disconnected" /* Disconnected */,
156
+ reason: 0 /* WebSocketClose */,
157
+ closeCode: code
158
+ };
159
+ } else {
160
+ this.state = {
161
+ ...this.state,
162
+ status: "signalling" /* Signalling */
163
+ };
164
+ this.rejoinAttempts++;
165
+ if (!this.state.adapter.sendPayload(DataStore.createJoinVoiceChannelPayload(this.joinConfig))) {
166
+ this.state = {
167
+ ...this.state,
168
+ status: "disconnected" /* Disconnected */,
169
+ reason: 1 /* AdapterUnavailable */
170
+ };
171
+ }
172
+ }
173
+ }
174
+ onNetworkingStateChange(oldState, newState) {
175
+ this.updateReceiveBindings(newState, oldState);
176
+ if (oldState.code === newState.code)
177
+ return;
178
+ if (this.state.status !== "connecting" /* Connecting */ && this.state.status !== "ready" /* Ready */)
179
+ return;
180
+ if (newState.code === Networking.NetworkingStatusCode.Ready) {
181
+ this.state = {
182
+ ...this.state,
183
+ status: "ready" /* Ready */
184
+ };
185
+ } else if (newState.code !== Networking.NetworkingStatusCode.Closed) {
186
+ this.state = {
187
+ ...this.state,
188
+ status: "connecting" /* Connecting */
189
+ };
190
+ }
191
+ }
192
+ onNetworkingError(error) {
193
+ this.emit("error", error);
194
+ }
195
+ onNetworkingDebug(message) {
196
+ this.debug?.(`[NW] ${message}`);
197
+ }
198
+ prepareAudioPacket(buffer) {
199
+ const state = this.state;
200
+ if (state.status !== "ready" /* Ready */)
201
+ return;
202
+ return state.networking.prepareAudioPacket(buffer);
203
+ }
204
+ dispatchAudio() {
205
+ const state = this.state;
206
+ if (state.status !== "ready" /* Ready */)
207
+ return;
208
+ return state.networking.dispatchAudio();
209
+ }
210
+ playOpusPacket(buffer) {
211
+ const state = this.state;
212
+ if (state.status !== "ready" /* Ready */)
213
+ return;
214
+ state.networking.prepareAudioPacket(buffer);
215
+ return state.networking.dispatchAudio();
216
+ }
217
+ destroy(adapterAvailable = true) {
218
+ if (this.state.status === "destroyed" /* Destroyed */) {
219
+ throw new Error("Cannot destroy VoiceConnection - it has already been destroyed");
220
+ }
221
+ if (DataStore.getVoiceConnection(this.joinConfig.guildId, this.joinConfig.group) === this) {
222
+ DataStore.untrackVoiceConnection(this);
223
+ }
224
+ if (adapterAvailable) {
225
+ this.state.adapter.sendPayload(DataStore.createJoinVoiceChannelPayload({ ...this.joinConfig, channelId: null }));
226
+ }
227
+ this.state = {
228
+ status: "destroyed" /* Destroyed */
229
+ };
230
+ }
231
+ disconnect() {
232
+ if (this.state.status === "destroyed" /* Destroyed */ || this.state.status === "signalling" /* Signalling */) {
233
+ return false;
234
+ }
235
+ this.joinConfig.channelId = null;
236
+ if (!this.state.adapter.sendPayload(DataStore.createJoinVoiceChannelPayload(this.joinConfig))) {
237
+ this.state = {
238
+ adapter: this.state.adapter,
239
+ subscription: this.state.subscription,
240
+ status: "disconnected" /* Disconnected */,
241
+ reason: 1 /* AdapterUnavailable */
242
+ };
243
+ return false;
244
+ }
245
+ this.state = {
246
+ adapter: this.state.adapter,
247
+ reason: 3 /* Manual */,
248
+ status: "disconnected" /* Disconnected */
249
+ };
250
+ return true;
251
+ }
252
+ rejoin(joinConfig) {
253
+ if (this.state.status === "destroyed" /* Destroyed */) {
254
+ return false;
255
+ }
256
+ const notReady = this.state.status !== "ready" /* Ready */;
257
+ if (notReady)
258
+ this.rejoinAttempts++;
259
+ Object.assign(this.joinConfig, joinConfig);
260
+ if (this.state.adapter.sendPayload(DataStore.createJoinVoiceChannelPayload(this.joinConfig))) {
261
+ if (notReady) {
262
+ this.state = {
263
+ ...this.state,
264
+ status: "signalling" /* Signalling */
265
+ };
266
+ }
267
+ return true;
268
+ }
269
+ this.state = {
270
+ adapter: this.state.adapter,
271
+ subscription: this.state.subscription,
272
+ status: "disconnected" /* Disconnected */,
273
+ reason: 1 /* AdapterUnavailable */
274
+ };
275
+ return false;
276
+ }
277
+ setSpeaking(enabled) {
278
+ if (this.state.status !== "ready" /* Ready */)
279
+ return false;
280
+ return this.state.networking.setSpeaking(enabled);
281
+ }
282
+ subscribe(player) {
283
+ if (this.state.status === "destroyed" /* Destroyed */)
284
+ return;
285
+ const subscription = player["subscribe"](this);
286
+ this.state = {
287
+ ...this.state,
288
+ subscription
289
+ };
290
+ return subscription;
291
+ }
292
+ get ping() {
293
+ if (this.state.status === "ready" /* Ready */ && this.state.networking.state.code === Networking.NetworkingStatusCode.Ready) {
294
+ return {
295
+ ws: this.state.networking.state.ws.ping,
296
+ udp: this.state.networking.state.udp.ping
297
+ };
298
+ }
299
+ return {
300
+ ws: void 0,
301
+ udp: void 0
302
+ };
303
+ }
304
+ onSubscriptionRemoved(subscription) {
305
+ if (this.state.status !== "destroyed" /* Destroyed */ && this.state.subscription === subscription) {
306
+ this.state = {
307
+ ...this.state,
308
+ subscription: void 0
309
+ };
310
+ }
311
+ }
312
+ }
313
+ function createVoiceConnection(joinConfig, options) {
314
+ const payload = DataStore.createJoinVoiceChannelPayload(joinConfig);
315
+ const existing = DataStore.getVoiceConnection(joinConfig.guildId, joinConfig.group);
316
+ if (existing && existing.state.status !== "destroyed" /* Destroyed */) {
317
+ if (existing.state.status === "disconnected" /* Disconnected */) {
318
+ existing.rejoin({
319
+ channelId: joinConfig.channelId,
320
+ selfDeaf: joinConfig.selfDeaf,
321
+ selfMute: joinConfig.selfMute
322
+ });
323
+ } else if (!existing.state.adapter.sendPayload(payload)) {
324
+ existing.state = {
325
+ ...existing.state,
326
+ status: "disconnected" /* Disconnected */,
327
+ reason: 1 /* AdapterUnavailable */
328
+ };
329
+ }
330
+ return existing;
331
+ }
332
+ const voiceConnection = new VoiceConnection(joinConfig, options);
333
+ DataStore.trackVoiceConnection(voiceConnection);
334
+ if (voiceConnection.state.status !== "destroyed" /* Destroyed */) {
335
+ if (!voiceConnection.state.adapter.sendPayload(payload)) {
336
+ voiceConnection.state = {
337
+ ...voiceConnection.state,
338
+ status: "disconnected" /* Disconnected */,
339
+ reason: 1 /* AdapterUnavailable */
340
+ };
341
+ }
342
+ }
343
+ return voiceConnection;
344
+ }
345
+
346
+ exports.VoiceConnection = VoiceConnection;
347
+ exports.VoiceConnectionDisconnectReason = VoiceConnectionDisconnectReason;
348
+ exports.VoiceConnectionStatus = VoiceConnectionStatus;
349
+ exports.createVoiceConnection = createVoiceConnection;
350
+ //# sourceMappingURL=VoiceConnection.cjs.map