diff options
Diffstat (limited to 'node_modules/discord.js/src')
142 files changed, 0 insertions, 13166 deletions
diff --git a/node_modules/discord.js/src/client/Client.js b/node_modules/discord.js/src/client/Client.js deleted file mode 100644 index 11cd5f4..0000000 --- a/node_modules/discord.js/src/client/Client.js +++ /dev/null @@ -1,478 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const mergeDefault = require('../util/MergeDefault'); -const Constants = require('../util/Constants'); -const RESTManager = require('./rest/RESTManager'); -const ClientDataManager = require('./ClientDataManager'); -const ClientManager = require('./ClientManager'); -const ClientDataResolver = require('./ClientDataResolver'); -const ClientVoiceManager = require('./voice/ClientVoiceManager'); -const WebSocketManager = require('./websocket/WebSocketManager'); -const ActionsManager = require('./actions/ActionsManager'); -const Collection = require('../util/Collection'); -const Presence = require('../structures/Presence').Presence; -const ShardClientUtil = require('../sharding/ShardClientUtil'); - -/** - * The starting point for making a Discord Bot. - * @extends {EventEmitter} - */ -class Client extends EventEmitter { - /** - * @param {ClientOptions} [options] Options for the client - */ - constructor(options = {}) { - super(); - - // Obtain shard details from environment - if (!options.shardId && 'SHARD_ID' in process.env) options.shardId = Number(process.env.SHARD_ID); - if (!options.shardCount && 'SHARD_COUNT' in process.env) options.shardCount = Number(process.env.SHARD_COUNT); - - /** - * The options the client was instantiated with - * @type {ClientOptions} - */ - this.options = mergeDefault(Constants.DefaultOptions, options); - this._validateOptions(); - - /** - * The REST manager of the client - * @type {RESTManager} - * @private - */ - this.rest = new RESTManager(this); - - /** - * The data manager of the Client - * @type {ClientDataManager} - * @private - */ - this.dataManager = new ClientDataManager(this); - - /** - * The manager of the Client - * @type {ClientManager} - * @private - */ - this.manager = new ClientManager(this); - - /** - * The WebSocket Manager of the Client - * @type {WebSocketManager} - * @private - */ - this.ws = new WebSocketManager(this); - - /** - * The Data Resolver of the Client - * @type {ClientDataResolver} - * @private - */ - this.resolver = new ClientDataResolver(this); - - /** - * The Action Manager of the Client - * @type {ActionsManager} - * @private - */ - this.actions = new ActionsManager(this); - - /** - * The Voice Manager of the Client (`null` in browsers) - * @type {?ClientVoiceManager} - * @private - */ - this.voice = !this.browser ? new ClientVoiceManager(this) : null; - - /** - * The shard helpers for the client (only if the process was spawned as a child, such as from a ShardingManager) - * @type {?ShardClientUtil} - */ - this.shard = process.send ? ShardClientUtil.singleton(this) : null; - - /** - * A collection of the Client's stored users - * @type {Collection<string, User>} - */ - this.users = new Collection(); - - /** - * A collection of the Client's stored guilds - * @type {Collection<string, Guild>} - */ - this.guilds = new Collection(); - - /** - * A collection of the Client's stored channels - * @type {Collection<string, Channel>} - */ - this.channels = new Collection(); - - /** - * A collection of presences for friends of the logged in user. - * <warn>This is only filled when using a user account.</warn> - * @type {Collection<string, Presence>} - */ - this.presences = new Collection(); - - if (!this.token && 'CLIENT_TOKEN' in process.env) { - /** - * The authorization token for the logged in user/bot. - * @type {?string} - */ - this.token = process.env.CLIENT_TOKEN; - } else { - this.token = null; - } - - /** - * The ClientUser representing the logged in Client - * @type {?ClientUser} - */ - this.user = null; - - /** - * The date at which the Client was regarded as being in the `READY` state. - * @type {?Date} - */ - this.readyAt = null; - - /** - * The previous heartbeat pings of the websocket (most recent first, limited to three elements) - * @type {number[]} - */ - this.pings = []; - - this._pingTimestamp = 0; - this._timeouts = new Set(); - this._intervals = new Set(); - - if (this.options.messageSweepInterval > 0) { - this.setInterval(this.sweepMessages.bind(this), this.options.messageSweepInterval * 1000); - } - } - - /** - * The status for the logged in Client. - * @type {?number} - * @readonly - */ - get status() { - return this.ws.status; - } - - /** - * The uptime for the logged in Client. - * @type {?number} - * @readonly - */ - get uptime() { - return this.readyAt ? Date.now() - this.readyAt : null; - } - - /** - * The average heartbeat ping of the websocket - * @type {number} - * @readonly - */ - get ping() { - return this.pings.reduce((prev, p) => prev + p, 0) / this.pings.length; - } - - /** - * Returns a collection, mapping guild ID to voice connections. - * @type {Collection<string, VoiceConnection>} - * @readonly - */ - get voiceConnections() { - if (this.browser) return new Collection(); - return this.voice.connections; - } - - /** - * The emojis that the client can use. Mapped by emoji ID. - * @type {Collection<string, Emoji>} - * @readonly - */ - get emojis() { - const emojis = new Collection(); - for (const guild of this.guilds.values()) { - for (const emoji of guild.emojis.values()) emojis.set(emoji.id, emoji); - } - return emojis; - } - - /** - * The timestamp that the client was last ready at - * @type {?number} - * @readonly - */ - get readyTimestamp() { - return this.readyAt ? this.readyAt.getTime() : null; - } - - /** - * Whether the client is in a browser environment - * @type {boolean} - * @readonly - */ - get browser() { - return typeof window !== 'undefined'; - } - - /** - * Logs the client in. If successful, resolves with the account's token. <warn>If you're making a bot, it's - * much better to use a bot account rather than a user account. - * Bot accounts have higher rate limits and have access to some features user accounts don't have. User bots - * that are making a lot of API requests can even be banned.</warn> - * @param {string} token The token used for the account. - * @returns {Promise<string>} - * @example - * // log the client in using a token - * const token = 'my token'; - * client.login(token); - * @example - * // log the client in using email and password - * const email = 'user@email.com'; - * const password = 'supersecret123'; - * client.login(email, password); - */ - login(token) { - return this.rest.methods.login(token); - } - - /** - * Destroys the client and logs out. - * @returns {Promise} - */ - destroy() { - for (const t of this._timeouts) clearTimeout(t); - for (const i of this._intervals) clearInterval(i); - this._timeouts.clear(); - this._intervals.clear(); - return this.manager.destroy(); - } - - /** - * This shouldn't really be necessary to most developers as it is automatically invoked every 30 seconds, however - * if you wish to force a sync of guild data, you can use this. - * <warn>This is only available when using a user account.</warn> - * @param {Guild[]|Collection<string, Guild>} [guilds=this.guilds] An array or collection of guilds to sync - */ - syncGuilds(guilds = this.guilds) { - if (this.user.bot) return; - this.ws.send({ - op: 12, - d: guilds instanceof Collection ? guilds.keyArray() : guilds.map(g => g.id), - }); - } - - /** - * Caches a user, or obtains it from the cache if it's already cached. - * <warn>This is only available when using a bot account.</warn> - * @param {string} id The ID of the user to obtain - * @returns {Promise<User>} - */ - fetchUser(id) { - if (this.users.has(id)) return Promise.resolve(this.users.get(id)); - return this.rest.methods.getUser(id); - } - - /** - * Fetches an invite object from an invite code. - * @param {InviteResolvable} invite An invite code or URL - * @returns {Promise<Invite>} - */ - fetchInvite(invite) { - const code = this.resolver.resolveInviteCode(invite); - return this.rest.methods.getInvite(code); - } - - /** - * Fetch a webhook by ID. - * @param {string} id ID of the webhook - * @param {string} [token] Token for the webhook - * @returns {Promise<Webhook>} - */ - fetchWebhook(id, token) { - return this.rest.methods.getWebhook(id, token); - } - - /** - * Sweeps all channels' messages and removes the ones older than the max message lifetime. - * If the message has been edited, the time of the edit is used rather than the time of the original message. - * @param {number} [lifetime=this.options.messageCacheLifetime] Messages that are older than this (in seconds) - * will be removed from the caches. The default is based on the client's `messageCacheLifetime` option. - * @returns {number} Amount of messages that were removed from the caches, - * or -1 if the message cache lifetime is unlimited - */ - sweepMessages(lifetime = this.options.messageCacheLifetime) { - if (typeof lifetime !== 'number' || isNaN(lifetime)) throw new TypeError('The lifetime must be a number.'); - if (lifetime <= 0) { - this.emit('debug', 'Didn\'t sweep messages - lifetime is unlimited'); - return -1; - } - - const lifetimeMs = lifetime * 1000; - const now = Date.now(); - let channels = 0; - let messages = 0; - - for (const channel of this.channels.values()) { - if (!channel.messages) continue; - channels++; - - for (const message of channel.messages.values()) { - if (now - (message.editedTimestamp || message.createdTimestamp) > lifetimeMs) { - channel.messages.delete(message.id); - messages++; - } - } - } - - this.emit('debug', `Swept ${messages} messages older than ${lifetime} seconds in ${channels} text-based channels`); - return messages; - } - - /** - * Gets the bot's OAuth2 application. - * <warn>This is only available when using a bot account.</warn> - * @returns {Promise<ClientOAuth2Application>} - */ - fetchApplication() { - if (!this.user.bot) throw new Error(Constants.Errors.NO_BOT_ACCOUNT); - return this.rest.methods.getMyApplication(); - } - - /** - * Generate an invite link for your bot - * @param {PermissionResolvable[]|number} [permissions] An array of permissions to request - * @returns {Promise<string>} The invite link - * @example - * client.generateInvite(['SEND_MESSAGES', 'MANAGE_GUILD', 'MENTION_EVERYONE']) - * .then(link => { - * console.log(`Generated bot invite link: ${link}`); - * }); - */ - generateInvite(permissions) { - if (permissions) { - if (permissions instanceof Array) permissions = this.resolver.resolvePermissions(permissions); - } else { - permissions = 0; - } - return this.fetchApplication().then(application => - `https://discordapp.com/oauth2/authorize?client_id=${application.id}&permissions=${permissions}&scope=bot` - ); - } - - /** - * Sets a timeout that will be automatically cancelled if the client is destroyed. - * @param {Function} fn Function to execute - * @param {number} delay Time to wait before executing (in milliseconds) - * @param {...*} args Arguments for the function - * @returns {Timeout} - */ - setTimeout(fn, delay, ...args) { - const timeout = setTimeout(() => { - fn(); - this._timeouts.delete(timeout); - }, delay, ...args); - this._timeouts.add(timeout); - return timeout; - } - - /** - * Clears a timeout - * @param {Timeout} timeout Timeout to cancel - */ - clearTimeout(timeout) { - clearTimeout(timeout); - this._timeouts.delete(timeout); - } - - /** - * Sets an interval that will be automatically cancelled if the client is destroyed. - * @param {Function} fn Function to execute - * @param {number} delay Time to wait before executing (in milliseconds) - * @param {...*} args Arguments for the function - * @returns {Timeout} - */ - setInterval(fn, delay, ...args) { - const interval = setInterval(fn, delay, ...args); - this._intervals.add(interval); - return interval; - } - - /** - * Clears an interval - * @param {Timeout} interval Interval to cancel - */ - clearInterval(interval) { - clearInterval(interval); - this._intervals.delete(interval); - } - - _pong(startTime) { - this.pings.unshift(Date.now() - startTime); - if (this.pings.length > 3) this.pings.length = 3; - this.ws.lastHeartbeatAck = true; - } - - _setPresence(id, presence) { - if (this.presences.get(id)) { - this.presences.get(id).update(presence); - return; - } - this.presences.set(id, new Presence(presence)); - } - - _eval(script) { - return eval(script); - } - - _validateOptions(options = this.options) { - if (typeof options.shardCount !== 'number' || isNaN(options.shardCount)) { - throw new TypeError('The shardCount option must be a number.'); - } - if (typeof options.shardId !== 'number' || isNaN(options.shardId)) { - throw new TypeError('The shardId option must be a number.'); - } - if (options.shardCount < 0) throw new RangeError('The shardCount option must be at least 0.'); - if (options.shardId < 0) throw new RangeError('The shardId option must be at least 0.'); - if (options.shardId !== 0 && options.shardId >= options.shardCount) { - throw new RangeError('The shardId option must be less than shardCount.'); - } - if (typeof options.messageCacheMaxSize !== 'number' || isNaN(options.messageCacheMaxSize)) { - throw new TypeError('The messageCacheMaxSize option must be a number.'); - } - if (typeof options.messageCacheLifetime !== 'number' || isNaN(options.messageCacheLifetime)) { - throw new TypeError('The messageCacheLifetime option must be a number.'); - } - if (typeof options.messageSweepInterval !== 'number' || isNaN(options.messageSweepInterval)) { - throw new TypeError('The messageSweepInterval option must be a number.'); - } - if (typeof options.fetchAllMembers !== 'boolean') { - throw new TypeError('The fetchAllMembers option must be a boolean.'); - } - if (typeof options.disableEveryone !== 'boolean') { - throw new TypeError('The disableEveryone option must be a boolean.'); - } - if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) { - throw new TypeError('The restWsBridgeTimeout option must be a number.'); - } - if (!(options.disabledEvents instanceof Array)) throw new TypeError('The disabledEvents option must be an Array.'); - } -} - -module.exports = Client; - -/** - * Emitted for general warnings - * @event Client#warn - * @param {string} info The warning - */ - -/** - * Emitted for general debugging information - * @event Client#debug - * @param {string} info The debug information - */ diff --git a/node_modules/discord.js/src/client/ClientDataManager.js b/node_modules/discord.js/src/client/ClientDataManager.js deleted file mode 100644 index 32b442b..0000000 --- a/node_modules/discord.js/src/client/ClientDataManager.js +++ /dev/null @@ -1,129 +0,0 @@ -const Constants = require('../util/Constants'); -const cloneObject = require('../util/CloneObject'); -const Guild = require('../structures/Guild'); -const User = require('../structures/User'); -const DMChannel = require('../structures/DMChannel'); -const Emoji = require('../structures/Emoji'); -const TextChannel = require('../structures/TextChannel'); -const VoiceChannel = require('../structures/VoiceChannel'); -const GuildChannel = require('../structures/GuildChannel'); -const GroupDMChannel = require('../structures/GroupDMChannel'); - -class ClientDataManager { - constructor(client) { - this.client = client; - } - - get pastReady() { - return this.client.ws.status === Constants.Status.READY; - } - - newGuild(data) { - const already = this.client.guilds.has(data.id); - const guild = new Guild(this.client, data); - this.client.guilds.set(guild.id, guild); - if (this.pastReady && !already) { - /** - * Emitted whenever the client joins a guild. - * @event Client#guildCreate - * @param {Guild} guild The created guild - */ - if (this.client.options.fetchAllMembers) { - guild.fetchMembers().then(() => { this.client.emit(Constants.Events.GUILD_CREATE, guild); }); - } else { - this.client.emit(Constants.Events.GUILD_CREATE, guild); - } - } - - return guild; - } - - newUser(data) { - if (this.client.users.has(data.id)) return this.client.users.get(data.id); - const user = new User(this.client, data); - this.client.users.set(user.id, user); - return user; - } - - newChannel(data, guild) { - const already = this.client.channels.has(data.id); - let channel; - if (data.type === Constants.ChannelTypes.DM) { - channel = new DMChannel(this.client, data); - } else if (data.type === Constants.ChannelTypes.groupDM) { - channel = new GroupDMChannel(this.client, data); - } else { - guild = guild || this.client.guilds.get(data.guild_id); - if (guild) { - if (data.type === Constants.ChannelTypes.text) { - channel = new TextChannel(guild, data); - guild.channels.set(channel.id, channel); - } else if (data.type === Constants.ChannelTypes.voice) { - channel = new VoiceChannel(guild, data); - guild.channels.set(channel.id, channel); - } - } - } - - if (channel) { - if (this.pastReady && !already) this.client.emit(Constants.Events.CHANNEL_CREATE, channel); - this.client.channels.set(channel.id, channel); - return channel; - } - - return null; - } - - newEmoji(data, guild) { - const already = guild.emojis.has(data.id); - if (data && !already) { - let emoji = new Emoji(guild, data); - this.client.emit(Constants.Events.GUILD_EMOJI_CREATE, emoji); - guild.emojis.set(emoji.id, emoji); - return emoji; - } else if (already) { - return guild.emojis.get(data.id); - } - - return null; - } - - killEmoji(emoji) { - if (!(emoji instanceof Emoji && emoji.guild)) return; - this.client.emit(Constants.Events.GUILD_EMOJI_DELETE, emoji); - emoji.guild.emojis.delete(emoji.id); - } - - killGuild(guild) { - const already = this.client.guilds.has(guild.id); - this.client.guilds.delete(guild.id); - if (already && this.pastReady) this.client.emit(Constants.Events.GUILD_DELETE, guild); - } - - killUser(user) { - this.client.users.delete(user.id); - } - - killChannel(channel) { - this.client.channels.delete(channel.id); - if (channel instanceof GuildChannel) channel.guild.channels.delete(channel.id); - } - - updateGuild(currentGuild, newData) { - const oldGuild = cloneObject(currentGuild); - currentGuild.setup(newData); - if (this.pastReady) this.client.emit(Constants.Events.GUILD_UPDATE, oldGuild, currentGuild); - } - - updateChannel(currentChannel, newData) { - currentChannel.setup(newData); - } - - updateEmoji(currentEmoji, newData) { - const oldEmoji = cloneObject(currentEmoji); - currentEmoji.setup(newData); - this.client.emit(Constants.Events.GUILD_EMOJI_UPDATE, oldEmoji, currentEmoji); - } -} - -module.exports = ClientDataManager; diff --git a/node_modules/discord.js/src/client/ClientDataResolver.js b/node_modules/discord.js/src/client/ClientDataResolver.js deleted file mode 100644 index d38fb7c..0000000 --- a/node_modules/discord.js/src/client/ClientDataResolver.js +++ /dev/null @@ -1,309 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const request = require('superagent'); - -const Constants = require('../util/Constants'); -const convertArrayBuffer = require('../util/ConvertArrayBuffer'); -const User = require('../structures/User'); -const Message = require('../structures/Message'); -const Guild = require('../structures/Guild'); -const Channel = require('../structures/Channel'); -const GuildMember = require('../structures/GuildMember'); -const Emoji = require('../structures/Emoji'); -const ReactionEmoji = require('../structures/ReactionEmoji'); - -/** - * The DataResolver identifies different objects and tries to resolve a specific piece of information from them, e.g. - * extracting a User from a Message object. - * @private - */ -class ClientDataResolver { - /** - * @param {Client} client The client the resolver is for - */ - constructor(client) { - this.client = client; - } - - /** - * Data that resolves to give a User object. This can be: - * * A User object - * * A user ID - * * A Message object (resolves to the message author) - * * A Guild object (owner of the guild) - * * A GuildMember object - * @typedef {User|string|Message|Guild|GuildMember} UserResolvable - */ - - /** - * Resolves a UserResolvable to a User object - * @param {UserResolvable} user The UserResolvable to identify - * @returns {?User} - */ - resolveUser(user) { - if (user instanceof User) return user; - if (typeof user === 'string') return this.client.users.get(user) || null; - if (user instanceof GuildMember) return user.user; - if (user instanceof Message) return user.author; - if (user instanceof Guild) return user.owner; - return null; - } - - /** - * Resolves a UserResolvable to a user ID string - * @param {UserResolvable} user The UserResolvable to identify - * @returns {?string} - */ - resolveUserID(user) { - if (user instanceof User || user instanceof GuildMember) return user.id; - if (typeof user === 'string') return user || null; - if (user instanceof Message) return user.author.id; - if (user instanceof Guild) return user.ownerID; - return null; - } - - /** - * Data that resolves to give a Guild object. This can be: - * * A Guild object - * * A Guild ID - * @typedef {Guild|string} GuildResolvable - */ - - /** - * Resolves a GuildResolvable to a Guild object - * @param {GuildResolvable} guild The GuildResolvable to identify - * @returns {?Guild} - */ - resolveGuild(guild) { - if (guild instanceof Guild) return guild; - if (typeof guild === 'string') return this.client.guilds.get(guild) || null; - return null; - } - - /** - * Data that resolves to give a GuildMember object. This can be: - * * A GuildMember object - * * A User object - * @typedef {Guild} GuildMemberResolvable - */ - - /** - * Resolves a GuildMemberResolvable to a GuildMember object - * @param {GuildResolvable} guild The guild that the member is part of - * @param {UserResolvable} user The user that is part of the guild - * @returns {?GuildMember} - */ - resolveGuildMember(guild, user) { - if (user instanceof GuildMember) return user; - guild = this.resolveGuild(guild); - user = this.resolveUser(user); - if (!guild || !user) return null; - return guild.members.get(user.id) || null; - } - - /** - * Data that can be resolved to give a Channel. This can be: - * * A Channel object - * * A Message object (the channel the message was sent in) - * * A Guild object (the #general channel) - * * A channel ID - * @typedef {Channel|Guild|Message|string} ChannelResolvable - */ - - /** - * Resolves a ChannelResolvable to a Channel object - * @param {ChannelResolvable} channel The channel resolvable to resolve - * @returns {?Channel} - */ - resolveChannel(channel) { - if (channel instanceof Channel) return channel; - if (channel instanceof Message) return channel.channel; - if (channel instanceof Guild) return channel.channels.get(channel.id) || null; - if (typeof channel === 'string') return this.client.channels.get(channel) || null; - return null; - } - - /** - * Data that can be resolved to give an invite code. This can be: - * * An invite code - * * An invite URL - * @typedef {string} InviteResolvable - */ - - /** - * Resolves InviteResolvable to an invite code - * @param {InviteResolvable} data The invite resolvable to resolve - * @returns {string} - */ - resolveInviteCode(data) { - const inviteRegex = /discord(?:app)?\.(?:gg|com\/invite)\/([a-z0-9]{5})/i; - const match = inviteRegex.exec(data); - if (match && match[1]) return match[1]; - return data; - } - - /** - * Data that can be resolved to give a permission number. This can be: - * * A string - * * A permission number - * - * Possible strings: - * ```js - * [ - * "CREATE_INSTANT_INVITE", - * "KICK_MEMBERS", - * "BAN_MEMBERS", - * "ADMINISTRATOR", - * "MANAGE_CHANNELS", - * "MANAGE_GUILD", - * "ADD_REACTIONS", // add reactions to messages - * "READ_MESSAGES", - * "SEND_MESSAGES", - * "SEND_TTS_MESSAGES", - * "MANAGE_MESSAGES", - * "EMBED_LINKS", - * "ATTACH_FILES", - * "READ_MESSAGE_HISTORY", - * "MENTION_EVERYONE", - * "EXTERNAL_EMOJIS", // use external emojis - * "CONNECT", // connect to voice - * "SPEAK", // speak on voice - * "MUTE_MEMBERS", // globally mute members on voice - * "DEAFEN_MEMBERS", // globally deafen members on voice - * "MOVE_MEMBERS", // move member's voice channels - * "USE_VAD", // use voice activity detection - * "CHANGE_NICKNAME", - * "MANAGE_NICKNAMES", // change nicknames of others - * "MANAGE_ROLES_OR_PERMISSIONS", - * "MANAGE_WEBHOOKS", - * "MANAGE_EMOJIS" - * ] - * ``` - * @typedef {string|number} PermissionResolvable - */ - - /** - * Resolves a PermissionResolvable to a permission number - * @param {PermissionResolvable} permission The permission resolvable to resolve - * @returns {number} - */ - resolvePermission(permission) { - if (typeof permission === 'string') permission = Constants.PermissionFlags[permission]; - if (typeof permission !== 'number' || permission < 1) throw new Error(Constants.Errors.NOT_A_PERMISSION); - return permission; - } - - /** - * Turn an array of permissions into a valid Discord permission bitfield - * @param {PermissionResolvable[]} permissions Permissions to resolve together - * @returns {number} - */ - resolvePermissions(permissions) { - let bitfield = 0; - for (const permission of permissions) bitfield |= this.resolvePermission(permission); - return bitfield; - } - - /** - * Data that can be resolved to give a string. This can be: - * * A string - * * An array (joined with a new line delimiter to give a string) - * * Any value - * @typedef {string|Array|*} StringResolvable - */ - - /** - * Resolves a StringResolvable to a string - * @param {StringResolvable} data The string resolvable to resolve - * @returns {string} - */ - resolveString(data) { - if (typeof data === 'string') return data; - if (data instanceof Array) return data.join('\n'); - return String(data); - } - - /** - * Data that resolves to give a Base64 string, typically for image uploading. This can be: - * * A Buffer - * * A base64 string - * @typedef {Buffer|string} Base64Resolvable - */ - - /** - * Resolves a Base64Resolvable to a Base 64 image - * @param {Base64Resolvable} data The base 64 resolvable you want to resolve - * @returns {?string} - */ - resolveBase64(data) { - if (data instanceof Buffer) return `data:image/jpg;base64,${data.toString('base64')}`; - return data; - } - - /** - * Data that can be resolved to give a Buffer. This can be: - * * A Buffer - * * The path to a local file - * * A URL - * @typedef {string|Buffer} BufferResolvable - */ - - /** - * Resolves a BufferResolvable to a Buffer - * @param {BufferResolvable} resource The buffer resolvable to resolve - * @returns {Promise<Buffer>} - */ - resolveBuffer(resource) { - if (resource instanceof Buffer) return Promise.resolve(resource); - if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertArrayBuffer(resource)); - - if (typeof resource === 'string') { - return new Promise((resolve, reject) => { - if (/^https?:\/\//.test(resource)) { - const req = request.get(resource).set('Content-Type', 'blob'); - if (this.client.browser) req.responseType('arraybuffer'); - req.end((err, res) => { - if (err) return reject(err); - if (this.client.browser) return resolve(convertArrayBuffer(res.xhr.response)); - if (!(res.body instanceof Buffer)) return reject(new TypeError('The response body isn\'t a Buffer.')); - return resolve(res.body); - }); - } else { - const file = path.resolve(resource); - fs.stat(file, (err, stats) => { - if (err) reject(err); - if (!stats || !stats.isFile()) throw new Error(`The file could not be found: ${file}`); - fs.readFile(file, (err2, data) => { - if (err2) reject(err2); else resolve(data); - }); - }); - } - }); - } - - return Promise.reject(new TypeError('The resource must be a string or Buffer.')); - } - - /** - * Data that can be resolved to give an emoji identifier. This can be: - * * A string - * * An Emoji - * * A ReactionEmoji - * @typedef {string|Emoji|ReactionEmoji} EmojiIdentifierResolvable - */ - - /** - * Resolves an EmojiResolvable to an emoji identifier - * @param {EmojiIdentifierResolvable} emoji The emoji resolvable to resolve - * @returns {string} - */ - resolveEmojiIdentifier(emoji) { - if (emoji instanceof Emoji || emoji instanceof ReactionEmoji) return emoji.identifier; - if (typeof emoji === 'string') { - if (!emoji.includes('%')) return encodeURIComponent(emoji); - } - return null; - } -} - -module.exports = ClientDataResolver; diff --git a/node_modules/discord.js/src/client/ClientManager.js b/node_modules/discord.js/src/client/ClientManager.js deleted file mode 100644 index 0cfbbfd..0000000 --- a/node_modules/discord.js/src/client/ClientManager.js +++ /dev/null @@ -1,67 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * Manages the State and Background Tasks of the Client - * @private - */ -class ClientManager { - constructor(client) { - /** - * The Client that instantiated this Manager - * @type {Client} - */ - this.client = client; - - /** - * The heartbeat interval, null if not yet set - * @type {?number} - */ - this.heartbeatInterval = null; - } - - /** - * Connects the Client to the WebSocket - * @param {string} token The authorization token - * @param {Function} resolve Function to run when connection is successful - * @param {Function} reject Function to run when connection fails - */ - connectToWebSocket(token, resolve, reject) { - this.client.emit(Constants.Events.DEBUG, `Authenticated using token ${token}`); - this.client.token = token; - const timeout = this.client.setTimeout(() => reject(new Error(Constants.Errors.TOOK_TOO_LONG)), 1000 * 300); - this.client.rest.methods.getGateway().then(gateway => { - this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`); - this.client.ws.connect(gateway); - this.client.ws.once('close', event => { - if (event.code === 4004) reject(new Error(Constants.Errors.BAD_LOGIN)); - if (event.code === 4010) reject(new Error(Constants.Errors.INVALID_SHARD)); - }); - this.client.once(Constants.Events.READY, () => { - resolve(token); - this.client.clearTimeout(timeout); - }); - }, reject); - } - - /** - * Sets up a keep-alive interval to keep the Client's connection valid - * @param {number} time The interval in milliseconds at which heartbeat packets should be sent - */ - setupKeepAlive(time) { - this.heartbeatInterval = this.client.setInterval(() => this.client.ws.heartbeat(true), time); - } - - destroy() { - this.client.ws.destroy(); - if (this.client.user.bot) { - this.client.token = null; - return Promise.resolve(); - } else { - return this.client.rest.methods.logout().then(() => { - this.client.token = null; - }); - } - } -} - -module.exports = ClientManager; diff --git a/node_modules/discord.js/src/client/WebhookClient.js b/node_modules/discord.js/src/client/WebhookClient.js deleted file mode 100644 index 68a8a94..0000000 --- a/node_modules/discord.js/src/client/WebhookClient.js +++ /dev/null @@ -1,46 +0,0 @@ -const Webhook = require('../structures/Webhook'); -const RESTManager = require('./rest/RESTManager'); -const ClientDataResolver = require('./ClientDataResolver'); -const mergeDefault = require('../util/MergeDefault'); -const Constants = require('../util/Constants'); - -/** - * The Webhook Client - * @extends {Webhook} - */ -class WebhookClient extends Webhook { - /** - * @param {string} id The id of the webhook. - * @param {string} token the token of the webhook. - * @param {ClientOptions} [options] Options for the client - * @example - * // create a new webhook and send a message - * let hook = new Discord.WebhookClient('1234', 'abcdef') - * hook.sendMessage('This will send a message').catch(console.error) - */ - constructor(id, token, options) { - super(null, id, token); - - /** - * The options the client was instantiated with - * @type {ClientOptions} - */ - this.options = mergeDefault(Constants.DefaultOptions, options); - - /** - * The REST manager of the client - * @type {RESTManager} - * @private - */ - this.rest = new RESTManager(this); - - /** - * The Data Resolver of the Client - * @type {ClientDataResolver} - * @private - */ - this.resolver = new ClientDataResolver(this); - } -} - -module.exports = WebhookClient; diff --git a/node_modules/discord.js/src/client/actions/Action.js b/node_modules/discord.js/src/client/actions/Action.js deleted file mode 100644 index 8fdadc9..0000000 --- a/node_modules/discord.js/src/client/actions/Action.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - -ABOUT ACTIONS - -Actions are similar to WebSocket Packet Handlers, but since introducing -the REST API methods, in order to prevent rewriting code to handle data, -"actions" have been introduced. They're basically what Packet Handlers -used to be but they're strictly for manipulating data and making sure -that WebSocket events don't clash with REST methods. - -*/ - -class GenericAction { - constructor(client) { - this.client = client; - } - - handle(data) { - return data; - } -} - -module.exports = GenericAction; diff --git a/node_modules/discord.js/src/client/actions/ActionsManager.js b/node_modules/discord.js/src/client/actions/ActionsManager.js deleted file mode 100644 index ac95aa7..0000000 --- a/node_modules/discord.js/src/client/actions/ActionsManager.js +++ /dev/null @@ -1,38 +0,0 @@ -class ActionsManager { - constructor(client) { - this.client = client; - - this.register(require('./MessageCreate')); - this.register(require('./MessageDelete')); - this.register(require('./MessageDeleteBulk')); - this.register(require('./MessageUpdate')); - this.register(require('./MessageReactionAdd')); - this.register(require('./MessageReactionRemove')); - this.register(require('./MessageReactionRemoveAll')); - this.register(require('./ChannelCreate')); - this.register(require('./ChannelDelete')); - this.register(require('./ChannelUpdate')); - this.register(require('./GuildDelete')); - this.register(require('./GuildUpdate')); - this.register(require('./GuildMemberGet')); - this.register(require('./GuildMemberRemove')); - this.register(require('./GuildBanRemove')); - this.register(require('./GuildRoleCreate')); - this.register(require('./GuildRoleDelete')); - this.register(require('./GuildRoleUpdate')); - this.register(require('./UserGet')); - this.register(require('./UserUpdate')); - this.register(require('./UserNoteUpdate')); - this.register(require('./GuildSync')); - this.register(require('./GuildEmojiCreate')); - this.register(require('./GuildEmojiDelete')); - this.register(require('./GuildEmojiUpdate')); - this.register(require('./GuildRolesPositionUpdate')); - } - - register(Action) { - this[Action.name.replace(/Action$/, '')] = new Action(this.client); - } -} - -module.exports = ActionsManager; diff --git a/node_modules/discord.js/src/client/actions/ChannelCreate.js b/node_modules/discord.js/src/client/actions/ChannelCreate.js deleted file mode 100644 index dc47041..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelCreate.js +++ /dev/null @@ -1,13 +0,0 @@ -const Action = require('./Action'); - -class ChannelCreateAction extends Action { - handle(data) { - const client = this.client; - const channel = client.dataManager.newChannel(data); - return { - channel, - }; - } -} - -module.exports = ChannelCreateAction; diff --git a/node_modules/discord.js/src/client/actions/ChannelDelete.js b/node_modules/discord.js/src/client/actions/ChannelDelete.js deleted file mode 100644 index 7b847ef..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelDelete.js +++ /dev/null @@ -1,31 +0,0 @@ -const Action = require('./Action'); - -class ChannelDeleteAction extends Action { - constructor(client) { - super(client); - this.deleted = new Map(); - } - - handle(data) { - const client = this.client; - - let channel = client.channels.get(data.id); - if (channel) { - client.dataManager.killChannel(channel); - this.deleted.set(channel.id, channel); - this.scheduleForDeletion(channel.id); - } else { - channel = this.deleted.get(data.id) || null; - } - - return { - channel, - }; - } - - scheduleForDeletion(id) { - this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout); - } -} - -module.exports = ChannelDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/ChannelUpdate.js b/node_modules/discord.js/src/client/actions/ChannelUpdate.js deleted file mode 100644 index df50ed4..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelUpdate.js +++ /dev/null @@ -1,34 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const cloneObject = require('../../util/CloneObject'); - -class ChannelUpdateAction extends Action { - handle(data) { - const client = this.client; - - const channel = client.channels.get(data.id); - if (channel) { - const oldChannel = cloneObject(channel); - channel.setup(data); - client.emit(Constants.Events.CHANNEL_UPDATE, oldChannel, channel); - return { - old: oldChannel, - updated: channel, - }; - } - - return { - old: null, - updated: null, - }; - } -} - -/** - * Emitted whenever a channel is updated - e.g. name change, topic change. - * @event Client#channelUpdate - * @param {Channel} oldChannel The channel before the update - * @param {Channel} newChannel The channel after the update - */ - -module.exports = ChannelUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildBanRemove.js b/node_modules/discord.js/src/client/actions/GuildBanRemove.js deleted file mode 100644 index 0276a52..0000000 --- a/node_modules/discord.js/src/client/actions/GuildBanRemove.js +++ /dev/null @@ -1,13 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class GuildBanRemove extends Action { - handle(data) { - const client = this.client; - const guild = client.guilds.get(data.guild_id); - const user = client.dataManager.newUser(data.user); - if (guild && user) client.emit(Constants.Events.GUILD_BAN_REMOVE, guild, user); - } -} - -module.exports = GuildBanRemove; diff --git a/node_modules/discord.js/src/client/actions/GuildDelete.js b/node_modules/discord.js/src/client/actions/GuildDelete.js deleted file mode 100644 index 1214263..0000000 --- a/node_modules/discord.js/src/client/actions/GuildDelete.js +++ /dev/null @@ -1,51 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class GuildDeleteAction extends Action { - constructor(client) { - super(client); - this.deleted = new Map(); - } - - handle(data) { - const client = this.client; - - let guild = client.guilds.get(data.id); - if (guild) { - if (guild.available && data.unavailable) { - // guild is unavailable - guild.available = false; - client.emit(Constants.Events.GUILD_UNAVAILABLE, guild); - - // stops the GuildDelete packet thinking a guild was actually deleted, - // handles emitting of event itself - return { - guild: null, - }; - } - - // delete guild - client.guilds.delete(guild.id); - this.deleted.set(guild.id, guild); - this.scheduleForDeletion(guild.id); - } else { - guild = this.deleted.get(data.id) || null; - } - - return { - guild, - }; - } - - scheduleForDeletion(id) { - this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout); - } -} - -/** - * Emitted whenever a guild becomes unavailable, likely due to a server outage. - * @event Client#guildUnavailable - * @param {Guild} guild The guild that has become unavailable. - */ - -module.exports = GuildDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js b/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js deleted file mode 100644 index 5df1ced..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js +++ /dev/null @@ -1,18 +0,0 @@ -const Action = require('./Action'); - -class GuildEmojiCreateAction extends Action { - handle(guild, createdEmoji) { - const client = this.client; - const emoji = client.dataManager.newEmoji(createdEmoji, guild); - return { - emoji, - }; - } -} - -/** - * Emitted whenever a custom emoji is created in a guild - * @event Client#emojiCreate - * @param {Emoji} emoji The emoji that was created. - */ -module.exports = GuildEmojiCreateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js b/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js deleted file mode 100644 index 8cfa205..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojiDelete.js +++ /dev/null @@ -1,18 +0,0 @@ -const Action = require('./Action'); - -class GuildEmojiDeleteAction extends Action { - handle(emoji) { - const client = this.client; - client.dataManager.killEmoji(emoji); - return { - emoji, - }; - } -} - -/** - * Emitted whenever a custom guild emoji is deleted - * @event Client#emojiDelete - * @param {Emoji} emoji The emoji that was deleted. - */ -module.exports = GuildEmojiDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js b/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js deleted file mode 100644 index 94bfa24..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js +++ /dev/null @@ -1,15 +0,0 @@ -const Action = require('./Action'); - -class GuildEmojiUpdateAction extends Action { - handle(oldEmoji, newEmoji) { - this.client.dataManager.updateEmoji(oldEmoji, newEmoji); - } -} - -/** - * Emitted whenever a custom guild emoji is updated - * @event Client#emojiUpdate - * @param {Emoji} oldEmoji The old emoji - * @param {Emoji} newEmoji The new emoji - */ -module.exports = GuildEmojiUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildMemberGet.js b/node_modules/discord.js/src/client/actions/GuildMemberGet.js deleted file mode 100644 index b00fa0f..0000000 --- a/node_modules/discord.js/src/client/actions/GuildMemberGet.js +++ /dev/null @@ -1,12 +0,0 @@ -const Action = require('./Action'); - -class GuildMemberGetAction extends Action { - handle(guild, data) { - const member = guild._addMember(data, false); - return { - member, - }; - } -} - -module.exports = GuildMemberGetAction; diff --git a/node_modules/discord.js/src/client/actions/GuildMemberRemove.js b/node_modules/discord.js/src/client/actions/GuildMemberRemove.js deleted file mode 100644 index d68b8b5..0000000 --- a/node_modules/discord.js/src/client/actions/GuildMemberRemove.js +++ /dev/null @@ -1,49 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class GuildMemberRemoveAction extends Action { - constructor(client) { - super(client); - this.deleted = new Map(); - } - - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - let member = guild.members.get(data.user.id); - if (member) { - guild.memberCount--; - guild._removeMember(member); - this.deleted.set(guild.id + data.user.id, member); - if (client.status === Constants.Status.READY) client.emit(Constants.Events.GUILD_MEMBER_REMOVE, member); - this.scheduleForDeletion(guild.id, data.user.id); - } else { - member = this.deleted.get(guild.id + data.user.id) || null; - } - - return { - guild, - member, - }; - } - - return { - guild, - member: null, - }; - } - - scheduleForDeletion(guildID, userID) { - this.client.setTimeout(() => this.deleted.delete(guildID + userID), this.client.options.restWsBridgeTimeout); - } -} - -/** - * Emitted whenever a member leaves a guild, or is kicked. - * @event Client#guildMemberRemove - * @param {GuildMember} member The member that has left/been kicked from the guild. - */ - -module.exports = GuildMemberRemoveAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleCreate.js b/node_modules/discord.js/src/client/actions/GuildRoleCreate.js deleted file mode 100644 index 82ea19a..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRoleCreate.js +++ /dev/null @@ -1,32 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const Role = require('../../structures/Role'); - -class GuildRoleCreate extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - const already = guild.roles.has(data.role.id); - const role = new Role(guild, data.role); - guild.roles.set(role.id, role); - if (!already) client.emit(Constants.Events.GUILD_ROLE_CREATE, role); - return { - role, - }; - } - - return { - role: null, - }; - } -} - -/** - * Emitted whenever a role is created. - * @event Client#roleCreate - * @param {Role} role The role that was created. - */ - -module.exports = GuildRoleCreate; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleDelete.js b/node_modules/discord.js/src/client/actions/GuildRoleDelete.js deleted file mode 100644 index eeaa1e9..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRoleDelete.js +++ /dev/null @@ -1,46 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class GuildRoleDeleteAction extends Action { - constructor(client) { - super(client); - this.deleted = new Map(); - } - - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - let role = guild.roles.get(data.role_id); - if (role) { - guild.roles.delete(data.role_id); - this.deleted.set(guild.id + data.role_id, role); - this.scheduleForDeletion(guild.id, data.role_id); - client.emit(Constants.Events.GUILD_ROLE_DELETE, role); - } else { - role = this.deleted.get(guild.id + data.role_id) || null; - } - - return { - role, - }; - } - - return { - role: null, - }; - } - - scheduleForDeletion(guildID, roleID) { - this.client.setTimeout(() => this.deleted.delete(guildID + roleID), this.client.options.restWsBridgeTimeout); - } -} - -/** - * Emitted whenever a guild role is deleted. - * @event Client#roleDelete - * @param {Role} role The role that was deleted. - */ - -module.exports = GuildRoleDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js b/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js deleted file mode 100644 index 8270517..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRoleUpdate.js +++ /dev/null @@ -1,41 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const cloneObject = require('../../util/CloneObject'); - -class GuildRoleUpdateAction extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - const roleData = data.role; - let oldRole = null; - - const role = guild.roles.get(roleData.id); - if (role) { - oldRole = cloneObject(role); - role.setup(data.role); - client.emit(Constants.Events.GUILD_ROLE_UPDATE, oldRole, role); - } - - return { - old: oldRole, - updated: role, - }; - } - - return { - old: null, - updated: null, - }; - } -} - -/** - * Emitted whenever a guild role is updated. - * @event Client#roleUpdate - * @param {Role} oldRole The role before the update. - * @param {Role} newRole The role after the update. - */ - -module.exports = GuildRoleUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js b/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js deleted file mode 100644 index a95c923..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js +++ /dev/null @@ -1,23 +0,0 @@ -const Action = require('./Action'); - -class GuildRolesPositionUpdate extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - for (const partialRole of data.roles) { - const role = guild.roles.get(partialRole.id); - if (role) { - role.position = partialRole.position; - } - } - } - - return { - guild, - }; - } -} - -module.exports = GuildRolesPositionUpdate; diff --git a/node_modules/discord.js/src/client/actions/GuildSync.js b/node_modules/discord.js/src/client/actions/GuildSync.js deleted file mode 100644 index 7b94ec8..0000000 --- a/node_modules/discord.js/src/client/actions/GuildSync.js +++ /dev/null @@ -1,27 +0,0 @@ -const Action = require('./Action'); - -class GuildSync extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.id); - if (guild) { - data.presences = data.presences || []; - for (const presence of data.presences) { - guild._setPresence(presence.user.id, presence); - } - - data.members = data.members || []; - for (const syncMember of data.members) { - const member = guild.members.get(syncMember.user.id); - if (member) { - guild._updateMember(member, syncMember); - } else { - guild._addMember(syncMember, false); - } - } - } - } -} - -module.exports = GuildSync; diff --git a/node_modules/discord.js/src/client/actions/GuildUpdate.js b/node_modules/discord.js/src/client/actions/GuildUpdate.js deleted file mode 100644 index efda7f7..0000000 --- a/node_modules/discord.js/src/client/actions/GuildUpdate.js +++ /dev/null @@ -1,34 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const cloneObject = require('../../util/CloneObject'); - -class GuildUpdateAction extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.id); - if (guild) { - const oldGuild = cloneObject(guild); - guild.setup(data); - client.emit(Constants.Events.GUILD_UPDATE, oldGuild, guild); - return { - old: oldGuild, - updated: guild, - }; - } - - return { - old: null, - updated: null, - }; - } -} - -/** - * Emitted whenever a guild is updated - e.g. name change. - * @event Client#guildUpdate - * @param {Guild} oldGuild The guild before the update. - * @param {Guild} newGuild The guild after the update. - */ - -module.exports = GuildUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/MessageCreate.js b/node_modules/discord.js/src/client/actions/MessageCreate.js deleted file mode 100644 index 00fc1e9..0000000 --- a/node_modules/discord.js/src/client/actions/MessageCreate.js +++ /dev/null @@ -1,40 +0,0 @@ -const Action = require('./Action'); -const Message = require('../../structures/Message'); - -class MessageCreateAction extends Action { - handle(data) { - const client = this.client; - - const channel = client.channels.get((data instanceof Array ? data[0] : data).channel_id); - const user = client.users.get((data instanceof Array ? data[0] : data).author.id); - if (channel) { - const member = channel.guild ? channel.guild.member(user) : null; - if (data instanceof Array) { - const messages = new Array(data.length); - for (let i = 0; i < data.length; i++) { - messages[i] = channel._cacheMessage(new Message(channel, data[i], client)); - } - channel.lastMessageID = messages[messages.length - 1].id; - if (user) user.lastMessageID = messages[messages.length - 1].id; - if (member) member.lastMessageID = messages[messages.length - 1].id; - return { - messages, - }; - } else { - const message = channel._cacheMessage(new Message(channel, data, client)); - channel.lastMessageID = data.id; - if (user) user.lastMessageID = data.id; - if (member) member.lastMessageID = data.id; - return { - message, - }; - } - } - - return { - message: null, - }; - } -} - -module.exports = MessageCreateAction; diff --git a/node_modules/discord.js/src/client/actions/MessageDelete.js b/node_modules/discord.js/src/client/actions/MessageDelete.js deleted file mode 100644 index beb8050..0000000 --- a/node_modules/discord.js/src/client/actions/MessageDelete.js +++ /dev/null @@ -1,40 +0,0 @@ -const Action = require('./Action'); - -class MessageDeleteAction extends Action { - constructor(client) { - super(client); - this.deleted = new Map(); - } - - handle(data) { - const client = this.client; - - const channel = client.channels.get(data.channel_id); - if (channel) { - let message = channel.messages.get(data.id); - - if (message) { - channel.messages.delete(message.id); - this.deleted.set(channel.id + message.id, message); - this.scheduleForDeletion(channel.id, message.id); - } else { - message = this.deleted.get(channel.id + data.id) || null; - } - - return { - message, - }; - } - - return { - message: null, - }; - } - - scheduleForDeletion(channelID, messageID) { - this.client.setTimeout(() => this.deleted.delete(channelID + messageID), - this.client.options.restWsBridgeTimeout); - } -} - -module.exports = MessageDeleteAction; diff --git a/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js b/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js deleted file mode 100644 index 6a12ef1..0000000 --- a/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js +++ /dev/null @@ -1,24 +0,0 @@ -const Action = require('./Action'); -const Collection = require('../../util/Collection'); -const Constants = require('../../util/Constants'); - -class MessageDeleteBulkAction extends Action { - handle(data) { - const client = this.client; - const channel = client.channels.get(data.channel_id); - - const ids = data.ids; - const messages = new Collection(); - for (const id of ids) { - const message = channel.messages.get(id); - if (message) messages.set(message.id, message); - } - - if (messages.size > 0) client.emit(Constants.Events.MESSAGE_BULK_DELETE, messages); - return { - messages, - }; - } -} - -module.exports = MessageDeleteBulkAction; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionAdd.js b/node_modules/discord.js/src/client/actions/MessageReactionAdd.js deleted file mode 100644 index f57ec2e..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionAdd.js +++ /dev/null @@ -1,43 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -/* -{ user_id: 'id', - message_id: 'id', - emoji: { name: '�', id: null }, - channel_id: 'id' } } -*/ - -class MessageReactionAdd extends Action { - handle(data) { - const user = this.client.users.get(data.user_id); - if (!user) return false; - - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - - const message = channel.messages.get(data.message_id); - if (!message) return false; - - if (!data.emoji) return false; - - const reaction = message._addReaction(data.emoji, user); - - if (reaction) { - this.client.emit(Constants.Events.MESSAGE_REACTION_ADD, reaction, user); - } - - return { - message, - reaction, - user, - }; - } -} -/** - * Emitted whenever a reaction is added to a message. - * @event Client#messageReactionAdd - * @param {MessageReaction} messageReaction The reaction object. - * @param {User} user The user that applied the emoji or reaction emoji. - */ -module.exports = MessageReactionAdd; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemove.js b/node_modules/discord.js/src/client/actions/MessageReactionRemove.js deleted file mode 100644 index 98a958d..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionRemove.js +++ /dev/null @@ -1,43 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -/* -{ user_id: 'id', - message_id: 'id', - emoji: { name: '�', id: null }, - channel_id: 'id' } } -*/ - -class MessageReactionRemove extends Action { - handle(data) { - const user = this.client.users.get(data.user_id); - if (!user) return false; - - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - - const message = channel.messages.get(data.message_id); - if (!message) return false; - - if (!data.emoji) return false; - - const reaction = message._removeReaction(data.emoji, user); - - if (reaction) { - this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE, reaction, user); - } - - return { - message, - reaction, - user, - }; - } -} -/** - * Emitted whenever a reaction is removed from a message. - * @event Client#messageReactionRemove - * @param {MessageReaction} messageReaction The reaction object. - * @param {User} user The user that removed the emoji or reaction emoji. - */ -module.exports = MessageReactionRemove; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js b/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js deleted file mode 100644 index f35b785..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionRemoveAll.js +++ /dev/null @@ -1,25 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class MessageReactionRemoveAll extends Action { - handle(data) { - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - - const message = channel.messages.get(data.message_id); - if (!message) return false; - - message._clearReactions(); - this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE_ALL, message); - - return { - message, - }; - } -} -/** - * Emitted whenever all reactions are removed from a message. - * @event Client#messageReactionRemoveAll - * @param {MessageReaction} messageReaction The reaction object. - */ -module.exports = MessageReactionRemoveAll; diff --git a/node_modules/discord.js/src/client/actions/MessageUpdate.js b/node_modules/discord.js/src/client/actions/MessageUpdate.js deleted file mode 100644 index a62c332..0000000 --- a/node_modules/discord.js/src/client/actions/MessageUpdate.js +++ /dev/null @@ -1,43 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const cloneObject = require('../../util/CloneObject'); - -class MessageUpdateAction extends Action { - handle(data) { - const client = this.client; - - const channel = client.channels.get(data.channel_id); - if (channel) { - const message = channel.messages.get(data.id); - if (message) { - const oldMessage = cloneObject(message); - message.patch(data); - message._edits.unshift(oldMessage); - client.emit(Constants.Events.MESSAGE_UPDATE, oldMessage, message); - return { - old: oldMessage, - updated: message, - }; - } - - return { - old: message, - updated: message, - }; - } - - return { - old: null, - updated: null, - }; - } -} - -/** - * Emitted whenever a message is updated - e.g. embed or content change. - * @event Client#messageUpdate - * @param {Message} oldMessage The message before the update. - * @param {Message} newMessage The message after the update. - */ - -module.exports = MessageUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/UserGet.js b/node_modules/discord.js/src/client/actions/UserGet.js deleted file mode 100644 index 65e7c95..0000000 --- a/node_modules/discord.js/src/client/actions/UserGet.js +++ /dev/null @@ -1,13 +0,0 @@ -const Action = require('./Action'); - -class UserGetAction extends Action { - handle(data) { - const client = this.client; - const user = client.dataManager.newUser(data); - return { - user, - }; - } -} - -module.exports = UserGetAction; diff --git a/node_modules/discord.js/src/client/actions/UserNoteUpdate.js b/node_modules/discord.js/src/client/actions/UserNoteUpdate.js deleted file mode 100644 index 4c2cc21..0000000 --- a/node_modules/discord.js/src/client/actions/UserNoteUpdate.js +++ /dev/null @@ -1,30 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class UserNoteUpdateAction extends Action { - handle(data) { - const client = this.client; - - const oldNote = client.user.notes.get(data.id); - const note = data.note.length ? data.note : null; - - client.user.notes.set(data.id, note); - - client.emit(Constants.Events.USER_NOTE_UPDATE, data.id, oldNote, note); - - return { - old: oldNote, - updated: note, - }; - } -} - -/** - * Emitted whenever a note is updated. - * @event Client#userNoteUpdate - * @param {User} user The user the note belongs to - * @param {string} oldNote The note content before the update - * @param {string} newNote The note content after the update - */ - -module.exports = UserNoteUpdateAction; diff --git a/node_modules/discord.js/src/client/actions/UserUpdate.js b/node_modules/discord.js/src/client/actions/UserUpdate.js deleted file mode 100644 index b361eca..0000000 --- a/node_modules/discord.js/src/client/actions/UserUpdate.js +++ /dev/null @@ -1,33 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); -const cloneObject = require('../../util/CloneObject'); - -class UserUpdateAction extends Action { - handle(data) { - const client = this.client; - - if (client.user) { - if (client.user.equals(data)) { - return { - old: client.user, - updated: client.user, - }; - } - - const oldUser = cloneObject(client.user); - client.user.patch(data); - client.emit(Constants.Events.USER_UPDATE, oldUser, client.user); - return { - old: oldUser, - updated: client.user, - }; - } - - return { - old: null, - updated: null, - }; - } -} - -module.exports = UserUpdateAction; diff --git a/node_modules/discord.js/src/client/rest/APIRequest.js b/node_modules/discord.js/src/client/rest/APIRequest.js deleted file mode 100644 index 36c2d8f..0000000 --- a/node_modules/discord.js/src/client/rest/APIRequest.js +++ /dev/null @@ -1,49 +0,0 @@ -const request = require('superagent'); -const Constants = require('../../util/Constants'); - -function getRoute(url) { - let route = url.split('?')[0]; - if (route.includes('/channels/') || route.includes('/guilds/')) { - const startInd = route.includes('/channels/') ? route.indexOf('/channels/') : route.indexOf('/guilds/'); - const majorID = route.substring(startInd).split('/')[2]; - route = route.replace(/(\d{8,})/g, ':id').replace(':id', majorID); - } - return route; -} - -class APIRequest { - constructor(rest, method, url, auth, data, file) { - this.rest = rest; - this.method = method; - this.url = url; - this.auth = auth; - this.data = data; - this.file = file; - this.route = getRoute(this.url); - } - - getAuth() { - if (this.rest.client.token && this.rest.client.user && this.rest.client.user.bot) { - return `Bot ${this.rest.client.token}`; - } else if (this.rest.client.token) { - return this.rest.client.token; - } - throw new Error(Constants.Errors.NO_TOKEN); - } - - gen() { - const apiRequest = request[this.method](this.url); - if (this.auth) apiRequest.set('authorization', this.getAuth()); - if (this.file && this.file.file) { - apiRequest.attach('file', this.file.file, this.file.name); - this.data = this.data || {}; - apiRequest.field('payload_json', JSON.stringify(this.data)); - } else if (this.data) { - apiRequest.send(this.data); - } - if (!this.rest.client.browser) apiRequest.set('User-Agent', this.rest.userAgentManager.userAgent); - return apiRequest; - } -} - -module.exports = APIRequest; diff --git a/node_modules/discord.js/src/client/rest/RESTManager.js b/node_modules/discord.js/src/client/rest/RESTManager.js deleted file mode 100644 index ac1ce6e..0000000 --- a/node_modules/discord.js/src/client/rest/RESTManager.js +++ /dev/null @@ -1,51 +0,0 @@ -const UserAgentManager = require('./UserAgentManager'); -const RESTMethods = require('./RESTMethods'); -const SequentialRequestHandler = require('./RequestHandlers/Sequential'); -const BurstRequestHandler = require('./RequestHandlers/Burst'); -const APIRequest = require('./APIRequest'); -const Constants = require('../../util/Constants'); - -class RESTManager { - constructor(client) { - this.client = client; - this.handlers = {}; - this.userAgentManager = new UserAgentManager(this); - this.methods = new RESTMethods(this); - this.rateLimitedEndpoints = {}; - this.globallyRateLimited = false; - } - - push(handler, apiRequest) { - return new Promise((resolve, reject) => { - handler.push({ - request: apiRequest, - resolve, - reject, - }); - }); - } - - getRequestHandler() { - switch (this.client.options.apiRequestMethod) { - case 'sequential': - return SequentialRequestHandler; - case 'burst': - return BurstRequestHandler; - default: - throw new Error(Constants.Errors.INVALID_RATE_LIMIT_METHOD); - } - } - - makeRequest(method, url, auth, data, file) { - const apiRequest = new APIRequest(this, method, url, auth, data, file); - - if (!this.handlers[apiRequest.route]) { - const RequestHandlerType = this.getRequestHandler(); - this.handlers[apiRequest.route] = new RequestHandlerType(this, apiRequest.route); - } - - return this.push(this.handlers[apiRequest.route], apiRequest); - } -} - -module.exports = RESTManager; diff --git a/node_modules/discord.js/src/client/rest/RESTMethods.js b/node_modules/discord.js/src/client/rest/RESTMethods.js deleted file mode 100644 index 7006248..0000000 --- a/node_modules/discord.js/src/client/rest/RESTMethods.js +++ /dev/null @@ -1,653 +0,0 @@ -const Constants = require('../../util/Constants'); -const Collection = require('../../util/Collection'); -const splitMessage = require('../../util/SplitMessage'); -const parseEmoji = require('../../util/ParseEmoji'); -const escapeMarkdown = require('../../util/EscapeMarkdown'); - -const User = require('../../structures/User'); -const GuildMember = require('../../structures/GuildMember'); -const Message = require('../../structures/Message'); -const Role = require('../../structures/Role'); -const Invite = require('../../structures/Invite'); -const Webhook = require('../../structures/Webhook'); -const UserProfile = require('../../structures/UserProfile'); -const ClientOAuth2Application = require('../../structures/ClientOAuth2Application'); - -class RESTMethods { - constructor(restManager) { - this.rest = restManager; - this.client = restManager.client; - } - - login(token = this.client.token) { - return new Promise((resolve, reject) => { - if (typeof token !== 'string') throw new Error(Constants.Errors.INVALID_TOKEN); - token = token.replace(/^Bot\s*/i, ''); - this.client.manager.connectToWebSocket(token, resolve, reject); - }); - } - - logout() { - return this.rest.makeRequest('post', Constants.Endpoints.logout, true, {}); - } - - getGateway() { - return this.rest.makeRequest('get', Constants.Endpoints.gateway, true).then(res => { - this.client.ws.gateway = `${res.url}/?v=${Constants.PROTOCOL_VERSION}`; - return this.client.ws.gateway; - }); - } - - getBotGateway() { - return this.rest.makeRequest('get', Constants.Endpoints.botGateway, true); - } - - sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code } = {}, file = null) { - return new Promise((resolve, reject) => { - if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content); - - if (content) { - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - } - - if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { - content = content.replace(/@(everyone|here)/g, '@\u200b$1'); - } - - if (split) content = splitMessage(content, typeof split === 'object' ? split : {}); - } - - const send = chan => { - if (content instanceof Array) { - const messages = []; - (function sendChunk(list, index) { - const options = index === list.length ? { tts, embed } : { tts }; - chan.send(list[index], options, index === list.length ? file : null).then((message) => { - messages.push(message); - if (index >= list.length) return resolve(messages); - return sendChunk(list, ++index); - }); - }(content, 0)); - } else { - this.rest.makeRequest('post', Constants.Endpoints.channelMessages(chan.id), true, { - content, tts, nonce, embed, - }, file).then(data => resolve(this.client.actions.MessageCreate.handle(data).message), reject); - } - }; - - if (channel instanceof User || channel instanceof GuildMember) { - this.createDM(channel).then(send, reject); - } else { - send(channel); - } - }); - } - - updateMessage(message, content, { embed, code } = {}) { - content = this.client.resolver.resolveString(content); - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - } - return this.rest.makeRequest('patch', Constants.Endpoints.channelMessage(message.channel.id, message.id), true, { - content, embed, - }).then(data => this.client.actions.MessageUpdate.handle(data).updated); - } - - deleteMessage(message) { - return this.rest.makeRequest('del', Constants.Endpoints.channelMessage(message.channel.id, message.id), true) - .then(() => - this.client.actions.MessageDelete.handle({ - id: message.id, - channel_id: message.channel.id, - }).message - ); - } - - bulkDeleteMessages(channel, messages) { - return this.rest.makeRequest('post', `${Constants.Endpoints.channelMessages(channel.id)}/bulk_delete`, true, { - messages, - }).then(() => - this.client.actions.MessageDeleteBulk.handle({ - channel_id: channel.id, - ids: messages, - }).messages - ); - } - - createChannel(guild, channelName, channelType, overwrites) { - if (overwrites instanceof Collection) overwrites = overwrites.array(); - return this.rest.makeRequest('post', Constants.Endpoints.guildChannels(guild.id), true, { - name: channelName, - type: channelType, - permission_overwrites: overwrites, - }).then(data => this.client.actions.ChannelCreate.handle(data).channel); - } - - createDM(recipient) { - const dmChannel = this.getExistingDM(recipient); - if (dmChannel) return Promise.resolve(dmChannel); - return this.rest.makeRequest('post', Constants.Endpoints.userChannels(this.client.user.id), true, { - recipient_id: recipient.id, - }).then(data => this.client.actions.ChannelCreate.handle(data).channel); - } - - getExistingDM(recipient) { - return this.client.channels.find(channel => - channel.recipient && channel.recipient.id === recipient.id - ); - } - - deleteChannel(channel) { - if (channel instanceof User || channel instanceof GuildMember) channel = this.getExistingDM(channel); - if (!channel) return Promise.reject(new Error('No channel to delete.')); - return this.rest.makeRequest('del', Constants.Endpoints.channel(channel.id), true).then(data => { - data.id = channel.id; - return this.client.actions.ChannelDelete.handle(data).channel; - }); - } - - updateChannel(channel, _data) { - const data = {}; - data.name = (_data.name || channel.name).trim(); - data.topic = _data.topic || channel.topic; - data.position = _data.position || channel.position; - data.bitrate = _data.bitrate || channel.bitrate; - data.user_limit = _data.userLimit || channel.userLimit; - return this.rest.makeRequest('patch', Constants.Endpoints.channel(channel.id), true, data).then(newData => - this.client.actions.ChannelUpdate.handle(newData).updated - ); - } - - leaveGuild(guild) { - if (guild.ownerID === this.client.user.id) return Promise.reject(new Error('Guild is owned by the client.')); - return this.rest.makeRequest('del', Constants.Endpoints.meGuild(guild.id), true).then(() => - this.client.actions.GuildDelete.handle({ id: guild.id }).guild - ); - } - - createGuild(options) { - options.icon = this.client.resolver.resolveBase64(options.icon) || null; - options.region = options.region || 'us-central'; - return new Promise((resolve, reject) => { - this.rest.makeRequest('post', Constants.Endpoints.guilds, true, options).then(data => { - if (this.client.guilds.has(data.id)) { - resolve(this.client.guilds.get(data.id)); - return; - } - - const handleGuild = guild => { - if (guild.id === data.id) { - this.client.removeListener('guildCreate', handleGuild); - this.client.clearTimeout(timeout); - resolve(guild); - } - }; - this.client.on('guildCreate', handleGuild); - - const timeout = this.client.setTimeout(() => { - this.client.removeListener('guildCreate', handleGuild); - reject(new Error('Took too long to receive guild data.')); - }, 10000); - }, reject); - }); - } - - // untested but probably will work - deleteGuild(guild) { - return this.rest.makeRequest('del', Constants.Endpoints.guild(guild.id), true).then(() => - this.client.actions.GuildDelete.handle({ id: guild.id }).guild - ); - } - - getUser(userID) { - return this.rest.makeRequest('get', Constants.Endpoints.user(userID), true).then(data => - this.client.actions.UserGet.handle(data).user - ); - } - - updateCurrentUser(_data, password) { - const user = this.client.user; - const data = {}; - data.username = _data.username || user.username; - data.avatar = this.client.resolver.resolveBase64(_data.avatar) || user.avatar; - if (!user.bot) { - data.email = _data.email || user.email; - data.password = password; - if (_data.new_password) data.new_password = _data.newPassword; - } - return this.rest.makeRequest('patch', Constants.Endpoints.me, true, data).then(newData => - this.client.actions.UserUpdate.handle(newData).updated - ); - } - - updateGuild(guild, _data) { - const data = {}; - if (_data.name) data.name = _data.name; - if (_data.region) data.region = _data.region; - if (_data.verificationLevel) data.verification_level = Number(_data.verificationLevel); - if (_data.afkChannel) data.afk_channel_id = this.client.resolver.resolveChannel(_data.afkChannel).id; - if (_data.afkTimeout) data.afk_timeout = Number(_data.afkTimeout); - if (_data.icon) data.icon = this.client.resolver.resolveBase64(_data.icon); - if (_data.owner) data.owner_id = this.client.resolver.resolveUser(_data.owner).id; - if (_data.splash) data.splash = this.client.resolver.resolveBase64(_data.splash); - return this.rest.makeRequest('patch', Constants.Endpoints.guild(guild.id), true, data).then(newData => - this.client.actions.GuildUpdate.handle(newData).updated - ); - } - - kickGuildMember(guild, member) { - return this.rest.makeRequest('del', Constants.Endpoints.guildMember(guild.id, member.id), true).then(() => - this.client.actions.GuildMemberRemove.handle({ - guild_id: guild.id, - user: member.user, - }).member - ); - } - - createGuildRole(guild) { - return this.rest.makeRequest('post', Constants.Endpoints.guildRoles(guild.id), true).then(role => - this.client.actions.GuildRoleCreate.handle({ - guild_id: guild.id, - role, - }).role - ); - } - - deleteGuildRole(role) { - return this.rest.makeRequest('del', Constants.Endpoints.guildRole(role.guild.id, role.id), true).then(() => - this.client.actions.GuildRoleDelete.handle({ - guild_id: role.guild.id, - role_id: role.id, - }).role - ); - } - - setChannelOverwrite(channel, payload) { - return this.rest.makeRequest( - 'put', `${Constants.Endpoints.channelPermissions(channel.id)}/${payload.id}`, true, payload - ); - } - - deletePermissionOverwrites(overwrite) { - return this.rest.makeRequest( - 'del', `${Constants.Endpoints.channelPermissions(overwrite.channel.id)}/${overwrite.id}`, true - ).then(() => overwrite); - } - - getChannelMessages(channel, payload = {}) { - const params = []; - if (payload.limit) params.push(`limit=${payload.limit}`); - if (payload.around) params.push(`around=${payload.around}`); - else if (payload.before) params.push(`before=${payload.before}`); - else if (payload.after) params.push(`after=${payload.after}`); - - let endpoint = Constants.Endpoints.channelMessages(channel.id); - if (params.length > 0) endpoint += `?${params.join('&')}`; - return this.rest.makeRequest('get', endpoint, true); - } - - getChannelMessage(channel, messageID) { - const msg = channel.messages.get(messageID); - if (msg) return Promise.resolve(msg); - return this.rest.makeRequest('get', Constants.Endpoints.channelMessage(channel.id, messageID), true); - } - - getGuildMember(guild, user) { - return this.rest.makeRequest('get', Constants.Endpoints.guildMember(guild.id, user.id), true).then(data => - this.client.actions.GuildMemberGet.handle(guild, data).member - ); - } - - updateGuildMember(member, data) { - if (data.channel) data.channel_id = this.client.resolver.resolveChannel(data.channel).id; - if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role); - - let endpoint = Constants.Endpoints.guildMember(member.guild.id, member.id); - // fix your endpoints, discord ;-; - if (member.id === this.client.user.id) { - const keys = Object.keys(data); - if (keys.length === 1 && keys[0] === 'nick') { - endpoint = Constants.Endpoints.guildMemberNickname(member.guild.id); - } - } - - return this.rest.makeRequest('patch', endpoint, true, data).then(newData => - member.guild._updateMember(member, newData).mem - ); - } - - addMemberRole(member, role) { - return this.rest.makeRequest('put', Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), true) - .then(() => { - if (!member._roles.includes(role.id)) member._roles.push(role.id); - return member; - }); - } - - removeMemberRole(member, role) { - return this.rest.makeRequest( - 'delete', - Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), - true - ).then(() => { - const index = member._roles.indexOf(role.id); - if (index >= 0) member._roles.splice(index, 1); - return member; - }); - } - - sendTyping(channelID) { - return this.rest.makeRequest('post', `${Constants.Endpoints.channel(channelID)}/typing`, true); - } - - banGuildMember(guild, member, deleteDays = 0) { - const id = this.client.resolver.resolveUserID(member); - if (!id) return Promise.reject(new Error('Couldn\'t resolve the user ID to ban.')); - return this.rest.makeRequest( - 'put', `${Constants.Endpoints.guildBans(guild.id)}/${id}?delete-message-days=${deleteDays}`, true, { - 'delete-message-days': deleteDays, - } - ).then(() => { - if (member instanceof GuildMember) return member; - const user = this.client.resolver.resolveUser(id); - if (user) { - member = this.client.resolver.resolveGuildMember(guild, user); - return member || user; - } - return id; - }); - } - - unbanGuildMember(guild, member) { - return new Promise((resolve, reject) => { - const id = this.client.resolver.resolveUserID(member); - if (!id) throw new Error('Couldn\'t resolve the user ID to unban.'); - - const listener = (eGuild, eUser) => { - if (eGuild.id === guild.id && eUser.id === id) { - this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener); - this.client.clearTimeout(timeout); - resolve(eUser); - } - }; - this.client.on(Constants.Events.GUILD_BAN_REMOVE, listener); - - const timeout = this.client.setTimeout(() => { - this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener); - reject(new Error('Took too long to receive the ban remove event.')); - }, 10000); - - this.rest.makeRequest('del', `${Constants.Endpoints.guildBans(guild.id)}/${id}`, true).catch(err => { - this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener); - this.client.clearTimeout(timeout); - reject(err); - }); - }); - } - - getGuildBans(guild) { - return this.rest.makeRequest('get', Constants.Endpoints.guildBans(guild.id), true).then(banItems => { - const bannedUsers = new Collection(); - for (const banItem of banItems) { - const user = this.client.dataManager.newUser(banItem.user); - bannedUsers.set(user.id, user); - } - return bannedUsers; - }); - } - - updateGuildRole(role, _data) { - const data = {}; - data.name = _data.name || role.name; - data.position = typeof _data.position !== 'undefined' ? _data.position : role.position; - data.color = _data.color || role.color; - if (typeof data.color === 'string' && data.color.startsWith('#')) { - data.color = parseInt(data.color.replace('#', ''), 16); - } - data.hoist = typeof _data.hoist !== 'undefined' ? _data.hoist : role.hoist; - data.mentionable = typeof _data.mentionable !== 'undefined' ? _data.mentionable : role.mentionable; - - if (_data.permissions) { - let perms = 0; - for (let perm of _data.permissions) { - if (typeof perm === 'string') perm = Constants.PermissionFlags[perm]; - perms |= perm; - } - data.permissions = perms; - } else { - data.permissions = role.permissions; - } - - return this.rest.makeRequest( - 'patch', Constants.Endpoints.guildRole(role.guild.id, role.id), true, data - ).then(_role => - this.client.actions.GuildRoleUpdate.handle({ - role: _role, - guild_id: role.guild.id, - }).updated - ); - } - - pinMessage(message) { - return this.rest.makeRequest('put', `${Constants.Endpoints.channel(message.channel.id)}/pins/${message.id}`, true) - .then(() => message); - } - - unpinMessage(message) { - return this.rest.makeRequest('del', `${Constants.Endpoints.channel(message.channel.id)}/pins/${message.id}`, true) - .then(() => message); - } - - getChannelPinnedMessages(channel) { - return this.rest.makeRequest('get', `${Constants.Endpoints.channel(channel.id)}/pins`, true); - } - - createChannelInvite(channel, options) { - const payload = {}; - payload.temporary = options.temporary; - payload.max_age = options.maxAge; - payload.max_uses = options.maxUses; - return this.rest.makeRequest('post', `${Constants.Endpoints.channelInvites(channel.id)}`, true, payload) - .then(invite => new Invite(this.client, invite)); - } - - deleteInvite(invite) { - return this.rest.makeRequest('del', Constants.Endpoints.invite(invite.code), true).then(() => invite); - } - - getInvite(code) { - return this.rest.makeRequest('get', Constants.Endpoints.invite(code), true).then(invite => - new Invite(this.client, invite) - ); - } - - getGuildInvites(guild) { - return this.rest.makeRequest('get', Constants.Endpoints.guildInvites(guild.id), true).then(inviteItems => { - const invites = new Collection(); - for (const inviteItem of inviteItems) { - const invite = new Invite(this.client, inviteItem); - invites.set(invite.code, invite); - } - return invites; - }); - } - - pruneGuildMembers(guild, days, dry) { - return this.rest.makeRequest(dry ? 'get' : 'post', `${Constants.Endpoints.guildPrune(guild.id)}?days=${days}`, true) - .then(data => data.pruned); - } - - createEmoji(guild, image, name) { - return this.rest.makeRequest('post', `${Constants.Endpoints.guildEmojis(guild.id)}`, true, { name, image }) - .then(data => this.client.actions.EmojiCreate.handle(data, guild).emoji); - } - - deleteEmoji(emoji) { - return this.rest.makeRequest('delete', `${Constants.Endpoints.guildEmojis(emoji.guild.id)}/${emoji.id}`, true) - .then(() => this.client.actions.EmojiDelete.handle(emoji).data); - } - - getWebhook(id, token) { - return this.rest.makeRequest('get', Constants.Endpoints.webhook(id, token), !token).then(data => - new Webhook(this.client, data) - ); - } - - getGuildWebhooks(guild) { - return this.rest.makeRequest('get', Constants.Endpoints.guildWebhooks(guild.id), true).then(data => { - const hooks = new Collection(); - for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook)); - return hooks; - }); - } - - getChannelWebhooks(channel) { - return this.rest.makeRequest('get', Constants.Endpoints.channelWebhooks(channel.id), true).then(data => { - const hooks = new Collection(); - for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook)); - return hooks; - }); - } - - createWebhook(channel, name, avatar) { - return this.rest.makeRequest('post', Constants.Endpoints.channelWebhooks(channel.id), true, { name, avatar }) - .then(data => new Webhook(this.client, data)); - } - - editWebhook(webhook, name, avatar) { - return this.rest.makeRequest('patch', Constants.Endpoints.webhook(webhook.id, webhook.token), false, { - name, - avatar, - }).then(data => { - webhook.name = data.name; - webhook.avatar = data.avatar; - return webhook; - }); - } - - deleteWebhook(webhook) { - return this.rest.makeRequest('delete', Constants.Endpoints.webhook(webhook.id, webhook.token), false); - } - - sendWebhookMessage(webhook, content, { avatarURL, tts, disableEveryone, embeds } = {}, file = null) { - if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content); - if (content) { - if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { - content = content.replace(/@(everyone|here)/g, '@\u200b$1'); - } - } - return this.rest.makeRequest('post', `${Constants.Endpoints.webhook(webhook.id, webhook.token)}?wait=true`, false, { - username: webhook.name, - avatar_url: avatarURL, - content, - tts, - file, - embeds, - }); - } - - sendSlackWebhookMessage(webhook, body) { - return this.rest.makeRequest( - 'post', `${Constants.Endpoints.webhook(webhook.id, webhook.token)}/slack?wait=true`, false, body - ); - } - - fetchUserProfile(user) { - return this.rest.makeRequest('get', Constants.Endpoints.userProfile(user.id), true).then(data => - new UserProfile(user, data) - ); - } - - fetchMeMentions(options) { - if (options.guild) options.guild = options.guild.id ? options.guild.id : options.guild; - return this.rest.makeRequest( - 'get', - Constants.Endpoints.meMentions(options.limit, options.roles, options.everyone, options.guild) - ).then(res => res.body.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client))); - } - - addFriend(user) { - return this.rest.makeRequest('post', Constants.Endpoints.relationships('@me'), true, { - username: user.username, - discriminator: user.discriminator, - }).then(() => user); - } - - removeFriend(user) { - return this.rest.makeRequest('delete', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true) - .then(() => user); - } - - blockUser(user) { - return this.rest.makeRequest('put', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true, { type: 2 }) - .then(() => user); - } - - unblockUser(user) { - return this.rest.makeRequest('delete', `${Constants.Endpoints.relationships('@me')}/${user.id}`, true) - .then(() => user); - } - - setRolePositions(guildID, roles) { - return this.rest.makeRequest('patch', Constants.Endpoints.guildRoles(guildID), true, roles).then(() => - this.client.actions.GuildRolesPositionUpdate.handle({ - guild_id: guildID, - roles, - }).guild - ); - } - - addMessageReaction(message, emoji) { - return this.rest.makeRequest( - 'put', Constants.Endpoints.selfMessageReaction(message.channel.id, message.id, emoji), true - ).then(() => - this.client.actions.MessageReactionAdd.handle({ - user_id: this.client.user.id, - message_id: message.id, - emoji: parseEmoji(emoji), - channel_id: message.channel.id, - }).reaction - ); - } - - removeMessageReaction(message, emoji, user) { - let endpoint = Constants.Endpoints.selfMessageReaction(message.channel.id, message.id, emoji); - if (user.id !== this.client.user.id) { - endpoint = Constants.Endpoints.userMessageReaction(message.channel.id, message.id, emoji, null, user.id); - } - return this.rest.makeRequest('delete', endpoint, true).then(() => - this.client.actions.MessageReactionRemove.handle({ - user_id: user.id, - message_id: message.id, - emoji: parseEmoji(emoji), - channel_id: message.channel.id, - }).reaction - ); - } - - removeMessageReactions(message) { - return this.rest.makeRequest('delete', Constants.Endpoints.messageReactions(message.channel.id, message.id), true) - .then(() => message); - } - - getMessageReactionUsers(message, emoji, limit = 100) { - return this.rest.makeRequest( - 'get', Constants.Endpoints.messageReaction(message.channel.id, message.id, emoji, limit), true - ); - } - - getMyApplication() { - return this.rest.makeRequest('get', Constants.Endpoints.myApplication, true).then(app => - new ClientOAuth2Application(this.client, app) - ); - } - - setNote(user, note) { - return this.rest.makeRequest('put', Constants.Endpoints.note(user.id), true, { note }).then(() => user); - } -} - -module.exports = RESTMethods; diff --git a/node_modules/discord.js/src/client/rest/RequestHandlers/Burst.js b/node_modules/discord.js/src/client/rest/RequestHandlers/Burst.js deleted file mode 100644 index 2cc1a59..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/Burst.js +++ /dev/null @@ -1,70 +0,0 @@ -const RequestHandler = require('./RequestHandler'); - -class BurstRequestHandler extends RequestHandler { - constructor(restManager, endpoint) { - super(restManager, endpoint); - this.requestRemaining = 1; - this.first = true; - } - - push(request) { - super.push(request); - this.handle(); - } - - handleNext(time) { - if (this.waiting) return; - this.waiting = true; - this.restManager.client.setTimeout(() => { - this.requestRemaining = this.requestLimit; - this.waiting = false; - this.handle(); - }, time); - } - - execute(item) { - item.request.gen().end((err, res) => { - if (res && res.headers) { - this.requestLimit = res.headers['x-ratelimit-limit']; - this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000; - this.requestRemaining = Number(res.headers['x-ratelimit-remaining']); - this.timeDifference = Date.now() - new Date(res.headers.date).getTime(); - this.handleNext( - this.requestResetTime - Date.now() + this.timeDifference + this.restManager.client.options.restTimeOffset - ); - } - if (err) { - if (err.status === 429) { - this.requestRemaining = 0; - this.queue.unshift(item); - this.restManager.client.setTimeout(() => { - this.globalLimit = false; - this.handle(); - }, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset); - if (res.headers['x-ratelimit-global']) this.globalLimit = true; - } else { - item.reject(err); - } - } else { - this.globalLimit = false; - const data = res && res.body ? res.body : {}; - item.resolve(data); - if (this.first) { - this.first = false; - this.handle(); - } - } - }); - } - - handle() { - super.handle(); - if (this.requestRemaining < 1 || this.queue.length === 0 || this.globalLimit) return; - while (this.queue.length > 0 && this.requestRemaining > 0) { - this.execute(this.queue.shift()); - this.requestRemaining--; - } - } -} - -module.exports = BurstRequestHandler; diff --git a/node_modules/discord.js/src/client/rest/RequestHandlers/RequestHandler.js b/node_modules/discord.js/src/client/rest/RequestHandlers/RequestHandler.js deleted file mode 100644 index a1a2f34..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/RequestHandler.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * A base class for different types of rate limiting handlers for the REST API. - * @private - */ -class RequestHandler { - /** - * @param {RESTManager} restManager The REST manager to use - */ - constructor(restManager) { - /** - * The RESTManager that instantiated this RequestHandler - * @type {RESTManager} - */ - this.restManager = restManager; - - /** - * A list of requests that have yet to be processed. - * @type {APIRequest[]} - */ - this.queue = []; - } - - /** - * Whether or not the client is being rate limited on every endpoint. - * @type {boolean} - */ - get globalLimit() { - return this.restManager.globallyRateLimited; - } - - set globalLimit(value) { - this.restManager.globallyRateLimited = value; - } - - /** - * Push a new API request into this bucket - * @param {APIRequest} request The new request to push into the queue - */ - push(request) { - this.queue.push(request); - } - - /** - * Attempts to get this RequestHandler to process its current queue - */ - handle() { - return; - } -} - -module.exports = RequestHandler; diff --git a/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js b/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js deleted file mode 100644 index 0abf36d..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js +++ /dev/null @@ -1,104 +0,0 @@ -const RequestHandler = require('./RequestHandler'); - -/** - * Handles API Requests sequentially, i.e. we wait until the current request is finished before moving onto - * the next. This plays a _lot_ nicer in terms of avoiding 429's when there is more than one session of the account, - * but it can be slower. - * @extends {RequestHandler} - * @private - */ -class SequentialRequestHandler extends RequestHandler { - /** - * @param {RESTManager} restManager The REST manager to use - * @param {string} endpoint The endpoint to handle - */ - constructor(restManager, endpoint) { - super(restManager, endpoint); - - /** - * Whether this rate limiter is waiting for a response from a request - * @type {boolean} - */ - this.waiting = false; - - /** - * The endpoint that this handler is handling - * @type {string} - */ - this.endpoint = endpoint; - - /** - * The time difference between Discord's Dates and the local computer's Dates. A positive number means the local - * computer's time is ahead of Discord's. - * @type {number} - */ - this.timeDifference = 0; - } - - push(request) { - super.push(request); - this.handle(); - } - - /** - * Performs a request then resolves a promise to indicate its readiness for a new request - * @param {APIRequest} item The item to execute - * @returns {Promise<?Object|Error>} - */ - execute(item) { - return new Promise(resolve => { - item.request.gen().end((err, res) => { - if (res && res.headers) { - this.requestLimit = res.headers['x-ratelimit-limit']; - this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000; - this.requestRemaining = Number(res.headers['x-ratelimit-remaining']); - this.timeDifference = Date.now() - new Date(res.headers.date).getTime(); - } - if (err) { - if (err.status === 429) { - this.restManager.client.setTimeout(() => { - this.waiting = false; - this.globalLimit = false; - resolve(); - }, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset); - if (res.headers['x-ratelimit-global']) this.globalLimit = true; - } else { - this.queue.shift(); - this.waiting = false; - item.reject(err); - resolve(err); - } - } else { - this.queue.shift(); - this.globalLimit = false; - const data = res && res.body ? res.body : {}; - item.resolve(data); - if (this.requestRemaining === 0) { - this.restManager.client.setTimeout( - () => { - this.waiting = false; - resolve(data); - }, - this.requestResetTime - Date.now() + this.timeDifference + this.restManager.client.options.restTimeOffset - ); - } else { - this.waiting = false; - resolve(data); - } - } - }); - }); - } - - handle() { - super.handle(); - - if (this.waiting || this.queue.length === 0 || this.globalLimit) return; - this.waiting = true; - - const item = this.queue[0]; - this.execute(item).then(() => this.handle()); - } -} - -module.exports = SequentialRequestHandler; diff --git a/node_modules/discord.js/src/client/rest/UserAgentManager.js b/node_modules/discord.js/src/client/rest/UserAgentManager.js deleted file mode 100644 index 12393ff..0000000 --- a/node_modules/discord.js/src/client/rest/UserAgentManager.js +++ /dev/null @@ -1,22 +0,0 @@ -const Constants = require('../../util/Constants'); - -class UserAgentManager { - constructor(restManager) { - this.restManager = restManager; - this._userAgent = { - url: 'https://github.com/hydrabolt/discord.js', - version: Constants.Package.version, - }; - } - - set(info) { - this._userAgent.url = info.url || 'https://github.com/hydrabolt/discord.js'; - this._userAgent.version = info.version || Constants.Package.version; - } - - get userAgent() { - return `DiscordBot (${this._userAgent.url}, ${this._userAgent.version})`; - } -} - -module.exports = UserAgentManager; diff --git a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js b/node_modules/discord.js/src/client/voice/ClientVoiceManager.js deleted file mode 100644 index ea83745..0000000 --- a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js +++ /dev/null @@ -1,245 +0,0 @@ -const Collection = require('../../util/Collection'); -const mergeDefault = require('../../util/MergeDefault'); -const Constants = require('../../util/Constants'); -const VoiceConnection = require('./VoiceConnection'); -const EventEmitter = require('events').EventEmitter; - -/** - * Manages all the voice stuff for the Client - * @private - */ -class ClientVoiceManager { - constructor(client) { - /** - * The client that instantiated this voice manager - * @type {Client} - */ - this.client = client; - - /** - * A collection mapping connection IDs to the Connection objects - * @type {Collection<string, VoiceConnection>} - */ - this.connections = new Collection(); - - /** - * Pending connection attempts, maps guild ID to VoiceChannel - * @type {Collection<string, VoiceChannel>} - */ - this.pending = new Collection(); - - this.client.on('self.voiceServer', this.onVoiceServer.bind(this)); - this.client.on('self.voiceStateUpdate', this.onVoiceStateUpdate.bind(this)); - } - - onVoiceServer(data) { - if (this.pending.has(data.guild_id)) this.pending.get(data.guild_id).setTokenAndEndpoint(data.token, data.endpoint); - } - - onVoiceStateUpdate(data) { - if (this.pending.has(data.guild_id)) this.pending.get(data.guild_id).setSessionID(data.session_id); - } - - /** - * Sends a request to the main gateway to join a voice channel - * @param {VoiceChannel} channel The channel to join - * @param {Object} [options] The options to provide - */ - sendVoiceStateUpdate(channel, options = {}) { - if (!this.client.user) throw new Error('Unable to join because there is no client user.'); - if (!channel.permissionsFor) { - throw new Error('Channel does not support permissionsFor; is it really a voice channel?'); - } - const permissions = channel.permissionsFor(this.client.user); - if (!permissions) { - throw new Error('There is no permission set for the client user in this channel - are they part of the guild?'); - } - if (!permissions.hasPermission('CONNECT')) { - throw new Error('You do not have permission to join this voice channel.'); - } - - options = mergeDefault({ - guild_id: channel.guild.id, - channel_id: channel.id, - self_mute: false, - self_deaf: false, - }, options); - - this.client.ws.send({ - op: Constants.OPCodes.VOICE_STATE_UPDATE, - d: options, - }); - } - - /** - * Sets up a request to join a voice channel - * @param {VoiceChannel} channel The voice channel to join - * @returns {Promise<VoiceConnection>} - */ - joinChannel(channel) { - return new Promise((resolve, reject) => { - if (this.pending.get(channel.guild.id)) throw new Error('Already connecting to this guild\'s voice server.'); - if (!channel.joinable) throw new Error('You do not have permission to join this voice channel.'); - - const existingConnection = this.connections.get(channel.guild.id); - if (existingConnection) { - if (existingConnection.channel.id !== channel.id) { - this.sendVoiceStateUpdate(channel); - this.connections.get(channel.guild.id).channel = channel; - } - resolve(existingConnection); - return; - } - - const pendingConnection = new PendingVoiceConnection(this, channel); - this.pending.set(channel.guild.id, pendingConnection); - - pendingConnection.on('fail', reason => { - this.pending.delete(channel.guild.id); - reject(reason); - }); - - pendingConnection.on('pass', voiceConnection => { - this.pending.delete(channel.guild.id); - this.connections.set(channel.guild.id, voiceConnection); - voiceConnection.once('ready', () => resolve(voiceConnection)); - voiceConnection.once('error', reject); - voiceConnection.once('disconnect', () => this.connections.delete(channel.guild.id)); - }); - }); - } -} - -/** - * Represents a Pending Voice Connection - * @private - */ -class PendingVoiceConnection extends EventEmitter { - constructor(voiceManager, channel) { - super(); - - /** - * The ClientVoiceManager that instantiated this pending connection - * @type {ClientVoiceManager} - */ - this.voiceManager = voiceManager; - - /** - * The channel that this pending voice connection will attempt to join - * @type {VoiceChannel} - */ - this.channel = channel; - - /** - * The timeout that will be invoked after 15 seconds signifying a failure to connect - * @type {Timeout} - */ - this.deathTimer = this.voiceManager.client.setTimeout( - () => this.fail(new Error('Connection not established within 15 seconds.')), 15000); - - /** - * An object containing data required to connect to the voice servers with - * @type {Object} - */ - this.data = {}; - - this.sendVoiceStateUpdate(); - } - - checkReady() { - if (this.data.token && this.data.endpoint && this.data.session_id) { - this.pass(); - return true; - } else { - return false; - } - } - - /** - * Set the token and endpoint required to connect to the the voice servers - * @param {string} token the token - * @param {string} endpoint the endpoint - * @returns {void} - */ - setTokenAndEndpoint(token, endpoint) { - if (!token) { - this.fail(new Error('Token not provided from voice server packet.')); - return; - } - if (!endpoint) { - this.fail(new Error('Endpoint not provided from voice server packet.')); - return; - } - if (this.data.token) { - this.fail(new Error('There is already a registered token for this connection.')); - return; - } - if (this.data.endpoint) { - this.fail(new Error('There is already a registered endpoint for this connection.')); - return; - } - - endpoint = endpoint.match(/([^:]*)/)[0]; - - if (!endpoint) { - this.fail(new Error('Failed to find an endpoint.')); - return; - } - - this.data.token = token; - this.data.endpoint = endpoint; - - this.checkReady(); - } - - /** - * Sets the Session ID for the connection - * @param {string} sessionID the session ID - */ - setSessionID(sessionID) { - if (!sessionID) { - this.fail(new Error('Session ID not supplied.')); - return; - } - if (this.data.session_id) { - this.fail(new Error('There is already a registered session ID for this connection.')); - return; - } - this.data.session_id = sessionID; - - this.checkReady(); - } - - clean() { - clearInterval(this.deathTimer); - this.emit('fail', new Error('Clean-up triggered :fourTriggered:')); - } - - pass() { - clearInterval(this.deathTimer); - this.emit('pass', this.upgrade()); - } - - fail(reason) { - this.emit('fail', reason); - this.clean(); - } - - sendVoiceStateUpdate() { - try { - this.voiceManager.sendVoiceStateUpdate(this.channel); - } catch (error) { - this.fail(error); - } - } - - /** - * Upgrades this Pending Connection to a full Voice Connection - * @returns {VoiceConnection} - */ - upgrade() { - return new VoiceConnection(this); - } -} - -module.exports = ClientVoiceManager; diff --git a/node_modules/discord.js/src/client/voice/VoiceConnection.js b/node_modules/discord.js/src/client/voice/VoiceConnection.js deleted file mode 100644 index ac44ff8..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceConnection.js +++ /dev/null @@ -1,276 +0,0 @@ -const VoiceWebSocket = require('./VoiceWebSocket'); -const VoiceUDP = require('./VoiceUDPClient'); -const Constants = require('../../util/Constants'); -const AudioPlayer = require('./player/AudioPlayer'); -const VoiceReceiver = require('./receiver/VoiceReceiver'); -const EventEmitter = require('events').EventEmitter; -const fs = require('fs'); - -/** - * Represents a connection to a voice channel in Discord. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * - * }); - * ``` - * @extends {EventEmitter} - */ -class VoiceConnection extends EventEmitter { - constructor(pendingConnection) { - super(); - - /** - * The Voice Manager that instantiated this connection - * @type {ClientVoiceManager} - */ - this.voiceManager = pendingConnection.voiceManager; - - /** - * The voice channel this connection is currently serving - * @type {VoiceChannel} - */ - this.channel = pendingConnection.channel; - - /** - * Whether we're currently transmitting audio - * @type {boolean} - */ - this.speaking = false; - - /** - * An array of Voice Receivers that have been created for this connection - * @type {VoiceReceiver[]} - */ - this.receivers = []; - - /** - * The authentication data needed to connect to the voice server - * @type {Object} - * @private - */ - this.authentication = pendingConnection.data; - - /** - * The audio player for this voice connection - * @type {AudioPlayer} - */ - this.player = new AudioPlayer(this); - - this.player.on('debug', m => { - /** - * Debug info from the connection - * @event VoiceConnection#debug - * @param {string} message the debug message - */ - this.emit('debug', `audio player - ${m}`); - }); - - this.player.on('error', e => { - /** - * Warning info from the connection - * @event VoiceConnection#warn - * @param {string|Error} warning the warning - */ - this.emit('warn', e); - this.player.cleanup(); - }); - - /** - * Map SSRC to speaking values - * @type {Map<number, boolean>} - * @private - */ - this.ssrcMap = new Map(); - - /** - * Whether this connection is ready - * @type {boolean} - * @private - */ - this.ready = false; - - /** - * Object that wraps contains the `ws` and `udp` sockets of this voice connection - * @type {Object} - * @private - */ - this.sockets = {}; - this.connect(); - } - - /** - * Sets whether the voice connection should display as "speaking" or not - * @param {boolean} value whether or not to speak - * @private - */ - setSpeaking(value) { - if (this.speaking === value) return; - this.speaking = value; - this.sockets.ws.sendPacket({ - op: Constants.VoiceOPCodes.SPEAKING, - d: { - speaking: true, - delay: 0, - }, - }).catch(e => { - this.emit('debug', e); - }); - } - - /** - * Disconnect the voice connection, causing a disconnect and closing event to be emitted. - */ - disconnect() { - this.emit('closing'); - this.voiceManager.client.ws.send({ - op: Constants.OPCodes.VOICE_STATE_UPDATE, - d: { - guild_id: this.channel.guild.id, - channel_id: null, - self_mute: false, - self_deaf: false, - }, - }); - /** - * Emitted when the voice connection disconnects - * @event VoiceConnection#disconnect - */ - this.emit('disconnect'); - } - - /** - * Connect the voice connection - * @private - */ - connect() { - if (this.sockets.ws) throw new Error('There is already an existing WebSocket connection.'); - if (this.sockets.udp) throw new Error('There is already an existing UDP connection.'); - this.sockets.ws = new VoiceWebSocket(this); - this.sockets.udp = new VoiceUDP(this); - this.sockets.ws.on('error', e => this.emit('error', e)); - this.sockets.udp.on('error', e => this.emit('error', e)); - this.sockets.ws.once('ready', d => { - this.authentication.port = d.port; - this.authentication.ssrc = d.ssrc; - /** - * Emitted whenever the connection encounters an error. - * @event VoiceConnection#error - * @param {Error} error the encountered error - */ - this.sockets.udp.findEndpointAddress() - .then(address => { - this.sockets.udp.createUDPSocket(address); - }, e => this.emit('error', e)); - }); - this.sockets.ws.once('sessionDescription', (mode, secret) => { - this.authentication.encryptionMode = mode; - this.authentication.secretKey = secret; - /** - * Emitted once the connection is ready, when a promise to join a voice channel resolves, - * the connection will already be ready. - * @event VoiceConnection#ready - */ - this.emit('ready'); - this.ready = true; - }); - this.sockets.ws.on('speaking', data => { - const guild = this.channel.guild; - const user = this.voiceManager.client.users.get(data.user_id); - this.ssrcMap.set(+data.ssrc, user); - if (!data.speaking) { - for (const receiver of this.receivers) { - const opusStream = receiver.opusStreams.get(user.id); - const pcmStream = receiver.pcmStreams.get(user.id); - if (opusStream) { - opusStream.push(null); - opusStream.open = false; - receiver.opusStreams.delete(user.id); - } - if (pcmStream) { - pcmStream.push(null); - pcmStream.open = false; - receiver.pcmStreams.delete(user.id); - } - } - } - /** - * Emitted whenever a user starts/stops speaking - * @event VoiceConnection#speaking - * @param {User} user The user that has started/stopped speaking - * @param {boolean} speaking Whether or not the user is speaking - */ - if (this.ready) this.emit('speaking', user, data.speaking); - guild._memberSpeakUpdate(data.user_id, data.speaking); - }); - } - - /** - * Options that can be passed to stream-playing methods: - * @typedef {Object} StreamOptions - * @property {number} [seek=0] The time to seek to - * @property {number} [volume=1] The volume to play at - * @property {number} [passes=1] How many times to send the voice packet to reduce packet loss - */ - - /** - * Play the given file in the voice connection. - * @param {string} file The path to the file - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // play files natively - * voiceChannel.join() - * .then(connection => { - * const dispatcher = connection.playFile('C:/Users/Discord/Desktop/music.mp3'); - * }) - * .catch(console.error); - */ - playFile(file, options) { - return this.playStream(fs.createReadStream(file), options); - } - - /** - * Plays and converts an audio stream in the voice connection. - * @param {ReadableStream} stream The audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // play streams using ytdl-core - * const ytdl = require('ytdl-core'); - * const streamOptions = { seek: 0, volume: 1 }; - * voiceChannel.join() - * .then(connection => { - * const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', {filter : 'audioonly'}); - * const dispatcher = connection.playStream(stream, streamOptions); - * }) - * .catch(console.error); - */ - playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - return this.player.playUnknownStream(stream, options); - } - - /** - * Plays a stream of 16-bit signed stereo PCM at 48KHz. - * @param {ReadableStream} stream The audio stream to play. - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playConvertedStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - return this.player.playPCMStream(stream, null, options); - } - - /** - * Creates a VoiceReceiver so you can start listening to voice data. It's recommended to only create one of these. - * @returns {VoiceReceiver} - */ - createReceiver() { - const receiver = new VoiceReceiver(this); - this.receivers.push(receiver); - return receiver; - } -} - -module.exports = VoiceConnection; diff --git a/node_modules/discord.js/src/client/voice/VoiceUDPClient.js b/node_modules/discord.js/src/client/voice/VoiceUDPClient.js deleted file mode 100644 index b7b0c0c..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceUDPClient.js +++ /dev/null @@ -1,145 +0,0 @@ -const udp = require('dgram'); -const dns = require('dns'); -const Constants = require('../../util/Constants'); -const EventEmitter = require('events').EventEmitter; - -/** - * Represents a UDP Client for a Voice Connection - * @extends {EventEmitter} - * @private - */ -class VoiceConnectionUDPClient extends EventEmitter { - constructor(voiceConnection) { - super(); - - /** - * The voice connection that this UDP client serves - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - - /** - * The UDP socket - * @type {?Socket} - */ - this.socket = null; - - /** - * The address of the discord voice server - * @type {?string} - */ - this.discordAddress = null; - - /** - * The local IP address - * @type {?string} - */ - this.localAddress = null; - - /** - * The local port - * @type {?string} - */ - this.localPort = null; - - this.voiceConnection.on('closing', this.shutdown.bind(this)); - } - - shutdown() { - if (this.socket) { - try { - this.socket.close(); - } catch (e) { - return; - } - this.socket = null; - } - } - - /** - * The port of the discord voice server - * @type {number} - * @readonly - */ - get discordPort() { - return this.voiceConnection.authentication.port; - } - - /** - * Tries to resolve the voice server endpoint to an address - * @returns {Promise<string>} - */ - findEndpointAddress() { - return new Promise((resolve, reject) => { - dns.lookup(this.voiceConnection.authentication.endpoint, (error, address) => { - if (error) { - reject(error); - return; - } - this.discordAddress = address; - resolve(address); - }); - }); - } - - /** - * Send a packet to the UDP client - * @param {Object} packet the packet to send - * @returns {Promise<Object>} - */ - send(packet) { - return new Promise((resolve, reject) => { - if (!this.socket) throw new Error('Tried to send a UDP packet, but there is no socket available.'); - if (!this.discordAddress || !this.discordPort) throw new Error('Malformed UDP address or port.'); - this.socket.send(packet, 0, packet.length, this.discordPort, this.discordAddress, error => { - if (error) reject(error); else resolve(packet); - }); - }); - } - - createUDPSocket(address) { - this.discordAddress = address; - const socket = this.socket = udp.createSocket('udp4'); - - socket.once('message', message => { - const packet = parseLocalPacket(message); - if (packet.error) { - this.emit('error', packet.error); - return; - } - - this.localAddress = packet.address; - this.localPort = packet.port; - - this.voiceConnection.sockets.ws.sendPacket({ - op: Constants.VoiceOPCodes.SELECT_PROTOCOL, - d: { - protocol: 'udp', - data: { - address: packet.address, - port: packet.port, - mode: 'xsalsa20_poly1305', - }, - }, - }); - }); - - const blankMessage = new Buffer(70); - blankMessage.writeUIntBE(this.voiceConnection.authentication.ssrc, 0, 4); - this.send(blankMessage); - } -} - -function parseLocalPacket(message) { - try { - const packet = new Buffer(message); - let address = ''; - for (let i = 4; i < packet.indexOf(0, i); i++) address += String.fromCharCode(packet[i]); - const port = parseInt(packet.readUIntLE(packet.length - 2, 2).toString(10), 10); - return { address, port }; - } catch (error) { - return { error }; - } -} - -module.exports = VoiceConnectionUDPClient; diff --git a/node_modules/discord.js/src/client/voice/VoiceWebSocket.js b/node_modules/discord.js/src/client/voice/VoiceWebSocket.js deleted file mode 100644 index bafa5dd..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceWebSocket.js +++ /dev/null @@ -1,249 +0,0 @@ -const Constants = require('../../util/Constants'); -const SecretKey = require('./util/SecretKey'); -const EventEmitter = require('events').EventEmitter; - -let WebSocket; -try { - WebSocket = require('uws'); -} catch (err) { - WebSocket = require('ws'); -} - -/** - * Represents a Voice Connection's WebSocket - * @extends {EventEmitter} - * @private - */ -class VoiceWebSocket extends EventEmitter { - constructor(voiceConnection) { - super(); - - /** - * The Voice Connection that this WebSocket serves - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - - /** - * How many connection attempts have been made - * @type {number} - */ - this.attempts = 0; - - this.connect(); - this.dead = false; - this.voiceConnection.on('closing', this.shutdown.bind(this)); - } - - shutdown() { - this.dead = true; - this.reset(); - } - - /** - * The client of this voice websocket - * @type {Client} - * @readonly - */ - get client() { - return this.voiceConnection.voiceManager.client; - } - - /** - * Resets the current WebSocket - */ - reset() { - if (this.ws) { - if (this.ws.readyState !== WebSocket.CLOSED) this.ws.close(); - this.ws = null; - } - this.clearHeartbeat(); - } - - /** - * Starts connecting to the Voice WebSocket Server. - */ - connect() { - if (this.dead) return; - if (this.ws) this.reset(); - if (this.attempts > 5) { - this.emit('error', new Error(`Too many connection attempts (${this.attempts}).`)); - return; - } - - this.attempts++; - - /** - * The actual WebSocket used to connect to the Voice WebSocket Server. - * @type {WebSocket} - */ - this.ws = new WebSocket(`wss://${this.voiceConnection.authentication.endpoint}`); - this.ws.onopen = this.onOpen.bind(this); - this.ws.onmessage = this.onMessage.bind(this); - this.ws.onclose = this.onClose.bind(this); - this.ws.onerror = this.onError.bind(this); - } - - /** - * Sends data to the WebSocket if it is open. - * @param {string} data the data to send to the WebSocket - * @returns {Promise<string>} - */ - send(data) { - return new Promise((resolve, reject) => { - if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { - throw new Error(`Voice websocket not open to send ${data}.`); - } - this.ws.send(data, null, error => { - if (error) reject(error); else resolve(data); - }); - }); - } - - /** - * JSON.stringify's a packet and then sends it to the WebSocket Server. - * @param {Object} packet the packet to send - * @returns {Promise<string>} - */ - sendPacket(packet) { - try { - packet = JSON.stringify(packet); - } catch (error) { - return Promise.reject(error); - } - return this.send(packet); - } - - /** - * Called whenever the WebSocket opens - */ - onOpen() { - this.sendPacket({ - op: Constants.OPCodes.DISPATCH, - d: { - server_id: this.voiceConnection.channel.guild.id, - user_id: this.client.user.id, - token: this.voiceConnection.authentication.token, - session_id: this.voiceConnection.authentication.session_id, - }, - }).catch(() => { - this.emit('error', new Error('Tried to send join packet, but the WebSocket is not open.')); - }); - } - - /** - * Called whenever a message is received from the WebSocket - * @param {MessageEvent} event the message event that was received - * @returns {void} - */ - onMessage(event) { - try { - return this.onPacket(JSON.parse(event.data)); - } catch (error) { - return this.onError(error); - } - } - - /** - * Called whenever the connection to the WebSocket Server is lost - */ - onClose() { - if (!this.dead) this.client.setTimeout(this.connect.bind(this), this.attempts * 1000); - } - - /** - * Called whenever an error occurs with the WebSocket. - * @param {Error} error the error that occurred - */ - onError(error) { - this.emit('error', error); - } - - /** - * Called whenever a valid packet is received from the WebSocket - * @param {Object} packet the received packet - */ - onPacket(packet) { - switch (packet.op) { - case Constants.VoiceOPCodes.READY: - this.setHeartbeat(packet.d.heartbeat_interval); - /** - * Emitted once the voice websocket receives the ready packet - * @param {Object} packet the received packet - * @event VoiceWebSocket#ready - */ - this.emit('ready', packet.d); - break; - case Constants.VoiceOPCodes.SESSION_DESCRIPTION: - /** - * Emitted once the Voice Websocket receives a description of this voice session - * @param {string} encryptionMode the type of encryption being used - * @param {SecretKey} secretKey the secret key used for encryption - * @event VoiceWebSocket#sessionDescription - */ - this.emit('sessionDescription', packet.d.mode, new SecretKey(packet.d.secret_key)); - break; - case Constants.VoiceOPCodes.SPEAKING: - /** - * Emitted whenever a speaking packet is received - * @param {Object} data - * @event VoiceWebSocket#speaking - */ - this.emit('speaking', packet.d); - break; - default: - /** - * Emitted when an unhandled packet is received - * @param {Object} packet - * @event VoiceWebSocket#unknownPacket - */ - this.emit('unknownPacket', packet); - break; - } - } - - /** - * Sets an interval at which to send a heartbeat packet to the WebSocket - * @param {number} interval the interval at which to send a heartbeat packet - */ - setHeartbeat(interval) { - if (!interval || isNaN(interval)) { - this.onError(new Error('Tried to set voice heartbeat but no valid interval was specified.')); - return; - } - if (this.heartbeatInterval) { - /** - * Emitted whenver the voice websocket encounters a non-fatal error - * @param {string} warn the warning - * @event VoiceWebSocket#warn - */ - this.emit('warn', 'A voice heartbeat interval is being overwritten'); - clearInterval(this.heartbeatInterval); - } - this.heartbeatInterval = this.client.setInterval(this.sendHeartbeat.bind(this), interval); - } - - /** - * Clears a heartbeat interval, if one exists - */ - clearHeartbeat() { - if (!this.heartbeatInterval) { - this.emit('warn', 'Tried to clear a heartbeat interval that does not exist'); - return; - } - clearInterval(this.heartbeatInterval); - this.heartbeatInterval = null; - } - - /** - * Sends a heartbeat packet - */ - sendHeartbeat() { - this.sendPacket({ op: Constants.VoiceOPCodes.HEARTBEAT, d: null }).catch(() => { - this.emit('warn', 'Tried to send heartbeat, but connection is not open'); - this.clearHeartbeat(); - }); - } -} - -module.exports = VoiceWebSocket; diff --git a/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js b/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js deleted file mode 100644 index e08a365..0000000 --- a/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js +++ /dev/null @@ -1,307 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const NaCl = require('tweetnacl'); - -const nonce = new Buffer(24); -nonce.fill(0); - -/** - * The class that sends voice packet data to the voice connection. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * // you can play a file or a stream here: - * const dispatcher = connection.playFile('./file.mp3'); - * }); - * ``` - * @extends {EventEmitter} - */ -class StreamDispatcher extends EventEmitter { - constructor(player, stream, sd, streamOptions) { - super(); - this.player = player; - this.stream = stream; - this.streamingData = { - channels: 2, - count: 0, - sequence: sd.sequence, - timestamp: sd.timestamp, - pausedTime: 0, - }; - this._startStreaming(); - this._triggered = false; - this._volume = streamOptions.volume; - - /** - * How many passes the dispatcher should take when sending packets to reduce packet loss. Values over 5 - * aren't recommended, as it means you are using 5x more bandwidth. You _can_ edit this at runtime. - * @type {number} - */ - this.passes = streamOptions.passes || 1; - - /** - * Whether playing is paused - * @type {boolean} - */ - this.paused = false; - - this.setVolume(streamOptions.volume || 1); - } - - /** - * How long the stream dispatcher has been "speaking" for - * @type {number} - * @readonly - */ - get time() { - return this.streamingData.count * (this.streamingData.length || 0); - } - - /** - * The total time, taking into account pauses and skips, that the dispatcher has been streaming for - * @type {number} - * @readonly - */ - get totalStreamTime() { - return this.time + this.streamingData.pausedTime; - } - - /** - * The volume of the stream, relative to the stream's input volume - * @type {number} - * @readonly - */ - get volume() { - return this._volume; - } - - /** - * Sets the volume relative to the input stream - i.e. 1 is normal, 0.5 is half, 2 is double. - * @param {number} volume The volume that you want to set - */ - setVolume(volume) { - this._volume = volume; - } - - /** - * Set the volume in decibels - * @param {number} db The decibels - */ - setVolumeDecibels(db) { - this._volume = Math.pow(10, db / 20); - } - - /** - * Set the volume so that a perceived value of 0.5 is half the perceived volume etc. - * @param {number} value The value for the volume - */ - setVolumeLogarithmic(value) { - this._volume = Math.pow(value, 1.660964); - } - - /** - * Stops sending voice packets to the voice connection (stream may still progress however) - */ - pause() { - this._setPaused(true); - } - - /** - * Resumes sending voice packets to the voice connection (may be further on in the stream than when paused) - */ - resume() { - this._setPaused(false); - } - - /** - * Stops the current stream permanently and emits an `end` event. - * @param {string} [reason='user'] An optional reason for stopping the dispatcher. - */ - end(reason = 'user') { - this._triggerTerminalState('end', reason); - } - - _setSpeaking(value) { - this.speaking = value; - /** - * Emitted when the dispatcher starts/stops speaking - * @event StreamDispatcher#speaking - * @param {boolean} value Whether or not the dispatcher is speaking - */ - this.emit('speaking', value); - } - - _sendBuffer(buffer, sequence, timestamp) { - let repeats = this.passes; - const packet = this._createPacket(sequence, timestamp, this.player.opusEncoder.encode(buffer)); - while (repeats--) { - this.player.voiceConnection.sockets.udp.send(packet) - .catch(e => this.emit('debug', `Failed to send a packet ${e}`)); - } - } - - _createPacket(sequence, timestamp, buffer) { - const packetBuffer = new Buffer(buffer.length + 28); - packetBuffer.fill(0); - packetBuffer[0] = 0x80; - packetBuffer[1] = 0x78; - - packetBuffer.writeUIntBE(sequence, 2, 2); - packetBuffer.writeUIntBE(timestamp, 4, 4); - packetBuffer.writeUIntBE(this.player.voiceConnection.authentication.ssrc, 8, 4); - - packetBuffer.copy(nonce, 0, 0, 12); - buffer = NaCl.secretbox(buffer, nonce, this.player.voiceConnection.authentication.secretKey.key); - - for (let i = 0; i < buffer.length; i++) packetBuffer[i + 12] = buffer[i]; - - return packetBuffer; - } - - _applyVolume(buffer) { - if (this._volume === 1) return buffer; - - const out = new Buffer(buffer.length); - for (let i = 0; i < buffer.length; i += 2) { - if (i >= buffer.length - 1) break; - const uint = Math.min(32767, Math.max(-32767, Math.floor(this._volume * buffer.readInt16LE(i)))); - out.writeInt16LE(uint, i); - } - - return out; - } - - _send() { - try { - if (this._triggered) { - this._setSpeaking(false); - return; - } - - const data = this.streamingData; - - if (data.missed >= 5) { - this._triggerTerminalState('end', 'Stream is not generating quickly enough.'); - return; - } - - if (this.paused) { - // data.timestamp = data.timestamp + 4294967295 ? data.timestamp + 960 : 0; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), data.length * 10); - return; - } - - this._setSpeaking(true); - - if (!data.startTime) { - /** - * Emitted once the dispatcher starts streaming - * @event StreamDispatcher#start - */ - this.emit('start'); - data.startTime = Date.now(); - } - - const bufferLength = 1920 * data.channels; - let buffer = this.stream.read(bufferLength); - if (!buffer) { - data.missed++; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), data.length * 10); - return; - } - - data.missed = 0; - - if (buffer.length !== bufferLength) { - const newBuffer = new Buffer(bufferLength).fill(0); - buffer.copy(newBuffer); - buffer = newBuffer; - } - - buffer = this._applyVolume(buffer); - - data.count++; - data.sequence = (data.sequence + 1) < 65536 ? data.sequence + 1 : 0; - data.timestamp = data.timestamp + 4294967295 ? data.timestamp + 960 : 0; - - this._sendBuffer(buffer, data.sequence, data.timestamp); - - const nextTime = data.length + (data.startTime + data.pausedTime + (data.count * data.length) - Date.now()); - this.player.voiceConnection.voiceManager.client.setTimeout(() => this._send(), nextTime); - } catch (e) { - this._triggerTerminalState('error', e); - } - } - - _triggerEnd(reason) { - /** - * Emitted once the stream has ended. Attach a `once` listener to this. - * @event StreamDispatcher#end - * @param {string} reason The reason for the end of the dispatcher. If it ended because it reached the end of the - * stream, this would be `stream`. If you invoke `.end()` without specifying a reason, this would be `user`. - */ - this.emit('end', reason); - } - - _triggerError(err) { - this.emit('end'); - /** - * Emitted once the stream has encountered an error. Attach a `once` listener to this. Also emits `end`. - * @event StreamDispatcher#error - * @param {Error} err The encountered error - */ - this.emit('error', err); - } - - _triggerTerminalState(state, err) { - if (this._triggered) return; - /** - * Emitted when the stream wants to give debug information. - * @event StreamDispatcher#debug - * @param {string} information The debug information - */ - this.emit('debug', `Triggered terminal state ${state} - stream is now dead`); - this._triggered = true; - this._setSpeaking(false); - switch (state) { - case 'end': - this._triggerEnd(err); - break; - case 'error': - this._triggerError(err); - break; - default: - this.emit('error', 'Unknown trigger state'); - break; - } - } - - _startStreaming() { - if (!this.stream) { - this.emit('error', 'No stream'); - return; - } - - this.stream.on('end', err => this._triggerTerminalState('end', err || 'stream')); - this.stream.on('error', err => this._triggerTerminalState('error', err)); - - const data = this.streamingData; - data.length = 20; - data.missed = 0; - - this.stream.once('readable', () => this._send()); - } - - _setPaused(paused) { - if (paused) { - this.paused = true; - this._setSpeaking(false); - } else { - this.paused = false; - this._setSpeaking(true); - } - } -} - -module.exports = StreamDispatcher; diff --git a/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js b/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js deleted file mode 100644 index 6c3ba6e..0000000 --- a/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js +++ /dev/null @@ -1,15 +0,0 @@ -class BaseOpus { - constructor(player) { - this.player = player; - } - - encode(buffer) { - return buffer; - } - - decode(buffer) { - return buffer; - } -} - -module.exports = BaseOpus; diff --git a/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js b/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js deleted file mode 100644 index 10f287b..0000000 --- a/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js +++ /dev/null @@ -1,27 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -let opus; - -class NodeOpusEngine extends OpusEngine { - constructor(player) { - super(player); - try { - opus = require('node-opus'); - } catch (err) { - throw err; - } - this.encoder = new opus.OpusEncoder(48000, 2); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 1920); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer, 1920); - } -} - -module.exports = NodeOpusEngine; diff --git a/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js b/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js deleted file mode 100644 index ffd512a..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js +++ /dev/null @@ -1,24 +0,0 @@ -const list = [ - require('./NodeOpusEngine'), - require('./OpusScriptEngine'), -]; - -function fetch(Encoder) { - try { - return new Encoder(); - } catch (err) { - return null; - } -} - -exports.add = encoder => { - list.push(encoder); -}; - -exports.fetch = () => { - for (const encoder of list) { - const fetched = fetch(encoder); - if (fetched) return fetched; - } - throw new Error('Couldn\'t find an Opus engine.'); -}; diff --git a/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js b/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js deleted file mode 100644 index 33b4ff5..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js +++ /dev/null @@ -1,27 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -let OpusScript; - -class NodeOpusEngine extends OpusEngine { - constructor(player) { - super(player); - try { - OpusScript = require('opusscript'); - } catch (err) { - throw err; - } - this.encoder = new OpusScript(48000, 2); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 960); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer); - } -} - -module.exports = NodeOpusEngine; diff --git a/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js b/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js deleted file mode 100644 index 6b7502f..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/ConverterEngine.js +++ /dev/null @@ -1,14 +0,0 @@ -const EventEmitter = require('events').EventEmitter; - -class ConverterEngine extends EventEmitter { - constructor(player) { - super(); - this.player = player; - } - - createConvertStream() { - return; - } -} - -module.exports = ConverterEngine; diff --git a/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js b/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js deleted file mode 100644 index 56d430e..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/ConverterEngineList.js +++ /dev/null @@ -1 +0,0 @@ -exports.fetch = () => require('./FfmpegConverterEngine'); diff --git a/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js b/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js deleted file mode 100644 index 8fb725b..0000000 --- a/node_modules/discord.js/src/client/voice/pcm/FfmpegConverterEngine.js +++ /dev/null @@ -1,86 +0,0 @@ -const ConverterEngine = require('./ConverterEngine'); -const ChildProcess = require('child_process'); -const EventEmitter = require('events').EventEmitter; - -class PCMConversionProcess extends EventEmitter { - constructor(process) { - super(); - this.process = process; - this.input = null; - this.process.on('error', e => this.emit('error', e)); - } - - setInput(stream) { - this.input = stream; - stream.pipe(this.process.stdin, { end: false }); - this.input.on('error', e => this.emit('error', e)); - this.process.stdin.on('error', e => this.emit('error', e)); - } - - destroy() { - this.emit('debug', 'destroying a ffmpeg process:'); - if (this.input && this.input.unpipe && this.process.stdin) { - this.input.unpipe(this.process.stdin); - this.emit('unpiped the user input stream from the process input stream'); - } - if (this.process.stdin) { - this.process.stdin.end(); - this.emit('ended the process stdin'); - } - if (this.process.stdin.destroy) { - this.process.stdin.destroy(); - this.emit('destroyed the process stdin'); - } - if (this.process.kill) { - this.process.kill(); - this.emit('killed the process'); - } - } - -} - -class FfmpegConverterEngine extends ConverterEngine { - constructor(player) { - super(player); - this.command = chooseCommand(); - } - - handleError(encoder, err) { - if (encoder.destroy) encoder.destroy(); - this.emit('error', err); - } - - createConvertStream(seek = 0) { - super.createConvertStream(); - const encoder = ChildProcess.spawn(this.command, [ - '-analyzeduration', '0', - '-loglevel', '0', - '-i', '-', - '-f', 's16le', - '-ar', '48000', - '-ac', '2', - '-ss', String(seek), - 'pipe:1', - ], { stdio: ['pipe', 'pipe', 'ignore'] }); - return new PCMConversionProcess(encoder); - } -} - -function chooseCommand() { - for (const cmd of [ - 'ffmpeg', - 'avconv', - './ffmpeg', - './avconv', - 'node_modules\\ffmpeg-binaries\\bin\\ffmpeg', - 'node_modules/ffmpeg-binaries/bin/ffmpeg', - ]) { - if (!ChildProcess.spawnSync(cmd, ['-h']).error) return cmd; - } - throw new Error( - 'FFMPEG was not found on your system, so audio cannot be played. ' + - 'Please make sure FFMPEG is installed and in your PATH.' - ); -} - -module.exports = FfmpegConverterEngine; diff --git a/node_modules/discord.js/src/client/voice/player/AudioPlayer.js b/node_modules/discord.js/src/client/voice/player/AudioPlayer.js deleted file mode 100644 index 96c6c24..0000000 --- a/node_modules/discord.js/src/client/voice/player/AudioPlayer.js +++ /dev/null @@ -1,80 +0,0 @@ -const PCMConverters = require('../pcm/ConverterEngineList'); -const OpusEncoders = require('../opus/OpusEngineList'); -const EventEmitter = require('events').EventEmitter; -const StreamDispatcher = require('../dispatcher/StreamDispatcher'); - -/** - * Represents the Audio Player of a Voice Connection - * @extends {EventEmitter} - * @private - */ -class AudioPlayer extends EventEmitter { - constructor(voiceConnection) { - super(); - /** - * The voice connection the player belongs to - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - this.audioToPCM = new (PCMConverters.fetch())(); - this.opusEncoder = OpusEncoders.fetch(); - this.currentConverter = null; - /** - * The current stream dispatcher, if a stream is being played - * @type {StreamDispatcher} - */ - this.dispatcher = null; - this.audioToPCM.on('error', e => this.emit('error', e)); - this.streamingData = { - channels: 2, - count: 0, - sequence: 0, - timestamp: 0, - pausedTime: 0, - }; - this.voiceConnection.on('closing', () => this.cleanup(null, 'voice connection closing')); - } - - playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - stream.on('end', () => { - this.emit('debug', 'Input stream to converter has ended'); - }); - stream.on('error', e => this.emit('error', e)); - const conversionProcess = this.audioToPCM.createConvertStream(options.seek); - conversionProcess.on('error', e => this.emit('error', e)); - conversionProcess.setInput(stream); - return this.playPCMStream(conversionProcess.process.stdout, conversionProcess, options); - } - - cleanup(checkStream, reason) { - // cleanup is a lot less aggressive than v9 because it doesn't try to kill every single stream it is aware of - this.emit('debug', `Clean up triggered due to ${reason}`); - const filter = checkStream && this.dispatcher && this.dispatcher.stream === checkStream; - if (this.currentConverter && (checkStream ? filter : true)) { - this.currentConverter.destroy(); - this.currentConverter = null; - } - } - - playPCMStream(stream, converter, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - stream.on('end', () => this.emit('debug', 'PCM input stream ended')); - this.cleanup(null, 'outstanding play stream'); - this.currentConverter = converter; - if (this.dispatcher) { - this.streamingData = this.dispatcher.streamingData; - } - stream.on('error', e => this.emit('error', e)); - const dispatcher = new StreamDispatcher(this, stream, this.streamingData, options); - dispatcher.on('error', e => this.emit('error', e)); - dispatcher.on('end', () => this.cleanup(dispatcher.stream, 'dispatcher ended')); - dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value)); - this.dispatcher = dispatcher; - dispatcher.on('debug', m => this.emit('debug', `Stream dispatch - ${m}`)); - return dispatcher; - } - -} - -module.exports = AudioPlayer; diff --git a/node_modules/discord.js/src/client/voice/player/BasePlayer.js b/node_modules/discord.js/src/client/voice/player/BasePlayer.js deleted file mode 100644 index d5285cd..0000000 --- a/node_modules/discord.js/src/client/voice/player/BasePlayer.js +++ /dev/null @@ -1,121 +0,0 @@ -const OpusEngines = require('../opus/OpusEngineList'); -const ConverterEngines = require('../pcm/ConverterEngineList'); -const Constants = require('../../../util/Constants'); -const StreamDispatcher = require('../dispatcher/StreamDispatcher'); -const EventEmitter = require('events').EventEmitter; - -class VoiceConnectionPlayer extends EventEmitter { - constructor(connection) { - super(); - this.connection = connection; - this.opusEncoder = OpusEngines.fetch(); - const Engine = ConverterEngines.fetch(); - this.converterEngine = new Engine(this); - this.converterEngine.on('error', err => { - this._shutdown(); - this.emit('error', err); - }); - this.speaking = false; - this.processMap = new Map(); - this.dispatcher = null; - this._streamingData = { - sequence: 0, - timestamp: 0, - }; - } - - convertStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - const encoder = this.converterEngine.createConvertStream(options.seek); - const pipe = stream.pipe(encoder.stdin, { end: false }); - pipe.on('unpipe', () => { - this.killStream(encoder.stdout); - pipe.destroy(); - }); - this.processMap.set(encoder.stdout, { - pcmConverter: encoder, - inputStream: stream, - }); - return encoder.stdout; - } - - _shutdown() { - this.speaking = false; - if (this.dispatcher) this.dispatcher._triggerTerminalState('end', 'ended by parent player shutdown'); - for (const stream of this.processMap.keys()) this.killStream(stream); - } - - killStream(stream) { - const streams = this.processMap.get(stream); - this._streamingData = this.dispatcher.streamingData; - this.emit(Constants.Events.DEBUG, 'Cleaning up player after audio stream ended or encountered an error'); - - const dummyHandler = () => null; - - if (streams) { - this.processMap.delete(stream); - if (streams.inputStream && streams.pcmConverter) { - try { - streams.inputStream.once('error', dummyHandler); - streams.pcmConverter.once('error', dummyHandler); - streams.pcmConverter.stdin.once('error', dummyHandler); - streams.pcmConverter.stdout.once('error', dummyHandler); - if (streams.inputStream.unpipe) { - streams.inputStream.unpipe(streams.pcmConverter.stdin); - this.emit(Constants.Events.DEBUG, '- Unpiped input stream'); - } else if (streams.inputStream.destroy) { - streams.inputStream.destroy(); - this.emit(Constants.Events.DEBUG, '- Couldn\'t unpipe input stream, so destroyed input stream'); - } - if (streams.pcmConverter.stdin) { - streams.pcmConverter.stdin.end(); - this.emit(Constants.Events.DEBUG, '- Ended input stream to PCM converter'); - } - if (streams.pcmConverter && streams.pcmConverter.kill) { - streams.pcmConverter.kill('SIGINT'); - this.emit(Constants.Events.DEBUG, '- Killed the PCM converter'); - } - } catch (err) { - // if an error happened make sure the pcm converter is killed anyway - try { - if (streams.pcmConverter && streams.pcmConverter.kill) { - streams.pcmConverter.kill('SIGINT'); - this.emit(Constants.Events.DEBUG, '- Killed the PCM converter after previous error (abnormal)'); - } - } catch (e) { - return e; - } - return err; - } - } - } - return null; - } - - setSpeaking(value) { - if (this.speaking === value) return; - this.speaking = value; - this.connection.websocket.send({ - op: Constants.VoiceOPCodes.SPEAKING, - d: { - speaking: true, - delay: 0, - }, - }).catch(e => { - this.emit('debug', e); - }); - } - - playPCMStream(pcmStream, { seek = 0, volume = 1, passes = 1 } = {}) { - const options = { seek, volume, passes }; - const dispatcher = new StreamDispatcher(this, pcmStream, this._streamingData, options); - dispatcher.on('speaking', value => this.setSpeaking(value)); - dispatcher.on('end', () => this.killStream(pcmStream)); - dispatcher.on('error', () => this.killStream(pcmStream)); - dispatcher.setVolume(options.volume); - this.dispatcher = dispatcher; - return dispatcher; - } -} - -module.exports = VoiceConnectionPlayer; diff --git a/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js b/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js deleted file mode 100644 index b465e8c..0000000 --- a/node_modules/discord.js/src/client/voice/player/DefaultPlayer.js +++ /dev/null @@ -1,19 +0,0 @@ -const BasePlayer = require('./BasePlayer'); -const fs = require('fs'); - -class DefaultPlayer extends BasePlayer { - playFile(file, { seek = 0, volume = 1 } = {}) { - const options = { seek: seek, volume: volume }; - return this.playStream(fs.createReadStream(file), options); - } - - playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) { - this._shutdown(); - const options = { seek, volume, passes }; - const pcmStream = this.convertStream(stream, options); - const dispatcher = this.playPCMStream(pcmStream, options); - return dispatcher; - } -} - -module.exports = DefaultPlayer; diff --git a/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js b/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js deleted file mode 100644 index 50ace27..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js +++ /dev/null @@ -1,19 +0,0 @@ -const Readable = require('stream').Readable; - -class VoiceReadable extends Readable { - constructor() { - super(); - this._packets = []; - this.open = true; - } - - _read() { - return; - } - - _push(d) { - if (this.open) this.push(d); - } -} - -module.exports = VoiceReadable; diff --git a/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js b/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js deleted file mode 100644 index bc9156f..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js +++ /dev/null @@ -1,154 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const NaCl = require('tweetnacl'); -const Readable = require('./VoiceReadable'); - -const nonce = new Buffer(24); -nonce.fill(0); - -/** - * Receives voice data from a voice connection. - * ```js - * // obtained using: - * voiceChannel.join().then(connection => { - * const receiver = connection.createReceiver(); - * }); - * ``` - * @extends {EventEmitter} - */ -class VoiceReceiver extends EventEmitter { - constructor(connection) { - super(); - /* - need a queue because we don't get the ssrc of the user speaking until after the first few packets, - so we queue up unknown SSRCs until they become known, then empty the queue. - */ - this.queues = new Map(); - this.pcmStreams = new Map(); - this.opusStreams = new Map(); - - /** - * Whether or not this receiver has been destroyed. - * @type {boolean} - */ - this.destroyed = false; - - /** - * The VoiceConnection that instantiated this - * @type {VoiceConnection} - */ - this.voiceConnection = connection; - - this._listener = msg => { - const ssrc = +msg.readUInt32BE(8).toString(10); - const user = this.voiceConnection.ssrcMap.get(ssrc); - if (!user) { - if (!this.queues.has(ssrc)) this.queues.set(ssrc, []); - this.queues.get(ssrc).push(msg); - } else { - if (this.queues.get(ssrc)) { - this.queues.get(ssrc).push(msg); - this.queues.get(ssrc).map(m => this.handlePacket(m, user)); - this.queues.delete(ssrc); - return; - } - this.handlePacket(msg, user); - } - }; - this.voiceConnection.sockets.udp.socket.on('message', this._listener); - } - - /** - * If this VoiceReceiver has been destroyed, running `recreate()` will recreate the listener. - * This avoids you having to create a new receiver. - * <info>Any streams that you had prior to destroying the receiver will not be recreated.</info> - */ - recreate() { - if (!this.destroyed) return; - this.voiceConnection.sockets.udp.socket.on('message', this._listener); - this.destroyed = false; - return; - } - - /** - * Destroy this VoiceReceiver, also ending any streams that it may be controlling. - */ - destroy() { - this.voiceConnection.sockets.udp.socket.removeListener('message', this._listener); - for (const stream of this.pcmStreams) { - stream[1]._push(null); - this.pcmStreams.delete(stream[0]); - } - for (const stream of this.opusStreams) { - stream[1]._push(null); - this.opusStreams.delete(stream[0]); - } - this.destroyed = true; - } - - /** - * Creates a readable stream for a user that provides opus data while the user is speaking. When the user - * stops speaking, the stream is destroyed. - * @param {UserResolvable} user The user to create the stream for - * @returns {ReadableStream} - */ - createOpusStream(user) { - user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user); - if (!user) throw new Error('Couldn\'t resolve the user to create Opus stream.'); - if (this.opusStreams.get(user.id)) throw new Error('There is already an existing stream for that user.'); - const stream = new Readable(); - this.opusStreams.set(user.id, stream); - return stream; - } - - /** - * Creates a readable stream for a user that provides PCM data while the user is speaking. When the user - * stops speaking, the stream is destroyed. The stream is 32-bit signed stereo PCM at 48KHz. - * @param {UserResolvable} user The user to create the stream for - * @returns {ReadableStream} - */ - createPCMStream(user) { - user = this.voiceConnection.voiceManager.client.resolver.resolveUser(user); - if (!user) throw new Error('Couldn\'t resolve the user to create PCM stream.'); - if (this.pcmStreams.get(user.id)) throw new Error('There is already an existing stream for that user.'); - const stream = new Readable(); - this.pcmStreams.set(user.id, stream); - return stream; - } - - handlePacket(msg, user) { - msg.copy(nonce, 0, 0, 12); - let data = NaCl.secretbox.open(msg.slice(12), nonce, this.voiceConnection.authentication.secretKey.key); - if (!data) { - /** - * Emitted whenever a voice packet cannot be decrypted - * @event VoiceReceiver#warn - * @param {string} message The warning message - */ - this.emit('warn', 'Failed to decrypt voice packet'); - return; - } - data = new Buffer(data); - if (this.opusStreams.get(user.id)) this.opusStreams.get(user.id)._push(data); - /** - * Emitted whenever voice data is received from the voice connection. This is _always_ emitted (unlike PCM). - * @event VoiceReceiver#opus - * @param {User} user The user that is sending the buffer (is speaking) - * @param {Buffer} buffer The opus buffer - */ - this.emit('opus', user, data); - if (this.listenerCount('pcm') > 0 || this.pcmStreams.size > 0) { - /** - * Emits decoded voice data when it's received. For performance reasons, the decoding will only - * happen if there is at least one `pcm` listener on this receiver. - * @event VoiceReceiver#pcm - * @param {User} user The user that is sending the buffer (is speaking) - * @param {Buffer} buffer The decoded buffer - */ - const pcm = this.voiceConnection.player.opusEncoder.decode(data); - if (this.pcmStreams.get(user.id)) this.pcmStreams.get(user.id)._push(pcm); - this.emit('pcm', user, pcm); - } - } -} - -module.exports = VoiceReceiver; diff --git a/node_modules/discord.js/src/client/voice/util/SecretKey.js b/node_modules/discord.js/src/client/voice/util/SecretKey.js deleted file mode 100644 index 508a1ba..0000000 --- a/node_modules/discord.js/src/client/voice/util/SecretKey.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Represents a Secret Key used in encryption over voice - * @private - */ -class SecretKey { - constructor(key) { - /** - * The key used for encryption - * @type {Uint8Array} - */ - this.key = new Uint8Array(new ArrayBuffer(key.length)); - for (const index in key) this.key[index] = key[index]; - } -} - -module.exports = SecretKey; diff --git a/node_modules/discord.js/src/client/websocket/WebSocketManager.js b/node_modules/discord.js/src/client/websocket/WebSocketManager.js deleted file mode 100644 index b67af59..0000000 --- a/node_modules/discord.js/src/client/websocket/WebSocketManager.js +++ /dev/null @@ -1,373 +0,0 @@ -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 deleted file mode 100644 index 78f5777..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js +++ /dev/null @@ -1,125 +0,0 @@ -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 deleted file mode 100644 index c1c2a5a..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/AbstractHandler.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 04cb298..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelCreate.js +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index b25f585..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelDelete.js +++ /dev/null @@ -1,20 +0,0 @@ -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 deleted file mode 100644 index 636df81..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelPinsUpdate.js +++ /dev/null @@ -1,31 +0,0 @@ -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 deleted file mode 100644 index fa535b1..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 60ce72d..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanAdd.js +++ /dev/null @@ -1,23 +0,0 @@ -// ##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 deleted file mode 100644 index c4edbde..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildBanRemove.js +++ /dev/null @@ -1,20 +0,0 @@ -// ##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 deleted file mode 100644 index c7fbd7e..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildCreate.js +++ /dev/null @@ -1,22 +0,0 @@ -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 deleted file mode 100644 index 35e3c53..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildDelete.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index c6ebdaa..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildEmojisUpdate.js +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index d4d122f..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberAdd.js +++ /dev/null @@ -1,17 +0,0 @@ -// ##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 deleted file mode 100644 index 6ec1bfe..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberRemove.js +++ /dev/null @@ -1,13 +0,0 @@ -// ##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 deleted file mode 100644 index 94ac71f..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMemberUpdate.js +++ /dev/null @@ -1,18 +0,0 @@ -// ##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 deleted file mode 100644 index 02a3c3c..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMembersChunk.js +++ /dev/null @@ -1,28 +0,0 @@ -// ##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 deleted file mode 100644 index 8581d53..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleCreate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 63439b0..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleDelete.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 6fbdc10..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildRoleUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 0b9f5aa..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildSync.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 70eff52..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 058dc85..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageCreate.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index b06ce98..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDelete.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 6cd3648..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageDeleteBulk.js +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index a58db70..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionAdd.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index cddde70..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemove.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 303da9c..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 527632d..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 09d78a0..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/PresenceUpdate.js +++ /dev/null @@ -1,72 +0,0 @@ -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 deleted file mode 100644 index 10bc6b2..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/Ready.js +++ /dev/null @@ -1,69 +0,0 @@ -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 deleted file mode 100644 index 122b4c5..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipAdd.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index b57326a..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/RelationshipRemove.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 1a35ca7..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/TypingStart.js +++ /dev/null @@ -1,68 +0,0 @@ -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 deleted file mode 100644 index 1e4777a..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/UserNoteUpdate.js +++ /dev/null @@ -1,12 +0,0 @@ -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 deleted file mode 100644 index bc34f34..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/UserUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index 97885d6..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceServerUpdate.js +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index ddbfbfc..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceStateUpdate.js +++ /dev/null @@ -1,49 +0,0 @@ -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; diff --git a/node_modules/discord.js/src/index.js b/node_modules/discord.js/src/index.js deleted file mode 100644 index 85326bf..0000000 --- a/node_modules/discord.js/src/index.js +++ /dev/null @@ -1,47 +0,0 @@ -module.exports = { - Client: require('./client/Client'), - WebhookClient: require('./client/WebhookClient'), - Shard: require('./sharding/Shard'), - ShardClientUtil: require('./sharding/ShardClientUtil'), - ShardingManager: require('./sharding/ShardingManager'), - - Collection: require('./util/Collection'), - splitMessage: require('./util/SplitMessage'), - escapeMarkdown: require('./util/EscapeMarkdown'), - fetchRecommendedShards: require('./util/FetchRecommendedShards'), - - Channel: require('./structures/Channel'), - ClientOAuth2Application: require('./structures/ClientOAuth2Application'), - ClientUser: require('./structures/ClientUser'), - DMChannel: require('./structures/DMChannel'), - Emoji: require('./structures/Emoji'), - EvaluatedPermissions: require('./structures/EvaluatedPermissions'), - Game: require('./structures/Presence').Game, - GroupDMChannel: require('./structures/GroupDMChannel'), - Guild: require('./structures/Guild'), - GuildChannel: require('./structures/GuildChannel'), - GuildMember: require('./structures/GuildMember'), - Invite: require('./structures/Invite'), - Message: require('./structures/Message'), - MessageAttachment: require('./structures/MessageAttachment'), - MessageCollector: require('./structures/MessageCollector'), - MessageEmbed: require('./structures/MessageEmbed'), - MessageReaction: require('./structures/MessageReaction'), - OAuth2Application: require('./structures/OAuth2Application'), - PartialGuild: require('./structures/PartialGuild'), - PartialGuildChannel: require('./structures/PartialGuildChannel'), - PermissionOverwrites: require('./structures/PermissionOverwrites'), - Presence: require('./structures/Presence').Presence, - ReactionEmoji: require('./structures/ReactionEmoji'), - RichEmbed: require('./structures/RichEmbed'), - Role: require('./structures/Role'), - TextChannel: require('./structures/TextChannel'), - User: require('./structures/User'), - VoiceChannel: require('./structures/VoiceChannel'), - Webhook: require('./structures/Webhook'), - - version: require('../package').version, - Constants: require('./util/Constants'), -}; - -if (typeof window !== 'undefined') window.Discord = module.exports; // eslint-disable-line no-undef diff --git a/node_modules/discord.js/src/sharding/Shard.js b/node_modules/discord.js/src/sharding/Shard.js deleted file mode 100644 index ab9b923..0000000 --- a/node_modules/discord.js/src/sharding/Shard.js +++ /dev/null @@ -1,164 +0,0 @@ -const childProcess = require('child_process'); -const path = require('path'); -const makeError = require('../util/MakeError'); -const makePlainError = require('../util/MakePlainError'); - -/** - * Represents a Shard spawned by the ShardingManager. - */ -class Shard { - /** - * @param {ShardingManager} manager The sharding manager - * @param {number} id The ID of this shard - * @param {Array} [args=[]] Command line arguments to pass to the script - */ - constructor(manager, id, args = []) { - /** - * Manager that created the shard - * @type {ShardingManager} - */ - this.manager = manager; - - /** - * ID of the shard - * @type {number} - */ - this.id = id; - - /** - * The environment variables for the shard - * @type {Object} - */ - this.env = Object.assign({}, process.env, { - SHARD_ID: this.id, - SHARD_COUNT: this.manager.totalShards, - CLIENT_TOKEN: this.manager.token, - }); - - /** - * Process of the shard - * @type {ChildProcess} - */ - this.process = childProcess.fork(path.resolve(this.manager.file), args, { - env: this.env, - }); - this.process.on('message', this._handleMessage.bind(this)); - this.process.once('exit', () => { - if (this.manager.respawn) this.manager.createShard(this.id); - }); - - this._evals = new Map(); - this._fetches = new Map(); - } - - /** - * Sends a message to the shard's process. - * @param {*} message Message to send to the shard - * @returns {Promise<Shard>} - */ - send(message) { - return new Promise((resolve, reject) => { - const sent = this.process.send(message, err => { - if (err) reject(err); else resolve(this); - }); - if (!sent) throw new Error('Failed to send message to shard\'s process.'); - }); - } - - /** - * Fetches a Client property value of the shard. - * @param {string} prop Name of the Client property to get, using periods for nesting - * @returns {Promise<*>} - * @example - * shard.fetchClientValue('guilds.size').then(count => { - * console.log(`${count} guilds in shard ${shard.id}`); - * }).catch(console.error); - */ - fetchClientValue(prop) { - if (this._fetches.has(prop)) return this._fetches.get(prop); - - const promise = new Promise((resolve, reject) => { - const listener = message => { - if (!message || message._fetchProp !== prop) return; - this.process.removeListener('message', listener); - this._fetches.delete(prop); - resolve(message._result); - }; - this.process.on('message', listener); - - this.send({ _fetchProp: prop }).catch(err => { - this.process.removeListener('message', listener); - this._fetches.delete(prop); - reject(err); - }); - }); - - this._fetches.set(prop, promise); - return promise; - } - - /** - * Evaluates a script on the shard, in the context of the Client. - * @param {string} script JavaScript to run on the shard - * @returns {Promise<*>} Result of the script execution - */ - eval(script) { - if (this._evals.has(script)) return this._evals.get(script); - - const promise = new Promise((resolve, reject) => { - const listener = message => { - if (!message || message._eval !== script) return; - this.process.removeListener('message', listener); - this._evals.delete(script); - if (!message._error) resolve(message._result); else reject(makeError(message._error)); - }; - this.process.on('message', listener); - - this.send({ _eval: script }).catch(err => { - this.process.removeListener('message', listener); - this._evals.delete(script); - reject(err); - }); - }); - - this._evals.set(script, promise); - return promise; - } - - /** - * Handles an IPC message - * @param {*} message Message received - * @private - */ - _handleMessage(message) { - if (message) { - // Shard is requesting a property fetch - if (message._sFetchProp) { - this.manager.fetchClientValues(message._sFetchProp).then( - results => this.send({ _sFetchProp: message._sFetchProp, _result: results }), - err => this.send({ _sFetchProp: message._sFetchProp, _error: makePlainError(err) }) - ); - return; - } - - // Shard is requesting an eval broadcast - if (message._sEval) { - this.manager.broadcastEval(message._sEval).then( - results => this.send({ _sEval: message._sEval, _result: results }), - err => this.send({ _sEval: message._sEval, _error: makePlainError(err) }) - ); - return; - } - } - - /** - * Emitted upon recieving a message from a shard - * @event ShardingManager#message - * @param {Shard} shard Shard that sent the message - * @param {*} message Message that was received - */ - this.manager.emit('message', this, message); - } -} - -module.exports = Shard; diff --git a/node_modules/discord.js/src/sharding/ShardClientUtil.js b/node_modules/discord.js/src/sharding/ShardClientUtil.js deleted file mode 100644 index 6449941..0000000 --- a/node_modules/discord.js/src/sharding/ShardClientUtil.js +++ /dev/null @@ -1,143 +0,0 @@ -const makeError = require('../util/MakeError'); -const makePlainError = require('../util/MakePlainError'); - -/** - * Helper class for sharded clients spawned as a child process, such as from a ShardingManager - */ -class ShardClientUtil { - /** - * @param {Client} client Client of the current shard - */ - constructor(client) { - this.client = client; - process.on('message', this._handleMessage.bind(this)); - } - - /** - * ID of this shard - * @type {number} - * @readonly - */ - get id() { - return this.client.options.shardId; - } - - /** - * Total number of shards - * @type {number} - * @readonly - */ - get count() { - return this.client.options.shardCount; - } - - /** - * Sends a message to the master process - * @param {*} message Message to send - * @returns {Promise<void>} - */ - send(message) { - return new Promise((resolve, reject) => { - const sent = process.send(message, err => { - if (err) reject(err); else resolve(); - }); - if (!sent) throw new Error('Failed to send message to master process.'); - }); - } - - /** - * Fetches a Client property value of each shard. - * @param {string} prop Name of the Client property to get, using periods for nesting - * @returns {Promise<Array>} - * @example - * client.shard.fetchClientValues('guilds.size').then(results => { - * console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`); - * }).catch(console.error); - */ - fetchClientValues(prop) { - return new Promise((resolve, reject) => { - const listener = message => { - if (!message || message._sFetchProp !== prop) return; - process.removeListener('message', listener); - if (!message._error) resolve(message._result); else reject(makeError(message._error)); - }; - process.on('message', listener); - - this.send({ _sFetchProp: prop }).catch(err => { - process.removeListener('message', listener); - reject(err); - }); - }); - } - - /** - * Evaluates a script on all shards, in the context of the Clients. - * @param {string} script JavaScript to run on each shard - * @returns {Promise<Array>} Results of the script execution - */ - broadcastEval(script) { - return new Promise((resolve, reject) => { - const listener = message => { - if (!message || message._sEval !== script) return; - process.removeListener('message', listener); - if (!message._error) resolve(message._result); else reject(makeError(message._error)); - }; - process.on('message', listener); - - this.send({ _sEval: script }).catch(err => { - process.removeListener('message', listener); - reject(err); - }); - }); - } - - /** - * Handles an IPC message - * @param {*} message Message received - * @private - */ - _handleMessage(message) { - if (!message) return; - if (message._fetchProp) { - const props = message._fetchProp.split('.'); - let value = this.client; - for (const prop of props) value = value[prop]; - this._respond('fetchProp', { _fetchProp: message._fetchProp, _result: value }); - } else if (message._eval) { - try { - this._respond('eval', { _eval: message._eval, _result: this.client._eval(message._eval) }); - } catch (err) { - this._respond('eval', { _eval: message._eval, _error: makePlainError(err) }); - } - } - } - - /** - * Sends a message to the master process, emitting an error from the client upon failure - * @param {string} type Type of response to send - * @param {*} message Message to send - * @private - */ - _respond(type, message) { - this.send(message).catch(err => { - err.message = `Error when sending ${type} response to master process: ${err.message}`; - this.client.emit('error', err); - }); - } - - /** - * Creates/gets the singleton of this class - * @param {Client} client Client to use - * @returns {ShardClientUtil} - */ - static singleton(client) { - if (!this._singleton) { - this._singleton = new this(client); - } else { - client.emit('warn', 'Multiple clients created in child process; only the first will handle sharding helpers.'); - } - return this._singleton; - } -} - -module.exports = ShardClientUtil; diff --git a/node_modules/discord.js/src/sharding/ShardingManager.js b/node_modules/discord.js/src/sharding/ShardingManager.js deleted file mode 100644 index 671b5d7..0000000 --- a/node_modules/discord.js/src/sharding/ShardingManager.js +++ /dev/null @@ -1,193 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const EventEmitter = require('events').EventEmitter; -const mergeDefault = require('../util/MergeDefault'); -const Shard = require('./Shard'); -const Collection = require('../util/Collection'); -const fetchRecommendedShards = require('../util/FetchRecommendedShards'); - -/** - * This is a utility class that can be used to help you spawn shards of your Client. Each shard is completely separate - * from the other. The Shard Manager takes a path to a file and spawns it under the specified amount of shards safely. - * If you do not select an amount of shards, the manager will automatically decide the best amount. - * @extends {EventEmitter} - */ -class ShardingManager extends EventEmitter { - /** - * @param {string} file Path to your shard script file - * @param {Object} [options] Options for the sharding manager - * @param {number|string} [options.totalShards='auto'] Number of shards to spawn, or "auto" - * @param {boolean} [options.respawn=true] Whether shards should automatically respawn upon exiting - * @param {string[]} [options.shardArgs=[]] Arguments to pass to the shard script when spawning - * @param {string} [options.token] Token to use for automatic shard count and passing to shards - */ - constructor(file, options = {}) { - super(); - options = mergeDefault({ - totalShards: 'auto', - respawn: true, - shardArgs: [], - token: null, - }, options); - - /** - * Path to the shard script file - * @type {string} - */ - this.file = file; - if (!file) throw new Error('File must be specified.'); - if (!path.isAbsolute(file)) this.file = path.resolve(process.cwd(), file); - const stats = fs.statSync(this.file); - if (!stats.isFile()) throw new Error('File path does not point to a file.'); - - /** - * Amount of shards that this manager is going to spawn - * @type {number|string} - */ - this.totalShards = options.totalShards; - if (this.totalShards !== 'auto') { - if (typeof this.totalShards !== 'number' || isNaN(this.totalShards)) { - throw new TypeError('Amount of shards must be a number.'); - } - if (this.totalShards < 1) throw new RangeError('Amount of shards must be at least 1.'); - if (this.totalShards !== Math.floor(this.totalShards)) { - throw new RangeError('Amount of shards must be an integer.'); - } - } - - /** - * Whether shards should automatically respawn upon exiting - * @type {boolean} - */ - this.respawn = options.respawn; - - /** - * An array of arguments to pass to shards. - * @type {string[]} - */ - this.shardArgs = options.shardArgs; - - /** - * Token to use for obtaining the automatic shard count, and passing to shards - * @type {?string} - */ - this.token = options.token ? options.token.replace(/^Bot\s*/i, '') : null; - - /** - * A collection of shards that this manager has spawned - * @type {Collection<number, Shard>} - */ - this.shards = new Collection(); - } - - /** - * Spawns a single shard. - * @param {number} id The ID of the shard to spawn. **This is usually not necessary.** - * @returns {Promise<Shard>} - */ - createShard(id = this.shards.size) { - const shard = new Shard(this, id, this.shardArgs); - this.shards.set(id, shard); - /** - * Emitted upon launching a shard - * @event ShardingManager#launch - * @param {Shard} shard Shard that was launched - */ - this.emit('launch', shard); - return Promise.resolve(shard); - } - - /** - * Spawns multiple shards. - * @param {number} [amount=this.totalShards] Number of shards to spawn - * @param {number} [delay=5500] How long to wait in between spawning each shard (in milliseconds) - * @returns {Promise<Collection<number, Shard>>} - */ - spawn(amount = this.totalShards, delay = 5500) { - if (amount === 'auto') { - return fetchRecommendedShards(this.token).then(count => { - this.totalShards = count; - return this._spawn(count, delay); - }); - } else { - if (typeof amount !== 'number' || isNaN(amount)) throw new TypeError('Amount of shards must be a number.'); - if (amount < 1) throw new RangeError('Amount of shards must be at least 1.'); - if (amount !== Math.floor(amount)) throw new TypeError('Amount of shards must be an integer.'); - return this._spawn(amount, delay); - } - } - - /** - * Actually spawns shards, unlike that poser above >:( - * @param {number} amount Number of shards to spawn - * @param {number} delay How long to wait in between spawning each shard (in milliseconds) - * @returns {Promise<Collection<number, Shard>>} - * @private - */ - _spawn(amount, delay) { - return new Promise(resolve => { - if (this.shards.size >= amount) throw new Error(`Already spawned ${this.shards.size} shards.`); - this.totalShards = amount; - - this.createShard(); - if (this.shards.size >= this.totalShards) { - resolve(this.shards); - return; - } - - if (delay <= 0) { - while (this.shards.size < this.totalShards) this.createShard(); - resolve(this.shards); - } else { - const interval = setInterval(() => { - this.createShard(); - if (this.shards.size >= this.totalShards) { - clearInterval(interval); - resolve(this.shards); - } - }, delay); - } - }); - } - - /** - * Send a message to all shards. - * @param {*} message Message to be sent to the shards - * @returns {Promise<Shard[]>} - */ - broadcast(message) { - const promises = []; - for (const shard of this.shards.values()) promises.push(shard.send(message)); - return Promise.all(promises); - } - - /** - * Evaluates a script on all shards, in the context of the Clients. - * @param {string} script JavaScript to run on each shard - * @returns {Promise<Array>} Results of the script execution - */ - broadcastEval(script) { - const promises = []; - for (const shard of this.shards.values()) promises.push(shard.eval(script)); - return Promise.all(promises); - } - - /** - * Fetches a Client property value of each shard. - * @param {string} prop Name of the Client property to get, using periods for nesting - * @returns {Promise<Array>} - * @example - * manager.fetchClientValues('guilds.size').then(results => { - * console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`); - * }).catch(console.error); - */ - fetchClientValues(prop) { - if (this.shards.size === 0) return Promise.reject(new Error('No shards have been spawned.')); - if (this.shards.size !== this.totalShards) return Promise.reject(new Error('Still spawning shards.')); - const promises = []; - for (const shard of this.shards.values()) promises.push(shard.fetchClientValue(prop)); - return Promise.all(promises); - } -} - -module.exports = ShardingManager; diff --git a/node_modules/discord.js/src/structures/Channel.js b/node_modules/discord.js/src/structures/Channel.js deleted file mode 100644 index b37b14b..0000000 --- a/node_modules/discord.js/src/structures/Channel.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Represents any channel on Discord - */ -class Channel { - constructor(client, data) { - /** - * The client that instantiated the Channel - * @name Channel#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The type of the channel, either: - * * `dm` - a DM channel - * * `group` - a Group DM channel - * * `text` - a guild text channel - * * `voice` - a guild voice channel - * @type {string} - */ - this.type = null; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The unique ID of the channel - * @type {string} - */ - this.id = data.id; - } - - /** - * The timestamp the channel was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the channel was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Deletes the channel - * @returns {Promise<Channel>} - * @example - * // delete the channel - * channel.delete() - * .then() // success - * .catch(console.error); // log error - */ - delete() { - return this.client.rest.methods.deleteChannel(this); - } -} - -module.exports = Channel; diff --git a/node_modules/discord.js/src/structures/ClientOAuth2Application.js b/node_modules/discord.js/src/structures/ClientOAuth2Application.js deleted file mode 100644 index 46e1250..0000000 --- a/node_modules/discord.js/src/structures/ClientOAuth2Application.js +++ /dev/null @@ -1,26 +0,0 @@ -const User = require('./User'); -const OAuth2Application = require('./OAuth2Application'); - -/** - * Represents the client's OAuth2 Application - * @extends {OAuth2Application} - */ -class ClientOAuth2Application extends OAuth2Application { - setup(data) { - super.setup(data); - - /** - * The app's flags - * @type {number} - */ - this.flags = data.flags; - - /** - * The app's owner - * @type {User} - */ - this.owner = new User(this.client, data.owner); - } -} - -module.exports = ClientOAuth2Application; diff --git a/node_modules/discord.js/src/structures/ClientUser.js b/node_modules/discord.js/src/structures/ClientUser.js deleted file mode 100644 index d526af6..0000000 --- a/node_modules/discord.js/src/structures/ClientUser.js +++ /dev/null @@ -1,274 +0,0 @@ -const User = require('./User'); -const Collection = require('../util/Collection'); - -/** - * Represents the logged in client's Discord user - * @extends {User} - */ -class ClientUser extends User { - setup(data) { - super.setup(data); - - /** - * Whether or not this account has been verified - * @type {boolean} - */ - this.verified = data.verified; - - /** - * The email of this account - * @type {string} - */ - this.email = data.email; - this.localPresence = {}; - this._typing = new Map(); - - /** - * A Collection of friends for the logged in user. - * <warn>This is only filled when using a user account.</warn> - * @type {Collection<string, User>} - */ - this.friends = new Collection(); - - /** - * A Collection of blocked users for the logged in user. - * <warn>This is only filled when using a user account.</warn> - * @type {Collection<string, User>} - */ - this.blocked = new Collection(); - - /** - * A Collection of notes for the logged in user. - * <warn>This is only filled when using a user account.</warn> - * @type {Collection<string, string>} - */ - this.notes = new Collection(); - } - - edit(data) { - return this.client.rest.methods.updateCurrentUser(data); - } - - /** - * Set the username of the logged in Client. - * <info>Changing usernames in Discord is heavily rate limited, with only 2 requests - * every hour. Use this sparingly!</info> - * @param {string} username The new username - * @param {string} [password] Current password (only for user accounts) - * @returns {Promise<ClientUser>} - * @example - * // set username - * client.user.setUsername('discordjs') - * .then(user => console.log(`My new username is ${user.username}`)) - * .catch(console.error); - */ - setUsername(username, password) { - return this.client.rest.methods.updateCurrentUser({ username }, password); - } - - /** - * Changes the email for the client user's account. - * <warn>This is only available when using a user account.</warn> - * @param {string} email New email to change to - * @param {string} password Current password - * @returns {Promise<ClientUser>} - * @example - * // set email - * client.user.setEmail('bob@gmail.com', 'some amazing password 123') - * .then(user => console.log(`My new email is ${user.email}`)) - * .catch(console.error); - */ - setEmail(email, password) { - return this.client.rest.methods.updateCurrentUser({ email }, password); - } - - /** - * Changes the password for the client user's account. - * <warn>This is only available when using a user account.</warn> - * @param {string} newPassword New password to change to - * @param {string} oldPassword Current password - * @returns {Promise<ClientUser>} - * @example - * // set password - * client.user.setPassword('some new amazing password 456', 'some amazing password 123') - * .then(user => console.log('New password set!')) - * .catch(console.error); - */ - setPassword(newPassword, oldPassword) { - return this.client.rest.methods.updateCurrentUser({ password: newPassword }, oldPassword); - } - - /** - * Set the avatar of the logged in Client. - * @param {BufferResolvable|Base64Resolvable} avatar The new avatar - * @returns {Promise<ClientUser>} - * @example - * // set avatar - * client.user.setAvatar('./avatar.png') - * .then(user => console.log(`New avatar set!`)) - * .catch(console.error); - */ - setAvatar(avatar) { - if (avatar.startsWith('data:')) { - return this.client.rest.methods.updateCurrentUser({ avatar }); - } else { - return this.client.resolver.resolveBuffer(avatar).then(data => - this.client.rest.methods.updateCurrentUser({ avatar: data }) - ); - } - } - - /** - * Data resembling a raw Discord presence - * @typedef {Object} PresenceData - * @property {PresenceStatus} [status] Status of the user - * @property {boolean} [afk] Whether the user is AFK - * @property {Object} [game] Game the user is playing - * @property {string} [game.name] Name of the game - * @property {string} [game.url] Twitch stream URL - */ - - /** - * Sets the full presence of the client user. - * @param {PresenceData} data Data for the presence - * @returns {Promise<ClientUser>} - */ - setPresence(data) { - // {"op":3,"d":{"status":"dnd","since":0,"game":null,"afk":false}} - return new Promise(resolve => { - let status = this.localPresence.status || this.presence.status; - let game = this.localPresence.game; - let afk = this.localPresence.afk || this.presence.afk; - - if (!game && this.presence.game) { - game = { - name: this.presence.game.name, - type: this.presence.game.type, - url: this.presence.game.url, - }; - } - - if (data.status) { - if (typeof data.status !== 'string') throw new TypeError('Status must be a string'); - status = data.status; - } - - if (data.game) { - game = data.game; - if (game.url) game.type = 1; - } - - if (typeof data.afk !== 'undefined') afk = data.afk; - afk = Boolean(afk); - - this.localPresence = { status, game, afk }; - this.localPresence.since = 0; - this.localPresence.game = this.localPresence.game || null; - - this.client.ws.send({ - op: 3, - d: this.localPresence, - }); - - this.client._setPresence(this.id, this.localPresence); - - resolve(this); - }); - } - - /** - * A user's status. Must be one of: - * - `online` - * - `idle` - * - `invisible` - * - `dnd` (do not disturb) - * @typedef {string} PresenceStatus - */ - - /** - * Sets the status of the client user. - * @param {PresenceStatus} status Status to change to - * @returns {Promise<ClientUser>} - */ - setStatus(status) { - return this.setPresence({ status }); - } - - /** - * Sets the game the client user is playing. - * @param {string} game Game being played - * @param {string} [streamingURL] Twitch stream URL - * @returns {Promise<ClientUser>} - */ - setGame(game, streamingURL) { - return this.setPresence({ game: { - name: game, - url: streamingURL, - } }); - } - - /** - * Sets/removes the AFK flag for the client user. - * @param {boolean} afk Whether or not the user is AFK - * @returns {Promise<ClientUser>} - */ - setAFK(afk) { - return this.setPresence({ afk }); - } - - /** - * Fetches messages that mentioned the client's user - * @param {Object} [options] Options for the fetch - * @param {number} [options.limit=25] Maximum number of mentions to retrieve - * @param {boolean} [options.roles=true] Whether to include role mentions - * @param {boolean} [options.everyone=true] Whether to include everyone/here mentions - * @param {Guild|string} [options.guild] Limit the search to a specific guild - * @returns {Promise<Message[]>} - */ - fetchMentions(options = { limit: 25, roles: true, everyone: true, guild: null }) { - return this.client.rest.methods.fetchMentions(options); - } - - /** - * Send a friend request - * <warn>This is only available when using a user account.</warn> - * @param {UserResolvable} user The user to send the friend request to. - * @returns {Promise<User>} The user the friend request was sent to. - */ - addFriend(user) { - user = this.client.resolver.resolveUser(user); - return this.client.rest.methods.addFriend(user); - } - - /** - * Remove a friend - * <warn>This is only available when using a user account.</warn> - * @param {UserResolvable} user The user to remove from your friends - * @returns {Promise<User>} The user that was removed - */ - removeFriend(user) { - user = this.client.resolver.resolveUser(user); - return this.client.rest.methods.removeFriend(user); - } - - /** - * Creates a guild - * <warn>This is only available when using a user account.</warn> - * @param {string} name The name of the guild - * @param {string} region The region for the server - * @param {BufferResolvable|Base64Resolvable} [icon=null] The icon for the guild - * @returns {Promise<Guild>} The guild that was created - */ - createGuild(name, region, icon = null) { - if (!icon) return this.client.rest.methods.createGuild({ name, icon, region }); - if (icon.startsWith('data:')) { - return this.client.rest.methods.createGuild({ name, icon, region }); - } else { - return this.client.resolver.resolveBuffer(icon).then(data => - this.client.rest.methods.createGuild({ name, icon: data, region }) - ); - } - } -} - -module.exports = ClientUser; diff --git a/node_modules/discord.js/src/structures/DMChannel.js b/node_modules/discord.js/src/structures/DMChannel.js deleted file mode 100644 index de49c8b..0000000 --- a/node_modules/discord.js/src/structures/DMChannel.js +++ /dev/null @@ -1,60 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a direct message channel between two users. - * @extends {Channel} - * @implements {TextBasedChannel} - */ -class DMChannel extends Channel { - constructor(client, data) { - super(client, data); - this.type = 'dm'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The recipient on the other end of the DM - * @type {User} - */ - this.recipient = this.client.dataManager.newUser(data.recipients[0]); - - this.lastMessageID = data.last_message_id; - } - - /** - * When concatenated with a string, this automatically concatenates the recipient's mention instead of the - * DM channel object. - * @returns {string} - */ - toString() { - return this.recipient.toString(); - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(DMChannel, true); - -module.exports = DMChannel; diff --git a/node_modules/discord.js/src/structures/Emoji.js b/node_modules/discord.js/src/structures/Emoji.js deleted file mode 100644 index d8a62e1..0000000 --- a/node_modules/discord.js/src/structures/Emoji.js +++ /dev/null @@ -1,140 +0,0 @@ -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); - -/** - * Represents a custom emoji - */ -class Emoji { - constructor(guild, data) { - /** - * The Client that instantiated this object - * @name Emoji#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild this emoji is part of - * @type {Guild} - */ - this.guild = guild; - - this.setup(data); - } - - setup(data) { - /** - * The ID of the emoji - * @type {string} - */ - this.id = data.id; - - /** - * The name of the emoji - * @type {string} - */ - this.name = data.name; - - /** - * Whether or not this emoji requires colons surrounding it - * @type {boolean} - */ - this.requiresColons = data.require_colons; - - /** - * Whether this emoji is managed by an external service - * @type {boolean} - */ - this.managed = data.managed; - - this._roles = data.roles; - } - - /** - * The timestamp the emoji was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the emoji was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * A collection of roles this emoji is active for (empty if all), mapped by role ID. - * @type {Collection<string, Role>} - * @readonly - */ - get roles() { - const roles = new Collection(); - for (const role of this._roles) { - if (this.guild.roles.has(role)) roles.set(role, this.guild.roles.get(role)); - } - return roles; - } - - /** - * The URL to the emoji file - * @type {string} - * @readonly - */ - get url() { - return Constants.Endpoints.emoji(this.id); - } - - /** - * When concatenated with a string, this automatically returns the emoji mention rather than the object. - * @returns {string} - * @example - * // send an emoji: - * const emoji = guild.emojis.first(); - * msg.reply(`Hello! ${emoji}`); - */ - toString() { - return this.requiresColons ? `<:${this.name}:${this.id}>` : this.name; - } - - /** - * Whether this emoji is the same as another one - * @param {Emoji|Object} other the emoji to compare it to - * @returns {boolean} whether the emoji is equal to the given emoji or not - */ - equals(other) { - if (other instanceof Emoji) { - return ( - other.id === this.id && - other.name === this.name && - other.managed === this.managed && - other.requiresColons === this.requiresColons - ); - } else { - return ( - other.id === this.id && - other.name === this.name - ); - } - } - - /** - * The identifier of this emoji, used for message reactions - * @readonly - * @type {string} - */ - get identifier() { - if (this.id) { - return `${this.name}:${this.id}`; - } - return encodeURIComponent(this.name); - } -} - -module.exports = Emoji; diff --git a/node_modules/discord.js/src/structures/EvaluatedPermissions.js b/node_modules/discord.js/src/structures/EvaluatedPermissions.js deleted file mode 100644 index ae8a643..0000000 --- a/node_modules/discord.js/src/structures/EvaluatedPermissions.js +++ /dev/null @@ -1,67 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * The final evaluated permissions for a member in a channel - */ -class EvaluatedPermissions { - constructor(member, raw) { - /** - * The member this permissions refer to - * @type {GuildMember} - */ - this.member = member; - - /** - * A number representing the packed permissions - * @type {number} - */ - this.raw = raw; - } - - /** - * Get an object mapping permission name, e.g. `READ_MESSAGES` to a boolean - whether the user - * can perform this or not. - * @returns {Object<string, boolean>} - */ - serialize() { - const serializedPermissions = {}; - for (const permissionName in Constants.PermissionFlags) { - serializedPermissions[permissionName] = this.hasPermission(permissionName); - } - return serializedPermissions; - } - - /** - * Checks whether the user has a certain permission, e.g. `READ_MESSAGES`. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permission - * @returns {boolean} - */ - hasPermission(permission, explicit = false) { - permission = this.member.client.resolver.resolvePermission(permission); - if (!explicit && (this.raw & Constants.PermissionFlags.ADMINISTRATOR) > 0) return true; - return (this.raw & permission) > 0; - } - - /** - * Checks whether the user has all specified permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Checks whether the user has all specified permissions, and lists any missing permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions - * @returns {PermissionResolvable[]} - */ - missingPermissions(permissions, explicit = false) { - return permissions.filter(p => !this.hasPermission(p, explicit)); - } -} - -module.exports = EvaluatedPermissions; diff --git a/node_modules/discord.js/src/structures/GroupDMChannel.js b/node_modules/discord.js/src/structures/GroupDMChannel.js deleted file mode 100644 index 84fe4f9..0000000 --- a/node_modules/discord.js/src/structures/GroupDMChannel.js +++ /dev/null @@ -1,144 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/* -{ type: 3, - recipients: - [ { username: 'Charlie', - id: '123', - discriminator: '6631', - avatar: '123' }, - { username: 'Ben', - id: '123', - discriminator: '2055', - avatar: '123' }, - { username: 'Adam', - id: '123', - discriminator: '2406', - avatar: '123' } ], - owner_id: '123', - name: null, - last_message_id: '123', - id: '123', - icon: null } -*/ - -/** - * Represents a Group DM on Discord - * @extends {Channel} - * @implements {TextBasedChannel} - */ -class GroupDMChannel extends Channel { - constructor(client, data) { - super(client, data); - this.type = 'group'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The name of this Group DM, can be null if one isn't set. - * @type {string} - */ - this.name = data.name; - - /** - * A hash of the Group DM icon. - * @type {string} - */ - this.icon = data.icon; - - /** - * The user ID of this Group DM's owner. - * @type {string} - */ - this.ownerID = data.owner_id; - - if (!this.recipients) { - /** - * A collection of the recipients of this DM, mapped by their ID. - * @type {Collection<string, User>} - */ - this.recipients = new Collection(); - } - - if (data.recipients) { - for (const recipient of data.recipients) { - const user = this.client.dataManager.newUser(recipient); - this.recipients.set(user.id, user); - } - } - - this.lastMessageID = data.last_message_id; - } - - /** - * The owner of this Group DM. - * @type {User} - * @readonly - */ - get owner() { - return this.client.users.get(this.ownerID); - } - - /** - * Whether this channel equals another channel. It compares all properties, so for most operations - * it is advisable to just compare `channel.id === channel2.id` as it is much faster and is often - * what most users need. - * @param {GroupDMChannel} channel Channel to compare with - * @returns {boolean} - */ - equals(channel) { - const equal = channel && - this.id === channel.id && - this.name === channel.name && - this.icon === channel.icon && - this.ownerID === channel.ownerID; - - if (equal) { - return this.recipients.equals(channel.recipients); - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object. - * @returns {string} - * @example - * // logs: Hello from My Group DM! - * console.log(`Hello from ${channel}!`); - * @example - * // logs: Hello from My Group DM! - * console.log(`Hello from ' + channel + '!'); - */ - toString() { - return this.name; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(GroupDMChannel, true); - -module.exports = GroupDMChannel; diff --git a/node_modules/discord.js/src/structures/Guild.js b/node_modules/discord.js/src/structures/Guild.js deleted file mode 100644 index acd5b6f..0000000 --- a/node_modules/discord.js/src/structures/Guild.js +++ /dev/null @@ -1,851 +0,0 @@ -const User = require('./User'); -const Role = require('./Role'); -const Emoji = require('./Emoji'); -const Presence = require('./Presence').Presence; -const GuildMember = require('./GuildMember'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const cloneObject = require('../util/CloneObject'); -const arraysEqual = require('../util/ArraysEqual'); - -/** - * Represents a guild (or a server) on Discord. - * <info>It's recommended to see if a guild is available before performing operations or reading data from it. You can - * check this with `guild.available`.</info> - */ -class Guild { - constructor(client, data) { - /** - * The Client that created the instance of the the Guild. - * @name Guild#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * A collection of members that are in this guild. The key is the member's ID, the value is the member. - * @type {Collection<string, GuildMember>} - */ - this.members = new Collection(); - - /** - * A collection of channels that are in this guild. The key is the channel's ID, the value is the channel. - * @type {Collection<string, GuildChannel>} - */ - this.channels = new Collection(); - - /** - * A collection of roles that are in this guild. The key is the role's ID, the value is the role. - * @type {Collection<string, Role>} - */ - this.roles = new Collection(); - - /** - * A collection of presences in this guild - * @type {Collection<string, Presence>} - */ - this.presences = new Collection(); - - if (!data) return; - if (data.unavailable) { - /** - * Whether the guild is available to access. If it is not available, it indicates a server outage. - * @type {boolean} - */ - this.available = false; - - /** - * The Unique ID of the Guild, useful for comparisons. - * @type {string} - */ - this.id = data.id; - } else { - this.available = true; - this.setup(data); - } - } - - /** - * Sets up the Guild - * @param {*} data The raw data of the guild - * @private - */ - setup(data) { - /** - * The name of the guild - * @type {string} - */ - this.name = data.name; - - /** - * The hash of the guild icon, or null if there is no icon. - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image, or null if no splash (VIP only) - * @type {?string} - */ - this.splash = data.splash; - - /** - * The region the guild is located in - * @type {string} - */ - this.region = data.region; - - /** - * The full amount of members in this guild as of `READY` - * @type {number} - */ - this.memberCount = data.member_count || this.memberCount; - - /** - * Whether the guild is "large" (has more than 250 members) - * @type {boolean} - */ - this.large = data.large || this.large; - - /** - * An array of guild features. - * @type {Object[]} - */ - this.features = data.features; - - /** - * The ID of the application that created this guild (if applicable) - * @type {?string} - */ - this.applicationID = data.application_id; - - /** - * A collection of emojis that are in this guild. The key is the emoji's ID, the value is the emoji. - * @type {Collection<string, Emoji>} - */ - this.emojis = new Collection(); - for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji)); - - /** - * The time in seconds before a user is counted as "away from keyboard". - * @type {?number} - */ - this.afkTimeout = data.afk_timeout; - - /** - * The ID of the voice channel where AFK members are moved. - * @type {?string} - */ - this.afkChannelID = data.afk_channel_id; - - /** - * Whether embedded images are enabled on this guild. - * @type {boolean} - */ - this.embedEnabled = data.embed_enabled; - - /** - * The verification level of the guild. - * @type {number} - */ - this.verificationLevel = data.verification_level; - - /** - * The timestamp the client user joined the guild at - * @type {number} - */ - this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp; - - this.id = data.id; - this.available = !data.unavailable; - this.features = data.features || this.features || []; - - if (data.members) { - this.members.clear(); - for (const guildUser of data.members) this._addMember(guildUser, false); - } - - if (data.owner_id) { - /** - * The user ID of this guild's owner. - * @type {string} - */ - this.ownerID = data.owner_id; - } - - if (data.channels) { - this.channels.clear(); - for (const channel of data.channels) this.client.dataManager.newChannel(channel, this); - } - - if (data.roles) { - this.roles.clear(); - for (const role of data.roles) { - const newRole = new Role(this, role); - this.roles.set(newRole.id, newRole); - } - } - - if (data.presences) { - for (const presence of data.presences) { - this._setPresence(presence.user.id, presence); - } - } - - this._rawVoiceStates = new Collection(); - if (data.voice_states) { - for (const voiceState of data.voice_states) { - this._rawVoiceStates.set(voiceState.user_id, voiceState); - const member = this.members.get(voiceState.user_id); - if (member) { - member.serverMute = voiceState.mute; - member.serverDeaf = voiceState.deaf; - member.selfMute = voiceState.self_mute; - member.selfDeaf = voiceState.self_deaf; - member.voiceSessionID = voiceState.session_id; - member.voiceChannelID = voiceState.channel_id; - this.channels.get(voiceState.channel_id).members.set(member.user.id, member); - } - } - } - } - - /** - * The timestamp the guild was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the guild was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The time the client user joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * Gets the URL to this guild's icon (if it has one, otherwise it returns null) - * @type {?string} - * @readonly - */ - get iconURL() { - if (!this.icon) return null; - return Constants.Endpoints.guildIcon(this.id, this.icon); - } - - /** - * Gets the URL to this guild's splash (if it has one, otherwise it returns null) - * @type {?string} - * @readonly - */ - get splashURL() { - if (!this.splash) return null; - return Constants.Endpoints.guildSplash(this.id, this.splash); - } - - /** - * The owner of the guild - * @type {GuildMember} - * @readonly - */ - get owner() { - return this.members.get(this.ownerID); - } - - /** - * If the client is connected to any voice channel in this guild, this will be the relevant VoiceConnection. - * @type {?VoiceConnection} - * @readonly - */ - get voiceConnection() { - if (this.client.browser) return null; - return this.client.voice.connections.get(this.id) || null; - } - - /** - * The `#general` GuildChannel of the server. - * @type {GuildChannel} - * @readonly - */ - get defaultChannel() { - return this.channels.get(this.id); - } - - /** - * Returns the GuildMember form of a User object, if the user is present in the guild. - * @param {UserResolvable} user The user that you want to obtain the GuildMember of - * @returns {?GuildMember} - * @example - * // get the guild member of a user - * const member = guild.member(message.author); - */ - member(user) { - return this.client.resolver.resolveGuildMember(this, user); - } - - /** - * Fetch a collection of banned users in this guild. - * @returns {Promise<Collection<string, User>>} - */ - fetchBans() { - return this.client.rest.methods.getGuildBans(this); - } - - /** - * Fetch a collection of invites to this guild. Resolves with a collection mapping invites by their codes. - * @returns {Promise<Collection<string, Invite>>} - */ - fetchInvites() { - return this.client.rest.methods.getGuildInvites(this); - } - - /** - * Fetch all webhooks for the guild. - * @returns {Collection<Webhook>} - */ - fetchWebhooks() { - return this.client.rest.methods.getGuildWebhooks(this); - } - - /** - * Fetch a single guild member from a user. - * @param {UserResolvable} user The user to fetch the member for - * @returns {Promise<GuildMember>} - */ - fetchMember(user) { - if (this._fetchWaiter) return Promise.reject(new Error('Already fetching guild members.')); - user = this.client.resolver.resolveUser(user); - if (!user) return Promise.reject(new Error('User is not cached. Use Client.fetchUser first.')); - if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id)); - return this.client.rest.methods.getGuildMember(this, user); - } - - /** - * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members, - * this should not be necessary. - * @param {string} [query=''] An optional query to provide when fetching members - * @returns {Promise<Guild>} - */ - fetchMembers(query = '') { - return new Promise((resolve, reject) => { - if (this._fetchWaiter) throw new Error('Already fetching guild members in ${this.id}.'); - if (this.memberCount === this.members.size) { - resolve(this); - return; - } - this._fetchWaiter = resolve; - this.client.ws.send({ - op: Constants.OPCodes.REQUEST_GUILD_MEMBERS, - d: { - guild_id: this.id, - query, - limit: 0, - }, - }); - this._checkChunks(); - this.client.setTimeout(() => reject(new Error('Members didn\'t arrive in time.')), 120 * 1000); - }); - } - - /** - * The data for editing a guild - * @typedef {Object} GuildEditData - * @property {string} [name] The name of the guild - * @property {string} [region] The region of the guild - * @property {number} [verificationLevel] The verification level of the guild - * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild - * @property {number} [afkTimeout] The AFK timeout of the guild - * @property {Base64Resolvable} [icon] The icon of the guild - * @property {GuildMemberResolvable} [owner] The owner of the guild - * @property {Base64Resolvable} [splash] The splash screen of the guild - */ - - /** - * Updates the Guild with new information - e.g. a new name. - * @param {GuildEditData} data The data to update the guild with - * @returns {Promise<Guild>} - * @example - * // set the guild name and region - * guild.edit({ - * name: 'Discord Guild', - * region: 'london', - * }) - * .then(updated => console.log(`New guild name ${updated.name} in region ${updated.region}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateGuild(this, data); - } - - /** - * Edit the name of the guild. - * @param {string} name The new name of the guild - * @returns {Promise<Guild>} - * @example - * // edit the guild name - * guild.setName('Discord Guild') - * .then(updated => console.log(`Updated guild name to ${guild.name}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Edit the region of the guild. - * @param {string} region The new region of the guild. - * @returns {Promise<Guild>} - * @example - * // edit the guild region - * guild.setRegion('london') - * .then(updated => console.log(`Updated guild region to ${guild.region}`)) - * .catch(console.error); - */ - setRegion(region) { - return this.edit({ region }); - } - - /** - * Edit the verification level of the guild. - * @param {number} verificationLevel The new verification level of the guild - * @returns {Promise<Guild>} - * @example - * // edit the guild verification level - * guild.setVerificationLevel(1) - * .then(updated => console.log(`Updated guild verification level to ${guild.verificationLevel}`)) - * .catch(console.error); - */ - setVerificationLevel(verificationLevel) { - return this.edit({ verificationLevel }); - } - - /** - * Edit the AFK channel of the guild. - * @param {ChannelResolvable} afkChannel The new AFK channel - * @returns {Promise<Guild>} - * @example - * // edit the guild AFK channel - * guild.setAFKChannel(channel) - * .then(updated => console.log(`Updated guild AFK channel to ${guild.afkChannel}`)) - * .catch(console.error); - */ - setAFKChannel(afkChannel) { - return this.edit({ afkChannel }); - } - - /** - * Edit the AFK timeout of the guild. - * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK - * @returns {Promise<Guild>} - * @example - * // edit the guild AFK channel - * guild.setAFKTimeout(60) - * .then(updated => console.log(`Updated guild AFK timeout to ${guild.afkTimeout}`)) - * .catch(console.error); - */ - setAFKTimeout(afkTimeout) { - return this.edit({ afkTimeout }); - } - - /** - * Set a new guild icon. - * @param {Base64Resolvable} icon The new icon of the guild - * @returns {Promise<Guild>} - * @example - * // edit the guild icon - * guild.setIcon(fs.readFileSync('./icon.png')) - * .then(updated => console.log('Updated the guild icon')) - * .catch(console.error); - */ - setIcon(icon) { - return this.edit({ icon }); - } - - /** - * Sets a new owner of the guild. - * @param {GuildMemberResolvable} owner The new owner of the guild - * @returns {Promise<Guild>} - * @example - * // edit the guild owner - * guild.setOwner(guilds.members[0]) - * .then(updated => console.log(`Updated the guild owner to ${updated.owner.username}`)) - * .catch(console.error); - */ - setOwner(owner) { - return this.edit({ owner }); - } - - /** - * Set a new guild splash screen. - * @param {Base64Resolvable} splash The new splash screen of the guild - * @returns {Promise<Guild>} - * @example - * // edit the guild splash - * guild.setIcon(fs.readFileSync('./splash.png')) - * .then(updated => console.log('Updated the guild splash')) - * .catch(console.error); - */ - setSplash(splash) { - return this.edit({ splash }); - } - - /** - * Bans a user from the guild. - * @param {UserResolvable} user The user to ban - * @param {number} [deleteDays=0] The amount of days worth of messages from this user that should - * also be deleted. Between `0` and `7`. - * @returns {Promise<GuildMember|User|string>} Result object will be resolved as specifically as possible. - * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot - * be resolved, the user ID will be the result. - * @example - * // ban a user - * guild.ban('123123123123'); - */ - ban(user, deleteDays = 0) { - return this.client.rest.methods.banGuildMember(this, user, deleteDays); - } - - /** - * Unbans a user from the guild. - * @param {UserResolvable} user The user to unban - * @returns {Promise<User>} - * @example - * // unban a user - * guild.unban('123123123123') - * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`)) - * .catch(reject); - */ - unban(user) { - return this.client.rest.methods.unbanGuildMember(this, user); - } - - /** - * Prunes members from the guild based on how long they have been inactive. - * @param {number} days Number of days of inactivity required to kick - * @param {boolean} [dry=false] If true, will return number of users that will be kicked, without actually doing it - * @returns {Promise<number>} The number of members that were/will be kicked - * @example - * // see how many members will be pruned - * guild.pruneMembers(12, true) - * .then(pruned => console.log(`This will prune ${pruned} people!`); - * .catch(console.error); - * @example - * // actually prune the members - * guild.pruneMembers(12) - * .then(pruned => console.log(`I just pruned ${pruned} people!`); - * .catch(console.error); - */ - pruneMembers(days, dry = false) { - if (typeof days !== 'number') throw new TypeError('Days must be a number.'); - return this.client.rest.methods.pruneGuildMembers(this, days, dry); - } - - /** - * Syncs this guild (already done automatically every 30 seconds). - * <warn>This is only available when using a user account.</warn> - */ - sync() { - if (!this.client.user.bot) this.client.syncGuilds([this]); - } - - /** - * Creates a new channel in the guild. - * @param {string} name The name of the new channel - * @param {string} type The type of the new channel, either `text` or `voice` - * @param {Array<PermissionOverwrites|Object>} overwrites Permission overwrites to apply to the new channel - * @returns {Promise<TextChannel|VoiceChannel>} - * @example - * // create a new text channel - * guild.createChannel('new-general', 'text') - * .then(channel => console.log(`Created new channel ${channel}`)) - * .catch(console.error); - */ - createChannel(name, type, overwrites) { - return this.client.rest.methods.createChannel(this, name, type, overwrites); - } - - /** - * Creates a new role in the guild, and optionally updates it with the given information. - * @param {RoleData} [data] The data to update the role with - * @returns {Promise<Role>} - * @example - * // create a new role - * guild.createRole() - * .then(role => console.log(`Created role ${role}`)) - * .catch(console.error); - * @example - * // create a new role with data - * guild.createRole({ name: 'Super Cool People' }) - * .then(role => console.log(`Created role ${role}`)) - * .catch(console.error) - */ - createRole(data) { - const create = this.client.rest.methods.createGuildRole(this); - if (!data) return create; - return create.then(role => role.edit(data)); - } - - /** - * Creates a new custom emoji in the guild. - * @param {BufferResolvable} attachment The image for the emoji. - * @param {string} name The name for the emoji. - * @returns {Promise<Emoji>} The created emoji. - * @example - * // create a new emoji from a url - * guild.createEmoji('https://i.imgur.com/w3duR07.png', 'rip') - * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) - * .catch(console.error); - * @example - * // create a new emoji from a file on your computer - * guild.createEmoji('./memes/banana.png', 'banana') - * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) - * .catch(console.error); - */ - createEmoji(attachment, name) { - return new Promise(resolve => { - if (attachment.startsWith('data:')) { - resolve(this.client.rest.methods.createEmoji(this, attachment, name)); - } else { - this.client.resolver.resolveBuffer(attachment).then(data => - resolve(this.client.rest.methods.createEmoji(this, data, name)) - ); - } - }); - } - - /** - * Delete an emoji. - * @param {Emoji|string} emoji The emoji to delete. - * @returns {Promise} - */ - deleteEmoji(emoji) { - if (!(emoji instanceof Emoji)) emoji = this.emojis.get(emoji); - return this.client.rest.methods.deleteEmoji(emoji); - } - - /** - * Causes the Client to leave the guild. - * @returns {Promise<Guild>} - * @example - * // leave a guild - * guild.leave() - * .then(g => console.log(`Left the guild ${g}`)) - * .catch(console.error); - */ - leave() { - return this.client.rest.methods.leaveGuild(this); - } - - /** - * Causes the Client to delete the guild. - * @returns {Promise<Guild>} - * @example - * // delete a guild - * guild.delete() - * .then(g => console.log(`Deleted the guild ${g}`)) - * .catch(console.error); - */ - delete() { - return this.client.rest.methods.deleteGuild(this); - } - - /** - * Set the position of a role in this guild - * @param {string|Role} role the role to edit, can be a role object or a role ID. - * @param {number} position the new position of the role - * @returns {Promise<Guild>} - */ - setRolePosition(role, position) { - if (typeof role === 'string') { - role = this.roles.get(role); - if (!role) return Promise.reject(new Error('Supplied role is not a role or string.')); - } - - position = Number(position); - if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.')); - - const lowestAffected = Math.min(role.position, position); - const highestAffected = Math.max(role.position, position); - - const rolesToUpdate = this.roles.filter(r => r.position >= lowestAffected && r.position <= highestAffected); - - // stop role positions getting stupidly inflated - if (position > role.position) { - position = rolesToUpdate.first().position; - } else { - position = rolesToUpdate.last().position; - } - - const updatedRoles = []; - - for (const uRole of rolesToUpdate.values()) { - updatedRoles.push({ - id: uRole.id, - position: uRole.id === role.id ? position : uRole.position + (position < role.position ? 1 : -1), - }); - } - - return this.client.rest.methods.setRolePositions(this.id, updatedRoles); - } - - /** - * Whether this Guild equals another Guild. It compares all properties, so for most operations - * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often - * what most users need. - * @param {Guild} guild Guild to compare with - * @returns {boolean} - */ - equals(guild) { - let equal = - guild && - this.id === guild.id && - this.available === !guild.unavailable && - this.splash === guild.splash && - this.region === guild.region && - this.name === guild.name && - this.memberCount === guild.member_count && - this.large === guild.large && - this.icon === guild.icon && - arraysEqual(this.features, guild.features) && - this.ownerID === guild.owner_id && - this.verificationLevel === guild.verification_level && - this.embedEnabled === guild.embed_enabled; - - if (equal) { - if (this.embedChannel) { - if (this.embedChannel.id !== guild.embed_channel_id) equal = false; - } else if (guild.embed_channel_id) { - equal = false; - } - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the guild's name instead of the Guild object. - * @returns {string} - * @example - * // logs: Hello from My Guild! - * console.log(`Hello from ${guild}!`); - * @example - * // logs: Hello from My Guild! - * console.log(`Hello from ' + guild + '!'); - */ - toString() { - return this.name; - } - - _addMember(guildUser, emitEvent = true) { - const existing = this.members.has(guildUser.user.id); - if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user); - - guildUser.joined_at = guildUser.joined_at || 0; - const member = new GuildMember(this, guildUser); - this.members.set(member.id, member); - - if (this._rawVoiceStates && this._rawVoiceStates.has(member.user.id)) { - const voiceState = this._rawVoiceStates.get(member.user.id); - member.serverMute = voiceState.mute; - member.serverDeaf = voiceState.deaf; - member.selfMute = voiceState.self_mute; - member.selfDeaf = voiceState.self_deaf; - member.voiceSessionID = voiceState.session_id; - member.voiceChannelID = voiceState.channel_id; - if (this.client.channels.has(voiceState.channel_id)) { - this.client.channels.get(voiceState.channel_id).members.set(member.user.id, member); - } else { - this.client.emit('warn', `Member ${member.id} added in guild ${this.id} with an uncached voice channel`); - } - } - - /** - * Emitted whenever a user joins a guild. - * @event Client#guildMemberAdd - * @param {GuildMember} member The member that has joined a guild - */ - if (this.client.ws.status === Constants.Status.READY && emitEvent && !existing) { - this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member); - } - - this._checkChunks(); - return member; - } - - _updateMember(member, data) { - const oldMember = cloneObject(member); - - if (data.roles) member._roles = data.roles; - if (typeof data.nick !== 'undefined') member.nickname = data.nick; - - const notSame = member.nickname !== oldMember.nickname || !arraysEqual(member._roles, oldMember._roles); - - if (this.client.ws.status === Constants.Status.READY && notSame) { - /** - * Emitted whenever a guild member changes - i.e. new role, removed role, nickname - * @event Client#guildMemberUpdate - * @param {GuildMember} oldMember The member before the update - * @param {GuildMember} newMember The member after the update - */ - this.client.emit(Constants.Events.GUILD_MEMBER_UPDATE, oldMember, member); - } - - return { - old: oldMember, - mem: member, - }; - } - - _removeMember(guildMember) { - this.members.delete(guildMember.id); - this._checkChunks(); - } - - _memberSpeakUpdate(user, speaking) { - const member = this.members.get(user); - if (member && member.speaking !== speaking) { - member.speaking = speaking; - /** - * Emitted once a guild member starts/stops speaking - * @event Client#guildMemberSpeaking - * @param {GuildMember} member The member that started/stopped speaking - * @param {boolean} speaking Whether or not the member is speaking - */ - this.client.emit(Constants.Events.GUILD_MEMBER_SPEAKING, member, speaking); - } - } - - _setPresence(id, presence) { - if (this.presences.get(id)) { - this.presences.get(id).update(presence); - return; - } - this.presences.set(id, new Presence(presence)); - } - - _checkChunks() { - if (this._fetchWaiter) { - if (this.members.size === this.memberCount) { - this._fetchWaiter(this); - this._fetchWaiter = null; - } - } - } -} - -module.exports = Guild; diff --git a/node_modules/discord.js/src/structures/GuildChannel.js b/node_modules/discord.js/src/structures/GuildChannel.js deleted file mode 100644 index a930789..0000000 --- a/node_modules/discord.js/src/structures/GuildChannel.js +++ /dev/null @@ -1,299 +0,0 @@ -const Channel = require('./Channel'); -const Role = require('./Role'); -const PermissionOverwrites = require('./PermissionOverwrites'); -const EvaluatedPermissions = require('./EvaluatedPermissions'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild channel (i.e. text channels and voice channels) - * @extends {Channel} - */ -class GuildChannel extends Channel { - constructor(guild, data) { - super(guild.client, data); - - /** - * The guild the channel is in - * @type {Guild} - */ - this.guild = guild; - } - - setup(data) { - super.setup(data); - - /** - * The name of the guild channel - * @type {string} - */ - this.name = data.name; - - /** - * The position of the channel in the list. - * @type {number} - */ - this.position = data.position; - - /** - * A map of permission overwrites in this channel for roles and users. - * @type {Collection<string, PermissionOverwrites>} - */ - this.permissionOverwrites = new Collection(); - if (data.permission_overwrites) { - for (const overwrite of data.permission_overwrites) { - this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite)); - } - } - } - - /** - * Gets the overall set of permissions for a user in this channel, taking into account roles and permission - * overwrites. - * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for - * @returns {?EvaluatedPermissions} - */ - permissionsFor(member) { - member = this.client.resolver.resolveGuildMember(this.guild, member); - if (!member) return null; - if (member.id === this.guild.ownerID) return new EvaluatedPermissions(member, Constants.ALL_PERMISSIONS); - - let permissions = 0; - - const roles = member.roles; - for (const role of roles.values()) permissions |= role.permissions; - - const overwrites = this.overwritesFor(member, true, roles); - for (const overwrite of overwrites.role.concat(overwrites.member)) { - permissions &= ~overwrite.deny; - permissions |= overwrite.allow; - } - - const admin = Boolean(permissions & Constants.PermissionFlags.ADMINISTRATOR); - if (admin) permissions = Constants.ALL_PERMISSIONS; - - return new EvaluatedPermissions(member, permissions); - } - - overwritesFor(member, verified = false, roles = null) { - if (!verified) member = this.client.resolver.resolveGuildMember(this.guild, member); - if (!member) return []; - - roles = roles || member.roles; - const roleOverwrites = []; - const memberOverwrites = []; - - for (const overwrite of this.permissionOverwrites.values()) { - if (overwrite.id === member.id) { - memberOverwrites.push(overwrite); - } else if (roles.has(overwrite.id)) { - roleOverwrites.push(overwrite); - } - } - - return { - role: roleOverwrites, - member: memberOverwrites, - }; - } - - /** - * An object mapping permission flags to `true` (enabled) or `false` (disabled) - * ```js - * { - * 'SEND_MESSAGES': true, - * 'ATTACH_FILES': false, - * } - * ``` - * @typedef {Object} PermissionOverwriteOptions - */ - - /** - * Overwrites the permissions for a user or role in this channel. - * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update - * @param {PermissionOverwriteOptions} options The configuration for the update - * @returns {Promise} - * @example - * // overwrite permissions for a message author - * message.channel.overwritePermissions(message.author, { - * SEND_MESSAGES: false - * }) - * .then(() => console.log('Done!')) - * .catch(console.error); - */ - overwritePermissions(userOrRole, options) { - const payload = { - allow: 0, - deny: 0, - }; - - if (userOrRole instanceof Role) { - payload.type = 'role'; - } else if (this.guild.roles.has(userOrRole)) { - userOrRole = this.guild.roles.get(userOrRole); - payload.type = 'role'; - } else { - userOrRole = this.client.resolver.resolveUser(userOrRole); - payload.type = 'member'; - if (!userOrRole) return Promise.reject(new TypeError('Supplied parameter was neither a User nor a Role.')); - } - - payload.id = userOrRole.id; - - const prevOverwrite = this.permissionOverwrites.get(userOrRole.id); - - if (prevOverwrite) { - payload.allow = prevOverwrite.allow; - payload.deny = prevOverwrite.deny; - } - - for (const perm in options) { - if (options[perm] === true) { - payload.allow |= Constants.PermissionFlags[perm] || 0; - payload.deny &= ~(Constants.PermissionFlags[perm] || 0); - } else if (options[perm] === false) { - payload.allow &= ~(Constants.PermissionFlags[perm] || 0); - payload.deny |= Constants.PermissionFlags[perm] || 0; - } else if (options[perm] === null) { - payload.allow &= ~(Constants.PermissionFlags[perm] || 0); - payload.deny &= ~(Constants.PermissionFlags[perm] || 0); - } - } - - return this.client.rest.methods.setChannelOverwrite(this, payload); - } - - /** - * The data for a guild channel - * @typedef {Object} ChannelData - * @property {string} [name] The name of the channel - * @property {number} [position] The position of the channel - * @property {string} [topic] The topic of the text channel - * @property {number} [bitrate] The bitrate of the voice channel - * @property {number} [userLimit] The user limit of the channel - */ - - /** - * Edits the channel - * @param {ChannelData} data The new data for the channel - * @returns {Promise<GuildChannel>} - * @example - * // edit a channel - * channel.edit({name: 'new-channel'}) - * .then(c => console.log(`Edited channel ${c}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateChannel(this, data); - } - - /** - * Set a new name for the guild channel - * @param {string} name The new name for the guild channel - * @returns {Promise<GuildChannel>} - * @example - * // set a new channel name - * channel.setName('not_general') - * .then(newChannel => console.log(`Channel's new name is ${newChannel.name}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Set a new position for the guild channel - * @param {number} position The new position for the guild channel - * @returns {Promise<GuildChannel>} - * @example - * // set a new channel position - * channel.setPosition(2) - * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) - * .catch(console.error); - */ - setPosition(position) { - return this.client.rest.methods.updateChannel(this, { position }); - } - - /** - * Set a new topic for the guild channel - * @param {string} topic The new topic for the guild channel - * @returns {Promise<GuildChannel>} - * @example - * // set a new channel topic - * channel.setTopic('needs more rate limiting') - * .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`)) - * .catch(console.error); - */ - setTopic(topic) { - return this.client.rest.methods.updateChannel(this, { topic }); - } - - /** - * Options given when creating a guild channel invite - * @typedef {Object} InviteOptions - * @property {boolean} [temporary=false] Whether the invite should kick users after 24hrs if they are not given a role - * @property {number} [maxAge=0] Time in seconds the invite expires in - * @property {number} [maxUses=0] Maximum amount of uses for this invite - */ - - /** - * Create an invite to this guild channel - * @param {InviteOptions} [options={}] The options for the invite - * @returns {Promise<Invite>} - */ - createInvite(options = {}) { - return this.client.rest.methods.createChannelInvite(this, options); - } - - /** - * Clone this channel - * @param {string} [name=this.name] Optional name for the new channel, otherwise it has the name of this channel - * @param {boolean} [withPermissions=true] Whether to clone the channel with this channel's permission overwrites - * @returns {Promise<GuildChannel>} - */ - clone(name = this.name, withPermissions = true) { - return this.guild.createChannel(name, this.type, withPermissions ? this.permissionOverwrites : []); - } - - /** - * Checks if this channel has the same type, topic, position, name, overwrites and ID as another channel. - * In most cases, a simple `channel.id === channel2.id` will do, and is much faster too. - * @param {GuildChannel} channel Channel to compare with - * @returns {boolean} - */ - equals(channel) { - let equal = channel && - this.id === channel.id && - this.type === channel.type && - this.topic === channel.topic && - this.position === channel.position && - this.name === channel.name; - - if (equal) { - if (this.permissionOverwrites && channel.permissionOverwrites) { - equal = this.permissionOverwrites.equals(channel.permissionOverwrites); - } else { - equal = !this.permissionOverwrites && !channel.permissionOverwrites; - } - } - - return equal; - } - - /** - * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. - * @returns {string} - * @example - * // Outputs: Hello from #general - * console.log(`Hello from ${channel}`); - * @example - * // Outputs: Hello from #general - * console.log('Hello from ' + channel); - */ - toString() { - return `<#${this.id}>`; - } -} - -module.exports = GuildChannel; diff --git a/node_modules/discord.js/src/structures/GuildMember.js b/node_modules/discord.js/src/structures/GuildMember.js deleted file mode 100644 index 60a498a..0000000 --- a/node_modules/discord.js/src/structures/GuildMember.js +++ /dev/null @@ -1,442 +0,0 @@ -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Role = require('./Role'); -const EvaluatedPermissions = require('./EvaluatedPermissions'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const Presence = require('./Presence').Presence; - -/** - * Represents a member of a guild on Discord - * @implements {TextBasedChannel} - */ -class GuildMember { - constructor(guild, data) { - /** - * The Client that instantiated this GuildMember - * @name GuildMember#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild that this member is part of - * @type {Guild} - */ - this.guild = guild; - - /** - * The user that this guild member instance Represents - * @type {User} - */ - this.user = {}; - - this._roles = []; - if (data) this.setup(data); - - /** - * The ID of the last message sent by the member in their guild, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - setup(data) { - /** - * Whether this member is deafened server-wide - * @type {boolean} - */ - this.serverDeaf = data.deaf; - - /** - * Whether this member is muted server-wide - * @type {boolean} - */ - this.serverMute = data.mute; - - /** - * Whether this member is self-muted - * @type {boolean} - */ - this.selfMute = data.self_mute; - - /** - * Whether this member is self-deafened - * @type {boolean} - */ - this.selfDeaf = data.self_deaf; - - /** - * The voice session ID of this member, if any - * @type {?string} - */ - this.voiceSessionID = data.session_id; - - /** - * The voice channel ID of this member, if any - * @type {?string} - */ - this.voiceChannelID = data.channel_id; - - /** - * Whether this member is speaking - * @type {boolean} - */ - this.speaking = false; - - /** - * The nickname of this guild member, if they have one - * @type {?string} - */ - this.nickname = data.nick || null; - - /** - * The timestamp the member joined the guild at - * @type {number} - */ - this.joinedTimestamp = new Date(data.joined_at).getTime(); - - this.user = data.user; - this._roles = data.roles; - } - - /** - * The time the member joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * The presence of this guild member - * @type {Presence} - * @readonly - */ - get presence() { - return this.frozenPresence || this.guild.presences.get(this.id) || new Presence(); - } - - /** - * A list of roles that are applied to this GuildMember, mapped by the role ID. - * @type {Collection<string, Role>} - * @readonly - */ - get roles() { - const list = new Collection(); - const everyoneRole = this.guild.roles.get(this.guild.id); - - if (everyoneRole) list.set(everyoneRole.id, everyoneRole); - - for (const roleID of this._roles) { - const role = this.guild.roles.get(roleID); - if (role) list.set(role.id, role); - } - - return list; - } - - /** - * The role of the member with the highest position. - * @type {Role} - * @readonly - */ - get highestRole() { - return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * Whether this member is muted in any way - * @type {boolean} - * @readonly - */ - get mute() { - return this.selfMute || this.serverMute; - } - - /** - * Whether this member is deafened in any way - * @type {boolean} - * @readonly - */ - get deaf() { - return this.selfDeaf || this.serverDeaf; - } - - /** - * The voice channel this member is in, if any - * @type {?VoiceChannel} - * @readonly - */ - get voiceChannel() { - return this.guild.channels.get(this.voiceChannelID); - } - - /** - * The ID of this user - * @type {string} - * @readonly - */ - get id() { - return this.user.id; - } - - /** - * The nickname of the member, or their username if they don't have one - * @type {string} - * @readonly - */ - get displayName() { - return this.nickname || this.user.username; - } - - /** - * The overall set of permissions for the guild member, taking only roles into account - * @type {EvaluatedPermissions} - * @readonly - */ - get permissions() { - if (this.user.id === this.guild.ownerID) return new EvaluatedPermissions(this, Constants.ALL_PERMISSIONS); - - let permissions = 0; - const roles = this.roles; - for (const role of roles.values()) permissions |= role.permissions; - - const admin = Boolean(permissions & Constants.PermissionFlags.ADMINISTRATOR); - if (admin) permissions = Constants.ALL_PERMISSIONS; - - return new EvaluatedPermissions(this, permissions); - } - - /** - * Whether the member is kickable by the client user. - * @type {boolean} - * @readonly - */ - get kickable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.KICK_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Whether the member is bannable by the client user. - * @type {boolean} - * @readonly - */ - get bannable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.BAN_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Returns `channel.permissionsFor(guildMember)`. Returns evaluated permissions for a member in a guild channel. - * @param {ChannelResolvable} channel Guild channel to use as context - * @returns {?EvaluatedPermissions} - */ - permissionsIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - if (!channel || !channel.guild) throw new Error('Could not resolve channel to a guild channel.'); - return channel.permissionsFor(this); - } - - /** - * Checks if any of the member's roles have a permission. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the roles to explicitly have the exact permission - * @returns {boolean} - */ - hasPermission(permission, explicit = false) { - if (!explicit && this.user.id === this.guild.ownerID) return true; - return this.roles.some(r => r.hasPermission(permission, explicit)); - } - - /** - * Checks whether the roles of the member allows them to perform specific actions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - if (!explicit && this.user.id === this.guild.ownerID) return true; - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Checks whether the roles of the member allows them to perform specific actions, and lists any missing permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions - * @returns {PermissionResolvable[]} - */ - missingPermissions(permissions, explicit = false) { - return permissions.filter(p => !this.hasPermission(p, explicit)); - } - - /** - * Edit a guild member - * @param {GuildmemberEditData} data The data to edit the member with - * @returns {Promise<GuildMember>} - */ - edit(data) { - return this.client.rest.methods.updateGuildMember(this, data); - } - - /** - * Mute/unmute a user - * @param {boolean} mute Whether or not the member should be muted - * @returns {Promise<GuildMember>} - */ - setMute(mute) { - return this.edit({ mute }); - } - - /** - * Deafen/undeafen a user - * @param {boolean} deaf Whether or not the member should be deafened - * @returns {Promise<GuildMember>} - */ - setDeaf(deaf) { - return this.edit({ deaf }); - } - - /** - * Moves the guild member to the given channel. - * @param {ChannelResolvable} channel The channel to move the member to - * @returns {Promise<GuildMember>} - */ - setVoiceChannel(channel) { - return this.edit({ channel }); - } - - /** - * Sets the roles applied to the member. - * @param {Collection<string, Role>|Role[]|string[]} roles The roles or role IDs to apply - * @returns {Promise<GuildMember>} - */ - setRoles(roles) { - return this.edit({ roles }); - } - - /** - * Adds a single role to the member. - * @param {Role|string} role The role or ID of the role to add - * @returns {Promise<GuildMember>} - */ - addRole(role) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - return this.client.rest.methods.addMemberRole(this, role); - } - - /** - * Adds multiple roles to the member. - * @param {Collection<string, Role>|Role[]|string[]} roles The roles or role IDs to add - * @returns {Promise<GuildMember>} - */ - addRoles(roles) { - let allRoles; - if (roles instanceof Collection) { - allRoles = this._roles.slice(); - for (const role of roles.values()) allRoles.push(role.id); - } else { - allRoles = this._roles.concat(roles); - } - return this.edit({ roles: allRoles }); - } - - /** - * Removes a single role from the member. - * @param {Role|string} role The role or ID of the role to remove - * @returns {Promise<GuildMember>} - */ - removeRole(role) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - return this.client.rest.methods.removeMemberRole(this, role); - } - - /** - * Removes multiple roles from the member. - * @param {Collection<string, Role>|Role[]|string[]} roles The roles or role IDs to remove - * @returns {Promise<GuildMember>} - */ - removeRoles(roles) { - const allRoles = this._roles.slice(); - if (roles instanceof Collection) { - for (const role of roles.values()) { - const index = allRoles.indexOf(role.id); - if (index >= 0) allRoles.splice(index, 1); - } - } else { - for (const role of roles) { - const index = allRoles.indexOf(role instanceof Role ? role.id : role); - if (index >= 0) allRoles.splice(index, 1); - } - } - return this.edit({ roles: allRoles }); - } - - /** - * Set the nickname for the guild member - * @param {string} nick The nickname for the guild member - * @returns {Promise<GuildMember>} - */ - setNickname(nick) { - return this.edit({ nick }); - } - - /** - * Deletes any DMs with this guild member - * @returns {Promise<DMChannel>} - */ - deleteDM() { - return this.client.rest.methods.deleteChannel(this); - } - - /** - * Kick this member from the guild - * @returns {Promise<GuildMember>} - */ - kick() { - return this.client.rest.methods.kickGuildMember(this.guild, this); - } - - /** - * Ban this guild member - * @param {number} [deleteDays=0] The amount of days worth of messages from this member that should - * also be deleted. Between `0` and `7`. - * @returns {Promise<GuildMember>} - * @example - * // ban a guild member - * guildMember.ban(7); - */ - ban(deleteDays = 0) { - return this.client.rest.methods.banGuildMember(this.guild, this, deleteDays); - } - - /** - * When concatenated with a string, this automatically concatenates the user's mention instead of the Member object. - * @returns {string} - * @example - * // logs: Hello from <@123456789>! - * console.log(`Hello from ${member}!`); - */ - toString() { - return `<@${this.nickname ? '!' : ''}${this.user.id}>`; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } -} - -TextBasedChannel.applyToClass(GuildMember); - -module.exports = GuildMember; diff --git a/node_modules/discord.js/src/structures/Invite.js b/node_modules/discord.js/src/structures/Invite.js deleted file mode 100644 index b4b34da..0000000 --- a/node_modules/discord.js/src/structures/Invite.js +++ /dev/null @@ -1,159 +0,0 @@ -const PartialGuild = require('./PartialGuild'); -const PartialGuildChannel = require('./PartialGuildChannel'); -const Constants = require('../util/Constants'); - -/* -{ max_age: 86400, - code: 'CG9A5', - guild: - { splash: null, - id: '123123123', - icon: '123123123', - name: 'name' }, - created_at: '2016-08-28T19:07:04.763368+00:00', - temporary: false, - uses: 0, - max_uses: 0, - inviter: - { username: '123', - discriminator: '4204', - bot: true, - id: '123123123', - avatar: '123123123' }, - channel: { type: 0, id: '123123', name: 'heavy-testing' } } -*/ - -/** - * Represents an invitation to a guild channel. - * <warn>The only guaranteed properties are `code`, `guild` and `channel`. Other properties can be missing.</warn> - */ -class Invite { - constructor(client, data) { - /** - * The client that instantiated the invite - * @name Invite#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The guild the invite is for. If this guild is already known, this will be a Guild object. If the guild is - * unknown, this will be a PartialGuild object. - * @type {Guild|PartialGuild} - */ - this.guild = this.client.guilds.get(data.guild.id) || new PartialGuild(this.client, data.guild); - - /** - * The code for this invite - * @type {string} - */ - this.code = data.code; - - /** - * Whether or not this invite is temporary - * @type {boolean} - */ - this.temporary = data.temporary; - - /** - * The maximum age of the invite, in seconds - * @type {?number} - */ - this.maxAge = data.max_age; - - /** - * How many times this invite has been used - * @type {number} - */ - this.uses = data.uses; - - /** - * The maximum uses of this invite - * @type {number} - */ - this.maxUses = data.max_uses; - - if (data.inviter) { - /** - * The user who created this invite - * @type {User} - */ - this.inviter = this.client.dataManager.newUser(data.inviter); - } - - /** - * The channel the invite is for. If this channel is already known, this will be a GuildChannel object. - * If the channel is unknown, this will be a PartialGuildChannel object. - * @type {GuildChannel|PartialGuildChannel} - */ - this.channel = this.client.channels.get(data.channel.id) || new PartialGuildChannel(this.client, data.channel); - - /** - * The timestamp the invite was created at - * @type {number} - */ - this.createdTimestamp = new Date(data.created_at).getTime(); - } - - /** - * The time the invite was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The timestamp the invite will expire at - * @type {number} - * @readonly - */ - get expiresTimestamp() { - return this.createdTimestamp + (this.maxAge * 1000); - } - - /** - * The time the invite will expire - * @type {Date} - * @readonly - */ - get expiresAt() { - return new Date(this.expiresTimestamp); - } - - /** - * The URL to the invite - * @type {string} - * @readonly - */ - get url() { - return Constants.Endpoints.inviteLink(this.code); - } - - /** - * Deletes this invite - * @returns {Promise<Invite>} - */ - delete() { - return this.client.rest.methods.deleteInvite(this); - } - - /** - * When concatenated with a string, this automatically concatenates the invite's URL instead of the object. - * @returns {string} - * @example - * // logs: Invite: https://discord.gg/A1b2C3 - * console.log(`Invite: ${invite}`); - */ - toString() { - return this.url; - } -} - -module.exports = Invite; diff --git a/node_modules/discord.js/src/structures/Message.js b/node_modules/discord.js/src/structures/Message.js deleted file mode 100644 index 7fcc5b4..0000000 --- a/node_modules/discord.js/src/structures/Message.js +++ /dev/null @@ -1,568 +0,0 @@ -const Attachment = require('./MessageAttachment'); -const Embed = require('./MessageEmbed'); -const MessageReaction = require('./MessageReaction'); -const Collection = require('../util/Collection'); -const Constants = require('../util/Constants'); -const escapeMarkdown = require('../util/EscapeMarkdown'); - -// Done purely for GuildMember, which would cause a bad circular dependency -const Discord = require('..'); - -/** - * Represents a message on Discord - */ -class Message { - constructor(channel, data, client) { - /** - * The Client that instantiated the Message - * @name Message#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The channel that the message was sent in - * @type {TextChannel|DMChannel|GroupDMChannel} - */ - this.channel = channel; - - if (data) this.setup(data); - } - - setup(data) { // eslint-disable-line complexity - /** - * The ID of the message (unique in the channel it was sent) - * @type {string} - */ - this.id = data.id; - - /** - * The type of the message - * @type {string} - */ - this.type = Constants.MessageTypes[data.type]; - - /** - * The content of the message - * @type {string} - */ - this.content = data.content; - - /** - * The author of the message - * @type {User} - */ - this.author = this.client.dataManager.newUser(data.author); - - /** - * Represents the author of the message as a guild member. Only available if the message comes from a guild - * where the author is still a member. - * @type {GuildMember} - */ - this.member = this.guild ? this.guild.member(this.author) || null : null; - - /** - * Whether or not this message is pinned - * @type {boolean} - */ - this.pinned = data.pinned; - - /** - * Whether or not the message was Text-To-Speech - * @type {boolean} - */ - this.tts = data.tts; - - /** - * A random number used for checking message delivery - * @type {string} - */ - this.nonce = data.nonce; - - /** - * Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications) - * @type {boolean} - */ - this.system = data.type === 6; - - /** - * A list of embeds in the message - e.g. YouTube Player - * @type {MessageEmbed[]} - */ - this.embeds = data.embeds.map(e => new Embed(this, e)); - - /** - * A collection of attachments in the message - e.g. Pictures - mapped by their ID. - * @type {Collection<string, MessageAttachment>} - */ - this.attachments = new Collection(); - for (const attachment of data.attachments) this.attachments.set(attachment.id, new Attachment(this, attachment)); - - /** - * The timestamp the message was sent at - * @type {number} - */ - this.createdTimestamp = new Date(data.timestamp).getTime(); - - /** - * The timestamp the message was last edited at (if applicable) - * @type {?number} - */ - this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp).getTime() : null; - - /** - * An object containing a further users, roles or channels collections - * @type {Object} - * @property {Collection<string, User>} mentions.users Mentioned users, maps their ID to the user object. - * @property {Collection<string, Role>} mentions.roles Mentioned roles, maps their ID to the role object. - * @property {Collection<string, GuildChannel>} mentions.channels Mentioned channels, - * maps their ID to the channel object. - * @property {boolean} mentions.everyone Whether or not @everyone was mentioned. - */ - this.mentions = { - users: new Collection(), - roles: new Collection(), - channels: new Collection(), - everyone: data.mention_everyone, - }; - - for (const mention of data.mentions) { - let user = this.client.users.get(mention.id); - if (user) { - this.mentions.users.set(user.id, user); - } else { - user = this.client.dataManager.newUser(mention); - this.mentions.users.set(user.id, user); - } - } - - if (data.mention_roles) { - for (const mention of data.mention_roles) { - const role = this.channel.guild.roles.get(mention); - if (role) this.mentions.roles.set(role.id, role); - } - } - - if (this.channel.guild) { - const channMentionsRaw = data.content.match(/<#([0-9]{14,20})>/g) || []; - for (const raw of channMentionsRaw) { - const chan = this.channel.guild.channels.get(raw.match(/([0-9]{14,20})/g)[0]); - if (chan) this.mentions.channels.set(chan.id, chan); - } - } - - this._edits = []; - - /** - * A collection of reactions to this message, mapped by the reaction "id". - * @type {Collection<string, MessageReaction>} - */ - this.reactions = new Collection(); - - if (data.reactions && data.reactions.length > 0) { - for (const reaction of data.reactions) { - const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; - this.reactions.set(id, new MessageReaction(this, reaction.emoji, reaction.count, reaction.me)); - } - } - - /** - * ID of the webhook that sent the message, if applicable - * @type {?string} - */ - this.webhookID = data.webhook_id || null; - } - - patch(data) { // eslint-disable-line complexity - if (data.author) { - this.author = this.client.users.get(data.author.id); - if (this.guild) this.member = this.guild.member(this.author); - } - if (data.content) this.content = data.content; - if (data.timestamp) this.createdTimestamp = new Date(data.timestamp).getTime(); - if (data.edited_timestamp) { - this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp).getTime() : null; - } - if ('tts' in data) this.tts = data.tts; - if ('mention_everyone' in data) this.mentions.everyone = data.mention_everyone; - if (data.nonce) this.nonce = data.nonce; - if (data.embeds) this.embeds = data.embeds.map(e => new Embed(this, e)); - if (data.type > -1) { - this.system = false; - if (data.type === 6) this.system = true; - } - if (data.attachments) { - this.attachments = new Collection(); - for (const attachment of data.attachments) { - this.attachments.set(attachment.id, new Attachment(this, attachment)); - } - } - if (data.mentions) { - for (const mention of data.mentions) { - let user = this.client.users.get(mention.id); - if (user) { - this.mentions.users.set(user.id, user); - } else { - user = this.client.dataManager.newUser(mention); - this.mentions.users.set(user.id, user); - } - } - } - if (data.mention_roles) { - for (const mention of data.mention_roles) { - const role = this.channel.guild.roles.get(mention); - if (role) this.mentions.roles.set(role.id, role); - } - } - if (data.id) this.id = data.id; - if (this.channel.guild && data.content) { - const channMentionsRaw = data.content.match(/<#([0-9]{14,20})>/g) || []; - for (const raw of channMentionsRaw) { - const chan = this.channel.guild.channels.get(raw.match(/([0-9]{14,20})/g)[0]); - if (chan) this.mentions.channels.set(chan.id, chan); - } - } - if (data.reactions) { - this.reactions = new Collection(); - if (data.reactions.length > 0) { - for (const reaction of data.reactions) { - const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; - this.reactions.set(id, new MessageReaction(this, data.emoji, data.count, data.me)); - } - } - } - } - - /** - * The time the message was sent - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The time the message was last edited at (if applicable) - * @type {?Date} - * @readonly - */ - get editedAt() { - return this.editedTimestamp ? new Date(this.editedTimestamp) : null; - } - - /** - * The guild the message was sent in (if in a guild channel) - * @type {?Guild} - * @readonly - */ - get guild() { - return this.channel.guild || null; - } - - /** - * The message contents with all mentions replaced by the equivalent text. If mentions cannot be resolved to a name, - * the relevant mention in the message content will not be converted. - * @type {string} - * @readonly - */ - get cleanContent() { - return this.content - .replace(/@(everyone|here)/g, '@\u200b$1') - .replace(/<@!?[0-9]+>/g, (input) => { - const id = input.replace(/<|!|>|@/g, ''); - if (this.channel.type === 'dm' || this.channel.type === 'group') { - return this.client.users.has(id) ? `@${this.client.users.get(id).username}` : input; - } - - const member = this.channel.guild.members.get(id); - if (member) { - if (member.nickname) return `@${member.nickname}`; - return `@${member.user.username}`; - } else { - const user = this.client.users.get(id); - if (user) return `@${user.username}`; - return input; - } - }) - .replace(/<#[0-9]+>/g, (input) => { - const channel = this.client.channels.get(input.replace(/<|#|>/g, '')); - if (channel) return `#${channel.name}`; - return input; - }) - .replace(/<@&[0-9]+>/g, (input) => { - if (this.channel.type === 'dm' || this.channel.type === 'group') return input; - const role = this.guild.roles.get(input.replace(/<|@|>|&/g, '')); - if (role) return `@${role.name}`; - return input; - }); - } - - /** - * An array of cached versions of the message, including the current version. - * Sorted from latest (first) to oldest (last). - * @type {Message[]} - * @readonly - */ - get edits() { - const copy = this._edits.slice(); - copy.unshift(this); - return copy; - } - - /** - * Whether the message is editable by the client user. - * @type {boolean} - * @readonly - */ - get editable() { - return this.author.id === this.client.user.id; - } - - /** - * Whether the message is deletable by the client user. - * @type {boolean} - * @readonly - */ - get deletable() { - return this.author.id === this.client.user.id || (this.guild && - this.channel.permissionsFor(this.client.user).hasPermission(Constants.PermissionFlags.MANAGE_MESSAGES) - ); - } - - /** - * Whether the message is pinnable by the client user. - * @type {boolean} - * @readonly - */ - get pinnable() { - return !this.guild || - this.channel.permissionsFor(this.client.user).hasPermission(Constants.PermissionFlags.MANAGE_MESSAGES); - } - - /** - * Whether or not a user, channel or role is mentioned in this message. - * @param {GuildChannel|User|Role|string} data either a guild channel, user or a role object, or a string representing - * the ID of any of these. - * @returns {boolean} - */ - isMentioned(data) { - data = data && data.id ? data.id : data; - return this.mentions.users.has(data) || this.mentions.channels.has(data) || this.mentions.roles.has(data); - } - - /** - * Whether or not a guild member is mentioned in this message. Takes into account - * user mentions, role mentions, and @everyone/@here mentions. - * @param {GuildMember|User} member Member/user to check for a mention of - * @returns {boolean} - */ - isMemberMentioned(member) { - if (this.mentions.everyone) return true; - if (this.mentions.users.has(member.id)) return true; - if (member instanceof Discord.GuildMember && member.roles.some(r => this.mentions.roles.has(r.id))) return true; - return false; - } - - /** - * Options that can be passed into editMessage - * @typedef {Object} MessageEditOptions - * @property {Object} [embed] An embed to be added/edited - * @property {string|boolean} [code] Language for optional codeblock formatting to apply - */ - - /** - * Edit the content of the message - * @param {StringResolvable} [content] The new content for the message - * @param {MessageEditOptions} [options] The options to provide - * @returns {Promise<Message>} - * @example - * // update the content of a message - * message.edit('This is my new content!') - * .then(msg => console.log(`Updated the content of a message from ${msg.author}`)) - * .catch(console.error); - */ - edit(content, options) { - if (!options && typeof content === 'object') { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.client.rest.methods.updateMessage(this, content, options); - } - - /** - * Edit the content of the message, with a code block - * @param {string} lang Language for the code block - * @param {StringResolvable} content The new content for the message - * @returns {Promise<Message>} - */ - editCode(lang, content) { - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - return this.edit(`\`\`\`${lang || ''}\n${content}\n\`\`\``); - } - - /** - * Pins this message to the channel's pinned messages - * @returns {Promise<Message>} - */ - pin() { - return this.client.rest.methods.pinMessage(this); - } - - /** - * Unpins this message from the channel's pinned messages - * @returns {Promise<Message>} - */ - unpin() { - return this.client.rest.methods.unpinMessage(this); - } - - /** - * Add a reaction to the message - * @param {string|Emoji|ReactionEmoji} emoji Emoji to react with - * @returns {Promise<MessageReaction>} - */ - react(emoji) { - emoji = this.client.resolver.resolveEmojiIdentifier(emoji); - if (!emoji) throw new TypeError('Emoji must be a string or Emoji/ReactionEmoji'); - - return this.client.rest.methods.addMessageReaction(this, emoji); - } - - /** - * Remove all reactions from a message - * @returns {Promise<Message>} - */ - clearReactions() { - return this.client.rest.methods.removeMessageReactions(this); - } - - /** - * Deletes the message - * @param {number} [timeout=0] How long to wait to delete the message in milliseconds - * @returns {Promise<Message>} - * @example - * // delete a message - * message.delete() - * .then(msg => console.log(`Deleted message from ${msg.author}`)) - * .catch(console.error); - */ - delete(timeout = 0) { - if (timeout <= 0) { - return this.client.rest.methods.deleteMessage(this); - } else { - return new Promise(resolve => { - this.client.setTimeout(() => { - resolve(this.delete()); - }, timeout); - }); - } - } - - /** - * Reply to the message - * @param {StringResolvable} content The content for the message - * @param {MessageOptions} [options = {}] The options to provide - * @returns {Promise<Message|Message[]>} - * @example - * // reply to a message - * message.reply('Hey, I\'m a reply!') - * .then(msg => console.log(`Sent a reply to ${msg.author}`)) - * .catch(console.error); - */ - reply(content, options = {}) { - content = `${this.guild || this.channel.type === 'group' ? `${this.author}, ` : ''}${content}`; - return this.channel.send(content, options); - } - - /** - * Fetches the webhook used to create this message. - * @returns {Promise<?Webhook>} - */ - fetchWebhook() { - if (!this.webhookID) return Promise.reject(new Error('The message was not sent by a webhook.')); - return this.client.fetchWebhook(this.webhookID); - } - - /** - * Used mainly internally. Whether two messages are identical in properties. If you want to compare messages - * without checking all the properties, use `message.id === message2.id`, which is much more efficient. This - * method allows you to see if there are differences in content, embeds, attachments, nonce and tts properties. - * @param {Message} message The message to compare it to - * @param {Object} rawData Raw data passed through the WebSocket about this message - * @returns {boolean} - */ - equals(message, rawData) { - if (!message) return false; - const embedUpdate = !message.author && !message.attachments; - if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length; - - let equal = this.id === message.id && - this.author.id === message.author.id && - this.content === message.content && - this.tts === message.tts && - this.nonce === message.nonce && - this.embeds.length === message.embeds.length && - this.attachments.length === message.attachments.length; - - if (equal && rawData) { - equal = this.mentions.everyone === message.mentions.everyone && - this.createdTimestamp === new Date(rawData.timestamp).getTime() && - this.editedTimestamp === new Date(rawData.edited_timestamp).getTime(); - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the message's content instead of the object. - * @returns {string} - * @example - * // logs: Message: This is a message! - * console.log(`Message: ${message}`); - */ - toString() { - return this.content; - } - - _addReaction(emoji, user) { - const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name; - let reaction; - if (this.reactions.has(emojiID)) { - reaction = this.reactions.get(emojiID); - if (!reaction.me) reaction.me = user.id === this.client.user.id; - } else { - reaction = new MessageReaction(this, emoji, 0, user.id === this.client.user.id); - this.reactions.set(emojiID, reaction); - } - if (!reaction.users.has(user.id)) { - reaction.users.set(user.id, user); - reaction.count++; - return reaction; - } - return null; - } - - _removeReaction(emoji, user) { - const emojiID = emoji.id || emoji; - if (this.reactions.has(emojiID)) { - const reaction = this.reactions.get(emojiID); - if (reaction.users.has(user.id)) { - reaction.users.delete(user.id); - reaction.count--; - if (user.id === this.client.user.id) reaction.me = false; - return reaction; - } - } - return null; - } - - _clearReactions() { - this.reactions.clear(); - } -} - -module.exports = Message; diff --git a/node_modules/discord.js/src/structures/MessageAttachment.js b/node_modules/discord.js/src/structures/MessageAttachment.js deleted file mode 100644 index 29dfb52..0000000 --- a/node_modules/discord.js/src/structures/MessageAttachment.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Represents an attachment in a message - */ -class MessageAttachment { - constructor(message, data) { - /** - * The Client that instantiated this MessageAttachment. - * @name MessageAttachment#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: message.client }); - - /** - * The message this attachment is part of. - * @type {Message} - */ - this.message = message; - - this.setup(data); - } - - setup(data) { - /** - * The ID of this attachment - * @type {string} - */ - this.id = data.id; - - /** - * The file name of this attachment - * @type {string} - */ - this.filename = data.filename; - - /** - * The size of this attachment in bytes - * @type {number} - */ - this.filesize = data.size; - - /** - * The URL to this attachment - * @type {string} - */ - this.url = data.url; - - /** - * The Proxy URL to this attachment - * @type {string} - */ - this.proxyURL = data.proxy_url; - - /** - * The height of this attachment (if an image) - * @type {?number} - */ - this.height = data.height; - - /** - * The width of this attachment (if an image) - * @type {?number} - */ - this.width = data.width; - } -} - -module.exports = MessageAttachment; diff --git a/node_modules/discord.js/src/structures/MessageCollector.js b/node_modules/discord.js/src/structures/MessageCollector.js deleted file mode 100644 index f84ecbd..0000000 --- a/node_modules/discord.js/src/structures/MessageCollector.js +++ /dev/null @@ -1,151 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const Collection = require('../util/Collection'); - -/** - * Collects messages based on a specified filter, then emits them. - * @extends {EventEmitter} - */ -class MessageCollector extends EventEmitter { - /** - * A function that takes a Message object and a MessageCollector and returns a boolean. - * ```js - * function(message, collector) { - * if (message.content.includes('discord')) { - * return true; // passed the filter test - * } - * return false; // failed the filter test - * } - * ``` - * @typedef {Function} CollectorFilterFunction - */ - - /** - * An object containing options used to configure a MessageCollector. All properties are optional. - * @typedef {Object} CollectorOptions - * @property {number} [time] Duration for the collector in milliseconds - * @property {number} [max] Maximum number of messages to handle - * @property {number} [maxMatches] Maximum number of successfully filtered messages to obtain - */ - - /** - * @param {Channel} channel The channel to collect messages in - * @param {CollectorFilterFunction} filter The filter function - * @param {CollectorOptions} [options] Options for the collector - */ - constructor(channel, filter, options = {}) { - super(); - - /** - * The channel this collector is operating on - * @type {Channel} - */ - this.channel = channel; - - /** - * A function used to filter messages that the collector collects. - * @type {CollectorFilterFunction} - */ - this.filter = filter; - - /** - * Options for the collecor. - * @type {CollectorOptions} - */ - this.options = options; - - /** - * Whether this collector has stopped collecting messages. - * @type {boolean} - */ - this.ended = false; - - /** - * A collection of collected messages, mapped by message ID. - * @type {Collection<string, Message>} - */ - this.collected = new Collection(); - - this.listener = message => this.verify(message); - this.channel.client.on('message', this.listener); - if (options.time) this.channel.client.setTimeout(() => this.stop('time'), options.time); - } - - /** - * Verifies a message against the filter and options - * @private - * @param {Message} message The message - * @returns {boolean} - */ - verify(message) { - if (this.channel ? this.channel.id !== message.channel.id : false) return false; - if (this.filter(message, this)) { - this.collected.set(message.id, message); - /** - * Emitted whenever the collector receives a message that passes the filter test. - * @param {Message} message The received message - * @param {MessageCollector} collector The collector the message passed through - * @event MessageCollector#message - */ - this.emit('message', message, this); - if (this.collected.size >= this.options.maxMatches) this.stop('matchesLimit'); - else if (this.options.max && this.collected.size === this.options.max) this.stop('limit'); - return true; - } - return false; - } - - /** - * Returns a promise that resolves when a valid message is sent. Rejects - * with collected messages if the Collector ends before receiving a message. - * @type {Promise<Message>} - * @readonly - */ - get next() { - return new Promise((resolve, reject) => { - if (this.ended) { - reject(this.collected); - return; - } - - const cleanup = () => { - this.removeListener('message', onMessage); - this.removeListener('end', onEnd); - }; - - const onMessage = (...args) => { - cleanup(); - resolve(...args); - }; - - const onEnd = (...args) => { - cleanup(); - reject(...args); - }; - - this.once('message', onMessage); - this.once('end', onEnd); - }); - } - - /** - * Stops the collector and emits `end`. - * @param {string} [reason='user'] An optional reason for stopping the collector - */ - stop(reason = 'user') { - if (this.ended) return; - this.ended = true; - this.channel.client.removeListener('message', this.listener); - /** - * Emitted when the Collector stops collecting. - * @param {Collection<string, Message>} collection A collection of messages collected - * during the lifetime of the collector, mapped by the ID of the messages. - * @param {string} reason The reason for the end of the collector. If it ended because it reached the specified time - * limit, this would be `time`. If you invoke `.stop()` without specifying a reason, this would be `user`. If it - * ended because it reached its message limit, it will be `limit`. - * @event MessageCollector#end - */ - this.emit('end', this.collected, reason); - } -} - -module.exports = MessageCollector; diff --git a/node_modules/discord.js/src/structures/MessageEmbed.js b/node_modules/discord.js/src/structures/MessageEmbed.js deleted file mode 100644 index 1249c42..0000000 --- a/node_modules/discord.js/src/structures/MessageEmbed.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * Represents an embed in a message (image/video preview, rich embed, etc.) - */ -class MessageEmbed { - constructor(message, data) { - /** - * The client that instantiated this embed - * @name MessageEmbed#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: message.client }); - - /** - * The message this embed is part of - * @type {Message} - */ - this.message = message; - - this.setup(data); - } - - setup(data) { - /** - * The type of this embed - * @type {string} - */ - this.type = data.type; - - /** - * The title of this embed, if there is one - * @type {?string} - */ - this.title = data.title; - - /** - * The description of this embed, if there is one - * @type {?string} - */ - this.description = data.description; - - /** - * The URL of this embed - * @type {string} - */ - this.url = data.url; - - /** - * The color of the embed - * @type {number} - */ - this.color = data.color; - - /** - * The fields of this embed - * @type {MessageEmbedField[]} - */ - this.fields = []; - if (data.fields) for (const field of data.fields) this.fields.push(new MessageEmbedField(this, field)); - - /** - * The timestamp of this embed - * @type {number} - */ - this.createdTimestamp = data.timestamp; - - /** - * The thumbnail of this embed, if there is one - * @type {MessageEmbedThumbnail} - */ - this.thumbnail = data.thumbnail ? new MessageEmbedThumbnail(this, data.thumbnail) : null; - - /** - * The author of this embed, if there is one - * @type {MessageEmbedAuthor} - */ - this.author = data.author ? new MessageEmbedAuthor(this, data.author) : null; - - /** - * The provider of this embed, if there is one - * @type {MessageEmbedProvider} - */ - this.provider = data.provider ? new MessageEmbedProvider(this, data.provider) : null; - - /** - * The footer of this embed - * @type {MessageEmbedFooter} - */ - this.footer = data.footer ? new MessageEmbedFooter(this, data.footer) : null; - } - - /** - * The date this embed was created - * @type {Date} - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The hexadecimal version of the embed color, with a leading hash. - * @type {string} - * @readonly - */ - get hexColor() { - let col = this.color.toString(16); - while (col.length < 6) col = `0${col}`; - return `#${col}`; - } -} - -/** - * Represents a thumbnail for a message embed - */ -class MessageEmbedThumbnail { - constructor(embed, data) { - /** - * The embed this thumbnail is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The URL for this thumbnail - * @type {string} - */ - this.url = data.url; - - /** - * The Proxy URL for this thumbnail - * @type {string} - */ - this.proxyURL = data.proxy_url; - - /** - * The height of the thumbnail - * @type {number} - */ - this.height = data.height; - - /** - * The width of the thumbnail - * @type {number} - */ - this.width = data.width; - } -} - -/** - * Represents a provider for a message embed - */ -class MessageEmbedProvider { - constructor(embed, data) { - /** - * The embed this provider is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this provider - * @type {string} - */ - this.name = data.name; - - /** - * The URL of this provider - * @type {string} - */ - this.url = data.url; - } -} - -/** - * Represents an author for a message embed - */ -class MessageEmbedAuthor { - constructor(embed, data) { - /** - * The embed this author is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this author - * @type {string} - */ - this.name = data.name; - - /** - * The URL of this author - * @type {string} - */ - this.url = data.url; - - /** - * The icon URL of this author - * @type {string} - */ - this.iconURL = data.icon_url; - } -} - -/** - * Represents a field for a message embed - */ -class MessageEmbedField { - constructor(embed, data) { - /** - * The embed this footer is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this field - * @type {string} - */ - this.name = data.name; - - /** - * The value of this field - * @type {string} - */ - this.value = data.value; - - /** - * If this field is displayed inline - * @type {boolean} - */ - this.inline = data.inline; - } -} - -/** - * Represents the footer of a message embed - */ -class MessageEmbedFooter { - constructor(embed, data) { - /** - * The embed this footer is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The text in this footer - * @type {string} - */ - this.text = data.text; - - /** - * The icon URL of this footer - * @type {string} - */ - this.iconURL = data.icon_url; - - /** - * The proxy icon URL of this footer - * @type {string} - */ - this.proxyIconUrl = data.proxy_icon_url; - } -} - -MessageEmbed.Thumbnail = MessageEmbedThumbnail; -MessageEmbed.Provider = MessageEmbedProvider; -MessageEmbed.Author = MessageEmbedAuthor; -MessageEmbed.Field = MessageEmbedField; -MessageEmbed.Footer = MessageEmbedFooter; - -module.exports = MessageEmbed; diff --git a/node_modules/discord.js/src/structures/MessageReaction.js b/node_modules/discord.js/src/structures/MessageReaction.js deleted file mode 100644 index 30c555f..0000000 --- a/node_modules/discord.js/src/structures/MessageReaction.js +++ /dev/null @@ -1,92 +0,0 @@ -const Collection = require('../util/Collection'); -const Emoji = require('./Emoji'); -const ReactionEmoji = require('./ReactionEmoji'); - -/** - * Represents a reaction to a message - */ -class MessageReaction { - constructor(message, emoji, count, me) { - /** - * The message that this reaction refers to - * @type {Message} - */ - this.message = message; - - /** - * Whether the client has given this reaction - * @type {boolean} - */ - this.me = me; - - /** - * The number of people that have given the same reaction. - * @type {number} - */ - this.count = count || 0; - - /** - * The users that have given this reaction, mapped by their ID. - * @type {Collection<string, User>} - */ - this.users = new Collection(); - - this._emoji = new ReactionEmoji(this, emoji.name, emoji.id); - } - - /** - * The emoji of this reaction, either an Emoji object for known custom emojis, or a ReactionEmoji - * object which has fewer properties. Whatever the prototype of the emoji, it will still have - * `name`, `id`, `identifier` and `toString()` - * @type {Emoji|ReactionEmoji} - */ - get emoji() { - if (this._emoji instanceof Emoji) return this._emoji; - // check to see if the emoji has become known to the client - if (this._emoji.id) { - const emojis = this.message.client.emojis; - if (emojis.has(this._emoji.id)) { - const emoji = emojis.get(this._emoji.id); - this._emoji = emoji; - return emoji; - } - } - return this._emoji; - } - - /** - * Removes a user from this reaction. - * @param {UserResolvable} [user=this.message.client.user] User to remove the reaction of - * @returns {Promise<MessageReaction>} - */ - remove(user = this.message.client.user) { - const message = this.message; - user = this.message.client.resolver.resolveUserID(user); - if (!user) return Promise.reject('Couldn\'t resolve the user ID to remove from the reaction.'); - return message.client.rest.methods.removeMessageReaction( - message, this.emoji.identifier, user - ); - } - - /** - * Fetch all the users that gave this reaction. Resolves with a collection of users, mapped by their IDs. - * @param {number} [limit=100] the maximum amount of users to fetch, defaults to 100 - * @returns {Promise<Collection<string, User>>} - */ - fetchUsers(limit = 100) { - const message = this.message; - return message.client.rest.methods.getMessageReactionUsers( - message, this.emoji.identifier, limit - ).then(users => { - this.users = new Collection(); - for (const rawUser of users) { - const user = this.message.client.dataManager.newUser(rawUser); - this.users.set(user.id, user); - } - this.count = this.users.size; - return users; - }); - } -} - -module.exports = MessageReaction; diff --git a/node_modules/discord.js/src/structures/OAuth2Application.js b/node_modules/discord.js/src/structures/OAuth2Application.js deleted file mode 100644 index b7c7285..0000000 --- a/node_modules/discord.js/src/structures/OAuth2Application.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Represents an OAuth2 Application - */ -class OAuth2Application { - constructor(client, data) { - /** - * The client that instantiated the application - * @name OAuth2Application#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of the app - * @type {string} - */ - this.id = data.id; - - /** - * The name of the app - * @type {string} - */ - this.name = data.name; - - /** - * The app's description - * @type {string} - */ - this.description = data.description; - - /** - * The app's icon hash - * @type {string} - */ - this.icon = data.icon; - - /** - * The app's icon URL - * @type {string} - */ - this.iconURL = `https://cdn.discordapp.com/app-icons/${this.id}/${this.icon}.jpg`; - - /** - * The app's RPC origins - * @type {Array<string>} - */ - this.rpcOrigins = data.rpc_origins; - } - - /** - * The timestamp the app was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the app was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * When concatenated with a string, this automatically concatenates the app name rather than the app object. - * @returns {string} - */ - toString() { - return this.name; - } -} - -module.exports = OAuth2Application; diff --git a/node_modules/discord.js/src/structures/PartialGuild.js b/node_modules/discord.js/src/structures/PartialGuild.js deleted file mode 100644 index 407212e..0000000 --- a/node_modules/discord.js/src/structures/PartialGuild.js +++ /dev/null @@ -1,51 +0,0 @@ -/* -{ splash: null, - id: '123123123', - icon: '123123123', - name: 'name' } -*/ - -/** - * Represents a guild that the client only has limited information for - e.g. from invites. - */ -class PartialGuild { - constructor(client, data) { - /** - * The Client that instantiated this PartialGuild - * @name PartialGuild#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of this guild - * @type {string} - */ - this.id = data.id; - - /** - * The name of this guild - * @type {string} - */ - this.name = data.name; - - /** - * The hash of this guild's icon, or null if there is none. - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image, or null if no splash (VIP only) - * @type {?string} - */ - this.splash = data.splash; - } -} - -module.exports = PartialGuild; diff --git a/node_modules/discord.js/src/structures/PartialGuildChannel.js b/node_modules/discord.js/src/structures/PartialGuildChannel.js deleted file mode 100644 index e58a6bb..0000000 --- a/node_modules/discord.js/src/structures/PartialGuildChannel.js +++ /dev/null @@ -1,44 +0,0 @@ -const Constants = require('../util/Constants'); - -/* -{ type: 0, id: '123123', name: 'heavy-testing' } } -*/ - -/** - * Represents a guild channel that the client only has limited information for - e.g. from invites. - */ -class PartialGuildChannel { - constructor(client, data) { - /** - * The Client that instantiated this PartialGuildChannel - * @name PartialGuildChannel#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of this guild channel - * @type {string} - */ - this.id = data.id; - - /** - * The name of this guild channel - * @type {string} - */ - this.name = data.name; - - /** - * The type of this guild channel - `text` or `voice` - * @type {string} - */ - this.type = Constants.ChannelTypes.text === data.type ? 'text' : 'voice'; - } -} - -module.exports = PartialGuildChannel; diff --git a/node_modules/discord.js/src/structures/PermissionOverwrites.js b/node_modules/discord.js/src/structures/PermissionOverwrites.js deleted file mode 100644 index 9b2f536..0000000 --- a/node_modules/discord.js/src/structures/PermissionOverwrites.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Represents a permission overwrite for a role or member in a guild channel. - */ -class PermissionOverwrites { - constructor(guildChannel, data) { - /** - * The GuildChannel this overwrite is for - * @name PermissionOverwrites#channel - * @type {GuildChannel} - * @readonly - */ - Object.defineProperty(this, 'channel', { value: guildChannel }); - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of this overwrite, either a user ID or a role ID - * @type {string} - */ - this.id = data.id; - - /** - * The type of this overwrite - * @type {string} - */ - this.type = data.type; - - this.deny = data.deny; - this.allow = data.allow; - } - - /** - * Delete this Permission Overwrite. - * @returns {Promise<PermissionOverwrites>} - */ - delete() { - return this.channel.client.rest.methods.deletePermissionOverwrites(this); - } -} - -module.exports = PermissionOverwrites; diff --git a/node_modules/discord.js/src/structures/Presence.js b/node_modules/discord.js/src/structures/Presence.js deleted file mode 100644 index ddca5fb..0000000 --- a/node_modules/discord.js/src/structures/Presence.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Represents a user's presence - */ -class Presence { - constructor(data = {}) { - /** - * The status of the presence: - * - * * **`online`** - user is online - * * **`offline`** - user is offline or invisible - * * **`idle`** - user is AFK - * * **`dnd`** - user is in Do not Disturb - * @type {string} - */ - this.status = data.status || 'offline'; - - /** - * The game that the user is playing, `null` if they aren't playing a game. - * @type {?Game} - */ - this.game = data.game ? new Game(data.game) : null; - } - - update(data) { - this.status = data.status || this.status; - this.game = data.game ? new Game(data.game) : null; - } - - /** - * Whether this presence is equal to another - * @param {Presence} presence Presence to compare with - * @returns {boolean} - */ - equals(presence) { - return this === presence || ( - presence && - this.status === presence.status && - this.game ? this.game.equals(presence.game) : !presence.game - ); - } -} - -/** - * Represents a game that is part of a user's presence. - */ -class Game { - constructor(data) { - /** - * The name of the game being played - * @type {string} - */ - this.name = data.name; - - /** - * The type of the game status - * @type {number} - */ - this.type = data.type; - - /** - * If the game is being streamed, a link to the stream - * @type {?string} - */ - this.url = data.url || null; - } - - /** - * Whether or not the game is being streamed - * @type {boolean} - * @readonly - */ - get streaming() { - return this.type === 1; - } - - /** - * Whether this game is equal to another game - * @param {Game} game Game to compare with - * @returns {boolean} - */ - equals(game) { - return this === game || ( - game && - this.name === game.name && - this.type === game.type && - this.url === game.url - ); - } -} - -exports.Presence = Presence; -exports.Game = Game; diff --git a/node_modules/discord.js/src/structures/ReactionEmoji.js b/node_modules/discord.js/src/structures/ReactionEmoji.js deleted file mode 100644 index b6d2cdb..0000000 --- a/node_modules/discord.js/src/structures/ReactionEmoji.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Represents a limited emoji set used for both custom and unicode emojis. Custom emojis - * will use this class opposed to the Emoji class when the client doesn't know enough - * information about them. - */ -class ReactionEmoji { - constructor(reaction, name, id) { - /** - * The message reaction this emoji refers to - * @type {MessageReaction} - */ - this.reaction = reaction; - - /** - * The name of this reaction emoji. - * @type {string} - */ - this.name = name; - - /** - * The ID of this reaction emoji. - * @type {string} - */ - this.id = id; - } - - /** - * The identifier of this emoji, used for message reactions - * @readonly - * @type {string} - */ - get identifier() { - if (this.id) return `${this.name}:${this.id}`; - return encodeURIComponent(this.name); - } - - /** - * Creates the text required to form a graphical emoji on Discord. - * @example - * // send the emoji used in a reaction to the channel the reaction is part of - * reaction.message.channel.sendMessage(`The emoji used is ${reaction.emoji}`); - * @returns {string} - */ - toString() { - return this.id ? `<:${this.name}:${this.id}>` : this.name; - } -} - -module.exports = ReactionEmoji; diff --git a/node_modules/discord.js/src/structures/RichEmbed.js b/node_modules/discord.js/src/structures/RichEmbed.js deleted file mode 100644 index fbd9383..0000000 --- a/node_modules/discord.js/src/structures/RichEmbed.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * A rich embed to be sent with a message - * @param {Object} [data] Data to set in the rich embed - */ -class RichEmbed { - constructor(data = {}) { - /** - * Title for this Embed - * @type {string} - */ - this.title = data.title; - - /** - * Description for this Embed - * @type {string} - */ - this.description = data.description; - - /** - * URL for this Embed - * @type {string} - */ - this.url = data.url; - - /** - * Color for this Embed - * @type {number} - */ - this.color = data.color; - - /** - * Author for this Embed - * @type {Object} - */ - this.author = data.author; - - /** - * Timestamp for this Embed - * @type {Date} - */ - this.timestamp = data.timestamp; - - /** - * Fields for this Embed - * @type {Object[]} - */ - this.fields = data.fields || []; - - /** - * Thumbnail for this Embed - * @type {Object} - */ - this.thumbnail = data.thumbnail; - - /** - * Image for this Embed - * @type {Object} - */ - this.image = data.image; - - /** - * Footer for this Embed - * @type {Object} - */ - this.footer = data.footer; - } - - /** - * Sets the title of this embed - * @param {StringResolvable} title The title - * @returns {RichEmbed} This embed - */ - setTitle(title) { - title = resolveString(title); - if (title.length > 256) throw new RangeError('RichEmbed titles may not exceed 256 characters.'); - this.title = title; - return this; - } - - /** - * Sets the description of this embed - * @param {StringResolvable} description The description - * @returns {RichEmbed} This embed - */ - setDescription(description) { - description = resolveString(description); - if (description.length > 2048) throw new RangeError('RichEmbed descriptions may not exceed 2048 characters.'); - this.description = description; - return this; - } - - /** - * Sets the URL of this embed - * @param {string} url The URL - * @returns {RichEmbed} This embed - */ - setURL(url) { - this.url = url; - return this; - } - - /** - * Sets the color of this embed - * @param {string|number|number[]} color The color to set - * @returns {RichEmbed} This embed - */ - setColor(color) { - let radix = 10; - if (color instanceof Array) { - color = (color[0] << 16) + (color[1] << 8) + color[2]; - } else if (typeof color === 'string' && color.startsWith('#')) { - radix = 16; - color = color.replace('#', ''); - } - color = parseInt(color, radix); - if (color < 0 || color > 0xFFFFFF) { - throw new RangeError('RichEmbed color must be within the range 0 - 16777215 (0xFFFFFF).'); - } else if (color && isNaN(color)) { - throw new TypeError('Unable to convert RichEmbed color to a number.'); - } - this.color = color; - return this; - } - - /** - * Sets the author of this embed - * @param {StringResolvable} name The name of the author - * @param {string} [icon] The icon URL of the author - * @param {string} [url] The URL of the author - * @returns {RichEmbed} This embed - */ - setAuthor(name, icon, url) { - this.author = { name: resolveString(name), icon_url: icon, url }; - return this; - } - - /** - * Sets the timestamp of this embed - * @param {Date} [timestamp=current date] The timestamp - * @returns {RichEmbed} This embed - */ - setTimestamp(timestamp = new Date()) { - this.timestamp = timestamp; - return this; - } - - /** - * Adds a field to the embed (max 25) - * @param {StringResolvable} name The name of the field - * @param {StringResolvable} value The value of the field - * @param {boolean} [inline=false] Set the field to display inline - * @returns {RichEmbed} This embed - */ - addField(name, value, inline = false) { - if (this.fields.length >= 25) throw new RangeError('RichEmbeds may not exceed 25 fields.'); - name = resolveString(name); - if (name.length > 256) throw new RangeError('RichEmbed field names may not exceed 256 characters.'); - value = resolveString(value); - if (value.length > 1024) throw new RangeError('RichEmbed field values may not exceed 1024 characters.'); - this.fields.push({ name: String(name), value: value, inline }); - return this; - } - - /** - * Set the thumbnail of this embed - * @param {string} url The URL of the thumbnail - * @returns {RichEmbed} This embed - */ - setThumbnail(url) { - this.thumbnail = { url }; - return this; - } - - /** - * Set the image of this embed - * @param {string} url The URL of the thumbnail - * @returns {RichEmbed} This embed - */ - setImage(url) { - this.image = { url }; - return this; - } - - /** - * Sets the footer of this embed - * @param {StringResolvable} text The text of the footer - * @param {string} [icon] The icon URL of the footer - * @returns {RichEmbed} This embed - */ - setFooter(text, icon) { - text = resolveString(text); - if (text.length > 2048) throw new RangeError('RichEmbed footer text may not exceed 2048 characters.'); - this.footer = { text, icon_url: icon }; - return this; - } -} - -module.exports = RichEmbed; - -function resolveString(data) { - if (typeof data === 'string') return data; - if (data instanceof Array) return data.join('\n'); - return String(data); -} diff --git a/node_modules/discord.js/src/structures/Role.js b/node_modules/discord.js/src/structures/Role.js deleted file mode 100644 index c15ff4b..0000000 --- a/node_modules/discord.js/src/structures/Role.js +++ /dev/null @@ -1,341 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * Represents a role on Discord - */ -class Role { - constructor(guild, data) { - /** - * The client that instantiated the role - * @name Role#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild that the role belongs to - * @type {Guild} - */ - this.guild = guild; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of the role (unique to the guild it is part of) - * @type {string} - */ - this.id = data.id; - - /** - * The name of the role - * @type {string} - */ - this.name = data.name; - - /** - * The base 10 color of the role - * @type {number} - */ - this.color = data.color; - - /** - * If true, users that are part of this role will appear in a separate category in the users list - * @type {boolean} - */ - this.hoist = data.hoist; - - /** - * The position of the role in the role manager - * @type {number} - */ - this.position = data.position; - - /** - * The evaluated permissions number - * @type {number} - */ - this.permissions = data.permissions; - - /** - * Whether or not the role is managed by an external service - * @type {boolean} - */ - this.managed = data.managed; - - /** - * Whether or not the role can be mentioned by anyone - * @type {boolean} - */ - this.mentionable = data.mentionable; - } - - /** - * The timestamp the role was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the role was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The hexadecimal version of the role color, with a leading hashtag. - * @type {string} - * @readonly - */ - get hexColor() { - let col = this.color.toString(16); - while (col.length < 6) col = `0${col}`; - return `#${col}`; - } - - /** - * The cached guild members that have this role. - * @type {Collection<string, GuildMember>} - * @readonly - */ - get members() { - return this.guild.members.filter(m => m.roles.has(this.id)); - } - - /** - * Whether the role is editable by the client user. - * @type {boolean} - * @readonly - */ - get editable() { - if (this.managed) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.MANAGE_ROLES_OR_PERMISSIONS)) return false; - return clientMember.highestRole.comparePositionTo(this) > 0; - } - - /** - * Get an object mapping permission names to whether or not the role enables that permission - * @returns {Object<string, boolean>} - * @example - * // print the serialized role - * console.log(role.serialize()); - */ - serialize() { - const serializedPermissions = {}; - for (const permissionName in Constants.PermissionFlags) { - serializedPermissions[permissionName] = this.hasPermission(permissionName); - } - return serializedPermissions; - } - - /** - * Checks if the role has a permission. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission - * @returns {boolean} - * @example - * // see if a role can ban a member - * if (role.hasPermission('BAN_MEMBERS')) { - * console.log('This role can ban members'); - * } else { - * console.log('This role can\'t ban members'); - * } - */ - hasPermission(permission, explicit = false) { - permission = this.client.resolver.resolvePermission(permission); - if (!explicit && (this.permissions & Constants.PermissionFlags.ADMINISTRATOR) > 0) return true; - return (this.permissions & permission) > 0; - } - - /** - * Checks if the role has all specified permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Compares this role's position to another role's. - * @param {Role} role Role to compare to this one - * @returns {number} Negative number if the this role's position is lower (other role's is higher), - * positive number if the this one is higher (other's is lower), 0 if equal - */ - comparePositionTo(role) { - return this.constructor.comparePositions(this, role); - } - - /** - * The data for a role - * @typedef {Object} RoleData - * @property {string} [name] The name of the role - * @property {number|string} [color] The color of the role, either a hex string or a base 10 number - * @property {boolean} [hoist] Whether or not the role should be hoisted - * @property {number} [position] The position of the role - * @property {string[]} [permissions] The permissions of the role - * @property {boolean} [mentionable] Whether or not the role should be mentionable - */ - - /** - * Edits the role - * @param {RoleData} data The new data for the role - * @returns {Promise<Role>} - * @example - * // edit a role - * role.edit({name: 'new role'}) - * .then(r => console.log(`Edited role ${r}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateGuildRole(this, data); - } - - /** - * Set a new name for the role - * @param {string} name The new name of the role - * @returns {Promise<Role>} - * @example - * // set the name of the role - * role.setName('new role') - * .then(r => console.log(`Edited name of role ${r}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Set a new color for the role - * @param {number|string} color The new color for the role, either a hex string or a base 10 number - * @returns {Promise<Role>} - * @example - * // set the color of a role - * role.setColor('#FF0000') - * .then(r => console.log(`Set color of role ${r}`)) - * .catch(console.error); - */ - setColor(color) { - return this.edit({ color }); - } - - /** - * Set whether or not the role should be hoisted - * @param {boolean} hoist Whether or not to hoist the role - * @returns {Promise<Role>} - * @example - * // set the hoist of the role - * role.setHoist(true) - * .then(r => console.log(`Role hoisted: ${r.hoist}`)) - * .catch(console.error); - */ - setHoist(hoist) { - return this.edit({ hoist }); - } - - /** - * Set the position of the role - * @param {number} position The position of the role - * @returns {Promise<Role>} - * @example - * // set the position of the role - * role.setPosition(1) - * .then(r => console.log(`Role position: ${r.position}`)) - * .catch(console.error); - */ - setPosition(position) { - return this.guild.setRolePosition(this, position).then(() => this); - } - - /** - * Set the permissions of the role - * @param {string[]} permissions The permissions of the role - * @returns {Promise<Role>} - * @example - * // set the permissions of the role - * role.setPermissions(['KICK_MEMBERS', 'BAN_MEMBERS']) - * .then(r => console.log(`Role updated ${r}`)) - * .catch(console.error); - */ - setPermissions(permissions) { - return this.edit({ permissions }); - } - - /** - * Set whether this role is mentionable - * @param {boolean} mentionable Whether this role should be mentionable - * @returns {Promise<Role>} - * @example - * // make the role mentionable - * role.setMentionable(true) - * .then(r => console.log(`Role updated ${r}`)) - * .catch(console.error); - */ - setMentionable(mentionable) { - return this.edit({ mentionable }); - } - - /** - * Deletes the role - * @returns {Promise<Role>} - * @example - * // delete a role - * role.delete() - * .then(r => console.log(`Deleted role ${r}`)) - * .catch(console.error); - */ - delete() { - return this.client.rest.methods.deleteGuildRole(this); - } - - /** - * Whether this role equals another role. It compares all properties, so for most operations - * it is advisable to just compare `role.id === role2.id` as it is much faster and is often - * what most users need. - * @param {Role} role Role to compare with - * @returns {boolean} - */ - equals(role) { - return role && - this.id === role.id && - this.name === role.name && - this.color === role.color && - this.hoist === role.hoist && - this.position === role.position && - this.permissions === role.permissions && - this.managed === role.managed; - } - - /** - * When concatenated with a string, this automatically concatenates the role mention rather than the Role object. - * @returns {string} - */ - toString() { - if (this.id === this.guild.id) return '@everyone'; - return `<@&${this.id}>`; - } - - /** - * Compares the positions of two roles. - * @param {Role} role1 First role to compare - * @param {Role} role2 Second role to compare - * @returns {number} Negative number if the first role's position is lower (second role's is higher), - * positive number if the first's is higher (second's is lower), 0 if equal - */ - static comparePositions(role1, role2) { - if (role1.position === role2.position) return role2.id - role1.id; - return role1.position - role2.position; - } -} - -module.exports = Role; diff --git a/node_modules/discord.js/src/structures/TextChannel.js b/node_modules/discord.js/src/structures/TextChannel.js deleted file mode 100644 index 9697abd..0000000 --- a/node_modules/discord.js/src/structures/TextChannel.js +++ /dev/null @@ -1,96 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild text channel on Discord. - * @extends {GuildChannel} - * @implements {TextBasedChannel} - */ -class TextChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - this.type = 'text'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The topic of the text channel, if there is one. - * @type {?string} - */ - this.topic = data.topic; - - this.lastMessageID = data.last_message_id; - } - - /** - * A collection of members that can see this channel, mapped by their ID. - * @type {Collection<string, GuildMember>} - * @readonly - */ - get members() { - const members = new Collection(); - for (const member of this.guild.members.values()) { - if (this.permissionsFor(member).hasPermission('READ_MESSAGES')) { - members.set(member.id, member); - } - } - return members; - } - - /** - * Fetch all webhooks for the channel. - * @returns {Promise<Collection<string, Webhook>>} - */ - fetchWebhooks() { - return this.client.rest.methods.getChannelWebhooks(this); - } - - /** - * Create a webhook for the channel. - * @param {string} name The name of the webhook. - * @param {BufferResolvable} avatar The avatar for the webhook. - * @returns {Promise<Webhook>} webhook The created webhook. - * @example - * channel.createWebhook('Snek', 'http://snek.s3.amazonaws.com/topSnek.png') - * .then(webhook => console.log(`Created Webhook ${webhook}`)) - * .catch(console.error) - */ - createWebhook(name, avatar) { - return new Promise(resolve => { - if (avatar.startsWith('data:')) { - resolve(this.client.rest.methods.createWebhook(this, name, avatar)); - } else { - this.client.resolver.resolveBuffer(avatar).then(data => - resolve(this.client.rest.methods.createWebhook(this, name, data)) - ); - } - }); - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(TextChannel, true); - -module.exports = TextChannel; diff --git a/node_modules/discord.js/src/structures/User.js b/node_modules/discord.js/src/structures/User.js deleted file mode 100644 index f714828..0000000 --- a/node_modules/discord.js/src/structures/User.js +++ /dev/null @@ -1,277 +0,0 @@ -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Constants = require('../util/Constants'); -const Presence = require('./Presence').Presence; - -/** - * Represents a user on Discord. - * @implements {TextBasedChannel} - */ -class User { - constructor(client, data) { - /** - * The Client that created the instance of the the User. - * @name User#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of the user - * @type {string} - */ - this.id = data.id; - - /** - * The username of the user - * @type {string} - */ - this.username = data.username; - - /** - * A discriminator based on username for the user - * @type {string} - */ - this.discriminator = data.discriminator; - - /** - * The ID of the user's avatar - * @type {string} - */ - this.avatar = data.avatar; - - /** - * Whether or not the user is a bot. - * @type {boolean} - */ - this.bot = Boolean(data.bot); - - /** - * The ID of the last message sent by the user, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - patch(data) { - for (const prop of ['id', 'username', 'discriminator', 'avatar', 'bot']) { - if (typeof data[prop] !== 'undefined') this[prop] = data[prop]; - } - if (data.token) this.client.token = data.token; - } - - /** - * The timestamp the user was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the user was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The presence of this user - * @type {Presence} - * @readonly - */ - get presence() { - if (this.client.presences.has(this.id)) return this.client.presences.get(this.id); - for (const guild of this.client.guilds.values()) { - if (guild.presences.has(this.id)) return guild.presences.get(this.id); - } - return new Presence(); - } - - /** - * A link to the user's avatar (if they have one, otherwise null) - * @type {?string} - * @readonly - */ - get avatarURL() { - if (!this.avatar) return null; - return Constants.Endpoints.avatar(this.id, this.avatar); - } - - /** - * A link to the user's default avatar - * @type {string} - * @readonly - */ - get defaultAvatarURL() { - let defaultAvatars = Object.values(Constants.DefaultAvatars); - let defaultAvatar = this.discriminator % defaultAvatars.length; - return Constants.Endpoints.assets(`${defaultAvatars[defaultAvatar]}.png`); - } - - /** - * A link to the user's avatar if they have one. Otherwise a link to their default avatar will be returned - * @type {string} - * @readonly - */ - get displayAvatarURL() { - return this.avatarURL || this.defaultAvatarURL; - } - - /** - * The note that is set for the user - * <warn>This is only available when using a user account.</warn> - * @type {?string} - * @readonly - */ - get note() { - return this.client.user.notes.get(this.id) || null; - } - - /** - * Check whether the user is typing in a channel. - * @param {ChannelResolvable} channel The channel to check in - * @returns {boolean} - */ - typingIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id); - } - - /** - * Get the time that the user started typing. - * @param {ChannelResolvable} channel The channel to get the time in - * @returns {?Date} - */ - typingSinceIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null; - } - - /** - * Get the amount of time the user has been typing in a channel for (in milliseconds), or -1 if they're not typing. - * @param {ChannelResolvable} channel The channel to get the time in - * @returns {number} - */ - typingDurationIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1; - } - - /** - * The DM between the client's user and this user - * @type {?DMChannel} - */ - get dmChannel() { - return this.client.channels.filter(c => c.type === 'dm').find(c => c.recipient.id === this.id); - } - - /** - * Deletes a DM channel (if one exists) between the client and the user. Resolves with the channel if successful. - * @returns {Promise<DMChannel>} - */ - deleteDM() { - return this.client.rest.methods.deleteChannel(this); - } - - /** - * Sends a friend request to the user - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<User>} - */ - addFriend() { - return this.client.rest.methods.addFriend(this); - } - - /** - * Removes the user from your friends - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<User>} - */ - removeFriend() { - return this.client.rest.methods.removeFriend(this); - } - - /** - * Blocks the user - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<User>} - */ - block() { - return this.client.rest.methods.blockUser(this); - } - - /** - * Unblocks the user - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<User>} - */ - unblock() { - return this.client.rest.methods.unblockUser(this); - } - - /** - * Get the profile of the user - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<UserProfile>} - */ - fetchProfile() { - return this.client.rest.methods.fetchUserProfile(this); - } - - /** - * Sets a note for the user - * <warn>This is only available when using a user account.</warn> - * @param {string} note The note to set for the user - * @returns {Promise<User>} - */ - setNote(note) { - return this.client.rest.methods.setNote(this, note); - } - - /** - * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, and bot flags. - * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. - * @param {User} user User to compare with - * @returns {boolean} - */ - equals(user) { - let equal = user && - this.id === user.id && - this.username === user.username && - this.discriminator === user.discriminator && - this.avatar === user.avatar && - this.bot === Boolean(user.bot); - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the user's mention instead of the User object. - * @returns {string} - * @example - * // logs: Hello from <@123456789>! - * console.log(`Hello from ${user}!`); - */ - toString() { - return `<@${this.id}>`; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } -} - -TextBasedChannel.applyToClass(User); - -module.exports = User; diff --git a/node_modules/discord.js/src/structures/UserConnection.js b/node_modules/discord.js/src/structures/UserConnection.js deleted file mode 100644 index 6ee9fc5..0000000 --- a/node_modules/discord.js/src/structures/UserConnection.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Represents a user connection (or "platform identity") - */ -class UserConnection { - constructor(user, data) { - /** - * The user that owns the Connection - * @type {User} - */ - this.user = user; - - this.setup(data); - } - - setup(data) { - /** - * The type of the Connection - * @type {string} - */ - this.type = data.type; - - /** - * The username of the connection account - * @type {string} - */ - this.name = data.name; - - /** - * The id of the connection account - * @type {string} - */ - this.id = data.id; - - /** - * Whether the connection is revoked - * @type {boolean} - */ - this.revoked = data.revoked; - - /** - * an array of partial server integrations (not yet implemented in this lib) - * @type {Object[]} - */ - this.integrations = data.integrations; - } -} - -module.exports = UserConnection; diff --git a/node_modules/discord.js/src/structures/UserProfile.js b/node_modules/discord.js/src/structures/UserProfile.js deleted file mode 100644 index 77f097c..0000000 --- a/node_modules/discord.js/src/structures/UserProfile.js +++ /dev/null @@ -1,56 +0,0 @@ -const Collection = require('../util/Collection'); -const UserConnection = require('./UserConnection'); - -/** - * Represents a user's profile on Discord. - */ -class UserProfile { - constructor(user, data) { - /** - * The owner of the profile - * @type {User} - */ - this.user = user; - - /** - * The Client that created the instance of the the UserProfile. - * @name UserProfile#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: user.client }); - - /** - * Guilds that the client user and the user share - * @type {Collection<Guild>} - */ - this.mutualGuilds = new Collection(); - - /** - * The user's connections - * @type {Collection<UserConnection>} - */ - this.connections = new Collection(); - - this.setup(data); - } - - setup(data) { - /** - * If the user has Discord Premium - * @type {boolean} - */ - this.premium = data.premium; - - for (const guild of data.mutual_guilds) { - if (this.client.guilds.has(guild.id)) { - this.mutualGuilds.set(guild.id, this.client.guilds.get(guild.id)); - } - } - for (const connection of data.connected_accounts) { - this.connections.set(connection.id, new UserConnection(this.user, connection)); - } - } -} - -module.exports = UserProfile; diff --git a/node_modules/discord.js/src/structures/VoiceChannel.js b/node_modules/discord.js/src/structures/VoiceChannel.js deleted file mode 100644 index 848a6d5..0000000 --- a/node_modules/discord.js/src/structures/VoiceChannel.js +++ /dev/null @@ -1,120 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild voice channel on Discord. - * @extends {GuildChannel} - */ -class VoiceChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - - /** - * The members in this voice channel. - * @type {Collection<string, GuildMember>} - */ - this.members = new Collection(); - - this.type = 'voice'; - } - - setup(data) { - super.setup(data); - - /** - * The bitrate of this voice channel - * @type {number} - */ - this.bitrate = data.bitrate; - - /** - * The maximum amount of users allowed in this channel - 0 means unlimited. - * @type {number} - */ - this.userLimit = data.user_limit; - } - - /** - * The voice connection for this voice channel, if the client is connected - * @type {?VoiceConnection} - * @readonly - */ - get connection() { - const connection = this.guild.voiceConnection; - if (connection && connection.channel.id === this.id) return connection; - return null; - } - - /** - * Checks if the client has permission join the voice channel - * @type {boolean} - */ - get joinable() { - if (this.client.browser) return false; - return this.permissionsFor(this.client.user).hasPermission('CONNECT'); - } - - /** - * Checks if the client has permission to send audio to the voice channel - * @type {boolean} - */ - get speakable() { - return this.permissionsFor(this.client.user).hasPermission('SPEAK'); - } - - /** - * Sets the bitrate of the channel - * @param {number} bitrate The new bitrate - * @returns {Promise<VoiceChannel>} - * @example - * // set the bitrate of a voice channel - * voiceChannel.setBitrate(48000) - * .then(vc => console.log(`Set bitrate to ${vc.bitrate} for ${vc.name}`)) - * .catch(console.error); - */ - setBitrate(bitrate) { - return this.edit({ bitrate }); - } - - /** - * Sets the user limit of the channel - * @param {number} userLimit The new user limit - * @returns {Promise<VoiceChannel>} - * @example - * // set the user limit of a voice channel - * voiceChannel.setUserLimit(42) - * .then(vc => console.log(`Set user limit to ${vc.userLimit} for ${vc.name}`)) - * .catch(console.error); - */ - setUserLimit(userLimit) { - return this.edit({ userLimit }); - } - - /** - * Attempts to join this voice channel - * @returns {Promise<VoiceConnection>} - * @example - * // join a voice channel - * voiceChannel.join() - * .then(connection => console.log('Connected!')) - * .catch(console.error); - */ - join() { - if (this.client.browser) return Promise.reject(new Error('Voice connections are not available in browsers.')); - return this.client.voice.joinChannel(this); - } - - /** - * Leaves this voice channel - * @example - * // leave a voice channel - * voiceChannel.leave(); - */ - leave() { - if (this.client.browser) return; - const connection = this.client.voice.connections.get(this.guild.id); - if (connection && connection.channel.id === this.id) connection.disconnect(); - } -} - -module.exports = VoiceChannel; diff --git a/node_modules/discord.js/src/structures/Webhook.js b/node_modules/discord.js/src/structures/Webhook.js deleted file mode 100644 index 96984ff..0000000 --- a/node_modules/discord.js/src/structures/Webhook.js +++ /dev/null @@ -1,200 +0,0 @@ -const path = require('path'); -const escapeMarkdown = require('../util/EscapeMarkdown'); - -/** - * Represents a webhook - */ -class Webhook { - constructor(client, dataOrID, token) { - if (client) { - /** - * The Client that instantiated the Webhook - * @name Webhook#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - if (dataOrID) this.setup(dataOrID); - } else { - this.id = dataOrID; - this.token = token; - Object.defineProperty(this, 'client', { value: this }); - } - } - - setup(data) { - /** - * The name of the webhook - * @type {string} - */ - this.name = data.name; - - /** - * The token for the webhook - * @type {string} - */ - this.token = data.token; - - /** - * The avatar for the webhook - * @type {string} - */ - this.avatar = data.avatar; - - /** - * The ID of the webhook - * @type {string} - */ - this.id = data.id; - - /** - * The guild the webhook belongs to - * @type {string} - */ - this.guildID = data.guild_id; - - /** - * The channel the webhook belongs to - * @type {string} - */ - this.channelID = data.channel_id; - - /** - * The owner of the webhook - * @type {User} - */ - if (data.user) this.owner = data.user; - } - - /** - * Options that can be passed into sendMessage, sendTTSMessage, sendFile, sendCode - * @typedef {Object} WebhookMessageOptions - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {boolean} [disableEveryone=this.options.disableEveryone] Whether or not @everyone and @here - * should be replaced with plain-text - */ - - /** - * Send a message with this webhook - * @param {StringResolvable} content The content to send. - * @param {WebhookMessageOptions} [options={}] The options to provide. - * @returns {Promise<Message|Message[]>} - * @example - * // send a message - * webhook.sendMessage('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - sendMessage(content, options = {}) { - return this.client.rest.methods.sendWebhookMessage(this, content, options); - } - - /** - * Send a raw slack message with this webhook - * @param {Object} body The raw body to send. - * @returns {Promise} - * @example - * // send a slack message - * webhook.sendSlackMessage({ - * 'username': 'Wumpus', - * 'attachments': [{ - * 'pretext': 'this looks pretty cool', - * 'color': '#F0F', - * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png', - * 'footer': 'Powered by sneks', - * 'ts': Date.now() / 1000 - * }] - * }).catch(console.error); - */ - sendSlackMessage(body) { - return this.client.rest.methods.sendSlackWebhookMessage(this, body); - } - - /** - * Send a text-to-speech message with this webhook - * @param {StringResolvable} content The content to send - * @param {WebhookMessageOptions} [options={}] The options to provide - * @returns {Promise<Message|Message[]>} - * @example - * // send a TTS message - * webhook.sendTTSMessage('hello!') - * .then(message => console.log(`Sent tts message: ${message.content}`)) - * .catch(console.error); - */ - sendTTSMessage(content, options = {}) { - Object.assign(options, { tts: true }); - return this.client.rest.methods.sendWebhookMessage(this, content, options); - } - - /** - * Send a file with this webhook - * @param {BufferResolvable} attachment The file to send - * @param {string} [fileName="file.jpg"] The name and extension of the file - * @param {StringResolvable} [content] Text message to send with the attachment - * @param {WebhookMessageOptions} [options] The options to provide - * @returns {Promise<Message>} - */ - sendFile(attachment, fileName, content, options = {}) { - if (!fileName) { - if (typeof attachment === 'string') { - fileName = path.basename(attachment); - } else if (attachment && attachment.path) { - fileName = path.basename(attachment.path); - } else { - fileName = 'file.jpg'; - } - } - return this.client.resolver.resolveBuffer(attachment).then(file => - this.client.rest.methods.sendWebhookMessage(this, content, options, { - file, - name: fileName, - }) - ); - } - - /** - * Send a code block with this webhook - * @param {string} lang Language for the code block - * @param {StringResolvable} content Content of the code block - * @param {WebhookMessageOptions} options The options to provide - * @returns {Promise<Message|Message[]>} - */ - sendCode(lang, content, options = {}) { - if (options.split) { - if (typeof options.split !== 'object') options.split = {}; - if (!options.split.prepend) options.split.prepend = `\`\`\`${lang || ''}\n`; - if (!options.split.append) options.split.append = '\n```'; - } - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - return this.sendMessage(`\`\`\`${lang || ''}\n${content}\n\`\`\``, options); - } - - /** - * Edit the webhook. - * @param {string} name The new name for the Webhook - * @param {BufferResolvable} avatar The new avatar for the Webhook. - * @returns {Promise<Webhook>} - */ - edit(name = this.name, avatar) { - if (avatar) { - return this.client.resolver.resolveBuffer(avatar).then(file => { - const dataURI = this.client.resolver.resolveBase64(file); - return this.client.rest.methods.editWebhook(this, name, dataURI); - }); - } - return this.client.rest.methods.editWebhook(this, name).then(data => { - this.setup(data); - return this; - }); - } - - /** - * Delete the webhook - * @returns {Promise} - */ - delete() { - return this.client.rest.methods.deleteWebhook(this); - } -} - -module.exports = Webhook; diff --git a/node_modules/discord.js/src/structures/interface/TextBasedChannel.js b/node_modules/discord.js/src/structures/interface/TextBasedChannel.js deleted file mode 100644 index 353c0a9..0000000 --- a/node_modules/discord.js/src/structures/interface/TextBasedChannel.js +++ /dev/null @@ -1,377 +0,0 @@ -const path = require('path'); -const Message = require('../Message'); -const MessageCollector = require('../MessageCollector'); -const Collection = require('../../util/Collection'); - - -/** - * Interface for classes that have text-channel-like features - * @interface - */ -class TextBasedChannel { - constructor() { - /** - * A collection containing the messages sent to this channel. - * @type {Collection<string, Message>} - */ - this.messages = new Collection(); - - /** - * The ID of the last message in the channel, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - /** - * Options that can be passed into send, sendMessage, sendFile, sendEmbed, sendCode, and Message#reply - * @typedef {Object} MessageOptions - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {string} [nonce=''] The nonce for the message - * @property {Object} [embed] An embed for the message - * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details) - * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here - * should be replaced with plain-text - * @property {FileOptions|string} [file] A file to send with the message - * @property {string|boolean} [code] Language for optional codeblock formatting to apply - * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if - * it exceeds the character limit. If an object is provided, these are the options for splitting the message. - */ - - /** - * @typedef {Object} FileOptions - * @property {BufferResolvable} attachment - * @property {string} [name='file.jpg'] - */ - - /** - * Options for splitting a message - * @typedef {Object} SplitOptions - * @property {number} [maxLength=1950] Maximum character length per message piece - * @property {string} [char='\n'] Character to split the message with - * @property {string} [prepend=''] Text to prepend to every piece except the first - * @property {string} [append=''] Text to append to every piece except the last - */ - - /** - * Send a message to this channel - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options={}] Options for the message - * @returns {Promise<Message|Message[]>} - * @example - * // send a message - * channel.send('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - send(content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - if (options.file) { - if (typeof options.file === 'string') options.file = { attachment: options.file }; - if (!options.file.name) { - if (typeof options.file.attachment === 'string') { - options.file.name = path.basename(options.file.attachment); - } else if (options.file.attachment && options.file.attachment.path) { - options.file.name = path.basename(options.file.attachment.path); - } else { - options.file.name = 'file.jpg'; - } - } - return this.client.resolver.resolveBuffer(options.file.attachment).then(file => - this.client.rest.methods.sendMessage(this, content, options, { - file, - name: options.file.name, - }) - ); - } - return this.client.rest.methods.sendMessage(this, content, options); - } - - /** - * Send a message to this channel - * @param {StringResolvable} content Text for the message - * @param {MessageOptions} [options={}] Options for the message - * @returns {Promise<Message|Message[]>} - * @example - * // send a message - * channel.sendMessage('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - sendMessage(content, options) { - return this.send(content, options); - } - - /** - * Send an embed to this channel - * @param {RichEmbed|Object} embed Embed for the message - * @param {string} [content] Text for the message - * @param {MessageOptions} [options] Options for the message - * @returns {Promise<Message>} - */ - sendEmbed(embed, content, options) { - if (!options && typeof content === 'object') { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.send(content, Object.assign(options, { embed })); - } - - /** - * Send a file to this channel - * @param {BufferResolvable} attachment File to send - * @param {string} [name='file.jpg'] Name and extension of the file - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options] Options for the message - * @returns {Promise<Message>} - */ - sendFile(attachment, name, content, options = {}) { - return this.send(content, Object.assign(options, { file: { attachment, name } })); - } - - /** - * Send a code block to this channel - * @param {string} lang Language for the code block - * @param {StringResolvable} content Content of the code block - * @param {MessageOptions} [options] Options for the message - * @returns {Promise<Message|Message[]>} - */ - sendCode(lang, content, options = {}) { - return this.send(content, Object.assign(options, { code: lang })); - } - - /** - * Gets a single message from this channel, regardless of it being cached or not. - * <warn>This is only available when using a bot account.</warn> - * @param {string} messageID ID of the message to get - * @returns {Promise<Message>} - * @example - * // get message - * channel.fetchMessage('99539446449315840') - * .then(message => console.log(message.content)) - * .catch(console.error); - */ - fetchMessage(messageID) { - return this.client.rest.methods.getChannelMessage(this, messageID).then(data => { - const msg = data instanceof Message ? data : new Message(this, data, this.client); - this._cacheMessage(msg); - return msg; - }); - } - - /** - * The parameters to pass in when requesting previous messages from a channel. `around`, `before` and - * `after` are mutually exclusive. All the parameters are optional. - * @typedef {Object} ChannelLogsQueryOptions - * @property {number} [limit=50] Number of messages to acquire - * @property {string} [before] ID of a message to get the messages that were posted before it - * @property {string} [after] ID of a message to get the messages that were posted after it - * @property {string} [around] ID of a message to get the messages that were posted around it - */ - - /** - * Gets the past messages sent in this channel. Resolves with a collection mapping message ID's to Message objects. - * @param {ChannelLogsQueryOptions} [options={}] Query parameters to pass in - * @returns {Promise<Collection<string, Message>>} - * @example - * // get messages - * channel.fetchMessages({limit: 10}) - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - */ - fetchMessages(options = {}) { - return this.client.rest.methods.getChannelMessages(this, options).then(data => { - const messages = new Collection(); - for (const message of data) { - const msg = new Message(this, message, this.client); - messages.set(message.id, msg); - this._cacheMessage(msg); - } - return messages; - }); - } - - /** - * Fetches the pinned messages of this channel and returns a collection of them. - * @returns {Promise<Collection<string, Message>>} - */ - fetchPinnedMessages() { - return this.client.rest.methods.getChannelPinnedMessages(this).then(data => { - const messages = new Collection(); - for (const message of data) { - const msg = new Message(this, message, this.client); - messages.set(message.id, msg); - this._cacheMessage(msg); - } - return messages; - }); - } - - /** - * Starts a typing indicator in the channel. - * @param {number} [count] The number of times startTyping should be considered to have been called - * @example - * // start typing in a channel - * channel.startTyping(); - */ - startTyping(count) { - if (typeof count !== 'undefined' && count < 1) throw new RangeError('Count must be at least 1.'); - if (!this.client.user._typing.has(this.id)) { - this.client.user._typing.set(this.id, { - count: count || 1, - interval: this.client.setInterval(() => { - this.client.rest.methods.sendTyping(this.id); - }, 4000), - }); - this.client.rest.methods.sendTyping(this.id); - } else { - const entry = this.client.user._typing.get(this.id); - entry.count = count || entry.count + 1; - } - } - - /** - * Stops the typing indicator in the channel. - * The indicator will only stop if this is called as many times as startTyping(). - * <info>It can take a few seconds for the client user to stop typing.</info> - * @param {boolean} [force=false] Whether or not to reset the call count and force the indicator to stop - * @example - * // stop typing in a channel - * channel.stopTyping(); - * @example - * // force typing to fully stop in a channel - * channel.stopTyping(true); - */ - stopTyping(force = false) { - if (this.client.user._typing.has(this.id)) { - const entry = this.client.user._typing.get(this.id); - entry.count--; - if (entry.count <= 0 || force) { - this.client.clearInterval(entry.interval); - this.client.user._typing.delete(this.id); - } - } - } - - /** - * Whether or not the typing indicator is being shown in the channel. - * @type {boolean} - * @readonly - */ - get typing() { - return this.client.user._typing.has(this.id); - } - - /** - * Number of times `startTyping` has been called. - * @type {number} - * @readonly - */ - get typingCount() { - if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count; - return 0; - } - - /** - * Creates a Message Collector - * @param {CollectorFilterFunction} filter The filter to create the collector with - * @param {CollectorOptions} [options={}] The options to pass to the collector - * @returns {MessageCollector} - * @example - * // create a message collector - * const collector = channel.createCollector( - * m => m.content.includes('discord'), - * { time: 15000 } - * ); - * collector.on('message', m => console.log(`Collected ${m.content}`)); - * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); - */ - createCollector(filter, options = {}) { - return new MessageCollector(this, filter, options); - } - - /** - * An object containing the same properties as CollectorOptions, but a few more: - * @typedef {CollectorOptions} AwaitMessagesOptions - * @property {string[]} [errors] Stop/end reasons that cause the promise to reject - */ - - /** - * Similar to createCollector but in promise form. Resolves with a collection of messages that pass the specified - * filter. - * @param {CollectorFilterFunction} filter The filter function to use - * @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector - * @returns {Promise<Collection<string, Message>>} - * @example - * // await !vote messages - * const filter = m => m.content.startsWith('!vote'); - * // errors: ['time'] treats ending because of the time limit as an error - * channel.awaitMessages(filter, { max: 4, time: 60000, errors: ['time'] }) - * .then(collected => console.log(collected.size)) - * .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`)); - */ - awaitMessages(filter, options = {}) { - return new Promise((resolve, reject) => { - const collector = this.createCollector(filter, options); - collector.on('end', (collection, reason) => { - if (options.errors && options.errors.includes(reason)) { - reject(collection); - } else { - resolve(collection); - } - }); - }); - } - - /** - * Bulk delete given messages. - * <warn>This is only available when using a bot account.</warn> - * @param {Collection<string, Message>|Message[]|number} messages Messages to delete, or number of messages to delete - * @returns {Promise<Collection<string, Message>>} Deleted messages - */ - bulkDelete(messages) { - if (!isNaN(messages)) return this.fetchMessages({ limit: messages }).then(msgs => this.bulkDelete(msgs)); - if (messages instanceof Array || messages instanceof Collection) { - const messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id); - return this.client.rest.methods.bulkDeleteMessages(this, messageIDs); - } - throw new TypeError('The messages must be an Array, Collection, or number.'); - } - - _cacheMessage(message) { - const maxSize = this.client.options.messageCacheMaxSize; - if (maxSize === 0) return null; - if (this.messages.size >= maxSize && maxSize > 0) this.messages.delete(this.messages.firstKey()); - this.messages.set(message.id, message); - return message; - } -} - -exports.applyToClass = (structure, full = false) => { - const props = ['send', 'sendMessage', 'sendEmbed', 'sendFile', 'sendCode']; - if (full) { - props.push( - '_cacheMessage', - 'fetchMessages', - 'fetchMessage', - 'bulkDelete', - 'startTyping', - 'stopTyping', - 'typing', - 'typingCount', - 'fetchPinnedMessages', - 'createCollector', - 'awaitMessages' - ); - } - for (const prop of props) { - Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop)); - } -}; diff --git a/node_modules/discord.js/src/util/ArraysEqual.js b/node_modules/discord.js/src/util/ArraysEqual.js deleted file mode 100644 index efd8275..0000000 --- a/node_modules/discord.js/src/util/ArraysEqual.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = function arraysEqual(a, b) { - if (a === b) return true; - if (a.length !== b.length) return false; - - for (const itemInd in a) { - const item = a[itemInd]; - const ind = b.indexOf(item); - if (ind) { - b.splice(ind, 1); - } - } - - return b.length === 0; -}; diff --git a/node_modules/discord.js/src/util/CloneObject.js b/node_modules/discord.js/src/util/CloneObject.js deleted file mode 100644 index 13366a7..0000000 --- a/node_modules/discord.js/src/util/CloneObject.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = function cloneObject(obj) { - const cloned = Object.create(obj); - Object.assign(cloned, obj); - return cloned; -}; diff --git a/node_modules/discord.js/src/util/Collection.js b/node_modules/discord.js/src/util/Collection.js deleted file mode 100644 index bafe710..0000000 --- a/node_modules/discord.js/src/util/Collection.js +++ /dev/null @@ -1,365 +0,0 @@ -/** - * A Map with additional utility methods. This is used throughout discord.js rather than Arrays for anything that has - * an ID, for significantly improved performance and ease-of-use. - * @extends {Map} - */ -class Collection extends Map { - constructor(iterable) { - super(iterable); - - /** - * Cached array for the `array()` method - will be reset to `null` whenever `set()` or `delete()` are called. - * @type {?Array} - * @private - */ - this._array = null; - - /** - * Cached array for the `keyArray()` method - will be reset to `null` whenever `set()` or `delete()` are called. - * @type {?Array} - * @private - */ - this._keyArray = null; - } - - set(key, val) { - this._array = null; - this._keyArray = null; - return super.set(key, val); - } - - delete(key) { - this._array = null; - this._keyArray = null; - return super.delete(key); - } - - /** - * Creates an ordered array of the values of this collection, and caches it internally. The array will only be - * reconstructed if an item is added to or removed from the collection, or if you change the length of the array - * itself. If you don't want this caching behaviour, use `Array.from(collection.values())` instead. - * @returns {Array} - */ - array() { - if (!this._array || this._array.length !== this.size) this._array = Array.from(this.values()); - return this._array; - } - - /** - * Creates an ordered array of the keys of this collection, and caches it internally. The array will only be - * reconstructed if an item is added to or removed from the collection, or if you change the length of the array - * itself. If you don't want this caching behaviour, use `Array.from(collection.keys())` instead. - * @returns {Array} - */ - keyArray() { - if (!this._keyArray || this._keyArray.length !== this.size) this._keyArray = Array.from(this.keys()); - return this._keyArray; - } - - /** - * Obtains the first item in this collection. - * @returns {*} - */ - first() { - return this.values().next().value; - } - - /** - * Obtains the first key in this collection. - * @returns {*} - */ - firstKey() { - return this.keys().next().value; - } - - /** - * Obtains the last item in this collection. This relies on the `array()` method, and thus the caching mechanism - * applies here as well. - * @returns {*} - */ - last() { - const arr = this.array(); - return arr[arr.length - 1]; - } - - /** - * Obtains the last key in this collection. This relies on the `keyArray()` method, and thus the caching mechanism - * applies here as well. - * @returns {*} - */ - lastKey() { - const arr = this.keyArray(); - return arr[arr.length - 1]; - } - - /** - * Obtains a random item from this collection. This relies on the `array()` method, and thus the caching mechanism - * applies here as well. - * @returns {*} - */ - random() { - const arr = this.array(); - return arr[Math.floor(Math.random() * arr.length)]; - } - - /** - * Obtains a random key from this collection. This relies on the `keyArray()` method, and thus the caching mechanism - * applies here as well. - * @returns {*} - */ - randomKey() { - const arr = this.keyArray(); - return arr[Math.floor(Math.random() * arr.length)]; - } - - /** - * Searches for all items where their specified property's value is identical to the given value - * (`item[prop] === value`). - * @param {string} prop The property to test against - * @param {*} value The expected value - * @returns {Array} - * @example - * collection.findAll('username', 'Bob'); - */ - findAll(prop, value) { - if (typeof prop !== 'string') throw new TypeError('Key must be a string.'); - if (typeof value === 'undefined') throw new Error('Value must be specified.'); - const results = []; - for (const item of this.values()) { - if (item[prop] === value) results.push(item); - } - return results; - } - - /** - * Searches for a single item where its specified property's value is identical to the given value - * (`item[prop] === value`), or the given function returns a truthy value. In the latter case, this is identical to - * [Array.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). - * <warn>Do not use this to obtain an item by its ID. Instead, use `collection.get(id)`. See - * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) for details.</warn> - * @param {string|Function} propOrFn The property to test against, or the function to test with - * @param {*} [value] The expected value - only applicable and required if using a property for the first argument - * @returns {*} - * @example - * collection.find('username', 'Bob'); - * @example - * collection.find(val => val.username === 'Bob'); - */ - find(propOrFn, value) { - if (typeof propOrFn === 'string') { - if (typeof value === 'undefined') throw new Error('Value must be specified.'); - if (propOrFn === 'id') throw new RangeError('Don\'t use .find() with IDs. Instead, use .get(id).'); - for (const item of this.values()) { - if (item[propOrFn] === value) return item; - } - return null; - } else if (typeof propOrFn === 'function') { - for (const [key, val] of this) { - if (propOrFn(val, key, this)) return val; - } - return null; - } else { - throw new Error('First argument must be a property string or a function.'); - } - } - - /* eslint-disable max-len */ - /** - * Searches for the key of a single item where its specified property's value is identical to the given value - * (`item[prop] === value`), or the given function returns a truthy value. In the latter case, this is identical to - * [Array.findIndex()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex). - * @param {string|Function} propOrFn The property to test against, or the function to test with - * @param {*} [value] The expected value - only applicable and required if using a property for the first argument - * @returns {*} - * @example - * collection.findKey('username', 'Bob'); - * @example - * collection.findKey(val => val.username === 'Bob'); - */ - /* eslint-enable max-len */ - findKey(propOrFn, value) { - if (typeof propOrFn === 'string') { - if (typeof value === 'undefined') throw new Error('Value must be specified.'); - for (const [key, val] of this) { - if (val[propOrFn] === value) return key; - } - return null; - } else if (typeof propOrFn === 'function') { - for (const [key, val] of this) { - if (propOrFn(val, key, this)) return key; - } - return null; - } else { - throw new Error('First argument must be a property string or a function.'); - } - } - - /** - * Searches for the existence of a single item where its specified property's value is identical to the given value - * (`item[prop] === value`). - * <warn>Do not use this to check for an item by its ID. Instead, use `collection.has(id)`. See - * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) for details.</warn> - * @param {string} prop The property to test against - * @param {*} value The expected value - * @returns {boolean} - * @example - * if (collection.exists('username', 'Bob')) { - * console.log('user here!'); - * } - */ - exists(prop, value) { - if (prop === 'id') throw new RangeError('Don\'t use .exists() with IDs. Instead, use .has(id).'); - return Boolean(this.find(prop, value)); - } - - /** - * Identical to - * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), - * but returns a Collection instead of an Array. - * @param {Function} fn Function used to test (should return a boolean) - * @param {Object} [thisArg] Value to use as `this` when executing function - * @returns {Collection} - */ - filter(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - const results = new Collection(); - for (const [key, val] of this) { - if (fn(val, key, this)) results.set(key, val); - } - return results; - } - - /** - * Identical to - * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). - * @param {Function} fn Function used to test (should return a boolean) - * @param {Object} [thisArg] Value to use as `this` when executing function - * @returns {Array} - */ - filterArray(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - const results = []; - for (const [key, val] of this) { - if (fn(val, key, this)) results.push(val); - } - return results; - } - - /** - * Identical to - * [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). - * @param {Function} fn Function that produces an element of the new array, taking three arguments - * @param {*} [thisArg] Value to use as `this` when executing function - * @returns {Array} - */ - map(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - const arr = new Array(this.size); - let i = 0; - for (const [key, val] of this) arr[i++] = fn(val, key, this); - return arr; - } - - /** - * Identical to - * [Array.some()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some). - * @param {Function} fn Function used to test (should return a boolean) - * @param {Object} [thisArg] Value to use as `this` when executing function - * @returns {boolean} - */ - some(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - for (const [key, val] of this) { - if (fn(val, key, this)) return true; - } - return false; - } - - /** - * Identical to - * [Array.every()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every). - * @param {Function} fn Function used to test (should return a boolean) - * @param {Object} [thisArg] Value to use as `this` when executing function - * @returns {boolean} - */ - every(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - for (const [key, val] of this) { - if (!fn(val, key, this)) return false; - } - return true; - } - - /** - * Identical to - * [Array.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce). - * @param {Function} fn Function used to reduce, taking four arguments; `accumulator`, `currentValue`, `currentKey`, - * and `collection` - * @param {*} [initialValue] Starting value for the accumulator - * @returns {*} - */ - reduce(fn, initialValue) { - let accumulator; - if (typeof initialValue !== 'undefined') { - accumulator = initialValue; - for (const [key, val] of this) accumulator = fn(accumulator, val, key, this); - } else { - let first = true; - for (const [key, val] of this) { - if (first) { - accumulator = val; - first = false; - continue; - } - accumulator = fn(accumulator, val, key, this); - } - } - return accumulator; - } - - /** - * Combines this collection with others into a new collection. None of the source collections are modified. - * @param {...Collection} collections Collections to merge - * @returns {Collection} - * @example const newColl = someColl.concat(someOtherColl, anotherColl, ohBoyAColl); - */ - concat(...collections) { - const newColl = new this.constructor(); - for (const [key, val] of this) newColl.set(key, val); - for (const coll of collections) { - for (const [key, val] of coll) newColl.set(key, val); - } - return newColl; - } - - /** - * Calls the `delete()` method on all items that have it. - * @returns {Promise[]} - */ - deleteAll() { - const returns = []; - for (const item of this.values()) { - if (item.delete) returns.push(item.delete()); - } - return returns; - } - - /** - * Checks if this collection shares identical key-value pairings with another. - * This is different to checking for equality using equal-signs, because - * the collections may be different objects, but contain the same data. - * @param {Collection} collection Collection to compare with - * @returns {boolean} Whether the collections have identical contents - */ - equals(collection) { - if (!collection) return false; - if (this === collection) return true; - if (this.size !== collection.size) return false; - return !this.find((value, key) => { - const testVal = collection.get(key); - return testVal !== value || (testVal === undefined && !collection.has(key)); - }); - } -} - -module.exports = Collection; diff --git a/node_modules/discord.js/src/util/Constants.js b/node_modules/discord.js/src/util/Constants.js deleted file mode 100644 index cee2192..0000000 --- a/node_modules/discord.js/src/util/Constants.js +++ /dev/null @@ -1,371 +0,0 @@ -exports.Package = require('../../package.json'); - -/** - * Options for a Client. - * @typedef {Object} ClientOptions - * @property {string} [apiRequestMethod='sequential'] 'sequential' or 'burst'. Sequential executes all requests in - * the order they are triggered, whereas burst runs multiple at a time, and doesn't guarantee a particular order. - * @property {number} [shardId=0] The ID of this shard - * @property {number} [shardCount=0] The number of shards - * @property {number} [messageCacheMaxSize=200] Maximum number of messages to cache per channel - * (-1 or Infinity for unlimited - don't do this without message sweeping, otherwise memory usage will climb - * indefinitely) - * @property {number} [messageCacheLifetime=0] How long until a message should be uncached by the message sweeping - * (in seconds, 0 for forever) - * @property {number} [messageSweepInterval=0] How frequently to remove messages from the cache that are older than - * the message cache lifetime (in seconds, 0 for never) - * @property {boolean} [fetchAllMembers=false] Whether to cache all guild members and users upon startup, as well as - * upon joining a guild - * @property {boolean} [disableEveryone=false] Default value for MessageOptions.disableEveryone - * @property {boolean} [sync=false] Whether to periodically sync guilds (for userbots) - * @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their - * corresponding websocket events - * @property {number} [restTimeOffset=500] The extra time in millseconds to wait before continuing to make REST - * requests (higher values will reduce rate-limiting errors on bad connections) - * @property {WSEventType[]} [disabledEvents] An array of disabled websocket events. Events in this array will not be - * processed, potentially resulting in performance improvements for larger bots. Only disable events you are - * 100% certain you don't need, as many are important, but not obviously so. The safest one to disable with the - * most impact is typically `TYPING_START`. - * @property {WebsocketOptions} [ws] Options for the websocket - */ -exports.DefaultOptions = { - apiRequestMethod: 'sequential', - shardId: 0, - shardCount: 0, - messageCacheMaxSize: 200, - messageCacheLifetime: 0, - messageSweepInterval: 0, - fetchAllMembers: false, - disableEveryone: false, - sync: false, - restWsBridgeTimeout: 5000, - disabledEvents: [], - restTimeOffset: 500, - - /** - * Websocket options. These are left as snake_case to match the API. - * @typedef {Object} WebsocketOptions - * @property {number} [large_threshold=250] Number of members in a guild to be considered large - * @property {boolean} [compress=true] Whether to compress data sent on the connection. - * Defaults to `false` for browsers. - */ - ws: { - large_threshold: 250, - compress: typeof window === 'undefined', - properties: { - $os: process ? process.platform : 'discord.js', - $browser: 'discord.js', - $device: 'discord.js', - $referrer: '', - $referring_domain: '', - }, - }, -}; - -exports.Errors = { - NO_TOKEN: 'Request to use token, but token was unavailable to the client.', - NO_BOT_ACCOUNT: 'Only bot accounts are able to make use of this feature.', - NO_USER_ACCOUNT: 'Only user accounts are able to make use of this feature.', - BAD_WS_MESSAGE: 'A bad message was received from the websocket; either bad compression, or not JSON.', - TOOK_TOO_LONG: 'Something took too long to do.', - NOT_A_PERMISSION: 'Invalid permission string or number.', - INVALID_RATE_LIMIT_METHOD: 'Unknown rate limiting method.', - BAD_LOGIN: 'Incorrect login details were provided.', - INVALID_SHARD: 'Invalid shard settings were provided.', - INVALID_TOKEN: 'An invalid token was provided.', -}; - -const PROTOCOL_VERSION = exports.PROTOCOL_VERSION = 6; -const HOST = exports.HOST = `https://discordapp.com`; -const API = exports.API = `${HOST}/api/v${PROTOCOL_VERSION}`; -const Endpoints = exports.Endpoints = { - // general - login: `${API}/auth/login`, - logout: `${API}/auth/logout`, - gateway: `${API}/gateway`, - botGateway: `${API}/gateway/bot`, - invite: (id) => `${API}/invite/${id}`, - inviteLink: (id) => `https://discord.gg/${id}`, - assets: (asset) => `${HOST}/assets/${asset}`, - CDN: 'https://cdn.discordapp.com', - - // users - user: (userID) => `${API}/users/${userID}`, - userChannels: (userID) => `${Endpoints.user(userID)}/channels`, - userProfile: (userID) => `${Endpoints.user(userID)}/profile`, - avatar: (userID, avatar) => { - if (userID === '1') return avatar; - return `${Endpoints.CDN}/avatars/${userID}/${avatar}.${avatar.startsWith('a_') ? 'gif' : 'jpg'}?size=1024`; - }, - me: `${API}/users/@me`, - meGuild: (guildID) => `${Endpoints.me}/guilds/${guildID}`, - meMentions: (limit, roles, everyone, guildID) => - `users/@me/mentions?limit=${limit}&roles=${roles}&everyone=${everyone}${guildID ? `&guild_id=${guildID}` : ''}`, - relationships: (userID) => `${Endpoints.user(userID)}/relationships`, - note: (userID) => `${Endpoints.me}/notes/${userID}`, - - // guilds - guilds: `${API}/guilds`, - guild: (guildID) => `${Endpoints.guilds}/${guildID}`, - guildIcon: (guildID, hash) => `${Endpoints.CDN}/icons/${guildID}/${hash}.jpg`, - guildSplash: (guildID, hash) => `${Endpoints.CDN}/splashes/${guildID}/${hash}.jpg`, - guildPrune: (guildID) => `${Endpoints.guild(guildID)}/prune`, - guildEmbed: (guildID) => `${Endpoints.guild(guildID)}/embed`, - guildInvites: (guildID) => `${Endpoints.guild(guildID)}/invites`, - guildRoles: (guildID) => `${Endpoints.guild(guildID)}/roles`, - guildRole: (guildID, roleID) => `${Endpoints.guildRoles(guildID)}/${roleID}`, - guildBans: (guildID) => `${Endpoints.guild(guildID)}/bans`, - guildIntegrations: (guildID) => `${Endpoints.guild(guildID)}/integrations`, - guildMembers: (guildID) => `${Endpoints.guild(guildID)}/members`, - guildMember: (guildID, memberID) => `${Endpoints.guildMembers(guildID)}/${memberID}`, - guildMemberRole: (guildID, memberID, roleID) => `${Endpoints.guildMember(guildID, memberID)}/roles/${roleID}`, - guildMemberNickname: (guildID) => `${Endpoints.guildMember(guildID, '@me')}/nick`, - guildChannels: (guildID) => `${Endpoints.guild(guildID)}/channels`, - guildEmojis: (guildID) => `${Endpoints.guild(guildID)}/emojis`, - - // channels - channels: `${API}/channels`, - channel: (channelID) => `${Endpoints.channels}/${channelID}`, - channelMessages: (channelID) => `${Endpoints.channel(channelID)}/messages`, - channelInvites: (channelID) => `${Endpoints.channel(channelID)}/invites`, - channelTyping: (channelID) => `${Endpoints.channel(channelID)}/typing`, - channelPermissions: (channelID) => `${Endpoints.channel(channelID)}/permissions`, - channelMessage: (channelID, messageID) => `${Endpoints.channelMessages(channelID)}/${messageID}`, - channelWebhooks: (channelID) => `${Endpoints.channel(channelID)}/webhooks`, - - // message reactions - messageReactions: (channelID, messageID) => `${Endpoints.channelMessage(channelID, messageID)}/reactions`, - messageReaction: - (channel, msg, emoji, limit) => - `${Endpoints.messageReactions(channel, msg)}/${emoji}` + - `${limit ? `?limit=${limit}` : ''}`, - selfMessageReaction: (channel, msg, emoji, limit) => - `${Endpoints.messageReaction(channel, msg, emoji, limit)}/@me`, - userMessageReaction: (channel, msg, emoji, limit, id) => - `${Endpoints.messageReaction(channel, msg, emoji, limit)}/${id}`, - - // webhooks - webhook: (webhookID, token) => `${API}/webhooks/${webhookID}${token ? `/${token}` : ''}`, - - // oauth - myApplication: `${API}/oauth2/applications/@me`, - getApp: (id) => `${API}/oauth2/authorize?client_id=${id}`, - - // emoji - emoji: (emojiID) => `${Endpoints.CDN}/emojis/${emojiID}.png`, -}; - -exports.Status = { - READY: 0, - CONNECTING: 1, - RECONNECTING: 2, - IDLE: 3, - NEARLY: 4, - DISCONNECTED: 5, -}; - -exports.ChannelTypes = { - text: 0, - DM: 1, - voice: 2, - groupDM: 3, -}; - -exports.OPCodes = { - DISPATCH: 0, - HEARTBEAT: 1, - IDENTIFY: 2, - STATUS_UPDATE: 3, - VOICE_STATE_UPDATE: 4, - VOICE_GUILD_PING: 5, - RESUME: 6, - RECONNECT: 7, - REQUEST_GUILD_MEMBERS: 8, - INVALID_SESSION: 9, - HELLO: 10, - HEARTBEAT_ACK: 11, -}; - -exports.VoiceOPCodes = { - IDENTIFY: 0, - SELECT_PROTOCOL: 1, - READY: 2, - HEARTBEAT: 3, - SESSION_DESCRIPTION: 4, - SPEAKING: 5, -}; - -exports.Events = { - READY: 'ready', - GUILD_CREATE: 'guildCreate', - GUILD_DELETE: 'guildDelete', - GUILD_UPDATE: 'guildUpdate', - GUILD_UNAVAILABLE: 'guildUnavailable', - GUILD_AVAILABLE: 'guildAvailable', - GUILD_MEMBER_ADD: 'guildMemberAdd', - GUILD_MEMBER_REMOVE: 'guildMemberRemove', - GUILD_MEMBER_UPDATE: 'guildMemberUpdate', - GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable', - GUILD_MEMBER_SPEAKING: 'guildMemberSpeaking', - GUILD_MEMBERS_CHUNK: 'guildMembersChunk', - GUILD_ROLE_CREATE: 'roleCreate', - GUILD_ROLE_DELETE: 'roleDelete', - GUILD_ROLE_UPDATE: 'roleUpdate', - GUILD_EMOJI_CREATE: 'emojiCreate', - GUILD_EMOJI_DELETE: 'emojiDelete', - GUILD_EMOJI_UPDATE: 'emojiUpdate', - GUILD_BAN_ADD: 'guildBanAdd', - GUILD_BAN_REMOVE: 'guildBanRemove', - CHANNEL_CREATE: 'channelCreate', - CHANNEL_DELETE: 'channelDelete', - CHANNEL_UPDATE: 'channelUpdate', - CHANNEL_PINS_UPDATE: 'channelPinsUpdate', - MESSAGE_CREATE: 'message', - MESSAGE_DELETE: 'messageDelete', - MESSAGE_UPDATE: 'messageUpdate', - MESSAGE_BULK_DELETE: 'messageDeleteBulk', - MESSAGE_REACTION_ADD: 'messageReactionAdd', - MESSAGE_REACTION_REMOVE: 'messageReactionRemove', - MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll', - USER_UPDATE: 'userUpdate', - USER_NOTE_UPDATE: 'userNoteUpdate', - PRESENCE_UPDATE: 'presenceUpdate', - VOICE_STATE_UPDATE: 'voiceStateUpdate', - TYPING_START: 'typingStart', - TYPING_STOP: 'typingStop', - DISCONNECT: 'disconnect', - RECONNECTING: 'reconnecting', - ERROR: 'error', - WARN: 'warn', - DEBUG: 'debug', -}; - -/** - * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events: - * - READY - * - GUILD_SYNC - * - GUILD_CREATE - * - GUILD_DELETE - * - GUILD_UPDATE - * - GUILD_MEMBER_ADD - * - GUILD_MEMBER_REMOVE - * - GUILD_MEMBER_UPDATE - * - GUILD_MEMBERS_CHUNK - * - GUILD_ROLE_CREATE - * - GUILD_ROLE_DELETE - * - GUILD_ROLE_UPDATE - * - GUILD_BAN_ADD - * - GUILD_BAN_REMOVE - * - CHANNEL_CREATE - * - CHANNEL_DELETE - * - CHANNEL_UPDATE - * - CHANNEL_PINS_UPDATE - * - MESSAGE_CREATE - * - MESSAGE_DELETE - * - MESSAGE_UPDATE - * - MESSAGE_DELETE_BULK - * - MESSAGE_REACTION_ADD - * - MESSAGE_REACTION_REMOVE - * - MESSAGE_REACTION_REMOVE_ALL - * - USER_UPDATE - * - USER_NOTE_UPDATE - * - PRESENCE_UPDATE - * - VOICE_STATE_UPDATE - * - TYPING_START - * - VOICE_SERVER_UPDATE - * - RELATIONSHIP_ADD - * - RELATIONSHIP_REMOVE - * @typedef {string} WSEventType - */ -exports.WSEvents = { - READY: 'READY', - GUILD_SYNC: 'GUILD_SYNC', - GUILD_CREATE: 'GUILD_CREATE', - GUILD_DELETE: 'GUILD_DELETE', - GUILD_UPDATE: 'GUILD_UPDATE', - GUILD_MEMBER_ADD: 'GUILD_MEMBER_ADD', - GUILD_MEMBER_REMOVE: 'GUILD_MEMBER_REMOVE', - GUILD_MEMBER_UPDATE: 'GUILD_MEMBER_UPDATE', - GUILD_MEMBERS_CHUNK: 'GUILD_MEMBERS_CHUNK', - GUILD_ROLE_CREATE: 'GUILD_ROLE_CREATE', - GUILD_ROLE_DELETE: 'GUILD_ROLE_DELETE', - GUILD_ROLE_UPDATE: 'GUILD_ROLE_UPDATE', - GUILD_BAN_ADD: 'GUILD_BAN_ADD', - GUILD_BAN_REMOVE: 'GUILD_BAN_REMOVE', - GUILD_EMOJIS_UPDATE: 'GUILD_EMOJIS_UPDATE', - CHANNEL_CREATE: 'CHANNEL_CREATE', - CHANNEL_DELETE: 'CHANNEL_DELETE', - CHANNEL_UPDATE: 'CHANNEL_UPDATE', - CHANNEL_PINS_UPDATE: 'CHANNEL_PINS_UPDATE', - MESSAGE_CREATE: 'MESSAGE_CREATE', - MESSAGE_DELETE: 'MESSAGE_DELETE', - MESSAGE_UPDATE: 'MESSAGE_UPDATE', - MESSAGE_DELETE_BULK: 'MESSAGE_DELETE_BULK', - MESSAGE_REACTION_ADD: 'MESSAGE_REACTION_ADD', - MESSAGE_REACTION_REMOVE: 'MESSAGE_REACTION_REMOVE', - MESSAGE_REACTION_REMOVE_ALL: 'MESSAGE_REACTION_REMOVE_ALL', - USER_UPDATE: 'USER_UPDATE', - USER_NOTE_UPDATE: 'USER_NOTE_UPDATE', - PRESENCE_UPDATE: 'PRESENCE_UPDATE', - VOICE_STATE_UPDATE: 'VOICE_STATE_UPDATE', - TYPING_START: 'TYPING_START', - VOICE_SERVER_UPDATE: 'VOICE_SERVER_UPDATE', - RELATIONSHIP_ADD: 'RELATIONSHIP_ADD', - RELATIONSHIP_REMOVE: 'RELATIONSHIP_REMOVE', -}; - -exports.MessageTypes = { - 0: 'DEFAULT', - 1: 'RECIPIENT_ADD', - 2: 'RECIPIENT_REMOVE', - 3: 'CALL', - 4: 'CHANNEL_NAME_CHANGE', - 5: 'CHANNEL_ICON_CHANGE', - 6: 'PINS_ADD', -}; - -exports.DefaultAvatars = { - BLURPLE: '6debd47ed13483642cf09e832ed0bc1b', - GREY: '322c936a8c8be1b803cd94861bdfa868', - GREEN: 'dd4dbc0016779df1378e7812eabaa04d', - ORANGE: '0e291f67c9274a1abdddeb3fd919cbaa', - RED: '1cbd08c76f8af6dddce02c5138971129', -}; - -const PermissionFlags = exports.PermissionFlags = { - CREATE_INSTANT_INVITE: 1 << 0, - KICK_MEMBERS: 1 << 1, - BAN_MEMBERS: 1 << 2, - ADMINISTRATOR: 1 << 3, - MANAGE_CHANNELS: 1 << 4, - MANAGE_GUILD: 1 << 5, - ADD_REACTIONS: 1 << 6, - - READ_MESSAGES: 1 << 10, - SEND_MESSAGES: 1 << 11, - SEND_TTS_MESSAGES: 1 << 12, - MANAGE_MESSAGES: 1 << 13, - EMBED_LINKS: 1 << 14, - ATTACH_FILES: 1 << 15, - READ_MESSAGE_HISTORY: 1 << 16, - MENTION_EVERYONE: 1 << 17, - EXTERNAL_EMOJIS: 1 << 18, - - CONNECT: 1 << 20, - SPEAK: 1 << 21, - MUTE_MEMBERS: 1 << 22, - DEAFEN_MEMBERS: 1 << 23, - MOVE_MEMBERS: 1 << 24, - USE_VAD: 1 << 25, - - CHANGE_NICKNAME: 1 << 26, - MANAGE_NICKNAMES: 1 << 27, - MANAGE_ROLES_OR_PERMISSIONS: 1 << 28, - MANAGE_WEBHOOKS: 1 << 29, - MANAGE_EMOJIS: 1 << 30, -}; - -let _ALL_PERMISSIONS = 0; -for (const key in PermissionFlags) _ALL_PERMISSIONS |= PermissionFlags[key]; -exports.ALL_PERMISSIONS = _ALL_PERMISSIONS; -exports.DEFAULT_PERMISSIONS = 104324097; diff --git a/node_modules/discord.js/src/util/ConvertArrayBuffer.js b/node_modules/discord.js/src/util/ConvertArrayBuffer.js deleted file mode 100644 index 26b1cc8..0000000 --- a/node_modules/discord.js/src/util/ConvertArrayBuffer.js +++ /dev/null @@ -1,18 +0,0 @@ -function arrayBufferToBuffer(ab) { - const buffer = new Buffer(ab.byteLength); - const view = new Uint8Array(ab); - for (var i = 0; i < buffer.length; ++i) buffer[i] = view[i]; - return buffer; -} - -function str2ab(str) { - const buffer = new ArrayBuffer(str.length * 2); - const view = new Uint16Array(buffer); - for (var i = 0, strLen = str.length; i < strLen; i++) view[i] = str.charCodeAt(i); - return buffer; -} - -module.exports = function convertArrayBuffer(x) { - if (typeof x === 'string') x = str2ab(x); - return arrayBufferToBuffer(x); -}; diff --git a/node_modules/discord.js/src/util/EscapeMarkdown.js b/node_modules/discord.js/src/util/EscapeMarkdown.js deleted file mode 100644 index 9db8c13..0000000 --- a/node_modules/discord.js/src/util/EscapeMarkdown.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = function escapeMarkdown(text, onlyCodeBlock = false, onlyInlineCode = false) { - if (onlyCodeBlock) return text.replace(/```/g, '`\u200b``'); - if (onlyInlineCode) return text.replace(/\\(`|\\)/g, '$1').replace(/(`|\\)/g, '\\$1'); - return text.replace(/\\(\*|_|`|~|\\)/g, '$1').replace(/(\*|_|`|~|\\)/g, '\\$1'); -}; diff --git a/node_modules/discord.js/src/util/FetchRecommendedShards.js b/node_modules/discord.js/src/util/FetchRecommendedShards.js deleted file mode 100644 index a60f510..0000000 --- a/node_modules/discord.js/src/util/FetchRecommendedShards.js +++ /dev/null @@ -1,19 +0,0 @@ -const superagent = require('superagent'); -const botGateway = require('./Constants').Endpoints.botGateway; - -/** - * Gets the recommended shard count from Discord - * @param {number} token Discord auth token - * @returns {Promise<number>} the recommended number of shards - */ -module.exports = function fetchRecommendedShards(token) { - return new Promise((resolve, reject) => { - if (!token) throw new Error('A token must be provided.'); - superagent.get(botGateway) - .set('Authorization', `Bot ${token.replace(/^Bot\s*/i, '')}`) - .end((err, res) => { - if (err) reject(err); - resolve(res.body.shards); - }); - }); -}; diff --git a/node_modules/discord.js/src/util/MakeError.js b/node_modules/discord.js/src/util/MakeError.js deleted file mode 100644 index bbc84db..0000000 --- a/node_modules/discord.js/src/util/MakeError.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = function makeError(obj) { - const err = new Error(obj.message); - err.name = obj.name; - err.stack = obj.stack; - return err; -}; diff --git a/node_modules/discord.js/src/util/MakePlainError.js b/node_modules/discord.js/src/util/MakePlainError.js deleted file mode 100644 index b409462..0000000 --- a/node_modules/discord.js/src/util/MakePlainError.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = function makePlainError(err) { - const obj = {}; - obj.name = err.name; - obj.message = err.message; - obj.stack = err.stack; - return obj; -}; diff --git a/node_modules/discord.js/src/util/MergeDefault.js b/node_modules/discord.js/src/util/MergeDefault.js deleted file mode 100644 index b09f970..0000000 --- a/node_modules/discord.js/src/util/MergeDefault.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = function merge(def, given) { - if (!given) return def; - for (const key in def) { - if (!{}.hasOwnProperty.call(given, key)) { - given[key] = def[key]; - } else if (given[key] === Object(given[key])) { - given[key] = merge(def[key], given[key]); - } - } - - return given; -}; diff --git a/node_modules/discord.js/src/util/ParseEmoji.js b/node_modules/discord.js/src/util/ParseEmoji.js deleted file mode 100644 index d9f7b22..0000000 --- a/node_modules/discord.js/src/util/ParseEmoji.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = function parseEmoji(text) { - if (text.includes('%')) { - text = decodeURIComponent(text); - } - if (text.includes(':')) { - const [name, id] = text.split(':'); - return { name, id }; - } else { - return { - name: text, - id: null, - }; - } -}; diff --git a/node_modules/discord.js/src/util/SplitMessage.js b/node_modules/discord.js/src/util/SplitMessage.js deleted file mode 100644 index 3833f00..0000000 --- a/node_modules/discord.js/src/util/SplitMessage.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = function splitMessage(text, { maxLength = 1950, char = '\n', prepend = '', append = '' } = {}) { - if (text.length <= maxLength) return text; - const splitText = text.split(char); - if (splitText.length === 1) throw new Error('Message exceeds the max length and contains no split characters.'); - const messages = ['']; - let msg = 0; - for (let i = 0; i < splitText.length; i++) { - if (messages[msg].length + splitText[i].length + 1 > maxLength) { - messages[msg] += append; - messages.push(prepend); - msg++; - } - messages[msg] += (messages[msg].length > 0 && messages[msg] !== prepend ? char : '') + splitText[i]; - } - return messages; -}; |
