diff options
| author | Alee14 <alee14498@gmail.com> | 2017-03-26 15:18:10 -0400 |
|---|---|---|
| committer | Alee14 <alee14498@gmail.com> | 2017-03-26 15:18:10 -0400 |
| commit | 29433e2f7dbd0e4a73d3c78ffe1005b922fb5982 (patch) | |
| tree | aa0ad3fe59468cbe452ee597e914839b68c01436 /node_modules/discord.js/src/client/websocket | |
| parent | 878fefb4c4e1f12b804ae5c0def433fa873f4c8b (diff) | |
| download | AleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.tar.gz AleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.tar.bz2 AleeBot-29433e2f7dbd0e4a73d3c78ffe1005b922fb5982.zip | |
Don't mind me i'm adding the discord.js files
Diffstat (limited to 'node_modules/discord.js/src/client/websocket')
37 files changed, 1280 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/client/websocket/WebSocketManager.js b/node_modules/discord.js/src/client/websocket/WebSocketManager.js new file mode 100644 index 0000000..b67af59 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/WebSocketManager.js @@ -0,0 +1,373 @@ +const browser = typeof window !== 'undefined'; +const EventEmitter = require('events').EventEmitter; +const Constants = require('../../util/Constants'); +const convertArrayBuffer = require('../../util/ConvertArrayBuffer'); +const pako = require('pako'); +const zlib = require('zlib'); +const PacketManager = require('./packets/WebSocketPacketManager'); + +let WebSocket, erlpack; +let serialize = JSON.stringify; +if (browser) { + WebSocket = window.WebSocket; // eslint-disable-line no-undef +} else { + try { + WebSocket = require('uws'); + } catch (err) { + WebSocket = require('ws'); + } + + try { + erlpack = require('erlpack'); + serialize = erlpack.pack; + } catch (err) { + erlpack = null; + } +} + +/** + * The WebSocket Manager of the Client + * @private + */ +class WebSocketManager extends EventEmitter { + constructor(client) { + super(); + /** + * The Client that instantiated this WebSocketManager + * @type {Client} + */ + this.client = client; + + /** + * A WebSocket Packet manager, it handles all the messages + * @type {PacketManager} + */ + this.packetManager = new PacketManager(this); + + /** + * The status of the WebSocketManager, a type of Constants.Status. It defaults to IDLE. + * @type {number} + */ + this.status = Constants.Status.IDLE; + + /** + * The session ID of the connection, null if not yet available. + * @type {?string} + */ + this.sessionID = null; + + /** + * The packet count of the client, null if not yet available. + * @type {?number} + */ + this.sequence = -1; + + /** + * The gateway address for this WebSocket connection, null if not yet available. + * @type {?string} + */ + this.gateway = null; + + /** + * Whether READY was emitted normally (all packets received) or not + * @type {boolean} + */ + this.normalReady = false; + + /** + * The WebSocket connection to the gateway + * @type {?WebSocket} + */ + this.ws = null; + + /** + * An object with keys that are websocket event names that should be ignored + * @type {Object} + */ + this.disabledEvents = {}; + for (const event of client.options.disabledEvents) this.disabledEvents[event] = true; + + this.first = true; + + this.lastHeartbeatAck = true; + } + + /** + * Connects the client to a given gateway + * @param {string} gateway The gateway to connect to + */ + _connect(gateway) { + this.client.emit('debug', `Connecting to gateway ${gateway}`); + this.normalReady = false; + if (this.status !== Constants.Status.RECONNECTING) this.status = Constants.Status.CONNECTING; + this.ws = new WebSocket(gateway); + if (browser) this.ws.binaryType = 'arraybuffer'; + this.ws.onopen = this.eventOpen.bind(this); + this.ws.onmessage = this.eventMessage.bind(this); + this.ws.onclose = this.eventClose.bind(this); + this.ws.onerror = this.eventError.bind(this); + this._queue = []; + this._remaining = 120; + this.client.setInterval(() => { + this._remaining = 120; + this._remainingReset = Date.now(); + }, 60e3); + } + + connect(gateway) { + gateway = `${gateway}&encoding=${erlpack ? 'etf' : 'json'}`; + if (this.first) { + this._connect(gateway); + this.first = false; + } else { + this.client.setTimeout(() => this._connect(gateway), 5500); + } + } + + heartbeat(normal) { + if (normal && !this.lastHeartbeatAck) { + this.ws.close(1007); + return; + } + + this.client.emit('debug', 'Sending heartbeat'); + this.client._pingTimestamp = Date.now(); + this.client.ws.send({ + op: Constants.OPCodes.HEARTBEAT, + d: this.sequence, + }, true); + + this.lastHeartbeatAck = false; + } + + /** + * Sends a packet to the gateway + * @param {Object} data An object that can be JSON stringified + * @param {boolean} force Whether or not to send the packet immediately + */ + send(data, force = false) { + if (force) { + this._send(serialize(data)); + return; + } + this._queue.push(serialize(data)); + this.doQueue(); + } + + destroy() { + this.ws.close(1000); + this._queue = []; + this.status = Constants.Status.IDLE; + } + + _send(data) { + if (this.ws.readyState === WebSocket.OPEN) { + this.emit('send', data); + this.ws.send(data); + } + } + + doQueue() { + const item = this._queue[0]; + if (!(this.ws.readyState === WebSocket.OPEN && item)) return; + if (this.remaining === 0) { + this.client.setTimeout(this.doQueue.bind(this), Date.now() - this.remainingReset); + return; + } + this._remaining--; + this._send(item); + this._queue.shift(); + this.doQueue(); + } + + /** + * Run whenever the gateway connections opens up + */ + eventOpen() { + this.client.emit('debug', 'Connection to gateway opened'); + this.lastHeartbeatAck = true; + if (this.status === Constants.Status.RECONNECTING) this._sendResume(); + else this._sendNewIdentify(); + } + + /** + * Sends a gateway resume packet, in cases of unexpected disconnections. + */ + _sendResume() { + if (!this.sessionID) { + this._sendNewIdentify(); + return; + } + this.client.emit('debug', 'Identifying as resumed session'); + const payload = { + token: this.client.token, + session_id: this.sessionID, + seq: this.sequence, + }; + + this.send({ + op: Constants.OPCodes.RESUME, + d: payload, + }); + } + + /** + * Sends a new identification packet, in cases of new connections or failed reconnections. + */ + _sendNewIdentify() { + this.reconnecting = false; + const payload = this.client.options.ws; + payload.token = this.client.token; + if (this.client.options.shardCount > 0) { + payload.shard = [Number(this.client.options.shardId), Number(this.client.options.shardCount)]; + } + this.client.emit('debug', 'Identifying as new session'); + this.send({ + op: Constants.OPCodes.IDENTIFY, + d: payload, + }); + this.sequence = -1; + } + + /** + * @external CloseEvent + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent} + */ + + /** + * Run whenever the connection to the gateway is closed, it will try to reconnect the client. + * @param {CloseEvent} event The WebSocket close event + */ + eventClose(event) { + this.emit('close', event); + this.client.clearInterval(this.client.manager.heartbeatInterval); + this.status = Constants.Status.DISCONNECTED; + this._queue = []; + /** + * Emitted whenever the client websocket is disconnected + * @event Client#disconnect + * @param {CloseEvent} event The WebSocket close event + */ + if (!this.reconnecting) this.client.emit(Constants.Events.DISCONNECT, event); + if (event.code === 4004) return; + if (event.code === 4010) return; + if (!this.reconnecting && event.code !== 1000) this.tryReconnect(); + } + + /** + * Run whenever a message is received from the WebSocket. Returns `true` if the message + * was handled properly. + * @param {Object} event The received websocket data + * @returns {boolean} + */ + eventMessage(event) { + const data = this.tryParseEventData(event.data); + if (data === null) { + this.eventError(new Error(Constants.Errors.BAD_WS_MESSAGE)); + return false; + } + + this.client.emit('raw', data); + + if (data.op === Constants.OPCodes.HELLO) this.client.manager.setupKeepAlive(data.d.heartbeat_interval); + return this.packetManager.handle(data); + } + + /** + * Parses the raw data from a websocket event, inflating it if necessary + * @param {*} data Event data + * @returns {Object} + */ + parseEventData(data) { + if (erlpack) { + if (data instanceof ArrayBuffer) data = convertArrayBuffer(data); + return erlpack.unpack(data); + } else { + if (data instanceof ArrayBuffer) data = pako.inflate(data, { to: 'string' }); + else if (data instanceof Buffer) data = zlib.inflateSync(data).toString(); + return JSON.parse(data); + } + } + + /** + * Tries to call `parseEventData()` and return its result, or returns `null` upon thrown errors. + * @param {*} data Event data + * @returns {?Object} + */ + tryParseEventData(data) { + try { + return this.parseEventData(data); + } catch (err) { + return null; + } + } + + /** + * Run whenever an error occurs with the WebSocket connection. Tries to reconnect + * @param {Error} err The encountered error + */ + eventError(err) { + /** + * Emitted whenever the Client encounters a serious connection error + * @event Client#error + * @param {Error} error The encountered error + */ + if (this.client.listenerCount('error') > 0) this.client.emit('error', err); + this.tryReconnect(); + } + + _emitReady(normal = true) { + /** + * Emitted when the Client becomes ready to start working + * @event Client#ready + */ + this.status = Constants.Status.READY; + this.client.emit(Constants.Events.READY); + this.packetManager.handleQueue(); + this.normalReady = normal; + } + + /** + * Runs on new packets before `READY` to see if the Client is ready yet, if it is prepares + * the `READY` event. + */ + checkIfReady() { + if (this.status !== Constants.Status.READY && this.status !== Constants.Status.NEARLY) { + let unavailableCount = 0; + for (const guildID of this.client.guilds.keys()) { + unavailableCount += this.client.guilds.get(guildID).available ? 0 : 1; + } + if (unavailableCount === 0) { + this.status = Constants.Status.NEARLY; + if (this.client.options.fetchAllMembers) { + const promises = this.client.guilds.map(g => g.fetchMembers()); + Promise.all(promises).then(() => this._emitReady(), e => { + this.client.emit(Constants.Events.WARN, 'Error in pre-ready guild member fetching'); + this.client.emit(Constants.Events.ERROR, e); + this._emitReady(); + }); + return; + } + this._emitReady(); + } + } + } + + /** + * Tries to reconnect the client, changing the status to Constants.Status.RECONNECTING. + */ + tryReconnect() { + if (this.status === Constants.Status.RECONNECTING || this.status === Constants.Status.CONNECTING) return; + this.status = Constants.Status.RECONNECTING; + this.ws.close(); + this.packetManager.handleQueue(); + /** + * Emitted when the Client tries to reconnect after being disconnected + * @event Client#reconnecting + */ + this.client.emit(Constants.Events.RECONNECTING); + this.connect(this.client.ws.gateway); + } +} + +module.exports = WebSocketManager; diff --git a/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js b/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js new file mode 100644 index 0000000..78f5777 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js @@ -0,0 +1,125 @@ +const Constants = require('../../../util/Constants'); + +const BeforeReadyWhitelist = [ + Constants.WSEvents.READY, + Constants.WSEvents.GUILD_CREATE, + Constants.WSEvents.GUILD_DELETE, + Constants.WSEvents.GUILD_MEMBERS_CHUNK, + Constants.WSEvents.GUILD_MEMBER_ADD, + Constants.WSEvents.GUILD_MEMBER_REMOVE, +]; + +class WebSocketPacketManager { + constructor(websocketManager) { + this.ws = websocketManager; + this.handlers = {}; + this.queue = []; + + this.register(Constants.WSEvents.READY, require('./handlers/Ready')); + this.register(Constants.WSEvents.GUILD_CREATE, require('./handlers/GuildCreate')); + this.register(Constants.WSEvents.GUILD_DELETE, require('./handlers/GuildDelete')); + this.register(Constants.WSEvents.GUILD_UPDATE, require('./handlers/GuildUpdate')); + this.register(Constants.WSEvents.GUILD_BAN_ADD, require('./handlers/GuildBanAdd')); + this.register(Constants.WSEvents.GUILD_BAN_REMOVE, require('./handlers/GuildBanRemove')); + this.register(Constants.WSEvents.GUILD_MEMBER_ADD, require('./handlers/GuildMemberAdd')); + this.register(Constants.WSEvents.GUILD_MEMBER_REMOVE, require('./handlers/GuildMemberRemove')); + this.register(Constants.WSEvents.GUILD_MEMBER_UPDATE, require('./handlers/GuildMemberUpdate')); + this.register(Constants.WSEvents.GUILD_ROLE_CREATE, require('./handlers/GuildRoleCreate')); + this.register(Constants.WSEvents.GUILD_ROLE_DELETE, require('./handlers/GuildRoleDelete')); + this.register(Constants.WSEvents.GUILD_ROLE_UPDATE, require('./handlers/GuildRoleUpdate')); + this.register(Constants.WSEvents.GUILD_EMOJIS_UPDATE, require('./handlers/GuildEmojisUpdate')); + this.register(Constants.WSEvents.GUILD_MEMBERS_CHUNK, require('./handlers/GuildMembersChunk')); + this.register(Constants.WSEvents.CHANNEL_CREATE, require('./handlers/ChannelCreate')); + this.register(Constants.WSEvents.CHANNEL_DELETE, require('./handlers/ChannelDelete')); + this.register(Constants.WSEvents.CHANNEL_UPDATE, require('./handlers/ChannelUpdate')); + this.register(Constants.WSEvents.CHANNEL_PINS_UPDATE, require('./handlers/ChannelPinsUpdate')); + this.register(Constants.WSEvents.PRESENCE_UPDATE, require('./handlers/PresenceUpdate')); + this.register(Constants.WSEvents.USER_UPDATE, require('./handlers/UserUpdate')); + this.register(Constants.WSEvents.USER_NOTE_UPDATE, require('./handlers/UserNoteUpdate')); + this.register(Constants.WSEvents.VOICE_STATE_UPDATE, require('./handlers/VoiceStateUpdate')); + this.register(Constants.WSEvents.TYPING_START, require('./handlers/TypingStart')); + this.register(Constants.WSEvents.MESSAGE_CREATE, require('./handlers/MessageCreate')); + this.register(Constants.WSEvents.MESSAGE_DELETE, require('./handlers/MessageDelete')); + this.register(Constants.WSEvents.MESSAGE_UPDATE, require('./handlers/MessageUpdate')); + this.register(Constants.WSEvents.MESSAGE_DELETE_BULK, require('./handlers/MessageDeleteBulk')); + this.register(Constants.WSEvents.VOICE_SERVER_UPDATE, require('./handlers/VoiceServerUpdate')); + this.register(Constants.WSEvents.GUILD_SYNC, require('./handlers/GuildSync')); + this.register(Constants.WSEvents.RELATIONSHIP_ADD, require('./handlers/RelationshipAdd')); + this.register(Constants.WSEvents.RELATIONSHIP_REMOVE, require('./handlers/RelationshipRemove')); + this.register(Constants.WSEvents.MESSAGE_REACTION_ADD, require('./handlers/MessageReactionAdd')); + this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE, require('./handlers/MessageReactionRemove')); + this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE_ALL, require('./handlers/MessageReactionRemoveAll')); + } + + get client() { + return this.ws.client; + } + + register(event, Handler) { + this.handlers[event] = new Handler(this); + } + + handleQueue() { + this.queue.forEach((element, index) => { + this.handle(this.queue[index]); + this.queue.splice(index, 1); + }); + } + + setSequence(s) { + if (s && s > this.ws.sequence) this.ws.sequence = s; + } + + handle(packet) { + if (packet.op === Constants.OPCodes.RECONNECT) { + this.setSequence(packet.s); + this.ws.tryReconnect(); + return false; + } + + if (packet.op === Constants.OPCodes.INVALID_SESSION) { + if (packet.d) { + setTimeout(() => { + this.ws._sendResume(); + }, 2500); + } else { + this.ws.sessionID = null; + this.ws._sendNewIdentify(); + } + return false; + } + + if (packet.op === Constants.OPCodes.HEARTBEAT_ACK) { + this.ws.client._pong(this.ws.client._pingTimestamp); + this.ws.lastHeartbeatAck = true; + this.ws.client.emit('debug', 'Heartbeat acknowledged'); + } else if (packet.op === Constants.OPCodes.HEARTBEAT) { + this.client.ws.send({ + op: Constants.OPCodes.HEARTBEAT, + d: this.client.ws.sequence, + }); + this.ws.client.emit('debug', 'Received gateway heartbeat'); + } + + if (this.ws.status === Constants.Status.RECONNECTING) { + this.ws.reconnecting = false; + this.ws.checkIfReady(); + } + + this.setSequence(packet.s); + + if (this.ws.disabledEvents[packet.t] !== undefined) return false; + + if (this.ws.status !== Constants.Status.READY) { + if (BeforeReadyWhitelist.indexOf(packet.t) === -1) { + this.queue.push(packet); + return false; + } + } + + if (this.handlers[packet.t]) return this.handlers[packet.t].handle(packet); + return false; + } +} + +module.exports = WebSocketPacketManager; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/AbstractHandler.js b/node_modules/discord.js/src/client/websocket/packets/handlers/AbstractHandler.js new file mode 100644 index 0000000..c1c2a5a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/AbstractHandler.js @@ -0,0 +1,11 @@ +class AbstractHandler { + constructor(packetManager) { + this.packetManager = packetManager; + } + + handle(packet) { + return packet; + } +} + +module.exports = AbstractHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelCreate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelCreate.js new file mode 100644 index 0000000..04cb298 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelCreate.js @@ -0,0 +1,17 @@ +const AbstractHandler = require('./AbstractHandler'); + +class ChannelCreateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.ChannelCreate.handle(data); + } +} + +/** + * Emitted whenever a channel is created. + * @event Client#channelCreate + * @param {Channel} channel The channel that was created + */ + +module.exports = ChannelCreateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelDelete.js b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelDelete.js new file mode 100644 index 0000000..b25f585 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelDelete.js @@ -0,0 +1,20 @@ +const AbstractHandler = require('./AbstractHandler'); + +const Constants = require('../../../../util/Constants'); + +class ChannelDeleteHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const response = client.actions.ChannelDelete.handle(data); + if (response.channel) client.emit(Constants.Events.CHANNEL_DELETE, response.channel); + } +} + +/** + * Emitted whenever a channel is deleted. + * @event Client#channelDelete + * @param {Channel} channel The channel that was deleted + */ + +module.exports = ChannelDeleteHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelPinsUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelPinsUpdate.js new file mode 100644 index 0000000..636df81 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelPinsUpdate.js @@ -0,0 +1,31 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +/* +{ t: 'CHANNEL_PINS_UPDATE', + s: 666, + op: 0, + d: + { last_pin_timestamp: '2016-08-28T17:37:13.171774+00:00', + channel_id: '314866471639044027' } } +*/ + +class ChannelPinsUpdate extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const channel = client.channels.get(data.channel_id); + const time = new Date(data.last_pin_timestamp); + if (channel && time) client.emit(Constants.Events.CHANNEL_PINS_UPDATE, channel, time); + } +} + +/** + * Emitted whenever the pins of a channel are updated. Due to the nature of the WebSocket event, not much information + * can be provided easily here - you need to manually check the pins yourself. + * @event Client#channelPinsUpdate + * @param {Channel} channel The channel that the pins update occured in + * @param {Date} time The time of the pins update + */ + +module.exports = ChannelPinsUpdate; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelUpdate.js new file mode 100644 index 0000000..fa535b1 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelUpdate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class ChannelUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.ChannelUpdate.handle(data); + } +} + +module.exports = ChannelUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanAdd.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanAdd.js new file mode 100644 index 0000000..60ce72d --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanAdd.js @@ -0,0 +1,23 @@ +// ##untested handler## + +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class GuildBanAddHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const guild = client.guilds.get(data.guild_id); + const user = client.users.get(data.user.id); + if (guild && user) client.emit(Constants.Events.GUILD_BAN_ADD, guild, user); + } +} + +/** + * Emitted whenever a member is banned from a guild. + * @event Client#guildBanAdd + * @param {Guild} guild The guild that the ban occurred in + * @param {User} user The user that was banned + */ + +module.exports = GuildBanAddHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanRemove.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanRemove.js new file mode 100644 index 0000000..c4edbde --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanRemove.js @@ -0,0 +1,20 @@ +// ##untested handler## + +const AbstractHandler = require('./AbstractHandler'); + +class GuildBanRemoveHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildBanRemove.handle(data); + } +} + +/** + * Emitted whenever a member is unbanned from a guild. + * @event Client#guildBanRemove + * @param {Guild} guild The guild that the unban occurred in + * @param {User} user The user that was unbanned + */ + +module.exports = GuildBanRemoveHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildCreate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildCreate.js new file mode 100644 index 0000000..c7fbd7e --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildCreate.js @@ -0,0 +1,22 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildCreateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + + const guild = client.guilds.get(data.id); + if (guild) { + if (!guild.available && !data.unavailable) { + // a newly available guild + guild.setup(data); + this.packetManager.ws.checkIfReady(); + } + } else { + // a new guild + client.dataManager.newGuild(data); + } + } +} + +module.exports = GuildCreateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildDelete.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildDelete.js new file mode 100644 index 0000000..35e3c53 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildDelete.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class GuildDeleteHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const response = client.actions.GuildDelete.handle(data); + if (response.guild) client.emit(Constants.Events.GUILD_DELETE, response.guild); + } +} + +/** + * Emitted whenever a guild is deleted/left. + * @event Client#guildDelete + * @param {Guild} guild The guild that was deleted + */ + +module.exports = GuildDeleteHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildEmojisUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildEmojisUpdate.js new file mode 100644 index 0000000..c6ebdaa --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildEmojisUpdate.js @@ -0,0 +1,40 @@ +const AbstractHandler = require('./AbstractHandler'); + +function mappify(iterable) { + const map = new Map(); + for (const x of iterable) map.set(...x); + return map; +} + +class GuildEmojisUpdate extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const guild = client.guilds.get(data.guild_id); + if (!guild || !guild.emojis) return; + + const deletions = mappify(guild.emojis.entries()); + + for (const emoji of data.emojis) { + // determine type of emoji event + const cachedEmoji = guild.emojis.get(emoji.id); + if (cachedEmoji) { + deletions.delete(emoji.id); + if (!cachedEmoji.equals(emoji, true)) { + // emoji updated + client.actions.GuildEmojiUpdate.handle(cachedEmoji, emoji); + } + } else { + // emoji added + client.actions.GuildEmojiCreate.handle(guild, emoji); + } + } + + for (const emoji of deletions.values()) { + // emoji deleted + client.actions.GuildEmojiDelete.handle(emoji); + } + } +} + +module.exports = GuildEmojisUpdate; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberAdd.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberAdd.js new file mode 100644 index 0000000..d4d122f --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberAdd.js @@ -0,0 +1,17 @@ +// ##untested handler## + +const AbstractHandler = require('./AbstractHandler'); + +class GuildMemberAddHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const guild = client.guilds.get(data.guild_id); + if (guild) { + guild.memberCount++; + guild._addMember(data); + } + } +} + +module.exports = GuildMemberAddHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberRemove.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberRemove.js new file mode 100644 index 0000000..6ec1bfe --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberRemove.js @@ -0,0 +1,13 @@ +// ##untested handler## + +const AbstractHandler = require('./AbstractHandler'); + +class GuildMemberRemoveHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildMemberRemove.handle(data); + } +} + +module.exports = GuildMemberRemoveHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberUpdate.js new file mode 100644 index 0000000..94ac71f --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberUpdate.js @@ -0,0 +1,18 @@ +// ##untested handler## + +const AbstractHandler = require('./AbstractHandler'); + +class GuildMemberUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + + const guild = client.guilds.get(data.guild_id); + if (guild) { + const member = guild.members.get(data.user.id); + if (member) guild._updateMember(member, data); + } + } +} + +module.exports = GuildMemberUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMembersChunk.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMembersChunk.js new file mode 100644 index 0000000..02a3c3c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMembersChunk.js @@ -0,0 +1,28 @@ +// ##untested## + +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class GuildMembersChunkHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const guild = client.guilds.get(data.guild_id); + if (!guild) return; + + const members = data.members.map(member => guild._addMember(member, false)); + + guild._checkChunks(); + client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members); + + client.ws.lastHeartbeatAck = true; + } +} + +/** + * Emitted whenever a chunk of guild members is received (all members come from the same guild) + * @event Client#guildMembersChunk + * @param {GuildMember[]} members The members in the chunk + */ + +module.exports = GuildMembersChunkHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleCreate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleCreate.js new file mode 100644 index 0000000..8581d53 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleCreate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildRoleCreateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildRoleCreate.handle(data); + } +} + +module.exports = GuildRoleCreateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleDelete.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleDelete.js new file mode 100644 index 0000000..63439b0 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleDelete.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildRoleDeleteHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildRoleDelete.handle(data); + } +} + +module.exports = GuildRoleDeleteHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleUpdate.js new file mode 100644 index 0000000..6fbdc10 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleUpdate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildRoleUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildRoleUpdate.handle(data); + } +} + +module.exports = GuildRoleUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildSync.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildSync.js new file mode 100644 index 0000000..0b9f5aa --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildSync.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildSyncHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildSync.handle(data); + } +} + +module.exports = GuildSyncHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildUpdate.js new file mode 100644 index 0000000..70eff52 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildUpdate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class GuildUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.GuildUpdate.handle(data); + } +} + +module.exports = GuildUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageCreate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageCreate.js new file mode 100644 index 0000000..058dc85 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageCreate.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class MessageCreateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const response = client.actions.MessageCreate.handle(data); + if (response.message) client.emit(Constants.Events.MESSAGE_CREATE, response.message); + } +} + +/** + * Emitted whenever a message is created + * @event Client#message + * @param {Message} message The created message + */ + +module.exports = MessageCreateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDelete.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDelete.js new file mode 100644 index 0000000..b06ce98 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDelete.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class MessageDeleteHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const response = client.actions.MessageDelete.handle(data); + if (response.message) client.emit(Constants.Events.MESSAGE_DELETE, response.message); + } +} + +/** + * Emitted whenever a message is deleted + * @event Client#messageDelete + * @param {Message} message The deleted message + */ + +module.exports = MessageDeleteHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDeleteBulk.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDeleteBulk.js new file mode 100644 index 0000000..6cd3648 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDeleteBulk.js @@ -0,0 +1,17 @@ +const AbstractHandler = require('./AbstractHandler'); + +class MessageDeleteBulkHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.MessageDeleteBulk.handle(data); + } +} + +/** + * Emitted whenever messages are deleted in bulk + * @event Client#messageDeleteBulk + * @param {Collection<string, Message>} messages The deleted messages, mapped by their ID + */ + +module.exports = MessageDeleteBulkHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionAdd.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionAdd.js new file mode 100644 index 0000000..a58db70 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionAdd.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class MessageReactionAddHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.MessageReactionAdd.handle(data); + } +} + +module.exports = MessageReactionAddHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemove.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemove.js new file mode 100644 index 0000000..cddde70 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemove.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class MessageReactionRemove extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.MessageReactionRemove.handle(data); + } +} + +module.exports = MessageReactionRemove; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js new file mode 100644 index 0000000..303da9c --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class MessageReactionRemoveAll extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.MessageReactionRemoveAll.handle(data); + } +} + +module.exports = MessageReactionRemoveAll; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageUpdate.js new file mode 100644 index 0000000..527632d --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageUpdate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class MessageUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.MessageUpdate.handle(data); + } +} + +module.exports = MessageUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/PresenceUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/PresenceUpdate.js new file mode 100644 index 0000000..09d78a0 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/PresenceUpdate.js @@ -0,0 +1,72 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); +const cloneObject = require('../../../../util/CloneObject'); + +class PresenceUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + let user = client.users.get(data.user.id); + const guild = client.guilds.get(data.guild_id); + + // step 1 + if (!user) { + if (data.user.username) { + user = client.dataManager.newUser(data.user); + } else { + return; + } + } + + const oldUser = cloneObject(user); + user.patch(data.user); + if (!user.equals(oldUser)) { + client.emit(Constants.Events.USER_UPDATE, oldUser, user); + } + + if (guild) { + let member = guild.members.get(user.id); + if (!member && data.status !== 'offline') { + member = guild._addMember({ + user, + roles: data.roles, + deaf: false, + mute: false, + }, false); + client.emit(Constants.Events.GUILD_MEMBER_AVAILABLE, member); + } + if (member) { + const oldMember = cloneObject(member); + if (member.presence) { + oldMember.frozenPresence = cloneObject(member.presence); + } + guild._setPresence(user.id, data); + client.emit(Constants.Events.PRESENCE_UPDATE, oldMember, member); + } else { + guild._setPresence(user.id, data); + } + } + } +} + +/** + * Emitted whenever a guild member's presence changes, or they change one of their details. + * @event Client#presenceUpdate + * @param {GuildMember} oldMember The member before the presence update + * @param {GuildMember} newMember The member after the presence update + */ + +/** + * Emitted whenever a user's details (e.g. username) are changed. + * @event Client#userUpdate + * @param {User} oldUser The user before the update + * @param {User} newUser The user after the update + */ + +/** + * Emitted whenever a member becomes available in a large guild + * @event Client#guildMemberAvailable + * @param {GuildMember} member The member that became available + */ + +module.exports = PresenceUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/Ready.js b/node_modules/discord.js/src/client/websocket/packets/handlers/Ready.js new file mode 100644 index 0000000..10bc6b2 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/Ready.js @@ -0,0 +1,69 @@ +const AbstractHandler = require('./AbstractHandler'); + +const ClientUser = require('../../../../structures/ClientUser'); + +class ReadyHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + + client.ws.heartbeat(); + + const clientUser = new ClientUser(client, data.user); + client.user = clientUser; + client.readyAt = new Date(); + client.users.set(clientUser.id, clientUser); + + for (const guild of data.guilds) client.dataManager.newGuild(guild); + for (const privateDM of data.private_channels) client.dataManager.newChannel(privateDM); + + for (const relation of data.relationships) { + const user = client.dataManager.newUser(relation.user); + if (relation.type === 1) { + client.user.friends.set(user.id, user); + } else if (relation.type === 2) { + client.user.blocked.set(user.id, user); + } + } + + data.presences = data.presences || []; + for (const presence of data.presences) { + client.dataManager.newUser(presence.user); + client._setPresence(presence.user.id, presence); + } + + if (data.notes) { + for (const user in data.notes) { + let note = data.notes[user]; + if (!note.length) note = null; + + client.user.notes.set(user, note); + } + } + + if (!client.user.bot && client.options.sync) client.setInterval(client.syncGuilds.bind(client), 30000); + client.once('ready', client.syncGuilds.bind(client)); + + if (!client.users.has('1')) { + client.dataManager.newUser({ + id: '1', + username: 'Clyde', + discriminator: '0000', + avatar: 'https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png', + bot: true, + status: 'online', + game: null, + verified: true, + }); + } + + client.setTimeout(() => { + if (!client.ws.normalReady) client.ws._emitReady(false); + }, 1200 * data.guilds.length); + + this.packetManager.ws.sessionID = data.session_id; + this.packetManager.ws.checkIfReady(); + } +} + +module.exports = ReadyHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipAdd.js b/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipAdd.js new file mode 100644 index 0000000..122b4c5 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipAdd.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); + +class RelationshipAddHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + if (data.type === 1) { + client.fetchUser(data.id).then(user => { + client.user.friends.set(user.id, user); + }); + } else if (data.type === 2) { + client.fetchUser(data.id).then(user => { + client.user.blocked.set(user.id, user); + }); + } + } +} + +module.exports = RelationshipAddHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipRemove.js b/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipRemove.js new file mode 100644 index 0000000..b57326a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipRemove.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); + +class RelationshipRemoveHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + if (data.type === 2) { + if (client.user.blocked.has(data.id)) { + client.user.blocked.delete(data.id); + } + } else if (data.type === 1) { + if (client.user.friends.has(data.id)) { + client.user.friends.delete(data.id); + } + } + } +} + +module.exports = RelationshipRemoveHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/TypingStart.js b/node_modules/discord.js/src/client/websocket/packets/handlers/TypingStart.js new file mode 100644 index 0000000..1a35ca7 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/TypingStart.js @@ -0,0 +1,68 @@ +const AbstractHandler = require('./AbstractHandler'); +const Constants = require('../../../../util/Constants'); + +class TypingStartHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + const channel = client.channels.get(data.channel_id); + const user = client.users.get(data.user_id); + const timestamp = new Date(data.timestamp * 1000); + + if (channel && user) { + if (channel.type === 'voice') { + client.emit(Constants.Events.WARN, `Discord sent a typing packet to voice channel ${channel.id}`); + return; + } + if (channel._typing.has(user.id)) { + const typing = channel._typing.get(user.id); + typing.lastTimestamp = timestamp; + typing.resetTimeout(tooLate(channel, user)); + } else { + channel._typing.set(user.id, new TypingData(client, timestamp, timestamp, tooLate(channel, user))); + client.emit(Constants.Events.TYPING_START, channel, user); + } + } + } +} + +class TypingData { + constructor(client, since, lastTimestamp, _timeout) { + this.client = client; + this.since = since; + this.lastTimestamp = lastTimestamp; + this._timeout = _timeout; + } + + resetTimeout(_timeout) { + this.client.clearTimeout(this._timeout); + this._timeout = _timeout; + } + + get elapsedTime() { + return Date.now() - this.since; + } +} + +function tooLate(channel, user) { + return channel.client.setTimeout(() => { + channel.client.emit(Constants.Events.TYPING_STOP, channel, user, channel._typing.get(user.id)); + channel._typing.delete(user.id); + }, 6000); +} + +/** + * Emitted whenever a user starts typing in a channel + * @event Client#typingStart + * @param {Channel} channel The channel the user started typing in + * @param {User} user The user that started typing + */ + +/** + * Emitted whenever a user stops typing in a channel + * @event Client#typingStop + * @param {Channel} channel The channel the user stopped typing in + * @param {User} user The user that stopped typing + */ + +module.exports = TypingStartHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/UserNoteUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/UserNoteUpdate.js new file mode 100644 index 0000000..1e4777a --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/UserNoteUpdate.js @@ -0,0 +1,12 @@ +const AbstractHandler = require('./AbstractHandler'); + +class UserNoteUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + + client.actions.UserNoteUpdate.handle(data); + } +} + +module.exports = UserNoteUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/UserUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/UserUpdate.js new file mode 100644 index 0000000..bc34f34 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/UserUpdate.js @@ -0,0 +1,11 @@ +const AbstractHandler = require('./AbstractHandler'); + +class UserUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.actions.UserUpdate.handle(data); + } +} + +module.exports = UserUpdateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceServerUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceServerUpdate.js new file mode 100644 index 0000000..97885d6 --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceServerUpdate.js @@ -0,0 +1,19 @@ +const AbstractHandler = require('./AbstractHandler'); + +/* +{ + "token": "my_token", + "guild_id": "41771983423143937", + "endpoint": "smart.loyal.discord.gg" +} +*/ + +class VoiceServerUpdate extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + client.emit('self.voiceServer', data); + } +} + +module.exports = VoiceServerUpdate; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceStateUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceStateUpdate.js new file mode 100644 index 0000000..ddbfbfc --- /dev/null +++ b/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceStateUpdate.js @@ -0,0 +1,49 @@ +const AbstractHandler = require('./AbstractHandler'); + +const Constants = require('../../../../util/Constants'); +const cloneObject = require('../../../../util/CloneObject'); + +class VoiceStateUpdateHandler extends AbstractHandler { + handle(packet) { + const client = this.packetManager.client; + const data = packet.d; + + const guild = client.guilds.get(data.guild_id); + if (guild) { + const member = guild.members.get(data.user_id); + if (member) { + const oldVoiceChannelMember = cloneObject(member); + if (member.voiceChannel && member.voiceChannel.id !== data.channel_id) { + member.voiceChannel.members.delete(oldVoiceChannelMember.id); + } + + // if the member left the voice channel, unset their speaking property + if (!data.channel_id) member.speaking = null; + + if (member.user.id === client.user.id && data.channel_id) { + client.emit('self.voiceStateUpdate', data); + } + + const newChannel = client.channels.get(data.channel_id); + if (newChannel) newChannel.members.set(member.user.id, member); + + member.serverMute = data.mute; + member.serverDeaf = data.deaf; + member.selfMute = data.self_mute; + member.selfDeaf = data.self_deaf; + member.voiceSessionID = data.session_id; + member.voiceChannelID = data.channel_id; + client.emit(Constants.Events.VOICE_STATE_UPDATE, oldVoiceChannelMember, member); + } + } + } +} + +/** + * Emitted whenever a user changes voice state - e.g. joins/leaves a channel, mutes/unmutes. + * @event Client#voiceStateUpdate + * @param {GuildMember} oldMember The member before the voice state update + * @param {GuildMember} newMember The member after the voice state update + */ + +module.exports = VoiceStateUpdateHandler; |
