safeness-sb-new 0.0.1

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 (343) hide show
  1. package/README.md +115 -0
  2. package/package.json +96 -0
  3. package/src/WebSocket.js +39 -0
  4. package/src/client/BaseClient.js +86 -0
  5. package/src/client/Client.js +836 -0
  6. package/src/client/WebhookClient.js +61 -0
  7. package/src/client/actions/Action.js +120 -0
  8. package/src/client/actions/ActionsManager.js +78 -0
  9. package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
  10. package/src/client/actions/AutoModerationActionExecution.js +27 -0
  11. package/src/client/actions/AutoModerationRuleCreate.js +28 -0
  12. package/src/client/actions/AutoModerationRuleDelete.js +32 -0
  13. package/src/client/actions/AutoModerationRuleUpdate.js +30 -0
  14. package/src/client/actions/ChannelCreate.js +23 -0
  15. package/src/client/actions/ChannelDelete.js +39 -0
  16. package/src/client/actions/ChannelUpdate.js +43 -0
  17. package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
  18. package/src/client/actions/GuildBanAdd.js +20 -0
  19. package/src/client/actions/GuildBanRemove.js +25 -0
  20. package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
  21. package/src/client/actions/GuildDelete.js +65 -0
  22. package/src/client/actions/GuildEmojiCreate.js +20 -0
  23. package/src/client/actions/GuildEmojiDelete.js +21 -0
  24. package/src/client/actions/GuildEmojiUpdate.js +20 -0
  25. package/src/client/actions/GuildEmojisUpdate.js +34 -0
  26. package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
  27. package/src/client/actions/GuildMemberRemove.js +33 -0
  28. package/src/client/actions/GuildMemberUpdate.js +44 -0
  29. package/src/client/actions/GuildRoleCreate.js +25 -0
  30. package/src/client/actions/GuildRoleDelete.js +31 -0
  31. package/src/client/actions/GuildRoleUpdate.js +39 -0
  32. package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
  33. package/src/client/actions/GuildScheduledEventCreate.js +27 -0
  34. package/src/client/actions/GuildScheduledEventDelete.js +31 -0
  35. package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
  36. package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
  37. package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
  38. package/src/client/actions/GuildStickerCreate.js +20 -0
  39. package/src/client/actions/GuildStickerDelete.js +21 -0
  40. package/src/client/actions/GuildStickerUpdate.js +20 -0
  41. package/src/client/actions/GuildStickersUpdate.js +34 -0
  42. package/src/client/actions/GuildUpdate.js +33 -0
  43. package/src/client/actions/InviteCreate.js +28 -0
  44. package/src/client/actions/InviteDelete.js +30 -0
  45. package/src/client/actions/MessageCreate.js +46 -0
  46. package/src/client/actions/MessageDelete.js +32 -0
  47. package/src/client/actions/MessageDeleteBulk.js +46 -0
  48. package/src/client/actions/MessageReactionAdd.js +56 -0
  49. package/src/client/actions/MessageReactionRemove.js +45 -0
  50. package/src/client/actions/MessageReactionRemoveAll.js +33 -0
  51. package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
  52. package/src/client/actions/MessageUpdate.js +26 -0
  53. package/src/client/actions/PresenceUpdate.js +46 -0
  54. package/src/client/actions/StageInstanceCreate.js +28 -0
  55. package/src/client/actions/StageInstanceDelete.js +33 -0
  56. package/src/client/actions/StageInstanceUpdate.js +30 -0
  57. package/src/client/actions/ThreadCreate.js +24 -0
  58. package/src/client/actions/ThreadDelete.js +32 -0
  59. package/src/client/actions/ThreadListSync.js +59 -0
  60. package/src/client/actions/ThreadMemberUpdate.js +30 -0
  61. package/src/client/actions/ThreadMembersUpdate.js +34 -0
  62. package/src/client/actions/TypingStart.js +29 -0
  63. package/src/client/actions/UserUpdate.js +35 -0
  64. package/src/client/actions/VoiceStateUpdate.js +57 -0
  65. package/src/client/actions/WebhooksUpdate.js +20 -0
  66. package/src/client/voice/ClientVoiceManager.js +150 -0
  67. package/src/client/voice/VoiceConnection.js +849 -0
  68. package/src/client/voice/dispatcher/AnnexBDispatcher.js +120 -0
  69. package/src/client/voice/dispatcher/AudioDispatcher.js +115 -0
  70. package/src/client/voice/dispatcher/BaseDispatcher.js +405 -0
  71. package/src/client/voice/dispatcher/VPxDispatcher.js +52 -0
  72. package/src/client/voice/dispatcher/VideoDispatcher.js +31 -0
  73. package/src/client/voice/networking/VoiceUDPClient.js +188 -0
  74. package/src/client/voice/networking/VoiceWebSocket.js +280 -0
  75. package/src/client/voice/player/MediaPlayer.js +294 -0
  76. package/src/client/voice/player/processing/AnnexBNalSplitter.js +244 -0
  77. package/src/client/voice/player/processing/IvfSplitter.js +106 -0
  78. package/src/client/voice/receiver/PacketHandler.js +170 -0
  79. package/src/client/voice/receiver/Receiver.js +82 -0
  80. package/src/client/voice/receiver/video/IvfJoinner.js +106 -0
  81. package/src/client/voice/util/Function.js +14 -0
  82. package/src/client/voice/util/PlayInterface.js +122 -0
  83. package/src/client/voice/util/Secretbox.js +42 -0
  84. package/src/client/voice/util/Silence.js +16 -0
  85. package/src/client/voice/util/Socket.js +62 -0
  86. package/src/client/voice/util/VolumeInterface.js +104 -0
  87. package/src/client/websocket/WebSocketManager.js +392 -0
  88. package/src/client/websocket/WebSocketShard.js +906 -0
  89. package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
  90. package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
  91. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
  92. package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
  93. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
  94. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
  95. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
  96. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
  97. package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
  98. package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
  99. package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
  100. package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
  101. package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
  102. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
  103. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +19 -0
  104. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
  105. package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
  106. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
  107. package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
  108. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
  109. package/src/client/websocket/handlers/GUILD_CREATE.js +52 -0
  110. package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
  111. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
  112. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
  113. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
  114. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
  115. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
  116. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
  117. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
  118. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
  119. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
  120. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
  121. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
  122. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
  123. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
  124. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
  125. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
  126. package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
  127. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +12 -0
  128. package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
  129. package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
  130. package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
  131. package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
  132. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
  133. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  134. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  135. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
  136. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
  137. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
  138. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
  139. package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
  140. package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
  141. package/src/client/websocket/handlers/READY.js +120 -0
  142. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +19 -0
  143. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +17 -0
  144. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +41 -0
  145. package/src/client/websocket/handlers/RESUMED.js +14 -0
  146. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
  147. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
  148. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
  149. package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
  150. package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
  151. package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
  152. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
  153. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
  154. package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
  155. package/src/client/websocket/handlers/TYPING_START.js +5 -0
  156. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +6 -0
  157. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
  158. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  159. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -0
  160. package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
  161. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  162. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
  163. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
  164. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
  165. package/src/client/websocket/handlers/index.js +83 -0
  166. package/src/errors/DJSError.js +61 -0
  167. package/src/errors/Messages.js +208 -0
  168. package/src/errors/index.js +4 -0
  169. package/src/index.js +159 -0
  170. package/src/managers/ApplicationCommandManager.js +264 -0
  171. package/src/managers/ApplicationCommandPermissionsManager.js +417 -0
  172. package/src/managers/AutoModerationRuleManager.js +296 -0
  173. package/src/managers/BaseGuildEmojiManager.js +80 -0
  174. package/src/managers/BaseManager.js +19 -0
  175. package/src/managers/BillingManager.js +66 -0
  176. package/src/managers/CachedManager.js +71 -0
  177. package/src/managers/ChannelManager.js +138 -0
  178. package/src/managers/ClientUserSettingManager.js +372 -0
  179. package/src/managers/DataManager.js +61 -0
  180. package/src/managers/GuildBanManager.js +204 -0
  181. package/src/managers/GuildChannelManager.js +488 -0
  182. package/src/managers/GuildEmojiManager.js +171 -0
  183. package/src/managers/GuildEmojiRoleManager.js +118 -0
  184. package/src/managers/GuildForumThreadManager.js +108 -0
  185. package/src/managers/GuildInviteManager.js +213 -0
  186. package/src/managers/GuildManager.js +304 -0
  187. package/src/managers/GuildMemberManager.js +597 -0
  188. package/src/managers/GuildMemberRoleManager.js +191 -0
  189. package/src/managers/GuildScheduledEventManager.js +296 -0
  190. package/src/managers/GuildSettingManager.js +155 -0
  191. package/src/managers/GuildStickerManager.js +179 -0
  192. package/src/managers/GuildTextThreadManager.js +98 -0
  193. package/src/managers/InteractionManager.js +39 -0
  194. package/src/managers/MessageManager.js +391 -0
  195. package/src/managers/PermissionOverwriteManager.js +166 -0
  196. package/src/managers/PresenceManager.js +58 -0
  197. package/src/managers/ReactionManager.js +67 -0
  198. package/src/managers/ReactionUserManager.js +71 -0
  199. package/src/managers/RelationshipManager.js +265 -0
  200. package/src/managers/RoleManager.js +352 -0
  201. package/src/managers/StageInstanceManager.js +162 -0
  202. package/src/managers/ThreadManager.js +174 -0
  203. package/src/managers/ThreadMemberManager.js +186 -0
  204. package/src/managers/UserManager.js +146 -0
  205. package/src/managers/UserNoteManager.js +53 -0
  206. package/src/managers/VoiceStateManager.js +37 -0
  207. package/src/rest/APIRequest.js +159 -0
  208. package/src/rest/APIRouter.js +53 -0
  209. package/src/rest/DiscordAPIError.js +104 -0
  210. package/src/rest/HTTPError.js +62 -0
  211. package/src/rest/RESTManager.js +62 -0
  212. package/src/rest/RateLimitError.js +55 -0
  213. package/src/rest/RequestHandler.js +444 -0
  214. package/src/sharding/Shard.js +443 -0
  215. package/src/sharding/ShardClientUtil.js +275 -0
  216. package/src/sharding/ShardingManager.js +318 -0
  217. package/src/structures/AnonymousGuild.js +98 -0
  218. package/src/structures/ApplicationCommand.js +593 -0
  219. package/src/structures/ApplicationRoleConnectionMetadata.js +48 -0
  220. package/src/structures/AutoModerationActionExecution.js +89 -0
  221. package/src/structures/AutoModerationRule.js +294 -0
  222. package/src/structures/AutocompleteInteraction.js +107 -0
  223. package/src/structures/Base.js +43 -0
  224. package/src/structures/BaseCommandInteraction.js +211 -0
  225. package/src/structures/BaseGuild.js +116 -0
  226. package/src/structures/BaseGuildEmoji.js +56 -0
  227. package/src/structures/BaseGuildTextChannel.js +191 -0
  228. package/src/structures/BaseGuildVoiceChannel.js +241 -0
  229. package/src/structures/BaseMessageComponent.js +114 -0
  230. package/src/structures/ButtonInteraction.js +11 -0
  231. package/src/structures/CallState.js +63 -0
  232. package/src/structures/CategoryChannel.js +85 -0
  233. package/src/structures/Channel.js +270 -0
  234. package/src/structures/ClientPresence.js +77 -0
  235. package/src/structures/ClientUser.js +450 -0
  236. package/src/structures/CommandInteraction.js +41 -0
  237. package/src/structures/CommandInteractionOptionResolver.js +276 -0
  238. package/src/structures/ContextMenuInteraction.js +65 -0
  239. package/src/structures/DMChannel.js +217 -0
  240. package/src/structures/DirectoryChannel.js +20 -0
  241. package/src/structures/Emoji.js +148 -0
  242. package/src/structures/ForumChannel.js +261 -0
  243. package/src/structures/GroupDMChannel.js +387 -0
  244. package/src/structures/Guild.js +1608 -0
  245. package/src/structures/GuildAuditLogs.js +729 -0
  246. package/src/structures/GuildBan.js +59 -0
  247. package/src/structures/GuildBoost.js +108 -0
  248. package/src/structures/GuildChannel.js +468 -0
  249. package/src/structures/GuildEmoji.js +161 -0
  250. package/src/structures/GuildMember.js +568 -0
  251. package/src/structures/GuildPreview.js +191 -0
  252. package/src/structures/GuildPreviewEmoji.js +27 -0
  253. package/src/structures/GuildScheduledEvent.js +441 -0
  254. package/src/structures/GuildTemplate.js +236 -0
  255. package/src/structures/Integration.js +188 -0
  256. package/src/structures/IntegrationApplication.js +96 -0
  257. package/src/structures/Interaction.js +290 -0
  258. package/src/structures/InteractionCollector.js +248 -0
  259. package/src/structures/InteractionWebhook.js +43 -0
  260. package/src/structures/Invite.js +358 -0
  261. package/src/structures/InviteGuild.js +23 -0
  262. package/src/structures/InviteStageInstance.js +86 -0
  263. package/src/structures/Message.js +1227 -0
  264. package/src/structures/MessageActionRow.js +103 -0
  265. package/src/structures/MessageAttachment.js +204 -0
  266. package/src/structures/MessageButton.js +165 -0
  267. package/src/structures/MessageCollector.js +146 -0
  268. package/src/structures/MessageComponentInteraction.js +120 -0
  269. package/src/structures/MessageContextMenuInteraction.js +20 -0
  270. package/src/structures/MessageEmbed.js +586 -0
  271. package/src/structures/MessageMentions.js +273 -0
  272. package/src/structures/MessagePayload.js +318 -0
  273. package/src/structures/MessagePoll.js +238 -0
  274. package/src/structures/MessageReaction.js +171 -0
  275. package/src/structures/MessageSelectMenu.js +140 -0
  276. package/src/structures/Modal.js +161 -0
  277. package/src/structures/ModalSubmitFieldsResolver.js +53 -0
  278. package/src/structures/ModalSubmitInteraction.js +119 -0
  279. package/src/structures/NewsChannel.js +32 -0
  280. package/src/structures/OAuth2Guild.js +28 -0
  281. package/src/structures/PermissionOverwrites.js +196 -0
  282. package/src/structures/Presence.js +1131 -0
  283. package/src/structures/ReactionCollector.js +229 -0
  284. package/src/structures/ReactionEmoji.js +31 -0
  285. package/src/structures/Role.js +531 -0
  286. package/src/structures/SelectMenuInteraction.js +21 -0
  287. package/src/structures/StageChannel.js +104 -0
  288. package/src/structures/StageInstance.js +208 -0
  289. package/src/structures/Sticker.js +310 -0
  290. package/src/structures/StickerPack.js +95 -0
  291. package/src/structures/StoreChannel.js +56 -0
  292. package/src/structures/Team.js +118 -0
  293. package/src/structures/TeamMember.js +71 -0
  294. package/src/structures/TextChannel.js +33 -0
  295. package/src/structures/TextInputComponent.js +131 -0
  296. package/src/structures/ThreadChannel.js +607 -0
  297. package/src/structures/ThreadMember.js +105 -0
  298. package/src/structures/Typing.js +74 -0
  299. package/src/structures/User.js +543 -0
  300. package/src/structures/UserContextMenuInteraction.js +29 -0
  301. package/src/structures/VoiceChannel.js +110 -0
  302. package/src/structures/VoiceRegion.js +53 -0
  303. package/src/structures/VoiceState.js +345 -0
  304. package/src/structures/WebEmbed.js +373 -0
  305. package/src/structures/Webhook.js +467 -0
  306. package/src/structures/WelcomeChannel.js +60 -0
  307. package/src/structures/WelcomeScreen.js +48 -0
  308. package/src/structures/Widget.js +87 -0
  309. package/src/structures/WidgetMember.js +99 -0
  310. package/src/structures/interfaces/Application.js +313 -0
  311. package/src/structures/interfaces/Collector.js +300 -0
  312. package/src/structures/interfaces/InteractionResponses.js +313 -0
  313. package/src/structures/interfaces/TextBasedChannel.js +719 -0
  314. package/src/util/ActivityFlags.js +44 -0
  315. package/src/util/ApplicationFlags.js +76 -0
  316. package/src/util/AttachmentFlags.js +38 -0
  317. package/src/util/BitField.js +170 -0
  318. package/src/util/ChannelFlags.js +45 -0
  319. package/src/util/Constants.js +1815 -0
  320. package/src/util/DataResolver.js +145 -0
  321. package/src/util/Formatters.js +228 -0
  322. package/src/util/GuildMemberFlags.js +43 -0
  323. package/src/util/Intents.js +74 -0
  324. package/src/util/InviteFlags.js +29 -0
  325. package/src/util/LimitedCollection.js +131 -0
  326. package/src/util/MessageFlags.js +54 -0
  327. package/src/util/Options.js +336 -0
  328. package/src/util/Permissions.js +202 -0
  329. package/src/util/PremiumUsageFlags.js +31 -0
  330. package/src/util/PurchasedFlags.js +33 -0
  331. package/src/util/RemoteAuth.js +382 -0
  332. package/src/util/RoleFlags.js +37 -0
  333. package/src/util/SnowflakeUtil.js +92 -0
  334. package/src/util/Speaking.js +33 -0
  335. package/src/util/Sweepers.js +466 -0
  336. package/src/util/SystemChannelFlags.js +55 -0
  337. package/src/util/ThreadMemberFlags.js +30 -0
  338. package/src/util/UserFlags.js +104 -0
  339. package/src/util/Util.js +889 -0
  340. package/typings/enums.d.ts +297 -0
  341. package/typings/index.d.ts +7670 -0
  342. package/typings/index.test-d.ts +0 -0
  343. package/typings/rawDataTypes.d.ts +342 -0
@@ -0,0 +1,849 @@
1
+ 'use strict';
2
+
3
+ const EventEmitter = require('events');
4
+ const { setTimeout } = require('node:timers');
5
+ const VoiceUDP = require('./networking/VoiceUDPClient');
6
+ const VoiceWebSocket = require('./networking/VoiceWebSocket');
7
+ const MediaPlayer = require('./player/MediaPlayer');
8
+ const VoiceReceiver = require('./receiver/Receiver');
9
+ const { parseStreamKey } = require('./util/Function');
10
+ const PlayInterface = require('./util/PlayInterface');
11
+ const Silence = require('./util/Silence');
12
+ const { Error } = require('../../errors');
13
+ const { Opcodes, VoiceOpcodes, VoiceStatus, Events } = require('../../util/Constants');
14
+ const Speaking = require('../../util/Speaking');
15
+ const Util = require('../../util/Util');
16
+
17
+ // Workaround for Discord now requiring silence to be sent before being able to receive audio
18
+ class SingleSilence extends Silence {
19
+ _read() {
20
+ super._read();
21
+ this.push(null);
22
+ }
23
+ }
24
+
25
+ const SUPPORTED_MODES = ['xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305'];
26
+ const SUPPORTED_CODECS = ['VP8', 'H264'];
27
+
28
+ /**
29
+ * Represents a connection to a guild's voice server.
30
+ * ```js
31
+ * // Obtained using:
32
+ * client.voice.joinChannel(channel)
33
+ * .then(connection => {
34
+ *
35
+ * });
36
+ * ```
37
+ * @extends {EventEmitter}
38
+ * @implements {PlayInterface}
39
+ */
40
+ class VoiceConnection extends EventEmitter {
41
+ constructor(voiceManager, channel) {
42
+ super();
43
+
44
+ /**
45
+ * The voice manager that instantiated this connection
46
+ * @type {ClientVoiceManager}
47
+ */
48
+ this.voiceManager = voiceManager;
49
+
50
+ /**
51
+ * The voice channel this connection is currently serving
52
+ * @type {VoiceChannel}
53
+ */
54
+ this.channel = channel;
55
+
56
+ /**
57
+ * The current status of the voice connection
58
+ * @type {VoiceStatus}
59
+ */
60
+ this.status = VoiceStatus.AUTHENTICATING;
61
+
62
+ /**
63
+ * Our current speaking state
64
+ * @type {Readonly<Speaking>}
65
+ */
66
+ this.speaking = new Speaking().freeze();
67
+
68
+ /**
69
+ * Our current video state
70
+ * @type {boolean}
71
+ */
72
+ this.videoStatus = false;
73
+
74
+ /**
75
+ * The authentication data needed to connect to the voice server
76
+ * @type {Object}
77
+ * @private
78
+ */
79
+ this.authentication = {};
80
+
81
+ /**
82
+ * The audio player for this voice connection
83
+ * @type {MediaPlayer}
84
+ */
85
+ this.player = new MediaPlayer(this);
86
+
87
+ this.player.on('debug', m => {
88
+ /**
89
+ * Debug info from the connection.
90
+ * @event VoiceConnection#debug
91
+ * @param {string} message The debug message
92
+ */
93
+ this.emit('debug', `audio player - ${m}`);
94
+ });
95
+
96
+ this.player.on('error', e => {
97
+ /**
98
+ * Warning info from the connection.
99
+ * @event VoiceConnection#warn
100
+ * @param {string|Error} warning The warning
101
+ */
102
+ this.emit('warn', e);
103
+ });
104
+
105
+ this.once('closing', () => this.player.destroy());
106
+
107
+ /**
108
+ * Map SSRC values to user IDs
109
+ * @type {Map<number, { userId: Snowflake, speaking: boolean, hasVideo: boolean }>}
110
+ * @private
111
+ */
112
+ this.ssrcMap = new Map();
113
+
114
+ /**
115
+ * Tracks which users are talking
116
+ * @type {Map<Snowflake, Readonly<Speaking>>}
117
+ * @private
118
+ */
119
+ this._speaking = new Map();
120
+
121
+ /**
122
+ * Object that wraps contains the `ws` and `udp` sockets of this voice connection
123
+ * @type {Object}
124
+ * @private
125
+ */
126
+ this.sockets = {};
127
+
128
+ /**
129
+ * The voice receiver of this connection
130
+ * @type {VoiceReceiver}
131
+ */
132
+ this.receiver = new VoiceReceiver(this);
133
+
134
+ /**
135
+ * Video codec (encoded)
136
+ * * `VP8`
137
+ * * `VP9` (Not supported)
138
+ * * `H264`
139
+ * * `H265` (Not supported)
140
+ * @typedef {string} VideoCodec
141
+ */
142
+
143
+ /**
144
+ * The voice receiver of this connection
145
+ * @type {VideoCodec}
146
+ */
147
+ this.videoCodec = 'H264';
148
+
149
+ /**
150
+ * Create a stream connection ?
151
+ * @type {?StreamConnection}
152
+ */
153
+ this.streamConnection = null;
154
+ }
155
+
156
+ /**
157
+ * The client that instantiated this connection
158
+ * @type {Client}
159
+ * @readonly
160
+ */
161
+ get client() {
162
+ return this.voiceManager.client;
163
+ }
164
+
165
+ /**
166
+ * The current audio dispatcher (if any)
167
+ * @type {?AudioDispatcher}
168
+ * @readonly
169
+ */
170
+ get dispatcher() {
171
+ return this.player.dispatcher;
172
+ }
173
+
174
+ /**
175
+ * The current video dispatcher (if any)
176
+ * @type {?VideoDispatcher}
177
+ * @readonly
178
+ */
179
+ get videoDispatcher() {
180
+ return this.player.videoDispatcher;
181
+ }
182
+
183
+ /**
184
+ * Sets whether the voice connection should display as "speaking", "soundshare" or "none".
185
+ * @param {BitFieldResolvable} value The new speaking state
186
+ */
187
+ setSpeaking(value) {
188
+ if (this.speaking.equals(value)) return;
189
+ if (this.status !== VoiceStatus.CONNECTED) return;
190
+ this.speaking = new Speaking(value).freeze();
191
+ this.sockets.ws
192
+ .sendPacket({
193
+ op: VoiceOpcodes.SPEAKING,
194
+ d: {
195
+ speaking: this.speaking.bitfield,
196
+ delay: 0,
197
+ ssrc: this.authentication.ssrc,
198
+ },
199
+ })
200
+ .catch(e => {
201
+ this.emit('debug', e);
202
+ });
203
+ }
204
+
205
+ /**
206
+ * Set video codec before select protocol
207
+ * @param {VideoCodec} value Codec
208
+ * @returns {VoiceConnection}
209
+ */
210
+ setVideoCodec(value) {
211
+ if (!SUPPORTED_CODECS.includes(value)) throw new Error('INVALID_VIDEO_CODEC', SUPPORTED_CODECS);
212
+ this.videoCodec = value;
213
+ return this;
214
+ }
215
+
216
+ /**
217
+ * Sets video status
218
+ * @param {boolean} value Video on or off
219
+ */
220
+ setVideoStatus(value) {
221
+ if (this.status !== VoiceStatus.CONNECTED) return;
222
+ if (value === this.videoStatus) return;
223
+ this.videoStatus = value;
224
+ this.sockets.ws
225
+ .sendPacket({
226
+ op: VoiceOpcodes.SOURCES,
227
+ d: {
228
+ audio_ssrc: this.authentication.ssrc,
229
+ video_ssrc: value ? this.authentication.ssrc + 1 : 0,
230
+ rtx_ssrc: value ? this.authentication.ssrc + 2 : 0,
231
+ streams: [
232
+ {
233
+ type: 'video',
234
+ rid: '100',
235
+ ssrc: value ? this.authentication.ssrc + 1 : 0,
236
+ active: true,
237
+ quality: 100,
238
+ rtx_ssrc: value ? this.authentication.ssrc + 2 : 0,
239
+ max_bitrate: 8000000,
240
+ max_framerate: 60,
241
+ max_resolution: {
242
+ type: 'source',
243
+ width: 0,
244
+ height: 0,
245
+ },
246
+ },
247
+ ],
248
+ },
249
+ })
250
+ .catch(e => {
251
+ this.emit('debug', e);
252
+ });
253
+ }
254
+
255
+ /**
256
+ * The voice state of this connection
257
+ * @type {?VoiceState}
258
+ */
259
+ get voice() {
260
+ return this.client.user.voice;
261
+ }
262
+
263
+ /**
264
+ * Sends a request to the main gateway to join a voice channel.
265
+ * @param {Object} [options] The options to provide
266
+ * @returns {Promise<Shard>}
267
+ * @private
268
+ */
269
+ sendVoiceStateUpdate(options = {}) {
270
+ options = Util.mergeDefault(
271
+ {
272
+ guild_id: this.channel.guild?.id || null,
273
+ channel_id: this.channel.id,
274
+ self_mute: this.voice ? this.voice.selfMute : false,
275
+ self_deaf: this.voice ? this.voice.selfDeaf : false,
276
+ self_video: this.voice ? this.voice.selfVideo : false,
277
+ flags: 2,
278
+ },
279
+ options,
280
+ );
281
+
282
+ this.emit('debug', `Sending voice state update: ${JSON.stringify(options)}`);
283
+
284
+ return this.channel.client.ws.broadcast({
285
+ op: Opcodes.VOICE_STATE_UPDATE,
286
+ d: options,
287
+ });
288
+ }
289
+
290
+ /**
291
+ * Set the token and endpoint required to connect to the voice servers.
292
+ * @param {string} token The voice token
293
+ * @param {string} endpoint The voice endpoint
294
+ * @returns {void}
295
+ * @private
296
+ */
297
+ setTokenAndEndpoint(token, endpoint) {
298
+ this.emit('debug', `Token "${token}" and endpoint "${endpoint}"`);
299
+ if (!endpoint) {
300
+ // Signifies awaiting endpoint stage
301
+ return;
302
+ }
303
+
304
+ if (!token) {
305
+ this.authenticateFailed('VOICE_TOKEN_ABSENT');
306
+ return;
307
+ }
308
+
309
+ endpoint = endpoint.match(/([^:]*)/)[0];
310
+ this.emit('debug', `Endpoint resolved as ${endpoint}`);
311
+
312
+ if (!endpoint) {
313
+ this.authenticateFailed('VOICE_INVALID_ENDPOINT');
314
+ return;
315
+ }
316
+
317
+ if (this.status === VoiceStatus.AUTHENTICATING) {
318
+ this.authentication.token = token;
319
+ this.authentication.endpoint = endpoint;
320
+ this.checkAuthenticated();
321
+ } else if (token !== this.authentication.token || endpoint !== this.authentication.endpoint) {
322
+ this.reconnect(token, endpoint);
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Sets the Session ID for the connection.
328
+ * @param {string} sessionId The voice session ID
329
+ * @private
330
+ */
331
+ setSessionId(sessionId) {
332
+ this.emit('debug', `Setting sessionId ${sessionId} (stored as "${this.authentication.sessionId}")`);
333
+ if (!sessionId) {
334
+ this.authenticateFailed('VOICE_SESSION_ABSENT');
335
+ return;
336
+ }
337
+
338
+ if (this.status === VoiceStatus.AUTHENTICATING) {
339
+ this.authentication.sessionId = sessionId;
340
+ this.checkAuthenticated();
341
+ } else if (sessionId !== this.authentication.sessionId) {
342
+ this.authentication.sessionId = sessionId;
343
+ /**
344
+ * Emitted when a new session ID is received.
345
+ * @event VoiceConnection#newSession
346
+ * @private
347
+ */
348
+ this.emit('newSession', sessionId);
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Checks whether the voice connection is authenticated.
354
+ * @private
355
+ */
356
+ checkAuthenticated() {
357
+ const { token, endpoint, sessionId } = this.authentication;
358
+ this.emit('debug', `Authenticated with sessionId ${sessionId}`);
359
+ if (token && endpoint && sessionId) {
360
+ this.status = VoiceStatus.CONNECTING;
361
+ /**
362
+ * Emitted when we successfully initiate a voice connection.
363
+ * @event VoiceConnection#authenticated
364
+ */
365
+ this.emit('authenticated');
366
+ this.connect();
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Invoked when we fail to initiate a voice connection.
372
+ * @param {string} reason The reason for failure
373
+ * @private
374
+ */
375
+ authenticateFailed(reason) {
376
+ clearTimeout(this.connectTimeout);
377
+ this.emit('debug', `Authenticate failed - ${reason}`);
378
+ if (this.status === VoiceStatus.AUTHENTICATING) {
379
+ /**
380
+ * Emitted when we fail to initiate a voice connection.
381
+ * @event VoiceConnection#failed
382
+ * @param {Error} error The encountered error
383
+ */
384
+ this.emit('failed', new Error(reason));
385
+ } else {
386
+ /**
387
+ * Emitted whenever the connection encounters an error.
388
+ * @event VoiceConnection#error
389
+ * @param {Error} error The encountered error
390
+ */
391
+ this.emit('error', new Error(reason));
392
+ }
393
+ this.status = VoiceStatus.DISCONNECTED;
394
+ }
395
+
396
+ /**
397
+ * Move to a different voice channel in the same guild.
398
+ * @param {VoiceChannel} channel The channel to move to
399
+ * @private
400
+ */
401
+ updateChannel(channel) {
402
+ this.channel = channel;
403
+ this.sendVoiceStateUpdate();
404
+ }
405
+
406
+ /**
407
+ * Attempts to authenticate to the voice server.
408
+ * @param {Object} options Join config
409
+ * @private
410
+ */
411
+ authenticate(options = {}) {
412
+ this.sendVoiceStateUpdate(options);
413
+ this.connectTimeout = setTimeout(() => this.authenticateFailed('VOICE_CONNECTION_TIMEOUT'), 15_000).unref();
414
+ }
415
+
416
+ /**
417
+ * Attempts to reconnect to the voice server (typically after a region change).
418
+ * @param {string} token The voice token
419
+ * @param {string} endpoint The voice endpoint
420
+ * @private
421
+ */
422
+ reconnect(token, endpoint) {
423
+ this.authentication.token = token;
424
+ this.authentication.endpoint = endpoint;
425
+ this.speaking = new Speaking().freeze();
426
+ this.status = VoiceStatus.RECONNECTING;
427
+ this.emit('debug', `Reconnecting to ${endpoint}`);
428
+ /**
429
+ * Emitted when the voice connection is reconnecting (typically after a region change).
430
+ * @event VoiceConnection#reconnecting
431
+ */
432
+ this.emit('reconnecting');
433
+ this.connect();
434
+ }
435
+
436
+ /**
437
+ * Disconnects the voice connection, causing a disconnect and closing event to be emitted.
438
+ */
439
+ disconnect() {
440
+ this.emit('closing');
441
+ this.emit('debug', 'disconnect() triggered');
442
+ clearTimeout(this.connectTimeout);
443
+ const conn = this.voiceManager.connection;
444
+ if (conn === this) this.voiceManager.connection = null;
445
+ this.sendVoiceStateUpdate({
446
+ channel_id: null,
447
+ });
448
+ this._disconnect();
449
+ }
450
+
451
+ /**
452
+ * Internally disconnects (doesn't send disconnect packet).
453
+ * @private
454
+ */
455
+ _disconnect() {
456
+ this.cleanup();
457
+ this.status = VoiceStatus.DISCONNECTED;
458
+ /**
459
+ * Emitted when the voice connection disconnects.
460
+ * @event VoiceConnection#disconnect
461
+ */
462
+ this.emit('disconnect');
463
+ }
464
+
465
+ /**
466
+ * Cleans up after disconnect.
467
+ * @private
468
+ */
469
+ cleanup() {
470
+ this.player.destroy();
471
+ this.speaking = new Speaking().freeze();
472
+ const { ws, udp } = this.sockets;
473
+
474
+ this.emit('debug', 'Connection clean up');
475
+
476
+ if (ws) {
477
+ ws.removeAllListeners('error');
478
+ ws.removeAllListeners('ready');
479
+ ws.removeAllListeners('sessionDescription');
480
+ ws.removeAllListeners('speaking');
481
+ ws.shutdown();
482
+ }
483
+
484
+ if (udp) udp.removeAllListeners('error');
485
+
486
+ this.sockets.ws = null;
487
+ this.sockets.udp = null;
488
+ }
489
+
490
+ /**
491
+ * Connect the voice connection.
492
+ * @private
493
+ */
494
+ connect() {
495
+ this.emit('debug', `Connect triggered`);
496
+ if (this.status !== VoiceStatus.RECONNECTING) {
497
+ if (this.sockets.ws) throw new Error('WS_CONNECTION_EXISTS');
498
+ if (this.sockets.udp) throw new Error('UDP_CONNECTION_EXISTS');
499
+ }
500
+
501
+ if (this.sockets.ws) this.sockets.ws.shutdown();
502
+ if (this.sockets.udp) this.sockets.udp.shutdown();
503
+
504
+ this.sockets.ws = new VoiceWebSocket(this);
505
+ this.sockets.udp = new VoiceUDP(this);
506
+
507
+ const { ws, udp } = this.sockets;
508
+
509
+ ws.on('debug', msg => this.emit('debug', msg));
510
+ udp.on('debug', msg => this.emit('debug', msg));
511
+ ws.on('error', err => this.emit('error', err));
512
+ udp.on('error', err => this.emit('error', err));
513
+ ws.on('ready', this.onReady.bind(this));
514
+ ws.on('sessionDescription', this.onSessionDescription.bind(this));
515
+ ws.on('startSpeaking', this.onStartSpeaking.bind(this));
516
+ ws.on('startStreaming', this.onStartStreaming.bind(this));
517
+
518
+ this.sockets.ws.connect();
519
+ }
520
+
521
+ /**
522
+ * Invoked when the voice websocket is ready.
523
+ * @param {Object} data The received data
524
+ * @private
525
+ */
526
+ onReady(data) {
527
+ Object.assign(this.authentication, data);
528
+ for (let mode of data.modes) {
529
+ if (SUPPORTED_MODES.includes(mode)) {
530
+ this.authentication.mode = mode;
531
+ this.emit('debug', `Selecting the ${mode} mode`);
532
+ break;
533
+ }
534
+ }
535
+ this.sockets.udp.createUDPSocket(data.ip);
536
+ }
537
+
538
+ /**
539
+ * Invoked when a session description is received.
540
+ * @param {Object} data The received data
541
+ * @private
542
+ */
543
+ onSessionDescription(data) {
544
+ Object.assign(this.authentication, data);
545
+ this.status = VoiceStatus.CONNECTED;
546
+ const ready = () => {
547
+ clearTimeout(this.connectTimeout);
548
+ this.emit('debug', `Ready with authentication details: ${JSON.stringify(this.authentication)}`);
549
+ /**
550
+ * Emitted once the connection is ready, when a promise to join a voice channel resolves,
551
+ * the connection will already be ready.
552
+ * @event VoiceConnection#ready
553
+ */
554
+ this.emit('ready');
555
+ };
556
+ if (this.dispatcher || this.videoDispatcher) {
557
+ ready();
558
+ } else {
559
+ // This serves to provide support for voice receive, sending audio is required to receive it.
560
+ const dispatcher = this.playAudio(new SingleSilence(), { type: 'opus', volume: false });
561
+ dispatcher.once('finish', ready);
562
+ }
563
+ }
564
+
565
+ onStartSpeaking({ user_id, ssrc, speaking }) {
566
+ this.ssrcMap.set(+ssrc, {
567
+ ...(this.ssrcMap.get(+ssrc) || {}),
568
+ userId: user_id,
569
+ speaking: speaking,
570
+ });
571
+ }
572
+
573
+ onStartStreaming({ video_ssrc, user_id, audio_ssrc }) {
574
+ this.ssrcMap.set(+audio_ssrc, {
575
+ ...(this.ssrcMap.get(+audio_ssrc) || {}),
576
+ userId: user_id,
577
+ hasVideo: Boolean(video_ssrc), // Maybe ?
578
+ });
579
+ /**
580
+ {
581
+ video_ssrc: 0,
582
+ user_id: 'uid',
583
+ streams: [
584
+ {
585
+ ssrc: 27734,
586
+ rtx_ssrc: 27735,
587
+ rid: '100',
588
+ quality: 100,
589
+ max_resolution: { width: 0, type: 'source', height: 0 },,
590
+ max_framerate: 60,
591
+ active: false
592
+ }
593
+ ],
594
+ audio_ssrc: 27733
595
+ }
596
+ */
597
+ }
598
+
599
+ /**
600
+ * Invoked when a speaking event is received.
601
+ * @param {Object} data The received data
602
+ * @private
603
+ */
604
+ onSpeaking({ user_id, speaking }) {
605
+ speaking = new Speaking(speaking).freeze();
606
+ const guild = this.channel.guild;
607
+ const user = this.client.users.cache.get(user_id);
608
+ const old = this._speaking.get(user_id) || new Speaking(0).freeze();
609
+ this._speaking.set(user_id, speaking);
610
+ /**
611
+ * Emitted whenever a user changes speaking state.
612
+ * @event VoiceConnection#speaking
613
+ * @param {User} user The user that has changed speaking state
614
+ * @param {Readonly<Speaking>} speaking The speaking state of the user
615
+ */
616
+ if (this.status === VoiceStatus.CONNECTED) {
617
+ this.emit('speaking', user, speaking);
618
+ if (!speaking.has(Speaking.FLAGS.SPEAKING)) {
619
+ this.receiver.packets._stoppedSpeaking(user_id);
620
+ }
621
+ }
622
+
623
+ if (guild && user && !speaking.equals(old)) {
624
+ const member = guild.members.cache.get(user);
625
+ if (member) {
626
+ /**
627
+ * Emitted once a guild member changes speaking state.
628
+ * @event Client#guildMemberSpeaking
629
+ * @param {GuildMember} member The member that started/stopped speaking
630
+ * @param {Readonly<Speaking>} speaking The speaking state of the member
631
+ */
632
+ this.client.emit(Events.GUILD_MEMBER_SPEAKING, member, speaking);
633
+ }
634
+ }
635
+ }
636
+
637
+ playAudio() {} // eslint-disable-line no-empty-function
638
+ playVideo() {} // eslint-disable-line no-empty-function
639
+
640
+ /**
641
+ * Create new connection to screenshare stream
642
+ * @returns {Promise<StreamConnection>}
643
+ */
644
+ createStreamConnection() {
645
+ // eslint-disable-next-line consistent-return
646
+ return new Promise((resolve, reject) => {
647
+ if (this.streamConnection) {
648
+ return resolve(this.streamConnection);
649
+ } else {
650
+ const connection = (this.streamConnection = new StreamConnection(this.voiceManager, this.channel, this));
651
+ connection.setVideoCodec(this.videoCodec); // Sync :?
652
+ // Setup event...
653
+ if (!this.eventHook) {
654
+ this.eventHook = true; // Dont listen this event two times :/
655
+ this.channel.client.on('raw', packet => {
656
+ if (
657
+ typeof packet !== 'object' ||
658
+ !packet.t ||
659
+ !packet.d ||
660
+ !this.streamConnection ||
661
+ !packet.d?.stream_key
662
+ ) {
663
+ return;
664
+ }
665
+ const { t: event, d: data } = packet;
666
+ const StreamKey = parseStreamKey(data.stream_key);
667
+ if (StreamKey.userId === this.channel.client.user.id && this.channel.id == StreamKey.channelId) {
668
+ switch (event) {
669
+ case 'STREAM_CREATE': {
670
+ this.streamConnection.setSessionId(this.authentication.sessionId);
671
+ this.streamConnection.serverId = data.rtc_server_id;
672
+ break;
673
+ }
674
+ case 'STREAM_SERVER_UPDATE': {
675
+ this.streamConnection.setTokenAndEndpoint(data.token, data.endpoint);
676
+ break;
677
+ }
678
+ case 'STREAM_DELETE': {
679
+ this.streamConnection.disconnect();
680
+ break;
681
+ }
682
+ }
683
+ }
684
+ });
685
+ }
686
+
687
+ connection.sendSignalScreenshare();
688
+ connection.sendScreenshareState(true);
689
+
690
+ connection.on('debug', msg =>
691
+ this.channel.client.emit(
692
+ 'debug',
693
+ `[VOICE STREAM (${this.channel.guild?.id || this.channel.id}:${connection.status})]: ${msg}`,
694
+ ),
695
+ );
696
+ connection.once('failed', reason => {
697
+ this.streamConnection = null;
698
+ reject(reason);
699
+ });
700
+
701
+ connection.on('error', reject);
702
+
703
+ connection.once('authenticated', () => {
704
+ connection.once('ready', () => {
705
+ resolve(connection);
706
+ connection.removeListener('error', reject);
707
+ });
708
+ connection.once('disconnect', () => {
709
+ this.streamConnection = null;
710
+ });
711
+ });
712
+ }
713
+ });
714
+ }
715
+ }
716
+
717
+ /**
718
+ * Represents a connection to a guild's voice server.
719
+ * ```js
720
+ * // Obtained using:
721
+ * client.voice.joinChannel(channel)
722
+ * .then(connection => connection.createStreamConnection())
723
+ * .then(connection => {
724
+ *
725
+ * });
726
+ * ```
727
+ * @extends {VoiceConnection}
728
+ */
729
+ class StreamConnection extends VoiceConnection {
730
+ #requestDisconnect = false;
731
+ /**
732
+ * @param {ClientVoiceManager} voiceManager Voice manager
733
+ * @param {Channel} channel any channel (joinable)
734
+ * @param {VoiceConnection} voiceConnection parent
735
+ */
736
+ constructor(voiceManager, channel, voiceConnection) {
737
+ super(voiceManager, channel);
738
+
739
+ /**
740
+ * Current voice connection
741
+ * @type {VoiceConnection}
742
+ */
743
+ this.voiceConnection = voiceConnection;
744
+
745
+ Object.defineProperty(this, 'voiceConnection', {
746
+ value: voiceConnection,
747
+ writable: false,
748
+ });
749
+
750
+ /**
751
+ * Server Id
752
+ * @type {string | null}
753
+ */
754
+ this.serverId = null;
755
+
756
+ /**
757
+ * Stream state
758
+ * @type {boolean}
759
+ */
760
+ this.isPaused = false;
761
+ }
762
+
763
+ createStreamConnection() {
764
+ return Promise.resolve(this);
765
+ }
766
+
767
+ get streamConnection() {
768
+ return this;
769
+ }
770
+
771
+ set streamConnection(value) {
772
+ // Why ?
773
+ }
774
+
775
+ disconnect() {
776
+ if (this.#requestDisconnect) return;
777
+ this.emit('closing');
778
+ this.emit('debug', 'Stream: disconnect() triggered');
779
+ clearTimeout(this.connectTimeout);
780
+ if (this.voiceConnection.streamConnection === this) this.voiceConnection.streamConnection = null;
781
+ this.sendStopScreenshare();
782
+ this._disconnect();
783
+ }
784
+
785
+ /**
786
+ * Create new stream connection (WS packet)
787
+ * @returns {void}
788
+ */
789
+ sendSignalScreenshare() {
790
+ const data = {
791
+ type: ['DM', 'GROUP_DM'].includes(this.channel.type) ? 'call' : 'guild',
792
+ guild_id: this.channel.guild?.id || null,
793
+ channel_id: this.channel.id,
794
+ preferred_region: null,
795
+ };
796
+ this.emit('debug', `Signal Stream: ${JSON.stringify(data)}`);
797
+ return this.channel.client.ws.broadcast({
798
+ op: Opcodes.STREAM_CREATE,
799
+ d: data,
800
+ });
801
+ }
802
+
803
+ /**
804
+ * Send screenshare state... (WS)
805
+ * @param {boolean} isPaused screenshare paused ?
806
+ * @returns {void}
807
+ */
808
+ sendScreenshareState(isPaused = false) {
809
+ if (isPaused == this.isPaused) return;
810
+ this.isPaused = isPaused;
811
+ this.channel.client.ws.broadcast({
812
+ op: Opcodes.STREAM_SET_PAUSED,
813
+ d: {
814
+ stream_key: this.streamKey,
815
+ paused: isPaused,
816
+ },
817
+ });
818
+ }
819
+
820
+ /**
821
+ * Stop screenshare, delete this connection (WS)
822
+ * @returns {void}
823
+ * @private Using StreamConnection#disconnect()
824
+ */
825
+ sendStopScreenshare() {
826
+ this.#requestDisconnect = true;
827
+ this.channel.client.ws.broadcast({
828
+ op: Opcodes.STREAM_DELETE,
829
+ d: {
830
+ stream_key: this.streamKey,
831
+ },
832
+ });
833
+ }
834
+
835
+ /**
836
+ * Current stream key
837
+ * @type {string}
838
+ */
839
+ get streamKey() {
840
+ return `${['DM', 'GROUP_DM'].includes(this.channel.type) ? 'call' : `guild:${this.channel.guild.id}`}:${
841
+ this.channel.id
842
+ }:${this.channel.client.user.id}`;
843
+ }
844
+ }
845
+
846
+ PlayInterface.applyToClass(VoiceConnection);
847
+ PlayInterface.applyToClass(StreamConnection);
848
+
849
+ module.exports = VoiceConnection;