discord.js-selfv13 13.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of discord.js-selfv13 might be problematic. Click here for more details.

Files changed (188) hide show
  1. package/.dccache +1 -0
  2. package/LICENSE +190 -0
  3. package/README.md +87 -0
  4. package/browser.js +9 -0
  5. package/deploy/deploy-key.enc +0 -0
  6. package/deploy/deploy.sh +90 -0
  7. package/deploy/test.sh +34 -0
  8. package/docs/README.md +1 -0
  9. package/docs/examples/attachments.md +163 -0
  10. package/docs/examples/avatars.js +29 -0
  11. package/docs/examples/embed.js +38 -0
  12. package/docs/examples/greeting.js +30 -0
  13. package/docs/examples/moderation.md +145 -0
  14. package/docs/examples/ping.js +29 -0
  15. package/docs/examples/webhook.js +12 -0
  16. package/docs/general/faq.md +23 -0
  17. package/docs/general/updating.md +181 -0
  18. package/docs/general/welcome.md +95 -0
  19. package/docs/index.yml +30 -0
  20. package/docs/logo.svg +19 -0
  21. package/docs/topics/voice.md +113 -0
  22. package/docs/topics/web.md +38 -0
  23. package/package.json +147 -0
  24. package/src/client/Client.js +564 -0
  25. package/src/client/ClientDataManager.js +150 -0
  26. package/src/client/ClientDataResolver.js +376 -0
  27. package/src/client/ClientManager.js +74 -0
  28. package/src/client/WebhookClient.js +118 -0
  29. package/src/client/actions/Action.js +23 -0
  30. package/src/client/actions/ActionsManager.js +40 -0
  31. package/src/client/actions/ChannelCreate.js +11 -0
  32. package/src/client/actions/ChannelDelete.js +30 -0
  33. package/src/client/actions/ChannelUpdate.js +74 -0
  34. package/src/client/actions/GuildBanRemove.js +13 -0
  35. package/src/client/actions/GuildChannelsPositionUpdate.js +19 -0
  36. package/src/client/actions/GuildDelete.js +57 -0
  37. package/src/client/actions/GuildEmojiCreate.js +17 -0
  38. package/src/client/actions/GuildEmojiDelete.js +18 -0
  39. package/src/client/actions/GuildEmojiUpdate.js +17 -0
  40. package/src/client/actions/GuildEmojisUpdate.js +38 -0
  41. package/src/client/actions/GuildMemberGet.js +10 -0
  42. package/src/client/actions/GuildMemberRemove.js +41 -0
  43. package/src/client/actions/GuildRoleCreate.js +26 -0
  44. package/src/client/actions/GuildRoleDelete.js +42 -0
  45. package/src/client/actions/GuildRoleUpdate.js +41 -0
  46. package/src/client/actions/GuildRolesPositionUpdate.js +19 -0
  47. package/src/client/actions/GuildSync.js +29 -0
  48. package/src/client/actions/GuildUpdate.js +34 -0
  49. package/src/client/actions/MessageCreate.js +53 -0
  50. package/src/client/actions/MessageDelete.js +35 -0
  51. package/src/client/actions/MessageDeleteBulk.js +26 -0
  52. package/src/client/actions/MessageReactionAdd.js +37 -0
  53. package/src/client/actions/MessageReactionRemove.js +37 -0
  54. package/src/client/actions/MessageReactionRemoveAll.js +25 -0
  55. package/src/client/actions/MessageUpdate.js +40 -0
  56. package/src/client/actions/Ready.js +1 -0
  57. package/src/client/actions/Ready.js.bak +65 -0
  58. package/src/client/actions/UserGet.js +11 -0
  59. package/src/client/actions/UserNoteUpdate.js +30 -0
  60. package/src/client/actions/UserUpdate.js +33 -0
  61. package/src/client/rest/APIRequest.js +56 -0
  62. package/src/client/rest/DiscordAPIError.js +60 -0
  63. package/src/client/rest/RESTManager.js +58 -0
  64. package/src/client/rest/RESTMethods.js +1006 -0
  65. package/src/client/rest/RequestHandlers/Burst.js +90 -0
  66. package/src/client/rest/RequestHandlers/RequestHandler.js +54 -0
  67. package/src/client/rest/RequestHandlers/Sequential.js +132 -0
  68. package/src/client/rest/UserAgentManager.js +25 -0
  69. package/src/client/voice/ClientVoiceManager.js +81 -0
  70. package/src/client/voice/VoiceBroadcast.js +366 -0
  71. package/src/client/voice/VoiceConnection.js +530 -0
  72. package/src/client/voice/VoiceUDPClient.js +127 -0
  73. package/src/client/voice/VoiceWebSocket.js +246 -0
  74. package/src/client/voice/dispatcher/StreamDispatcher.js +331 -0
  75. package/src/client/voice/opus/BaseOpusEngine.js +60 -0
  76. package/src/client/voice/opus/NodeOpusEngine.js +40 -0
  77. package/src/client/voice/opus/OpusEngineList.js +28 -0
  78. package/src/client/voice/opus/OpusScriptEngine.js +45 -0
  79. package/src/client/voice/player/AudioPlayer.js +170 -0
  80. package/src/client/voice/receiver/VoiceReadable.js +17 -0
  81. package/src/client/voice/receiver/VoiceReceiver.js +219 -0
  82. package/src/client/voice/util/SecretKey.js +16 -0
  83. package/src/client/voice/util/Secretbox.js +33 -0
  84. package/src/client/voice/util/VolumeInterface.js +86 -0
  85. package/src/client/websocket/WebSocketConnection.js +506 -0
  86. package/src/client/websocket/WebSocketManager.js +90 -0
  87. package/src/client/websocket/packets/WebSocketPacketManager.js +110 -0
  88. package/src/client/websocket/packets/handlers/AbstractHandler.js +11 -0
  89. package/src/client/websocket/packets/handlers/ChannelCreate.js +17 -0
  90. package/src/client/websocket/packets/handlers/ChannelDelete.js +20 -0
  91. package/src/client/websocket/packets/handlers/ChannelPinsUpdate.js +37 -0
  92. package/src/client/websocket/packets/handlers/ChannelUpdate.js +11 -0
  93. package/src/client/websocket/packets/handlers/GuildBanAdd.js +23 -0
  94. package/src/client/websocket/packets/handlers/GuildBanRemove.js +20 -0
  95. package/src/client/websocket/packets/handlers/GuildCreate.js +22 -0
  96. package/src/client/websocket/packets/handlers/GuildDelete.js +19 -0
  97. package/src/client/websocket/packets/handlers/GuildEmojisUpdate.js +11 -0
  98. package/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js +19 -0
  99. package/src/client/websocket/packets/handlers/GuildMemberAdd.js +17 -0
  100. package/src/client/websocket/packets/handlers/GuildMemberRemove.js +13 -0
  101. package/src/client/websocket/packets/handlers/GuildMemberUpdate.js +18 -0
  102. package/src/client/websocket/packets/handlers/GuildMembersChunk.js +33 -0
  103. package/src/client/websocket/packets/handlers/GuildRoleCreate.js +11 -0
  104. package/src/client/websocket/packets/handlers/GuildRoleDelete.js +11 -0
  105. package/src/client/websocket/packets/handlers/GuildRoleUpdate.js +11 -0
  106. package/src/client/websocket/packets/handlers/GuildSync.js +11 -0
  107. package/src/client/websocket/packets/handlers/GuildUpdate.js +11 -0
  108. package/src/client/websocket/packets/handlers/MessageCreate.js +19 -0
  109. package/src/client/websocket/packets/handlers/MessageDelete.js +19 -0
  110. package/src/client/websocket/packets/handlers/MessageDeleteBulk.js +17 -0
  111. package/src/client/websocket/packets/handlers/MessageReactionAdd.js +11 -0
  112. package/src/client/websocket/packets/handlers/MessageReactionRemove.js +11 -0
  113. package/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js +11 -0
  114. package/src/client/websocket/packets/handlers/MessageUpdate.js +11 -0
  115. package/src/client/websocket/packets/handlers/PresenceUpdate.js +76 -0
  116. package/src/client/websocket/packets/handlers/Ready.js +83 -0
  117. package/src/client/websocket/packets/handlers/RelationshipAdd.js +19 -0
  118. package/src/client/websocket/packets/handlers/RelationshipRemove.js +19 -0
  119. package/src/client/websocket/packets/handlers/Resumed.js +28 -0
  120. package/src/client/websocket/packets/handlers/TypingStart.js +68 -0
  121. package/src/client/websocket/packets/handlers/UserGuildSettingsUpdate.js +21 -0
  122. package/src/client/websocket/packets/handlers/UserNoteUpdate.js +12 -0
  123. package/src/client/websocket/packets/handlers/UserSettingsUpdate.js +18 -0
  124. package/src/client/websocket/packets/handlers/UserUpdate.js +11 -0
  125. package/src/client/websocket/packets/handlers/VoiceServerUpdate.js +19 -0
  126. package/src/client/websocket/packets/handlers/VoiceStateUpdate.js +52 -0
  127. package/src/client/websocket/packets/handlers/WebhooksUpdate.js +19 -0
  128. package/src/index.js +66 -0
  129. package/src/sharding/Shard.js +282 -0
  130. package/src/sharding/ShardClientUtil.js +146 -0
  131. package/src/sharding/ShardingManager.js +220 -0
  132. package/src/structures/Attachment.js +75 -0
  133. package/src/structures/CategoryChannel.js +22 -0
  134. package/src/structures/Channel.js +78 -0
  135. package/src/structures/ClientUser.js +447 -0
  136. package/src/structures/ClientUserChannelOverride.js +30 -0
  137. package/src/structures/ClientUserGuildSettings.js +60 -0
  138. package/src/structures/ClientUserSettings.js +80 -0
  139. package/src/structures/DMChannel.js +76 -0
  140. package/src/structures/Emoji.js +256 -0
  141. package/src/structures/GroupDMChannel.js +246 -0
  142. package/src/structures/Guild.js +1461 -0
  143. package/src/structures/GuildAuditLogs.js +371 -0
  144. package/src/structures/GuildChannel.js +537 -0
  145. package/src/structures/GuildMember.js +613 -0
  146. package/src/structures/Invite.js +164 -0
  147. package/src/structures/Message.js +605 -0
  148. package/src/structures/MessageAttachment.js +68 -0
  149. package/src/structures/MessageCollector.js +100 -0
  150. package/src/structures/MessageEmbed.js +386 -0
  151. package/src/structures/MessageMentions.js +144 -0
  152. package/src/structures/MessageReaction.js +96 -0
  153. package/src/structures/NewsChannel.js +24 -0
  154. package/src/structures/OAuth2Application.js +148 -0
  155. package/src/structures/PartialGuild.js +51 -0
  156. package/src/structures/PartialGuildChannel.js +44 -0
  157. package/src/structures/PermissionOverwrites.js +69 -0
  158. package/src/structures/Presence.js +241 -0
  159. package/src/structures/ReactionCollector.js +85 -0
  160. package/src/structures/ReactionEmoji.js +49 -0
  161. package/src/structures/RichEmbed.js +295 -0
  162. package/src/structures/Role.js +376 -0
  163. package/src/structures/StoreChannel.js +25 -0
  164. package/src/structures/TextChannel.js +154 -0
  165. package/src/structures/User.js +329 -0
  166. package/src/structures/UserConnection.js +48 -0
  167. package/src/structures/UserProfile.js +62 -0
  168. package/src/structures/VoiceChannel.js +146 -0
  169. package/src/structures/VoiceRegion.js +50 -0
  170. package/src/structures/Webhook.js +304 -0
  171. package/src/structures/interfaces/Collector.js +179 -0
  172. package/src/structures/interfaces/TextBasedChannel.js +635 -0
  173. package/src/structures/shared/resolvePermissions.js +26 -0
  174. package/src/util/Collection.js +532 -0
  175. package/src/util/Constants.js +845 -0
  176. package/src/util/Permissions.js +306 -0
  177. package/src/util/Snowflake.js +82 -0
  178. package/src/util/Util.js +221 -0
  179. package/test/random.js +207 -0
  180. package/test/shard.js +31 -0
  181. package/test/sharder.js +7 -0
  182. package/test/voice.js +78 -0
  183. package/test/webpack.html +31 -0
  184. package/tsconfig.json +13 -0
  185. package/tslint.json +62 -0
  186. package/typings/discord.js-test.ts +69 -0
  187. package/typings/index.d.ts +2190 -0
  188. package/webpack.config.js +62 -0
@@ -0,0 +1,19 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+
3
+ class RelationshipRemoveHandler extends AbstractHandler {
4
+ handle(packet) {
5
+ const client = this.packetManager.client;
6
+ const data = packet.d;
7
+ if (data.type === 2) {
8
+ if (client.user.blocked.has(data.id)) {
9
+ client.user.blocked.delete(data.id);
10
+ }
11
+ } else if (data.type === 1) {
12
+ if (client.user.friends.has(data.id)) {
13
+ client.user.friends.delete(data.id);
14
+ }
15
+ }
16
+ }
17
+ }
18
+
19
+ module.exports = RelationshipRemoveHandler;
@@ -0,0 +1,28 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+ const Constants = require('../../../../util/Constants');
3
+
4
+ class ResumedHandler extends AbstractHandler {
5
+ handle(packet) {
6
+ const client = this.packetManager.client;
7
+ const ws = client.ws.connection;
8
+
9
+ ws._trace = packet.d._trace;
10
+
11
+ ws.status = Constants.Status.READY;
12
+ this.packetManager.handleQueue();
13
+
14
+ const replayed = ws.sequence - ws.closeSequence;
15
+
16
+ ws.debug(`RESUMED ${ws._trace.join(' -> ')} | replayed ${replayed} events.`);
17
+ client.emit(Constants.Events.RESUME, replayed);
18
+ ws.heartbeat();
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Emitted whenever a WebSocket resumes.
24
+ * @event Client#resume
25
+ * @param {number} replayed The number of events that were replayed
26
+ */
27
+
28
+ module.exports = ResumedHandler;
@@ -0,0 +1,68 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+ const Constants = require('../../../../util/Constants');
3
+
4
+ class TypingStartHandler extends AbstractHandler {
5
+ handle(packet) {
6
+ const client = this.packetManager.client;
7
+ const data = packet.d;
8
+ const channel = client.channels.get(data.channel_id);
9
+ const user = client.users.get(data.user_id);
10
+ const timestamp = new Date(data.timestamp * 1000);
11
+
12
+ if (channel && user) {
13
+ if (channel.type === 'voice') {
14
+ client.emit(Constants.Events.WARN, `Discord sent a typing packet to voice channel ${channel.id}`);
15
+ return;
16
+ }
17
+ if (channel._typing.has(user.id)) {
18
+ const typing = channel._typing.get(user.id);
19
+ typing.lastTimestamp = timestamp;
20
+ typing.resetTimeout(tooLate(channel, user));
21
+ } else {
22
+ channel._typing.set(user.id, new TypingData(client, timestamp, timestamp, tooLate(channel, user)));
23
+ client.emit(Constants.Events.TYPING_START, channel, user);
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ class TypingData {
30
+ constructor(client, since, lastTimestamp, _timeout) {
31
+ this.client = client;
32
+ this.since = since;
33
+ this.lastTimestamp = lastTimestamp;
34
+ this._timeout = _timeout;
35
+ }
36
+
37
+ resetTimeout(_timeout) {
38
+ this.client.clearTimeout(this._timeout);
39
+ this._timeout = _timeout;
40
+ }
41
+
42
+ get elapsedTime() {
43
+ return Date.now() - this.since;
44
+ }
45
+ }
46
+
47
+ function tooLate(channel, user) {
48
+ return channel.client.setTimeout(() => {
49
+ channel.client.emit(Constants.Events.TYPING_STOP, channel, user, channel._typing.get(user.id));
50
+ channel._typing.delete(user.id);
51
+ }, 6000);
52
+ }
53
+
54
+ /**
55
+ * Emitted whenever a user starts typing in a channel.
56
+ * @event Client#typingStart
57
+ * @param {Channel} channel The channel the user started typing in
58
+ * @param {User} user The user that started typing
59
+ */
60
+
61
+ /**
62
+ * Emitted whenever a user stops typing in a channel.
63
+ * @event Client#typingStop
64
+ * @param {Channel} channel The channel the user stopped typing in
65
+ * @param {User} user The user that stopped typing
66
+ */
67
+
68
+ module.exports = TypingStartHandler;
@@ -0,0 +1,21 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+ const Constants = require('../../../../util/Constants');
3
+ const ClientUserGuildSettings = require('../../../../structures/ClientUserGuildSettings');
4
+
5
+ class UserGuildSettingsUpdateHandler extends AbstractHandler {
6
+ handle(packet) {
7
+ const client = this.packetManager.client;
8
+ const settings = client.user.guildSettings.get(packet.d.guild_id);
9
+ if (settings) settings.patch(packet.d);
10
+ else client.user.guildSettings.set(packet.d.guild_id, new ClientUserGuildSettings(packet.d, client));
11
+ client.emit(Constants.Events.USER_GUILD_SETTINGS_UPDATE, client.user.guildSettings.get(packet.d.guild_id));
12
+ }
13
+ }
14
+
15
+ /**
16
+ * Emitted whenever the client user's settings update.
17
+ * @event Client#clientUserGuildSettingsUpdate
18
+ * @param {ClientUserGuildSettings} clientUserGuildSettings The new client user guild settings
19
+ */
20
+
21
+ module.exports = UserGuildSettingsUpdateHandler;
@@ -0,0 +1,12 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+
3
+ class UserNoteUpdateHandler extends AbstractHandler {
4
+ handle(packet) {
5
+ const client = this.packetManager.client;
6
+ const data = packet.d;
7
+
8
+ client.actions.UserNoteUpdate.handle(data);
9
+ }
10
+ }
11
+
12
+ module.exports = UserNoteUpdateHandler;
@@ -0,0 +1,18 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+ const Constants = require('../../../../util/Constants');
3
+
4
+ class UserSettingsUpdateHandler extends AbstractHandler {
5
+ handle(packet) {
6
+ const client = this.packetManager.client;
7
+ client.user.settings.patch(packet.d);
8
+ client.emit(Constants.Events.USER_SETTINGS_UPDATE, client.user.settings);
9
+ }
10
+ }
11
+
12
+ /**
13
+ * Emitted when the client user's settings update.
14
+ * @event Client#clientUserSettingsUpdate
15
+ * @param {ClientUserSettings} clientUserSettings The new client user settings
16
+ */
17
+
18
+ module.exports = UserSettingsUpdateHandler;
@@ -0,0 +1,11 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+
3
+ class UserUpdateHandler extends AbstractHandler {
4
+ handle(packet) {
5
+ const client = this.packetManager.client;
6
+ const data = packet.d;
7
+ client.actions.UserUpdate.handle(data);
8
+ }
9
+ }
10
+
11
+ module.exports = UserUpdateHandler;
@@ -0,0 +1,19 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+
3
+ /*
4
+ {
5
+ "token": "my_token",
6
+ "guild_id": "41771983423143937",
7
+ "endpoint": "smart.loyal.discord.gg"
8
+ }
9
+ */
10
+
11
+ class VoiceServerUpdate extends AbstractHandler {
12
+ handle(packet) {
13
+ const client = this.packetManager.client;
14
+ const data = packet.d;
15
+ client.emit('self.voiceServer', data);
16
+ }
17
+ }
18
+
19
+ module.exports = VoiceServerUpdate;
@@ -0,0 +1,52 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+
3
+ const Constants = require('../../../../util/Constants');
4
+ const Util = require('../../../../util/Util');
5
+
6
+ class VoiceStateUpdateHandler extends AbstractHandler {
7
+ handle(packet) {
8
+ const client = this.packetManager.client;
9
+ const data = packet.d;
10
+
11
+ const guild = client.guilds.get(data.guild_id);
12
+ if (guild) {
13
+ const member = guild.members.get(data.user_id);
14
+ if (member) {
15
+ const oldVoiceChannelMember = Util.cloneObject(member);
16
+ if (member.voiceChannel && member.voiceChannel.id !== data.channel_id) {
17
+ member.voiceChannel.members.delete(oldVoiceChannelMember.id);
18
+ }
19
+
20
+ // If the member left the voice channel, unset their speaking property
21
+ if (!data.channel_id) member.speaking = null;
22
+
23
+ if (member.user.id === client.user.id && data.channel_id) {
24
+ client.emit('self.voiceStateUpdate', data);
25
+ }
26
+
27
+ const newChannel = client.channels.get(data.channel_id);
28
+ if (newChannel) {
29
+ newChannel.members.set(member.id, member);
30
+ member.guild.channels.set(data.channel_id, newChannel);
31
+ }
32
+
33
+ member.serverMute = data.mute;
34
+ member.serverDeaf = data.deaf;
35
+ member.selfMute = data.self_mute;
36
+ member.selfDeaf = data.self_deaf;
37
+ member.voiceSessionID = data.session_id;
38
+ member.voiceChannelID = data.channel_id;
39
+ client.emit(Constants.Events.VOICE_STATE_UPDATE, oldVoiceChannelMember, member);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Emitted whenever a user changes voice state - e.g. joins/leaves a channel, mutes/unmutes.
47
+ * @event Client#voiceStateUpdate
48
+ * @param {GuildMember} oldMember The member before the voice state update
49
+ * @param {GuildMember} newMember The member after the voice state update
50
+ */
51
+
52
+ module.exports = VoiceStateUpdateHandler;
@@ -0,0 +1,19 @@
1
+ const AbstractHandler = require('./AbstractHandler');
2
+ const { Events } = require('../../../../util/Constants');
3
+
4
+ class WebhooksUpdate extends AbstractHandler {
5
+ handle(packet) {
6
+ const client = this.packetManager.client;
7
+ const data = packet.d;
8
+ const channel = client.channels.get(data.channel_id);
9
+ if (channel) client.emit(Events.WEBHOOKS_UPDATE, channel);
10
+ }
11
+ }
12
+
13
+ /**
14
+ * Emitted whenever a guild text channel has its webhooks changed.
15
+ * @event Client#webhookUpdate
16
+ * @param {TextChannel} channel The channel that had a webhook update
17
+ */
18
+
19
+ module.exports = WebhooksUpdate;
package/src/index.js ADDED
@@ -0,0 +1,66 @@
1
+ const Util = require('./util/Util');
2
+
3
+ module.exports = {
4
+ // "Root" classes (starting points)
5
+ Client: require('./client/Client'),
6
+ Shard: require('./sharding/Shard'),
7
+ ShardClientUtil: require('./sharding/ShardClientUtil'),
8
+ ShardingManager: require('./sharding/ShardingManager'),
9
+ WebhookClient: require('./client/WebhookClient'),
10
+
11
+ // Utilities
12
+ Collection: require('./util/Collection'),
13
+ Constants: require('./util/Constants'),
14
+ DiscordAPIError: require('./client/rest/DiscordAPIError'),
15
+ EvaluatedPermissions: require('./util/Permissions'),
16
+ Permissions: require('./util/Permissions'),
17
+ Snowflake: require('./util/Snowflake'),
18
+ SnowflakeUtil: require('./util/Snowflake'),
19
+ Util: Util,
20
+ util: Util,
21
+ version: require('../package').version,
22
+
23
+ // Shortcuts to Util methods
24
+ escapeMarkdown: Util.escapeMarkdown,
25
+ fetchRecommendedShards: Util.fetchRecommendedShards,
26
+ splitMessage: Util.splitMessage,
27
+
28
+ // Structures
29
+ Attachment: require('./structures/Attachment'),
30
+ CategoryChannel: require('./structures/CategoryChannel'),
31
+ Channel: require('./structures/Channel'),
32
+ ClientUser: require('./structures/ClientUser'),
33
+ ClientUserSettings: require('./structures/ClientUserSettings'),
34
+ Collector: require('./structures/interfaces/Collector'),
35
+ DMChannel: require('./structures/DMChannel'),
36
+ Emoji: require('./structures/Emoji'),
37
+ Game: require('./structures/Presence').Game,
38
+ GroupDMChannel: require('./structures/GroupDMChannel'),
39
+ Guild: require('./structures/Guild'),
40
+ GuildAuditLogs: require('./structures/GuildAuditLogs'),
41
+ GuildChannel: require('./structures/GuildChannel'),
42
+ GuildMember: require('./structures/GuildMember'),
43
+ Invite: require('./structures/Invite'),
44
+ Message: require('./structures/Message'),
45
+ MessageAttachment: require('./structures/MessageAttachment'),
46
+ MessageCollector: require('./structures/MessageCollector'),
47
+ MessageEmbed: require('./structures/MessageEmbed'),
48
+ MessageMentions: require('./structures/MessageMentions'),
49
+ MessageReaction: require('./structures/MessageReaction'),
50
+ NewsChannel: require('./structures/NewsChannel'),
51
+ OAuth2Application: require('./structures/OAuth2Application'),
52
+ ClientOAuth2Application: require('./structures/OAuth2Application'),
53
+ PartialGuild: require('./structures/PartialGuild'),
54
+ PartialGuildChannel: require('./structures/PartialGuildChannel'),
55
+ PermissionOverwrites: require('./structures/PermissionOverwrites'),
56
+ Presence: require('./structures/Presence').Presence,
57
+ ReactionEmoji: require('./structures/ReactionEmoji'),
58
+ ReactionCollector: require('./structures/ReactionCollector'),
59
+ RichEmbed: require('./structures/RichEmbed'),
60
+ Role: require('./structures/Role'),
61
+ StoreChannel: require('./structures/StoreChannel'),
62
+ TextChannel: require('./structures/TextChannel'),
63
+ User: require('./structures/User'),
64
+ VoiceChannel: require('./structures/VoiceChannel'),
65
+ Webhook: require('./structures/Webhook'),
66
+ };
@@ -0,0 +1,282 @@
1
+ const childProcess = require('child_process');
2
+ const EventEmitter = require('events');
3
+ const path = require('path');
4
+ const Util = require('../util/Util');
5
+
6
+ /**
7
+ * Represents a Shard spawned by the ShardingManager.
8
+ */
9
+ class Shard extends EventEmitter {
10
+ /**
11
+ * @param {ShardingManager} manager The sharding manager
12
+ * @param {number} id The ID of this shard
13
+ * @param {Array} [args=[]] Command line arguments to pass to the script
14
+ */
15
+ constructor(manager, id, args = []) {
16
+ super();
17
+ /**
18
+ * Manager that created the shard
19
+ * @type {ShardingManager}
20
+ */
21
+ this.manager = manager;
22
+
23
+ /**
24
+ * ID of the shard
25
+ * @type {number}
26
+ */
27
+ this.id = id;
28
+
29
+ /**
30
+ * The environment variables for the shard
31
+ * @type {Object}
32
+ */
33
+ this.env = Object.assign({}, process.env, {
34
+ SHARD_ID: this.id,
35
+ SHARD_COUNT: this.manager.totalShards,
36
+ CLIENT_TOKEN: this.manager.token,
37
+ });
38
+
39
+ /**
40
+ * Whether the shard's {@link Client} is ready
41
+ * @type {boolean}
42
+ */
43
+ this.ready = false;
44
+
45
+ this._evals = new Map();
46
+ this._fetches = new Map();
47
+
48
+ /**
49
+ * Listener function for the {@link ChildProcess}' `exit` event
50
+ * @type {Function}
51
+ * @private
52
+ */
53
+ this._exitListener = this._handleExit.bind(this, undefined);
54
+
55
+ /**
56
+ * Process of the shard
57
+ * @type {ChildProcess}
58
+ */
59
+ this.process = null;
60
+
61
+ this.spawn(args);
62
+ }
63
+
64
+ /**
65
+ * Forks a child process for the shard.
66
+ * <warn>You should not need to call this manually.</warn>
67
+ * @param {Array} [args=this.manager.args] Command line arguments to pass to the script
68
+ * @param {Array} [execArgv=this.manager.execArgv] Command line arguments to pass to the process executable
69
+ * @returns {ChildProcess}
70
+ */
71
+ spawn(args = this.manager.args, execArgv = this.manager.execArgv) {
72
+ this.process = childProcess.fork(path.resolve(this.manager.file), args, {
73
+ env: this.env, execArgv,
74
+ })
75
+ .on('exit', this._exitListener)
76
+ .on('message', this._handleMessage.bind(this));
77
+
78
+ /**
79
+ * Emitted upon the creation of the shard's child process.
80
+ * @event Shard#spawn
81
+ * @param {ChildProcess} process Child process that was created
82
+ */
83
+ this.emit('spawn', this.process);
84
+
85
+ return new Promise((resolve, reject) => {
86
+ this.once('ready', resolve);
87
+ this.once('disconnect', () => reject(new Error(`Shard ${this.id}'s Client disconnected before becoming ready.`)));
88
+ this.once('death', () => reject(new Error(`Shard ${this.id}'s process exited before its Client became ready.`)));
89
+ setTimeout(() => reject(new Error(`Shard ${this.id}'s Client took too long to become ready.`)), 30000);
90
+ }).then(() => this.process);
91
+ }
92
+
93
+ /**
94
+ * Immediately kills the shard's process and does not restart it.
95
+ */
96
+ kill() {
97
+ this.process.removeListener('exit', this._exitListener);
98
+ this.process.kill();
99
+ this._handleExit(false);
100
+ }
101
+
102
+ /**
103
+ * Kills and restarts the shard's process.
104
+ * @param {number} [delay=500] How long to wait between killing the process and restarting it (in milliseconds)
105
+ * @returns {Promise<ChildProcess>}
106
+ */
107
+ respawn(delay = 500) {
108
+ this.kill();
109
+ if (delay > 0) return Util.delayFor(delay).then(() => this.spawn());
110
+ return this.spawn();
111
+ }
112
+
113
+ /**
114
+ * Sends a message to the shard's process.
115
+ * @param {*} message Message to send to the shard
116
+ * @returns {Promise<Shard>}
117
+ */
118
+ send(message) {
119
+ return new Promise((resolve, reject) => {
120
+ this.process.send(message, err => {
121
+ if (err) reject(err); else resolve(this);
122
+ });
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Fetches a client property value of the shard.
128
+ * @param {string} prop Name of the client property to get, using periods for nesting
129
+ * @returns {Promise<*>}
130
+ * @example
131
+ * shard.fetchClientValue('guilds.size')
132
+ * .then(count => console.log(`${count} guilds in shard ${shard.id}`))
133
+ * .catch(console.error);
134
+ */
135
+ fetchClientValue(prop) {
136
+ if (this._fetches.has(prop)) return this._fetches.get(prop);
137
+
138
+ const promise = new Promise((resolve, reject) => {
139
+ const listener = message => {
140
+ if (!message || message._fetchProp !== prop) return;
141
+ this.process.removeListener('message', listener);
142
+ this._fetches.delete(prop);
143
+ resolve(message._result);
144
+ };
145
+ this.process.on('message', listener);
146
+
147
+ this.send({ _fetchProp: prop }).catch(err => {
148
+ this.process.removeListener('message', listener);
149
+ this._fetches.delete(prop);
150
+ reject(err);
151
+ });
152
+ });
153
+
154
+ this._fetches.set(prop, promise);
155
+ return promise;
156
+ }
157
+
158
+ /**
159
+ * Evaluates a script on the shard, in the context of the client.
160
+ * @param {string} script JavaScript to run on the shard
161
+ * @returns {Promise<*>} Result of the script execution
162
+ */
163
+ eval(script) {
164
+ if (this._evals.has(script)) return this._evals.get(script);
165
+
166
+ const promise = new Promise((resolve, reject) => {
167
+ const listener = message => {
168
+ if (!message || message._eval !== script) return;
169
+ this.process.removeListener('message', listener);
170
+ this._evals.delete(script);
171
+ if (!message._error) resolve(message._result); else reject(Util.makeError(message._error));
172
+ };
173
+ this.process.on('message', listener);
174
+
175
+ this.send({ _eval: script }).catch(err => {
176
+ this.process.removeListener('message', listener);
177
+ this._evals.delete(script);
178
+ reject(err);
179
+ });
180
+ });
181
+
182
+ this._evals.set(script, promise);
183
+ return promise;
184
+ }
185
+
186
+ /**
187
+ * Handles an IPC message.
188
+ * @param {*} message Message received
189
+ * @private
190
+ */
191
+ _handleMessage(message) {
192
+ if (message) {
193
+ // Shard is ready
194
+ if (message._ready) {
195
+ this.ready = true;
196
+ /**
197
+ * Emitted upon the shard's {@link Client#ready} event.
198
+ * @event Shard#ready
199
+ */
200
+ this.emit('ready');
201
+ return;
202
+ }
203
+
204
+ // Shard has disconnected
205
+ if (message._disconnect) {
206
+ this.ready = false;
207
+ /**
208
+ * Emitted upon the shard's {@link Client#disconnect} event.
209
+ * @event Shard#disconnect
210
+ */
211
+ this.emit('disconnect');
212
+ return;
213
+ }
214
+
215
+ // Shard is attempting to reconnect
216
+ if (message._reconnecting) {
217
+ this.ready = false;
218
+ /**
219
+ * Emitted upon the shard's {@link Client#reconnecting} event.
220
+ * @event Shard#reconnecting
221
+ */
222
+ this.emit('reconnecting');
223
+ return;
224
+ }
225
+
226
+ // Shard is requesting a property fetch
227
+ if (message._sFetchProp) {
228
+ this.manager.fetchClientValues(message._sFetchProp).then(
229
+ results => this.send({ _sFetchProp: message._sFetchProp, _result: results }),
230
+ err => this.send({ _sFetchProp: message._sFetchProp, _error: Util.makePlainError(err) })
231
+ );
232
+ return;
233
+ }
234
+
235
+ // Shard is requesting an eval broadcast
236
+ if (message._sEval) {
237
+ this.manager.broadcastEval(message._sEval).then(
238
+ results => this.send({ _sEval: message._sEval, _result: results }),
239
+ err => this.send({ _sEval: message._sEval, _error: Util.makePlainError(err) })
240
+ );
241
+ return;
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Emitted upon recieving a message from a shard.
247
+ * @event ShardingManager#message
248
+ * @param {Shard} shard Shard that sent the message
249
+ * @param {*} message Message that was received
250
+ */
251
+ this.manager.emit('message', this, message);
252
+
253
+ /**
254
+ * Emitted upon recieving a message from the child process.
255
+ * @event Shard#message
256
+ * @param {*} message Message that was received
257
+ */
258
+ this.emit('message', message);
259
+ }
260
+
261
+ /**
262
+ * Handles the shard's process exiting.
263
+ * @param {boolean} [respawn=this.manager.respawn] Whether to spawn the shard again
264
+ * @private
265
+ */
266
+ _handleExit(respawn = this.manager.respawn) {
267
+ /**
268
+ * Emitted upon the shard's child process exiting.
269
+ * @event Shard#death
270
+ * @param {ChildProcess} process Child process that exited
271
+ */
272
+ this.emit('death', this.process);
273
+
274
+ this.process = null;
275
+ this._evals.clear();
276
+ this._fetches.clear();
277
+
278
+ if (respawn) this.manager.createShard(this.id);
279
+ }
280
+ }
281
+
282
+ module.exports = Shard;