diff options
| author | 8cy <[email protected]> | 2020-04-03 02:48:28 -0700 |
|---|---|---|
| committer | 8cy <[email protected]> | 2020-04-03 02:48:28 -0700 |
| commit | f9159ea2d994e14180fb02ab562f0119513e67cf (patch) | |
| tree | 09d14cdf05456567156738b681379d4bccd64e5c /node_modules/discord.js/src | |
| parent | 2020/04/03, 02:42, V1.2.1 (diff) | |
| download | s5nical-f9159ea2d994e14180fb02ab562f0119513e67cf.tar.xz s5nical-f9159ea2d994e14180fb02ab562f0119513e67cf.zip | |
2020/04/03, 02:47, V1.2.2
Diffstat (limited to 'node_modules/discord.js/src')
168 files changed, 0 insertions, 21382 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 9ad7c95..0000000 --- a/node_modules/discord.js/src/client/Client.js +++ /dev/null @@ -1,564 +0,0 @@ -const EventEmitter = require('events'); -const Constants = require('../util/Constants'); -const Permissions = require('../util/Permissions'); -const Util = require('../util/Util'); -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'); -const VoiceBroadcast = require('./voice/VoiceBroadcast'); - -/** - * The main hub for interacting with the Discord API, and the starting point for any 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 = Util.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 {@link ShardingManager}) - * @type {?ShardClientUtil} - */ - this.shard = process.send ? ShardClientUtil.singleton(this) : null; - - /** - * All of the {@link User} objects that have been cached at any point, mapped by their IDs - * @type {Collection<Snowflake, User>} - */ - this.users = new Collection(); - - /** - * All of the guilds the client is currently handling, mapped by their IDs - - * as long as sharding isn't being used, this will be *every* guild the bot is a member of - * @type {Collection<Snowflake, Guild>} - */ - this.guilds = new Collection(); - - /** - * All of the {@link Channel}s that the client is currently handling, mapped by their IDs - - * as long as sharding isn't being used, this will be *every* channel in *every* guild, and all DM channels - * @type {Collection<Snowflake, Channel>} - */ - this.channels = new Collection(); - - /** - * Presences that have been received for the client user's friends, mapped by user IDs - * <warn>This is only filled when using a user account.</warn> - * @type {Collection<Snowflake, Presence>} - * @deprecated - */ - this.presences = new Collection(); - - Object.defineProperty(this, 'token', { writable: true }); - if (!this.token && 'CLIENT_TOKEN' in process.env) { - /** - * Authorization token for the logged in user/bot - * <warn>This should be kept private at all times.</warn> - * @type {?string} - */ - this.token = process.env.CLIENT_TOKEN; - } else { - this.token = null; - } - - /** - * User that the client is logged in as - * @type {?ClientUser} - */ - this.user = null; - - /** - * Time at which the client was last regarded as being in the `READY` state - * (each time the client disconnects and successfully reconnects, this will be overwritten) - * @type {?Date} - */ - this.readyAt = null; - - /** - * Active voice broadcasts that have been created - * @type {VoiceBroadcast[]} - */ - this.broadcasts = []; - - /** - * Previous heartbeat pings of the websocket (most recent first, limited to three elements) - * @type {number[]} - */ - this.pings = []; - - /** - * Timeouts set by {@link Client#setTimeout} that are still active - * @type {Set<Timeout>} - * @private - */ - this._timeouts = new Set(); - - /** - * Intervals set by {@link Client#setInterval} that are still active - * @type {Set<Timeout>} - * @private - */ - this._intervals = new Set(); - - if (this.options.messageSweepInterval > 0) { - this.setInterval(this.sweepMessages.bind(this), this.options.messageSweepInterval * 1000); - } - } - - /** - * Timestamp of the latest ping's start time - * @type {number} - * @private - */ - get _pingTimestamp() { - return this.ws.connection ? this.ws.connection.lastPingTimestamp : 0; - } - - /** - * Current status of the client's connection to Discord - * @type {Status} - * @readonly - */ - get status() { - return this.ws.connection ? this.ws.connection.status : Constants.Status.IDLE; - } - - /** - * How long it has been since the client last entered the `READY` state in milliseconds - * @type {?number} - * @readonly - */ - get uptime() { - return this.readyAt ? Date.now() - this.readyAt : null; - } - - /** - * Average heartbeat ping of the websocket, obtained by averaging the {@link Client#pings} property - * @type {number} - * @readonly - */ - get ping() { - return this.pings.reduce((prev, p) => prev + p, 0) / this.pings.length; - } - - /** - * All active voice connections that have been established, mapped by guild ID - * @type {Collection<Snowflake, VoiceConnection>} - * @readonly - */ - get voiceConnections() { - if (this.browser) return new Collection(); - return this.voice.connections; - } - - /** - * All custom emojis that the client has access to, mapped by their IDs - * @type {Collection<Snowflake, 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; - } - - /** - * Timestamp of the time 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'; - } - - /** - * Creates a voice broadcast. - * @returns {VoiceBroadcast} - */ - createVoiceBroadcast() { - const broadcast = new VoiceBroadcast(this); - this.broadcasts.push(broadcast); - return broadcast; - } - - /** - * Logs the client in, establishing a websocket connection to Discord. - * <info>Both bot and regular user accounts are supported, but it is highly recommended to use a bot account whenever - * possible. User accounts are subject to harsher ratelimits and other restrictions that don't apply to bot accounts. - * Bot accounts also have access to many features that user accounts cannot utilise. Automating a user account is - * considered a violation of Discord's ToS.</info> - * @param {string} token Token of the account to log in with - * @returns {Promise<string>} Token of the account used - * @example - * client.login('my token') - * .then(console.log) - * .catch(console.error); - */ - login(token = this.token) { - return this.rest.methods.login(token); - } - - /** - * Logs out, terminates the connection to Discord, and destroys the client. - * @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(); - } - - /** - * Requests a sync of guild data with Discord. - * <info>This can be done automatically every 30 seconds by enabling {@link ClientOptions#sync}.</info> - * <warn>This is only available when using a user account.</warn> - * @param {Guild[]|Collection<Snowflake, Guild>} [guilds=this.guilds] An array or collection of guilds to sync - * @deprecated - */ - 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), - }); - } - - /** - * Obtains a user from Discord, or the user cache if it's already available. - * <warn>This is only available when using a bot account.</warn> - * @param {Snowflake} id ID of the user - * @param {boolean} [cache=true] Whether to cache the new user object if it isn't already - * @returns {Promise<User>} - */ - fetchUser(id, cache = true) { - if (this.users.has(id)) return Promise.resolve(this.users.get(id)); - return this.rest.methods.getUser(id, cache); - } - - /** - * Obtains an invite from Discord. - * @param {InviteResolvable} invite Invite code or URL - * @returns {Promise<Invite>} - * @example - * client.fetchInvite('https://discord.gg/bRCvFy9') - * .then(invite => console.log(`Obtained invite with code: ${invite.code}`)) - * .catch(console.error); - */ - fetchInvite(invite) { - const code = this.resolver.resolveInviteCode(invite); - return this.rest.methods.getInvite(code); - } - - /** - * Obtains a webhook from Discord. - * @param {Snowflake} id ID of the webhook - * @param {string} [token] Token for the webhook - * @returns {Promise<Webhook>} - * @example - * client.fetchWebhook('id', 'token') - * .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`)) - * .catch(console.error); - */ - fetchWebhook(id, token) { - return this.rest.methods.getWebhook(id, token); - } - - /** - * Obtains the available voice regions from Discord. - * @returns {Promise<Collection<string, VoiceRegion>>} - * @example - * client.fetchVoiceRegions() - * .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`)) - * .catch(console.error); - */ - fetchVoiceRegions() { - return this.rest.methods.fetchVoiceRegions(); - } - - /** - * Sweeps all text-based 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 {@link ClientOptions#messageCacheLifetime} - * @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++; - - messages += channel.messages.sweep( - message => now - (message.editedTimestamp || message.createdTimestamp) > lifetimeMs - ); - } - - this.emit('debug', `Swept ${messages} messages older than ${lifetime} seconds in ${channels} text-based channels`); - return messages; - } - - /** - * Obtains the OAuth Application of the bot from Discord. - * <warn>Bots can only fetch their own profile.</warn> - * @param {Snowflake} [id='@me'] ID of application to fetch - * @returns {Promise<OAuth2Application>} - * @example - * client.fetchApplication() - * .then(application => console.log(`Obtained application with name: ${application.name}`)) - * .catch(console.error); - */ - fetchApplication(id = '@me') { - if (id !== '@me') process.emitWarning('fetchApplication: use "@me" as an argument', 'DeprecationWarning'); - return this.rest.methods.getApplication(id); - } - - /** - * Generates a link that can be used to invite the bot to a guild. - * <warn>This is only available when using a bot account.</warn> - * @param {PermissionResolvable} [permissions] Permissions to request - * @returns {Promise<string>} - * @example - * client.generateInvite(['SEND_MESSAGES', 'MANAGE_GUILD', 'MENTION_EVERYONE']) - * .then(link => console.log(`Generated bot invite link: ${link}`)) - * .catch(console.error); - */ - generateInvite(permissions) { - permissions = Permissions.resolve(permissions); - 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(...args); - this._timeouts.delete(timeout); - }, delay); - 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); - } - - /** - * Adds a ping to {@link Client#pings}. - * @param {number} startTime Starting time of the ping - * @private - */ - _pong(startTime) { - this.pings.unshift(Date.now() - startTime); - if (this.pings.length > 3) this.pings.length = 3; - this.ws.lastHeartbeatAck = true; - } - - /** - * Adds/updates a friend's presence in {@link Client#presences}. - * @param {Snowflake} id ID of the user - * @param {Object} presence Raw presence object from Discord - * @private - */ - _setPresence(id, presence) { - if (this.presences.has(id)) { - this.presences.get(id).update(presence); - return; - } - this.presences.set(id, new Presence(presence, this)); - } - - /** - * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script - * with the client as `this`. - * @param {string} script Script to eval - * @returns {*} - * @private - */ - _eval(script) { - return eval(script); - } - - /** - * Validates the client options. - * @param {ClientOptions} [options=this.options] Options to validate - * @private - */ - _validateOptions(options = this.options) { // eslint-disable-line complexity - 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.'); - if (typeof options.retryLimit !== 'number' || isNaN(options.retryLimit)) { - throw new TypeError('The retryLimit options must be a number.'); - } - } -} - -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 4f0f2d7..0000000 --- a/node_modules/discord.js/src/client/ClientDataManager.js +++ /dev/null @@ -1,149 +0,0 @@ -const Constants = require('../util/Constants'); -const Util = require('../util/Util'); -const Guild = require('../structures/Guild'); -const User = require('../structures/User'); -const Emoji = require('../structures/Emoji'); -const GuildChannel = require('../structures/GuildChannel'); -const TextChannel = require('../structures/TextChannel'); -const VoiceChannel = require('../structures/VoiceChannel'); -const CategoryChannel = require('../structures/CategoryChannel'); -const NewsChannel = require('../structures/NewsChannel'); -const StoreChannel = require('../structures/StoreChannel'); -const DMChannel = require('../structures/DMChannel'); -const GroupDMChannel = require('../structures/GroupDMChannel'); - -class ClientDataManager { - constructor(client) { - this.client = client; - } - - get pastReady() { - return this.client.ws.connection.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, cache = true) { - if (this.client.users.has(data.id)) return this.client.users.get(data.id); - const user = new User(this.client, data); - if (cache) 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.GROUP_DM) { - channel = new GroupDMChannel(this.client, data); - } else { - guild = guild || this.client.guilds.get(data.guild_id); - if (already) { - channel = this.client.channels.get(data.id); - } else if (guild) { - switch (data.type) { - case Constants.ChannelTypes.TEXT: - channel = new TextChannel(guild, data); - break; - case Constants.ChannelTypes.VOICE: - channel = new VoiceChannel(guild, data); - break; - case Constants.ChannelTypes.CATEGORY: - channel = new CategoryChannel(guild, data); - break; - case Constants.ChannelTypes.NEWS: - channel = new NewsChannel(guild, data); - break; - case Constants.ChannelTypes.STORE: - channel = new StoreChannel(guild, data); - break; - } - - guild.channels.set(channel.id, channel); - } - } - - if (channel && !already) { - if (this.pastReady) this.client.emit(Constants.Events.CHANNEL_CREATE, channel); - this.client.channels.set(channel.id, channel); - return channel; - } else if (already) { - 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 = Util.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 = Util.cloneObject(currentEmoji); - currentEmoji.setup(newData); - this.client.emit(Constants.Events.GUILD_EMOJI_UPDATE, oldEmoji, currentEmoji); - return 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 50a7bb9..0000000 --- a/node_modules/discord.js/src/client/ClientDataResolver.js +++ /dev/null @@ -1,376 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const snekfetch = require('snekfetch'); - -const Constants = require('../util/Constants'); -const convertToBuffer = require('../util/Util').convertToBuffer; -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'); -const Role = require('../structures/Role'); - -/** - * 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 Snowflake - * * A Message object (resolves to the message author) - * * A Guild object (owner of the guild) - * * A GuildMember object - * @typedef {User|Snowflake|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 this.resolveUser(user.ownerID); - return null; - } - - /** - * Resolves a UserResolvable to a user ID string. - * @param {UserResolvable} user The UserResolvable to identify - * @returns {?Snowflake} - */ - 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 Snowflake - * @typedef {Guild|Snowflake} 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 {GuildMember|User} 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 a Role object. This can be: - * * A Role - * * A Snowflake - * @typedef {Role|Snowflake} RoleResolvable - */ - - /** - * Resolves a RoleResolvable to a Role object. - * @param {GuildResolvable} guild The guild that this role is part of - * @param {RoleResolvable} role The role resolvable to resolve - * @returns {?Role} - */ - resolveRole(guild, role) { - if (role instanceof Role) return role; - guild = this.resolveGuild(guild); - if (!guild) return null; - if (typeof role === 'string') return guild.roles.get(role); - return null; - } - - /** - * Data that can be resolved to give a Channel object. This can be: - * * A Channel object - * * A Message object (the channel the message was sent in) - * * A Guild object (the #general channel) - * * A Snowflake - * @typedef {Channel|Guild|Message|Snowflake} 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 (typeof channel === 'string') return this.client.channels.get(channel) || null; - if (channel instanceof Message) return channel.channel; - if (channel instanceof Guild) return channel.channels.get(channel.id) || null; - return null; - } - - /** - * Resolves a ChannelResolvable to a channel ID. - * @param {ChannelResolvable} channel The channel resolvable to resolve - * @returns {?Snowflake} - */ - resolveChannelID(channel) { - if (channel instanceof Channel) return channel.id; - if (typeof channel === 'string') return channel; - if (channel instanceof Message) return channel.channel.id; - if (channel instanceof Guild) return channel.defaultChannel.id; - 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\.com\/invite|\.gg(?:\/invite)?)\/([\w-]{2,255})/i; - const match = inviteRegex.exec(data); - if (match && match[1]) return match[1]; - return data; - } - - /** - * 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); - } - - - /** - * Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image. - * @param {BufferResolvable|Base64Resolvable} image The image to be resolved - * @returns {Promise<?string>} - */ - resolveImage(image) { - if (!image) return Promise.resolve(null); - if (typeof image === 'string' && image.startsWith('data:')) { - return Promise.resolve(image); - } - return this.resolveFile(image).then(this.resolveBase64); - } - - /** - * 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 - * * A Stream - * @typedef {string|Buffer} BufferResolvable - */ - - /** - * @external Stream - * @see {@link https://nodejs.org/api/stream.html} - */ - - /** - * Resolves a BufferResolvable to a Buffer. - * @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve - * @returns {Promise<Buffer>} - */ - resolveFile(resource) { - if (resource instanceof Buffer) return Promise.resolve(resource); - if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertToBuffer(resource)); - - if (typeof resource === 'string') { - if (/^https?:\/\//.test(resource)) { - return snekfetch.get(resource).then(res => res.body instanceof Buffer ? res.body : Buffer.from(res.text)); - } - return new Promise((resolve, reject) => { - const file = path.resolve(resource); - fs.stat(file, (err, stats) => { - if (err) return reject(err); - if (!stats || !stats.isFile()) return reject(new Error(`The file could not be found: ${file}`)); - fs.readFile(file, (err2, data) => { - if (err2) reject(err2); - else resolve(data); - }); - return null; - }); - }); - } else if (resource && resource.pipe && typeof resource.pipe === 'function') { - return new Promise((resolve, reject) => { - const buffers = []; - resource.once('error', reject); - resource.on('data', data => buffers.push(data)); - resource.once('end', () => resolve(Buffer.concat(buffers))); - }); - } - - 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: - * * The unicode representation of an emoji - * * A custom emoji ID - * * An Emoji object - * * A ReactionEmoji object - * @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 (this.client.emojis.has(emoji)) return this.client.emojis.get(emoji).identifier; - else if (!emoji.includes('%')) return encodeURIComponent(emoji); - else return emoji; - } - return null; - } - - /** - * Can be a Hex Literal, Hex String, Number, RGB Array, or one of the following - * ``` - * [ - * 'DEFAULT', - * 'WHITE', - * 'AQUA', - * 'GREEN', - * 'BLUE', - * 'PURPLE', - * 'LUMINOUS_VIVID_PINK', - * 'GOLD', - * 'ORANGE', - * 'RED', - * 'GREY', - * 'DARKER_GREY', - * 'NAVY', - * 'DARK_AQUA', - * 'DARK_GREEN', - * 'DARK_BLUE', - * 'DARK_PURPLE', - * 'DARK_VIVID_PINK', - * 'DARK_GOLD', - * 'DARK_ORANGE', - * 'DARK_RED', - * 'DARK_GREY', - * 'LIGHT_GREY', - * 'DARK_NAVY', - * 'RANDOM', - * ] - * ``` - * or something like - * ``` - * [255, 0, 255] - * ``` - * for purple - * @typedef {string|number|Array} ColorResolvable - */ - - /** - * Resolves a ColorResolvable into a color number. - * @param {ColorResolvable} color Color to resolve - * @returns {number} A color - */ - static resolveColor(color) { - if (typeof color === 'string') { - if (color === 'RANDOM') return Math.floor(Math.random() * (0xFFFFFF + 1)); - if (color === 'DEFAULT') return 0; - color = Constants.Colors[color] || parseInt(color.replace('#', ''), 16); - } else if (color instanceof Array) { - color = (color[0] << 16) + (color[1] << 8) + color[2]; - } - - if (color < 0 || color > 0xFFFFFF) { - throw new RangeError('Color must be within the range 0 - 16777215 (0xFFFFFF).'); - } else if (color && isNaN(color)) { - throw new TypeError('Unable to convert color to a number.'); - } - - return color; - } - - /** - * @param {ColorResolvable} color Color to resolve - * @returns {number} A color - */ - resolveColor(color) { - return this.constructor.resolveColor(color); - } -} - -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 0f2480c..0000000 --- a/node_modules/discord.js/src/client/ClientManager.js +++ /dev/null @@ -1,74 +0,0 @@ -const Constants = require('../util/Constants'); -const WebSocketConnection = require('./websocket/WebSocketConnection'); - -/** - * 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 - * @type {?number} - */ - this.heartbeatInterval = null; - } - - /** - * The status of the client - * @type {number} - */ - get status() { - return this.connection ? this.connection.status : Constants.Status.IDLE; - } - - /** - * 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(res => { - const protocolVersion = Constants.DefaultOptions.ws.version; - const gateway = `${res.url}/?v=${protocolVersion}&encoding=${WebSocketConnection.ENCODING}`; - this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`); - this.client.ws.connect(gateway); - this.client.ws.connection.once('error', reject); - this.client.ws.connection.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)); - if (event.code === 4011) reject(new Error(Constants.Errors.SHARDING_REQUIRED)); - }); - this.client.once(Constants.Events.READY, () => { - resolve(token); - this.client.clearTimeout(timeout); - }); - }, reject); - } - - destroy() { - this.client.ws.destroy(); - this.client.rest.destroy(); - if (!this.client.user) return Promise.resolve(); - 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 99291b5..0000000 --- a/node_modules/discord.js/src/client/WebhookClient.js +++ /dev/null @@ -1,118 +0,0 @@ -const Webhook = require('../structures/Webhook'); -const RESTManager = require('./rest/RESTManager'); -const ClientDataResolver = require('./ClientDataResolver'); -const Constants = require('../util/Constants'); -const Util = require('../util/Util'); - -/** - * The webhook client. - * @extends {Webhook} - */ -class WebhookClient extends Webhook { - /** - * @param {Snowflake} id ID of the webhook - * @param {string} token Token of the webhook - * @param {ClientOptions} [options] Options for the client - * @example - * // Create a new webhook and send a message - * const 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 = Util.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); - - /** - * Timeouts set by {@link WebhookClient#setTimeout} that are still active - * @type {Set<Timeout>} - * @private - */ - this._timeouts = new Set(); - - /** - * Intervals set by {@link WebhookClient#setInterval} that are still active - * @type {Set<Timeout>} - * @private - */ - this._intervals = new Set(); - } - - /** - * 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(...args); - this._timeouts.delete(timeout); - }, delay); - 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); - } - - - /** - * Destroys the client. - */ - destroy() { - for (const t of this._timeouts) clearTimeout(t); - for (const i of this._intervals) clearInterval(i); - this._timeouts.clear(); - this._intervals.clear(); - } -} - -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 f9739cc..0000000 --- a/node_modules/discord.js/src/client/actions/ActionsManager.js +++ /dev/null @@ -1,43 +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('./MessageReactionRemoveEmoji')); - 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('./InviteCreate')); - this.register(require('./InviteDelete')); - 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('./GuildEmojisUpdate')); - this.register(require('./GuildRolesPositionUpdate')); - this.register(require('./GuildChannelsPositionUpdate')); - } - - 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 83b1aa0..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelCreate.js +++ /dev/null @@ -1,11 +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 6def629..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelDelete.js +++ /dev/null @@ -1,38 +0,0 @@ -const Action = require('./Action'); -const DMChannel = require('../../structures/DMChannel'); - -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; - } - if (channel) { - if (channel.messages && !(channel instanceof DMChannel)) { - for (const message of channel.messages.values()) { - message.deleted = true; - } - } - channel.deleted = true; - } - - 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 ba1c4ef..0000000 --- a/node_modules/discord.js/src/client/actions/ChannelUpdate.js +++ /dev/null @@ -1,74 +0,0 @@ -const Action = require('./Action'); -const TextChannel = require('../../structures/TextChannel'); -const VoiceChannel = require('../../structures/VoiceChannel'); -const CategoryChannel = require('../../structures/CategoryChannel'); -const NewsChannel = require('../../structures/NewsChannel'); -const StoreChannel = require('../../structures/StoreChannel'); -const Constants = require('../../util/Constants'); -const ChannelTypes = Constants.ChannelTypes; -const Util = require('../../util/Util'); - -class ChannelUpdateAction extends Action { - handle(data) { - const client = this.client; - - let channel = client.channels.get(data.id); - if (channel) { - const oldChannel = Util.cloneObject(channel); - - // If the channel is changing types, we need to follow a different process - if (ChannelTypes[channel.type.toUpperCase()] !== data.type) { - // Determine which channel class we're changing to - let channelClass; - switch (data.type) { - case ChannelTypes.TEXT: - channelClass = TextChannel; - break; - case ChannelTypes.VOICE: - channelClass = VoiceChannel; - break; - case ChannelTypes.CATEGORY: - channelClass = CategoryChannel; - break; - case ChannelTypes.NEWS: - channelClass = NewsChannel; - break; - case ChannelTypes.STORE: - channelClass = StoreChannel; - break; - } - - // Create the new channel instance and copy over cached data - const newChannel = new channelClass(channel.guild, data); - if (channel.messages && newChannel.messages) { - for (const [id, message] of channel.messages) newChannel.messages.set(id, message); - } - - channel = newChannel; - this.client.channels.set(channel.id, channel); - } else { - 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/GuildChannelsPositionUpdate.js b/node_modules/discord.js/src/client/actions/GuildChannelsPositionUpdate.js deleted file mode 100644 index ea184ef..0000000 --- a/node_modules/discord.js/src/client/actions/GuildChannelsPositionUpdate.js +++ /dev/null @@ -1,19 +0,0 @@ -const Action = require('./Action'); - -class GuildChannelsPositionUpdate extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.guild_id); - if (guild) { - for (const partialChannel of data.channels) { - const channel = guild.channels.get(partialChannel.id); - if (channel) channel.position = partialChannel.position; - } - } - - return { guild }; - } -} - -module.exports = GuildChannelsPositionUpdate; 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 8222323..0000000 --- a/node_modules/discord.js/src/client/actions/GuildDelete.js +++ /dev/null @@ -1,57 +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) { - for (const channel of guild.channels.values()) { - if (channel.type === 'text') channel.stopTyping(true); - } - - 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, - }; - } - - for (const channel of guild.channels.values()) this.client.channels.delete(channel.id); - if (guild.voiceConnection) guild.voiceConnection.disconnect(); - - // 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; - } - if (guild) guild.deleted = true; - - 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 79f55ba..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojiCreate.js +++ /dev/null @@ -1,17 +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 044679c..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); - emoji.deleted = true; - 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 ff6ae65..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojiUpdate.js +++ /dev/null @@ -1,17 +0,0 @@ -const Action = require('./Action'); - -class GuildEmojiUpdateAction extends Action { - handle(oldEmoji, newEmoji) { - const emoji = this.client.dataManager.updateEmoji(oldEmoji, newEmoji); - return { emoji }; - } -} - -/** - * 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/GuildEmojisUpdate.js b/node_modules/discord.js/src/client/actions/GuildEmojisUpdate.js deleted file mode 100644 index 8656a34..0000000 --- a/node_modules/discord.js/src/client/actions/GuildEmojisUpdate.js +++ /dev/null @@ -1,38 +0,0 @@ -const Action = require('./Action'); - -function mappify(iterable) { - const map = new Map(); - for (const x of iterable) map.set(...x); - return map; -} - -class GuildEmojisUpdateAction extends Action { - handle(data) { - const guild = this.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 - this.client.actions.GuildEmojiUpdate.handle(cachedEmoji, emoji); - } - } else { - // Emoji added - this.client.actions.GuildEmojiCreate.handle(guild, emoji); - } - } - - for (const emoji of deletions.values()) { - // Emoji deleted - this.client.actions.GuildEmojiDelete.handle(emoji); - } - } -} - -module.exports = GuildEmojisUpdateAction; 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 ecb7a8f..0000000 --- a/node_modules/discord.js/src/client/actions/GuildMemberGet.js +++ /dev/null @@ -1,10 +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 6682b63..0000000 --- a/node_modules/discord.js/src/client/actions/GuildMemberRemove.js +++ /dev/null @@ -1,41 +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); - let member = null; - if (guild) { - member = guild.members.get(data.user.id); - guild.memberCount--; - if (member) { - 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; - } - if (member) member.deleted = true; - } - return { guild, member }; - } - - 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 b4f320f..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRoleCreate.js +++ /dev/null @@ -1,26 +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); - let role; - if (guild) { - const already = guild.roles.has(data.role.id); - role = new Role(guild, data.role); - guild.roles.set(role.id, role); - if (!already) client.emit(Constants.Events.GUILD_ROLE_CREATE, role); - } - return { role }; - } -} - -/** - * 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 deafc85..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRoleDelete.js +++ /dev/null @@ -1,42 +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); - let role; - - if (guild) { - 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; - } - if (role) role.deleted = true; - } - - return { role }; - } - - 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 7d127ab..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 Util = require('../../util/Util'); - -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 = Util.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 9094965..0000000 --- a/node_modules/discord.js/src/client/actions/GuildRolesPositionUpdate.js +++ /dev/null @@ -1,19 +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 3d3a47b..0000000 --- a/node_modules/discord.js/src/client/actions/GuildSync.js +++ /dev/null @@ -1,29 +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) { - if (data.presences) { - for (const presence of data.presences) guild._setPresence(presence.user.id, presence); - } - - if (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); - } - } - } - - if ('large' in data) guild.large = data.large; - } - } -} - -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 6806d1c..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 Util = require('../../util/Util'); - -class GuildUpdateAction extends Action { - handle(data) { - const client = this.client; - - const guild = client.guilds.get(data.id); - if (guild) { - const oldGuild = Util.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/InviteCreate.js b/node_modules/discord.js/src/client/actions/InviteCreate.js deleted file mode 100644 index 36e8cf1..0000000 --- a/node_modules/discord.js/src/client/actions/InviteCreate.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -const Action = require('./Action'); -const Invite = require('../../structures/Invite'); -const { Events } = require('../../util/Constants'); - -class InviteCreateAction extends Action { - handle(data) { - const client = this.client; - const guild = client.guilds.get(data.guild_id); - const channel = client.channels.get(data.channel_id); - if (guild && channel) { - const inviteData = Object.assign(data, { guild, channel }); - const invite = new Invite(client, inviteData); - /** - * Emitted when an invite is created. - * <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild, - * or `MANAGE_CHANNEL` permissions for the channel.</info> - * @event Client#inviteCreate - * @param {Invite} invite The invite that was created - */ - client.emit(Events.INVITE_CREATE, invite); - return { invite }; - } - return { invite: null }; - } -} - -module.exports = InviteCreateAction; diff --git a/node_modules/discord.js/src/client/actions/InviteDelete.js b/node_modules/discord.js/src/client/actions/InviteDelete.js deleted file mode 100644 index a25eb88..0000000 --- a/node_modules/discord.js/src/client/actions/InviteDelete.js +++ /dev/null @@ -1,25 +0,0 @@ -const Action = require('./Action'); -const Invite = require('../../structures/Invite'); -const { Events } = require('../../util/Constants'); - -class InviteDeleteAction extends Action { - handle(data) { - const client = this.client; - const guild = client.guilds.get(data.guild_id); - const channel = client.channels.get(data.channel_id); - if (guild && channel) { - const inviteData = Object.assign(data, { guild, channel }); - const invite = new Invite(client, inviteData); - /** - * Emitted when an invite is deleted. - * <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild, - * or `MANAGE_CHANNEL` permissions for the channel.</info> - * @event Client#inviteDelete - * @param {Invite} invite The invite that was deleted - */ - client.emit(Events.INVITE_DELETE, invite); - } - } -} - -module.exports = InviteDeleteAction; 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 532f80c..0000000 --- a/node_modules/discord.js/src/client/actions/MessageCreate.js +++ /dev/null @@ -1,53 +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)); - } - const lastMessage = messages[messages.length - 1]; - channel.lastMessageID = lastMessage.id; - if (user) { - user.lastMessageID = lastMessage.id; - user.lastMessage = lastMessage; - } - if (member) { - member.lastMessageID = lastMessage.id; - member.lastMessage = lastMessage; - } - return { - messages, - }; - } else { - const message = channel._cacheMessage(new Message(channel, data, client)); - channel.lastMessageID = data.id; - if (user) { - user.lastMessageID = data.id; - user.lastMessage = message; - } - if (member) { - member.lastMessageID = data.id; - member.lastMessage = message; - } - 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 9dc0828..0000000 --- a/node_modules/discord.js/src/client/actions/MessageDelete.js +++ /dev/null @@ -1,35 +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); - let message; - - if (channel) { - 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; - } - if (message) message.deleted = true; - } - - return { message }; - } - - 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 7ee2455..0000000 --- a/node_modules/discord.js/src/client/actions/MessageDeleteBulk.js +++ /dev/null @@ -1,26 +0,0 @@ -const Action = require('./Action'); -const Collection = require('../../util/Collection'); -const Constants = require('../../util/Constants'); - -class MessageDeleteBulkAction extends Action { - handle(data) { - const messages = new Collection(); - const channel = this.client.channels.get(data.channel_id); - - if (channel) { - for (const id of data.ids) { - const message = channel.messages.get(id); - if (message) { - message.deleted = true; - messages.set(message.id, message); - channel.messages.delete(id); - } - } - } - - if (messages.size > 0) this.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 d962953..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionAdd.js +++ /dev/null @@ -1,37 +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; - // Verify channel - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - // Verify message - const message = channel.messages.get(data.message_id); - if (!message) return false; - if (!data.emoji) return false; - // Verify reaction - 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 cached 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 2403c3b..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionRemove.js +++ /dev/null @@ -1,37 +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; - // Verify channel - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - // Verify message - const message = channel.messages.get(data.message_id); - if (!message) return false; - if (!data.emoji) return false; - // Verify reaction - 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 cached message. - * @event Client#messageReactionRemove - * @param {MessageReaction} messageReaction The reaction object - * @param {User} user The user whose emoji or reaction emoji was removed - */ - -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 e365646..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 cached message. - * @event Client#messageReactionRemoveAll - * @param {Message} message The message the reactions were removed from - */ - -module.exports = MessageReactionRemoveAll; diff --git a/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js b/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js deleted file mode 100644 index 12b4445..0000000 --- a/node_modules/discord.js/src/client/actions/MessageReactionRemoveEmoji.js +++ /dev/null @@ -1,27 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -class MessageReactionRemoveEmoji extends Action { - handle(data) { - // Verify channel - const channel = this.client.channels.get(data.channel_id); - if (!channel || channel.type === 'voice') return false; - // Verify message - const message = channel.messages.get(data.message_id); - if (!message) return false; - if (!data.emoji) return false; - // Verify reaction - const reaction = message._removeReaction(data.emoji); - if (reaction) this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE_EMOJI, reaction); - - return { message, reaction }; - } -} - -/** - * Emitted whenever a reaction emoji is removed from a cached message. - * @event Client#messageReactionRemoveEmoji - * @param {MessageReaction} messageReaction The reaction object - */ - -module.exports = MessageReactionRemoveEmoji; 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 4e0392d..0000000 --- a/node_modules/discord.js/src/client/actions/MessageUpdate.js +++ /dev/null @@ -1,40 +0,0 @@ -const Action = require('./Action'); -const Constants = require('../../util/Constants'); - -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) { - message.patch(data); - client.emit(Constants.Events.MESSAGE_UPDATE, message._edits[0], message); - return { - old: message._edits[0], - 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 0ee85ae..0000000 --- a/node_modules/discord.js/src/client/actions/UserGet.js +++ /dev/null @@ -1,11 +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 6b917d1..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 Util = require('../../util/Util'); - -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 = Util.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 3492fa7..0000000 --- a/node_modules/discord.js/src/client/rest/APIRequest.js +++ /dev/null @@ -1,52 +0,0 @@ -const snekfetch = require('snekfetch'); -const Constants = require('../../util/Constants'); - -class APIRequest { - constructor(rest, method, path, auth, data, files, reason) { - this.rest = rest; - this.client = rest.client; - this.method = method; - this.path = path.toString(); - this.auth = auth; - this.data = data; - this.files = files; - this.route = this.getRoute(this.path); - this.reason = reason; - } - - 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; - } - - getAuth() { - if (this.client.token && this.client.user && this.client.user.bot) { - return `Bot ${this.client.token}`; - } else if (this.client.token) { - return this.client.token; - } - throw new Error(Constants.Errors.NO_TOKEN); - } - - gen() { - const API = `${this.client.options.http.host}/api/v${this.client.options.http.version}`; - const request = snekfetch[this.method](`${API}${this.path}`); - if (this.auth) request.set('Authorization', this.getAuth()); - if (this.reason) request.set('X-Audit-Log-Reason', encodeURIComponent(this.reason)); - if (!this.rest.client.browser) request.set('User-Agent', this.rest.userAgentManager.userAgent); - if (this.files) { - for (const file of this.files) if (file && file.file) request.attach(file.name, file.file, file.name); - if (typeof this.data !== 'undefined') request.attach('payload_json', JSON.stringify(this.data)); - } else if (this.data) { - request.send(this.data); - } - return request; - } -} - -module.exports = APIRequest; diff --git a/node_modules/discord.js/src/client/rest/DiscordAPIError.js b/node_modules/discord.js/src/client/rest/DiscordAPIError.js deleted file mode 100644 index f5f8336..0000000 --- a/node_modules/discord.js/src/client/rest/DiscordAPIError.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Represents an error from the Discord API. - * @extends Error - */ -class DiscordAPIError extends Error { - constructor(path, error, method) { - super(); - const flattened = this.constructor.flattenErrors(error.errors || error).join('\n'); - this.name = 'DiscordAPIError'; - this.message = error.message && flattened ? `${error.message}\n${flattened}` : error.message || flattened; - - /** - * The path of the request relative to the HTTP endpoint - * @type {string} - */ - this.path = path; - - /** - * HTTP error code returned by Discord - * @type {number} - */ - this.code = error.code; - - /** - * The HTTP method used for the request - * @type {string} - */ - this.method = method; - } - - /** - * Flattens an errors object returned from the API into an array. - * @param {Object} obj Discord errors object - * @param {string} [key] Used internally to determine key names of nested fields - * @returns {string[]} - * @private - */ - static flattenErrors(obj, key = '') { - let messages = []; - - for (const k of Object.keys(obj)) { - if (k === 'message') continue; - const newKey = key ? isNaN(k) ? `${key}.${k}` : `${key}[${k}]` : k; - - if (obj[k]._errors) { - messages.push(`${newKey}: ${obj[k]._errors.map(e => e.message).join(' ')}`); - } else if (obj[k].code || obj[k].message) { - messages.push(`${obj[k].code ? `${obj[k].code}: ` : ''}: ${obj[k].message}`.trim()); - } else if (typeof obj[k] === 'string') { - messages.push(obj[k]); - } else { - messages = messages.concat(this.flattenErrors(obj[k], newKey)); - } - } - - return messages; - } -} - -module.exports = DiscordAPIError; 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 ee64712..0000000 --- a/node_modules/discord.js/src/client/rest/RESTManager.js +++ /dev/null @@ -1,58 +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; - } - - destroy() { - for (const handlerKey of Object.keys(this.handlers)) { - const handler = this.handlers[handlerKey]; - if (handler.destroy) handler.destroy(); - } - } - - push(handler, apiRequest) { - return new Promise((resolve, reject) => { - handler.push({ - request: apiRequest, - resolve, - reject, - retries: 0, - }); - }); - } - - 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, reason) { - const apiRequest = new APIRequest(this, method, url, auth, data, file, reason); - 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 59f3c65..0000000 --- a/node_modules/discord.js/src/client/rest/RESTMethods.js +++ /dev/null @@ -1,1067 +0,0 @@ -const querystring = require('querystring'); -const long = require('long'); -const Permissions = require('../../util/Permissions'); -const Constants = require('../../util/Constants'); -const Endpoints = Constants.Endpoints; -const Collection = require('../../util/Collection'); -const Util = require('../../util/Util'); -const resolvePermissions = require('../../structures/shared/resolvePermissions'); - -const RichEmbed = require('../../structures/RichEmbed'); -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 OAuth2Application = require('../../structures/OAuth2Application'); -const Channel = require('../../structures/Channel'); -const GroupDMChannel = require('../../structures/GroupDMChannel'); -const Guild = require('../../structures/Guild'); -const VoiceRegion = require('../../structures/VoiceRegion'); -const GuildAuditLogs = require('../../structures/GuildAuditLogs'); - -const MessageFlags = require('../../util/MessageFlags'); - -class RESTMethods { - constructor(restManager) { - this.rest = restManager; - this.client = restManager.client; - this._ackToken = null; - } - - login(token = this.client.token) { - return new Promise((resolve, reject) => { - if (!token || typeof token !== 'string') throw new Error(Constants.Errors.INVALID_TOKEN); - token = token.replace(/^Bot\s*/i, ''); - this.client.manager.connectToWebSocket(token, resolve, reject); - }).catch(e => { - this.client.destroy(); - return Promise.reject(e); - }); - } - - logout() { - return this.rest.makeRequest('post', Endpoints.logout, true, {}); - } - - getGateway(bot = false) { - return this.rest.makeRequest('get', bot ? Endpoints.gateway.bot : Endpoints.gateway, true); - } - - fetchVoiceRegions(guildID) { - let endpoint; - if (guildID) endpoint = Endpoints.Guild(guildID).voiceRegions; - else endpoint = Endpoints.voiceRegions; - return this.rest.makeRequest('get', endpoint, true).then(res => { - const regions = new Collection(); - for (const region of res) regions.set(region.id, new VoiceRegion(region)); - return regions; - }); - } - - fetchEmbed(guildID) { - return this.rest.makeRequest('get', Endpoints.Guild(guildID).embed, true).then(data => ({ - enabled: data.enabled, - channel: data.channel_id ? this.client.channels.get(data.channel_id) : null, - })); - } - - sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code, reply } = {}, files = null) { - return new Promise((resolve, reject) => { // eslint-disable-line complexity - if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content); - - // The nonce has to be a uint64 :< - if (typeof nonce !== 'undefined') { - nonce = parseInt(nonce); - if (isNaN(nonce) || nonce < 0) throw new RangeError('Message nonce must fit in an unsigned 64-bit integer.'); - } - - if (content) { - if (split && typeof split !== 'object') split = {}; - - // Wrap everything in a code block - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - if (split) { - split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`; - split.append = '\n```'; - } - } - - // Add zero-width spaces to @everyone/@here - if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { - content = content.replace(/@(everyone|here)/g, '@\u200b$1'); - } - - // Add the reply prefix - if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') { - const id = this.client.resolver.resolveUserID(reply); - const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`; - content = `${mention}${content ? `, ${content}` : ''}`; - if (split) split.prepend = `${mention}, ${split.prepend || ''}`; - } - - // Split the content - if (split) content = Util.splitMessage(content, split); - } else if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') { - const id = this.client.resolver.resolveUserID(reply); - content = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`; - } - - const send = chan => { - if (content instanceof Array) { - const messages = []; - (function sendChunk(list, index) { - const options = index === list.length - 1 ? { tts, embed, files } : { tts }; - chan.send(list[index], options).then(message => { - messages.push(message); - if (index >= list.length - 1) return resolve(messages); - return sendChunk(list, ++index); - }).catch(reject); - }(content, 0)); - } else { - this.rest.makeRequest('post', Endpoints.Channel(chan).messages, true, { - content, tts, nonce, embed, - }, files).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, { flags, embed, code, reply } = {}) { - if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content); - - if (typeof flags !== 'undefined') flags = MessageFlags.resolve(flags); - - // Wrap everything in a code block - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - } - - // Add the reply prefix - if (reply && message.channel.type !== 'dm') { - const id = this.client.resolver.resolveUserID(reply); - const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`; - content = `${mention}${content ? `, ${content}` : ''}`; - } - - if (embed instanceof RichEmbed) embed = embed.toJSON(); - - return this.rest.makeRequest('patch', Endpoints.Message(message), true, { - content, embed, flags, - }).then(data => this.client.actions.MessageUpdate.handle(data).updated); - } - - deleteMessage(message) { - return this.rest.makeRequest('delete', Endpoints.Message(message), true) - .then(() => - this.client.actions.MessageDelete.handle({ - id: message.id, - channel_id: message.channel.id, - }).message - ); - } - - ackMessage(message) { - return this.rest.makeRequest('post', Endpoints.Message(message).ack, true, { token: this._ackToken }).then(res => { - if (res.token) this._ackToken = res.token; - return message; - }); - } - - ackTextChannel(channel) { - return this.rest.makeRequest('post', Endpoints.Channel(channel).Message(channel.lastMessageID).ack, true, { - token: this._ackToken, - }).then(res => { - if (res.token) this._ackToken = res.token; - return channel; - }); - } - - ackGuild(guild) { - return this.rest.makeRequest('post', Endpoints.Guild(guild).ack, true).then(() => guild); - } - - bulkDeleteMessages(channel, messages) { - return this.rest.makeRequest('post', Endpoints.Channel(channel).messages.bulkDelete, true, { - messages: messages, - }).then(() => - this.client.actions.MessageDeleteBulk.handle({ - channel_id: channel.id, - ids: messages, - }).messages - ); - } - - search(target, options) { - if (typeof options === 'string') options = { content: options }; - if (options.before) { - if (!(options.before instanceof Date)) options.before = new Date(options.before); - options.maxID = long.fromNumber(options.before.getTime() - 14200704e5).shiftLeft(22).toString(); - } - if (options.after) { - if (!(options.after instanceof Date)) options.after = new Date(options.after); - options.minID = long.fromNumber(options.after.getTime() - 14200704e5).shiftLeft(22).toString(); - } - if (options.during) { - if (!(options.during instanceof Date)) options.during = new Date(options.during); - const t = options.during.getTime() - 14200704e5; - options.minID = long.fromNumber(t).shiftLeft(22).toString(); - options.maxID = long.fromNumber(t + 86400000).shiftLeft(22).toString(); - } - if (options.channel) options.channel = this.client.resolver.resolveChannelID(options.channel); - if (options.author) options.author = this.client.resolver.resolveUserID(options.author); - if (options.mentions) options.mentions = this.client.resolver.resolveUserID(options.options.mentions); - options = { - content: options.content, - max_id: options.maxID, - min_id: options.minID, - has: options.has, - channel_id: options.channel, - author_id: options.author, - author_type: options.authorType, - context_size: options.contextSize, - sort_by: options.sortBy, - sort_order: options.sortOrder, - limit: options.limit, - offset: options.offset, - mentions: options.mentions, - mentions_everyone: options.mentionsEveryone, - link_hostname: options.linkHostname, - embed_provider: options.embedProvider, - embed_type: options.embedType, - attachment_filename: options.attachmentFilename, - attachment_extension: options.attachmentExtension, - include_nsfw: options.nsfw, - }; - - for (const key of Object.keys(options)) if (options[key] === undefined) delete options[key]; - const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&'); - - let endpoint; - if (target instanceof Channel) { - endpoint = Endpoints.Channel(target).search; - } else if (target instanceof Guild) { - endpoint = Endpoints.Guild(target).search; - } else { - throw new TypeError('Target must be a TextChannel, DMChannel, GroupDMChannel, or Guild.'); - } - return this.rest.makeRequest('get', `${endpoint}?${queryString}`, true).then(body => { - const messages = body.messages.map(x => - x.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client)) - ); - return { - totalResults: body.total_results, - messages, - }; - }); - } - - createChannel(guild, name, options) { - const { - type, - topic, - nsfw, - bitrate, - userLimit, - parent, - permissionOverwrites, - position, - rateLimitPerUser, - reason, - } = options; - return this.rest.makeRequest('post', Endpoints.Guild(guild).channels, true, { - name, - topic, - type: type ? Constants.ChannelTypes[type.toUpperCase()] : Constants.ChannelTypes.TEXT, - nsfw, - bitrate, - user_limit: userLimit, - parent_id: parent instanceof Channel ? parent.id : parent, - permission_overwrites: resolvePermissions.call(this, permissionOverwrites, guild), - position, - rate_limit_per_user: rateLimitPerUser, - }, - undefined, - reason).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', Endpoints.User(this.client.user).channels, true, { - recipient_id: recipient.id, - }).then(data => this.client.actions.ChannelCreate.handle(data).channel); - } - - createGroupDM(options) { - const data = this.client.user.bot ? - { access_tokens: options.accessTokens, nicks: options.nicks } : - { recipients: options.recipients }; - return this.rest.makeRequest('post', Endpoints.User('@me').channels, true, data) - .then(res => new GroupDMChannel(this.client, res)); - } - - addUserToGroupDM(channel, options) { - const data = this.client.user.bot ? - { nick: options.nick, access_token: options.accessToken } : - { recipient: options.id }; - return this.rest.makeRequest('put', Endpoints.Channel(channel).Recipient(options.id), true, data) - .then(() => channel); - } - - removeUserFromGroupDM(channel, userId) { - return this.rest.makeRequest('delete', Endpoints.Channel(channel).Recipient(userId), true) - .then(() => channel); - } - - updateGroupDMChannel(channel, _data) { - const data = {}; - data.name = _data.name; - data.icon = _data.icon; - return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data).then(() => channel); - } - - getExistingDM(recipient) { - return this.client.channels.find(channel => - channel.recipient && channel.recipient.id === recipient.id - ); - } - - deleteChannel(channel, reason) { - 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('delete', Endpoints.Channel(channel), true, undefined, undefined, reason) - .then(data => { - data.id = channel.id; - return this.client.actions.ChannelDelete.handle(data).channel; - }); - } - - updateChannel(channel, _data, reason) { - const data = {}; - data.name = (_data.name || channel.name).trim(); - data.topic = typeof _data.topic === 'undefined' ? channel.topic : _data.topic; - data.nsfw = typeof _data.nsfw === 'undefined' ? channel.nsfw : _data.nsfw; - data.position = _data.position || channel.position; - data.bitrate = _data.bitrate || (channel.bitrate ? channel.bitrate * 1000 : undefined); - data.user_limit = typeof _data.userLimit !== 'undefined' ? _data.userLimit : channel.userLimit; - data.parent_id = _data.parent instanceof Channel ? _data.parent.id : _data.parent; - data.permission_overwrites = _data.permissionOverwrites ? - resolvePermissions.call(this, _data.permissionOverwrites, channel.guild) : undefined; - data.rate_limit_per_user = typeof _data.rateLimitPerUser !== 'undefined' ? - _data.rateLimitPerUser : channel.rateLimitPerUser; - return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data, undefined, reason).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('delete', Endpoints.User('@me').Guild(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', Endpoints.guilds, true, options).then(data => { - if (this.client.guilds.has(data.id)) return resolve(this.client.guilds.get(data.id)); - - const handleGuild = guild => { - if (guild.id === data.id) { - this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild); - this.client.clearTimeout(timeout); - resolve(guild); - } - }; - this.client.on(Constants.Events.GUILD_CREATE, handleGuild); - - const timeout = this.client.setTimeout(() => { - this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild); - reject(new Error('Took too long to receive guild data.')); - }, 10000); - return undefined; - }, reject); - }); - } - - // Untested but probably will work - deleteGuild(guild) { - return this.rest.makeRequest('delete', Endpoints.Guild(guild), true).then(() => - this.client.actions.GuildDelete.handle({ id: guild.id }).guild - ); - } - - getUser(userID, cache) { - return this.rest.makeRequest('get', Endpoints.User(userID), true).then(data => { - if (cache) return this.client.actions.UserGet.handle(data).user; - else return new User(this.client, data); - }); - } - - updateCurrentUser(_data, password) { - const user = this.client.user; - const data = {}; - data.username = _data.username || user.username; - data.avatar = typeof _data.avatar === 'undefined' ? user.avatar : this.client.resolver.resolveBase64(_data.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', Endpoints.User('@me'), true, data).then(newData => - this.client.actions.UserUpdate.handle(newData).updated - ); - } - - updateGuild(guild, data, reason) { - return this.rest.makeRequest('patch', Endpoints.Guild(guild), true, data, undefined, reason).then(newData => - this.client.actions.GuildUpdate.handle(newData).updated - ); - } - - kickGuildMember(guild, member, reason) { - return this.rest.makeRequest( - 'delete', Endpoints.Guild(guild).Member(member), true, - undefined, undefined, reason) - .then(() => member); - } - - createGuildRole(guild, data, reason) { - if (data.color) data.color = this.client.resolver.resolveColor(data.color); - if (data.permissions) data.permissions = Permissions.resolve(data.permissions); - return this.rest.makeRequest('post', Endpoints.Guild(guild).roles, true, data, undefined, reason).then(r => { - const { role } = this.client.actions.GuildRoleCreate.handle({ - guild_id: guild.id, - role: r, - }); - if (data.position) return role.setPosition(data.position, reason); - return role; - }); - } - - deleteGuildRole(role, reason) { - return this.rest.makeRequest( - 'delete', Endpoints.Guild(role.guild).Role(role.id), true, - undefined, undefined, reason) - .then(() => - this.client.actions.GuildRoleDelete.handle({ - guild_id: role.guild.id, - role_id: role.id, - }).role - ); - } - - setChannelOverwrite(channel, payload) { - return this.rest.makeRequest('put', `${Endpoints.Channel(channel).permissions}/${payload.id}`, true, payload); - } - - deletePermissionOverwrites(overwrite, reason) { - return this.rest.makeRequest( - 'delete', `${Endpoints.Channel(overwrite.channel).permissions}/${overwrite.id}`, - true, undefined, undefined, reason - ).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 = Endpoints.Channel(channel).messages; - 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', Endpoints.Channel(channel).Message(messageID), true); - } - - putGuildMember(guild, userID, options) { - options.access_token = options.accessToken; - if (options.roles) { - const roles = options.roles; - if (roles instanceof Collection || (roles instanceof Array && roles[0] instanceof Role)) { - options.roles = roles.map(role => role.id); - } - } - return this.rest.makeRequest('put', Endpoints.Guild(guild).Member(userID), true, options) - .then(data => this.client.actions.GuildMemberGet.handle(guild, data).member); - } - - getGuild(guild) { - return this.rest.makeRequest('get', Endpoints.Guild(guild), true); - } - - getGuildMember(guild, userID, cache) { - return this.rest.makeRequest('get', Endpoints.Guild(guild).Member(userID), true).then(data => { - if (cache) return this.client.actions.GuildMemberGet.handle(guild, data).member; - else return new GuildMember(guild, data); - }); - } - - updateGuildMember(member, data, reason) { - if (data.channel) { - const channel = this.client.resolver.resolveChannel(data.channel); - if (!channel || channel.guild.id !== member.guild.id || channel.type !== 'voice') { - return Promise.reject(new Error('Could not resolve channel to a guild voice channel.')); - } - data.channel_id = channel.id; - data.channel = undefined; - } else if (data.channel === null) { - data.channel_id = null; - data.channel = undefined; - } - if (data.roles) data.roles = [...new Set(data.roles.map(role => role instanceof Role ? role.id : role))]; - - let endpoint = Endpoints.Member(member); - // Fix your endpoints, discord ;-; - if (member.id === this.client.user.id) { - const keys = Object.keys(data); - if (keys.length === 1 && keys[0] === 'nick') { - endpoint = Endpoints.Member(member).nickname; - } - } - - return this.rest.makeRequest('patch', endpoint, true, data, undefined, reason).then(newData => - member.guild._updateMember(member, newData).mem - ); - } - - addMemberRole(member, role, reason) { - return new Promise((resolve, reject) => { - if (member._roles.includes(role.id)) return resolve(member); - - const listener = (oldMember, newMember) => { - if (newMember.id === member.id && !oldMember._roles.includes(role.id) && newMember._roles.includes(role.id)) { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - resolve(newMember); - } - }; - - this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener); - const timeout = this.client.setTimeout(() => { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - reject(new Error('Adding the role timed out.')); - }, 10e3); - - return this.rest.makeRequest('put', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason) - .catch(err => { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - this.client.clearTimeout(timeout); - reject(err); - }); - }); - } - - removeMemberRole(member, role, reason) { - return new Promise((resolve, reject) => { - if (!member._roles.includes(role.id)) return resolve(member); - - const listener = (oldMember, newMember) => { - if (newMember.id === member.id && oldMember._roles.includes(role.id) && !newMember._roles.includes(role.id)) { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - resolve(newMember); - } - }; - - this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener); - const timeout = this.client.setTimeout(() => { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - reject(new Error('Removing the role timed out.')); - }, 10e3); - - return this.rest.makeRequest('delete', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason) - .catch(err => { - this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener); - this.client.clearTimeout(timeout); - reject(err); - }); - }); - } - - sendTyping(channelID) { - return this.rest.makeRequest('post', Endpoints.Channel(channelID).typing, true); - } - - banGuildMember(guild, member, options) { - const id = this.client.resolver.resolveUserID(member); - if (!id) return Promise.reject(new Error('Couldn\'t resolve the user ID to ban.')); - - const url = `${Endpoints.Guild(guild).bans}/${id}?${querystring.stringify(options)}`; - return this.rest.makeRequest('put', url, true).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, reason) { - 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('delete', `${Endpoints.Guild(guild).bans}/${id}`, true, undefined, undefined, reason) - .catch(err => { - this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener); - this.client.clearTimeout(timeout); - reject(err); - }); - }); - } - - getGuildBan(guild, user) { - const id = this.client.resolver.resolveUserID(user); - return this.rest.makeRequest('get', `${Endpoints.Guild(guild).bans}/${id}`, true).then(ban => ({ - reason: ban.reason, - user: this.client.dataManager.newUser(ban.user), - })); - } - - getGuildBans(guild) { - return this.rest.makeRequest('get', Endpoints.Guild(guild).bans, true).then(bans => - bans.reduce((collection, ban) => { - collection.set(ban.user.id, { - reason: ban.reason, - user: this.client.dataManager.newUser(ban.user), - }); - return collection; - }, new Collection()) - ); - } - - updateGuildRole(role, _data, reason) { - const data = {}; - data.name = _data.name || role.name; - data.position = typeof _data.position !== 'undefined' ? _data.position : role.position; - data.color = _data.color === null ? null : this.client.resolver.resolveColor(_data.color || role.color); - data.hoist = typeof _data.hoist !== 'undefined' ? _data.hoist : role.hoist; - data.mentionable = typeof _data.mentionable !== 'undefined' ? _data.mentionable : role.mentionable; - - if (typeof _data.permissions !== 'undefined') data.permissions = Permissions.resolve(_data.permissions); - else data.permissions = role.permissions; - - return this.rest.makeRequest('patch', Endpoints.Guild(role.guild).Role(role.id), true, data, undefined, reason) - .then(_role => - this.client.actions.GuildRoleUpdate.handle({ - role: _role, - guild_id: role.guild.id, - }).updated - ); - } - - pinMessage(message) { - return this.rest.makeRequest('put', Endpoints.Channel(message.channel).Pin(message.id), true) - .then(() => message); - } - - unpinMessage(message) { - return this.rest.makeRequest('delete', Endpoints.Channel(message.channel).Pin(message.id), true) - .then(() => message); - } - - getChannelPinnedMessages(channel) { - return this.rest.makeRequest('get', Endpoints.Channel(channel).pins, true); - } - - createChannelInvite(channel, options, reason) { - const payload = {}; - payload.temporary = options.temporary; - payload.max_age = options.maxAge; - payload.max_uses = options.maxUses; - payload.unique = options.unique; - return this.rest.makeRequest('post', Endpoints.Channel(channel).invites, true, payload, undefined, reason) - .then(invite => new Invite(this.client, invite)); - } - - deleteInvite(invite, reason) { - return this.rest.makeRequest('delete', Endpoints.Invite(invite.code), true, undefined, undefined, reason) - .then(() => invite); - } - - getInvite(code) { - return this.rest.makeRequest('get', Endpoints.Invite(code), true).then(invite => - new Invite(this.client, invite) - ); - } - - getGuildInvites(guild) { - return this.rest.makeRequest('get', Endpoints.Guild(guild).invites, 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; - }); - } - - getGuildVanityCode(guild) { - return this.rest.makeRequest('get', Endpoints.Guild(guild).vanityURL, true) - .then(res => res.code); - } - - pruneGuildMembers(guild, days, dry, reason) { - return this.rest.makeRequest(dry ? - 'get' : - 'post', - `${Endpoints.Guild(guild).prune}?days=${days}`, true, undefined, undefined, reason) - .then(data => data.pruned); - } - - createEmoji(guild, image, name, roles, reason) { - const data = { image, name }; - if (roles) data.roles = roles.map(r => r.id ? r.id : r); - return this.rest.makeRequest('post', Endpoints.Guild(guild).emojis, true, data, undefined, reason) - .then(emoji => this.client.actions.GuildEmojiCreate.handle(guild, emoji).emoji); - } - - updateEmoji(emoji, _data, reason) { - const data = {}; - if (_data.name) data.name = _data.name; - if (_data.roles) data.roles = _data.roles.map(r => r.id ? r.id : r); - return this.rest.makeRequest('patch', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, data, undefined, reason) - .then(newEmoji => this.client.actions.GuildEmojiUpdate.handle(emoji, newEmoji).emoji); - } - - deleteEmoji(emoji, reason) { - return this.rest.makeRequest('delete', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, undefined, reason) - .then(() => this.client.actions.GuildEmojiDelete.handle(emoji).emoji); - } - - getGuildAuditLogs(guild, options = {}) { - if (options.before && options.before instanceof GuildAuditLogs.Entry) options.before = options.before.id; - if (options.after && options.after instanceof GuildAuditLogs.Entry) options.after = options.after.id; - if (typeof options.type === 'string') options.type = GuildAuditLogs.Actions[options.type]; - - const queryString = (querystring.stringify({ - before: options.before, - after: options.after, - limit: options.limit, - user_id: this.client.resolver.resolveUserID(options.user), - action_type: options.type, - }).match(/[^=&?]+=[^=&?]+/g) || []).join('&'); - - return this.rest.makeRequest('get', `${Endpoints.Guild(guild).auditLogs}?${queryString}`, true) - .then(data => GuildAuditLogs.build(guild, data)); - } - - getWebhook(id, token) { - return this.rest.makeRequest('get', Endpoints.Webhook(id, token), !token).then(data => - new Webhook(this.client, data) - ); - } - - getGuildWebhooks(guild) { - return this.rest.makeRequest('get', Endpoints.Guild(guild).webhooks, 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', Endpoints.Channel(channel).webhooks, 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, reason) { - return this.rest.makeRequest('post', Endpoints.Channel(channel).webhooks, true, { name, avatar }, undefined, reason) - .then(data => new Webhook(this.client, data)); - } - - editWebhook(webhook, options, reason) { - let endpoint; - let auth; - - // Changing the channel of a webhook or specifying a reason requires a bot token - if (options.channel_id || reason) { - endpoint = Endpoints.Webhook(webhook.id); - auth = true; - } else { - endpoint = Endpoints.Webhook(webhook.id, webhook.token); - auth = false; - } - - return this.rest.makeRequest('patch', endpoint, auth, options, undefined, reason).then(data => { - webhook.name = data.name; - webhook.avatar = data.avatar; - webhook.channelID = data.channel_id; - return webhook; - }); - } - - deleteWebhook(webhook, reason) { - return this.rest.makeRequest( - 'delete', Endpoints.Webhook(webhook.id, webhook.token), - false, undefined, undefined, reason); - } - - sendWebhookMessage(webhook, content, { avatarURL, tts, embeds, username } = {}, files = null) { - return new Promise((resolve, reject) => { - username = username || webhook.name; - - if (content instanceof Array) { - const messages = []; - (function sendChunk(list, index) { - const options = index === list.length - 1 ? { tts, embeds, files } : { tts }; - webhook.send(list[index], options).then(message => { - messages.push(message); - if (index >= list.length - 1) return resolve(messages); - return sendChunk(list, ++index); - }).catch(reject); - }(content, 0)); - } else { - this.rest.makeRequest('post', `${Endpoints.Webhook(webhook.id, webhook.token)}?wait=true`, false, { - username, - avatar_url: avatarURL, - content, - tts, - embeds, - }, files).then(data => { - if (!this.client.channels) resolve(data); - else resolve(this.client.actions.MessageCreate.handle(data).message); - }, reject); - } - }); - } - - sendSlackWebhookMessage(webhook, body) { - return this.rest.makeRequest( - 'post', `${Endpoints.Webhook(webhook.id, webhook.token)}/slack?wait=true`, false, body - ); - } - - fetchUserProfile(user) { - return this.rest.makeRequest('get', Endpoints.User(user).profile, true).then(data => - new UserProfile(user, data) - ); - } - - fetchMentions(options) { - if (options.guild instanceof Guild) options.guild = options.guild.id; - Util.mergeDefault({ limit: 25, roles: true, everyone: true, guild: null }, options); - - return this.rest.makeRequest( - 'get', Endpoints.User('@me').Mentions(options.limit, options.roles, options.everyone, options.guild), true - ).then(data => data.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client))); - } - - addFriend(user) { - return this.rest.makeRequest('post', Endpoints.User('@me'), true, { - username: user.username, - discriminator: user.discriminator, - }).then(() => user); - } - - removeFriend(user) { - return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true) - .then(() => user); - } - - blockUser(user) { - return this.rest.makeRequest('put', Endpoints.User('@me').Relationship(user.id), true, { type: 2 }) - .then(() => user); - } - - unblockUser(user) { - return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true) - .then(() => user); - } - - updateEmbed(guildID, embed, reason) { - return this.rest.makeRequest('patch', Endpoints.Guild(guildID).embed, true, { - enabled: embed.enabled, - channel_id: this.client.resolver.resolveChannelID(embed.channel), - }, undefined, reason); - } - - setRolePositions(guildID, roles) { - return this.rest.makeRequest('patch', Endpoints.Guild(guildID).roles, true, roles).then(() => - this.client.actions.GuildRolesPositionUpdate.handle({ - guild_id: guildID, - roles, - }).guild - ); - } - - setChannelPositions(guildID, channels) { - return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, channels).then(() => - this.client.actions.GuildChannelsPositionUpdate.handle({ - guild_id: guildID, - channels, - }).guild - ); - } - - addMessageReaction(message, emoji) { - return this.rest.makeRequest( - 'put', Endpoints.Message(message).Reaction(emoji).User('@me'), true - ).then(() => - message._addReaction(Util.parseEmoji(emoji), message.client.user) - ); - } - - removeMessageReaction(message, emoji, userID) { - const endpoint = Endpoints.Message(message).Reaction(emoji).User(userID === this.client.user.id ? '@me' : userID); - return this.rest.makeRequest('delete', endpoint, true).then(() => - this.client.actions.MessageReactionRemove.handle({ - user_id: userID, - message_id: message.id, - emoji: Util.parseEmoji(emoji), - channel_id: message.channel.id, - }).reaction - ); - } - - removeMessageReactionEmoji(message, emoji) { - const endpoint = Endpoints.Message(message).Reaction(emoji); - return this.rest.makeRequest('delete', endpoint, true).then(() => - this.client.actions.MessageReactionRemoveEmoji.handle({ - message_id: message.id, - emoji: Util.parseEmoji(emoji), - channel_id: message.channel.id, - }).reaction - ); - } - - removeMessageReactions(message) { - return this.rest.makeRequest('delete', Endpoints.Message(message).reactions, true) - .then(() => message); - } - - getMessageReactionUsers(message, emoji, options) { - const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&'); - - return this.rest.makeRequest('get', `${Endpoints.Message(message).Reaction(emoji)}?${queryString}`, true); - } - - getApplication(id) { - return this.rest.makeRequest('get', Endpoints.OAUTH2.Application(id), true).then(app => - new OAuth2Application(this.client, app) - ); - } - - resetApplication(id) { - return this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetToken, true) - .then(() => this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetSecret, true)) - .then(app => new OAuth2Application(this.client, app)); - } - - setNote(user, note) { - return this.rest.makeRequest('put', Endpoints.User(user).note, true, { note }).then(() => user); - } - - acceptInvite(code) { - if (code.id) code = code.id; - return new Promise((resolve, reject) => - this.rest.makeRequest('post', Endpoints.Invite(code), true).then(res => { - const handler = guild => { - if (guild.id === res.id) { - resolve(guild); - this.client.removeListener(Constants.Events.GUILD_CREATE, handler); - } - }; - this.client.on(Constants.Events.GUILD_CREATE, handler); - this.client.setTimeout(() => { - this.client.removeListener(Constants.Events.GUILD_CREATE, handler); - reject(new Error('Accepting invite timed out')); - }, 120e3); - }) - ); - } - - patchUserSettings(data) { - return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').settings, true, data); - } - - patchClientUserGuildSettings(guildID, data) { - return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').Guild(guildID).settings, true, data); - } - - getIntegrations(guild) { - return this.rest.makeRequest( - 'get', - Constants.Endpoints.Guild(guild.id).integrations, - true - ); - } - - createIntegration(guild, data, reason) { - return this.rest.makeRequest( - 'post', - Constants.Endpoints.Guild(guild.id).integrations, - true, - data, - undefined, - reason - ); - } - - syncIntegration(integration) { - return this.rest.makeRequest( - 'post', - Constants.Endpoints.Guild(integration.guild.id).Integration(integration.id), - true - ); - } - - editIntegration(integration, data, reason) { - return this.rest.makeRequest( - 'patch', - Constants.Endpoints.Guild(integration.guild.id).Integration(integration.id), - true, - data, - undefined, - reason - ); - } - - deleteIntegration(integration, reason) { - return this.rest.makeRequest( - 'delete', - Constants.Endpoints.Guild(integration.guild.id).Integration(integration.id), - true, - undefined, - undefined, - reason - ); - } -} - -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 eceee65..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/Burst.js +++ /dev/null @@ -1,90 +0,0 @@ -const RequestHandler = require('./RequestHandler'); -const DiscordAPIError = require('../DiscordAPIError'); -const { Events: { RATE_LIMIT } } = require('../../../util/Constants'); - -class BurstRequestHandler extends RequestHandler { - constructor(restManager, endpoint) { - super(restManager, endpoint); - - this.client = restManager.client; - - this.limit = Infinity; - this.resetTime = null; - this.remaining = 1; - this.timeDifference = 0; - - this.resetTimeout = null; - } - - push(request) { - super.push(request); - this.handle(); - } - - execute(item) { - if (!item) return; - item.request.gen().end((err, res) => { - if (res && res.headers) { - this.limit = Number(res.headers['x-ratelimit-limit']); - this.resetTime = Number(res.headers['x-ratelimit-reset']) * 1000; - this.remaining = Number(res.headers['x-ratelimit-remaining']); - this.timeDifference = Date.now() - new Date(res.headers.date).getTime(); - } - if (err) { - if (err.status === 429) { - this.queue.unshift(item); - if (res.headers['x-ratelimit-global']) this.globalLimit = true; - if (this.resetTimeout) return; - this.resetTimeout = this.client.setTimeout(() => { - this.remaining = this.limit; - this.globalLimit = false; - this.handle(); - this.resetTimeout = null; - }, Number(res.headers['retry-after']) + this.client.options.restTimeOffset); - } else if (err.status >= 500 && err.status < 600) { - if (item.retries === this.client.options.retryLimit) { - item.reject(err); - this.handle(); - } else { - item.retries++; - this.queue.unshift(item); - this.resetTimeout = this.client.setTimeout(() => { - this.handle(); - this.resetTimeout = null; - }, 1e3 + this.client.options.restTimeOffset); - } - } else { - item.reject(err.status >= 400 && err.status < 500 ? - new DiscordAPIError(res.request.path, res.body, res.request.method) : err); - this.handle(); - } - } else { - if (this.remaining === 0) { - if (this.client.listenerCount(RATE_LIMIT)) { - this.client.emit(RATE_LIMIT, { - limit: this.limit, - timeDifference: this.timeDifference, - path: item.request.path, - method: item.request.method, - }); - } - } - this.globalLimit = false; - const data = res && res.body ? res.body : {}; - item.resolve(data); - this.handle(); - } - }); - } - - handle() { - super.handle(); - if (this.queue.length === 0) return; - if ((this.remaining <= 0 || this.globalLimit) && Date.now() - this.timeDifference < this.resetTime) return; - this.execute(this.queue.shift()); - this.remaining--; - this.handle(); - } -} - -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 c5bad20..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/RequestHandler.js +++ /dev/null @@ -1,54 +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} - * @readonly - */ - 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() {} // eslint-disable-line no-empty-function - - destroy() { - this.queue = []; - } -} - -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 9d25bdb..0000000 --- a/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js +++ /dev/null @@ -1,132 +0,0 @@ -const RequestHandler = require('./RequestHandler'); -const DiscordAPIError = require('../DiscordAPIError'); -const { Events: { RATE_LIMIT } } = require('../../../util/Constants'); - -/** - * 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); - - /** - * The client that instantiated this handler - * @type {Client} - */ - this.client = restManager.client; - - /** - * 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; - - /** - * Whether the queue is being processed or not - * @type {boolean} - */ - this.busy = false; - } - - 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) { - this.busy = true; - return new Promise(resolve => { - item.request.gen().end((err, res) => { - if (res && res.headers) { - this.requestLimit = Number(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.queue.unshift(item); - this.client.setTimeout(() => { - this.globalLimit = false; - resolve(); - }, Number(res.headers['retry-after']) + this.client.options.restTimeOffset); - if (res.headers['x-ratelimit-global']) this.globalLimit = true; - } else if (err.status >= 500 && err.status < 600) { - if (item.retries === this.client.options.retryLimit) { - item.reject(err); - resolve(); - } else { - item.retries++; - this.queue.unshift(item); - this.client.setTimeout(resolve, 1e3 + this.client.options.restTimeOffset); - } - } else { - item.reject(err.status >= 400 && err.status < 500 ? - new DiscordAPIError(res.request.path, res.body, res.request.method) : err); - resolve(err); - } - } else { - this.globalLimit = false; - const data = res && res.body ? res.body : {}; - item.resolve(data); - if (this.requestRemaining === 0) { - if (this.client.listenerCount(RATE_LIMIT)) { - /** - * Emitted when the client hits a rate limit while making a request - * @event Client#rateLimit - * @param {Object} rateLimitInfo Object containing the rate limit info - * @param {number} rateLimitInfo.limit Number of requests that can be made to this endpoint - * @param {number} rateLimitInfo.timeDifference Delta-T in ms between your system and Discord servers - * @param {string} rateLimitInfo.path Path used for request that triggered this event - * @param {string} rateLimitInfo.method HTTP method used for request that triggered this event - */ - this.client.emit(RATE_LIMIT, { - limit: this.requestLimit, - timeDifference: this.timeDifference, - path: item.request.path, - method: item.request.method, - }); - } - this.client.setTimeout( - () => resolve(data), - this.requestResetTime - Date.now() + this.timeDifference + this.client.options.restTimeOffset - ); - } else { - resolve(data); - } - } - }); - }); - } - - handle() { - super.handle(); - if (this.busy || this.remaining === 0 || this.queue.length === 0 || this.globalLimit) return; - this.execute(this.queue.shift()).then(() => { - this.busy = false; - 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 13e5528..0000000 --- a/node_modules/discord.js/src/client/rest/UserAgentManager.js +++ /dev/null @@ -1,25 +0,0 @@ -const Constants = require('../../util/Constants'); - -class UserAgentManager { - constructor() { - this.build(this.constructor.DEFAULT); - } - - set({ url, version } = {}) { - this.build({ - url: url || this.constructor.DFEAULT.url, - version: version || this.constructor.DEFAULT.version, - }); - } - - build(ua) { - this.userAgent = `DiscordBot (${ua.url}, ${ua.version}) Node.js/${process.version}`; - } -} - -UserAgentManager.DEFAULT = { - url: Constants.Package.homepage.split('#')[0], - version: Constants.Package.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 d8d3f9f..0000000 --- a/node_modules/discord.js/src/client/voice/ClientVoiceManager.js +++ /dev/null @@ -1,86 +0,0 @@ -const Collection = require('../../util/Collection'); -const VoiceConnection = require('./VoiceConnection'); - -/** - * 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<Snowflake, VoiceConnection>} - */ - this.connections = new Collection(); - - this.client.on('self.voiceServer', this.onVoiceServer.bind(this)); - this.client.on('self.voiceStateUpdate', this.onVoiceStateUpdate.bind(this)); - } - - onVoiceServer({ guild_id, token, endpoint }) { - const connection = this.connections.get(guild_id); - if (connection) connection.setTokenAndEndpoint(token, endpoint); - } - - onVoiceStateUpdate({ guild_id, session_id, channel_id }) { - const connection = this.connections.get(guild_id); - if (!connection) return; - if (!channel_id) { - connection._disconnect(); - this.connections.delete(guild_id); - return; - } - - connection.channel = this.client.channels.get(channel_id); - connection.setSessionID(session_id); - } - - /** - * 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 (!channel.joinable) { - if (channel.full) { - throw new Error('You do not have permission to join this voice channel; it is full.'); - } else { - throw new Error('You do not have permission to join this voice channel.'); - } - } - - let connection = this.connections.get(channel.guild.id); - - if (connection) { - if (connection.channel.id !== channel.id) { - this.connections.get(channel.guild.id).updateChannel(channel); - } - resolve(connection); - return; - } else { - connection = new VoiceConnection(this, channel); - this.connections.set(channel.guild.id, connection); - } - - connection.once('failed', reason => { - this.connections.delete(channel.guild.id); - reject(reason); - }); - - connection.once('authenticated', () => { - connection.once('ready', () => resolve(connection)); - connection.once('error', reject); - connection.once('disconnect', () => this.connections.delete(channel.guild.id)); - }); - }); - } -} - -module.exports = ClientVoiceManager; diff --git a/node_modules/discord.js/src/client/voice/VoiceBroadcast.js b/node_modules/discord.js/src/client/voice/VoiceBroadcast.js deleted file mode 100644 index 3a78d87..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceBroadcast.js +++ /dev/null @@ -1,366 +0,0 @@ -const VolumeInterface = require('./util/VolumeInterface'); -const Prism = require('prism-media'); -const OpusEncoders = require('./opus/OpusEngineList'); -const Collection = require('../../util/Collection'); - -const ffmpegArguments = [ - '-analyzeduration', '0', - '-loglevel', '0', - '-f', 's16le', - '-ar', '48000', - '-ac', '2', -]; - -/** - * A voice broadcast can be played across multiple voice connections for improved shared-stream efficiency. - * - * Example usage: - * ```js - * const broadcast = client.createVoiceBroadcast(); - * broadcast.playFile('./music.mp3'); - * // Play "music.mp3" in all voice connections that the client is in - * for (const connection of client.voiceConnections.values()) { - * connection.playBroadcast(broadcast); - * } - * ``` - * @implements {VolumeInterface} - */ -class VoiceBroadcast extends VolumeInterface { - constructor(client) { - super(); - /** - * The client that created the broadcast - * @type {Client} - */ - this.client = client; - this._dispatchers = new Collection(); - this._encoders = new Collection(); - /** - * The audio transcoder that this broadcast uses - * @type {Prism} - */ - this.prism = new Prism(); - /** - * The current audio transcoder that is being used - * @type {Object} - */ - this.currentTranscoder = null; - this.tickInterval = null; - this._volume = 1; - } - - /** - * An array of subscribed dispatchers - * @type {StreamDispatcher[]} - * @readonly - */ - get dispatchers() { - let d = []; - for (const container of this._dispatchers.values()) { - d = d.concat(Array.from(container.values())); - } - return d; - } - - get _playableStream() { - const currentTranscoder = this.currentTranscoder; - if (!currentTranscoder) return null; - const transcoder = currentTranscoder.transcoder; - const options = currentTranscoder.options; - return (transcoder && transcoder.output) || options.stream; - } - - unregisterDispatcher(dispatcher, old) { - const volume = old || dispatcher.volume; - - /** - * Emitted whenever a stream dispatcher unsubscribes from the broadcast. - * @event VoiceBroadcast#unsubscribe - * @param {StreamDispatcher} dispatcher The unsubscribed dispatcher - */ - this.emit('unsubscribe', dispatcher); - for (const container of this._dispatchers.values()) { - container.delete(dispatcher); - - if (!container.size) { - this._encoders.get(volume).destroy(); - this._dispatchers.delete(volume); - this._encoders.delete(volume); - } - } - } - - registerDispatcher(dispatcher) { - if (!this._dispatchers.has(dispatcher.volume)) { - this._dispatchers.set(dispatcher.volume, new Set()); - this._encoders.set(dispatcher.volume, OpusEncoders.fetch()); - } - const container = this._dispatchers.get(dispatcher.volume); - if (!container.has(dispatcher)) { - container.add(dispatcher); - dispatcher.once('end', () => this.unregisterDispatcher(dispatcher)); - dispatcher.on('volumeChange', (o, n) => { - this.unregisterDispatcher(dispatcher, o); - if (!this._dispatchers.has(n)) { - this._dispatchers.set(n, new Set()); - this._encoders.set(n, OpusEncoders.fetch()); - } - this._dispatchers.get(n).add(dispatcher); - }); - /** - * Emitted whenever a stream dispatcher subscribes to the broadcast. - * @event VoiceBroadcast#subscribe - * @param {StreamDispatcher} dispatcher The subscribed dispatcher - */ - this.emit('subscribe', dispatcher); - } - } - - killCurrentTranscoder() { - if (this.currentTranscoder) { - if (this.currentTranscoder.transcoder) this.currentTranscoder.transcoder.kill(); - this.currentTranscoder = null; - this.emit('end'); - } - } - - /** - * Plays any audio stream across the broadcast. - * @param {ReadableStream} stream The audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {VoiceBroadcast} - * @example - * // Play streams using ytdl-core - * const ytdl = require('ytdl-core'); - * const streamOptions = { seek: 0, volume: 1 }; - * const broadcast = client.createVoiceBroadcast(); - * - * voiceChannel.join() - * .then(connection => { - * const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', { filter : 'audioonly' }); - * broadcast.playStream(stream); - * const dispatcher = connection.playBroadcast(broadcast); - * }) - * .catch(console.error); - */ - playStream(stream, options = {}) { - this.setVolume(options.volume || 1); - return this._playTranscodable(stream, options); - } - - /** - * Play the given file in the voice connection. - * @param {string} file The absolute path to the file - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // Play files natively - * const broadcast = client.createVoiceBroadcast(); - * - * voiceChannel.join() - * .then(connection => { - * broadcast.playFile('C:/Users/Discord/Desktop/music.mp3'); - * const dispatcher = connection.playBroadcast(broadcast); - * }) - * .catch(console.error); - */ - playFile(file, options = {}) { - this.setVolume(options.volume || 1); - return this._playTranscodable(`file:${file}`, options); - } - - _playTranscodable(media, options) { - this.killCurrentTranscoder(); - const transcoder = this.prism.transcode({ - type: 'ffmpeg', - media, - ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek || 0)]), - }); - /** - * Emitted whenever an error occurs. - * @event VoiceBroadcast#error - * @param {Error} error The error that occurred - */ - transcoder.once('error', e => { - if (this.listenerCount('error') > 0) this.emit('error', e); - /** - * Emitted whenever the VoiceBroadcast has any warnings. - * @event VoiceBroadcast#warn - * @param {string|Error} warning The warning that was raised - */ - else this.emit('warn', e); - }); - /** - * Emitted once the broadcast (the audio stream) ends. - * @event VoiceBroadcast#end - */ - transcoder.once('end', () => this.killCurrentTranscoder()); - this.currentTranscoder = { - transcoder, - options, - }; - transcoder.output.once('readable', () => this._startPlaying()); - return this; - } - - /** - * Plays a stream of 16-bit signed stereo PCM. - * @param {ReadableStream} stream The audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {VoiceBroadcast} - */ - playConvertedStream(stream, options = {}) { - this.killCurrentTranscoder(); - this.setVolume(options.volume || 1); - this.currentTranscoder = { options: { stream } }; - stream.once('readable', () => this._startPlaying()); - return this; - } - - /** - * Plays an Opus encoded stream. - * <warn>Note that inline volume is not compatible with this method.</warn> - * @param {ReadableStream} stream The Opus audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playOpusStream(stream) { - this.currentTranscoder = { options: { stream }, opus: true }; - stream.once('readable', () => this._startPlaying()); - return this; - } - - /** - * Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description) - * @param {string} input The arbitrary input - * @param {StreamOptions} [options] Options for playing the stream - * @returns {VoiceBroadcast} - */ - playArbitraryInput(input, options = {}) { - this.setVolume(options.volume || 1); - options.input = input; - return this._playTranscodable(input, options); - } - - /** - * Pauses the entire broadcast - all dispatchers also pause. - */ - pause() { - this.paused = true; - for (const container of this._dispatchers.values()) { - for (const dispatcher of container.values()) { - dispatcher.pause(); - } - } - } - - /** - * Resumes the entire broadcast - all dispatchers also resume. - */ - resume() { - this.paused = false; - for (const container of this._dispatchers.values()) { - for (const dispatcher of container.values()) { - dispatcher.resume(); - } - } - } - - _startPlaying() { - if (this.tickInterval) clearInterval(this.tickInterval); - // Old code? - // this.tickInterval = this.client.setInterval(this.tick.bind(this), 20); - this._startTime = Date.now(); - this._count = 0; - this._pausedTime = 0; - this._missed = 0; - this.tick(); - } - - tick() { - if (!this._playableStream) return; - if (this.paused) { - this._pausedTime += 20; - setTimeout(() => this.tick(), 20); - return; - } - - const opus = this.currentTranscoder.opus; - const buffer = this.readStreamBuffer(); - - if (!buffer) { - this._missed++; - if (this._missed < 5) { - this._pausedTime += 200; - setTimeout(() => this.tick(), 200); - } else { - this.killCurrentTranscoder(); - } - return; - } - - this._missed = 0; - - let packetMatrix = {}; - - const getOpusPacket = volume => { - if (packetMatrix[volume]) return packetMatrix[volume]; - - const opusEncoder = this._encoders.get(volume); - const opusPacket = opusEncoder.encode(this.applyVolume(buffer, this._volume * volume)); - packetMatrix[volume] = opusPacket; - return opusPacket; - }; - - for (const dispatcher of this.dispatchers) { - if (opus) { - dispatcher.processPacket(buffer); - continue; - } - - const volume = dispatcher.volume; - dispatcher.processPacket(getOpusPacket(volume)); - } - - const next = 20 + (this._startTime + this._pausedTime + (this._count * 20) - Date.now()); - this._count++; - setTimeout(() => this.tick(), next); - } - - readStreamBuffer() { - const opus = this.currentTranscoder.opus; - const bufferLength = (opus ? 80 : 1920) * 2; - let buffer = this._playableStream.read(bufferLength); - if (opus) return buffer; - if (!buffer) return null; - - if (buffer.length !== bufferLength) { - const newBuffer = Buffer.alloc(bufferLength).fill(0); - buffer.copy(newBuffer); - buffer = newBuffer; - } - - return buffer; - } - - /** - * Stop the current stream from playing without unsubscribing dispatchers. - */ - end() { - this.killCurrentTranscoder(); - } - - /** - * End the current broadcast, all subscribed dispatchers will also end. - */ - destroy() { - this.end(); - for (const container of this._dispatchers.values()) { - for (const dispatcher of container.values()) { - dispatcher.destroy('end', 'broadcast ended'); - } - } - } -} - -module.exports = VoiceBroadcast; 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 2fc6338..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceConnection.js +++ /dev/null @@ -1,598 +0,0 @@ -const VoiceWebSocket = require('./VoiceWebSocket'); -const VoiceUDP = require('./VoiceUDPClient'); -const Util = require('../../util/Util'); -const Constants = require('../../util/Constants'); -const AudioPlayer = require('./player/AudioPlayer'); -const VoiceReceiver = require('./receiver/VoiceReceiver'); -const SingleSilence = require('./util/SingleSilence'); -const EventEmitter = require('events').EventEmitter; -const Prism = require('prism-media'); - -// The delay between packets when a user is considered to have stopped speaking -// https://github.com/discordjs/discord.js/issues/3524#issuecomment-540373200 -const DISCORD_SPEAKING_DELAY = 250; - -/** - * Represents a connection to a guild's voice server. - * ```js - * // Obtained using: - * voiceChannel.join() - * .then(connection => { - * - * }); - * ``` - * @extends {EventEmitter} - */ -class VoiceConnection extends EventEmitter { - constructor(voiceManager, channel) { - super(); - - /** - * The voice manager that instantiated this connection - * @type {ClientVoiceManager} - */ - this.voiceManager = voiceManager; - - /** - * The client that instantiated this connection - * @type {Client} - */ - this.client = voiceManager.client; - - /** - * @external Prism - * @see {@link https://github.com/hydrabolt/prism-media} - */ - - /** - * The audio transcoder for this connection - * @type {Prism} - */ - this.prism = new Prism(); - - /** - * The voice channel this connection is currently serving - * @type {VoiceChannel} - */ - this.channel = channel; - - /** - * The current status of the voice connection - * @type {VoiceStatus} - */ - this.status = Constants.VoiceStatus.AUTHENTICATING; - - /** - * 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 = {}; - - /** - * 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); - }); - - /** - * Map SSRC to user id - * @type {Map<number, Snowflake>} - * @private - */ - this.ssrcMap = new Map(); - - /** - * Map user id to speaking timeout - * @type {Map<Snowflake, Timeout>} - * @private - */ - this.speakingTimeouts = new Map(); - - /** - * Object that wraps contains the `ws` and `udp` sockets of this voice connection - * @type {Object} - * @private - */ - this.sockets = {}; - - this.authenticate(); - } - - /** - * The current stream dispatcher (if any) - * @type {?StreamDispatcher} - * @readonly - */ - get dispatcher() { - return this.player.dispatcher; - } - - /** - * 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; - if (this.status !== Constants.VoiceStatus.CONNECTED) return; - this.speaking = value; - this.sockets.ws.sendPacket({ - op: Constants.VoiceOPCodes.SPEAKING, - d: { - speaking: true, - delay: 0, - }, - }).catch(e => { - this.emit('debug', e); - }); - } - - /** - * Sends a request to the main gateway to join a voice channel. - * @param {Object} [options] The options to provide - */ - sendVoiceStateUpdate(options = {}) { - options = Util.mergeDefault({ - guild_id: this.channel.guild.id, - channel_id: this.channel.id, - self_mute: false, - self_deaf: false, - }, options); - - this.client.ws.send({ - op: Constants.OPCodes.VOICE_STATE_UPDATE, - d: options, - }); - } - - /** - * Set the token and endpoint required to connect to the voice servers. - * @param {string} token The voice token - * @param {string} endpoint The voice endpoint - * @returns {void} - */ - setTokenAndEndpoint(token, endpoint) { - if (!endpoint) { - // Signifies awaiting endpoint stage - return; - } - - if (!token) { - this.authenticateFailed('Token not provided from voice server packet.'); - return; - } - - endpoint = endpoint.match(/([^:]*)/)[0]; - - if (!endpoint) { - this.authenticateFailed('Invalid endpoint received.'); - return; - } - - if (this.status === Constants.VoiceStatus.AUTHENTICATING) { - this.authentication.token = token; - this.authentication.endpoint = endpoint; - this.checkAuthenticated(); - } else if (token !== this.authentication.token || endpoint !== this.authentication.endpoint) { - this.reconnect(token, endpoint); - } - } - - /** - * Sets the Session ID for the connection. - * @param {string} sessionID The voice session ID - */ - setSessionID(sessionID) { - if (!sessionID) { - this.authenticateFailed('Session ID not supplied.'); - return; - } - - if (this.status === Constants.VoiceStatus.AUTHENTICATING) { - this.authentication.sessionID = sessionID; - this.checkAuthenticated(); - } else if (sessionID !== this.authentication.sessionID) { - this.authentication.sessionID = sessionID; - /** - * Emitted when a new session ID is received. - * @event VoiceConnection#newSession - * @private - */ - this.emit('newSession', sessionID); - } - } - - /** - * Checks whether the voice connection is authenticated. - * @private - */ - checkAuthenticated() { - const { token, endpoint, sessionID } = this.authentication; - - if (token && endpoint && sessionID) { - this.client.clearTimeout(this.connectTimeout); - this.status = Constants.VoiceStatus.CONNECTING; - /** - * Emitted when we successfully initiate a voice connection. - * @event VoiceConnection#authenticated - */ - this.emit('authenticated'); - this.connect(); - } - } - - /** - * Invoked when we fail to initiate a voice connection. - * @param {string} reason The reason for failure - * @private - */ - authenticateFailed(reason) { - this.client.clearTimeout(this.connectTimeout); - if (this.status === Constants.VoiceStatus.AUTHENTICATING) { - /** - * Emitted when we fail to initiate a voice connection. - * @event VoiceConnection#failed - * @param {Error} error The encountered error - */ - this.emit('failed', new Error(reason)); - } else { - /** - * Emitted whenever the connection encounters an error. - * @event VoiceConnection#error - * @param {Error} error The encountered error - */ - this.emit('error', new Error(reason)); - } - this.status = Constants.VoiceStatus.DISCONNECTED; - } - - /** - * Move to a different voice channel in the same guild. - * @param {VoiceChannel} channel The channel to move to - * @private - */ - updateChannel(channel) { - this.channel = channel; - this.sendVoiceStateUpdate(); - } - - /** - * Attempts to authenticate to the voice server. - * @private - */ - authenticate() { - this.sendVoiceStateUpdate(); - this.connectTimeout = this.client.setTimeout( - () => this.authenticateFailed(new Error('Connection not established within 15 seconds.')), 15000); - } - - /** - * Attempts to reconnect to the voice server (typically after a region change). - * @param {string} token The voice token - * @param {string} endpoint The voice endpoint - * @private - */ - reconnect(token, endpoint) { - this.authentication.token = token; - this.authentication.endpoint = endpoint; - - this.status = Constants.VoiceStatus.RECONNECTING; - /** - * Emitted when the voice connection is reconnecting (typically after a region change). - * @event VoiceConnection#reconnecting - */ - this.emit('reconnecting'); - this.connect(); - } - - /** - * Disconnect the voice connection, causing a disconnect and closing event to be emitted. - */ - disconnect() { - this.emit('closing'); - this.sendVoiceStateUpdate({ - channel_id: null, - }); - - this._disconnect(); - } - - /** - * Internally disconnects (doesn't send disconnect packet). - * @private - */ - _disconnect() { - this.player.destroy(); - this.cleanup(); - this.status = Constants.VoiceStatus.DISCONNECTED; - /** - * Emitted when the voice connection disconnects. - * @event VoiceConnection#disconnect - */ - this.emit('disconnect'); - } - - /** - * Cleans up after disconnect. - * @private - */ - cleanup() { - const { ws, udp } = this.sockets; - - if (ws) { - ws.removeAllListeners('error'); - ws.removeAllListeners('ready'); - ws.removeAllListeners('sessionDescription'); - ws.removeAllListeners('startSpeaking'); - ws.shutdown(); - } - - if (udp) udp.removeAllListeners('error'); - - this.sockets.ws = null; - this.sockets.udp = null; - } - - /** - * Connect the voice connection. - * @private - */ - connect() { - if (this.status !== Constants.VoiceStatus.RECONNECTING) { - 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.'); - } - - if (this.sockets.ws) this.sockets.ws.shutdown(); - if (this.sockets.udp) this.sockets.udp.shutdown(); - - this.sockets.ws = new VoiceWebSocket(this); - this.sockets.udp = new VoiceUDP(this); - - const { ws, udp } = this.sockets; - - ws.on('error', err => this.emit('error', err)); - udp.on('error', err => this.emit('error', err)); - ws.on('ready', this.onReady.bind(this)); - ws.on('sessionDescription', this.onSessionDescription.bind(this)); - ws.on('startSpeaking', this.onStartSpeaking.bind(this)); - } - - /** - * Invoked when the voice websocket is ready. - * @param {Object} data The received data - * @private - */ - onReady({ port, ssrc, ip }) { - this.authentication.port = port; - this.authentication.ssrc = ssrc; - this.sockets.udp.createUDPSocket(ip); - this.sockets.udp.socket.on('message', this.onUDPMessage.bind(this)); - } - - /** - * Invoked when a session description is received. - * @param {string} mode The encryption mode - * @param {string} secret The secret key - * @private - */ - onSessionDescription(mode, secret) { - this.authentication.encryptionMode = mode; - this.authentication.secretKey = secret; - - this.status = Constants.VoiceStatus.CONNECTED; - const ready = () => { - /** - * 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'); - }; - if (this.dispatcher) { - ready(); - } else { - // This serves to provide support for voice receive, sending audio is required to receive it. - this.playOpusStream(new SingleSilence()).once('end', ready); - } - } - - /** - * Invoked whenever a user initially starts speaking. - * @param {Object} data The speaking data - * @private - */ - onStartSpeaking({ user_id, ssrc }) { - this.ssrcMap.set(+ssrc, user_id); - } - - /** - * Invoked when a speaking event is received. - * @param {Object} data The received data - * @private - */ - onSpeaking({ user_id, speaking }) { - const guild = this.channel.guild; - const user = this.client.users.get(user_id); - if (!speaking) { - for (const receiver of this.receivers) { - receiver.stoppedSpeaking(user); - } - } - /** - * 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.status === Constants.VoiceStatus.CONNECTED) this.emit('speaking', user, speaking); - guild._memberSpeakUpdate(user_id, speaking); - } - - /** - * Handles synthesizing of the speaking event. - * @param {Buffer} buffer Received packet from the UDP socket - * @private - */ - onUDPMessage(buffer) { - const ssrc = +buffer.readUInt32BE(8).toString(10); - const user = this.client.users.get(this.ssrcMap.get(ssrc)); - if (!user) return; - - let speakingTimeout = this.speakingTimeouts.get(ssrc); - if (typeof speakingTimeout === 'undefined') { - this.onSpeaking({ user_id: user.id, ssrc, speaking: true }); - } else { - this.client.clearTimeout(speakingTimeout); - } - - speakingTimeout = this.client.setTimeout(() => { - try { - this.onSpeaking({ user_id: user.id, ssrc, speaking: false }); - this.client.clearTimeout(speakingTimeout); - this.speakingTimeouts.delete(ssrc); - } catch (ex) { - // Connection already closed, ignore - } - }, DISCORD_SPEAKING_DELAY); - this.speakingTimeouts.set(ssrc, speakingTimeout); - } - - /** - * 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 - * @property {number|string} [bitrate=48000] The bitrate (quality) of the audio. - * If set to 'auto', the voice channel's bitrate will be used - */ - - /** - * Play the given file in the voice connection. - * @param {string} file The absolute 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.player.playUnknownStream(`file:${file}`, options); - } - - /** - * Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description) - * @param {string} input the arbitrary input - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playArbitraryInput(input, options) { - return this.player.playUnknownStream(input, 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, options) { - return this.player.playUnknownStream(stream, options); - } - - /** - * Plays a stream of 16-bit signed stereo PCM. - * @param {ReadableStream} stream The audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playConvertedStream(stream, options) { - return this.player.playPCMStream(stream, options); - } - - /** - * Plays an Opus encoded stream. - * <warn>Note that inline volume is not compatible with this method.</warn> - * @param {ReadableStream} stream The Opus audio stream to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - */ - playOpusStream(stream, options) { - return this.player.playOpusStream(stream, options); - } - - /** - * Plays a voice broadcast. - * @param {VoiceBroadcast} broadcast The broadcast to play - * @param {StreamOptions} [options] Options for playing the stream - * @returns {StreamDispatcher} - * @example - * // Play a broadcast - * const broadcast = client - * .createVoiceBroadcast() - * .playFile('./test.mp3'); - * const dispatcher = voiceConnection.playBroadcast(broadcast); - */ - playBroadcast(broadcast, options) { - return this.player.playBroadcast(broadcast, 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 cf1e388..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceUDPClient.js +++ /dev/null @@ -1,127 +0,0 @@ -const udp = require('dgram'); -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) { - this.socket.removeAllListeners('message'); - try { - this.socket.close(); - } finally { - this.socket = null; - } - } - } - - /** - * The port of the Discord voice server - * @type {number} - * @readonly - */ - get discordPort() { - return this.voiceConnection.authentication.port; - } - - /** - * 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 = Buffer.alloc(70); - blankMessage.writeUIntBE(this.voiceConnection.authentication.ssrc, 0, 4); - this.send(blankMessage); - } -} - -function parseLocalPacket(message) { - try { - const packet = Buffer.from(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 2269007..0000000 --- a/node_modules/discord.js/src/client/voice/VoiceWebSocket.js +++ /dev/null @@ -1,246 +0,0 @@ -const Constants = require('../../util/Constants'); -const SecretKey = require('./util/SecretKey'); -const EventEmitter = require('events').EventEmitter; - -let WebSocket; -try { - WebSocket = require('@discordjs/uws'); -} catch (err) { - WebSocket = require('ws'); -} - -/** - * Represents a Voice Connection's WebSocket. - * @extends {EventEmitter} - * @private - */ -class VoiceWebSocket extends EventEmitter { - constructor(voiceConnection) { - super(); - - /** - * The client of this voice WebSocket - * @type {Client} - */ - this.client = voiceConnection.voiceManager.client; - - /** - * 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(); - } - - /** - * 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('debug', 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.sessionID, - }, - }).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#startSpeaking - */ - this.emit('startSpeaking', 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 77734ca..0000000 --- a/node_modules/discord.js/src/client/voice/dispatcher/StreamDispatcher.js +++ /dev/null @@ -1,331 +0,0 @@ -const VolumeInterface = require('../util/VolumeInterface'); -const VoiceBroadcast = require('../VoiceBroadcast'); -const Constants = require('../../../util/Constants'); - -const secretbox = require('../util/Secretbox'); - -const nonce = Buffer.alloc(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'); - * }); - * ``` - * @implements {VolumeInterface} - */ -class StreamDispatcher extends VolumeInterface { - constructor(player, stream, streamOptions) { - super(streamOptions); - /** - * The Audio Player that controls this dispatcher - * @type {AudioPlayer} - */ - this.player = player; - /** - * The stream that the dispatcher plays - * @type {ReadableStream|VoiceBroadcast} - */ - this.stream = stream; - if (!(this.stream instanceof VoiceBroadcast)) this.startStreaming(); - this.streamOptions = streamOptions; - - const data = this.streamingData; - data.length = 20; - data.missed = 0; - - /** - * Whether playing is paused - * @type {boolean} - */ - this.paused = false; - /** - * Whether this dispatcher has been destroyed - * @type {boolean} - */ - this.destroyed = false; - - this._opus = streamOptions.opus; - } - - /** - * 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} - * @readonly - */ - get passes() { - return this.streamOptions.passes || 1; - } - - set passes(n) { - this.streamOptions.passes = n; - } - - get streamingData() { - return this.player.streamingData; - } - - /** - * 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; - } - - /** - * 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.destroy('end', reason); - } - - setSpeaking(value) { - if (this.speaking === value) return; - if (this.player.voiceConnection.status !== Constants.VoiceStatus.CONNECTED) return; - 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); - } - - - /** - * Set the bitrate of the current Opus encoder. - * @param {number} bitrate New bitrate, in kbps - * If set to 'auto', the voice channel's bitrate will be used - */ - setBitrate(bitrate) { - this.player.setBitrate(bitrate); - } - - sendBuffer(buffer, sequence, timestamp, opusPacket) { - opusPacket = opusPacket || this.player.opusEncoder.encode(buffer); - const packet = this.createPacket(sequence, timestamp, opusPacket); - this.sendPacket(packet); - } - - sendPacket(packet) { - let repeats = this.passes; - /** - * Emitted whenever the dispatcher has debug information. - * @event StreamDispatcher#debug - * @param {string} info The debug info - */ - this.setSpeaking(true); - while (repeats-- && this.player.voiceConnection.sockets.udp) { - this.player.voiceConnection.sockets.udp.send(packet) - .catch(e => { - this.setSpeaking(false); - this.emit('debug', `Failed to send a packet ${e}`); - }); - } - } - - createPacket(sequence, timestamp, buffer) { - const packetBuffer = Buffer.alloc(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 = secretbox.methods.close(buffer, nonce, this.player.voiceConnection.authentication.secretKey.key); - for (let i = 0; i < buffer.length; i++) packetBuffer[i + 12] = buffer[i]; - - return packetBuffer; - } - - processPacket(packet) { - try { - if (this.destroyed || !this.player.voiceConnection.authentication.secretKey) { - this.setSpeaking(false); - return; - } - - const data = this.streamingData; - - if (this.paused) { - this.setSpeaking(false); - data.pausedTime = data.length * 10; - return; - } - - if (!packet) { - data.missed++; - data.pausedTime += data.length * 10; - return; - } - - this.started(); - this.missed = 0; - - this.stepStreamingData(); - this.sendBuffer(null, data.sequence, data.timestamp, packet); - } catch (e) { - this.destroy('error', e); - } - } - - process() { - try { - if (this.destroyed) { - this.setSpeaking(false); - return; - } - - const data = this.streamingData; - - if (data.missed >= 5) { - this.destroy('end', 'Stream is not generating quickly enough.'); - return; - } - - if (this.paused) { - this.setSpeaking(false); - // Old code? - // data.timestamp = data.timestamp + 4294967295 ? data.timestamp + 960 : 0; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this.process(), data.length * 10); - return; - } - - this.started(); - - const buffer = this.readStreamBuffer(); - if (!buffer) { - data.missed++; - data.pausedTime += data.length * 10; - this.player.voiceConnection.voiceManager.client.setTimeout(() => this.process(), data.length * 10); - return; - } - - data.missed = 0; - - this.stepStreamingData(); - - if (this._opus) { - this.sendBuffer(null, data.sequence, data.timestamp, buffer); - } else { - 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.process(), nextTime); - } catch (e) { - this.destroy('error', e); - } - } - - readStreamBuffer() { - const data = this.streamingData; - const bufferLength = (this._opus ? 80 : 1920) * data.channels; - let buffer = this.stream.read(bufferLength); - if (this._opus) return buffer; - if (!buffer) return null; - - if (buffer.length !== bufferLength) { - const newBuffer = Buffer.alloc(bufferLength).fill(0); - buffer.copy(newBuffer); - buffer = newBuffer; - } - - buffer = this.applyVolume(buffer); - return buffer; - } - - started() { - const data = this.streamingData; - - if (!data.startTime) { - /** - * Emitted once the dispatcher starts streaming. - * @event StreamDispatcher#start - */ - this.emit('start'); - data.startTime = Date.now(); - } - } - - stepStreamingData() { - const data = this.streamingData; - data.count++; - data.sequence = data.sequence < 65535 ? data.sequence + 1 : 0; - data.timestamp = (data.timestamp + 960) < 4294967295 ? data.timestamp + 960 : 0; - } - - destroy(type, reason) { - if (this.destroyed) return; - this.destroyed = true; - this.setSpeaking(false); - this.emit(type, reason); - /** - * Emitted once the dispatcher ends. - * @param {string} [reason] The reason the dispatcher ended - * @event StreamDispatcher#end - */ - if (type !== 'end') this.emit('end', `destroyed due to ${type} - ${reason}`); - } - - startStreaming() { - if (!this.stream) { - /** - * Emitted if the dispatcher encounters an error. - * @event StreamDispatcher#error - * @param {string} error The error message - */ - this.emit('error', 'No stream'); - return; - } - - this.stream.on('end', err => this.destroy('end', err || 'stream')); - this.stream.on('error', err => this.destroy('error', err)); - - const data = this.streamingData; - data.length = 20; - data.missed = 0; - - this.stream.once('readable', () => { - data.startTime = null; - data.count = 0; - this.process(); - }); - } - - setPaused(paused) { this.setSpeaking(!(this.paused = paused)); } -} - -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 a510449..0000000 --- a/node_modules/discord.js/src/client/voice/opus/BaseOpusEngine.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * The base opus encoding engine. - * @private - */ -class BaseOpus { - /** - * @param {Object} [options] The options to apply to the Opus engine - * @param {number} [options.bitrate=48] The desired bitrate (kbps) - * @param {boolean} [options.fec=false] Whether to enable forward error correction - * @param {number} [options.plp=0] The expected packet loss percentage - */ - constructor({ bitrate = 48, fec = false, plp = 0 } = {}) { - this.ctl = { - BITRATE: 4002, - FEC: 4012, - PLP: 4014, - }; - - this.samplingRate = 48000; - this.channels = 2; - - /** - * The desired bitrate (kbps) - * @type {number} - */ - this.bitrate = bitrate; - - /** - * Miscellaneous Opus options - * @type {Object} - */ - this.options = { fec, plp }; - } - - init() { - try { - this.setBitrate(this.bitrate); - - // Set FEC (forward error correction) - if (this.options.fec) this.setFEC(this.options.fec); - - // Set PLP (expected packet loss percentage) - if (this.options.plp) this.setPLP(this.options.plp); - } catch (err) { - // Opus engine likely has no support for libopus CTL - } - } - - encode(buffer) { - return buffer; - } - - decode(buffer) { - return buffer; - } - - destroy() {} // eslint-disable-line no-empty-function -} - -module.exports = BaseOpus; diff --git a/node_modules/discord.js/src/client/voice/opus/DiscordJsOpusEngine.js b/node_modules/discord.js/src/client/voice/opus/DiscordJsOpusEngine.js deleted file mode 100644 index a3759c2..0000000 --- a/node_modules/discord.js/src/client/voice/opus/DiscordJsOpusEngine.js +++ /dev/null @@ -1,34 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -class DiscordJsOpusEngine extends OpusEngine { - constructor(player) { - super(player); - const opus = require('@discordjs/opus'); - this.encoder = new opus.OpusEncoder(this.samplingRate, this.channels); - super.init(); - } - - setBitrate(bitrate) { - this.encoder.setBitrate(Math.min(128, Math.max(16, bitrate)) * 1000); - } - - setFEC(enabled) { - this.encoder.applyEncoderCTL(this.ctl.FEC, enabled ? 1 : 0); - } - - setPLP(percent) { - this.encoder.applyEncoderCTL(this.ctl.PLP, Math.min(100, Math.max(0, percent * 100))); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 1920); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer, 1920); - } -} - -module.exports = DiscordJsOpusEngine; 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 a9ffc55..0000000 --- a/node_modules/discord.js/src/client/voice/opus/NodeOpusEngine.js +++ /dev/null @@ -1,34 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -class NodeOpusEngine extends OpusEngine { - constructor(player) { - super(player); - const opus = require('node-opus'); - this.encoder = new opus.OpusEncoder(this.samplingRate, this.channels); - super.init(); - } - - setBitrate(bitrate) { - this.encoder.applyEncoderCTL(this.ctl.BITRATE, Math.min(128, Math.max(16, bitrate)) * 1000); - } - - setFEC(enabled) { - this.encoder.applyEncoderCTL(this.ctl.FEC, enabled ? 1 : 0); - } - - setPLP(percent) { - this.encoder.applyEncoderCTL(this.ctl.PLP, Math.min(100, Math.max(0, percent * 100))); - } - - 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 cf63fbc..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js +++ /dev/null @@ -1,29 +0,0 @@ -const list = [ - require('./DiscordJsOpusEngine'), - require('./NodeOpusEngine'), - require('./OpusScriptEngine'), -]; - -function fetch(Encoder, engineOptions) { - try { - return new Encoder(engineOptions); - } catch (err) { - if (err.message.includes('Cannot find module')) return null; - - // The Opus engine exists, but another error occurred. - throw err; - } -} - -exports.add = encoder => { - list.push(encoder); -}; - -exports.fetch = engineOptions => { - for (const encoder of list) { - const fetched = fetch(encoder, engineOptions); - 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 271a068..0000000 --- a/node_modules/discord.js/src/client/voice/opus/OpusScriptEngine.js +++ /dev/null @@ -1,39 +0,0 @@ -const OpusEngine = require('./BaseOpusEngine'); - -class OpusScriptEngine extends OpusEngine { - constructor(player) { - super(player); - const OpusScript = require('opusscript'); - this.encoder = new OpusScript(this.samplingRate, this.channels); - super.init(); - } - - setBitrate(bitrate) { - this.encoder.encoderCTL(this.ctl.BITRATE, Math.min(128, Math.max(16, bitrate)) * 1000); - } - - setFEC(enabled) { - this.encoder.encoderCTL(this.ctl.FEC, enabled ? 1 : 0); - } - - setPLP(percent) { - this.encoder.encoderCTL(this.ctl.PLP, Math.min(100, Math.max(0, percent * 100))); - } - - encode(buffer) { - super.encode(buffer); - return this.encoder.encode(buffer, 960); - } - - decode(buffer) { - super.decode(buffer); - return this.encoder.decode(buffer); - } - - destroy() { - super.destroy(); - this.encoder.delete(); - } -} - -module.exports = OpusScriptEngine; 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 9b30c85..0000000 --- a/node_modules/discord.js/src/client/voice/player/AudioPlayer.js +++ /dev/null @@ -1,170 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const Prism = require('prism-media'); -const StreamDispatcher = require('../dispatcher/StreamDispatcher'); -const Collection = require('../../../util/Collection'); -const OpusEncoders = require('../opus/OpusEngineList'); - -const ffmpegArguments = [ - '-analyzeduration', '0', - '-loglevel', '0', - '-f', 's16le', - '-ar', '48000', - '-ac', '2', -]; - -/** - * An Audio Player for a Voice Connection. - * @private - * @extends {EventEmitter} - */ -class AudioPlayer extends EventEmitter { - constructor(voiceConnection) { - super(); - /** - * The voice connection that the player serves - * @type {VoiceConnection} - */ - this.voiceConnection = voiceConnection; - /** - * The prism transcoder that the player uses - * @type {Prism} - */ - this.prism = new Prism(); - this.streams = new Collection(); - this.currentStream = {}; - this.streamingData = { - channels: 2, - count: 0, - sequence: 0, - timestamp: 0, - pausedTime: 0, - }; - this.voiceConnection.once('closing', () => this.destroyCurrentStream()); - } - - /** - * The current transcoder - * @type {?Object} - * @readonly - */ - get transcoder() { - return this.currentStream.transcoder; - } - - /** - * The current dispatcher - * @type {?StreamDispatcher} - * @readonly - */ - get dispatcher() { - return this.currentStream.dispatcher; - } - - destroy() { - if (this.opusEncoder) this.opusEncoder.destroy(); - this.opusEncoder = null; - } - - destroyCurrentStream() { - const transcoder = this.transcoder; - const dispatcher = this.dispatcher; - if (transcoder) transcoder.kill(); - if (dispatcher) { - const end = dispatcher.listeners('end')[0]; - const error = dispatcher.listeners('error')[0]; - if (end) dispatcher.removeListener('end', end); - if (error) dispatcher.removeListener('error', error); - dispatcher.destroy('end'); - } - this.currentStream = {}; - } - - /** - * Set the bitrate of the current Opus encoder. - * @param {number} value New bitrate, in kbps - * If set to 'auto', the voice channel's bitrate will be used - */ - setBitrate(value) { - if (!value) return; - if (!this.opusEncoder) return; - const bitrate = value === 'auto' ? this.voiceConnection.channel.bitrate : value; - this.opusEncoder.setBitrate(bitrate); - } - - playUnknownStream(stream, options = {}) { - this.destroy(); - this.opusEncoder = OpusEncoders.fetch(options); - const transcoder = this.prism.transcode({ - type: 'ffmpeg', - media: stream, - ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek || 0)]), - }); - this.destroyCurrentStream(); - this.currentStream = { - transcoder: transcoder, - output: transcoder.output, - input: stream, - }; - transcoder.on('error', e => { - this.destroyCurrentStream(); - if (this.listenerCount('error') > 0) this.emit('error', e); - this.emit('warn', `prism transcoder error - ${e}`); - }); - return this.playPCMStream(transcoder.output, options, true); - } - - playPCMStream(stream, options = {}, fromUnknown = false) { - this.destroy(); - this.opusEncoder = OpusEncoders.fetch(options); - this.setBitrate(options.bitrate); - const dispatcher = this.createDispatcher(stream, options); - if (fromUnknown) { - this.currentStream.dispatcher = dispatcher; - } else { - this.destroyCurrentStream(); - this.currentStream = { - dispatcher, - input: stream, - output: stream, - }; - } - return dispatcher; - } - - playOpusStream(stream, options = {}) { - options.opus = true; - this.destroyCurrentStream(); - const dispatcher = this.createDispatcher(stream, options); - this.currentStream = { - dispatcher, - input: stream, - output: stream, - }; - return dispatcher; - } - - playBroadcast(broadcast, options) { - this.destroyCurrentStream(); - const dispatcher = this.createDispatcher(broadcast, options); - this.currentStream = { - dispatcher, - broadcast, - input: broadcast, - output: broadcast, - }; - broadcast.registerDispatcher(dispatcher); - return dispatcher; - } - - createDispatcher(stream, { seek = 0, volume = 1, passes = 1, opus } = {}) { - const options = { seek, volume, passes, opus }; - - const dispatcher = new StreamDispatcher(this, stream, options); - dispatcher.on('end', () => this.destroyCurrentStream()); - dispatcher.on('error', () => this.destroyCurrentStream()); - dispatcher.on('speaking', value => this.voiceConnection.setSpeaking(value)); - return dispatcher; - } -} - -module.exports = AudioPlayer; 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 d349428..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReadable.js +++ /dev/null @@ -1,17 +0,0 @@ -const Readable = require('stream').Readable; - -class VoiceReadable extends Readable { - constructor() { - super(); - this._packets = []; - this.open = true; - } - - _read() {} // eslint-disable-line no-empty-function - - _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 e37b273..0000000 --- a/node_modules/discord.js/src/client/voice/receiver/VoiceReceiver.js +++ /dev/null @@ -1,220 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const secretbox = require('../util/Secretbox'); -const Readable = require('./VoiceReadable'); -const OpusEncoders = require('../opus/OpusEngineList'); - -const nonce = Buffer.alloc(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(); - this.opusEncoders = 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 = connection.client.users.get(connection.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; - } - - /** - * Destroy this VoiceReceiver, also ending any streams that it may be controlling. - */ - destroy() { - this.voiceConnection.sockets.udp.socket.removeListener('message', this._listener); - for (const [id, stream] of this.pcmStreams) { - stream._push(null); - this.pcmStreams.delete(id); - } - for (const [id, stream] of this.opusStreams) { - stream._push(null); - this.opusStreams.delete(id); - } - for (const [id, encoder] of this.opusEncoders) { - encoder.destroy(); - this.opusEncoders.delete(id); - } - this.destroyed = true; - } - - /** - * Invoked when a user stops speaking. - * @param {User} user The user that stopped speaking - * @private - */ - stoppedSpeaking(user) { - const opusStream = this.opusStreams.get(user.id); - const pcmStream = this.pcmStreams.get(user.id); - const opusEncoder = this.opusEncoders.get(user.id); - if (opusStream) { - opusStream.push(null); - opusStream.open = false; - this.opusStreams.delete(user.id); - } - if (pcmStream) { - pcmStream.push(null); - pcmStream.open = false; - this.pcmStreams.delete(user.id); - } - if (opusEncoder) { - opusEncoder.destroy(); - this.opusEncoders.delete(user.id); - } - } - - /** - * 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 16-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 = secretbox.methods.open(msg.slice(12), nonce, this.voiceConnection.authentication.secretKey.key); - if (!data) { - /** - * Emitted whenever a voice packet experiences a problem. - * @event VoiceReceiver#warn - * @param {string} reason The reason for the warning. If it happened because the voice packet could not be - * decrypted, this would be `decrypt`. If it happened because the voice packet could not be decoded into - * PCM, this would be `decode` - * @param {string} message The warning message - */ - this.emit('warn', 'decrypt', 'Failed to decrypt voice packet'); - return; - } - data = Buffer.from(data); - - // Strip RTP Header Extensions (one-byte only) - if (data[0] === 0xBE && data[1] === 0xDE && data.length > 4) { - const headerExtensionLength = data.readUInt16BE(2); - let offset = 4; - for (let i = 0; i < headerExtensionLength; i++) { - const byte = data[offset]; - offset++; - if (byte === 0) { - continue; - } - offset += 1 + (0b1111 & (byte >> 4)); - } - // Skip over undocumented Discord byte - offset++; - - data = data.slice(offset); - } - - 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) { - if (!this.opusEncoders.get(user.id)) this.opusEncoders.set(user.id, OpusEncoders.fetch()); - const { pcm, error } = VoiceReceiver._tryDecode(this.opusEncoders.get(user.id), data); - if (error) { - this.emit('warn', 'decode', `Failed to decode packet voice to PCM because: ${error.message}`); - return; - } - if (this.pcmStreams.get(user.id)) this.pcmStreams.get(user.id)._push(pcm); - /** - * 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 - */ - this.emit('pcm', user, pcm); - } - } - - static _tryDecode(encoder, data) { - try { - return { pcm: encoder.decode(data) }; - } catch (error) { - return { error }; - } - } -} - -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 670e9e5..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 of Object.keys(key)) this.key[index] = key[index]; - } -} - -module.exports = SecretKey; diff --git a/node_modules/discord.js/src/client/voice/util/Secretbox.js b/node_modules/discord.js/src/client/voice/util/Secretbox.js deleted file mode 100644 index a833d51..0000000 --- a/node_modules/discord.js/src/client/voice/util/Secretbox.js +++ /dev/null @@ -1,33 +0,0 @@ -const libs = { - sodium: sodium => ({ - open: sodium.api.crypto_secretbox_open_easy, - close: sodium.api.crypto_secretbox_easy, - }), - 'libsodium-wrappers': sodium => ({ - open: sodium.crypto_secretbox_open_easy, - close: sodium.crypto_secretbox_easy, - }), - tweetnacl: tweetnacl => ({ - open: tweetnacl.secretbox.open, - close: tweetnacl.secretbox, - }), -}; - -exports.methods = {}; - -for (const libName of Object.keys(libs)) { - try { - const lib = require(libName); - if (libName === 'libsodium-wrappers' && lib.ready) { - lib.ready.then(() => { - exports.methods = libs[libName](lib); - }).catch(() => { - const tweetnacl = require('tweetnacl'); - exports.methods = libs.tweetnacl(tweetnacl); - }).catch(() => undefined); - } else { - exports.methods = libs[libName](lib); - } - break; - } catch (err) {} // eslint-disable-line no-empty -} diff --git a/node_modules/discord.js/src/client/voice/util/Silence.js b/node_modules/discord.js/src/client/voice/util/Silence.js deleted file mode 100644 index 239ceb4..0000000 --- a/node_modules/discord.js/src/client/voice/util/Silence.js +++ /dev/null @@ -1,16 +0,0 @@ -const { Readable } = require('stream'); - -const SILENCE_FRAME = Buffer.from([0xF8, 0xFF, 0xFE]); - -/** - * A readable emitting silent opus frames. - * @extends {Readable} - * @private - */ -class Silence extends Readable { - _read() { - this.push(SILENCE_FRAME); - } -} - -module.exports = Silence; diff --git a/node_modules/discord.js/src/client/voice/util/SingleSilence.js b/node_modules/discord.js/src/client/voice/util/SingleSilence.js deleted file mode 100644 index b59341e..0000000 --- a/node_modules/discord.js/src/client/voice/util/SingleSilence.js +++ /dev/null @@ -1,17 +0,0 @@ -const Silence = require('./Silence'); - -/** - * Only emits a single silent opus frame. - * This is used as a workaround for Discord now requiring - * silence to be sent before being able to receive audio. - * @extends {Silence} - * @private - */ -class SingleSilence extends Silence { - _read() { - super._read(); - this.push(null); - } -} - -module.exports = SingleSilence; diff --git a/node_modules/discord.js/src/client/voice/util/VolumeInterface.js b/node_modules/discord.js/src/client/voice/util/VolumeInterface.js deleted file mode 100644 index 62e6da5..0000000 --- a/node_modules/discord.js/src/client/voice/util/VolumeInterface.js +++ /dev/null @@ -1,86 +0,0 @@ -const EventEmitter = require('events'); - -/** - * An interface class for volume transformation. - * @extends {EventEmitter} - */ -class VolumeInterface extends EventEmitter { - constructor({ volume = 1 } = {}) { - super(); - this.setVolume(volume); - } - - /** - * The current volume of the broadcast - * @readonly - * @type {number} - */ - get volume() { - return this._volume; - } - - /** - * The current volume of the broadcast in decibels - * @readonly - * @type {number} - */ - get volumeDecibels() { - return Math.log10(this._volume) * 20; - } - - /** - * The current volume of the broadcast from a logarithmic scale - * @readonly - * @type {number} - */ - get volumeLogarithmic() { - return Math.pow(this._volume, 1 / 1.660964); - } - - applyVolume(buffer, volume) { - volume = volume || this._volume; - if (volume === 1) return buffer; - - const out = Buffer.alloc(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(volume * buffer.readInt16LE(i)))); - out.writeInt16LE(uint, i); - } - - return out; - } - - /** - * 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) { - /** - * Emitted when the volume of this interface changes. - * @event VolumeInterface#volumeChange - * @param {number} oldVolume The old volume of this interface - * @param {number} newVolume The new volume of this interface - */ - this.emit('volumeChange', this._volume, volume); - this._volume = volume; - } - - /** - * Set the volume in decibels. - * @param {number} db The decibels - */ - setVolumeDecibels(db) { - this.setVolume(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.setVolume(Math.pow(value, 1.660964)); - } -} - -module.exports = VolumeInterface; diff --git a/node_modules/discord.js/src/client/websocket/WebSocketConnection.js b/node_modules/discord.js/src/client/websocket/WebSocketConnection.js deleted file mode 100644 index 4ea078b..0000000 --- a/node_modules/discord.js/src/client/websocket/WebSocketConnection.js +++ /dev/null @@ -1,509 +0,0 @@ -const browser = typeof window !== 'undefined'; -const EventEmitter = require('events'); -const Constants = require('../../util/Constants'); -const zlib = require('zlib'); -const PacketManager = require('./packets/WebSocketPacketManager'); -const erlpack = (function findErlpack() { - try { - const e = require('erlpack'); - if (!e.pack) return null; - return e; - } catch (e) { - return null; - } -}()); - -const WebSocket = (function findWebSocket() { - if (browser) return window.WebSocket; // eslint-disable-line no-undef - try { - const uws = require('@discordjs/uws'); - process.emitWarning('uws support is being removed in the next version of discord.js', - 'DeprecationWarning', findWebSocket); - return uws; - } catch (e) { - return require('ws'); - } -}()); - -/** - * Abstracts a WebSocket connection with decoding/encoding for the Discord gateway. - * @private - */ -class WebSocketConnection extends EventEmitter { - /** - * @param {WebSocketManager} manager The WebSocket manager - * @param {string} gateway The WebSocket gateway to connect to - */ - constructor(manager, gateway) { - super(); - /** - * The WebSocket Manager of this connection - * @type {WebSocketManager} - */ - this.manager = manager; - - /** - * The client this belongs to - * @type {Client} - */ - this.client = manager.client; - - /** - * The WebSocket connection itself - * @type {WebSocket} - */ - this.ws = null; - - /** - * The current sequence of the WebSocket - * @type {number} - */ - this.sequence = -1; - - /** - * The current status of the client - * @type {Status} - */ - this.status = Constants.Status.IDLE; - - /** - * The Packet Manager of the connection - * @type {WebSocketPacketManager} - */ - this.packetManager = new PacketManager(this); - - /** - * The last time a ping was sent (a timestamp) - * @type {number} - */ - this.lastPingTimestamp = 0; - - /** - * Contains the rate limit queue and metadata - * @type {Object} - */ - this.ratelimit = { - queue: [], - remaining: 120, - total: 120, - time: 60e3, - resetTimer: null, - }; - this.connect(gateway); - - /** - * Events that are disabled (will not be processed) - * @type {Object} - */ - this.disabledEvents = {}; - - /** - * The sequence on WebSocket close - * @type {number} - */ - this.closeSequence = 0; - - /** - * Whether or not the WebSocket is expecting to be closed - * @type {boolean} - */ - this.expectingClose = false; - for (const event of this.client.options.disabledEvents) this.disabledEvents[event] = true; - } - - /** - * Causes the client to be marked as ready and emits the ready event. - * @returns {void} - */ - triggerReady() { - if (this.status === Constants.Status.READY) { - this.debug('Tried to mark self as ready, but already ready'); - return; - } - /** - * 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(); - } - - /** - * Checks whether the client is ready to be marked as ready. - * @returns {void} - */ - checkIfReady() { - if (this.status === Constants.Status.READY || this.status === Constants.Status.NEARLY) return false; - let unavailableGuilds = 0; - for (const guild of this.client.guilds.values()) { - if (!guild.available) unavailableGuilds++; - } - if (unavailableGuilds === 0) { - this.status = Constants.Status.NEARLY; - if (!this.client.options.fetchAllMembers) return this.triggerReady(); - // Fetch all members before marking self as ready - const promises = this.client.guilds.map(g => g.fetchMembers()); - Promise.all(promises) - .then(() => this.triggerReady()) - .catch(e => { - this.debug(`Failed to fetch all members before ready! ${e}`); - this.triggerReady(); - }); - } - return true; - } - - // Util - /** - * Emits a debug message. - * @param {string} message Debug message - * @returns {void} - */ - debug(message) { - if (message instanceof Error) message = message.stack; - return this.manager.debug(`[connection] ${message}`); - } - - /** - * Attempts to serialise data from the WebSocket. - * @param {string|Object} data Data to unpack - * @returns {Object} - */ - unpack(data) { - if (data instanceof ArrayBuffer) data = Buffer.from(new Uint8Array(data)); - - if (erlpack && typeof data !== 'string') return erlpack.unpack(data); - else if (data instanceof Buffer) data = zlib.inflateSync(data).toString(); - - return JSON.parse(data); - } - - /** - * Packs an object ready to be sent. - * @param {Object} data Data to pack - * @returns {string|Buffer} - */ - pack(data) { - return erlpack ? erlpack.pack(data) : JSON.stringify(data); - } - - /** - * Processes the current WebSocket queue. - */ - processQueue() { - if (this.ratelimit.remaining === 0) return; - if (this.ratelimit.queue.length === 0) return; - if (this.ratelimit.remaining === this.ratelimit.total) { - this.ratelimit.resetTimer = this.client.setTimeout(() => { - this.ratelimit.remaining = this.ratelimit.total; - this.processQueue(); - }, this.ratelimit.time); - } - while (this.ratelimit.remaining > 0) { - const item = this.ratelimit.queue.shift(); - if (!item) return; - this._send(item); - this.ratelimit.remaining--; - } - } - - /** - * Sends data, bypassing the queue. - * @param {Object} data Packet to send - * @returns {void} - */ - _send(data) { - if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { - this.debug(`Tried to send packet ${JSON.stringify(data)} but no WebSocket is available!`); - return; - } - this.ws.send(this.pack(data)); - } - - /** - * Adds data to the queue to be sent. - * @param {Object} data Packet to send - * @returns {void} - */ - send(data) { - if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { - this.debug(`Tried to send packet ${JSON.stringify(data)} but no WebSocket is available!`); - return; - } - this.ratelimit.queue.push(data); - this.processQueue(); - } - - /** - * Creates a connection to a gateway. - * @param {string} gateway The gateway to connect to - * @param {number} [after=0] How long to wait before connecting - * @param {boolean} [force=false] Whether or not to force a new connection even if one already exists - * @returns {boolean} - */ - connect(gateway = this.gateway, after = 0, force = false) { - if (after) return this.client.setTimeout(() => this.connect(gateway, 0, force), after); // eslint-disable-line - if (this.ws && !force) { - this.debug('WebSocket connection already exists'); - return false; - } else if (typeof gateway !== 'string') { - this.debug(`Tried to connect to an invalid gateway: ${gateway}`); - return false; - } - this.expectingClose = false; - this.gateway = gateway; - this.debug(`Connecting to ${gateway}`); - const ws = this.ws = new WebSocket(gateway); - if (browser) ws.binaryType = 'arraybuffer'; - ws.onmessage = this.onMessage.bind(this); - ws.onopen = this.onOpen.bind(this); - ws.onerror = this.onError.bind(this); - ws.onclose = this.onClose.bind(this); - this.status = Constants.Status.CONNECTING; - return true; - } - - /** - * Destroys the connection. - * @returns {boolean} - */ - destroy() { - const ws = this.ws; - if (!ws) { - this.debug('Attempted to destroy WebSocket but no connection exists!'); - return false; - } - this.heartbeat(-1); - this.expectingClose = true; - ws.close(1000); - this.packetManager.handleQueue(); - this.ws = null; - this.status = Constants.Status.DISCONNECTED; - this.ratelimit.remaining = this.ratelimit.total; - return true; - } - - /** - * Called whenever a message is received. - * @param {Event} event Event received - * @returns {boolean} - */ - onMessage(event) { - let data; - try { - data = this.unpack(event.data); - } catch (err) { - this.emit('debug', err); - } - return this.onPacket(data); - } - - /** - * Sets the current sequence of the connection. - * @param {number} s New sequence - */ - setSequence(s) { - this.sequence = s > this.sequence ? s : this.sequence; - } - - /** - * Called whenever a packet is received. - * @param {Object} packet Received packet - * @returns {boolean} - */ - onPacket(packet) { - if (!packet) { - this.debug('Received null packet'); - return false; - } - this.client.emit('raw', packet); - switch (packet.op) { - case Constants.OPCodes.HELLO: - return this.heartbeat(packet.d.heartbeat_interval); - case Constants.OPCodes.RECONNECT: - return this.reconnect(); - case Constants.OPCodes.INVALID_SESSION: - if (!packet.d) this.sessionID = null; - this.sequence = -1; - this.debug('Session invalidated -- will identify with a new session'); - return this.identify(packet.d ? 2500 : 0); - case Constants.OPCodes.HEARTBEAT_ACK: - return this.ackHeartbeat(); - case Constants.OPCodes.HEARTBEAT: - return this.heartbeat(); - default: - return this.packetManager.handle(packet); - } - } - - /** - * Called whenever a connection is opened to the gateway. - * @param {Event} event Received open event - */ - onOpen(event) { - if (event && event.target && event.target.url) this.gateway = event.target.url; - this.debug(`Connected to gateway ${this.gateway}`); - this.identify(); - } - - /** - * Causes a reconnection to the gateway. - */ - reconnect() { - this.debug('Attemping to reconnect in 5500ms...'); - /** - * Emitted whenever the client tries to reconnect to the WebSocket. - * @event Client#reconnecting - */ - this.client.emit(Constants.Events.RECONNECTING); - this.connect(this.gateway, 5500, true); - } - - /** - * Called whenever an error occurs with the WebSocket. - * @param {Error} error The error that occurred - */ - onError(error) { - if (error && error.message === 'uWs client connection error') { - this.reconnect(); - return; - } - /** - * Emitted whenever the client's WebSocket encounters a connection error. - * @event Client#error - * @param {Error} error The encountered error - */ - this.client.emit(Constants.Events.ERROR, error); - } - - /** - * @external CloseEvent - * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent} - */ - - /** - * Called whenever a connection to the gateway is closed. - * @param {CloseEvent} event Close event that was received - */ - onClose(event) { - this.debug(`${this.expectingClose ? 'Client' : 'Server'} closed the WebSocket connection: ${event.code}`); - this.closeSequence = this.sequence; - // Reset the state before trying to fix anything - this.emit('close', event); - this.heartbeat(-1); - // Should we reconnect? - if (event.code === 1000 ? this.expectingClose : Constants.WSCodes[event.code]) { - this.expectingClose = false; - /** - * Emitted when the client's WebSocket disconnects and will no longer attempt to reconnect. - * @event Client#disconnect - * @param {CloseEvent} event The WebSocket close event - */ - this.client.emit(Constants.Events.DISCONNECT, event); - this.debug(Constants.WSCodes[event.code]); - this.destroy(); - return; - } - this.expectingClose = false; - this.reconnect(); - } - - // Heartbeat - /** - * Acknowledges a heartbeat. - */ - ackHeartbeat() { - this.debug(`Heartbeat acknowledged, latency of ${Date.now() - this.lastPingTimestamp}ms`); - this.client._pong(this.lastPingTimestamp); - } - - /** - * Sends a heartbeat or sets an interval for sending heartbeats. - * @param {number} [time] If -1, clears the interval, any other number sets an interval - * If no value is given, a heartbeat will be sent instantly - */ - heartbeat(time) { - if (!isNaN(time)) { - if (time === -1) { - this.debug('Clearing heartbeat interval'); - this.client.clearInterval(this.heartbeatInterval); - this.heartbeatInterval = null; - } else { - this.debug(`Setting a heartbeat interval for ${time}ms`); - this.heartbeatInterval = this.client.setInterval(() => this.heartbeat(), time); - } - return; - } - this.debug('Sending a heartbeat'); - this.lastPingTimestamp = Date.now(); - this.send({ - op: Constants.OPCodes.HEARTBEAT, - d: this.sequence, - }); - } - - // Identification - /** - * Identifies the client on a connection. - * @param {number} [after] How long to wait before identifying - * @returns {void} - */ - identify(after) { - if (after) return this.client.setTimeout(this.identify.bind(this), after); - return this.sessionID ? this.identifyResume() : this.identifyNew(); - } - - /** - * Identifies as a new connection on the gateway. - * @returns {void} - */ - identifyNew() { - if (!this.client.token) { - this.debug('No token available to identify a new session with'); - return; - } - // Clone the generic payload and assign the token - const d = Object.assign({ token: this.client.token }, this.client.options.ws); - - // Sharding stuff - const { shardId, shardCount } = this.client.options; - if (shardCount > 0) d.shard = [Number(shardId), Number(shardCount)]; - - // Send the payload - this.debug('Identifying as a new session'); - this.send({ op: Constants.OPCodes.IDENTIFY, d }); - } - - /** - * Resumes a session on the gateway. - * @returns {void} - */ - identifyResume() { - if (!this.sessionID) { - this.debug('Warning: wanted to resume but session ID not available; identifying as a new session instead'); - return this.identifyNew(); - } - this.debug(`Attempting to resume session ${this.sessionID}`); - - const d = { - token: this.client.token, - session_id: this.sessionID, - seq: this.sequence, - }; - - return this.send({ - op: Constants.OPCodes.RESUME, - d, - }); - } -} - -/** - * Encoding the WebSocket connections will use. - * @type {string} - */ -WebSocketConnection.ENCODING = erlpack ? 'etf' : 'json'; -WebSocketConnection.WebSocket = WebSocket; - -module.exports = WebSocketConnection; 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 9ef073f..0000000 --- a/node_modules/discord.js/src/client/websocket/WebSocketManager.js +++ /dev/null @@ -1,90 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const Constants = require('../../util/Constants'); -const WebSocketConnection = require('./WebSocketConnection'); - -/** - * WebSocket Manager of the client. - * @private - */ -class WebSocketManager extends EventEmitter { - constructor(client) { - super(); - /** - * The client that instantiated this WebSocketManager - * @type {Client} - */ - this.client = client; - - /** - * The WebSocket connection of this manager - * @type {?WebSocketConnection} - */ - this.connection = null; - } - - /** - * Sends a heartbeat on the available connection. - * @returns {void} - */ - heartbeat() { - if (!this.connection) return this.debug('No connection to heartbeat'); - return this.connection.heartbeat(); - } - - /** - * Emits a debug event. - * @param {string} message Debug message - * @returns {void} - */ - debug(message) { - return this.client.emit('debug', `[ws] ${message}`); - } - - /** - * Destroy the client. - * @returns {void} Whether or not destruction was successful - */ - destroy() { - if (!this.connection) { - this.debug('Attempted to destroy WebSocket but no connection exists!'); - return false; - } - return this.connection.destroy(); - } - - /** - * Send a packet on the available WebSocket. - * @param {Object} packet Packet to send - * @returns {void} - */ - send(packet) { - if (!this.connection) { - this.debug('No connection to websocket'); - return; - } - this.connection.send(packet); - } - - /** - * Connects the client to a gateway. - * @param {string} gateway The gateway to connect to - * @returns {boolean} - */ - connect(gateway) { - if (!this.connection) { - this.connection = new WebSocketConnection(this, gateway); - return true; - } - switch (this.connection.status) { - case Constants.Status.IDLE: - case Constants.Status.DISCONNECTED: - this.connection.connect(gateway, 5500); - return true; - default: - this.debug(`Couldn't connect to ${gateway} as the websocket is at state ${this.connection.status}`); - return false; - } - } -} - -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 c84b16b..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/WebSocketPacketManager.js +++ /dev/null @@ -1,113 +0,0 @@ -const Constants = require('../../../util/Constants'); - -const BeforeReadyWhitelist = [ - Constants.WSEvents.READY, - Constants.WSEvents.RESUMED, - 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(connection) { - this.ws = connection; - this.handlers = {}; - this.queue = []; - - this.register(Constants.WSEvents.READY, require('./handlers/Ready')); - this.register(Constants.WSEvents.RESUMED, require('./handlers/Resumed')); - 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.GUILD_INTEGRATIONS_UPDATE, require('./handlers/GuildIntegrationsUpdate')); - this.register(Constants.WSEvents.INVITE_CREATE, require('./handlers/InviteCreate')); - this.register(Constants.WSEvents.INVITE_DELETE, require('./handlers/InviteDelete')); - 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.USER_SETTINGS_UPDATE, require('./handlers/UserSettingsUpdate')); - this.register(Constants.WSEvents.USER_GUILD_SETTINGS_UPDATE, require('./handlers/UserGuildSettingsUpdate')); - 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_EMOJI, require('./handlers/MessageReactionRemoveEmoji')); - this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE_ALL, require('./handlers/MessageReactionRemoveAll')); - this.register(Constants.WSEvents.WEBHOOKS_UPDATE, require('./handlers/WebhooksUpdate')); - } - - 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], true); - this.queue.splice(index, 1); - }); - } - - handle(packet, queue = 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.ws.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 (!queue && this.queue.length > 0) this.handleQueue(); - 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 16ffe1c..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/ChannelPinsUpdate.js +++ /dev/null @@ -1,37 +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) { - // Discord sends null for last_pin_timestamp if the last pinned message was removed - channel.lastPinTimestamp = time.getTime() || null; - - 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. - * <warn>The `time` parameter will be a Unix Epoch Date object when there are no pins left.</warn> - * @event Client#channelPinsUpdate - * @param {Channel} channel The channel that the pins update occured in - * @param {Date} time The time when the last pinned message was pinned - */ - -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 d7c1803..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 2906e74..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildEmojisUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); - -class GuildEmojisUpdate extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - client.actions.GuildEmojisUpdate.handle(data); - } -} - -module.exports = GuildEmojisUpdate; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js deleted file mode 100644 index 5adfb5b..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js +++ /dev/null @@ -1,19 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const { Events } = require('../../../../util/Constants'); - -class GuildIntegrationsHandler extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - const guild = client.guilds.get(data.guild_id); - if (guild) client.emit(Events.GUILD_INTEGRATIONS_UPDATE, guild); - } -} - -module.exports = GuildIntegrationsHandler; - -/** - * Emitted whenever a guild integration is updated - * @event Client#guildIntegrationsUpdate - * @param {Guild} guild The guild whose integrations were updated - */ 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 4458644..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/GuildMembersChunk.js +++ /dev/null @@ -1,33 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const Constants = require('../../../../util/Constants'); -// Uncomment in v12 -// const Collection = require('../../../../util/Collection'); - -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; - - // Uncomment in v12 - // const members = new Collection(); - // - // for (const member of data.members) members.set(member.id, guild._addMember(member, false)); - - const members = data.members.map(member => guild._addMember(member, false)); - - client.emit(Constants.Events.GUILD_MEMBERS_CHUNK, members, guild); - - 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 - * @param {Guild} guild The guild related to the member 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/InviteCreate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/InviteCreate.js deleted file mode 100644 index 00efb67..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/InviteCreate.js +++ /dev/null @@ -1,11 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); - -class InviteCreateHandler extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - client.actions.InviteCreate.handle(data); - } -} - -module.exports = InviteCreateHandler; diff --git a/node_modules/discord.js/src/client/websocket/packets/handlers/InviteDelete.js b/node_modules/discord.js/src/client/websocket/packets/handlers/InviteDelete.js deleted file mode 100644 index 0b8da42..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/InviteDelete.js +++ /dev/null @@ -1,11 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); - -class InviteDeleteHandler extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - client.actions.InviteDelete.handle(data); - } -} - -module.exports = InviteDeleteHandler; 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 beed34d..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 043c70a..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 db02df0..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<Snowflake, 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/MessageReactionRemoveEmoji.js b/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveEmoji.js deleted file mode 100644 index c16af74..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/MessageReactionRemoveEmoji.js +++ /dev/null @@ -1,11 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); - -class MessageReactionRemoveEmoji extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - client.actions.MessageReactionRemoveEmoji.handle(data); - } -} - -module.exports = MessageReactionRemoveEmoji; 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 8bcf659..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/PresenceUpdate.js +++ /dev/null @@ -1,76 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const Constants = require('../../../../util/Constants'); -const Util = require('../../../../util/Util'); - -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 = Util.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) { - if (client.listenerCount(Constants.Events.PRESENCE_UPDATE) === 0) { - guild._setPresence(user.id, data); - return; - } - const oldMember = Util.cloneObject(member); - if (member.presence) { - oldMember.frozenPresence = Util.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 3eb80a2..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/Ready.js +++ /dev/null @@ -1,84 +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(); - - data.user.user_settings = data.user_settings; - data.user.user_guild_settings = data.user_guild_settings; - - 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) if (!client.guilds.has(guild.id)) 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 of Object.keys(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); - - 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, - }); - } - - const t = client.setTimeout(() => { - client.ws.connection.triggerReady(); - }, 1200 * data.guilds.length); - - const guildCount = data.guilds.length; - - if (client.getMaxListeners() !== 0) client.setMaxListeners(client.getMaxListeners() + guildCount); - - client.once('ready', () => { - client.syncGuilds(); - if (client.getMaxListeners() !== 0) client.setMaxListeners(client.getMaxListeners() - guildCount); - client.clearTimeout(t); - }); - - const ws = this.packetManager.ws; - - ws.sessionID = data.session_id; - client.emit('debug', `READY ${ws.sessionID}`); - 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/Resumed.js b/node_modules/discord.js/src/client/websocket/packets/handlers/Resumed.js deleted file mode 100644 index a0a51c0..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/Resumed.js +++ /dev/null @@ -1,26 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const Constants = require('../../../../util/Constants'); - -class ResumedHandler extends AbstractHandler { - handle() { - const client = this.packetManager.client; - const ws = client.ws.connection; - - ws.status = Constants.Status.READY; - this.packetManager.handleQueue(); - - const replayed = ws.sequence - ws.closeSequence; - - ws.debug(`RESUMED | replayed ${replayed} events.`); - client.emit(Constants.Events.RESUME, replayed); - ws.heartbeat(); - } -} - -/** - * Emitted whenever a WebSocket resumes. - * @event Client#resume - * @param {number} replayed The number of events that were replayed - */ - -module.exports = ResumedHandler; 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 a7f5a36..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/UserGuildSettingsUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/UserGuildSettingsUpdate.js deleted file mode 100644 index 90bca4c..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/UserGuildSettingsUpdate.js +++ /dev/null @@ -1,21 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const Constants = require('../../../../util/Constants'); -const ClientUserGuildSettings = require('../../../../structures/ClientUserGuildSettings'); - -class UserGuildSettingsUpdateHandler extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const settings = client.user.guildSettings.get(packet.d.guild_id); - if (settings) settings.patch(packet.d); - else client.user.guildSettings.set(packet.d.guild_id, new ClientUserGuildSettings(packet.d, client)); - client.emit(Constants.Events.USER_GUILD_SETTINGS_UPDATE, client.user.guildSettings.get(packet.d.guild_id)); - } -} - -/** - * Emitted whenever the client user's settings update. - * @event Client#clientUserGuildSettingsUpdate - * @param {ClientUserGuildSettings} clientUserGuildSettings The new client user guild settings - */ - -module.exports = UserGuildSettingsUpdateHandler; 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/UserSettingsUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/UserSettingsUpdate.js deleted file mode 100644 index 903b64b..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/UserSettingsUpdate.js +++ /dev/null @@ -1,18 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const Constants = require('../../../../util/Constants'); - -class UserSettingsUpdateHandler extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - client.user.settings.patch(packet.d); - client.emit(Constants.Events.USER_SETTINGS_UPDATE, client.user.settings); - } -} - -/** - * Emitted when the client user's settings update. - * @event Client#clientUserSettingsUpdate - * @param {ClientUserSettings} clientUserSettings The new client user settings - */ - -module.exports = UserSettingsUpdateHandler; 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 2b0b40f..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/VoiceStateUpdate.js +++ /dev/null @@ -1,53 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); - -const Constants = require('../../../../util/Constants'); -const Util = require('../../../../util/Util'); - -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 = Util.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) { - client.emit('self.voiceStateUpdate', data); - } - - const newChannel = client.channels.get(data.channel_id); - if (newChannel) { - newChannel.members.set(member.id, member); - member.guild.channels.set(data.channel_id, newChannel); - } - - member.serverMute = data.mute; - member.serverDeaf = data.deaf; - member.selfMute = data.self_mute; - member.selfDeaf = data.self_deaf; - member.selfStream = data.self_stream || false; - 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/client/websocket/packets/handlers/WebhooksUpdate.js b/node_modules/discord.js/src/client/websocket/packets/handlers/WebhooksUpdate.js deleted file mode 100644 index 7ed2721..0000000 --- a/node_modules/discord.js/src/client/websocket/packets/handlers/WebhooksUpdate.js +++ /dev/null @@ -1,19 +0,0 @@ -const AbstractHandler = require('./AbstractHandler'); -const { Events } = require('../../../../util/Constants'); - -class WebhooksUpdate extends AbstractHandler { - handle(packet) { - const client = this.packetManager.client; - const data = packet.d; - const channel = client.channels.get(data.channel_id); - if (channel) client.emit(Events.WEBHOOKS_UPDATE, channel); - } -} - -/** - * Emitted whenever a guild text channel has its webhooks changed. - * @event Client#webhookUpdate - * @param {TextChannel} channel The channel that had a webhook update - */ - -module.exports = WebhooksUpdate; diff --git a/node_modules/discord.js/src/index.js b/node_modules/discord.js/src/index.js deleted file mode 100644 index f1fe01f..0000000 --- a/node_modules/discord.js/src/index.js +++ /dev/null @@ -1,71 +0,0 @@ -const Util = require('./util/Util'); - -module.exports = { - // "Root" classes (starting points) - Client: require('./client/Client'), - Shard: require('./sharding/Shard'), - ShardClientUtil: require('./sharding/ShardClientUtil'), - ShardingManager: require('./sharding/ShardingManager'), - WebhookClient: require('./client/WebhookClient'), - - // Utilities - BitField: require('./util/BitField'), - Collection: require('./util/Collection'), - Constants: require('./util/Constants'), - DiscordAPIError: require('./client/rest/DiscordAPIError'), - EvaluatedPermissions: require('./util/Permissions'), - MessageFlags: require('./util/MessageFlags'), - Permissions: require('./util/Permissions'), - Snowflake: require('./util/Snowflake'), - SnowflakeUtil: require('./util/Snowflake'), - SystemChannelFlags: require('./util/SystemChannelFlags'), - Util: Util, - util: Util, - version: require('../package').version, - - // Shortcuts to Util methods - escapeMarkdown: Util.escapeMarkdown, - fetchRecommendedShards: Util.fetchRecommendedShards, - resolveString: Util.resolveString, - splitMessage: Util.splitMessage, - - // Structures - Attachment: require('./structures/Attachment'), - CategoryChannel: require('./structures/CategoryChannel'), - Channel: require('./structures/Channel'), - ClientUser: require('./structures/ClientUser'), - ClientUserSettings: require('./structures/ClientUserSettings'), - Collector: require('./structures/interfaces/Collector'), - DMChannel: require('./structures/DMChannel'), - Emoji: require('./structures/Emoji'), - Game: require('./structures/Presence').Game, - GroupDMChannel: require('./structures/GroupDMChannel'), - Guild: require('./structures/Guild'), - GuildAuditLogs: require('./structures/GuildAuditLogs'), - GuildChannel: require('./structures/GuildChannel'), - GuildMember: require('./structures/GuildMember'), - Integration: require('./structures/Integration'), - Invite: require('./structures/Invite'), - Message: require('./structures/Message'), - MessageAttachment: require('./structures/MessageAttachment'), - MessageCollector: require('./structures/MessageCollector'), - MessageEmbed: require('./structures/MessageEmbed'), - MessageMentions: require('./structures/MessageMentions'), - MessageReaction: require('./structures/MessageReaction'), - NewsChannel: require('./structures/NewsChannel'), - OAuth2Application: require('./structures/OAuth2Application'), - ClientOAuth2Application: require('./structures/OAuth2Application'), - PartialGuild: require('./structures/PartialGuild'), - PartialGuildChannel: require('./structures/PartialGuildChannel'), - PermissionOverwrites: require('./structures/PermissionOverwrites'), - Presence: require('./structures/Presence').Presence, - ReactionEmoji: require('./structures/ReactionEmoji'), - ReactionCollector: require('./structures/ReactionCollector'), - RichEmbed: require('./structures/RichEmbed'), - Role: require('./structures/Role'), - StoreChannel: require('./structures/StoreChannel'), - TextChannel: require('./structures/TextChannel'), - User: require('./structures/User'), - VoiceChannel: require('./structures/VoiceChannel'), - Webhook: require('./structures/Webhook'), -}; 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 b6fddb4..0000000 --- a/node_modules/discord.js/src/sharding/Shard.js +++ /dev/null @@ -1,282 +0,0 @@ -const childProcess = require('child_process'); -const EventEmitter = require('events'); -const path = require('path'); -const Util = require('../util/Util'); - -/** - * Represents a Shard spawned by the ShardingManager. - */ -class Shard extends EventEmitter { - /** - * @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 = []) { - super(); - /** - * 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, - }); - - /** - * Whether the shard's {@link Client} is ready - * @type {boolean} - */ - this.ready = false; - - this._evals = new Map(); - this._fetches = new Map(); - - /** - * Listener function for the {@link ChildProcess}' `exit` event - * @type {Function} - * @private - */ - this._exitListener = this._handleExit.bind(this, undefined); - - /** - * Process of the shard - * @type {ChildProcess} - */ - this.process = null; - - this.spawn(args); - } - - /** - * Forks a child process for the shard. - * <warn>You should not need to call this manually.</warn> - * @param {Array} [args=this.manager.args] Command line arguments to pass to the script - * @param {Array} [execArgv=this.manager.execArgv] Command line arguments to pass to the process executable - * @returns {ChildProcess} - */ - spawn(args = this.manager.args, execArgv = this.manager.execArgv) { - this.process = childProcess.fork(path.resolve(this.manager.file), args, { - env: this.env, execArgv, - }) - .on('exit', this._exitListener) - .on('message', this._handleMessage.bind(this)); - - /** - * Emitted upon the creation of the shard's child process. - * @event Shard#spawn - * @param {ChildProcess} process Child process that was created - */ - this.emit('spawn', this.process); - - return new Promise((resolve, reject) => { - this.once('ready', resolve); - this.once('disconnect', () => reject(new Error(`Shard ${this.id}'s Client disconnected before becoming ready.`))); - this.once('death', () => reject(new Error(`Shard ${this.id}'s process exited before its Client became ready.`))); - setTimeout(() => reject(new Error(`Shard ${this.id}'s Client took too long to become ready.`)), 30000); - }).then(() => this.process); - } - - /** - * Immediately kills the shard's process and does not restart it. - */ - kill() { - this.process.removeListener('exit', this._exitListener); - this.process.kill(); - this._handleExit(false); - } - - /** - * Kills and restarts the shard's process. - * @param {number} [delay=500] How long to wait between killing the process and restarting it (in milliseconds) - * @returns {Promise<ChildProcess>} - */ - respawn(delay = 500) { - this.kill(); - if (delay > 0) return Util.delayFor(delay).then(() => this.spawn()); - return this.spawn(); - } - - /** - * 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) => { - this.process.send(message, err => { - if (err) reject(err); else resolve(this); - }); - }); - } - - /** - * 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(Util.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 ready - if (message._ready) { - this.ready = true; - /** - * Emitted upon the shard's {@link Client#ready} event. - * @event Shard#ready - */ - this.emit('ready'); - return; - } - - // Shard has disconnected - if (message._disconnect) { - this.ready = false; - /** - * Emitted upon the shard's {@link Client#disconnect} event. - * @event Shard#disconnect - */ - this.emit('disconnect'); - return; - } - - // Shard is attempting to reconnect - if (message._reconnecting) { - this.ready = false; - /** - * Emitted upon the shard's {@link Client#reconnecting} event. - * @event Shard#reconnecting - */ - this.emit('reconnecting'); - return; - } - - // 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: Util.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: Util.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); - - /** - * Emitted upon recieving a message from the child process. - * @event Shard#message - * @param {*} message Message that was received - */ - this.emit('message', message); - } - - /** - * Handles the shard's process exiting. - * @param {boolean} [respawn=this.manager.respawn] Whether to spawn the shard again - * @private - */ - _handleExit(respawn = this.manager.respawn) { - /** - * Emitted upon the shard's child process exiting. - * @event Shard#death - * @param {ChildProcess} process Child process that exited - */ - this.emit('death', this.process); - - this.process = null; - this._evals.clear(); - this._fetches.clear(); - - if (respawn) this.manager.createShard(this.id); - } -} - -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 28571f1..0000000 --- a/node_modules/discord.js/src/sharding/ShardClientUtil.js +++ /dev/null @@ -1,146 +0,0 @@ -const Util = require('../util/Util'); - -/** - * Helper class for sharded clients spawned as a child process, such as from a ShardingManager. - */ -class ShardClientUtil { - /** - * @param {Client} client The client of the current shard - */ - constructor(client) { - this.client = client; - process.on('message', this._handleMessage.bind(this)); - client.on('ready', () => { process.send({ _ready: true }); }); - client.on('disconnect', () => { process.send({ _disconnect: true }); }); - client.on('reconnecting', () => { process.send({ _reconnecting: true }); }); - } - - /** - * 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) => { - process.send(message, err => { - if (err) reject(err); else resolve(); - }); - }); - } - - /** - * 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(Util.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(Util.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: Util.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 The 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 5b07299..0000000 --- a/node_modules/discord.js/src/sharding/ShardingManager.js +++ /dev/null @@ -1,220 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const EventEmitter = require('events').EventEmitter; -const Shard = require('./Shard'); -const Collection = require('../util/Collection'); -const Util = require('../util/Util'); - -/** - * 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 = Util.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; - - /** - * Arguments for the shard's process executable - * @type {?string[]} - */ - this.execArgv = options.execArgv; - - /** - * 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=7500] How long to wait in between spawning each shard (in milliseconds) - * @returns {Promise<Collection<number, Shard>>} - */ - spawn(amount = this.totalShards, delay = 7500) { - if (amount === 'auto') { - return Util.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); - } - - /** - * Kills all running shards and respawns them. - * @param {number} [shardDelay=5000] How long to wait between shards (in milliseconds) - * @param {number} [respawnDelay=500] How long to wait between killing a shard's process and restarting it - * (in milliseconds) - * @param {boolean} [waitForReady=true] Whether to wait for a shard to become ready before continuing to another - * @param {number} [currentShardIndex=0] The shard index to start respawning at - * @returns {Promise<Collection<number, Shard>>} - */ - respawnAll(shardDelay = 5000, respawnDelay = 500, waitForReady = true, currentShardIndex = 0) { - let s = 0; - const shard = this.shards.get(currentShardIndex); - const promises = [shard.respawn(respawnDelay, waitForReady)]; - if (++s < this.shards.size && shardDelay > 0) promises.push(Util.delayFor(shardDelay)); - return Promise.all(promises).then(() => { - if (++currentShardIndex === this.shards.size) return this.shards; - return this.respawnAll(shardDelay, respawnDelay, waitForReady, currentShardIndex); - }); - } -} - -module.exports = ShardingManager; diff --git a/node_modules/discord.js/src/structures/Attachment.js b/node_modules/discord.js/src/structures/Attachment.js deleted file mode 100644 index 216b61c..0000000 --- a/node_modules/discord.js/src/structures/Attachment.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Represents an attachment in a message. - * @param {BufferResolvable|Stream} file The file - * @param {string} [name] The name of the file, if any - */ -class Attachment { - constructor(file, name) { - this.file = null; - if (name) this.setAttachment(file, name); - else this._attach(file); - } - - /** - * The name of the file - * @type {?string} - * @readonly - */ - get name() { - return this.file.name; - } - - /** - * The file - * @type {?BufferResolvable|Stream} - * @readonly - */ - get attachment() { - return this.file.attachment; - } - - /** - * Set the file of this attachment. - * @param {BufferResolvable|Stream} file The file - * @param {string} name The name of the file - * @returns {Attachment} This attachment - */ - setAttachment(file, name) { - this.file = { attachment: file, name }; - return this; - } - - /** - * Set the file of this attachment. - * @param {BufferResolvable|Stream} attachment The file - * @returns {Attachment} This attachment - */ - setFile(attachment) { - this.file = { attachment }; - return this; - } - - /** - * Set the name of this attachment. - * @param {string} name The name of the image - * @returns {Attachment} This attachment - */ - setName(name) { - this.file.name = name; - return this; - } - - /** - * Set the file of this attachment. - * @param {BufferResolvable|Stream} file The file - * @param {string} name The name of the file - * @returns {void} - * @private - */ - _attach(file, name) { - if (typeof file === 'string') this.file = file; - else this.setAttachment(file, name); - } -} - -module.exports = Attachment; diff --git a/node_modules/discord.js/src/structures/CategoryChannel.js b/node_modules/discord.js/src/structures/CategoryChannel.js deleted file mode 100644 index 9ba263a..0000000 --- a/node_modules/discord.js/src/structures/CategoryChannel.js +++ /dev/null @@ -1,22 +0,0 @@ -const GuildChannel = require('./GuildChannel'); - -/** - * Represents a guild category channel on Discord. - * @extends {GuildChannel} - */ -class CategoryChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - this.type = 'category'; - } - /** - * The channels that are part of this category - * @type {?Collection<Snowflake, GuildChannel>} - * @readonly - */ - get children() { - return this.guild.channels.filter(c => c.parentID === this.id); - } -} - -module.exports = CategoryChannel; 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 732945d..0000000 --- a/node_modules/discord.js/src/structures/Channel.js +++ /dev/null @@ -1,78 +0,0 @@ -const Snowflake = require('../util/Snowflake'); - -/** - * 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 - * * `category` - a guild category channel - * * `news` - a guild news channel - * * `store` - a guild store channel - * @type {string} - */ - this.type = null; - - /** - * Whether the channel has been deleted - * @type {boolean} - */ - this.deleted = false; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The unique ID of the channel - * @type {Snowflake} - */ - this.id = data.id; - } - - /** - * The timestamp the channel was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * 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(console.log) - * .catch(console.error); - */ - delete() { - return this.client.rest.methods.deleteChannel(this); - } -} - -module.exports = Channel; 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 4ae8c6e..0000000 --- a/node_modules/discord.js/src/structures/ClientUser.js +++ /dev/null @@ -1,447 +0,0 @@ -const User = require('./User'); -const Collection = require('../util/Collection'); -const ClientUserSettings = require('./ClientUserSettings'); -const ClientUserGuildSettings = require('./ClientUserGuildSettings'); -const Constants = require('../util/Constants'); -const util = require('util'); - -/** - * 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 - * <warn>This is only filled when using a user account.</warn> - * @type {?string} - * @deprecated - */ - 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<Snowflake, User>} - * @deprecated - */ - 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<Snowflake, User>} - * @deprecated - */ - 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<Snowflake, string>} - * @deprecated - */ - this.notes = new Collection(); - - /** - * If the user has Discord premium (nitro) - * <warn>This is only filled when using a user account.</warn> - * @type {?boolean} - * @deprecated - */ - this.premium = typeof data.premium === 'boolean' ? data.premium : null; - - /** - * If the user has MFA enabled on their account - * @type {boolean} - */ - this.mfaEnabled = data.mfa_enabled; - - /** - * If the user has ever used a mobile device on Discord - * <warn>This is only filled when using a user account.</warn> - * @type {?boolean} - * @deprecated - */ - this.mobile = typeof data.mobile === 'boolean' ? data.mobile : null; - - /** - * Various settings for this user - * <warn>This is only filled when using a user account.</warn> - * @type {?ClientUserSettings} - * @deprecated - */ - this.settings = data.user_settings ? new ClientUserSettings(this, data.user_settings) : null; - - /** - * All of the user's guild settings - * <warn>This is only filled when using a user account</warn> - * @type {Collection<Snowflake, ClientUserGuildSettings>} - * @deprecated - */ - this.guildSettings = new Collection(); - if (data.user_guild_settings) { - for (const settings of data.user_guild_settings) { - this.guildSettings.set(settings.guild_id, new ClientUserGuildSettings(settings, this.client)); - } - } - } - - 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>} - * @deprecated - * @example - * // Set email - * client.user.setEmail('[email protected]', '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>} - * @deprecated - * @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) { - return this.client.resolver.resolveImage(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 - * @property {?ActivityType|number} [game.type] Type of the activity - */ - - /** - * Sets the full presence of the client user. - * @param {PresenceData} data Data for the presence - * @returns {Promise<ClientUser>} - * @example - * // Set the client user's presence - * client.user.setPresence({ game: { name: 'with discord.js' }, status: 'idle' }) - * .then(console.log) - * .catch(console.error); - */ - 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'); - if (this.bot) { - status = data.status; - } else { - this.settings.update(Constants.UserSettingsMap.status, data.status); - status = 'invisible'; - } - } - - if (data.game) { - game = data.game; - game.type = game.url && typeof game.type === 'undefined' ? 1 : game.type || 0; - if (typeof game.type === 'string') { - game.type = Constants.ActivityTypes.indexOf(game.type.toUpperCase()); - } - } else if (typeof data.game !== 'undefined') { - game = null; - } - - 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>} - * @example - * // Set the client user's status - * client.user.setStatus('idle') - * .then(console.log) - * .catch(console.error); - */ - 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>} - * @deprecated - */ - setGame(game, streamingURL) { - if (!game) return this.setPresence({ game: null }); - return this.setPresence({ - game: { - name: game, - url: streamingURL, - }, - }); - } - - /** - * Sets the activity the client user is playing. - * @param {?string} name Activity being played - * @param {Object} [options] Options for setting the activity - * @param {string} [options.url] Twitch stream URL - * @param {ActivityType|number} [options.type] Type of the activity - * @returns {Promise<Presence>} - * @example - * client.user.setActivity('YouTube', { type: 'WATCHING' }) - * .then(presence => console.log(`Activity set to ${presence.game ? presence.game.name : 'none'}`)) - * .catch(console.error); - */ - setActivity(name, { url, type } = {}) { - if (!name) return this.setPresence({ game: null }); - return this.setPresence({ - game: { name, type, url }, - }).then(clientUser => clientUser.presence); - } - - /** - * 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. - * <warn>This is only available when using a user account.</warn> - * @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 {GuildResolvable} [options.guild] Limit the search to a specific guild - * @returns {Promise<Message[]>} - * @deprecated - * @example - * // Fetch mentions - * client.user.fetchMentions() - * .then(console.log) - * .catch(console.error); - * @example - * // Fetch mentions from a guild - * client.user.fetchMentions({ guild: '222078108977594368' }) - * .then(console.log) - * .catch(console.error); - */ - fetchMentions(options = {}) { - 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 - * @deprecated - */ - 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 - * @deprecated - */ - removeFriend(user) { - user = this.client.resolver.resolveUser(user); - return this.client.rest.methods.removeFriend(user); - } - - /** - * Creates a guild. - * <warn>This is only available to bots in less than 10 guilds and user accounts.</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 (typeof icon === 'string' && icon.startsWith('data:')) { - return this.client.rest.methods.createGuild({ name, icon, region }); - } else { - return this.client.resolver.resolveImage(icon).then(data => - this.client.rest.methods.createGuild({ name, icon: data, region }) - ); - } - } - - /** - * An object containing either a user or access token, and an optional nickname. - * @typedef {Object} GroupDMRecipientOptions - * @property {UserResolvable|Snowflake} [user] User to add to the Group DM - * (only available if a user is creating the DM) - * @property {string} [accessToken] Access token to use to add a user to the Group DM - * (only available if a bot is creating the DM) - * @property {string} [nick] Permanent nickname (only available if a bot is creating the DM) - */ - - /** - * Creates a Group DM. - * @param {GroupDMRecipientOptions[]} recipients The recipients - * @returns {Promise<GroupDMChannel>} - * @example - * // Create a Group DM with a token provided from OAuth - * client.user.createGroupDM([{ - * user: '66564597481480192', - * accessToken: token - * }]) - * .then(console.log) - * .catch(console.error); - */ - createGroupDM(recipients) { - return this.client.rest.methods.createGroupDM({ - recipients: recipients.map(u => this.client.resolver.resolveUserID(u.user)), - accessTokens: recipients.map(u => u.accessToken), - nicks: recipients.reduce((o, r) => { - if (r.nick) o[r.user ? r.user.id : r.id] = r.nick; - return o; - }, {}), - }); - } - - /** - * Accepts an invite to join a guild. - * <warn>This is only available when using a user account.</warn> - * @param {Invite|string} invite Invite or code to accept - * @returns {Promise<Guild>} Joined guild - * @deprecated - */ - acceptInvite(invite) { - return this.client.rest.methods.acceptInvite(invite); - } -} - -ClientUser.prototype.acceptInvite = - util.deprecate(ClientUser.prototype.acceptInvite, 'ClientUser#acceptInvite: userbot methods will be removed'); - -ClientUser.prototype.setGame = - util.deprecate(ClientUser.prototype.setGame, 'ClientUser#setGame: use ClientUser#setActivity instead'); - -ClientUser.prototype.addFriend = - util.deprecate(ClientUser.prototype.addFriend, 'ClientUser#addFriend: userbot methods will be removed'); - -ClientUser.prototype.removeFriend = - util.deprecate(ClientUser.prototype.removeFriend, 'ClientUser#removeFriend: userbot methods will be removed'); - -ClientUser.prototype.setPassword = - util.deprecate(ClientUser.prototype.setPassword, 'ClientUser#setPassword: userbot methods will be removed'); - -ClientUser.prototype.setEmail = - util.deprecate(ClientUser.prototype.setEmail, 'ClientUser#setEmail: userbot methods will be removed'); - -ClientUser.prototype.fetchMentions = - util.deprecate(ClientUser.prototype.fetchMentions, 'ClientUser#fetchMentions: userbot methods will be removed'); - -module.exports = ClientUser; diff --git a/node_modules/discord.js/src/structures/ClientUserChannelOverride.js b/node_modules/discord.js/src/structures/ClientUserChannelOverride.js deleted file mode 100644 index 93efa45..0000000 --- a/node_modules/discord.js/src/structures/ClientUserChannelOverride.js +++ /dev/null @@ -1,30 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * A wrapper around the ClientUser's channel overrides. - */ -class ClientUserChannelOverride { - constructor(data) { - this.patch(data); - } - - /** - * Patch the data contained in this class with new partial data. - * @param {Object} data Data to patch this with - * @returns {void} - * @private - */ - patch(data) { - for (const key of Object.keys(Constants.UserChannelOverrideMap)) { - const value = Constants.UserChannelOverrideMap[key]; - if (!data.hasOwnProperty(key)) continue; - if (typeof value === 'function') { - this[value.name] = value(data[key]); - } else { - this[value] = data[key]; - } - } - } -} - -module.exports = ClientUserChannelOverride; diff --git a/node_modules/discord.js/src/structures/ClientUserGuildSettings.js b/node_modules/discord.js/src/structures/ClientUserGuildSettings.js deleted file mode 100644 index 5a28747..0000000 --- a/node_modules/discord.js/src/structures/ClientUserGuildSettings.js +++ /dev/null @@ -1,60 +0,0 @@ -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const ClientUserChannelOverride = require('./ClientUserChannelOverride'); - -/** - * A wrapper around the ClientUser's guild settings. - */ -class ClientUserGuildSettings { - constructor(data, client) { - /** - * The client that created the instance of the ClientUserGuildSettings - * @name ClientUserGuildSettings#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - /** - * The ID of the guild this settings are for - * @type {Snowflake} - */ - this.guildID = data.guild_id; - this.channelOverrides = new Collection(); - this.patch(data); - } - - /** - * Patch the data contained in this class with new partial data. - * @param {Object} data Data to patch this with - * @returns {void} - * @private - */ - patch(data) { - for (const key of Object.keys(Constants.UserGuildSettingsMap)) { - const value = Constants.UserGuildSettingsMap[key]; - if (!data.hasOwnProperty(key)) continue; - if (key === 'channel_overrides') { - for (const channel of data[key]) { - this.channelOverrides.set(channel.channel_id, - new ClientUserChannelOverride(channel)); - } - } else if (typeof value === 'function') { - this[value.name] = value(data[key]); - } else { - this[value] = data[key]; - } - } - } - - /** - * Update a specific property of the guild settings. - * @param {string} name Name of property - * @param {value} value Value to patch - * @returns {Promise<Object>} - */ - update(name, value) { - return this.client.rest.methods.patchClientUserGuildSettings(this.guildID, { [name]: value }); - } -} - -module.exports = ClientUserGuildSettings; diff --git a/node_modules/discord.js/src/structures/ClientUserSettings.js b/node_modules/discord.js/src/structures/ClientUserSettings.js deleted file mode 100644 index 6b18c03..0000000 --- a/node_modules/discord.js/src/structures/ClientUserSettings.js +++ /dev/null @@ -1,80 +0,0 @@ -const Constants = require('../util/Constants'); -const Util = require('../util/Util'); - -/** - * A wrapper around the ClientUser's settings. - */ -class ClientUserSettings { - constructor(user, data) { - this.user = user; - this.patch(data); - } - - /** - * Patch the data contained in this class with new partial data. - * @param {Object} data Data to patch this with - * @returns {void} - * @private - */ - patch(data) { - for (const key of Object.keys(Constants.UserSettingsMap)) { - const value = Constants.UserSettingsMap[key]; - if (!data.hasOwnProperty(key)) continue; - if (typeof value === 'function') { - this[value.name] = value(data[key]); - } else { - this[value] = data[key]; - } - } - } - - /** - * Update a specific property of of user settings. - * @param {string} name Name of property - * @param {*} value Value to patch - * @returns {Promise<Object>} - */ - update(name, value) { - return this.user.client.rest.methods.patchUserSettings({ [name]: value }); - } - - /** - * Sets the position at which this guild will appear in the Discord client. - * @param {Guild} guild The guild to move - * @param {number} position Absolute or relative position - * @param {boolean} [relative=false] Whether to position relatively or absolutely - * @returns {Promise<Guild>} - */ - setGuildPosition(guild, position, relative) { - const temp = Object.assign([], this.guildPositions); - Util.moveElementInArray(temp, guild.id, position, relative); - return this.update('guild_positions', temp).then(() => guild); - } - - /** - * Add a guild to the list of restricted guilds. - * @param {Guild} guild The guild to add - * @returns {Promise<Guild>} - */ - addRestrictedGuild(guild) { - const temp = Object.assign([], this.restrictedGuilds); - if (temp.includes(guild.id)) return Promise.reject(new Error('Guild is already restricted')); - temp.push(guild.id); - return this.update('restricted_guilds', temp).then(() => guild); - } - - /** - * Remove a guild from the list of restricted guilds. - * @param {Guild} guild The guild to remove - * @returns {Promise<Guild>} - */ - removeRestrictedGuild(guild) { - const temp = Object.assign([], this.restrictedGuilds); - const index = temp.indexOf(guild.id); - if (index < 0) return Promise.reject(new Error('Guild is not restricted')); - temp.splice(index, 1); - return this.update('restricted_guilds', temp).then(() => guild); - } -} - -module.exports = ClientUserSettings; 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 0a6a3d9..0000000 --- a/node_modules/discord.js/src/structures/DMChannel.js +++ /dev/null @@ -1,76 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interfaces/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]); - - /** - * The ID of the last message in the channel, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = data.last_message_id; - - /** - * The timestamp when the last pinned message was pinned, if there was one - * @type {?number} - */ - this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; - } - - /** - * 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 - /* eslint-disable no-empty-function */ - get lastPinAt() {} - send() {} - sendMessage() {} - sendEmbed() {} - sendFile() {} - sendFiles() {} - sendCode() {} - fetchMessage() {} - fetchMessages() {} - fetchPinnedMessages() {} - search() {} - startTyping() {} - stopTyping() {} - get typing() {} - get typingCount() {} - createCollector() {} - createMessageCollector() {} - awaitMessages() {} - // Doesn't work on DM channels; bulkDelete() {} - acknowledge() {} - _cacheMessage() {} -} - -TextBasedChannel.applyToClass(DMChannel, true, ['bulkDelete']); - -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 f514b81..0000000 --- a/node_modules/discord.js/src/structures/Emoji.js +++ /dev/null @@ -1,273 +0,0 @@ -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const Permissions = require('../util/Permissions'); -const Snowflake = require('../util/Snowflake'); - -/** - * 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; - - /** - * Whether this emoji has been deleted - * @type {boolean} - */ - this.deleted = false; - - this.setup(data); - } - - setup(data) { - /** - * The ID of the emoji - * @type {Snowflake} - */ - 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; - - /** - * Whether this emoji is animated - * @type {boolean} - */ - this.animated = data.animated; - - /** - * Whether this emoji is available - * @type {boolean} - * @name Emoji#available - */ - if (typeof data.available !== 'undefined') this.available = data.available; - - this._roles = data.roles; - } - - /** - * The timestamp the emoji was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the emoji was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Whether the emoji is deletable by the client user - * @type {boolean} - * @readonly - */ - get deletable() { - return !this.managed && this.guild.me.hasPermission(Permissions.FLAGS.MANAGE_EMOJIS); - } - - /** - * A collection of roles this emoji is active for (empty if all), mapped by role ID - * @type {Collection<Snowflake, 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.CDN(this.client.options.http.cdn).Emoji(this.id, this.animated ? 'gif' : 'png'); - } - - /** - * The identifier of this emoji, used for message reactions - * @type {string} - * @readonly - */ - get identifier() { - if (this.id) return `${this.name}:${this.id}`; - return encodeURIComponent(this.name); - } - - /** - * Data for editing an emoji. - * @typedef {Object} EmojiEditData - * @property {string} [name] The name of the emoji - * @property {Collection<Snowflake, Role>|Array<Snowflake|Role>} [roles] Roles to restrict emoji to - */ - - /** - * Edits the emoji. - * @param {EmojiEditData} data The new data for the emoji - * @param {string} [reason] Reason for editing this emoji - * @returns {Promise<Emoji>} - * @example - * // Edit an emoji - * emoji.edit({name: 'newemoji'}) - * .then(e => console.log(`Edited emoji ${e}`)) - * .catch(console.error); - */ - edit(data, reason) { - return this.client.rest.methods.updateEmoji(this, data, reason); - } - - /** - * Set the name of the emoji. - * @param {string} name The new name for the emoji - * @param {string} [reason] The reason for changing the emoji's name - * @returns {Promise<Emoji>} - */ - setName(name, reason) { - return this.edit({ name }, reason); - } - - /** - * Fetches the author for this emoji - * @returns {Promise<User>} - */ - fetchAuthor() { - if (this.managed) return Promise.reject(new Error('Emoji is managed and has no Author.')); - if (!this.guild.me.permissions.has(Permissions.FLAGS.MANAGE_EMOJIS)) { - return Promise.reject( - new Error(`Client must have Manage Emoji permission in guild ${this.guild} to see emoji authors.`) - ); - } - return this.client.rest.makeRequest('get', Constants.Endpoints.Guild(this.guild).Emoji(this.id), true) - .then(emoji => this.client.dataManager.newUser(emoji.user)); - } - - /** - * Add a role to the list of roles that can use this emoji. - * @param {Role} role The role to add - * @returns {Promise<Emoji>} - */ - addRestrictedRole(role) { - return this.addRestrictedRoles([role]); - } - - /** - * Add multiple roles to the list of roles that can use this emoji. - * @param {Role[]} roles Roles to add - * @returns {Promise<Emoji>} - */ - addRestrictedRoles(roles) { - const newRoles = new Collection(this.roles); - for (const role of roles) { - if (this.guild.roles.has(role.id)) newRoles.set(role.id, role); - } - return this.edit({ roles: newRoles }); - } - - /** - * Remove a role from the list of roles that can use this emoji. - * @param {Role} role The role to remove - * @returns {Promise<Emoji>} - */ - removeRestrictedRole(role) { - return this.removeRestrictedRoles([role]); - } - - /** - * Remove multiple roles from the list of roles that can use this emoji. - * @param {Role[]} roles Roles to remove - * @returns {Promise<Emoji>} - */ - removeRestrictedRoles(roles) { - const newRoles = new Collection(this.roles); - for (const role of roles) { - if (newRoles.has(role.id)) newRoles.delete(role.id); - } - return this.edit({ roles: newRoles }); - } - - - /** - * Deletes the emoji. - * @param {string} [reason] Reason for deleting the emoji - * @returns {Promise<Emoji>} - */ - delete(reason) { - return this.client.rest.methods.deleteEmoji(this, reason); - } - - /** - * 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() { - if (!this.id || !this.requiresColons) { - return this.name; - } - - return `<${this.animated ? 'a' : ''}:${this.name}:${this.id}>`; - } - - /** - * 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 - ); - } - } -} - -module.exports = Emoji; 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 0febf6c..0000000 --- a/node_modules/discord.js/src/structures/GroupDMChannel.js +++ /dev/null @@ -1,246 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interfaces/TextBasedChannel'); -const Collection = require('../util/Collection'); -const Constants = require('../util/Constants'); - -/* -{ 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 this 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 the DM is managed by an application - * @type {boolean} - */ - this.managed = data.managed; - - /** - * Application ID of the application that made this Group DM, if applicable - * @type {?string} - */ - this.applicationID = data.application_id; - - if (data.nicks) { - /** - * Nicknames for group members - * @type {?Collection<Snowflake, string>} - */ - this.nicks = new Collection(data.nicks.map(n => [n.id, n.nick])); - } - - if (!this.recipients) { - /** - * A collection of the recipients of this DM, mapped by their ID - * @type {Collection<Snowflake, 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); - } - } - - /** - * The ID of the last message in the channel, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = data.last_message_id; - - /** - * The timestamp when the last pinned message was pinned, if there was one - * @type {?number} - */ - this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; - } - - /** - * The owner of this Group DM - * @type {User} - * @readonly - */ - get owner() { - return this.client.users.get(this.ownerID); - } - - /** - * The URL to this guild's icon - * @type {?string} - * @readonly - */ - get iconURL() { - if (!this.icon) return null; - return Constants.Endpoints.Channel(this).Icon(this.client.options.http.cdn, this.icon); - } - - edit(data) { - const _data = {}; - if (data.name) _data.name = data.name; - if (typeof data.icon !== 'undefined') _data.icon = data.icon; - return this.client.rest.methods.updateGroupDMChannel(this, _data); - } - - /** - * 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; - } - - /** - * Add a user to the DM - * @param {UserResolvable|string} accessTokenOrID Access token or user resolvable - * @param {string} [nick] Permanent nickname to give the user (only available if a bot is creating the DM) - * @returns {Promise<GroupDMChannel>} - */ - - addUser(accessTokenOrID, nick) { - return this.client.rest.methods.addUserToGroupDM(this, { - nick, - id: this.client.resolver.resolveUserID(accessTokenOrID), - accessToken: accessTokenOrID, - }); - } - - /** - * Set a new GroupDMChannel icon. - * @param {Base64Resolvable|BufferResolvable} icon The new icon of the group dm - * @returns {Promise<GroupDMChannel>} - * @example - * // Edit the group dm icon - * channel.setIcon('./icon.png') - * .then(updated => console.log('Updated the channel icon')) - * .catch(console.error); - */ - setIcon(icon) { - return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data })); - } - - /** - * Sets a new name for this Group DM. - * @param {string} name New name for this Group DM - * @returns {Promise<GroupDMChannel>} - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Removes a user from this Group DM. - * @param {UserResolvable} user User to remove - * @returns {Promise<GroupDMChannel>} - */ - removeUser(user) { - const id = this.client.resolver.resolveUserID(user); - return this.client.rest.methods.removeUserFromGroupDM(this, id); - } - - /** - * 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 - /* eslint-disable no-empty-function */ - get lastPinAt() {} - send() {} - sendMessage() {} - sendEmbed() {} - sendFile() {} - sendFiles() {} - sendCode() {} - fetchMessage() {} - fetchMessages() {} - fetchPinnedMessages() {} - search() {} - startTyping() {} - stopTyping() {} - get typing() {} - get typingCount() {} - createCollector() {} - createMessageCollector() {} - awaitMessages() {} - // Doesn't work on Group DMs; bulkDelete() {} - acknowledge() {} - _cacheMessage() {} -} - -TextBasedChannel.applyToClass(GroupDMChannel, true, ['bulkDelete']); - -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 69acfe1..0000000 --- a/node_modules/discord.js/src/structures/Guild.js +++ /dev/null @@ -1,1711 +0,0 @@ -const util = require('util'); -const Long = require('long'); -const User = require('./User'); -const Role = require('./Role'); -const Emoji = require('./Emoji'); -const Presence = require('./Presence').Presence; -const GuildMember = require('./GuildMember'); -const Integration = require('./Integration'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const Util = require('../util/Util'); -const Snowflake = require('../util/Snowflake'); -const SystemChannelFlags = require('../util/SystemChannelFlags'); - -/** - * 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 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<Snowflake, 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<Snowflake, 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<Snowflake, Role>} - */ - this.roles = new Collection(); - - /** - * A collection of presences in this guild - * @type {Collection<Snowflake, Presence>} - */ - this.presences = new Collection(); - - /** - * Whether the bot has been removed from the guild - * @type {boolean} - */ - this.deleted = false; - - 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 {Snowflake} - */ - this.id = data.id; - } else { - this.setup(data); - if (!data.channels) this.available = false; - } - } - - /* eslint-disable complexity */ - /** - * 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 - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image (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 - * @type {number} - */ - this.memberCount = data.member_count || this.memberCount; - - /** - * Whether the guild is "large" (has more than 250 members) - * @type {boolean} - */ - this.large = Boolean('large' in data ? 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 {?Snowflake} - */ - this.applicationID = data.application_id; - - /** - * 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; - - /** - * The ID of the system channel - * @type {?Snowflake} - */ - this.systemChannelID = data.system_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 explicit content filter level of the guild - * @type {number} - */ - this.explicitContentFilter = data.explicit_content_filter; - - /** - * The required MFA level for the guild - * @type {number} - */ - this.mfaLevel = data.mfa_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; - - /** - * The value set for a guild's default message notifications - * @type {DefaultMessageNotifications|number} - */ - this.defaultMessageNotifications = Constants.DefaultMessageNotifications[data.default_message_notifications] || - data.default_message_notifications; - - /** - * The value for the guild's system channel flags - * @type {Readonly<SystemChannelFlags>} - */ - this.systemChannelFlags = new SystemChannelFlags(data.system_channel_flags).freeze(); - - /** - * The type of premium tier: - * * 0: NONE - * * 1: TIER_1 - * * 2: TIER_2 - * * 3: TIER_3 - * @typedef {number} PremiumTier - */ - - /** - * The premium tier on this guild - * @type {PremiumTier} - */ - this.premiumTier = data.premium_tier; - - /** - * The total number of users currently boosting this server - * @type {?number} - * @name Guild#premiumSubscriptionCount - */ - if (typeof data.premium_subscription_count !== 'undefined') { - this.premiumSubscriptionCount = data.premium_subscription_count; - } - - /** - * The hash of the guild banner - * @type {?string} - */ - this.banner = data.banner; - - /** - * The description of the guild, if any - * @type {?string} - */ - this.description = data.description; - - /** - * The embed channel ID, if enabled - * @type {?string} - * @name Guild#embedChannelID - */ - if (typeof data.embed_channel_id !== 'undefined') this.embedChannelID = data.embed_channel_id; - - /** - * The maximum amount of members the guild can have - * <info>You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter</info> - * @type {?number} - * @name Guild#maximumMembers - */ - if (typeof data.max_members !== 'undefined') this.maximumMembers = data.max_members || 250000; - - /** - * The maximum amount of presences the guild can have - * <info>You will need to fetch the guild using {@link Guild#fetch} if you want to receive this parameter</info> - * @type {?number} - * @name Guild#maximumPresences - */ - if (typeof data.max_presences !== 'undefined') this.maximumPresences = data.max_presences || 5000; - - /** - * Whether widget images are enabled on this guild - * @type {?boolean} - * @name Guild#widgetEnabled - */ - if (typeof data.widget_enabled !== 'undefined') this.widgetEnabled = data.widget_enabled; - - /** - * The widget channel ID, if enabled - * @type {?string} - * @name Guild#widgetChannelID - */ - if (typeof data.widget_channel_id !== 'undefined') this.widgetChannelID = data.widget_channel_id; - - /** - * The vanity URL code of the guild, if any - * @type {?string} - */ - this.vanityURLCode = data.vanity_url_code; - - this.id = data.id; - this.available = !data.unavailable; - this.features = data.features || this.features || []; - - /** - * The ID of the rules channel for the guild - * <info>This is only available on guilds with the `PUBLIC` feature</info> - * @type {?Snowflake} - */ - this.rulesChannelID = data.rules_channel_id; - - /** - * The ID of the public updates channel for the guild - * <info>This is only available on guilds with the `PUBLIC` feature</info> - * @type {?Snowflake} - */ - this.publicUpdatesChannelID = data.public_updates_channel_id; - - 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 {Snowflake} - */ - 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); - const voiceChannel = this.channels.get(voiceState.channel_id); - if (member && voiceChannel) { - member.serverMute = voiceState.mute; - member.serverDeaf = voiceState.deaf; - member.selfMute = voiceState.self_mute; - member.selfDeaf = voiceState.self_deaf; - member.selfStream = voiceState.self_stream || false; - member.voiceSessionID = voiceState.session_id; - member.voiceChannelID = voiceState.channel_id; - voiceChannel.members.set(member.user.id, member); - } - } - } - - if (!this.emojis) { - /** - * A collection of emojis that are in this guild - * The key is the emoji's ID, the value is the emoji - * @type {Collection<Snowflake, Emoji>} - */ - this.emojis = new Collection(); - for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji)); - } else { - this.client.actions.GuildEmojisUpdate.handle({ - guild_id: this.id, - emojis: data.emojis, - }); - } - } - - /** - * The timestamp the guild was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the guild was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Embed channel for this guild - * @type {?TextChannel} - * @readonly - */ - get embedChannel() { - return this.channels.get(this.embedChannelID) || null; - } - - /** - * Widget channel for this guild - * @type {?TextChannel} - * @readonly - */ - get widgetChannel() { - return this.channels.get(this.widgetChannelID) || null; - } - - /** - * The time the client user joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * If this guild is verified - * @type {boolean} - * @readonly - */ - get verified() { - return this.features.includes('VERIFIED'); - } - - /** - * The URL to this guild's icon - * @type {?string} - * @readonly - */ - get iconURL() { - if (!this.icon) return null; - return Constants.Endpoints.Guild(this).Icon(this.client.options.http.cdn, this.icon); - } - - /** - * The URL to this guild's banner. - * @type {?string} - * @readonly - */ - get bannerURL() { - if (!this.banner) return null; - return Constants.Endpoints.Guild(this).Banner(this.client.options.http.cdn, this.banner); - } - - /** - * The acronym that shows up in place of a guild icon. - * @type {string} - * @readonly - */ - get nameAcronym() { - return this.name.replace(/\w+/g, name => name[0]).replace(/\s/g, ''); - } - - /** - * The URL to this guild's splash - * @type {?string} - * @readonly - */ - get splashURL() { - if (!this.splash) return null; - return Constants.Endpoints.Guild(this).Splash(this.client.options.http.cdn, this.splash); - } - - /** - * The owner of the guild - * @type {?GuildMember} - * @readonly - */ - get owner() { - return this.members.get(this.ownerID); - } - - /** - * AFK voice channel for this guild - * @type {?VoiceChannel} - * @readonly - */ - get afkChannel() { - return this.client.channels.get(this.afkChannelID) || null; - } - - /** - * System channel for this guild - * @type {?GuildChannel} - * @readonly - */ - get systemChannel() { - return this.client.channels.get(this.systemChannelID) || null; - } - - /** - * 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 position of this guild - * <warn>This is only available when using a user account.</warn> - * @type {?number} - * @readonly - * @deprecated - */ - get position() { - if (this.client.user.bot) return null; - if (!this.client.user.settings.guildPositions) return null; - return this.client.user.settings.guildPositions.indexOf(this.id); - } - - /** - * Whether the guild is muted - * <warn>This is only available when using a user account.</warn> - * @type {?boolean} - * @readonly - * @deprecated - */ - get muted() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.id).muted; - } catch (err) { - return false; - } - } - - /** - * The type of message that should notify you - * <warn>This is only available when using a user account.</warn> - * @type {?MessageNotificationType} - * @readonly - * @deprecated - */ - get messageNotifications() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.id).messageNotifications; - } catch (err) { - return null; - } - } - - /** - * Whether to receive mobile push notifications - * <warn>This is only available when using a user account.</warn> - * @type {?boolean} - * @readonly - * @deprecated - */ - get mobilePush() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.id).mobilePush; - } catch (err) { - return false; - } - } - - /** - * Whether to suppress everyone messages - * <warn>This is only available when using a user account.</warn> - * @type {?boolean} - * @readonly - * @deprecated - */ - get suppressEveryone() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.id).suppressEveryone; - } catch (err) { - return null; - } - } - - /** - * The `@everyone` role of the guild - * @type {Role} - * @readonly - */ - get defaultRole() { - return this.roles.get(this.id); - } - - /** - * Rules channel for this guild - * <info>This is only available on guilds with the `PUBLIC` feature</info> - * @type {?TextChannel} - * @readonly - */ - get rulesChannel() { - return this.client.channels.get(this.rulesChannelID) || null; - } - - /** - * Public updates channel for this guild - * <info>This is only available on guilds with the `PUBLIC` feature</info> - * @type {?TextChannel} - * @readonly - */ - get publicUpdatesChannel() { - return this.client.channels.get(this.publicUpdatesChannelID) || null; - } - - /** - * The client user as a GuildMember of this guild - * @type {?GuildMember} - * @readonly - */ - get me() { - return this.members.get(this.client.user.id); - } - - /** - * Fetches a collection of roles in the current guild sorted by position - * @type {Collection<Snowflake, Role>} - * @readonly - * @private - */ - get _sortedRoles() { - return this._sortPositionWithID(this.roles); - } - - /** - * 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); - } - - /** - * Fetches this guild. - * @returns {Promise<Guild>} - */ - fetch() { - return this.client.rest.methods.getGuild(this).then(data => { - this.setup(data); - - return this; - }); - } - - /** - * An object containing information about a guild member's ban. - * @typedef {Object} BanInfo - * @property {User} user User that was banned - * @property {?string} reason Reason the user was banned - */ - - /** - * Fetch a ban for a user. - * @returns {Promise<BanInfo>} - * @param {UserResolvable} user The user to fetch the ban for - * @example - * // Get ban - * guild.fetchBan(message.author) - * .then(({ user, reason }) => console.log(`${user.tag} was banned for the reason: ${reason}.`)) - * .catch(console.error); - */ - fetchBan(user) { - return this.client.rest.methods.getGuildBan(this, user); - } - - /** - * Fetch a collection of banned users in this guild. - * @returns {Promise<Collection<Snowflake, User|BanInfo>>} - * @param {boolean} [withReasons=false] Whether or not to include the ban reason(s) - * @example - * // Fetch bans in guild - * guild.fetchBans() - * .then(bans => console.log(`This guild has ${bans.size} bans`)) - * .catch(console.error); - */ - fetchBans(withReasons = false) { - if (withReasons) return this.client.rest.methods.getGuildBans(this); - return this.client.rest.methods.getGuildBans(this) - .then(bans => { - const users = new Collection(); - for (const ban of bans.values()) users.set(ban.user.id, ban.user); - return users; - }); - } - - /** - * Fetches a collection of integrations to this guild. - * Resolves with a collection mapping integrations by their ids. - * @returns {Promise<Collection<string, Integration>>} - * @example - * // Fetch integrations - * guild.fetchIntegrations() - * .then(integrations => console.log(`Fetched ${integrations.size} integrations`)) - * .catch(console.error); - */ - fetchIntegrations() { - return this.client.rest.methods.getIntegrations(this).then(data => - data.reduce((collection, integration) => - collection.set(integration.id, new Integration(this.client, integration, this)), - new Collection()) - ); - } - - /** - * The data for creating an integration. - * @typedef {Object} IntegrationData - * @property {string} id The integration id - * @property {string} type The integration type - */ - - /** - * Creates an integration by attaching an integration object - * @param {IntegrationData} data The data for thes integration - * @param {string} reason Reason for creating the integration - * @returns {Promise<Guild>} - */ - createIntegration(data, reason) { - return this.client.rest.methods.createIntegration(this, data, reason) - .then(() => this); - } - - /** - * Fetch a collection of invites to this guild. - * Resolves with a collection mapping invites by their codes. - * @returns {Promise<Collection<string, Invite>>} - * @example - * // Fetch invites - * guild.fetchInvites() - * .then(invites => console.log(`Fetched ${invites.size} invites`)) - * .catch(console.error); - * @example - * // Fetch invite creator by their id - * guild.fetchInvites() - * .then(invites => console.log(invites.find(invite => invite.inviter.id === '84484653687267328'))) - * .catch(console.error); - */ - fetchInvites() { - return this.client.rest.methods.getGuildInvites(this); - } - - /** - * Fetches the vanity url invite code to this guild. - * Resolves with a string matching the vanity url invite code, not the full url. - * @returns {Promise<string>} - * @example - * // Fetch invites - * guild.fetchVanityCode() - * .then(code => { - * console.log(`Vanity URL: https://discord.gg/${code}`); - * }) - * .catch(console.error); - */ - fetchVanityCode() { - if (!this.features.includes('VANITY_URL')) { - return Promise.reject(new Error('This guild does not have the VANITY_URL feature enabled.')); - } - return this.client.rest.methods.getGuildVanityCode(this); - } - - - /** - * Fetch all webhooks for the guild. - * @returns {Promise<Collection<Snowflake, Webhook>>} - * @example - * // Fetch webhooks - * guild.fetchWebhooks() - * .then(webhooks => console.log(`Fetched ${webhooks.size} webhooks`)) - * .catch(console.error); - */ - fetchWebhooks() { - return this.client.rest.methods.getGuildWebhooks(this); - } - - /** - * Fetch available voice regions. - * @returns {Promise<Collection<string, VoiceRegion>>} - * @example - * // Fetch voice regions - * guild.fetchVoiceRegions() - * .then(console.log) - * .catch(console.error); - */ - fetchVoiceRegions() { - return this.client.rest.methods.fetchVoiceRegions(this.id); - } - - /** - * The Guild Embed object - * @typedef {Object} GuildEmbedData - * @property {boolean} enabled Whether the embed is enabled - * @property {?ChannelResolvable} channel The embed channel - */ - - /** - * Fetches the guild embed. - * @returns {Promise<GuildEmbedData>} - * @example - * // Fetches the guild embed - * guild.fetchEmbed() - * .then(embed => console.log(`The embed is ${embed.enabled ? 'enabled' : 'disabled'}`)) - * .catch(console.error); - */ - fetchEmbed() { - return this.client.rest.methods.fetchEmbed(this.id); - } - - /** - * Fetch audit logs for this guild. - * @param {Object} [options={}] Options for fetching audit logs - * @param {Snowflake|GuildAuditLogsEntry} [options.before] Limit to entries from before specified entry - * @param {Snowflake|GuildAuditLogsEntry} [options.after] Limit to entries from after specified entry - * @param {number} [options.limit] Limit number of entries - * @param {UserResolvable} [options.user] Only show entries involving this user - * @param {AuditLogAction} [options.type] Only show entries involving this action type - * @returns {Promise<GuildAuditLogs>} - * @example - * // Output audit log entries - * guild.fetchAuditLogs() - * .then(audit => console.log(audit.entries.first())) - * .catch(console.error); - */ - fetchAuditLogs(options) { - return this.client.rest.methods.getGuildAuditLogs(this, options); - } - - /** - * Adds a user to the guild using OAuth2. Requires the `CREATE_INSTANT_INVITE` permission. - * @param {UserResolvable} user User to add to the guild - * @param {Object} options Options for the addition - * @param {string} options.accessToken An OAuth2 access token for the user with the `guilds.join` scope granted to the - * bot's application - * @param {string} [options.nick] Nickname to give the member (requires `MANAGE_NICKNAMES`) - * @param {Collection<Snowflake, Role>|Role[]|Snowflake[]} [options.roles] Roles to add to the member - * (requires `MANAGE_ROLES`) - * @param {boolean} [options.mute] Whether the member should be muted (requires `MUTE_MEMBERS`) - * @param {boolean} [options.deaf] Whether the member should be deafened (requires `DEAFEN_MEMBERS`) - * @returns {Promise<GuildMember>} - */ - addMember(user, options) { - user = this.client.resolver.resolveUserID(user); - if (this.members.has(user)) return Promise.resolve(this.members.get(user)); - return this.client.rest.methods.putGuildMember(this, user, options); - } - - /** - * Fetch a single guild member from a user. - * @param {UserResolvable} user The user to fetch the member for - * @param {boolean} [cache=true] Insert the member into the members cache - * @returns {Promise<GuildMember>} - * @example - * // Fetch a guild member - * guild.fetchMember(message.author) - * .then(console.log) - * .catch(console.error); - */ - fetchMember(user, cache = true) { - const userID = this.client.resolver.resolveUserID(user); - if (!userID) return Promise.reject(new Error('Invalid id provided.')); - const member = this.members.get(userID); - if (member && member.joinedTimestamp) return Promise.resolve(member); - return this.client.rest.methods.getGuildMember(this, userID, cache); - } - - /** - * 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=''] Limit fetch to members with similar usernames - * @param {number} [limit=0] Maximum number of members to request - * @returns {Promise<Guild>} - * @example - * // Fetch guild members - * guild.fetchMembers() - * .then(console.log) - * .catch(console.error); - * @example - * // Fetches a maximum of 1 member with the given query - * guild.fetchMembers('hydrabolt', 1) - * .then(console.log) - * .catch(console.error); - */ - fetchMembers(query = '', limit = 0) { - return new Promise((resolve, reject) => { - if (this.memberCount === this.members.size) { - resolve(this); - return; - } - this.client.ws.send({ - op: Constants.OPCodes.REQUEST_GUILD_MEMBERS, - d: { - guild_id: this.id, - query, - limit, - }, - }); - const handler = (members, guild) => { - if (guild.id !== this.id) return; - if (this.memberCount === this.members.size || members.length < 1000) { - this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler); - resolve(this); - } - }; - this.client.on(Constants.Events.GUILD_MEMBERS_CHUNK, handler); - this.client.setTimeout(() => reject(new Error('Members didn\'t arrive in time.')), 120 * 1000); - }); - } - - /** - * Performs a search within the entire guild. - * <warn>This is only available when using a user account.</warn> - * @param {MessageSearchOptions} [options={}] Options to pass to the search - * @returns {Promise<MessageSearchResult>} - * @deprecated - * @example - * guild.search({ - * content: 'discord.js', - * before: '2016-11-17' - * }) - * .then(res => { - * const hit = res.messages[0].find(m => m.hit).content; - * console.log(`I found: **${hit}**, total results: ${res.totalResults}`); - * }) - * .catch(console.error); - */ - search(options = {}) { - return this.client.rest.methods.search(this, options); - } - - /** - * 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 {number} [explicitContentFilter] The level of the explicit content filter - * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild - * @property {ChannelResolvable} [systemChannel] The system channel of the guild - * @property {number} [afkTimeout] The AFK timeout of the guild - * @property {Base64Resolvable} [icon] The icon of the guild - * @property {Base64Resolvable} [banner] The banner of the guild - * @property {GuildMemberResolvable} [owner] The owner of the guild - * @property {Base64Resolvable} [splash] The splash screen of the guild - * @property {SystemChannelFlagsResolvable} [systemChannelFlags] The system channel flags of the guild - */ - - /** - * Updates the guild with new information - e.g. a new name. - * @param {GuildEditData} data The data to update the guild with - * @param {string} [reason] Reason for editing the guild - * @returns {Promise<Guild>} - * @example - * // Set the guild name and region - * guild.edit({ - * name: 'Discord Guild', - * region: 'london', - * }) - * .then(g => console.log(`Changed guild name to ${g} and region to ${g.region}`)) - * .catch(console.error); - */ - edit(data, reason) { - const _data = {}; - if (data.name) _data.name = data.name; - if (data.region) _data.region = data.region; - if (typeof data.verificationLevel !== 'undefined') _data.verification_level = Number(data.verificationLevel); - if (typeof data.afkChannel !== 'undefined') { - _data.afk_channel_id = this.client.resolver.resolveChannelID(data.afkChannel); - } - if (typeof data.systemChannel !== 'undefined') { - _data.system_channel_id = this.client.resolver.resolveChannelID(data.systemChannel); - } - if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout); - if (typeof data.icon !== 'undefined') _data.icon = data.icon; - if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id; - if (typeof data.splash !== 'undefined') _data.splash = data.splash; - if (typeof data.banner !== 'undefined') _data.banner = data.banner; - if (typeof data.explicitContentFilter !== 'undefined') { - _data.explicit_content_filter = Number(data.explicitContentFilter); - } - if (typeof data.defaultMessageNotifications !== 'undefined') { - _data.default_message_notifications = typeof data.defaultMessageNotifications === 'string' ? - Constants.DefaultMessageNotifications.indexOf(data.defaultMessageNotifications) : - Number(data.defaultMessageNotifications); - } - if (typeof data.systemChannelFlags !== 'undefined') { - _data.system_channel_flags = SystemChannelFlags.resolve(data.systemChannelFlags); - } - return this.client.rest.methods.updateGuild(this, _data, reason); - } - - /** - * Sets a new guild banner. - * @param {BufferResolvable|Base64Resolvable} banner The new banner of the guild - * @param {string} [reason] Reason for changing the guild's banner - * @returns {Guild} - */ - setBanner(banner, reason) { - return this.client.resolver.resolveImage(banner).then(data => this.edit({ banner: data }, reason)); - } - - /** - * Edit the level of the explicit content filter. - * @param {number} explicitContentFilter The new level of the explicit content filter - * @param {string} [reason] Reason for changing the level of the guild's explicit content filter - * @returns {Promise<Guild>} - */ - setExplicitContentFilter(explicitContentFilter, reason) { - return this.edit({ explicitContentFilter }, reason); - } - - /** - * Edits the setting of the default message notifications of the guild. - * @param {DefaultMessageNotifications|number} defaultMessageNotifications - * The new setting for the default message notifications - * @param {string} [reason] Reason for changing the setting of the default message notifications - * @returns {Promise<Guild>} - */ - setDefaultMessageNotifications(defaultMessageNotifications, reason) { - return this.edit({ defaultMessageNotifications }, reason); - } - - /** - * Edits the flags of the default message notifications of the guild. - * @param {SystemChannelFlagsResolvable} systemChannelFlags The new flags for the default message notifications - * @param {string} [reason] Reason for changing the flags of the default message notifications - * @returns {Promise<Guild>} - */ - setSystemChannelFlags(systemChannelFlags, reason) { - return this.edit({ systemChannelFlags }, reason); - } - - /** - * Edit the name of the guild. - * @param {string} name The new name of the guild - * @param {string} [reason] Reason for changing the guild's name - * @returns {Promise<Guild>} - * @example - * // Edit the guild name - * guild.setName('Discord Guild') - * .then(g => console.log(`Updated guild name to ${g}`)) - * .catch(console.error); - */ - setName(name, reason) { - return this.edit({ name }, reason); - } - - /** - * Edit the region of the guild. - * @param {string} region The new region of the guild - * @param {string} [reason] Reason for changing the guild's region - * @returns {Promise<Guild>} - * @example - * // Edit the guild region - * guild.setRegion('london') - * .then(g => console.log(`Updated guild region to ${g.region}`)) - * .catch(console.error); - */ - setRegion(region, reason) { - return this.edit({ region }, reason); - } - - /** - * Edit the verification level of the guild. - * @param {number} verificationLevel The new verification level of the guild - * @param {string} [reason] Reason for changing the guild's verification level - * @returns {Promise<Guild>} - * @example - * // Edit the guild verification level - * guild.setVerificationLevel(1) - * .then(g => console.log(`Updated guild verification level to ${g.verificationLevel}`)) - * .catch(console.error); - */ - setVerificationLevel(verificationLevel, reason) { - return this.edit({ verificationLevel }, reason); - } - - /** - * Edit the AFK channel of the guild. - * @param {ChannelResolvable} afkChannel The new AFK channel - * @param {string} [reason] Reason for changing the guild's AFK channel - * @returns {Promise<Guild>} - * @example - * // Edit the guild AFK channel - * guild.setAFKChannel(channel) - * .then(g => console.log(`Updated guild AFK channel to ${g.afkChannel.name}`)) - * .catch(console.error); - */ - setAFKChannel(afkChannel, reason) { - return this.edit({ afkChannel }, reason); - } - - /** - * Edit the system channel of the guild. - * @param {ChannelResolvable} systemChannel The new system channel - * @param {string} [reason] Reason for changing the guild's system channel - * @returns {Promise<Guild>} - */ - setSystemChannel(systemChannel, reason) { - return this.edit({ systemChannel }, reason); - } - - /** - * Edit the AFK timeout of the guild. - * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK - * @param {string} [reason] Reason for changing the guild's AFK timeout - * @returns {Promise<Guild>} - * @example - * // Edit the guild AFK channel - * guild.setAFKTimeout(60) - * .then(g => console.log(`Updated guild AFK timeout to ${g.afkTimeout}`)) - * .catch(console.error); - */ - setAFKTimeout(afkTimeout, reason) { - return this.edit({ afkTimeout }, reason); - } - - /** - * Set a new guild icon. - * @param {Base64Resolvable|BufferResolvable} icon The new icon of the guild - * @param {string} [reason] Reason for changing the guild's icon - * @returns {Promise<Guild>} - * @example - * // Edit the guild icon - * guild.setIcon('./icon.png') - * .then(console.log) - * .catch(console.error); - */ - setIcon(icon, reason) { - return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data, reason })); - } - - /** - * Sets a new owner of the guild. - * @param {GuildMemberResolvable} owner The new owner of the guild - * @param {string} [reason] Reason for setting the new owner - * @returns {Promise<Guild>} - * @example - * // Edit the guild owner - * guild.setOwner(guild.members.first()) - * .then(g => console.log(`Updated the guild owner to ${g.owner.displayName}`)) - * .catch(console.error); - */ - setOwner(owner, reason) { - return this.edit({ owner }, reason); - } - - /** - * Set a new guild splash screen. - * @param {BufferResolvable|Base64Resolvable} splash The new splash screen of the guild - * @param {string} [reason] Reason for changing the guild's splash screen - * @returns {Promise<Guild>} - * @example - * // Edit the guild splash - * guild.setSplash('./splash.png') - * .then(console.log) - * .catch(console.error); - */ - setSplash(splash) { - return this.client.resolver.resolveImage(splash).then(data => this.edit({ splash: data })); - } - - /** - * Sets the position of the guild in the guild listing. - * <warn>This is only available when using a user account.</warn> - * @param {number} position Absolute or relative position - * @param {boolean} [relative=false] Whether to position relatively or absolutely - * @returns {Promise<Guild>} - * @deprecated - */ - setPosition(position, relative) { - if (this.client.user.bot) { - return Promise.reject(new Error('Setting guild position is only available for user accounts')); - } - return this.client.user.settings.setGuildPosition(this, position, relative); - } - - /** - * Marks all messages in this guild as read. - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<Guild>} - * @deprecated - */ - acknowledge() { - return this.client.rest.methods.ackGuild(this); - } - - /** - * Allow direct messages from guild members. - * <warn>This is only available when using a user account.</warn> - * @param {boolean} allow Whether to allow direct messages - * @returns {Promise<Guild>} - * @deprecated - */ - allowDMs(allow) { - const settings = this.client.user.settings; - if (allow) return settings.removeRestrictedGuild(this); - else return settings.addRestrictedGuild(this); - } - - /** - * Bans a user from the guild. - * @param {UserResolvable} user The user to ban - * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a - * string, the ban reason. Supplying an object allows you to do both. - * @param {number} [options.days=0] Number of days of messages to delete - * @param {string} [options.reason] Reason for banning - * @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 by ID - * guild.ban('some user ID') - * .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild}`)) - * .catch(console.error); - * @example - * // Ban a user by object with reason and days - * guild.ban(user, { days: 7, reason: 'He needed to go' }) - * .then(console.log) - * .catch(console.error); - */ - ban(user, options = {}) { - if (typeof options === 'number') { - options = { reason: null, 'delete-message-days': options }; - } else if (typeof options === 'string') { - options = { reason: options, 'delete-message-days': 0 }; - } - if (options.days) options['delete-message-days'] = options.days; - return this.client.rest.methods.banGuildMember(this, user, options); - } - - /** - * Unbans a user from the guild. - * @param {UserResolvable} user The user to unban - * @param {string} [reason] Reason for unbanning the user - * @returns {Promise<User>} - * @example - * // Unban a user by ID (or with a user/guild member object) - * guild.unban('some user ID') - * .then(user => console.log(`Unbanned ${user.username} from ${guild}`)) - * .catch(console.error); - */ - unban(user, reason) { - return this.client.rest.methods.unbanGuildMember(this, user, reason); - } - - /** - * 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 - * @param {string} [reason] Reason for this prune - * @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, reason) { - if (typeof days !== 'number') throw new TypeError('Days must be a number.'); - return this.client.rest.methods.pruneGuildMembers(this, days, dry, reason); - } - - /** - * Syncs this guild (already done automatically every 30 seconds). - * <warn>This is only available when using a user account.</warn> - * @deprecated - */ - sync() { - if (!this.client.user.bot) this.client.syncGuilds([this]); - } - - /** - * Overwrites to use when creating a channel or replacing overwrites - * @typedef {Object} ChannelCreationOverwrites - * @property {PermissionResolvable} [allow] The permissions to allow - * @property {PermissionResolvable} [allowed] The permissions to allow - * **(deprecated)** - * @property {PermissionResolvable} [deny] The permissions to deny - * @property {PermissionResolvable} [denied] The permissions to deny - * **(deprecated)** - * @property {GuildMemberResolvable|RoleResolvable} id Member or role this overwrite is for - */ - - /** - * Creates a new channel in the guild. - * @param {string} name The name of the new channel - * @param {string|ChannelData} [typeOrOptions='text'] - * The type of the new channel, one of `text`, `voice`, `category`, `news`, or `store`. **(deprecated, use options)** - * Alternatively options for the new channel, overriding the following parameters. - * @param {ChannelCreationOverwrites[]|Collection<Snowflake, PermissionOverwrites>} [permissionOverwrites] - * Permission overwrites **(deprecated, use options)** - * @param {string} [reason] Reason for creating this channel **(deprecated, use options)** - * @returns {Promise<CategoryChannel|TextChannel|VoiceChannel>} - * @example - * // Create a new text channel - * guild.createChannel('new-general', { type: 'text' }) - * .then(console.log) - * .catch(console.error); - * @example - * // Create a new category channel with permission overwrites - * guild.createChannel('new-category', { - * type: 'category', - * permissionOverwrites: [{ - * id: guild.id, - * deny: ['MANAGE_MESSAGES'], - * allow: ['SEND_MESSAGES'] - * }] - * }) - * .then(console.log) - * .catch(console.error); - */ - createChannel(name, typeOrOptions, permissionOverwrites, reason) { - if (!typeOrOptions || (typeof typeOrOptions === 'string')) { - if (typeOrOptions) { - process.emitWarning( - 'Guild#createChannel: Create channels with an options object instead of separate parameters', - 'DeprecationWarning' - ); - } - typeOrOptions = { - type: typeOrOptions, - permissionOverwrites, - reason, - }; - } - return this.client.rest.methods.createChannel(this, name, typeOrOptions); - } - - /** - * The data needed for updating a channel's position. - * @typedef {Object} ChannelPosition - * @property {ChannelResolvable} channel Channel to update - * @property {number} position New position for the channel - */ - - /** - * Batch-updates the guild's channels' positions. - * @param {ChannelPosition[]} channelPositions Channel positions to update - * @returns {Promise<Guild>} - * @example - * guild.updateChannels([{ channel: channelID, position: newChannelIndex }]) - * .then(g => console.log(`Updated channel positions for ${g}`)) - * .catch(console.error); - */ - setChannelPositions(channelPositions) { - channelPositions = channelPositions.map(({ channel, position }) => ({ id: channel.id || channel, position })); - return this.client.rest.methods.setChannelPositions(this.id, channelPositions); - } - - /** - * The data needed for updating a role's position. - * @typedef {Object} RolePosition - * @property {RoleResolvable} role Role to update - * @property {number} position New position for the role - */ - - /** - * Batch-updates the guild's role's positions. - * @param {RolePosition[]} rolePositions Role positions to update - * @returns {Promise<Guild>} - */ - setRolePositions(rolePositions) { - rolePositions = rolePositions.map(({ role, position }) => ({ id: role.id || role, position })); - return this.client.rest.methods.setRolePositions(this.id, rolePositions); - } - - /** - * Edits the guild's embed. - * @param {GuildEmbedData} embed The embed for the guild - * @param {string} [reason] Reason for changing the guild's embed - * @returns {Promise<Guild>} - */ - setEmbed(embed, reason) { - return this.client.rest.methods.updateEmbed(this.id, embed, reason) - .then(() => this); - } - - /** - * Creates a new role in the guild with given information. - * @param {RoleData} [data] The data to update the role with - * @param {string} [reason] Reason for creating this role - * @returns {Promise<Role>} - * @example - * // Create a new role - * guild.createRole() - * .then(role => console.log(`Created new role with name ${role.name}`)) - * .catch(console.error); - * @example - * // Create a new role with data - * guild.createRole({ - * name: 'Super Cool People', - * color: 'BLUE', - * }) - * .then(role => console.log(`Created new role with name ${role.name} and color ${role.color}`)) - * .catch(console.error) - */ - createRole(data = {}, reason) { - return this.client.rest.methods.createGuildRole(this, data, reason); - } - - /** - * Creates a new custom emoji in the guild. - * @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji - * @param {string} name The name for the emoji - * @param {Collection<Snowflake, Role>|Role[]} [roles] Roles to limit the emoji to - * @param {string} [reason] Reason for creating 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, roles, reason) { - if (typeof attachment === 'string' && attachment.startsWith('data:')) { - return this.client.rest.methods.createEmoji(this, attachment, name, roles, reason); - } else { - return this.client.resolver.resolveImage(attachment).then(data => - this.client.rest.methods.createEmoji(this, data, name, roles, reason) - ); - } - } - - /** - * Delete an emoji. - * @param {Emoji|string} emoji The emoji to delete - * @param {string} [reason] Reason for deleting the emoji - * @returns {Promise} - * @deprecated - */ - deleteEmoji(emoji, reason) { - if (typeof emoji === 'string') emoji = this.emojis.get(emoji); - if (!(emoji instanceof Emoji)) throw new TypeError('Emoji must be either an instance of Emoji or an ID'); - return emoji.delete(reason); - } - - /** - * 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); - } - - /** - * 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 The 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 && - Util.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.selfStream = voiceState.self_stream || false; - 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.connection.status === Constants.Status.READY && emitEvent && !existing) { - this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member); - } - - return member; - } - - _updateMember(member, data) { - const oldMember = Util.cloneObject(member); - - if (data.premium_since) member.premiumSinceTimestamp = new Date(data.premium_since).getTime(); - if (data.roles) member._roles = data.roles; - if (typeof data.nick !== 'undefined') member.nickname = data.nick; - - const notSame = member.nickname !== oldMember.nickname || - member.premiumSinceTimestamp !== oldMember.premiumSinceTimestamp || - !Util.arraysEqual(member._roles, oldMember._roles); - - if (this.client.ws.connection.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) { - if (guildMember.voiceChannel) guildMember.voiceChannel.members.delete(guildMember.id); - this.members.delete(guildMember.id); - } - - _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, this.client)); - } - - /** - * 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 - * @param {boolean} [relative=false] Position Moves the role relative to its current position - * @returns {Promise<Guild>} - */ - setRolePosition(role, position, relative = false) { - if (typeof role === 'string') { - role = this.roles.get(role); - if (!role) return Promise.reject(new Error('Supplied role is not a role or snowflake.')); - } - - position = Number(position); - if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.')); - - let updatedRoles = this._sortedRoles.array(); - - Util.moveElementInArray(updatedRoles, role, position, relative); - - updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i })); - return this.client.rest.methods.setRolePositions(this.id, updatedRoles); - } - - /** - * Set the position of a channel in this guild. - * @param {string|GuildChannel} channel The channel to edit, can be a channel object or a channel ID - * @param {number} position The new position of the channel - * @param {boolean} [relative=false] Position Moves the channel relative to its current position - * @returns {Promise<Guild>} - */ - setChannelPosition(channel, position, relative = false) { - if (typeof channel === 'string') { - channel = this.channels.get(channel); - if (!channel) return Promise.reject(new Error('Supplied channel is not a channel or snowflake.')); - } - - position = Number(position); - if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.')); - - let updatedChannels = this._sortedChannels(channel.type).array(); - - Util.moveElementInArray(updatedChannels, channel, position, relative); - - updatedChannels = updatedChannels.map((c, i) => ({ id: c.id, position: i })); - return this.client.rest.methods.setChannelPositions(this.id, updatedChannels); - } - - /** - * Fetches a collection of channels in the current guild sorted by position. - * @param {string} type The channel type - * @returns {Collection<Snowflake, GuildChannel>} - * @private - */ - _sortedChannels(type) { - return this._sortPositionWithID(this.channels.filter(c => { - if (type === 'voice' && c.type === 'voice') return true; - else if (type !== 'voice' && c.type !== 'voice') return true; - else return type === c.type; - })); - } - - /** - * Sorts a collection by object position or ID if the positions are equivalent. - * Intended to be identical to Discord's sorting method. - * @param {Collection} collection The collection to sort - * @returns {Collection} - * @private - */ - _sortPositionWithID(collection) { - return collection.sort((a, b) => - a.position !== b.position ? - a.position - b.position : - Long.fromString(b.id).sub(Long.fromString(a.id)).toNumber() - ); - } -} - -/** - * The `#general` TextChannel of the guild - * @name Guild#defaultChannel - * @type {TextChannel} - * @readonly - * @deprecated - */ -Object.defineProperty(Guild.prototype, 'defaultChannel', { - get: util.deprecate(function defaultChannel() { - return this.channels.get(this.id); - }, 'Guild#defaultChannel: This property is obsolete, will be removed in v12.0.0, and may not function as expected.'), -}); - -Guild.prototype.allowDMs = - util.deprecate(Guild.prototype.allowDMs, 'Guild#allowDMs: userbot methods will be removed'); - -Guild.prototype.acknowledge = - util.deprecate(Guild.prototype.acknowledge, 'Guild#acknowledge: userbot methods will be removed'); - -Guild.prototype.setPosition = - util.deprecate(Guild.prototype.setPosition, 'Guild#setPosition: userbot methods will be removed'); - -Guild.prototype.search = - util.deprecate(Guild.prototype.search, 'Guild#search: userbot methods will be removed'); - -Guild.prototype.sync = - util.deprecate(Guild.prototype.sync, 'Guild#sync:, userbot methods will be removed'); - -Guild.prototype.deleteEmoji = - util.deprecate(Guild.prototype.deleteEmoji, 'Guild#deleteEmoji: use Emoji#delete instead'); - -module.exports = Guild; diff --git a/node_modules/discord.js/src/structures/GuildAuditLogs.js b/node_modules/discord.js/src/structures/GuildAuditLogs.js deleted file mode 100644 index 5c98594..0000000 --- a/node_modules/discord.js/src/structures/GuildAuditLogs.js +++ /dev/null @@ -1,462 +0,0 @@ -const Collection = require('../util/Collection'); -const Snowflake = require('../util/Snowflake'); -const Webhook = require('./Webhook'); -const Integration = require('./Integration'); -const Invite = require('./Invite'); - -/** - * The target type of an entry, e.g. `GUILD`. Here are the available types: - * * GUILD - * * CHANNEL - * * USER - * * ROLE - * * INVITE - * * WEBHOOK - * * EMOJI - * * MESSAGE - * * INTEGRATION - * @typedef {string} AuditLogTargetType - */ - -/** - * Key mirror of all available audit log targets. - * @name GuildAuditLogs.Targets - * @type {AuditLogTargetType} - */ -const Targets = { - ALL: 'ALL', - GUILD: 'GUILD', - CHANNEL: 'CHANNEL', - USER: 'USER', - ROLE: 'ROLE', - INVITE: 'INVITE', - WEBHOOK: 'WEBHOOK', - EMOJI: 'EMOJI', - MESSAGE: 'MESSAGE', - INTEGRATION: 'INTEGRATION', - UNKNOWN: 'UNKNOWN', -}; - -/** - * The action of an entry. Here are the available actions: - * * ALL: null - * * GUILD_UPDATE: 1 - * * CHANNEL_CREATE: 10 - * * CHANNEL_UPDATE: 11 - * * CHANNEL_DELETE: 12 - * * CHANNEL_OVERWRITE_CREATE: 13 - * * CHANNEL_OVERWRITE_UPDATE: 14 - * * CHANNEL_OVERWRITE_DELETE: 15 - * * MEMBER_KICK: 20 - * * MEMBER_PRUNE: 21 - * * MEMBER_BAN_ADD: 22 - * * MEMBER_BAN_REMOVE: 23 - * * MEMBER_UPDATE: 24 - * * MEMBER_ROLE_UPDATE: 25 - * * MEMBER_MOVE: 26 - * * MEMBER_DISCONNECT: 27 - * * BOT_ADD: 28, - * * ROLE_CREATE: 30 - * * ROLE_UPDATE: 31 - * * ROLE_DELETE: 32 - * * INVITE_CREATE: 40 - * * INVITE_UPDATE: 41 - * * INVITE_DELETE: 42 - * * WEBHOOK_CREATE: 50 - * * WEBHOOK_UPDATE: 51 - * * WEBHOOK_DELETE: 52 - * * EMOJI_CREATE: 60 - * * EMOJI_UPDATE: 61 - * * EMOJI_DELETE: 62 - * * MESSAGE_DELETE: 72 - * * MESSAGE_BULK_DELETE: 73 - * * MESSAGE_PIN: 74 - * * MESSAGE_UNPIN: 75 - * * INTEGRATION_CREATE: 80 - * * INTEGRATION_UPDATE: 81 - * * INTEGRATION_DELETE: 82 - * @typedef {?number|string} AuditLogAction - */ - -/** - * All available actions keyed under their names to their numeric values. - * @name GuildAuditLogs.Actions - * @type {AuditLogAction} - */ -const Actions = { - ALL: null, - GUILD_UPDATE: 1, - CHANNEL_CREATE: 10, - CHANNEL_UPDATE: 11, - CHANNEL_DELETE: 12, - CHANNEL_OVERWRITE_CREATE: 13, - CHANNEL_OVERWRITE_UPDATE: 14, - CHANNEL_OVERWRITE_DELETE: 15, - MEMBER_KICK: 20, - MEMBER_PRUNE: 21, - MEMBER_BAN_ADD: 22, - MEMBER_BAN_REMOVE: 23, - MEMBER_UPDATE: 24, - MEMBER_ROLE_UPDATE: 25, - MEMBER_MOVE: 26, - MEMBER_DISCONNECT: 27, - BOT_ADD: 28, - ROLE_CREATE: 30, - ROLE_UPDATE: 31, - ROLE_DELETE: 32, - INVITE_CREATE: 40, - INVITE_UPDATE: 41, - INVITE_DELETE: 42, - WEBHOOK_CREATE: 50, - WEBHOOK_UPDATE: 51, - WEBHOOK_DELETE: 52, - EMOJI_CREATE: 60, - EMOJI_UPDATE: 61, - EMOJI_DELETE: 62, - MESSAGE_DELETE: 72, - MESSAGE_BULK_DELETE: 73, - MESSAGE_PIN: 74, - MESSAGE_UNPIN: 75, - INTEGRATION_CREATE: 80, - INTEGRATION_UPDATE: 81, - INTEGRATION_DELETE: 82, -}; - - -/** - * Audit logs entries are held in this class. - */ -class GuildAuditLogs { - constructor(guild, data) { - if (data.users) for (const user of data.users) guild.client.dataManager.newUser(user); - - /** - * Cached webhooks - * @type {Collection<Snowflake, Webhook>} - * @private - */ - this.webhooks = new Collection(); - if (data.webhooks) { - for (const hook of data.webhooks) { - this.webhooks.set(hook.id, new Webhook(guild.client, hook)); - } - } - - /** - * Cached integrations - * @type {Collection<Snowflake, Integration>} - * @private - */ - this.integrations = new Collection(); - if (data.integrations) { - for (const integration of data.integrations) { - this.integrations.set(integration.id, new Integration(guild.client, integration, guild)); - } - } - - /** - * The entries for this guild's audit logs - * @type {Collection<Snowflake, GuildAuditLogsEntry>} - */ - this.entries = new Collection(); - for (const item of data.audit_log_entries) { - const entry = new GuildAuditLogsEntry(this, guild, item); - this.entries.set(entry.id, entry); - } - } - - /** - * Handles possible promises for entry targets. - * @returns {Promise<GuildAuditLogs>} - */ - static build(...args) { - const logs = new GuildAuditLogs(...args); - return Promise.all(logs.entries.map(e => e.target)).then(() => logs); - } - - /** - * The target of an entry. It can be one of: - * * A guild - * * A user - * * A role - * * An emoji - * * An invite - * * A webhook - * * An integration - * * An object with an id key if target was deleted - * * An object where the keys represent either the new value or the old value - * @typedef {?Object|Guild|User|Role|Emoji|Invite|Webhook|Integration} AuditLogEntryTarget - */ - - /** - * Find target type from entry action. - * @param {number} target The action target - * @returns {?string} - */ - static targetType(target) { - if (target < 10) return Targets.GUILD; - if (target < 20) return Targets.CHANNEL; - if (target < 30) return Targets.USER; - if (target < 40) return Targets.ROLE; - if (target < 50) return Targets.INVITE; - if (target < 60) return Targets.WEBHOOK; - if (target < 70) return Targets.EMOJI; - if (target < 80) return Targets.MESSAGE; - if (target < 90) return Targets.INTEGRATION; - return null; - } - - /** - * The action type of an entry, e.g. `CREATE`. Here are the available types: - * * CREATE - * * DELETE - * * UPDATE - * * ALL - * @typedef {string} AuditLogActionType - */ - - - /** - * Finds the action type from the entry action. - * @param {AuditLogAction} action The action target - * @returns {AuditLogActionType} - */ - static actionType(action) { - if ([ - Actions.CHANNEL_CREATE, - Actions.CHANNEL_OVERWRITE_CREATE, - Actions.MEMBER_BAN_REMOVE, - Actions.BOT_ADD, - Actions.ROLE_CREATE, - Actions.INVITE_CREATE, - Actions.WEBHOOK_CREATE, - Actions.EMOJI_CREATE, - Actions.MESSAGE_PIN, - Actions.INTEGRATION_CREATE, - ].includes(action)) return 'CREATE'; - - if ([ - Actions.CHANNEL_DELETE, - Actions.CHANNEL_OVERWRITE_DELETE, - Actions.MEMBER_KICK, - Actions.MEMBER_PRUNE, - Actions.MEMBER_BAN_ADD, - Actions.MEMBER_DISCONNECT, - Actions.ROLE_DELETE, - Actions.INVITE_DELETE, - Actions.WEBHOOK_DELETE, - Actions.EMOJI_DELETE, - Actions.MESSAGE_DELETE, - Actions.MESSAGE_BULK_DELETE, - Actions.MESSAGE_UNPIN, - Actions.INTEGRATION_DELETE, - ].includes(action)) return 'DELETE'; - - if ([ - Actions.GUILD_UPDATE, - Actions.CHANNEL_UPDATE, - Actions.CHANNEL_OVERWRITE_UPDATE, - Actions.MEMBER_UPDATE, - Actions.MEMBER_ROLE_UPDATE, - Actions.MEMBER_MOVE, - Actions.ROLE_UPDATE, - Actions.INVITE_UPDATE, - Actions.WEBHOOK_UPDATE, - Actions.EMOJI_UPDATE, - Actions.INTEGRATION_UPDATE, - ].includes(action)) return 'UPDATE'; - - return 'ALL'; - } -} - -/** - * Audit logs entry. - */ -class GuildAuditLogsEntry { - // eslint-disable-next-line complexity - constructor(logs, guild, data) { - const targetType = GuildAuditLogs.targetType(data.action_type); - /** - * The target type of this entry - * @type {AuditLogTargetType} - */ - this.targetType = targetType; - - /** - * The action type of this entry - * @type {AuditLogActionType} - */ - this.actionType = GuildAuditLogs.actionType(data.action_type); - - /** - * Specific action type of this entry in its string representation - * @type {AuditLogAction} - */ - this.action = Object.keys(Actions).find(k => Actions[k] === data.action_type); - - /** - * The reason of this entry - * @type {?string} - */ - this.reason = data.reason || null; - - /** - * The user that executed this entry - * @type {User} - */ - this.executor = guild.client.users.get(data.user_id); - - /** - * An entry in the audit log representing a specific change. - * @typedef {object} AuditLogChange - * @property {string} key The property that was changed, e.g. `nick` for nickname changes - * @property {*} [old] The old value of the change, e.g. for nicknames, the old nickname - * @property {*} [new] The new value of the change, e.g. for nicknames, the new nickname - */ - - /** - * Specific property changes - * @type {AuditLogChange[]} - */ - this.changes = data.changes ? data.changes.map(c => ({ key: c.key, old: c.old_value, new: c.new_value })) : null; - - /** - * The ID of this entry - * @type {Snowflake} - */ - this.id = data.id; - - /** - * Any extra data from the entry - * @type {?Object|Role|GuildMember} - */ - this.extra = null; - switch (data.action_type) { - case Actions.MEMBER_PRUNE: - this.extra = { - removed: Number(data.options.members_removed), - days: Number(data.options.delete_member_days), - }; - break; - - case Actions.MEMBER_MOVE: - case Actions.MESSAGE_DELETE: - case Actions.MESSAGE_BULK_DELETE: - this.extra = { - channel: guild.channels.get(data.options.channel_id) || { id: data.options.channel_id }, - count: Number(data.options.count), - }; - break; - - case Actions.MESSAGE_PIN: - case Actions.MESSAGE_UNPIN: - this.extra = { - channel: guild.client.channels.get(data.options.channel_id) || { id: data.options.channel_id }, - messageID: data.options.message_id, - }; - break; - - case Actions.MEMBER_DISCONNECT: - this.extra = { - count: Number(data.options.count), - }; - break; - - case Actions.CHANNEL_OVERWRITE_CREATE: - case Actions.CHANNEL_OVERWRITE_UPDATE: - case Actions.CHANNEL_OVERWRITE_DELETE: - switch (data.options.type) { - case 'member': - this.extra = guild.members.get(data.options.id) || - { id: data.options.id, type: 'member' }; - break; - case 'role': - this.extra = guild.roles.get(data.options.id) || - { id: data.options.id, name: data.options.role_name, type: 'role' }; - break; - default: - break; - } - break; - - default: - break; - } - - /** - * The target of this entry - * @type {AuditLogEntryTarget} - */ - this.target = null; - if (targetType === Targets.UNKNOWN) { - this.changes.reduce((o, c) => { - o[c.key] = c.new || c.old; - return o; - }, {}); - this.target.id = data.target_id; - // MEMBER_DISCONNECT and similar types do not provide a target_id. - } else if (targetType === Targets.USER && data.target_id) { - this.target = guild.client.users.get(data.target_id); - } else if (targetType === Targets.GUILD) { - this.target = guild.client.guilds.get(data.target_id); - } else if (targetType === Targets.WEBHOOK) { - this.target = logs.webhooks.get(data.target_id) || - new Webhook(guild.client, - this.changes.reduce((o, c) => { - o[c.key] = c.new || c.old; - return o; - }, { - id: data.target_id, - guild_id: guild.id, - })); - } else if (targetType === Targets.INVITE) { - const changes = this.changes.reduce((o, c) => { - o[c.key] = c.new || c.old; - return o; - }, { - id: data.target_id, - guild, - }); - changes.channel = { id: changes.channel_id }; - this.target = new Invite(guild.client, changes); - } else if (targetType === Targets.MESSAGE) { - // Discord sends a channel id for the MESSAGE_BULK_DELETE action type. - this.target = data.action_type === Actions.MESSAGE_BULK_DELETE ? - guild.channels.get(data.target_id) || { id: data.target_id } : - guild.client.users.get(data.target_id); - } else if (targetType === Targets.INTEGRATION) { - this.target = logs.integrations.get(data.target_id) || - new Integration(guild.client, this.changes.reduce((o, c) => { - o[c.key] = c.new || c.old; - return o; - }, { id: data.target_id }), guild); - } else if (data.target_id) { - this.target = guild[`${targetType.toLowerCase()}s`].get(data.target_id) || { id: data.target_id }; - } - } - - /** - * The timestamp this entry was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time this entry was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } -} - -GuildAuditLogs.Actions = Actions; -GuildAuditLogs.Targets = Targets; -GuildAuditLogs.Entry = GuildAuditLogsEntry; - -module.exports = GuildAuditLogs; 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 0dbc0e3..0000000 --- a/node_modules/discord.js/src/structures/GuildChannel.js +++ /dev/null @@ -1,601 +0,0 @@ -const Channel = require('./Channel'); -const Role = require('./Role'); -const PermissionOverwrites = require('./PermissionOverwrites'); -const Permissions = require('../util/Permissions'); -const Collection = require('../util/Collection'); -const Constants = require('../util/Constants'); -const Invite = require('./Invite'); -const Util = require('../util/Util'); - -/** - * 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; - - /** - * The ID of the category parent of this channel - * @type {?Snowflake} - */ - this.parentID = data.parent_id; - - /** - * A map of permission overwrites in this channel for roles and users - * @type {Collection<Snowflake, 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)); - } - } - } - - /** - * The position of the channel - * @type {number} - * @readonly - */ - get calculatedPosition() { - const sorted = this.guild._sortedChannels(this.type); - return sorted.array().indexOf(sorted.get(this.id)); - } - - /** - * The category parent of this channel - * @type {?CategoryChannel} - * @readonly - */ - get parent() { - return this.guild.channels.get(this.parentID) || null; - } - - /** - * If the permissionOverwrites match the parent channel, null if no parent - * @type {?boolean} - * @readonly - */ - get permissionsLocked() { - if (!this.parent) return null; - if (this.permissionOverwrites.size !== this.parent.permissionOverwrites.size) return false; - return this.permissionOverwrites.every((value, key) => { - const testVal = this.parent.permissionOverwrites.get(key); - return testVal !== undefined && - testVal.deny === value.deny && - testVal.allow === value.allow; - }); - } - - /** - * Gets the overall set of permissions for a user in this channel, taking into account channel overwrites. - * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for - * @returns {?Permissions} - */ - memberPermissions(member) { - member = this.client.resolver.resolveGuildMember(this.guild, member); - if (!member) return null; - - if (member.id === this.guild.ownerID) return new Permissions(member, Permissions.ALL); - - const roles = member.roles; - const permissions = new Permissions(roles.map(role => role.permissions)); - - if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze(); - - const overwrites = this.overwritesFor(member, true, roles); - - return permissions - .remove(overwrites.everyone ? overwrites.everyone.deny : 0) - .add(overwrites.everyone ? overwrites.everyone.allow : 0) - .remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : 0) - .add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : 0) - .remove(overwrites.member ? overwrites.member.deny : 0) - .add(overwrites.member ? overwrites.member.allow : 0) - .freeze(); - } - - /** - * Gets the overall set of permissions for a role in this channel, taking into account channel overwrites. - * @param {RoleResolvable} role The role that you want to obtain the overall permissions for - * @returns {?Permissions} - */ - rolePermissions(role) { - if (role.permissions & Permissions.FLAGS.ADMINISTRATOR) return new Permissions(Permissions.ALL).freeze(); - - const everyoneOverwrites = this.permissionOverwrites.get(this.guild.id); - const roleOverwrites = this.permissionOverwrites.get(role.id); - - return new Permissions(role.permissions) - .remove(everyoneOverwrites ? everyoneOverwrites.deny : 0) - .add(everyoneOverwrites ? everyoneOverwrites.allow : 0) - .remove(roleOverwrites ? roleOverwrites.deny : 0) - .add(roleOverwrites ? roleOverwrites.allow : 0) - .freeze(); - } - - /** - * Get the overall set of permissions for a member or role in this channel, taking into account channel overwrites. - * @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for - * @returns {?Permissions} - */ - permissionsFor(memberOrRole) { - const member = this.guild.member(memberOrRole); - if (member) return this.memberPermissions(member); - const role = this.client.resolver.resolveRole(this.guild, memberOrRole); - if (role) return this.rolePermissions(role); - return null; - } - - 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 = []; - let memberOverwrites; - let everyoneOverwrites; - - for (const overwrite of this.permissionOverwrites.values()) { - if (overwrite.id === this.guild.id) { - everyoneOverwrites = overwrite; - } else if (roles.has(overwrite.id)) { - roleOverwrites.push(overwrite); - } else if (overwrite.id === member.id) { - memberOverwrites = overwrite; - } - } - - return { - everyone: everyoneOverwrites, - roles: roleOverwrites, - member: memberOverwrites, - }; - } - - /** - * Replaces the permission overwrites for a channel - * @param {Object} [options] Options - * @param {ChannelCreationOverwrites[]|Collection<Snowflake, PermissionOverwrites>} [options.overwrites] - * Permission overwrites - * @param {string} [options.reason] Reason for updating the channel overwrites - * @returns {Promise<GuildChannel>} - * @example - * channel.replacePermissionOverwrites({ - * overwrites: [ - * { - * id: message.author.id, - * denied: ['VIEW_CHANNEL'], - * }, - * ], - * reason: 'Needed to change permissions' - * }); - */ - replacePermissionOverwrites({ overwrites, reason } = {}) { - return this.edit({ permissionOverwrites: overwrites, reason }) - .then(() => this); - } - - /** - * An object mapping permission flags to `true` (enabled), `null` (unset) or `false` (disabled). - * ```js - * { - * 'SEND_MESSAGES': true, - * 'EMBED_LINKS': null, - * 'ATTACH_FILES': false, - * } - * ``` - * @typedef {Object} PermissionOverwriteOptions - */ - - /** - * Overwrites the permissions for a user or role in this channel. - * @param {Role|Snowflake|UserResolvable} userOrRole The user or role to update - * @param {PermissionOverwriteOptions} options The configuration for the update - * @param {string} [reason] Reason for creating/editing this overwrite - * @returns {Promise<GuildChannel>} - * @example - * // Overwrite permissions for a message author - * message.channel.overwritePermissions(message.author, { - * SEND_MESSAGES: false - * }) - * .then(updated => console.log(updated.permissionOverwrites.get(message.author.id))) - * .catch(console.error); - * @example - * // Overwite permissions for a message author and reset some - * message.channel.overwritePermissions(message.author, { - * VIEW_CHANNEL: false, - * SEND_MESSAGES: null - * }) - * .then(updated => console.log(updated.permissionOverwrites.get(message.author.id))) - * .catch(console.error); - */ - overwritePermissions(userOrRole, options, reason) { - 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 of Object.keys(options)) { - if (options[perm] === true) { - payload.allow |= Permissions.FLAGS[perm] || 0; - payload.deny &= ~(Permissions.FLAGS[perm] || 0); - } else if (options[perm] === false) { - payload.allow &= ~(Permissions.FLAGS[perm] || 0); - payload.deny |= Permissions.FLAGS[perm] || 0; - } else if (options[perm] === null) { - payload.allow &= ~(Permissions.FLAGS[perm] || 0); - payload.deny &= ~(Permissions.FLAGS[perm] || 0); - } - } - - return this.client.rest.methods.setChannelOverwrite(this, payload, reason).then(() => this); - } - - /** - * Locks in the permission overwrites from the parent channel. - * @returns {Promise<GuildChannel>} - */ - lockPermissions() { - if (!this.parent) return Promise.reject(new TypeError('Could not find a parent to this guild channel.')); - const permissionOverwrites = this.parent.permissionOverwrites.map(overwrite => ({ - deny: overwrite.deny, - allow: overwrite.allow, - id: overwrite.id, - type: overwrite.type, - })); - return this.edit({ permissionOverwrites }); - } - - /** - * The data for a guild channel. - * @typedef {Object} ChannelData - * @property {string} [type] The type of the channel (Only when creating) - * @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 {boolean} [nsfw] Whether the channel is NSFW - * @property {number} [bitrate] The bitrate of the voice channel - * @property {number} [userLimit] The user limit of the channel - * @property {CategoryChannel|Snowflake} [parent] The parent or parent ID of the channel - * @property {ChannelCreationOverwrites[]|Collection<Snowflake, PermissionOverwrites>} [permissionOverwrites] - * Overwrites of the channel - * @property {number} [rateLimitPerUser] The rate limit per user of the channel in seconds - * @property {string} [reason] Reason for creating the channel (Only when creating) - */ - - /** - * Edits the channel. - * @param {ChannelData} data The new data for the channel - * @param {string} [reason] Reason for editing this channel - * @returns {Promise<GuildChannel>} - * @example - * // Edit a channel - * channel.edit({ name: 'new-channel' }) - * .then(console.log) - * .catch(console.error); - */ - edit(data, reason) { - return this.client.rest.methods.updateChannel(this, data, reason).then(() => this); - } - - /** - * Set a new name for the guild channel. - * @param {string} name The new name for the guild channel - * @param {string} [reason] Reason for changing the guild channel's name - * @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, reason) { - return this.edit({ name }, reason); - } - - /** - * Set a new position for the guild channel. - * @param {number} position The new position for the guild channel - * @param {boolean} [relative=false] Move the position relative to its current value - * @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, relative) { - return this.guild.setChannelPosition(this, position, relative).then(() => this); - } - - /** - * Set a new parent for the guild channel. - * @param {CategoryChannel|SnowFlake} parent The new parent for the guild channel - * @param {string} [reason] Reason for changing the guild channel's parent - * @returns {Promise<GuildChannel>} - * @example - * // Sets the parent of a channel - * channel.setParent('174674066072928256') - * .then(updated => console.log(`Set the category of ${updated.name} to ${updated.parent.name}`)) - * .catch(console.error); - */ - setParent(parent, reason) { - parent = this.client.resolver.resolveChannelID(parent); - return this.edit({ parent }, reason); - } - - /** - * Set a new topic for the guild channel. - * @param {string} topic The new topic for the guild channel - * @param {string} [reason] Reason for changing the guild channel's topic - * @returns {Promise<GuildChannel>} - * @example - * // Set a new channel topic - * channel.setTopic('Needs more rate limiting') - * .then(updated => console.log(`Channel's new topic is ${updated.topic}`)) - * .catch(console.error); - */ - setTopic(topic, reason) { - return this.edit({ topic }, reason); - } - - /** - * Create an invite to this guild channel. - * <warn>This is only available when using a bot account.</warn> - * @param {Object} [options={}] Options for the invite - * @param {boolean} [options.temporary=false] Whether members that joined via the invite should be automatically - * kicked after 24 hours if they have not yet received a role - * @param {number} [options.maxAge=86400] How long the invite should last (in seconds, 0 for forever) - * @param {number} [options.maxUses=0] Maximum number of uses - * @param {boolean} [options.unique=false] Create a unique invite, or use an existing one with similar settings - * @param {string} [reason] Reason for creating the invite - * @returns {Promise<Invite>} - * @example - * // Create an invite to a channel - * channel.createInvite() - * .then(invite => console.log(`Created an invite with a code of ${invite.code}`)) - * .catch(console.error); - */ - createInvite(options = {}, reason) { - return this.client.rest.methods.createChannelInvite(this, options, reason); - } - - /* eslint-disable max-len */ - /** - * Options to clone a guild channel. - * @typedef {Object} GuildChannelCloneOptions - * @property {string} [name=this.name] Name of the new channel - * @property {ChannelCreationOverwrites[]|Collection<Snowflake, PermissionOverwrites>} [permissionOverwrites=this.permissionOverwrites] - * Permission overwrites of the new channel - * @property {string} [type=this.type] Type of the new channel - * @property {string} [topic=this.topic] Topic of the new channel (only text) - * @property {boolean} [nsfw=this.nsfw] Whether the new channel is nsfw (only text) - * @property {number} [bitrate=this.bitrate] Bitrate of the new channel in bits (only voice) - * @property {number} [userLimit=this.userLimit] Maximum amount of users allowed in the new channel (only voice) - * @property {number} [rateLimitPerUser=ThisType.rateLimitPerUser] Ratelimit per user for the new channel (only text) - * @property {ChannelResolvable} [parent=this.parent] Parent of the new channel - * @property {string} [reason] Reason for cloning this channel - */ - /* eslint-enable max-len */ - - /** - * Clone this channel. - * @param {string|GuildChannelCloneOptions} [nameOrOptions={}] Name for the new channel. - * **(deprecated, use options)** - * Alternatively options for cloning the channel - * @param {boolean} [withPermissions=true] Whether to clone the channel with this channel's permission overwrites - * **(deprecated, use options)** - * @param {boolean} [withTopic=true] Whether to clone the channel with this channel's topic - * **(deprecated, use options)** - * @param {string} [reason] Reason for cloning this channel **(deprecated, user options)** - * @returns {Promise<GuildChannel>} - * @example - * // Clone a channel - * channel.clone({ topic: null, reason: 'Needed a clone' }) - * .then(clone => console.log(`Cloned ${channel.name} to make a channel called ${clone.name}`)) - * .catch(console.error); - */ - clone(nameOrOptions = {}, withPermissions = true, withTopic = true, reason) { - // If more than one parameter was specified or the first is a string, - // convert them to a compatible options object and issue a warning - if (arguments.length > 1 || typeof nameOrOptions === 'string') { - process.emitWarning( - 'GuildChannel#clone: Clone channels using an options object instead of separate parameters.', - 'Deprecation Warning' - ); - - nameOrOptions = { - name: nameOrOptions, - permissionOverwrites: withPermissions ? this.permissionOverwrites : null, - topic: withTopic ? this.topic : null, - reason: reason || null, - }; - } - - Util.mergeDefault({ - name: this.name, - permissionOverwrites: this.permissionOverwrites, - topic: this.topic, - type: this.type, - nsfw: this.nsfw, - parent: this.parent, - bitrate: this.bitrate, - userLimit: this.userLimit, - rateLimitPerUser: this.rateLimitPerUser, - reason: null, - }, nameOrOptions); - - return this.guild.createChannel(nameOrOptions.name, nameOrOptions); - } - - /** - * Fetches a collection of invites to this guild channel. - * Resolves with a collection mapping invites by their codes. - * @returns {Promise<Collection<string, Invite>>} - */ - fetchInvites() { - return this.client.rest.makeRequest('get', Constants.Endpoints.Channel(this.id).invites, true) - .then(data => { - const invites = new Collection(); - for (let invite of data) { - invite = new Invite(this.client, invite); - invites.set(invite.code, invite); - } - - return invites; - }); - } - - /** - * Deletes this channel. - * @param {string} [reason] Reason for deleting this channel - * @returns {Promise<GuildChannel>} - * @example - * // Delete the channel - * channel.delete('Making room for new channels') - * .then(deleted => console.log(`Deleted ${deleted.name} to make room for new channels`)) - * .catch(console.error); - */ - delete(reason) { - return this.client.rest.methods.deleteChannel(this, reason); - } - - /** - * 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; - } - - /** - * Whether the channel is deletable by the client user - * @type {boolean} - * @readonly - */ - get deletable() { - return this.id !== this.guild.id && - this.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_CHANNELS); - } - - /** - * Whether the channel is manageable by the client user - * @type {boolean} - * @readonly - */ - get manageable() { - if (this.client.user.id === this.guild.ownerID) return true; - const permissions = this.permissionsFor(this.client.user); - if (!permissions) return false; - return permissions.has([Permissions.FLAGS.MANAGE_CHANNELS, Permissions.FLAGS.VIEW_CHANNEL]); - } - - /** - * Whether the channel is muted - * <warn>This is only available when using a user account.</warn> - * @type {?boolean} - * @readonly - * @deprecated - */ - get muted() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).muted; - } catch (err) { - return false; - } - } - - /** - * The type of message that should notify you - * <warn>This is only available when using a user account.</warn> - * @type {?MessageNotificationType} - * @readonly - * @deprecated - */ - get messageNotifications() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).messageNotifications; - } catch (err) { - return Constants.MessageNotificationTypes[3]; - } - } - - /** - * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. - * @returns {string} - * @example - * // Logs: Hello from <#123456789012345678> - * console.log(`Hello from ${channel}`); - * @example - * // Logs: Hello from <#123456789012345678> - * 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 45b75b3..0000000 --- a/node_modules/discord.js/src/structures/GuildMember.js +++ /dev/null @@ -1,636 +0,0 @@ -const TextBasedChannel = require('./interfaces/TextBasedChannel'); -const Role = require('./Role'); -const Permissions = require('../util/Permissions'); -const Collection = require('../util/Collection'); -const { Presence } = require('./Presence'); -const util = require('util'); - -/** - * 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 member instance Represents - * @type {User} - */ - this.user = {}; - - /** - * The timestamp this member joined the guild at - * @type {number} - */ - this.joinedTimestamp = null; - - /** - * The timestamp of when the member used their Nitro boost on the guild, if it was used - * @type {?number} - */ - this.premiumSinceTimestamp = null; - - this._roles = []; - if (data) this.setup(data); - - /** - * The ID of the last message sent by this member in their guild, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = null; - - /** - * The Message object of the last message sent by this member in their guild, if one was sent - * @type {?Message} - */ - this.lastMessage = null; - - /** - * Whether the member has been removed from the guild - * @type {boolean} - */ - this.deleted = false; - } - - 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; - - /** - * Whether this member is streaming using "Go Live" - * @type {boolean} - */ - this.selfStream = data.self_stream || false; - - /** - * The voice session ID of this member, if any - * @type {?Snowflake} - */ - this.voiceSessionID = data.session_id; - - /** - * The voice channel ID of this member, if any - * @type {?Snowflake} - */ - this.voiceChannelID = data.channel_id; - - /** - * Whether this member is speaking and the client is in the same channel - * @type {boolean} - */ - this.speaking = false; - - /** - * The nickname of this member, if they have one - * @type {?string} - */ - this.nickname = data.nick || null; - - if (data.joined_at) this.joinedTimestamp = new Date(data.joined_at).getTime(); - if (data.premium_since) this.premiumSinceTimestamp = new Date(data.premium_since).getTime(); - - this.user = data.user; - this._roles = data.roles; - } - - /** - * The time this member joined the guild - * @type {?Date} - * @readonly - */ - get joinedAt() { - return this.joinedTimestamp ? new Date(this.joinedTimestamp) : null; - } - - /** - * The time of when the member used their Nitro boost on the guild, if it was used - * @type {?Date} - * @readonly - */ - get premiumSince() { - return this.premiumSinceTimestamp ? new Date(this.premiumSinceTimestamp) : null; - } - - /** - * The presence of this member - * @type {Presence} - * @readonly - */ - get presence() { - return this.frozenPresence || this.guild.presences.get(this.id) || new Presence(undefined, this.client); - } - - /** - * A list of roles that are applied to this member, mapped by the role ID - * @type {Collection<Snowflake, 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 this member with the highest position - * @type {Role} - * @readonly - */ - get highestRole() { - return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * The role of this member used to set their color - * @type {?Role} - * @readonly - */ - get colorRole() { - const coloredRoles = this.roles.filter(role => role.color); - if (!coloredRoles.size) return null; - return coloredRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * The displayed color of this member in base 10 - * @type {number} - * @readonly - */ - get displayColor() { - const role = this.colorRole; - return (role && role.color) || 0; - } - - /** - * The displayed color of this member in hexadecimal - * @type {string} - * @readonly - */ - get displayHexColor() { - const role = this.colorRole; - return (role && role.hexColor) || '#000000'; - } - - /** - * The role of this member used to hoist them in a separate category in the users list - * @type {?Role} - * @readonly - */ - get hoistRole() { - const hoistedRoles = this.roles.filter(role => role.hoist); - if (!hoistedRoles.size) return null; - return hoistedRoles.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 {Snowflake} - * @readonly - */ - get id() { - return this.user.id; - } - - /** - * The nickname of this 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 this member, taking only roles into account - * @type {Permissions} - * @readonly - */ - get permissions() { - if (this.user.id === this.guild.ownerID) return new Permissions(this, Permissions.ALL); - - let permissions = 0; - const roles = this.roles; - for (const role of roles.values()) permissions |= role.permissions; - - return new Permissions(this, permissions); - } - - /** - * Whether this member is manageable in terms of role hierarchy by the client user - * @type {boolean} - * @readonly - */ - get manageable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - if (this.client.user.id === this.guild.ownerID) return true; - return this.guild.me.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Whether this member is kickable by the client user - * @type {boolean} - * @readonly - */ - get kickable() { - return this.manageable && this.guild.me.permissions.has(Permissions.FLAGS.KICK_MEMBERS); - } - - /** - * Whether this member is bannable by the client user - * @type {boolean} - * @readonly - */ - get bannable() { - return this.manageable && this.guild.me.permissions.has(Permissions.FLAGS.BAN_MEMBERS); - } - - /** - * Returns `channel.permissionsFor(guildMember)`. Returns permissions for this member in a guild channel, - * taking into account roles and permission overwrites. - * @param {ChannelResolvable} channel The guild channel to use as context - * @returns {?Permissions} - */ - 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 this member's roles have a permission. - * @param {PermissionResolvable} permission Permission(s) to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission - * **(deprecated)** - * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override - * (takes priority over `explicit`) - * @param {boolean} [checkOwner] Whether to allow being the guild's owner to override - * (takes priority over `explicit`) - * @returns {boolean} - */ - hasPermission(permission, explicit = false, checkAdmin, checkOwner) { - if (typeof checkAdmin === 'undefined') checkAdmin = !explicit; - if (typeof checkOwner === 'undefined') checkOwner = !explicit; - if (checkOwner && this.user.id === this.guild.ownerID) return true; - return this.roles.some(r => r.hasPermission(permission, undefined, checkAdmin)); - } - - /** - * Checks whether the roles of this 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} - * @deprecated - */ - hasPermissions(permissions, explicit = false) { - if (!explicit && this.user.id === this.guild.ownerID) return true; - return this.hasPermission(permissions, explicit); - } - - /** - * Checks whether the roles of this 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) { - if (!(permissions instanceof Array)) permissions = [permissions]; - return this.permissions.missing(permissions, explicit); - } - - /** - * The data for editing this member. - * @typedef {Object} GuildMemberEditData - * @property {string} [nick] The nickname to set for the member - * @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles or role IDs to apply - * @property {boolean} [mute] Whether or not the member should be muted - * @property {boolean} [deaf] Whether or not the member should be deafened - * @property {ChannelResolvable|null} [channel] Channel to move member to (if they are connected to voice), or `null` - * if you want to kick them from voice - */ - - /** - * Edits this member. - * @param {GuildMemberEditData} data The data to edit the member with - * @param {string} [reason] Reason for editing this user - * @returns {Promise<GuildMember>} - * @example - * // Set a member's nickname and clear their roles - * message.member.edit({ - * nick: 'Cool Name', - * roles: [] - * }) - * .then(console.log) - * .catch(console.error); - */ - edit(data, reason) { - return this.client.rest.methods.updateGuildMember(this, data, reason); - } - - /** - * Mute/unmute this member. - * @param {boolean} mute Whether or not the member should be muted - * @param {string} [reason] Reason for muting or unmuting - * @returns {Promise<GuildMember>} - * @example - * // Mute a member with a reason - * message.member.setMute(true, 'It needed to be done') - * .then(() => console.log(`Muted ${message.member.displayName}`))) - * .catch(console.error); - */ - setMute(mute, reason) { - return this.edit({ mute }, reason); - } - - /** - * Deafen/undeafen this member. - * @param {boolean} deaf Whether or not the member should be deafened - * @param {string} [reason] Reason for deafening or undeafening - * @returns {Promise<GuildMember>} - * @example - * // Deafen a member - * message.member.setDeaf(true) - * .then(() => console.log(`Deafened ${message.member.displayName}`)) - * .catch(console.error); - */ - setDeaf(deaf, reason) { - return this.edit({ deaf }, reason); - } - - /** - * Moves this member to the given channel. - * @param {ChannelResolvable|null} channel Channel to move the member to, or `null` if you want to kick them from - * voice - * @returns {Promise<GuildMember>} - * @example - * // Moves a member to a voice channel - * member.setVoiceChannel('174674066072928256') - * .then(() => console.log(`Moved ${member.displayName}`)) - * .catch(console.error); - */ - setVoiceChannel(channel) { - return this.edit({ channel }); - } - - /** - * Sets the roles applied to this member. - * @param {Collection<Snowflake, Role>|RoleResolvable[]} roles The roles or role IDs to apply - * @param {string} [reason] Reason for applying the roles - * @returns {Promise<GuildMember>} - * @example - * // Set the member's roles to a single role - * guildMember.setRoles(['391156570408615936']) - * .then(console.log) - * .catch(console.error); - * @example - * // Remove all of the member's roles - * guildMember.setRoles([]) - * .then(member => console.log(`${member.displayName} now has ${member.roles.size} roles`)) - * .catch(console.error); - */ - setRoles(roles, reason) { - return this.edit({ roles }, reason); - } - - /** - * Adds a single role to this member. - * @param {RoleResolvable} role The role or ID of the role to add - * @param {string} [reason] Reason for adding the role - * @returns {Promise<GuildMember>} - * @example - * // Give a role to a member - * message.member.addRole('193654001089118208') - * .then(console.log) - * .catch(console.error); - */ - addRole(role, reason) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - if (!role) return Promise.reject(new TypeError('Supplied parameter was neither a Role nor a Snowflake.')); - return this.client.rest.methods.addMemberRole(this, role, reason); - } - - /** - * Adds multiple roles to this member. - * @param {Collection<Snowflake, Role>|RoleResolvable[]} roles The roles or role IDs to add - * @param {string} [reason] Reason for adding the roles - * @returns {Promise<GuildMember>} - * @example - * // Gives a member a few roles - * message.member.addRoles(['193654001089118208', '369308579892690945']) - * .then(console.log) - * .catch(console.error); - */ - addRoles(roles, reason) { - 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 }, reason); - } - - /** - * Removes a single role from this member. - * @param {RoleResolvable} role The role or ID of the role to remove - * @param {string} [reason] Reason for removing the role - * @returns {Promise<GuildMember>} - * @example - * // Remove a role from a member - * message.member.removeRole('193654001089118208') - * .then(console.log) - * .catch(console.error); - */ - removeRole(role, reason) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - if (!role) return Promise.reject(new TypeError('Supplied parameter was neither a Role nor a Snowflake.')); - return this.client.rest.methods.removeMemberRole(this, role, reason); - } - - /** - * Removes multiple roles from this member. - * @param {Collection<Snowflake, Role>|RoleResolvable[]} roles The roles or role IDs to remove - * @param {string} [reason] Reason for removing the roles - * @returns {Promise<GuildMember>} - * @example - * // Removes a few roles from the member - * message.member.removeRoles(['193654001089118208', '369308579892690945']) - * .then(console.log) - * .catch(console.error); - */ - removeRoles(roles, reason) { - 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 }, reason); - } - - /** - * Set the nickname for this member. - * @param {string} nick The nickname for the guild member - * @param {string} [reason] Reason for setting the nickname - * @returns {Promise<GuildMember>} - * @example - * // Update the member's nickname - * message.member.setNickname('Cool Name') - * .then(console.log) - * .catch(console.error); - */ - setNickname(nick, reason) { - return this.edit({ nick }, reason); - } - - /** - * Creates a DM channel between the client and this member. - * @returns {Promise<DMChannel>} - */ - createDM() { - return this.user.createDM(); - } - - /** - * Deletes any DMs with this guild member. - * @returns {Promise<DMChannel>} - */ - deleteDM() { - return this.user.deleteDM(); - } - - /** - * Kick this member from the guild. - * @param {string} [reason] Reason for kicking user - * @returns {Promise<GuildMember>} - * @example - * // Kick a member - * member.kick() - * .then(() => console.log(`Kicked ${member.displayName}`)) - * .catch(console.error); - */ - kick(reason) { - return this.client.rest.methods.kickGuildMember(this.guild, this, reason); - } - - /** - * Ban this member. - * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a - * string, the ban reason. Supplying an object allows you to do both. - * @param {number} [options.days=0] Number of days of messages to delete - * @param {string} [options.reason] Reason for banning - * @returns {Promise<GuildMember>} - * @example - * // Ban a guild member - * member.ban(7) - * .then(() => console.log(`Banned ${member.displayName}`)) - * .catch(console.error); - */ - ban(options) { - return this.guild.ban(this, options); - } - - /** - * 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 - /* eslint-disable no-empty-function */ - send() {} - sendMessage() {} - sendEmbed() {} - sendFile() {} - sendCode() {} -} - -TextBasedChannel.applyToClass(GuildMember); - -GuildMember.prototype.hasPermissions = util.deprecate(GuildMember.prototype.hasPermissions, - 'GuildMember#hasPermissions is deprecated - use GuildMember#hasPermission, it now takes an array'); -GuildMember.prototype.missingPermissions = util.deprecate(GuildMember.prototype.missingPermissions, - 'GuildMember#missingPermissions is deprecated - use GuildMember#permissions.missing, it now takes an array'); - -module.exports = GuildMember; diff --git a/node_modules/discord.js/src/structures/Integration.js b/node_modules/discord.js/src/structures/Integration.js deleted file mode 100644 index 96af017..0000000 --- a/node_modules/discord.js/src/structures/Integration.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * The information account for an integration - * @typedef {Object} IntegrationAccount - * @property {string} id The id of the account - * @property {string} name The name of the account - */ - -/** - * Represents a guild integration. - */ -class Integration { - constructor(client, data, guild) { - /** - * The client that created this integration - * @name Integration#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The guild this integration belongs to - * @type {Guild} - */ - this.guild = guild; - - /** - * The integration id - * @type {Snowflake} - */ - this.id = data.id; - - /** - * The integration name - * @type {string} - */ - this.name = data.name; - /** - * The integration type (twitch, youtube, etc) - * @type {string} - */ - this.type = data.type; - - /** - * Whether this integration is enabled - * @type {boolean} - */ - this.enabled = data.enabled; - - /** - * Whether this integration is syncing - * @type {boolean} - */ - this.syncing = data.syncing; - - /** - * The role that this integration uses for subscribers - * @type {Role} - */ - this.role = this.guild.roles.get(data.role_id); - - /** - * The user for this integration - * @type {User} - */ - this.user = this.client.dataManager.newUser(data.user); - - /** - * The account integration information - * @type {IntegrationAccount} - */ - this.account = data.account; - - /** - * The last time this integration was last synced - * @type {number} - */ - this.syncedAt = data.synced_at; - this._patch(data); - } - - _patch(data) { - /** - * The behavior of expiring subscribers - * @type {number} - */ - this.expireBehavior = data.expire_behavior; - - /** - * The grace period before expiring subscribers - * @type {number} - */ - this.expireGracePeriod = data.expire_grace_period; - } - - /** - * Syncs this integration - * @returns {Promise<Integration>} - */ - sync() { - this.syncing = true; - return this.client.rest.methods.syncIntegration(this) - .then(() => { - this.syncing = false; - this.syncedAt = Date.now(); - return this; - }); - } - - /** - * The data for editing an integration. - * @typedef {Object} IntegrationEditData - * @property {number} [expireBehavior] The new behaviour of expiring subscribers - * @property {number} [expireGracePeriod] The new grace period before expiring subscribers - */ - - /** - * Edits this integration. - * @param {IntegrationEditData} data The data to edit this integration with - * @param {string} reason Reason for editing this integration - * @returns {Promise<Integration>} - */ - edit(data, reason) { - if ('expireBehavior' in data) { - data.expire_behavior = data.expireBehavior; - data.expireBehavior = undefined; - } - if ('expireGracePeriod' in data) { - data.expire_grace_period = data.expireGracePeriod; - data.expireGracePeriod = undefined; - } - // The option enable_emoticons is only available for Twitch at this moment - return this.client.rest.methods.editIntegration(this, data, reason) - .then(() => { - this._patch(data); - return this; - }); - } - - /** - * Deletes this integration. - * @returns {Promise<Integration>} - * @param {string} [reason] Reason for deleting this integration - */ - delete(reason) { - return this.client.rest.methods.deleteIntegration(this, reason) - .then(() => this); - } -} - -module.exports = Integration; 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 1d84cf5..0000000 --- a/node_modules/discord.js/src/structures/Invite.js +++ /dev/null @@ -1,164 +0,0 @@ -const PartialGuild = require('./PartialGuild'); -const PartialGuildChannel = require('./PartialGuildChannel'); -const Constants = require('../util/Constants'); - -/** - * Represents an invitation to a guild channel. - * <warn>The only guaranteed properties are `code`, `url`, `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; - - /** - * The approximate number of online members of the guild this invite is for - * @type {number} - */ - this.presenceCount = data.approximate_presence_count; - - /** - * The approximate total number of members of the guild this invite is for - * @type {number} - */ - this.memberCount = data.approximate_member_count; - - /** - * The number of text channels the guild this invite goes to has - * @type {number} - */ - this.textChannelCount = data.guild.text_channel_count; - - /** - * The number of voice channels the guild this invite goes to has - * @type {number} - */ - this.voiceChannelCount = data.guild.voice_channel_count; - - /** - * 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. - * @param {string} [reason] Reason for deleting this invite - * @returns {Promise<Invite>} - */ - delete(reason) { - return this.client.rest.methods.deleteInvite(this, reason); - } - - /** - * 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 c71844f..0000000 --- a/node_modules/discord.js/src/structures/Message.js +++ /dev/null @@ -1,661 +0,0 @@ -const Mentions = require('./MessageMentions'); -const Attachment = require('./MessageAttachment'); -const Embed = require('./MessageEmbed'); -const RichEmbed = require('./RichEmbed'); -const MessageReaction = require('./MessageReaction'); -const ReactionCollector = require('./ReactionCollector'); -const Util = require('../util/Util'); -const Collection = require('../util/Collection'); -const Constants = require('../util/Constants'); -const Permissions = require('../util/Permissions'); -const MessageFlags = require('../util/MessageFlags'); -let GuildMember; - -/** - * 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; - - /** - * Whether this message has been deleted - * @type {boolean} - */ - this.deleted = false; - - if (data) this.setup(data); - } - - setup(data) { // eslint-disable-line complexity - /** - * The ID of the message - * @type {Snowflake} - */ - this.id = data.id; - - /** - * The type of the message - * @type {MessageType} - */ - 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, !data.webhook_id); - - /** - * 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 or string used for checking message delivery - * <warn>This is only received after the message was sent successfully, and - * lost if re-fetched</warn> - * @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 !== 0; - - /** - * 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<Snowflake, 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; - - /** - * A collection of reactions to this message, mapped by the reaction ID - * @type {Collection<Snowflake, 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)); - } - } - - /** - * All valid mentions that the message contains - * @type {MessageMentions} - */ - this.mentions = new Mentions(this, data.mentions, data.mention_roles, data.mention_everyone, data.mention_channels); - - /** - * ID of the webhook that sent the message, if applicable - * @type {?Snowflake} - */ - this.webhookID = data.webhook_id || null; - - /** - * Whether this message is a hit in a search - * @type {?boolean} - */ - this.hit = typeof data.hit === 'boolean' ? data.hit : null; - - /** - * Flags that are applied to the message - * @type {Readonly<MessageFlags>} - */ - this.flags = new MessageFlags(data.flags).freeze(); - - /** - * Reference data sent in a crossposted message. - * @typedef {Object} MessageReference - * @property {string} channelID ID of the channel the message was crossposted from - * @property {?string} guildID ID of the guild the message was crossposted from - * @property {?string} messageID ID of the message that was crossposted - */ - - /** - * Message reference data - * @type {?MessageReference} - */ - this.reference = data.message_reference ? { - channelID: data.message_reference.channel_id, - guildID: data.message_reference.guild_id, - messageID: data.message_reference.message_id, - } : null; - - /** - * The previous versions of the message, sorted with the most recent first - * @type {Message[]} - * @private - */ - this._edits = []; - - if (data.member && this.guild && this.author && !this.guild.members.has(this.author.id)) { - this.guild._addMember(Object.assign(data.member, { user: this.author }), false); - } - - /** - * 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; - } - - /** - * Updates the message. - * @param {Object} data Raw Discord message update data - * @private - */ - patch(data) { - const clone = Util.cloneObject(this); - this._edits.unshift(clone); - - if ('edited_timestamp' in data) this.editedTimestamp = new Date(data.edited_timestamp).getTime(); - if ('content' in data) this.content = data.content; - if ('pinned' in data) this.pinned = data.pinned; - if ('tts' in data) this.tts = data.tts; - if ('embeds' in data) this.embeds = data.embeds.map(e => new Embed(this, e)); - else this.embeds = this.embeds.slice(); - - if ('attachments' in data) { - this.attachments = new Collection(); - for (const attachment of data.attachments) this.attachments.set(attachment.id, new Attachment(this, attachment)); - } else { - this.attachments = new Collection(this.attachments); - } - - this.mentions = new Mentions( - this, - 'mentions' in data ? data.mentions : this.mentions.users, - 'mentions_roles' in data ? data.mentions_roles : this.mentions.roles, - 'mention_everyone' in data ? data.mention_everyone : this.mentions.everyone, - 'mention_channels' in data ? data.mention_channels : this.mentions.crosspostedChannels - ); - - this.flags = new MessageFlags('flags' in data ? data.flags : 0).freeze(); - } - - /** - * 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 url to jump to the message - * @type {string} - * @readonly - */ - get url() { - return `https://discordapp.com/channels/${this.guild ? this.guild.id : '@me'}/${this.channel.id}/${this.id}`; - } - - /** - * 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; - }); - } - - /** - * Creates a reaction collector. - * @param {CollectorFilter} filter The filter to apply - * @param {ReactionCollectorOptions} [options={}] Options to send to the collector - * @returns {ReactionCollector} - * @example - * // Create a reaction collector - * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someID' - * const collector = message.createReactionCollector(filter, { time: 15000 }); - * collector.on('collect', r => console.log(`Collected ${r.emoji.name}`)); - * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); - */ - createReactionCollector(filter, options = {}) { - return new ReactionCollector(this, filter, options); - } - - /** - * An object containing the same properties as CollectorOptions, but a few more: - * @typedef {ReactionCollectorOptions} AwaitReactionsOptions - * @property {string[]} [errors] Stop/end reasons that cause the promise to reject - */ - - /** - * Similar to createMessageCollector but in promise form. - * Resolves with a collection of reactions that pass the specified filter. - * @param {CollectorFilter} filter The filter function to use - * @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector - * @returns {Promise<Collection<string, MessageReaction>>} - * @example - * // Create a reaction collector - * const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someID' - * message.awaitReactions(filter, { time: 15000 }) - * .then(collected => console.log(`Collected ${collected.size} reactions`)) - * .catch(console.error); - */ - awaitReactions(filter, options = {}) { - return new Promise((resolve, reject) => { - const collector = this.createReactionCollector(filter, options); - collector.once('end', (reactions, reason) => { - if (options.errors && options.errors.includes(reason)) reject(reactions); - else resolve(reactions); - }); - }); - } - - /** - * 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.deleted && (this.author.id === this.client.user.id || (this.guild && - this.channel.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_MESSAGES) - )); - } - - /** - * Whether the message is pinnable by the client user - * @type {boolean} - * @readonly - */ - get pinnable() { - return this.type === 'DEFAULT' && (!this.guild || - this.channel.permissionsFor(this.client.user).has(Permissions.FLAGS.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 The member/user to check for a mention of - * @returns {boolean} - */ - isMemberMentioned(member) { - // Lazy-loading is used here to get around a circular dependency that breaks things - if (!GuildMember) GuildMember = require('./GuildMember'); - if (this.mentions.everyone) return true; - if (this.mentions.users.has(member.id)) return true; - if (member instanceof 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 - * @property {MessageFlagsResolvable} [flags] Message flags to apply - */ - - /** - * Edit the content of the message. - * @param {StringResolvable} [content] The new content for the message - * @param {MessageEditOptions|RichEmbed} [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(`New message content: ${msg}`)) - * .catch(console.error); - */ - edit(content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - if (options instanceof RichEmbed) options = { embed: options }; - return this.client.rest.methods.updateMessage(this, content, options); - } - - /** - * Edit the content of the message, with a code block. - * @param {string} lang The language for the code block - * @param {StringResolvable} content The new content for the message - * @returns {Promise<Message>} - * @deprecated - */ - editCode(lang, content) { - content = Util.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 The emoji to react with - * @returns {Promise<MessageReaction>} - * @example - * // React to a message with a unicode emoji - * message.react('🤔') - * .then(console.log) - * .catch(console.error); - * @example - * // React to a message with a custom emoji - * message.react(message.guild.emojis.get('123456789012345678')) - * .then(console.log) - * .catch(console.error); - */ - 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.username}`)) - * .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(sent => console.log(`Sent a reply to ${sent.author.username}`)) - * .catch(console.error); - */ - reply(content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.channel.send(content, Object.assign(options, { reply: this.member || this.author })); - } - - /** - * Marks the message as read. - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<Message>} - * @deprecated - */ - acknowledge() { - return this.client.rest.methods.ackMessage(this); - } - - /** - * 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); - } - - /** - * Suppresses or unsuppresses embeds on a message - * @param {boolean} [suppress=true] If the embeds should be suppressed or not - * @returns {Promise<Message>} - */ - suppressEmbeds(suppress = true) { - const flags = new MessageFlags(this.flags.bitfield); - - if (suppress) { - flags.add(MessageFlags.FLAGS.SUPPRESS_EMBEDS); - } else { - flags.remove(MessageFlags.FLAGS.SUPPRESS_EMBEDS); - } - - return this.edit(undefined, { flags }); - } - - /** - * 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; - } - - _removeReaction(emoji, user) { - const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name; - if (this.reactions.has(emojiID)) { - const reaction = this.reactions.get(emojiID); - if (!user) { - this.reactions.delete(emojiID); - return reaction; - } - if (reaction.users.has(user.id)) { - reaction.users.delete(user.id); - reaction.count--; - if (user.id === this.client.user.id) reaction.me = false; - if (reaction.count <= 0) this.reactions.delete(emojiID); - 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 6db15c8..0000000 --- a/node_modules/discord.js/src/structures/MessageAttachment.js +++ /dev/null @@ -1,79 +0,0 @@ -const { basename } = require('path'); - -/** - * 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 {Snowflake} - */ - 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; - } - - /** - * Whether or not this attachment has been marked as a spoiler - * @type {boolean} - * @readonly - */ - get spoiler() { - return basename(this.url).startsWith('SPOILER_'); - } -} - -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 acd82be..0000000 --- a/node_modules/discord.js/src/structures/MessageCollector.js +++ /dev/null @@ -1,97 +0,0 @@ -const Collector = require('./interfaces/Collector'); -const util = require('util'); - -/** - * @typedef {CollectorOptions} MessageCollectorOptions - * @property {number} max The maximum amount of messages to process - * @property {number} maxMatches The maximum amount of messages to collect - */ - -/** - * Collects messages on a channel. - * @extends {Collector} - */ -class MessageCollector extends Collector { - /** - * @param {TextChannel|DMChannel|GroupDMChannel} channel The channel - * @param {CollectorFilter} filter The filter to be applied to this collector - * @param {MessageCollectorOptions} options The options to be applied to this collector - * @emits MessageCollector#message - */ - constructor(channel, filter, options = {}) { - super(channel.client, filter, options); - - /** - * The channel - * @type {TextBasedChannel} - */ - this.channel = channel; - - /** - * Total number of messages that were received in the channel during message collection - * @type {number} - */ - this.received = 0; - - if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() + 1); - this.client.on('message', this.listener); - - this._reEmitter = message => { - /** - * Emitted when the collector receives a message. - * @event MessageCollector#message - * @param {Message} message The message - * @deprecated - */ - this.emit('message', message); - }; - this.on('collect', this._reEmitter); - } - - // Remove in v12 - on(eventName, listener) { - if (eventName === 'message') { - listener = util.deprecate(listener, 'MessageCollector will soon no longer emit "message", use "collect" instead'); - } - super.on(eventName, listener); - } - - /** - * Handle an incoming message for possible collection. - * @param {Message} message The message that could be collected - * @returns {?{key: Snowflake, value: Message}} - * @private - */ - handle(message) { - if (message.channel.id !== this.channel.id) return null; - this.received++; - return { - key: message.id, - value: message, - }; - } - - /** - * Check after collection to see if the collector is done. - * @returns {?string} Reason to end the collector, if any - * @private - */ - postCheck() { - // Consider changing the end reasons for v12 - if (this.options.maxMatches && this.collected.size >= this.options.maxMatches) return 'matchesLimit'; - if (this.options.max && this.received >= this.options.max) return 'limit'; - return null; - } - - /** - * Removes event listeners. - * @private - */ - cleanup() { - this.removeListener('collect', this._reEmitter); - this.client.removeListener('message', this.listener); - if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() - 1); - } -} - -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 2a87679..0000000 --- a/node_modules/discord.js/src/structures/MessageEmbed.js +++ /dev/null @@ -1,386 +0,0 @@ -/** - * Represents an embed in a message (image/video preview, rich embed, etc.) - * <info>This class is only used for *received* embeds. If you wish to send one, use the {@link RichEmbed} class.</info> - */ -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 - * @type {?string} - */ - this.title = data.title; - - /** - * The description of this embed - * @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.timestamp = data.timestamp; - - /** - * The thumbnail of this embed - * @type {?MessageEmbedThumbnail} - */ - this.thumbnail = data.thumbnail ? new MessageEmbedThumbnail(this, data.thumbnail) : null; - - /** - * The image of this embed - * @type {?MessageEmbedImage} - */ - this.image = data.image ? new MessageEmbedImage(this, data.image) : null; - - /** - * The video of this embed - * @type {?MessageEmbedVideo} - */ - this.video = data.video ? new MessageEmbedVideo(this, data.video) : null; - - /** - * The author of this embed - * @type {?MessageEmbedAuthor} - */ - this.author = data.author ? new MessageEmbedAuthor(this, data.author) : null; - - /** - * The provider of this embed - * @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} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The hexadecimal version of the embed color, with a leading hash - * @type {?string} - * @readonly - */ - get hexColor() { - if (!this.color) return null; - 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 an image for a message embed. - */ -class MessageEmbedImage { - constructor(embed, data) { - /** - * The embed this image is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The URL for this image - * @type {string} - */ - this.url = data.url; - - /** - * The Proxy URL for this image - * @type {string} - */ - this.proxyURL = data.proxy_url; - - /** - * The height of the image - * @type {number} - */ - this.height = data.height; - - /** - * The width of the image - * @type {number} - */ - this.width = data.width; - } -} - -/** - * Represents a video for a message embed. - */ -class MessageEmbedVideo { - constructor(embed, data) { - /** - * The embed this video is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The source URL for this video - * @type {string} - */ - this.url = data.url; - - /** - * The height of the video - * @type {number} - */ - this.height = data.height; - - /** - * The width of the video - * @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.Image = MessageEmbedImage; -MessageEmbed.Video = MessageEmbedVideo; -MessageEmbed.Provider = MessageEmbedProvider; -MessageEmbed.Author = MessageEmbedAuthor; -MessageEmbed.Field = MessageEmbedField; -MessageEmbed.Footer = MessageEmbedFooter; - -module.exports = MessageEmbed; diff --git a/node_modules/discord.js/src/structures/MessageMentions.js b/node_modules/discord.js/src/structures/MessageMentions.js deleted file mode 100644 index 47aff55..0000000 --- a/node_modules/discord.js/src/structures/MessageMentions.js +++ /dev/null @@ -1,185 +0,0 @@ -const Collection = require('../util/Collection'); -const { ChannelTypes } = require('../util/Constants'); - -/** - * Keeps track of mentions in a {@link Message}. - */ -class MessageMentions { - constructor(message, users, roles, everyone, crosspostedChannels) { - /** - * Whether `@everyone` or `@here` were mentioned - * @type {boolean} - */ - this.everyone = Boolean(everyone); - - if (users) { - if (users instanceof Collection) { - /** - * Any users that were mentioned - * <info>Order as received from the API, not as they appear in the message content</info> - * @type {Collection<Snowflake, User>} - */ - this.users = new Collection(users); - } else { - this.users = new Collection(); - for (const mention of users) { - let user = message.client.users.get(mention.id); - if (!user) user = message.client.dataManager.newUser(mention); - this.users.set(user.id, user); - if (mention.member && message.guild && !message.guild.members.has(mention.id)) { - message.guild._addMember(Object.assign(mention.member, { user }), false); - } - } - } - } else { - this.users = new Collection(); - } - - if (roles) { - if (roles instanceof Collection) { - /** - * Any roles that were mentioned - * <info>Order as received from the API, not as they appear in the message content</ - * @type {Collection<Snowflake, Role>} - */ - this.roles = new Collection(roles); - } else { - this.roles = new Collection(); - for (const mention of roles) { - const role = message.channel.guild.roles.get(mention); - if (role) this.roles.set(role.id, role); - } - } - } else { - this.roles = new Collection(); - } - - /** - * Content of the message - * @type {Message} - * @private - */ - this._content = message.content; - - /** - * The client the message is from - * @type {Client} - * @private - */ - this._client = message.client; - - /** - * The guild the message is in - * @type {?Guild} - * @private - */ - this._guild = message.channel.guild; - - /** - * Cached members for {@MessageMention#members} - * @type {?Collection<Snowflake, GuildMember>} - * @private - */ - this._members = null; - - /** - * Cached channels for {@MessageMention#channels} - * @type {?Collection<Snowflake, GuildChannel>} - * @private - */ - this._channels = null; - - /** - * Crossposted channel data. - * @typedef {Object} CrosspostedChannel - * @property {Snowflake} channelID ID of the mentioned channel - * @property {Snowflake} guildID ID of the guild that has the channel - * @property {string} type Type of the channel - * @property {string} name Name of the channel - */ - - if (crosspostedChannels) { - if (crosspostedChannels instanceof Collection) { - /** - * A collection of crossposted channels - * @type {Collection<Snowflake, CrosspostedChannel>} - */ - this.crosspostedChannels = new Collection(crosspostedChannels); - } else { - this.crosspostedChannels = new Collection(); - const channelTypes = Object.keys(ChannelTypes); - for (const d of crosspostedChannels) { - const type = channelTypes[d.type]; - this.crosspostedChannels.set(d.id, { - channelID: d.id, - guildID: d.guild_id, - type: type ? type.toLowerCase() : 'unknown', - name: d.name, - }); - } - } - } else { - this.crosspostedChannels = new Collection(); - } - } - - /** - * Any members that were mentioned (only in {@link TextChannel}s) - * <info>Order as received from the API, not as they appear in the message content</ - * @type {?Collection<Snowflake, GuildMember>} - * @readonly - */ - get members() { - if (this._members) return this._members; - if (!this._guild) return null; - this._members = new Collection(); - this.users.forEach(user => { - const member = this._guild.member(user); - if (member) this._members.set(member.user.id, member); - }); - return this._members; - } - - /** - * Any channels that were mentioned - * <info>Order as they appear first in the message content</info> - * @type {Collection<Snowflake, GuildChannel>} - * @readonly - */ - get channels() { - if (this._channels) return this._channels; - this._channels = new Collection(); - let matches; - while ((matches = this.constructor.CHANNELS_PATTERN.exec(this._content)) !== null) { - const chan = this._client.channels.get(matches[1]); - if (chan) this._channels.set(chan.id, chan); - } - return this._channels; - } -} - -/** - * Regular expression that globally matches `@everyone` and `@here` - * @type {RegExp} - */ -MessageMentions.EVERYONE_PATTERN = /@(everyone|here)/g; - -/** - * Regular expression that globally matches user mentions like `<@81440962496172032>` - * @type {RegExp} - */ -MessageMentions.USERS_PATTERN = /<@!?[0-9]+>/g; - -/** - * Regular expression that globally matches role mentions like `<@&297577916114403338>` - * @type {RegExp} - */ -MessageMentions.ROLES_PATTERN = /<@&[0-9]+>/g; - -/** - * Regular expression that globally matches channel mentions like `<#222079895583457280>` - * @type {RegExp} - */ -MessageMentions.CHANNELS_PATTERN = /<#([0-9]+)>/g; - -module.exports = MessageMentions; 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 9109e18..0000000 --- a/node_modules/discord.js/src/structures/MessageReaction.js +++ /dev/null @@ -1,107 +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<Snowflake, User>} - */ - this.users = new Collection(); - - this._emoji = new ReactionEmoji(this, emoji); - } - - /** - * 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} - * @readonly - */ - 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] The user to remove the reaction of - * @returns {Promise<MessageReaction>} - */ - remove(user = this.message.client.user) { - const message = this.message; - const userID = this.message.client.resolver.resolveUserID(user); - if (!userID) return Promise.reject(new Error('Couldn\'t resolve the user ID to remove from the reaction.')); - return message.client.rest.methods.removeMessageReaction( - message, this.emoji.identifier, userID - ); - } - - /** - * Removes this reaction from the message - * @returns {Promise<MessageReaction>} - */ - removeAll() { - const message = this.message; - return message.client.rest.methods.removeMessageReactionEmoji( - message, this.emoji.identifier - ); - } - - /** - * 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 - * @param {Object} [options] Options to fetch users - * @param {Snowflake} [options.before] Limit fetching users to those with an id lower than the supplied id - * @param {Snowflake} [options.after] Limit fetching users to those with an id greater than the supplied id - * @returns {Promise<Collection<Snowflake, User>>} - */ - fetchUsers(limit = 100, { after, before } = {}) { - const message = this.message; - return message.client.rest.methods.getMessageReactionUsers( - message, this.emoji.identifier, { after, before, limit } - ).then(data => { - const users = new Collection(); - for (const rawUser of data) { - const user = this.message.client.dataManager.newUser(rawUser); - this.users.set(user.id, user); - users.set(user.id, user); - } - return users; - }); - } -} - -module.exports = MessageReaction; diff --git a/node_modules/discord.js/src/structures/NewsChannel.js b/node_modules/discord.js/src/structures/NewsChannel.js deleted file mode 100644 index bcbfbf3..0000000 --- a/node_modules/discord.js/src/structures/NewsChannel.js +++ /dev/null @@ -1,24 +0,0 @@ -const TextChannel = require('./TextChannel'); - -/** - * Represents a guild news channel on Discord. - * @extends {TextChannel} - */ -class NewsChannel extends TextChannel { - constructor(guild, data) { - super(guild, data); - this.type = 'news'; - } - - setup(data) { - super.setup(data); - - /** - * The ratelimit per user for this channel (always 0) - * @type {number} - */ - this.rateLimitPerUser = 0; - } -} - -module.exports = NewsChannel; 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 710aae8..0000000 --- a/node_modules/discord.js/src/structures/OAuth2Application.js +++ /dev/null @@ -1,157 +0,0 @@ -const Snowflake = require('../util/Snowflake'); -const Team = require('./Team'); -const util = require('util'); - -/** - * 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 {Snowflake} - */ - 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 {?string[]} - */ - this.rpcOrigins = data.rpc_origins; - - /** - * The app's redirect URIs - * @type {string[]} - */ - this.redirectURIs = data.redirect_uris; - - /** - * If this app's bot requires a code grant when using the OAuth2 flow - * @type {boolean} - */ - this.botRequireCodeGrant = data.bot_require_code_grant; - - /** - * If this app's bot is public - * @type {boolean} - */ - this.botPublic = data.bot_public; - - /** - * If this app can use rpc - * @type {boolean} - */ - this.rpcApplicationState = data.rpc_application_state; - - /** - * Object containing basic info about this app's bot - * @type {Object} - */ - this.bot = data.bot; - - /** - * The flags for the app - * @type {number} - */ - this.flags = data.flags; - - /** - * OAuth2 secret for the application - * @type {boolean} - */ - this.secret = data.secret; - - if (data.owner) { - /** - * The owner of this OAuth application - * @type {?User} - */ - this.owner = this.client.dataManager.newUser(data.owner); - } - - /** - * The owning team of this OAuth application - * <info>In v12.0.0 this property moves to `Team#owner`.</info> - * @type {?Team} - * @deprecated - */ - this.team = data.team ? new Team(this.client, data.team) : null; - } - - /** - * The timestamp the app was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the app was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Reset the app's secret and bot token. - * <warn>This is only available when using a user account.</warn> - * @returns {OAuth2Application} - * @deprecated - */ - reset() { - return this.client.rest.methods.resetApplication(this.id); - } - - /** - * When concatenated with a string, this automatically concatenates the app name rather than the app object. - * @returns {string} - */ - toString() { - return this.name; - } -} - -OAuth2Application.prototype.reset = - util.deprecate(OAuth2Application.prototype.reset, 'OAuth2Application#reset: userbot methods will be removed'); - -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 3eb64f2..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 {Snowflake} - */ - this.id = data.id; - - /** - * The name of this guild - * @type {string} - */ - this.name = data.name; - - /** - * The hash of this guild's icon - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image (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 c30c054..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 {Snowflake} - */ - 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 ebb78fb..0000000 --- a/node_modules/discord.js/src/structures/PermissionOverwrites.js +++ /dev/null @@ -1,69 +0,0 @@ -const Permissions = require('../util/Permissions'); - -/** - * 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 {Snowflake} - */ - this.id = data.id; - - /** - * The type of this overwrite - * @type {string} - */ - this.type = data.type; - - /** - * The permissions that are denied for the user or role as a bitfield. - * @type {number} - */ - this.deny = data.deny; - - /** - * The permissions that are allowed for the user or role as a bitfield. - * @type {number} - */ - this.allow = data.allow; - - /** - * The permissions that are denied for the user or role. - * @type {Permissions} - * @deprecated - */ - this.denied = new Permissions(data.deny).freeze(); - - /** - * The permissions that are allowed for the user or role. - * @type {Permissions} - * @deprecated - */ - this.allowed = new Permissions(data.allow).freeze(); - } - - /** - * Delete this Permission Overwrite. - * @param {string} [reason] Reason for deleting this overwrite - * @returns {Promise<PermissionOverwrites>} - */ - delete(reason) { - return this.channel.client.rest.methods.deletePermissionOverwrites(this, reason); - } -} - -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 18cc3cc..0000000 --- a/node_modules/discord.js/src/structures/Presence.js +++ /dev/null @@ -1,301 +0,0 @@ -const { ActivityFlags, Endpoints } = require('../util/Constants'); -const ReactionEmoji = require('./ReactionEmoji'); - -/** - * The status of this presence: - * * **`online`** - user is online - * * **`idle`** - user is AFK - * * **`offline`** - user is offline or invisible - * * **`dnd`** - user is in Do Not Disturb - * @typedef {string} PresenceStatus - */ - -/** - * The status of this presence: - * * **`online`** - user is online - * * **`idle`** - user is AFK - * * **`dnd`** - user is in Do Not Disturb - * @typedef {string} ClientPresenceStatus - */ - -/** - * Represents a user's presence. - */ -class Presence { - constructor(data = {}, client) { - /** - * The client that instantiated this - * @name Presence#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.update(data); - } - - update(data) { - /** - * The status of this presence: - * @type {PresenceStatus} - */ - this.status = data.status || this.status || 'offline'; - - /** - * The game that the user is playing - * @type {?Game} - * @deprecated - */ - this.game = data.game ? new Game(data.game, this) : null; - - if (data.activities) { - /** - * The activities of this presence - * @type {Game[]} - */ - this.activities = data.activities.map(activity => new Game(activity, this)); - } else if (data.activity || data.game) { - this.activities = [new Game(data.activity || data.game, this)]; - } else { - this.activities = []; - } - - /** - * The devices this presence is on - * @type {?Object} - * @property {?ClientPresenceStatus} web The current presence in the web application - * @property {?ClientPresenceStatus} mobile The current presence in the mobile application - * @property {?ClientPresenceStatus} desktop The current presence in the desktop application - */ - this.clientStatus = data.client_status || null; - } - - /** - * Whether this presence is equal to another - * @param {Presence} presence The presence to compare with - * @returns {boolean} - */ - equals(presence) { - return this === presence || ( - presence && - this.status === presence.status && - this.activities.length === presence.activities.length && - this.activities.every((activity, index) => activity.equals(presence.activities[index])) && - this.clientStatus.web === presence.clientStatus.web && - this.clientStatus.mobile === presence.clientStatus.mobile && - this.clientStatus.desktop === presence.clientStatus.desktop - ); - } -} - -/** - * Represents a game that is part of a user's presence. - */ -class Game { - constructor(data, presence) { - Object.defineProperty(this, 'presence', { value: presence }); - - /** - * The name of the game being played - * @type {string} - */ - this.name = data.name; - - /** - * The type of the game status, its possible values: - * - 0: Playing - * - 1: Streaming - * - 2: Listening - * - 3: Watching - * @type {number} - */ - this.type = data.type; - - /** - * If the game is being streamed, a link to the stream - * @type {?string} - */ - this.url = data.url || null; - - /** - * Details about the activity - * @type {?string} - */ - this.details = data.details || null; - - /** - * State of the activity - * @type {?string} - */ - this.state = data.state || null; - - /** - * Application ID associated with this activity - * @type {?Snowflake} - */ - this.applicationID = data.application_id || null; - - /** - * Timestamps for the activity - * @type {?Object} - * @prop {?Date} start When the activity started - * @prop {?Date} end When the activity will end - */ - this.timestamps = data.timestamps ? { - start: data.timestamps.start ? new Date(Number(data.timestamps.start)) : null, - end: data.timestamps.end ? new Date(Number(data.timestamps.end)) : null, - } : null; - - /** - * Party of the activity - * @type {?Object} - * @prop {?string} id ID of the party - * @prop {number[]} size Size of the party as `[current, max]` - */ - this.party = data.party || null; - - /** - * Assets for rich presence - * @type {?RichPresenceAssets} - */ - this.assets = data.assets ? new RichPresenceAssets(this, data.assets) : null; - - if (data.emoji) { - /** - * Emoji for a custom activity - * <warn>There is no `reaction` property for this emoji.</warn> - * @type {?ReactionEmoji} - */ - this.emoji = new ReactionEmoji({ message: { client: this.presence.client } }, data.emoji); - this.emoji.reaction = null; - } else { - this.emoji = null; - } - - - /** - * Creation date of the activity - * @type {number} - */ - this.createdTimestamp = new Date(data.created_at).getTime(); - - this.syncID = data.sync_id; - this._flags = data.flags; - } - - /** - * The time the activity was created at - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Flags that describe the activity - * @type {ActivityFlags[]} - */ - get flags() { - const flags = []; - for (const [name, flag] of Object.entries(ActivityFlags)) { - if ((this._flags & flag) === flag) flags.push(name); - } - return flags; - } - - /** - * Whether or not the game is being streamed - * @type {boolean} - * @readonly - */ - get streaming() { - return this.type === 1; - } - - /** - * When concatenated with a string, this automatically returns the game's name instead of the Game object. - * @returns {string} - */ - toString() { - return this.name; - } - - /** - * Whether this game is equal to another game - * @param {Game} game The game to compare with - * @returns {boolean} - */ - equals(game) { - return this === game || ( - game && - this.name === game.name && - this.type === game.type && - this.url === game.url - ); - } -} - -/** - * Assets for a rich presence - */ -class RichPresenceAssets { - constructor(game, assets) { - Object.defineProperty(this, 'game', { value: game }); - - /** - * Hover text for the large image - * @type {?string} - */ - this.largeText = assets.large_text || null; - - /** - * Hover text for the small image - * @type {?string} - */ - this.smallText = assets.small_text || null; - - /** - * ID of the large image asset - * @type {?Snowflake} - */ - this.largeImage = assets.large_image || null; - - /** - * ID of the small image asset - * @type {?Snowflake} - */ - this.smallImage = assets.small_image || null; - } - - /** - * The URL of the small image asset - * @type {?string} - * @readonly - */ - get smallImageURL() { - if (!this.smallImage) return null; - return Endpoints.CDN(this.game.presence.client.options.http.cdn) - .AppAsset(this.game.applicationID, this.smallImage); - } - - /** - * The URL of the large image asset - * @type {?string} - * @readonly - */ - get largeImageURL() { - if (!this.largeImage) return null; - if (/^spotify:/.test(this.largeImage)) { - return `https://i.scdn.co/image/${this.largeImage.slice(8)}`; - } else if (/^twitch:/.test(this.largeImage)) { - return `https://static-cdn.jtvnw.net/previews-ttv/live_user_${this.largeImage.slice(7)}.png`; - } - return Endpoints.CDN(this.game.presence.client.options.http.cdn) - .AppAsset(this.game.applicationID, this.largeImage); - } -} - -exports.Presence = Presence; -exports.Game = Game; -exports.RichPresenceAssets = RichPresenceAssets; diff --git a/node_modules/discord.js/src/structures/ReactionCollector.js b/node_modules/discord.js/src/structures/ReactionCollector.js deleted file mode 100644 index 2b3235e..0000000 --- a/node_modules/discord.js/src/structures/ReactionCollector.js +++ /dev/null @@ -1,89 +0,0 @@ -const Collector = require('./interfaces/Collector'); -const Collection = require('../util/Collection'); - -/** - * @typedef {CollectorOptions} ReactionCollectorOptions - * @property {number} max The maximum total amount of reactions to collect - * @property {number} maxEmojis The maximum number of emojis to collect - * @property {number} maxUsers The maximum number of users to react - */ - -/** - * Collects reactions on messages. - * @extends {Collector} - */ -class ReactionCollector extends Collector { - /** - * @param {Message} message The message upon which to collect reactions - * @param {CollectorFilter} filter The filter to apply to this collector - * @param {ReactionCollectorOptions} [options={}] The options to apply to this collector - */ - constructor(message, filter, options = {}) { - super(message.client, filter, options); - - /** - * The message - * @type {Message} - */ - this.message = message; - - /** - * The users which have reacted - * @type {Collection} - */ - this.users = new Collection(); - - /** - * The total number of reactions collected - * @type {number} - */ - this.total = 0; - - if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() + 1); - this.client.on('messageReactionAdd', this.listener); - - this.on('fullCollect', (reaction, user) => { - this.users.set(user.id, user); - this.total++; - }); - } - - /** - * Handle an incoming reaction for possible collection. - * @param {MessageReaction} reaction The reaction to possibly collect - * @returns {?{key: Snowflake, value: MessageReaction}} - * @private - */ - handle(reaction) { - if (reaction.message.id !== this.message.id) return null; - return { - key: reaction.emoji.id || reaction.emoji.name, - value: reaction, - }; - } - - /** - * Check after collection to see if the collector is done. - * @param {MessageReaction} reaction The reaction that was collected - * @param {User} user The user that reacted - * @returns {?string} Reason to end the collector, if any - * @private - */ - postCheck() { - if (this.options.max && this.total >= this.options.max) return 'limit'; - if (this.options.maxEmojis && this.collected.size >= this.options.maxEmojis) return 'emojiLimit'; - if (this.options.maxUsers && this.users.size >= this.options.maxUsers) return 'userLimit'; - return null; - } - - /** - * Remove event listeners. - * @private - */ - cleanup() { - this.client.removeListener('messageReactionAdd', this.listener); - if (this.client.getMaxListeners() !== 0) this.client.setMaxListeners(this.client.getMaxListeners() - 1); - } -} - -module.exports = ReactionCollector; 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 9f7597e..0000000 --- a/node_modules/discord.js/src/structures/ReactionEmoji.js +++ /dev/null @@ -1,98 +0,0 @@ -const Constants = require('../util/Constants'); -const Snowflake = require('../util/Snowflake'); - -/** - * 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, emoji) { - /** - * The client that instantiated this object - * @name ReactionEmoji#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: reaction.message.client }); - - /** - * The message reaction this emoji refers to - * @type {MessageReaction} - */ - this.reaction = reaction; - - /** - * The name of this reaction emoji - * @type {string} - */ - this.name = emoji.name; - - /** - * The ID of this reaction emoji - * @type {?Snowflake} - */ - this.id = emoji.id; - - /** - * Whether this reaction emoji is animated - * @type {boolean} - */ - this.animated = emoji.animated || false; - } - - /** - * The timestamp the reaction emoji was created at, or null if unicode - * @type {?number} - * @readonly - */ - get createdTimestamp() { - if (!this.id) return null; - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the reaction emoji was created, or null if unicode - * @type {?Date} - * @readonly - */ - get createdAt() { - if (!this.id) return null; - return new Date(this.createdTimestamp); - } - - /** - * The URL to the reaction emoji file, or null if unicode - * @type {string} - * @readonly - */ - get url() { - if (!this.id) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).Emoji(this.id, this.animated ? 'gif' : 'png'); - } - - /** - * The identifier of this emoji, used for message reactions - * @type {string} - * @readonly - */ - 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.send(`The emoji used is ${reaction.emoji}`); - * @returns {string} - */ - toString() { - if (!this.id) return this.name; - - return `<${this.animated ? 'a' : ''}:${this.name}:${this.id}>`; - } -} - -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 5ccb22d..0000000 --- a/node_modules/discord.js/src/structures/RichEmbed.js +++ /dev/null @@ -1,331 +0,0 @@ -const Attachment = require('./Attachment'); -const MessageEmbed = require('./MessageEmbed'); -const util = require('../util/Util'); -let ClientDataResolver; - -/** - * A rich embed to be sent with a message with a fluent interface for creation. - * @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; - - /** - * File to upload alongside this Embed - * @type {FileOptions|string|Attachment} - */ - this.file = data.file; - - /** - * The files to upload alongside this Embed - * @type {Array<FileOptions|string|Attachment>} - */ - this.files = []; - } - - /** - * Sets the title of this embed. - * @param {StringResolvable} title The title - * @returns {RichEmbed} This embed - */ - setTitle(title) { - title = util.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 = util.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 {ColorResolvable} color The color of the embed - * @returns {RichEmbed} This embed - */ - setColor(color) { - if (!ClientDataResolver) ClientDataResolver = require('../client/ClientDataResolver'); - this.color = ClientDataResolver.resolveColor(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: util.resolveString(name), icon_url: icon, url }; - return this; - } - - /** - * Sets the timestamp of this embed. - * @param {Date|number} [timestamp=Date.now()] The timestamp or date - * @returns {RichEmbed} This embed - */ - setTimestamp(timestamp = Date.now()) { - if (timestamp instanceof Date) timestamp = timestamp.getTime(); - 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.'); - this.fields.push(this.constructor.normalizeField(name, value, inline)); - return this; - } - - /** - * Convenience function for `<RichEmbed>.addField('\u200B', '\u200B', inline)`. - * @param {boolean} [inline=false] Set the field to display inline - * @returns {RichEmbed} This embed - */ - addBlankField(inline = false) { - return this.addField('\u200B', '\u200B', inline); - } - - /** - * @typedef {Object} EmbedField - * @property {string} name The name of this field - * @property {string} value The value of this field - * @property {boolean} inline If this field will be displayed inline - */ - - /** - * @typedef {Object} EmbedFieldData - * @property {StringResolvable} name The name of this field - * @property {StringResolvable} value The value of this field - * @property {boolean} [inline=false] If this field will be displayed inline - */ - - /** - * Removes, replaces, and inserts fields in the embed (max 25). - * @param {number} index The index to start at - * @param {number} deleteCount The number of fields to remove - * @param {...EmbedFieldData} [fields] The replacing field objects - * @returns {RichEmbed} - */ - spliceFields(index, deleteCount, ...fields) { - if (fields) { - const mapper = ({ name, value, inline }) => this.constructor.normalizeField(name, value, inline); - this.fields.splice(index, deleteCount, ...fields.map(mapper)); - } else { - this.fields.splice(index, deleteCount); - } - 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 image - * @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 = util.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; - } - - /** - * Sets the file to upload alongside the embed. This file can be accessed via `attachment://fileName.extension` when - * setting an embed image or author/footer icons. Only one file may be attached. - * @param {FileOptions|string|Attachment} file Local path or URL to the file to attach, - * or valid FileOptions for a file to attach - * @returns {RichEmbed} This embed - */ - attachFile(file) { - if (this.file) throw new RangeError('You may not upload more than one file at once.'); - if (file instanceof Attachment) file = file.file; - this.file = file; - return this; - } - - /** - * Sets the files to upload alongside the embed. A file can be accessed via `attachment://fileName.extension` when - * setting an embed image or author/footer icons. Multiple files can be attached. - * @param {Array<FileOptions|string|Attachment>} files Files to attach - * @returns {RichEmbed} - */ - attachFiles(files) { - files = files.map(file => file instanceof Attachment ? file.file : file); - this.files = this.files.concat(files); - return this; - } - - /** - * The accumulated length for the embed title, description, fields, author and footer text - * @type {number} - * @readonly - */ - get length() { - return ( - (this.title ? this.title.length : 0) + - (this.description ? this.description.length : 0) + - (this.fields.length >= 1 ? this.fields.reduce((prev, curr) => - prev + curr.name.length + curr.value.length, 0) : 0) + - (this.footer ? this.footer.text.length : 0) + - (this.author ? this.author.name.length : 0)); - } - - /** - * Transforms the embed to a plain object. - * @returns {Object} The raw data of this embed - */ - toJSON() { - return { - title: this.title, - type: 'rich', - description: this.description, - url: this.url, - timestamp: this.timestamp ? new Date(this.timestamp) : null, - color: this.color, - fields: this.fields ? - this.fields.map(field => ({ name: field.name, value: field.value, inline: field.inline })) : - null, - thumbnail: this.thumbnail ? { - url: this.thumbnail.url, - } : null, - image: this.image ? { - url: this.image.url, - } : null, - author: this.author ? { - name: this.author.name, - url: this.author.url, - icon_url: this.author instanceof MessageEmbed.Author ? this.author.iconURL : this.author.icon_url, - } : null, - footer: this.footer ? { - text: this.footer.text, - icon_url: this.footer instanceof MessageEmbed.Footer ? this.footer.iconURL : this.footer.icon_url, - } : null, - }; - } - - /** - * Normalizes field input and resolves strings. - * @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 {EmbedField} - */ - static normalizeField(name, value, inline = false) { - name = util.resolveString(name); - if (name.length > 256) throw new RangeError('RichEmbed field names may not exceed 256 characters.'); - if (!/\S/.test(name)) throw new RangeError('RichEmbed field names may not be empty.'); - value = util.resolveString(value); - if (value.length > 1024) throw new RangeError('RichEmbed field values may not exceed 1024 characters.'); - if (!/\S/.test(value)) throw new RangeError('RichEmbed field values may not be empty.'); - return { name, value, inline }; - } -} - -module.exports = RichEmbed; 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 056cf98..0000000 --- a/node_modules/discord.js/src/structures/Role.js +++ /dev/null @@ -1,376 +0,0 @@ -const Snowflake = require('../util/Snowflake'); -const Permissions = require('../util/Permissions'); -const util = require('util'); - -/** - * 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; - - /** - * Whether the role has been deleted - * @type {boolean} - */ - this.deleted = false; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of the role (unique to the guild it is part of) - * @type {Snowflake} - */ - 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 from the API - * @type {number} - */ - this.position = data.position; - - /** - * The permissions bitfield of the role - * @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 Snowflake.deconstruct(this.id).timestamp; - } - - /** - * 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<Snowflake, 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.permissions.has(Permissions.FLAGS.MANAGE_ROLES_OR_PERMISSIONS)) return false; - return clientMember.highestRole.comparePositionTo(this) > 0; - } - - /** - * The position of the role in the role manager - * @type {number} - * @readonly - */ - get calculatedPosition() { - const sorted = this.guild._sortedRoles; - return sorted.array().indexOf(sorted.get(this.id)); - } - - /** - * Get an object mapping permission names to whether or not the role enables that permission. - * @returns {Object<string, boolean>} - * @example - * // Print the serialized role permissions - * console.log(role.serialize()); - */ - serialize() { - return new Permissions(this.permissions).serialize(); - } - - /** - * Checks if the role has a permission. - * @param {PermissionResolvable} permission Permission(s) to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission - * **(deprecated)** - * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override - * (takes priority over `explicit`) - * @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, checkAdmin) { - return new Permissions(this.permissions).has( - permission, typeof checkAdmin !== 'undefined' ? checkAdmin : !explicit - ); - } - - /** - * 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} - * @deprecated - */ - hasPermissions(permissions, explicit = false) { - return new Permissions(this.permissions).has(permissions, !explicit); - } - - /** - * Compares this role's position to another role's. - * @param {Role} role Role to compare to this one - * @returns {number} Negative number if this role's position is lower (other role's is higher), - * positive number if 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 {ColorResolvable} [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 {PermissionResolvable|number} [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 - * @param {string} [reason] The reason for editing this role - * @returns {Promise<Role>} - * @example - * // Edit name of a role - * role.edit({ name: 'New Name' }) - * .then(updated => console.log(`Edited role name from ${role.name} to ${updated.name}`)) - * .catch(console.error); - */ - edit(data, reason) { - return this.client.rest.methods.updateGuildRole(this, data, reason); - } - - /** - * Set a new name for the role. - * @param {string} name The new name of the role - * @param {string} [reason] Reason for changing the role's name - * @returns {Promise<Role>} - * @example - * // Set the name of the role - * role.setName('New Name') - * .then(updated => console.log(`Edited role name from ${role.name} to ${updated.name}`)) - * .catch(console.error); - */ - setName(name, reason) { - return this.edit({ name }, reason); - } - - /** - * Set a new color for the role. - * @param {ColorResolvable} color The color of the role - * @param {string} [reason] Reason for changing the role's color - * @returns {Promise<Role>} - * @example - * // Set the color of a role - * role.setColor('#FF0000') - * .then(updated => console.log(`Set color of role to ${role.color}`)) - * .catch(console.error); - */ - setColor(color, reason) { - return this.edit({ color }, reason); - } - - /** - * Set whether or not the role should be hoisted. - * @param {boolean} hoist Whether or not to hoist the role - * @param {string} [reason] Reason for setting whether or not the role should be hoisted - * @returns {Promise<Role>} - * @example - * // Set the hoist of the role - * role.setHoist(true) - * .then(updated => console.log(`Role hoisted: ${updated.hoist}`)) - * .catch(console.error); - */ - setHoist(hoist, reason) { - return this.edit({ hoist }, reason); - } - - /** - * Set the position of the role. - * @param {number} position The position of the role - * @param {boolean} [relative=false] Move the position relative to its current value - * @returns {Promise<Role>} - * @example - * // Set the position of the role - * role.setPosition(1) - * .then(updated => console.log(`Role position: ${updated.position}`)) - * .catch(console.error); - */ - setPosition(position, relative) { - return this.guild.setRolePosition(this, position, relative).then(() => this); - } - - /** - * Set the permissions of the role. - * @param {PermissionResolvable} permissions The permissions of the role - * @param {string} [reason] Reason for changing the role's permissions - * @returns {Promise<Role>} - * @example - * // Set the permissions of the role - * role.setPermissions(['KICK_MEMBERS', 'BAN_MEMBERS']) - * .then(updated => console.log(`Updated permissions to ${updated.permissions.bitfield}`)) - * .catch(console.error); - * @example - * // Remove all permissions from a role - * role.setPermissions(0) - * .then(updated => console.log(`Updated permissions to ${updated.permissions.bitfield}`)) - * .catch(console.error); - */ - setPermissions(permissions, reason) { - return this.edit({ permissions }, reason); - } - - /** - * Set whether this role is mentionable. - * @param {boolean} mentionable Whether this role should be mentionable - * @param {string} [reason] Reason for setting whether or not this role should be mentionable - * @returns {Promise<Role>} - * @example - * // Make the role mentionable - * role.setMentionable(true, 'Role needs to be pinged') - * .then(updated => console.log(`Role mentionable: ${updated.mentionable}`)) - * .catch(console.error); - */ - setMentionable(mentionable, reason) { - return this.edit({ mentionable }, reason); - } - - /** - * Deletes the role. - * @param {string} [reason] Reason for deleting the role - * @returns {Promise<Role>} - * @example - * // Delete a role - * role.delete('The role needed to go') - * .then(deleted => console.log(`Deleted role ${deleted.name}`)) - * .catch(console.error); - */ - delete(reason) { - return this.client.rest.methods.deleteGuildRole(this, reason); - } - - /** - * 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; - } -} - -Role.prototype.hasPermissions = util - .deprecate(Role.prototype.hasPermissions, - 'Role#hasPermissions is deprecated - use Role#hasPermission instead, it now takes an array'); - -module.exports = Role; diff --git a/node_modules/discord.js/src/structures/StoreChannel.js b/node_modules/discord.js/src/structures/StoreChannel.js deleted file mode 100644 index 8985c0f..0000000 --- a/node_modules/discord.js/src/structures/StoreChannel.js +++ /dev/null @@ -1,25 +0,0 @@ -const GuildChannel = require('./GuildChannel'); - -/** - * Represents a guild store channel on Discord. - * @extends {GuildChannel} - */ -class StoreChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - this.type = 'store'; - } - - setup(data) { - super.setup(data); - - /** - * If the guild considers this channel NSFW - * @type {boolean} - * @readonly - */ - this.nsfw = data.nsfw; - } -} - -module.exports = StoreChannel; diff --git a/node_modules/discord.js/src/structures/Team.js b/node_modules/discord.js/src/structures/Team.js deleted file mode 100644 index e0dc0e0..0000000 --- a/node_modules/discord.js/src/structures/Team.js +++ /dev/null @@ -1,109 +0,0 @@ -const Snowflake = require('../util/Snowflake'); -const Collection = require('../util/Collection'); -const TeamMember = require('./TeamMember'); -const Constants = require('../util/Constants'); - -/** - * Represents a Client OAuth2 Application Team. - */ -class Team { - constructor(client, data) { - /** - * The client that instantiated the team - * @name Team#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this._patch(data); - } - - _patch(data) { - /** - * The ID of the Team - * @type {Snowflake} - */ - this.id = data.id; - - /** - * The name of the Team - * @type {string} - */ - this.name = data.name; - - /** - * The Team's icon hash - * @type {?string} - */ - this.icon = data.icon || null; - - /** - * The Team's owner id - * @type {?string} - */ - this.ownerID = data.owner_user_id || null; - - /** - * The Team's members - * @type {Collection<Snowflake, TeamMember>} - */ - this.members = new Collection(); - - for (const memberData of data.members) { - const member = new TeamMember(this.client, this, memberData); - this.members.set(member.id, member); - } - } - - /** - * The owner of the team - * @type {?TeamMember} - * @readonly - */ - get owner() { - return this.members.get(this.ownerID) || null; - } - - /** - * The timestamp the team was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the team was created at - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * A link to the teams's icon. - * @type {?string} - * @readonly - */ - get iconURL() { - if (!this.icon) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).TeamIcon(this.id, this.icon); - } - - /** - * When concatenated with a string, this automatically returns the Team's name instead of the - * Team object. - * @returns {string} - * @example - * // Logs: Team name: My Team - * console.log(`Team name: ${team}`); - */ - toString() { - return this.name; - } -} - -module.exports = Team; diff --git a/node_modules/discord.js/src/structures/TeamMember.js b/node_modules/discord.js/src/structures/TeamMember.js deleted file mode 100644 index 5dbc2ce..0000000 --- a/node_modules/discord.js/src/structures/TeamMember.js +++ /dev/null @@ -1,67 +0,0 @@ -const { MembershipStates } = require('../util/Constants'); - -/** - * Represents a Client OAuth2 Application Team Member. - */ -class TeamMember { - constructor(client, team, data) { - /** - * The client that instantiated the Team Member - * @name TeamMember#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The Team this member is part of - * @type {Team} - */ - this.team = team; - - this._patch(data); - } - - _patch(data) { - /** - * The permissions this Team Member has with regard to the team - * @type {string[]} - */ - this.permissions = data.permissions; - - /** - * The membership state this Team Member has with regard to the team - * @type {MembershipStates} - */ - this.membershipState = MembershipStates[data.membership_state]; - - /** - * The user for this Team Member - * @type {User} - */ - this.user = this.client.dataManager.newUser(data.user); - } - - /** - * The ID of the Team Member - * @type {Snowflake} - * @readonly - */ - get id() { - return this.user.id; - } - - /** - * When concatenated with a string, this automatically returns the team members's mention instead of the - * TeamMember object. - * @returns {string} - * @example - * // Logs: Team Member's mention: <@123456789> - * console.log(`Team Member's mention: ${teamMember}`); - */ - toString() { - return this.user.toString(); - } -} - -module.exports = TeamMember; 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 d16dac8..0000000 --- a/node_modules/discord.js/src/structures/TextChannel.js +++ /dev/null @@ -1,154 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const TextBasedChannel = require('./interfaces/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'; - /** - * A collection containing the messages sent to this channel - * @type {Collection<Snowflake, Message>} - */ - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The topic of the text channel - * @type {?string} - */ - this.topic = data.topic; - - /** - * If the Discord considers this channel NSFW - * @type {boolean} - * @readonly - */ - this.nsfw = Boolean(data.nsfw); - - /** - * The ID of the last message sent in this channel, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = data.last_message_id; - - /** - * The timestamp when the last pinned message was pinned, if there was one - * @type {?number} - */ - this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; - - /** - * The ratelimit per user for this channel in seconds - * @type {number} - */ - this.rateLimitPerUser = data.rate_limit_per_user || 0; - } - - /** - * A collection of members that can see this channel, mapped by their ID - * @type {Collection<Snowflake, GuildMember>} - * @readonly - */ - get members() { - const members = new Collection(); - for (const member of this.guild.members.values()) { - if (this.permissionsFor(member).has('READ_MESSAGES')) { - members.set(member.id, member); - } - } - return members; - } - - /** - * Fetch all webhooks for the channel. - * @returns {Promise<Collection<Snowflake, Webhook>>} - * @example - * // Fetch webhooks - * channel.fetchWebhooks() - * .then(hooks => console.log(`This channel has ${hooks.size} hooks`)) - * .catch(console.error); - */ - fetchWebhooks() { - return this.client.rest.methods.getChannelWebhooks(this); - } - - /** - * Sets whether this channel is flagged as NSFW. - * @param {boolean} nsfw Whether the channel should be considered NSFW - * @param {string} [reason] Reason for changing the channel's NSFW flag - * @returns {Promise<TextChannel>} - */ - setNSFW(nsfw, reason) { - return this.edit({ nsfw }, reason); - } - - /** - * Create a webhook for the channel. - * @param {string} name The name of the webhook - * @param {BufferResolvable|Base64Resolvable} [avatar] The avatar for the webhook - * @param {string} [reason] Reason for creating this webhook - * @returns {Promise<Webhook>} webhook The created webhook - * @example - * channel.createWebhook('Snek', 'https://i.imgur.com/mI8XcpG.jpg') - * .then(webhook => console.log(`Created webhook ${webhook}`)) - * .catch(console.error) - */ - createWebhook(name, avatar, reason) { - if (typeof avatar === 'string' && avatar.startsWith('data:')) { - return this.client.rest.methods.createWebhook(this, name, avatar, reason); - } else { - return this.client.resolver.resolveImage(avatar).then(data => - this.client.rest.methods.createWebhook(this, name, data, reason) - ); - } - } - - /** - * Sets the rate limit per user for this channel. - * @param {number} rateLimitPerUser The new ratelimit in seconds - * @param {string} [reason] Reason for changing the channel's ratelimits - * @returns {Promise<TextChannel>} - */ - setRateLimitPerUser(rateLimitPerUser, reason) { - return this.edit({ rateLimitPerUser }, reason); - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - /* eslint-disable no-empty-function */ - get lastMessage() {} - get lastPinAt() {} - send() { } - sendMessage() { } - sendEmbed() { } - sendFile() { } - sendFiles() { } - sendCode() { } - fetchMessage() { } - fetchMessages() { } - fetchPinnedMessages() { } - search() { } - startTyping() { } - stopTyping() { } - get typing() { } - get typingCount() { } - createCollector() { } - createMessageCollector() { } - awaitMessages() { } - bulkDelete() { } - acknowledge() { } - _cacheMessage() { } -} - -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 86c2bc0..0000000 --- a/node_modules/discord.js/src/structures/User.js +++ /dev/null @@ -1,336 +0,0 @@ -const TextBasedChannel = require('./interfaces/TextBasedChannel'); -const Constants = require('../util/Constants'); -const Presence = require('./Presence').Presence; -const Snowflake = require('../util/Snowflake'); -const util = require('util'); - -/** - * Represents a user on Discord. - * @implements {TextBasedChannel} - */ -class User { - constructor(client, data) { - /** - * The client that created the instance of 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 {Snowflake} - */ - 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); - - /** - * Whether this is an Official Discord System user (part of the urgent message system) - * @type {?boolean} - * @name User#system - */ - if (typeof data.system !== 'undefined') this.system = Boolean(data.system); - - /** - * The ID of the last message sent by the user, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = null; - - /** - * The Message object of the last message sent by the user, if one was sent - * @type {?Message} - */ - this.lastMessage = 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 Snowflake.deconstruct(this.id).timestamp; - } - - /** - * 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(undefined, this.client); - } - - /** - * A link to the user's avatar - * @type {?string} - * @readonly - */ - get avatarURL() { - if (!this.avatar) return null; - return Constants.Endpoints.User(this).Avatar(this.client.options.http.cdn, this.avatar); - } - - /** - * A link to the user's default avatar - * @type {string} - * @readonly - */ - get defaultAvatarURL() { - const avatars = Object.keys(Constants.DefaultAvatars); - const avatar = avatars[this.discriminator % avatars.length]; - return Constants.Endpoints.CDN(this.client.options.http.host).Asset(`${Constants.DefaultAvatars[avatar]}.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 Discord "tag" (e.g. `hydrabolt#0001`) for this user - * @type {string} - * @readonly - */ - get tag() { - return `${this.username}#${this.discriminator}`; - } - - /** - * The note that is set for the user - * <warn>This is only available when using a user account.</warn> - * @type {?string} - * @readonly - * @deprecated - */ - 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} - * @readonly - */ - get dmChannel() { - return this.client.channels.find(c => c.type === 'dm' && c.recipient.id === this.id); - } - - /** - * Creates a DM channel between the client and the user. - * @returns {Promise<DMChannel>} - */ - createDM() { - return this.client.rest.methods.createDM(this); - } - - /** - * 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>} - * @deprecated - */ - 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>} - * @deprecated - */ - 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>} - * @deprecated - */ - 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>} - * @deprecated - */ - 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>} - * @deprecated - */ - 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>} - * @deprecated - */ - 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 - /* eslint-disable no-empty-function */ - send() {} - sendMessage() {} - sendEmbed() {} - sendFile() {} - sendCode() {} -} - -TextBasedChannel.applyToClass(User); - -User.prototype.block = - util.deprecate(User.prototype.block, 'User#block: userbot methods will be removed'); - -User.prototype.unblock = - util.deprecate(User.prototype.unblock, 'User#unblock: userbot methods will be removed'); - -User.prototype.addFriend = - util.deprecate(User.prototype.addFriend, 'User#addFriend: userbot methods will be removed'); - -User.prototype.removeFriend = - util.deprecate(User.prototype.removeFriend, 'User#removeFriend: userbot methods will be removed'); - -User.prototype.setNote = - util.deprecate(User.prototype.setNote, 'User#setNote, userbot methods will be removed'); - -User.prototype.fetchProfile = - util.deprecate(User.prototype.fetchProfile, 'User#fetchProfile: userbot methods will be removed'); - -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 ea6c65f..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; - - /** - * Partial server integrations (not yet implemented) - * @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 a27d4d0..0000000 --- a/node_modules/discord.js/src/structures/UserProfile.js +++ /dev/null @@ -1,62 +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 UserProfile - * @name UserProfile#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: user.client }); - - /** - * The guilds that the client user and the user share - * @type {Collection<Snowflake, Guild>} - */ - this.mutualGuilds = new Collection(); - - /** - * The user's connections - * @type {Collection<Snowflake, UserConnection>} - */ - this.connections = new Collection(); - - this.setup(data); - } - - setup(data) { - /** - * If the user has Discord Premium - * @type {boolean} - */ - this.premium = data.premium; - - /** - * The date since which the user has had Discord Premium - * @type {?Date} - */ - this.premiumSince = data.premium_since ? new Date(data.premium_since) : null; - - 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 a89dafa..0000000 --- a/node_modules/discord.js/src/structures/VoiceChannel.js +++ /dev/null @@ -1,146 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const Collection = require('../util/Collection'); -const Permissions = require('../util/Permissions'); - -/** - * 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<Snowflake, 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 * 0.001; - - /** - * 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 voice channel is full - * @type {boolean} - * @readonly - */ - get full() { - return this.userLimit > 0 && this.members.size >= this.userLimit; - } - - /** - * Whether the channel is deletable by the client user - * @type {boolean} - * @readonly - */ - get deletable() { - return super.deletable && this.permissionsFor(this.client.user).has(Permissions.FLAGS.CONNECT); - } - - /** - * Checks if the client has permission join the voice channel - * @type {boolean} - * @readonly - */ - get joinable() { - if (this.client.browser) return false; - if (!this.permissionsFor(this.client.user).has('CONNECT')) return false; - if (this.full && !this.permissionsFor(this.client.user).has('MOVE_MEMBERS')) return false; - return true; - } - - /** - * Checks if the client has permission to send audio to the voice channel - * @type {boolean} - * @readonly - */ - get speakable() { - return this.permissionsFor(this.client.user).has('SPEAK'); - } - - /** - * Sets the bitrate of the channel (in kbps). - * @param {number} bitrate The new bitrate - * @param {string} [reason] Reason for changing the channel's bitrate - * @returns {Promise<VoiceChannel>} - * @example - * // Set the bitrate of a voice channel - * voiceChannel.setBitrate(48) - * .then(vc => console.log(`Set bitrate to ${vc.bitrate}kbps for ${vc.name}`)) - * .catch(console.error); - */ - setBitrate(bitrate, reason) { - bitrate *= 1000; - return this.edit({ bitrate }, reason); - } - - /** - * Sets the user limit of the channel. - * @param {number} userLimit The new user limit - * @param {string} [reason] Reason for changing the 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, reason) { - return this.edit({ userLimit }, reason); - } - - /** - * 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/VoiceRegion.js b/node_modules/discord.js/src/structures/VoiceRegion.js deleted file mode 100644 index dc6b461..0000000 --- a/node_modules/discord.js/src/structures/VoiceRegion.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Represents a Discord voice region for guilds. - */ -class VoiceRegion { - constructor(data) { - /** - * The ID of the region - * @type {string} - */ - this.id = data.id; - - /** - * Name of the region - * @type {string} - */ - this.name = data.name; - - /** - * Whether the region is VIP-only - * @type {boolean} - */ - this.vip = data.vip; - - /** - * Whether the region is deprecated - * @type {boolean} - */ - this.deprecated = data.deprecated; - - /** - * Whether the region is optimal - * @type {boolean} - */ - this.optimal = data.optimal; - - /** - * Whether the region is custom - * @type {boolean} - */ - this.custom = data.custom; - - /** - * A sample hostname for what a connection might look like - * @type {string} - */ - this.sampleHostname = data.sample_hostname; - } -} - -module.exports = VoiceRegion; 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 5d82b0c..0000000 --- a/node_modules/discord.js/src/structures/Webhook.js +++ /dev/null @@ -1,377 +0,0 @@ -const EventEmitter = require('events'); -const path = require('path'); -const Util = require('../util/Util'); -const Attachment = require('./Attachment'); -const RichEmbed = require('./RichEmbed'); -const Constants = require('../util/Constants'); -const Snowflake = require('../util/Snowflake'); - -/** - * Represents a webhook. - */ -class Webhook extends EventEmitter { - constructor(client, dataOrID, token) { - super(); - 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 - * @name Webhook#token - * @type {?string} - */ - Object.defineProperty(this, 'token', { value: data.token || null, writable: true, configurable: true }); - - /** - * The avatar for the webhook - * @type {?string} - */ - this.avatar = data.avatar; - - /** - * The ID of the webhook - * @type {Snowflake} - */ - this.id = data.id; - - /** - * The type of the webhook - * @type {WebhookTypes} - */ - this.type = Constants.WebhookTypes[data.type]; - - /** - * The guild the webhook belongs to - * @type {Snowflake} - */ - this.guildID = data.guild_id; - - /** - * The channel the webhook belongs to - * @type {Snowflake} - */ - this.channelID = data.channel_id; - - if (data.user) { - /** - * The owner of the webhook - * @type {?User|Object} - */ - this.owner = this.client.users ? this.client.users.get(data.user.id) : data.user; - } else { - this.owner = null; - } - } - - /** - * The timestamp the webhook was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the webhook was created at - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * A link to the webhook user's avatar - * @type {?stirng} - * @readonly - */ - get avatarURL() { - if (!this.avatar) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).Avatar(this.id, this.avatar); - } - - /** - * The url of this webhook - * @type {string} - * @readonly - */ - get url() { - const API = `${this.client.options.http.host}/api/v${this.client.options.http.version}`; - return API + Constants.Endpoints.Webhook(this.id, this.token); - } - - /** - * Options that can be passed into send, sendMessage, sendFile, sendEmbed, and sendCode. - * @typedef {Object} WebhookMessageOptions - * @property {string} [username=this.name] Username override for the message - * @property {string} [avatarURL] Avatar URL override for the message - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {string} [nonce=''] The nonce for the message - * @property {Array<RichEmbed|Object>} [embeds] An array of embeds 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|BufferResolvable|Attachment} [file] A file to send with the message **(deprecated)** - * @property {FileOptions[]|BufferResolvable[]|Attachment[]} [files] Files 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. - */ - - /** - * Send a message with this webhook. - * @param {StringResolvable} content The content to send - * @param {WebhookMessageOptions|Attachment|RichEmbed} [options] The options to provide, - * can also be just a RichEmbed or Attachment - * @returns {Promise<Message|Message[]|Object|Object[]>} - * @example - * // Send a basic message - * webhook.send('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - * @example - * // Send a remote file - * webhook.send({ - * files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048'] - * }) - * .then(console.log) - * .catch(console.error); - * @example - * // Send a local file - * webhook.send({ - * files: [{ - * attachment: 'entire/path/to/file.jpg', - * name: 'file.jpg' - * }] - * }) - * .then(console.log) - * .catch(console.error); - * @example - * // Send an embed with a local image inside - * webhook.send('This is an embed', { - * embeds: [{ - * thumbnail: { - * url: 'attachment://file.jpg' - * } - * }], - * files: [{ - * attachment: 'entire/path/to/file.jpg', - * name: 'file.jpg' - * }] - * }) - * .then(console.log) - * .catch(console.error); - */ - send(content, options) { // eslint-disable-line complexity - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - - if (options instanceof Attachment) options = { files: [options] }; - if (options instanceof RichEmbed) options = { embeds: [options] }; - - if (content) { - content = this.client.resolver.resolveString(content); - let { split, code, disableEveryone } = options; - if (split && typeof split !== 'object') split = {}; - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = Util.escapeMarkdown(content, true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - if (split) { - split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`; - split.append = '\n```'; - } - } - if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { - content = content.replace(/@(everyone|here)/g, '@\u200b$1'); - } - - if (split) content = Util.splitMessage(content, split); - } - - if (options.file) { - if (options.files) options.files.push(options.file); - else options.files = [options.file]; - } - - if (options.embeds) { - const files = []; - for (const embed of options.embeds) { - if (embed.file) files.push(embed.file); - } - if (options.files) options.files.push(...files); - else options.files = files; - } - - if (options.embeds) options.embeds = options.embeds.map(e => new RichEmbed(e).toJSON()); - - if (options.files) { - for (let i = 0; i < options.files.length; i++) { - let file = options.files[i]; - if (typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file }; - if (!file.name) { - if (typeof file.attachment === 'string') { - file.name = path.basename(file.attachment); - } else if (file.attachment && file.attachment.path) { - file.name = path.basename(file.attachment.path); - } else if (file instanceof Attachment) { - file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' }; - } else { - file.name = 'file.jpg'; - } - } else if (file instanceof Attachment) { - file = file.file; - } - options.files[i] = file; - } - - return Promise.all(options.files.map(file => - this.client.resolver.resolveFile(file.attachment).then(resource => { - file.file = resource; - return file; - }) - )).then(files => this.client.rest.methods.sendWebhookMessage(this, content, options, files)); - } - - return this.client.rest.methods.sendWebhookMessage(this, content, options); - } - - /** - * Send a message with this webhook - * @param {StringResolvable} content The content to send - * @param {WebhookMessageOptions} [options={}] The options to provide - * @returns {Promise<Message|Message[]>} - * @deprecated - * @example - * // Send a message - * webhook.sendMessage('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - sendMessage(content, options = {}) { - return this.send(content, options); - } - - /** - * Send a file with this webhook. - * @param {BufferResolvable} attachment The file to send - * @param {string} [name='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>} - * @deprecated - */ - sendFile(attachment, name, content, options = {}) { - return this.send(content, Object.assign(options, { file: { attachment, name } })); - } - - /** - * 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[]>} - * @deprecated - */ - sendCode(lang, content, options = {}) { - return this.send(content, Object.assign(options, { code: lang })); - } - - /** - * 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); - } - - /** - * Options provided to edit a webhook. - * @property {string} [name] The new name for the webhook - * @property {BufferResolvable} [avatar] The new avatar for the webhook - * @property {ChannelResolvable} [channel] The new channel for the webhook - * @typedef {Object} WebhookEditOptions - */ - - /** - * Edit the webhook. - * @param {string|WebhookEditOptions} nameOrOptions The new name for the webhook **(deprecated, use options)** - * Alternatively options for the webhook, overriding the avatar parameter. - * @param {BufferResolvable|string} [avatarOrReason] The new avatar for the webhook **(deprecated, use options)** - * Alternatively a reason to edit, if using options as first parameter. - * @returns {Promise<Webhook>} - */ - edit(nameOrOptions = this.name, avatarOrReason) { - if (typeof nameOrOptions !== 'object') { - process.emitWarning('Webhook#edit: Use options object instead of separate parameters.'); - nameOrOptions = { - name: nameOrOptions, - avatar: avatarOrReason, - }; - // Parameter was an avatar here; Clear the now reason parameter - avatarOrReason = undefined; - } - - if (nameOrOptions.channel) { - nameOrOptions.channel_id = this.client.resolver.resolveChannelID(nameOrOptions.channel); - nameOrOptions.channel = undefined; - } - - if (nameOrOptions.avatar) { - return this.client.resolver.resolveImage(nameOrOptions.avatar).then(data => { - nameOrOptions.avatar = data; - return this.client.rest.methods.editWebhook(this, nameOrOptions, avatarOrReason); - }); - } - - return this.client.rest.methods.editWebhook(this, nameOrOptions, avatarOrReason); - } - - /** - * Delete the webhook. - * @param {string} [reason] Reason for deleting the webhook - * @returns {Promise} - */ - delete(reason) { - return this.client.rest.methods.deleteWebhook(this, reason); - } -} - -module.exports = Webhook; diff --git a/node_modules/discord.js/src/structures/interfaces/Collector.js b/node_modules/discord.js/src/structures/interfaces/Collector.js deleted file mode 100644 index 6767b42..0000000 --- a/node_modules/discord.js/src/structures/interfaces/Collector.js +++ /dev/null @@ -1,208 +0,0 @@ -const Collection = require('../../util/Collection'); -const EventEmitter = require('events').EventEmitter; - -/** - * Filter to be applied to the collector. - * @typedef {Function} CollectorFilter - * @param {...*} args Any arguments received by the listener - * @param {Collection} collection The items collected by this collector - * @returns {boolean} - */ - -/** - * Options to be applied to the collector. - * @typedef {Object} CollectorOptions - * @property {number} [time] How long to run the collector for - * @property {number} [idle] How long to stop the collector after inactivity in milliseconds - */ - -/** - * Abstract class for defining a new Collector. - * @abstract - */ -class Collector extends EventEmitter { - constructor(client, filter, options = {}) { - super(); - - /** - * The client - * @name Collector#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The filter applied to this collector - * @type {CollectorFilter} - */ - this.filter = filter; - - /** - * The options of this collector - * @type {CollectorOptions} - */ - this.options = options; - - /** - * The items collected by this collector - * @type {Collection} - */ - this.collected = new Collection(); - - /** - * Whether this collector has finished collecting - * @type {boolean} - */ - this.ended = false; - - /** - * Timeout for cleanup - * @type {?Timeout} - * @private - */ - this._timeout = null; - - /** - * Timeout for cleanup due to inactivity - * @type {?Timeout} - * @private - */ - this._idletimeout = null; - - /** - * Call this to handle an event as a collectable element - * Accepts any event data as parameters - * @type {Function} - * @private - */ - this.listener = this._handle.bind(this); - if (options.time) this._timeout = this.client.setTimeout(() => this.stop('time'), options.time); - if (options.idle) this._idletimeout = this.client.setTimeout(() => this.stop('idle'), options.idle); - } - - /** - * @param {...*} args The arguments emitted by the listener - * @emits Collector#collect - * @private - */ - _handle(...args) { - const collect = this.handle(...args); - if (collect && this.filter(...args, this.collected)) { - this.collected.set(collect.key, collect.value); - - /** - * Emitted whenever an element is collected. - * @event Collector#collect - * @param {*} element The element that got collected - * @param {Collector} collector The collector - */ - this.emit('collect', collect.value, this); - - /** - * Emitted whenever an element is collected. - * @event Collector#fullCollect - * @param {...*} args The arguments emitted by the listener - * @private - */ - this.emit('fullCollect', ...args, this); - - if (this._idletimeout) { - this.client.clearTimeout(this._idletimeout); - this._idletimeout = this.client.setTimeout(() => this.stop('idle'), this.options.idle); - } - } - - const post = this.postCheck(...args); - if (post) this.stop(post); - } - - /** - * Return a promise that resolves with the next collected element; - * rejects with collected elements if the collector finishes without receiving a next element - * @type {Promise} - * @readonly - */ - get next() { - return new Promise((resolve, reject) => { - if (this.ended) { - reject(this.collected); - return; - } - - const cleanup = () => { - this.removeListener('collect', onCollect); - this.removeListener('end', onEnd); - }; - - const onCollect = item => { - cleanup(); - resolve(item); - }; - - const onEnd = () => { - cleanup(); - reject(this.collected); // eslint-disable-line prefer-promise-reject-errors - }; - - this.on('collect', onCollect); - this.on('end', onEnd); - }); - } - - /** - * Stop this collector and emit the `end` event. - * @param {string} [reason='user'] The reason this collector is ending - * @emits Collector#end - */ - stop(reason = 'user') { - if (this.ended) return; - - if (this._timeout) { - this.client.clearTimeout(this._timeout); - this._timeout = null; - } - if (this._idletimeout) { - this.client.clearTimeout(this._idletimeout); - this._idletimeout = null; - } - this.ended = true; - this.cleanup(); - - /** - * Emitted when the collector is finished collecting. - * @event Collector#end - * @param {Collection} collected The elements collected by the collector - * @param {string} reason The reason the collector ended - */ - this.emit('end', this.collected, reason); - } - - /* eslint-disable no-empty-function, valid-jsdoc */ - /** - * Handles incoming events from the `listener` function. Returns null if the event should not be collected, - * or returns an object describing the data that should be stored. - * @see Collector#listener - * @param {...*} args Any args the event listener emits - * @returns {?{key: string, value}} Data to insert into collection, if any - * @abstract - */ - handle() {} - - /** - * This method runs after collection to see if the collector should finish. - * @param {...*} args Any args the event listener emits - * @returns {?string} Reason to end the collector, if any - * @abstract - */ - postCheck() {} - - /** - * Called when the collector is ending. - * @abstract - */ - cleanup() {} - /* eslint-enable no-empty-function, valid-jsdoc */ -} - -module.exports = Collector; diff --git a/node_modules/discord.js/src/structures/interfaces/TextBasedChannel.js b/node_modules/discord.js/src/structures/interfaces/TextBasedChannel.js deleted file mode 100644 index ceaa73b..0000000 --- a/node_modules/discord.js/src/structures/interfaces/TextBasedChannel.js +++ /dev/null @@ -1,635 +0,0 @@ -const path = require('path'); -const Message = require('../Message'); -const MessageCollector = require('../MessageCollector'); -const Collection = require('../../util/Collection'); -const Attachment = require('../../structures/Attachment'); -const RichEmbed = require('../../structures/RichEmbed'); -const Snowflake = require('../../util/Snowflake'); -const util = require('util'); - -/** - * Interface for classes that have text-channel-like features. - * @interface - */ -class TextBasedChannel { - constructor() { - /** - * A collection containing the messages sent to this channel - * @type {Collection<Snowflake, Message>} - */ - this.messages = new Collection(); - - /** - * The ID of the last message in the channel, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = null; - - /** - * The Message object of the last message in the channel, if one was sent - * @type {?Message} - */ - this.lastMessage = null; - - /** - * The timestamp when the last pinned message was pinned, if there was one - * @type {?number} - */ - this.lastPinTimestamp = null; - } - - /** - * Options provided when sending or editing a message. - * @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 {RichEmbed|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|BufferResolvable|Attachment} [file] A file to send with the message **(deprecated)** - * @property {FileOptions[]|BufferResolvable[]|Attachment[]} [files] Files 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 - * @property {UserResolvable} [reply] User to reply to (prefixes the message with a mention, except in DMs) - */ - - /** - * @typedef {Object} FileOptions - * @property {BufferResolvable} attachment File to attach - * @property {string} [name='file.jpg'] Filename of the attachment - */ - - /** - * 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|Attachment|RichEmbed} [options] Options for the message, - * can also be just a RichEmbed or Attachment - * @returns {Promise<Message|Message[]>} - * @example - * // Send a basic message - * channel.send('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - * @example - * // Send a remote file - * channel.send({ - * files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048'] - * }) - * .then(console.log) - * .catch(console.error); - * @example - * // Send a local file - * channel.send({ - * files: [{ - * attachment: 'entire/path/to/file.jpg', - * name: 'file.jpg' - * }] - * }) - * .then(console.log) - * .catch(console.error); - * @example - * // Send an embed with a local image inside - * channel.send('This is an embed', { - * embed: { - * thumbnail: { - * url: 'attachment://file.jpg' - * } - * }, - * files: [{ - * attachment: 'entire/path/to/file.jpg', - * name: 'file.jpg' - * }] - * }) - * .then(console.log) - * .catch(console.error); - */ - // eslint-disable-next-line complexity - send(content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - - const { reply } = options; - if (options instanceof Attachment) options = { files: [options.file] }; - if (options instanceof RichEmbed) { - if (options.reply) options.reply = undefined; - options = { embed: options }; - } - options.reply = reply; - - if (options.embed) { - if (options.embed.file) { - if (options.files) options.files.push(options.embed.file); - else options.files = [options.embed.file]; - } - if (options.embed.files) { - if (options.files) options.files = options.files.concat(options.embed.files); - else options.files = options.embed.files; - } - } - - if (options.file) { - if (options.files) options.files.push(options.file); - else options.files = [options.file]; - } - - if (options.embed) options.embed = new RichEmbed(options.embed).toJSON(); - - if (options.files) { - for (let i = 0; i < options.files.length; i++) { - let file = options.files[i]; - if (!file || typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file }; - if (!file.name) { - if (typeof file.attachment === 'string') { - file.name = path.basename(file.attachment); - } else if (file.attachment && file.attachment.path) { - file.name = path.basename(file.attachment.path); - } else if (file instanceof Attachment) { - file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' }; - } else { - file.name = 'file.jpg'; - } - } else if (file instanceof Attachment) { - file = file.file; - } - options.files[i] = file; - } - - return Promise.all(options.files.map(file => - this.client.resolver.resolveFile(file.attachment).then(resource => { - file.file = resource; - return file; - }) - )).then(files => this.client.rest.methods.sendMessage(this, content, options, files)); - } - - return this.client.rest.methods.sendMessage(this, content, options); - } - - /** - * Gets a single message from this channel, regardless of it being cached or not. - * @param {Snowflake} 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) { - if (!this.client.user.bot) { - return this.fetchMessages({ limit: 1, around: messageID }).then(messages => { - const msg = messages.get(messageID); - if (!msg) throw new Error('Message not found.'); - return msg; - }); - } - 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 {Snowflake} [before] ID of a message to get the messages that were posted before it - * @property {Snowflake} [after] ID of a message to get the messages that were posted after it - * @property {Snowflake} [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. - * <info>The returned Collection does not contain reaction users of the messages if they were not cached. - * Those need to be fetched separately in such a case.</info> - * @param {ChannelLogsQueryOptions} [options={}] Query parameters to pass in - * @returns {Promise<Collection<Snowflake, Message>>} - * @example - * // Get messages - * channel.fetchMessages({ limit: 10 }) - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - * @example - * // Get messages and filter by user ID - * channel.fetchMessages() - * .then(messages => console.log(`${messages.filter(m => m.author.id === '84484653687267328').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. - * <info>The returned Collection does not contain any reaction data of the messages. - * Those need to be fetched separately.</info> - * @returns {Promise<Collection<Snowflake, Message>>} - * @example - * // Get pinned messages - * channel.fetchPinnedMessages() - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - */ - 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; - }); - } - - /** - * @typedef {Object} MessageSearchOptions - * @property {string} [content] Message content - * @property {Snowflake} [maxID] Maximum ID for the filter - * @property {Snowflake} [minID] Minimum ID for the filter - * @property {string} [has] One of `link`, `embed`, `file`, `video`, `image`, or `sound`, - * or add `-` to negate (e.g. `-file`) - * @property {ChannelResolvable} [channel] Channel to limit search to (only for guild search endpoint) - * @property {UserResolvable} [author] Author to limit search - * @property {string} [authorType] One of `user`, `bot`, `webhook`, or add `-` to negate (e.g. `-webhook`) - * @property {string} [sortBy='recent'] `recent` or `relevant` - * @property {string} [sortOrder='desc'] `asc` or `desc` - * @property {number} [contextSize=2] How many messages to get around the matched message (0 to 2) - * @property {number} [limit=25] Maximum number of results to get (1 to 25) - * @property {number} [offset=0] Offset the "pages" of results (since you can only see 25 at a time) - * @property {UserResolvable} [mentions] Mentioned user filter - * @property {boolean} [mentionsEveryone] If everyone is mentioned - * @property {string} [linkHostname] Filter links by hostname - * @property {string} [embedProvider] The name of an embed provider - * @property {string} [embedType] one of `image`, `video`, `url`, `rich` - * @property {string} [attachmentFilename] The name of an attachment - * @property {string} [attachmentExtension] The extension of an attachment - * @property {Date} [before] Date to find messages before - * @property {Date} [after] Date to find messages before - * @property {Date} [during] Date to find messages during (range of date to date + 24 hours) - * @property {boolean} [nsfw=false] Include results from NSFW channels - */ - - /** - * @typedef {Object} MessageSearchResult - * @property {number} totalResults Total result count - * @property {Message[][]} messages Array of message results - * The message which has triggered the result will have the `hit` property set to `true` - */ - - /** - * Performs a search within the channel. - * <warn>This is only available when using a user account.</warn> - * @param {MessageSearchOptions} [options={}] Options to pass to the search - * @returns {Promise<MessageSearchResult>} - * @deprecated - * @example - * channel.search({ - * content: 'discord.js', - * before: '2016-11-17' - * }).then(res => { - * const hit = res.messages[0].find(m => m.hit).content; - * console.log(`I found: **${hit}**, total results: ${res.totalResults}`); - * }).catch(console.error); - */ - search(options = {}) { - return this.client.rest.methods.search(this, options); - } - - /** - * 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)) { - const entry = this.client.user._typing.get(this.id); - entry.count = count || entry.count + 1; - return; - } - - const entry = { - count: count || 1, - interval: this.client.setInterval(() => { - this.client.rest.methods.sendTyping(this.id).catch(() => { - this.client.clearInterval(entry.interval); - this.client.user._typing.delete(this.id); - }); - }, 9000), - }; - this.client.rest.methods.sendTyping(this.id).catch(() => { - this.client.clearInterval(entry.interval); - this.client.user._typing.delete(this.id); - }); - this.client.user._typing.set(this.id, entry); - } - - /** - * 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 - * // Reduce the typing count by one and stop typing if it reached 0 - * 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; - } - - /** - * The Message object of the last message in the channel, if one was sent - * @type {?Message} - * @readonly - */ - get lastMessage() { - return this.messages.get(this.lastMessageID) || null; - } - - /** - * The date when the last pinned message was pinned, if there was one - * @type {?Date} - * @readonly - */ - get lastPinAt() { - return this.lastPinTimestamp ? new Date(this.lastPinTimestamp) : null; - } - - /** - * Creates a Message Collector - * @param {CollectorFilter} filter The filter to create the collector with - * @param {MessageCollectorOptions} [options={}] The options to pass to the collector - * @returns {MessageCollector} - * @deprecated - */ - createCollector(filter, options) { - return this.createMessageCollector(filter, options); - } - - /** - * Creates a Message Collector. - * @param {CollectorFilter} filter The filter to create the collector with - * @param {MessageCollectorOptions} [options={}] The options to pass to the collector - * @returns {MessageCollector} - * @example - * // Create a message collector - * const filter = m => m.content.includes('discord'); - * const collector = channel.createMessageCollector(filter, { time: 15000 }); - * collector.on('collect', m => console.log(`Collected ${m.content}`)); - * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); - */ - createMessageCollector(filter, options = {}) { - return new MessageCollector(this, filter, options); - } - - /** - * An object containing the same properties as CollectorOptions, but a few more: - * @typedef {MessageCollectorOptions} 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 {CollectorFilter} filter The filter function to use - * @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector - * @returns {Promise<Collection<Snowflake, 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.once('end', (collection, reason) => { - if (options.errors && options.errors.includes(reason)) { - reject(collection); - } else { - resolve(collection); - } - }); - }); - } - - /** - * Bulk delete given messages that are newer than two weeks. - * <warn>This is only available when using a bot account.</warn> - * @param {Collection<Snowflake, Message>|Message[]|Snowflake[]|number} messages - * Messages or number of messages to delete - * @param {boolean} [filterOld=false] Filter messages to remove those which are older than two weeks automatically - * @returns {Promise<Collection<Snowflake, Message>>} Deleted messages - * @example - * // Bulk delete messages - * channel.bulkDelete(5) - * .then(messages => console.log(`Bulk deleted ${messages.size} messages`)) - * .catch(console.error); - */ - bulkDelete(messages, filterOld = false) { - if (messages instanceof Array || messages instanceof Collection) { - let messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id || m); - if (filterOld) { - messageIDs = messageIDs.filter(id => Date.now() - Snowflake.deconstruct(id).date.getTime() < 1209600000); - } - if (messageIDs.length === 0) return Promise.resolve(new Collection()); - if (messageIDs.length === 1) { - return this.fetchMessage(messageIDs[0]).then(m => m.delete()).then(m => new Collection([[m.id, m]])); - } - return this.client.rest.methods.bulkDeleteMessages(this, messageIDs); - } - if (!isNaN(messages)) return this.fetchMessages({ limit: messages }).then(msgs => this.bulkDelete(msgs, filterOld)); - throw new TypeError('The messages must be an Array, Collection, or number.'); - } - - /** - * Marks all messages in this channel as read. - * <warn>This is only available when using a user account.</warn> - * @returns {Promise<TextChannel|GroupDMChannel|DMChannel>} - * @deprecated - */ - acknowledge() { - if (!this.lastMessageID) return Promise.resolve(this); - return this.client.rest.methods.ackTextChannel(this); - } - - _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; - } -} - -/** @lends TextBasedChannel.prototype */ -const Deprecated = { - /** - * Send a message to this channel. - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options={}] Options for the message - * @returns {Promise<Message|Message[]>} - * @deprecated - * @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>} - * @deprecated - */ - sendEmbed(embed, content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.send(content, Object.assign(options, { embed })); - }, - - /** - * Send files to this channel. - * @param {FileOptions[]|string[]} files Files to send with the message - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options] Options for the message - * @returns {Promise<Message>} - * @deprecated - */ - sendFiles(files, content, options = {}) { - return this.send(content, Object.assign(options, { files })); - }, - - /** - * 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>} - * @deprecated - */ - sendFile(attachment, name, content, options = {}) { - return this.send({ files: [{ attachment, name }], content, options }); - }, - - /** - * 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[]>} - * @deprecated - */ - sendCode(lang, content, options = {}) { - return this.send(content, Object.assign(options, { code: lang })); - }, -}; - -for (const key of Object.keys(Deprecated)) { - TextBasedChannel.prototype[key] = util.deprecate(Deprecated[key], `TextChannel#${key}: use TextChannel#send instead`); -} - -exports.applyToClass = (structure, full = false, ignore = []) => { - const props = ['send', 'sendMessage', 'sendEmbed', 'sendFile', 'sendFiles', 'sendCode']; - if (full) { - props.push( - '_cacheMessage', - 'acknowledge', - 'fetchMessages', - 'fetchMessage', - 'search', - 'lastMessage', - 'lastPinAt', - 'bulkDelete', - 'startTyping', - 'stopTyping', - 'typing', - 'typingCount', - 'fetchPinnedMessages', - 'createCollector', - 'createMessageCollector', - 'awaitMessages' - ); - } - for (const prop of props) { - if (ignore.includes(prop)) continue; - Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop)); - } -}; - -TextBasedChannel.prototype.acknowledge = util.deprecate( - TextBasedChannel.prototype.acknowledge, 'TextBasedChannel#acknowledge: userbot methods will be removed' -); - -TextBasedChannel.prototype.search = - util.deprecate(TextBasedChannel.prototype.search, 'TextBasedChannel#search: userbot methods will be removed'); diff --git a/node_modules/discord.js/src/structures/shared/resolvePermissions.js b/node_modules/discord.js/src/structures/shared/resolvePermissions.js deleted file mode 100644 index c266d46..0000000 --- a/node_modules/discord.js/src/structures/shared/resolvePermissions.js +++ /dev/null @@ -1,26 +0,0 @@ -const Permissions = require('../../util/Permissions'); -const Collection = require('../../util/Collection'); - -module.exports = function resolvePermissions(overwrites, guild) { - if (overwrites instanceof Collection || overwrites instanceof Array) { - overwrites = overwrites.map(overwrite => { - const role = this.client.resolver.resolveRole(guild, overwrite.id); - if (role) { - overwrite.id = role.id; - overwrite.type = 'role'; - } else { - overwrite.id = this.client.resolver.resolveUserID(overwrite.id); - overwrite.type = 'member'; - } - - return { - allow: Permissions.resolve(overwrite.allow || overwrite.allowed || 0), - deny: Permissions.resolve(overwrite.deny || overwrite.denied || 0), - type: overwrite.type, - id: overwrite.id, - }; - }); - } - - return overwrites; -}; diff --git a/node_modules/discord.js/src/util/BitField.js b/node_modules/discord.js/src/util/BitField.js deleted file mode 100644 index e0f86b1..0000000 --- a/node_modules/discord.js/src/util/BitField.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Data structure that makes it easy to interact with a bitfield. - */ -class BitField { - /** - * @param {BitFieldResolvable} [bits=0] Bits(s) to read from - */ - constructor(bits) { - /** - * Bitfield of the packed bits - * @type {number} - */ - this.bitfield = this.constructor.resolve(bits); - } - - /** - * Checks whether the bitfield has a bit, or any of multiple bits. - * @param {BitFieldResolvable} bit Bit(s) to check for - * @returns {boolean} - */ - any(bit) { - return (this.bitfield & this.constructor.resolve(bit)) !== 0; - } - - /** - * Checks if this bitfield equals another - * @param {BitFieldResolvable} bit Bit(s) to check for - * @returns {boolean} - */ - equals(bit) { - return this.bitfield === this.constructor.resolve(bit); - } - - /** - * Checks whether the bitfield has a bit, or multiple bits. - * @param {BitFieldResolvable} bit Bit(s) to check for - * @returns {boolean} - */ - has(bit) { - if (Array.isArray(bit)) return bit.every(p => this.has(p)); - bit = this.constructor.resolve(bit); - return (this.bitfield & bit) === bit; - } - - /** - * Gets all given bits that are missing from the bitfield. - * @param {BitFieldResolvable} bits Bits(s) to check for - * @param {...*} hasParams Additional parameters for the has method, if any - * @returns {string[]} - */ - missing(bits, ...hasParams) { - if (!Array.isArray(bits)) bits = new this.constructor(bits).toArray(false); - return bits.filter(p => !this.has(p, ...hasParams)); - } - - /** - * Freezes these bits, making them immutable. - * @returns {Readonly<BitField>} These bits - */ - freeze() { - return Object.freeze(this); - } - - /** - * Adds bits to these ones. - * @param {...BitFieldResolvable} [bits] Bits to add - * @returns {BitField} These bits or new BitField if the instance is frozen. - */ - add(...bits) { - let total = 0; - for (const bit of bits) { - total |= this.constructor.resolve(bit); - } - if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total); - this.bitfield |= total; - return this; - } - - /** - * Removes bits from these. - * @param {...BitFieldResolvable} [bits] Bits to remove - * @returns {BitField} These bits or new BitField if the instance is frozen. - */ - remove(...bits) { - let total = 0; - for (const bit of bits) { - total |= this.constructor.resolve(bit); - } - if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total); - this.bitfield &= ~total; - return this; - } - - /** - * Gets an object mapping field names to a {@link boolean} indicating whether the - * bit is available. - * @param {...*} hasParams Additional parameters for the has method, if any - * @returns {Object} - */ - serialize(...hasParams) { - const serialized = {}; - for (const flag of Object.keys(this.constructor.FLAGS)) { - serialized[flag] = this.has(this.constructor.FLAGS[flag], ...hasParams); - } - return serialized; - } - - /** - * Gets an {@link Array} of bitfield names based on the bits available. - * @param {...*} hasParams Additional parameters for the has method, if any - * @returns {string[]} - */ - toArray(...hasParams) { - return Object.keys(this.constructor.FLAGS).filter(bit => this.has(bit, ...hasParams)); - } - - toJSON() { - return this.bitfield; - } - - valueOf() { - return this.bitfield; - } - - *[Symbol.iterator]() { - yield* this.toArray(); - } - - /** - * Data that can be resolved to give a bitfield. This can be: - * * A string (see {@link BitField.FLAGS}) - * * A bit number - * * An instance of BitField - * * An Array of BitFieldResolvable - * @typedef {string|number|BitField|BitFieldResolvable[]} BitFieldResolvable - */ - - /** - * Resolves bitfields to their numeric form. - * @param {BitFieldResolvable} [bit=0] - bit(s) to resolve - * @returns {number} - */ - static resolve(bit = 0) { - if (typeof bit === 'number' && bit >= 0) return bit; - if (bit instanceof BitField) return bit.bitfield; - if (Array.isArray(bit)) return bit.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0); - if (typeof bit === 'string' && typeof this.FLAGS[bit] !== 'undefined') return this.FLAGS[bit]; - throw new RangeError('Invalid bitfield flag or number.'); - } -} - -/** - * Numeric bitfield flags. - * <info>Defined in extension classes</info> - * @type {Object} - * @abstract - */ -BitField.FLAGS = {}; - -module.exports = BitField; 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 612b67c..0000000 --- a/node_modules/discord.js/src/util/Collection.js +++ /dev/null @@ -1,532 +0,0 @@ -const util = require('util'); - -/** - * 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 - * @name Collection#_array - * @type {?Array} - * @private - */ - Object.defineProperty(this, '_array', { value: null, writable: true, configurable: true }); - - /** - * Cached array for the `keyArray()` method - will be reset to `null` whenever `set()` or `delete()` are called - * @name Collection#_keyArray - * @type {?Array} - * @private - */ - Object.defineProperty(this, '_keyArray', { value: null, writable: true, configurable: true }); - } - - 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 behavior, use `[...collection.values()]` or - * `Array.from(collection.values())` instead. - * @returns {Array} - */ - array() { - if (!this._array || this._array.length !== this.size) this._array = [...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 behavior, use `[...collection.keys()]` or - * `Array.from(collection.keys())` instead. - * @returns {Array} - */ - keyArray() { - if (!this._keyArray || this._keyArray.length !== this.size) this._keyArray = [...this.keys()]; - return this._keyArray; - } - - /** - * Obtains the first value(s) in this collection. - * @param {number} [count] Number of values to obtain from the beginning - * @returns {*|Array<*>} The single value if `count` is undefined, or an array of values of `count` length - */ - first(count) { - if (count === undefined) return this.values().next().value; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - count = Math.min(this.size, count); - const arr = new Array(count); - const iter = this.values(); - for (let i = 0; i < count; i++) arr[i] = iter.next().value; - return arr; - } - - /** - * Obtains the first key(s) in this collection. - * @param {number} [count] Number of keys to obtain from the beginning - * @returns {*|Array<*>} The single key if `count` is undefined, or an array of keys of `count` length - */ - firstKey(count) { - if (count === undefined) return this.keys().next().value; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - count = Math.min(this.size, count); - const arr = new Array(count); - const iter = this.keys(); - for (let i = 0; i < count; i++) arr[i] = iter.next().value; - return arr; - } - - /** - * Obtains the last value(s) in this collection. This relies on {@link Collection#array}, and thus the caching - * mechanism applies here as well. - * @param {number} [count] Number of values to obtain from the end - * @returns {*|Array<*>} The single value if `count` is undefined, or an array of values of `count` length - */ - last(count) { - const arr = this.array(); - if (count === undefined) return arr[arr.length - 1]; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - return arr.slice(-count); - } - - /** - * Obtains the last key(s) in this collection. This relies on {@link Collection#keyArray}, and thus the caching - * mechanism applies here as well. - * @param {number} [count] Number of keys to obtain from the end - * @returns {*|Array<*>} The single key if `count` is undefined, or an array of keys of `count` length - */ - lastKey(count) { - const arr = this.keyArray(); - if (count === undefined) return arr[arr.length - 1]; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - return arr.slice(-count); - } - - /** - * Obtains random value(s) from this collection. This relies on {@link Collection#array}, and thus the caching - * mechanism applies here as well. - * @param {number} [count] Number of values to obtain randomly - * @returns {*|Array<*>} The single value if `count` is undefined, or an array of values of `count` length - */ - random(count) { - let arr = this.array(); - if (count === undefined) return arr[Math.floor(Math.random() * arr.length)]; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - if (arr.length === 0) return []; - const rand = new Array(count); - arr = arr.slice(); - for (let i = 0; i < count; i++) rand[i] = arr.splice(Math.floor(Math.random() * arr.length), 1)[0]; - return rand; - } - - /** - * Obtains random key(s) from this collection. This relies on {@link Collection#keyArray}, and thus the caching - * mechanism applies here as well. - * @param {number} [count] Number of keys to obtain randomly - * @returns {*|Array<*>} The single key if `count` is undefined, or an array of keys of `count` length - */ - randomKey(count) { - let arr = this.keyArray(); - if (count === undefined) return arr[Math.floor(Math.random() * arr.length)]; - if (typeof count !== 'number') throw new TypeError('The count must be a number.'); - if (!Number.isInteger(count) || count < 1) throw new RangeError('The count must be an integer greater than 0.'); - if (arr.length === 0) return []; - const rand = new Array(count); - arr = arr.slice(); - for (let i = 0; i < count; i++) rand[i] = arr.splice(Math.floor(Math.random() * arr.length), 1)[0]; - return rand; - } - - /** - * 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} - * @deprecated - * @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>All collections used in Discord.js are mapped using their `id` property, and if you want to find by id you - * should use the `get` method. 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.'); - 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'); - */ - findKey(propOrFn, value) { - /* eslint-enable max-len */ - 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} - * @deprecated - * @example - * if (collection.exists('username', 'Bob')) { - * console.log('user here!'); - * } - */ - exists(prop, value) { - return Boolean(this.find(prop, value)); - } - - /** - * Removes entries that satisfy the provided filter function. - * @param {Function} fn Function used to test (should return a boolean) - * @param {Object} [thisArg] Value to use as `this` when executing function - * @returns {number} The number of removed entries - */ - sweep(fn, thisArg) { - if (thisArg) fn = fn.bind(thisArg); - const previousSize = this.size; - for (const [key, val] of this) { - if (fn(val, key, this)) this.delete(key); - } - return previousSize - this.size; - } - - /** - * 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} - * @deprecated - */ - 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; - } - - /** - * Partitions the collection into two collections where the first collection - * contains the items that passed and the second contains the items that failed. - * @param {Function} fn Function used to test (should return a boolean) - * @param {*} [thisArg] Value to use as `this` when executing function - * @returns {Collection[]} - * @example const [big, small] = collection.partition(guild => guild.memberCount > 250); - */ - partition(fn, thisArg) { - if (typeof thisArg !== 'undefined') fn = fn.bind(thisArg); - const results = [new Collection(), new Collection()]; - for (const [key, val] of this) { - if (fn(val, key, this)) { - results[0].set(key, val); - } else { - results[1].set(key, 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; - } - - /** - * Identical to - * [Map.forEach()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach), - * but returns the collection instead of undefined. - * @param {Function} fn Function to execute for each element - * @param {*} [thisArg] Value to use as `this` when executing function - * @returns {Collection} - * @example - * collection - * .tap(user => console.log(user.username)) - * .filter(user => user.bot) - * .tap(user => console.log(user.username)); - */ - tap(fn, thisArg) { - this.forEach(fn, thisArg); - return this; - } - - /** - * Creates an identical shallow copy of this collection. - * @returns {Collection} - * @example const newColl = someColl.clone(); - */ - clone() { - return new this.constructor(this); - } - - /** - * 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 = this.clone(); - 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)); - }); - } - - /** - * The sort() method sorts the elements of a collection in place and returns the collection. - * The sort is not necessarily stable. The default sort order is according to string Unicode code points. - * @param {Function} [compareFunction] Specifies a function that defines the sort order. - * if omitted, the collection is sorted according to each character's Unicode code point value, - * according to the string conversion of each element. - * @returns {Collection} - */ - sort(compareFunction = (x, y) => +(x > y) || +(x === y) - 1) { - return new Collection([...this.entries()].sort((a, b) => compareFunction(a[1], b[1], a[0], b[0]))); - } -} - -Collection.prototype.findAll = - util.deprecate(Collection.prototype.findAll, 'Collection#findAll: use Collection#filter instead'); - -Collection.prototype.filterArray = - util.deprecate(Collection.prototype.filterArray, 'Collection#filterArray: use Collection#filter instead'); - -Collection.prototype.exists = - util.deprecate(Collection.prototype.exists, 'Collection#exists: use Collection#some instead'); - -Collection.prototype.find = function find(propOrFn, value) { - if (typeof propOrFn === 'string') { - process.emitWarning('Collection#find: pass a function instead', 'DeprecationWarning'); - if (typeof value === 'undefined') throw new Error('Value must be specified.'); - 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.'); - } -}; - -Collection.prototype.findKey = function findKey(propOrFn, value) { - if (typeof propOrFn === 'string') { - process.emitWarning('Collection#findKey: pass a function instead', 'DeprecationWarning'); - 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.'); - } -}; - -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 3a2392b..0000000 --- a/node_modules/discord.js/src/util/Constants.js +++ /dev/null @@ -1,943 +0,0 @@ -exports.Package = require('../../package.json'); - -/** - * Options for a client. - * @typedef {Object} ClientOptions - * @property {string} [apiRequestMethod='sequential'] One of `sequential` or `burst`. The sequential handler executes - * all requests in the order they are triggered, whereas the burst handler runs multiple in parallel, and doesn't - * provide the guarantee of any particular order. Burst mode is more likely to hit a 429 ratelimit error by its nature, - * and is therefore slightly riskier to use. - * @property {number} [shardId=0] ID of the shard to run - * @property {number} [shardCount=0] Total 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 a message should stay in the cache until it is considered - * sweepable (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 (should be avoided whenever possible) - * @property {boolean} [disableEveryone=false] Default value for {@link MessageOptions#disableEveryone} - * @property {boolean} [sync=false] Whether to periodically sync guilds (for user accounts) - * @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their - * corresponding websocket events - * @property {number} [restTimeOffset=500] Extra time in millseconds to wait before continuing to make REST - * requests (higher values will reduce rate-limiting errors on bad connections) - * @property {number} [retryLimit=Infinity] How many times to retry on 5XX errors - * (Infinity for indefinite amount of retries) - * @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 - * @property {HTTPOptions} [http] HTTP options - */ -exports.DefaultOptions = { - apiRequestMethod: 'sequential', - shardId: 0, - shardCount: 0, - messageCacheMaxSize: 200, - messageCacheLifetime: 0, - messageSweepInterval: 0, - fetchAllMembers: false, - disableEveryone: false, - sync: false, - restWsBridgeTimeout: 5000, - retryLimit: Infinity, - 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: require('os').platform() !== 'browser', - properties: { - $os: process ? process.platform : 'discord.js', - $browser: 'discord.js', - $device: 'discord.js', - $referrer: '', - $referring_domain: '', - }, - version: 6, - }, - - /** - * HTTP options - * @typedef {Object} HTTPOptions - * @property {number} [version=7] API version to use - * @property {string} [api='https://discordapp.com/api'] Base url of the API - * @property {string} [cdn='https://cdn.discordapp.com'] Base url of the CDN - * @property {string} [invite='https://discord.gg'] Base url of invites - */ - http: { - version: 7, - host: 'https://discordapp.com', - cdn: 'https://cdn.discordapp.com', - }, -}; - -exports.WSCodes = { - 1000: 'Connection gracefully closed', - 4004: 'Tried to identify with an invalid token', - 4010: 'Sharding data provided was invalid', - 4011: 'Shard would be on too many guilds if connected', -}; - -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.', - SHARDING_REQUIRED: 'This session would have handled too many guilds - Sharding is required.', - INVALID_TOKEN: 'An invalid token was provided.', -}; - -const Endpoints = exports.Endpoints = { - User: userID => { - if (userID.id) userID = userID.id; - const base = `/users/${userID}`; - return { - toString: () => base, - channels: `${base}/channels`, - profile: `${base}/profile`, - relationships: `${base}/relationships`, - settings: `${base}/settings`, - Relationship: uID => `${base}/relationships/${uID}`, - Guild: guildID => ({ - toString: () => `${base}/guilds/${guildID}`, - settings: `${base}/guilds/${guildID}/settings`, - }), - Note: id => `${base}/notes/${id}`, - Mentions: (limit, roles, everyone, guildID) => - `${base}/mentions?limit=${limit}&roles=${roles}&everyone=${everyone}${guildID ? `&guild_id=${guildID}` : ''}`, - Avatar: (root, hash) => { - if (userID === '1') return hash; - return Endpoints.CDN(root).Avatar(userID, hash); - }, - }; - }, - guilds: '/guilds', - Guild: guildID => { - if (guildID.id) guildID = guildID.id; - const base = `/guilds/${guildID}`; - return { - toString: () => base, - prune: `${base}/prune`, - embed: `${base}/embed`, - bans: `${base}/bans`, - integrations: `${base}/integrations`, - members: `${base}/members`, - channels: `${base}/channels`, - invites: `${base}/invites`, - roles: `${base}/roles`, - emojis: `${base}/emojis`, - search: `${base}/messages/search`, - vanityURL: `${base}/vanity-url`, - voiceRegions: `${base}/regions`, - webhooks: `${base}/webhooks`, - ack: `${base}/ack`, - settings: `${base}/settings`, - auditLogs: `${base}/audit-logs`, - Emoji: emojiID => `${base}/emojis/${emojiID}`, - Icon: (root, hash) => Endpoints.CDN(root).Icon(guildID, hash), - Banner: (root, hash) => Endpoints.CDN(root).Banner(guildID, hash), - Splash: (root, hash) => Endpoints.CDN(root).Splash(guildID, hash), - Role: roleID => `${base}/roles/${roleID}`, - Member: memberID => { - if (memberID.id) memberID = memberID.id; - const mbase = `${base}/members/${memberID}`; - return { - toString: () => mbase, - Role: roleID => `${mbase}/roles/${roleID}`, - nickname: `${base}/members/@me/nick`, - }; - }, - Integration: id => `${base}/integrations/${id}`, - }; - }, - channels: '/channels', - Channel: channelID => { - if (channelID.id) channelID = channelID.id; - const base = `/channels/${channelID}`; - return { - toString: () => base, - messages: { - toString: () => `${base}/messages`, - bulkDelete: `${base}/messages/bulk-delete`, - }, - invites: `${base}/invites`, - typing: `${base}/typing`, - permissions: `${base}/permissions`, - webhooks: `${base}/webhooks`, - search: `${base}/messages/search`, - pins: `${base}/pins`, - Icon: (root, hash) => Endpoints.CDN(root).GDMIcon(channelID, hash), - Pin: messageID => `${base}/pins/${messageID}`, - Recipient: recipientID => `${base}/recipients/${recipientID}`, - Message: messageID => { - if (messageID.id) messageID = messageID.id; - const mbase = `${base}/messages/${messageID}`; - return { - toString: () => mbase, - reactions: `${mbase}/reactions`, - ack: `${mbase}/ack`, - Reaction: emoji => { - const rbase = `${mbase}/reactions/${emoji}`; - return { - toString: () => rbase, - User: userID => `${rbase}/${userID}`, - }; - }, - }; - }, - }; - }, - Message: m => exports.Endpoints.Channel(m.channel).Message(m), - Member: m => exports.Endpoints.Guild(m.guild).Member(m), - CDN(root) { - return { - Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`, - Asset: name => `${root}/assets/${name}`, - Avatar: (userID, hash) => `${root}/avatars/${userID}/${hash}.${hash.startsWith('a_') ? 'gif' : 'png?size=2048'}`, - Icon: (guildID, hash) => `${root}/icons/${guildID}/${hash}.jpg`, - Banner: (guildID, hash) => `${root}/banners/${guildID}/${hash}.jpg`, - AppIcon: (clientID, hash) => `${root}/app-icons/${clientID}/${hash}.png`, - AppAsset: (clientID, hash) => `${root}/app-assets/${clientID}/${hash}.png`, - GDMIcon: (channelID, hash) => `${root}/channel-icons/${channelID}/${hash}.jpg?size=2048`, - Splash: (guildID, hash) => `${root}/splashes/${guildID}/${hash}.jpg`, - TeamIcon: (teamID, hash) => `${root}/team-icons/${teamID}/${hash}.jpg`, - }; - }, - OAUTH2: { - Application: appID => { - const base = `/oauth2/applications/${appID}`; - return { - toString: () => base, - resetSecret: `${base}/reset`, - resetToken: `${base}/bot/reset`, - }; - }, - App: appID => `/oauth2/authorize?client_id=${appID}`, - }, - login: '/auth/login', - logout: '/auth/logout', - voiceRegions: '/voice/regions', - gateway: { - toString: () => '/gateway', - bot: '/gateway/bot', - }, - Invite: inviteID => `/invite/${inviteID}?with_counts=true`, - inviteLink: id => `https://discord.gg/${id}`, - Webhook: (webhookID, token) => `/webhooks/${webhookID}${token ? `/${token}` : ''}`, -}; - - -/** - * The current status of the client. Here are the available statuses: - * * READY: 0 - * * CONNECTING: 1 - * * RECONNECTING: 2 - * * IDLE: 3 - * * NEARLY: 4 - * * DISCONNECTED: 5 - * @typedef {number} Status - */ -exports.Status = { - READY: 0, - CONNECTING: 1, - RECONNECTING: 2, - IDLE: 3, - NEARLY: 4, - DISCONNECTED: 5, -}; - -/** - * The current status of a voice connection. Here are the available statuses: - * * CONNECTED: 0 - * * CONNECTING: 1 - * * AUTHENTICATING: 2 - * * RECONNECTING: 3 - * * DISCONNECTED: 4 - * @typedef {number} VoiceStatus - */ -exports.VoiceStatus = { - CONNECTED: 0, - CONNECTING: 1, - AUTHENTICATING: 2, - RECONNECTING: 3, - DISCONNECTED: 4, -}; - -exports.ChannelTypes = { - TEXT: 0, - DM: 1, - VOICE: 2, - GROUP_DM: 3, - CATEGORY: 4, - NEWS: 5, - STORE: 6, -}; - -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 = { - RATE_LIMIT: 'rateLimit', - READY: 'ready', - RESUME: 'resume', - 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_INTEGRATIONS_UPDATE: 'guildIntegrationsUpdate', - 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', - INVITE_CREATE: 'inviteCreate', - INVITE_DELETE: 'inviteDelete', - 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_EMOJI: 'messageReactionRemoveEmoji', - MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll', - USER_UPDATE: 'userUpdate', - USER_NOTE_UPDATE: 'userNoteUpdate', - USER_SETTINGS_UPDATE: 'clientUserSettingsUpdate', - USER_GUILD_SETTINGS_UPDATE: 'clientUserGuildSettingsUpdate', - PRESENCE_UPDATE: 'presenceUpdate', - VOICE_STATE_UPDATE: 'voiceStateUpdate', - TYPING_START: 'typingStart', - TYPING_STOP: 'typingStop', - WEBHOOKS_UPDATE: 'webhookUpdate', - DISCONNECT: 'disconnect', - RECONNECTING: 'reconnecting', - ERROR: 'error', - WARN: 'warn', - DEBUG: 'debug', -}; - -/** - * <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info> - * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types: - * * PLAYING - * * STREAMING - * * LISTENING - * * WATCHING - * * CUSTOM_STATUS - * @typedef {string} ActivityType - */ -exports.ActivityTypes = [ - 'PLAYING', - 'STREAMING', - 'LISTENING', - 'WATCHING', - 'CUSTOM_STATUS', -]; - -/** - * Numeric activity flags. All available properties: - * * `INSTANCE` - * * `JOIN` - * * `SPECTATE` - * * `JOIN_REQUEST` - * * `SYNC` - * * `PLAY` - * @typedef {string} ActivityFlag - * @see {@link https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-flags} - */ -exports.ActivityFlags = { - INSTANCE: 1 << 0, - JOIN: 1 << 1, - SPECTATE: 1 << 2, - JOIN_REQUEST: 1 << 3, - SYNC: 1 << 4, - PLAY: 1 << 5, -}; - -/** - * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events: - * * READY - * * RESUMED - * * GUILD_SYNC - * * GUILD_CREATE - * * GUILD_DELETE - * * GUILD_UPDATE - * * GUILD_MEMBER_ADD - * * GUILD_MEMBER_REMOVE - * * GUILD_MEMBER_UPDATE - * * GUILD_MEMBERS_CHUNK - * * GUILD_INTEGRATIONS_UPDATE - * * 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_EMOJI - * * MESSAGE_REACTION_REMOVE_ALL - * * USER_UPDATE - * * USER_NOTE_UPDATE - * * USER_SETTINGS_UPDATE - * * PRESENCE_UPDATE - * * VOICE_STATE_UPDATE - * * TYPING_START - * * VOICE_SERVER_UPDATE - * * RELATIONSHIP_ADD - * * RELATIONSHIP_REMOVE - * * WEBHOOKS_UPDATE - * @typedef {string} WSEventType - */ -exports.WSEvents = { - READY: 'READY', - RESUMED: 'RESUMED', - 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_INTEGRATIONS_UPDATE: 'GUILD_INTEGRATIONS_UPDATE', - 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', - INVITE_CREATE: 'INVITE_CREATE', - INVITE_DELETE: 'INVITE_DELETE', - 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_EMOJI: 'MESSAGE_REACTION_REMOVE_EMOJI', - MESSAGE_REACTION_REMOVE_ALL: 'MESSAGE_REACTION_REMOVE_ALL', - USER_UPDATE: 'USER_UPDATE', - USER_NOTE_UPDATE: 'USER_NOTE_UPDATE', - USER_SETTINGS_UPDATE: 'USER_SETTINGS_UPDATE', - USER_GUILD_SETTINGS_UPDATE: 'USER_GUILD_SETTINGS_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', - WEBHOOKS_UPDATE: 'WEBHOOKS_UPDATE', -}; - -/** - * The type of a message, e.g. `DEFAULT`. Here are the available types: - * * DEFAULT - * * RECIPIENT_ADD - * * RECIPIENT_REMOVE - * * CALL - * * CHANNEL_NAME_CHANGE - * * CHANNEL_ICON_CHANGE - * * PINS_ADD - * * GUILD_MEMBER_JOIN - * * USER_PREMIUM_GUILD_SUBSCRIPTION - * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 - * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 - * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 - * * CHANNEL_FOLLOW_ADD - * * GUILD_DISCOVERY_DISQUALIFIED - * * GUILD_DISCOVERY_REQUALIFIED - * @typedef {string} MessageType - */ -exports.MessageTypes = [ - 'DEFAULT', - 'RECIPIENT_ADD', - 'RECIPIENT_REMOVE', - 'CALL', - 'CHANNEL_NAME_CHANGE', - 'CHANNEL_ICON_CHANGE', - 'PINS_ADD', - 'GUILD_MEMBER_JOIN', - 'USER_PREMIUM_GUILD_SUBSCRIPTION', - 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1', - 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2', - 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3', - 'CHANNEL_FOLLOW_ADD', - // 13 isn't yet documented - null, - 'GUILD_DISCOVERY_DISQUALIFIED', - 'GUILD_DISCOVERY_REQUALIFIED', -]; - -/** - * The type of a message notification setting. Here are the available types: - * * EVERYTHING - * * MENTIONS - * * NOTHING - * * INHERIT (only for GuildChannel) - * @typedef {string} MessageNotificationType - */ -exports.MessageNotificationTypes = [ - 'EVERYTHING', - 'MENTIONS', - 'NOTHING', - 'INHERIT', -]; - -exports.DefaultAvatars = { - BLURPLE: '6debd47ed13483642cf09e832ed0bc1b', - GREY: '322c936a8c8be1b803cd94861bdfa868', - GREEN: 'dd4dbc0016779df1378e7812eabaa04d', - ORANGE: '0e291f67c9274a1abdddeb3fd919cbaa', - RED: '1cbd08c76f8af6dddce02c5138971129', -}; - -exports.ExplicitContentFilterTypes = [ - 'DISABLED', - 'NON_FRIENDS', - 'FRIENDS_AND_NON_FRIENDS', -]; - -exports.UserSettingsMap = { - /** - * Automatically convert emoticons in your messages to emoji - * For example, when you type `:-)` Discord will convert it to 😃 - * @name ClientUserSettings#convertEmoticons - * @type {boolean} - */ - convert_emoticons: 'convertEmoticons', - - /** - * If new guilds should automatically disable DMs between you and its members - * @name ClientUserSettings#defaultGuildsRestricted - * @type {boolean} - */ - default_guilds_restricted: 'defaultGuildsRestricted', - - /** - * Automatically detect accounts from services like Steam and Blizzard when you open the Discord client - * @name ClientUserSettings#detectPlatformAccounts - * @type {boolean} - */ - detect_platform_accounts: 'detectPlatformAccounts', - - /** - * Developer Mode exposes context menu items helpful for people writing bots using the Discord API - * @name ClientUserSettings#developerMode - * @type {boolean} - */ - developer_mode: 'developerMode', - - /** - * Allow playback and usage of the `/tts` command - * @name ClientUserSettings#enableTTSCommand - * @type {boolean} - */ - enable_tts_command: 'enableTTSCommand', - - /** - * The theme of the client. Either `light` or `dark` - * @name ClientUserSettings#theme - * @type {string} - */ - theme: 'theme', - - /** - * Last status set in the client - * @name ClientUserSettings#status - * @type {PresenceStatus} - */ - status: 'status', - - /** - * Display currently running game as status message - * @name ClientUserSettings#showCurrentGame - * @type {boolean} - */ - show_current_game: 'showCurrentGame', - - /** - * Display images, videos, and lolcats when uploaded directly to Discord - * @name ClientUserSettings#inlineAttachmentMedia - * @type {boolean} - */ - inline_attachment_media: 'inlineAttachmentMedia', - - /** - * Display images, videos, and lolcats when uploaded posted as links in chat - * @name ClientUserSettings#inlineEmbedMedia - * @type {boolean} - */ - inline_embed_media: 'inlineEmbedMedia', - - /** - * Language the Discord client will use, as an RFC 3066 language identifier - * @name ClientUserSettings#locale - * @type {string} - */ - locale: 'locale', - - /** - * Display messages in compact mode - * @name ClientUserSettings#messageDisplayCompact - * @type {boolean} - */ - message_display_compact: 'messageDisplayCompact', - - /** - * Show emoji reactions on messages - * @name ClientUserSettings#renderReactions - * @type {boolean} - */ - render_reactions: 'renderReactions', - - /** - * Array of snowflake IDs for guilds, in the order they appear in the Discord client - * @name ClientUserSettings#guildPositions - * @type {Snowflake[]} - */ - guild_positions: 'guildPositions', - - /** - * Array of snowflake IDs for guilds which you will not recieve DMs from - * @name ClientUserSettings#restrictedGuilds - * @type {Snowflake[]} - */ - restricted_guilds: 'restrictedGuilds', - - explicit_content_filter: function explicitContentFilter(type) { // eslint-disable-line func-name-matching - /** - * Safe direct messaging; force people's messages with images to be scanned before they are sent to you. - * One of `DISABLED`, `NON_FRIENDS`, `FRIENDS_AND_NON_FRIENDS` - * @name ClientUserSettings#explicitContentFilter - * @type {string} - */ - return exports.ExplicitContentFilterTypes[type]; - }, - friend_source_flags: function friendSources(flags) { // eslint-disable-line func-name-matching - /** - * Who can add you as a friend - * @name ClientUserSettings#friendSources - * @type {Object} - * @property {boolean} all Mutual friends and mutual guilds - * @property {boolean} mutualGuilds Only mutual guilds - * @property {boolean} mutualFriends Only mutual friends - */ - return { - all: flags.all || false, - mutualGuilds: flags.all ? true : flags.mutual_guilds || false, - mutualFriends: flags.all ? true : flags.mutualFriends || false, - }; - }, -}; - -exports.UserGuildSettingsMap = { - message_notifications: function messageNotifications(type) { // eslint-disable-line func-name-matching - /** - * The type of message that should notify you - * @name ClientUserGuildSettings#messageNotifications - * @type {MessageNotificationType} - */ - return exports.MessageNotificationTypes[type]; - }, - /** - * Whether to receive mobile push notifications - * @name ClientUserGuildSettings#mobilePush - * @type {boolean} - */ - mobile_push: 'mobilePush', - /** - * Whether the guild is muted - * @name ClientUserGuildSettings#muted - * @type {boolean} - */ - muted: 'muted', - /** - * Whether to suppress everyone mention - * @name ClientUserGuildSettings#suppressEveryone - * @type {boolean} - */ - suppress_everyone: 'suppressEveryone', - /** - * A collection containing all the channel overrides - * @name ClientUserGuildSettings#channelOverrides - * @type {Collection<ClientUserChannelOverride>} - */ - channel_overrides: 'channelOverrides', -}; - -exports.UserChannelOverrideMap = { - message_notifications: function messageNotifications(type) { // eslint-disable-line func-name-matching - /** - * The type of message that should notify you - * @name ClientUserChannelOverride#messageNotifications - * @type {MessageNotificationType} - */ - return exports.MessageNotificationTypes[type]; - }, - /** - * Whether the channel is muted - * @name ClientUserChannelOverride#muted - * @type {boolean} - */ - muted: 'muted', -}; - -exports.Colors = { - DEFAULT: 0x000000, - WHITE: 0xFFFFFF, - AQUA: 0x1ABC9C, - GREEN: 0x2ECC71, - BLUE: 0x3498DB, - PURPLE: 0x9B59B6, - LUMINOUS_VIVID_PINK: 0xE91E63, - GOLD: 0xF1C40F, - ORANGE: 0xE67E22, - RED: 0xE74C3C, - GREY: 0x95A5A6, - NAVY: 0x34495E, - DARK_AQUA: 0x11806A, - DARK_GREEN: 0x1F8B4C, - DARK_BLUE: 0x206694, - DARK_PURPLE: 0x71368A, - DARK_VIVID_PINK: 0xAD1457, - DARK_GOLD: 0xC27C0E, - DARK_ORANGE: 0xA84300, - DARK_RED: 0x992D22, - DARK_GREY: 0x979C9F, - DARKER_GREY: 0x7F8C8D, - LIGHT_GREY: 0xBCC0C0, - DARK_NAVY: 0x2C3E50, - BLURPLE: 0x7289DA, - GREYPLE: 0x99AAB5, - DARK_BUT_NOT_BLACK: 0x2C2F33, - NOT_QUITE_BLACK: 0x23272A, -}; - -/** - * The value set for the verification levels for a guild: - * * None - * * Low - * * Medium - * * (╯°□°)╯︵ ┻━┻ - * * ┻━┻ ミヽ(ಠ益ಠ)ノ彡┻━┻ - * @typedef {string} VerificationLevel - */ -exports.VerificationLevels = [ - 'None', - 'Low', - 'Medium', - '(╯°□°)╯︵ ┻━┻', - '┻━┻ ミヽ(ಠ益ಠ)ノ彡┻━┻', -]; - -/** - * An error encountered while performing an API request. Here are the potential errors: - * * UNKNOWN_ACCOUNT - * * UNKNOWN_APPLICATION - * * UNKNOWN_CHANNEL - * * UNKNOWN_GUILD - * * UNKNOWN_INTEGRATION - * * UNKNOWN_INVITE - * * UNKNOWN_MEMBER - * * UNKNOWN_MESSAGE - * * UNKNOWN_OVERWRITE - * * UNKNOWN_PROVIDER - * * UNKNOWN_ROLE - * * UNKNOWN_TOKEN - * * UNKNOWN_USER - * * UNKNOWN_EMOJI - * * UNKNOWN_WEBHOOK - * * BOT_PROHIBITED_ENDPOINT - * * BOT_ONLY_ENDPOINT - * * MAXIMUM_GUILDS - * * MAXIMUM_FRIENDS - * * MAXIMUM_PINS - * * MAXIMUM_ROLES - * * MAXIMUM_REACTIONS - * * MAXIMUM_CHANNELS - * * MAXIMUM_INVITES - * * UNAUTHORIZED - * * USER_BANNED - * * MISSING_ACCESS - * * INVALID_ACCOUNT_TYPE - * * CANNOT_EXECUTE_ON_DM - * * EMBED_DISABLED - * * CANNOT_EDIT_MESSAGE_BY_OTHER - * * CANNOT_SEND_EMPTY_MESSAGE - * * CANNOT_MESSAGE_USER - * * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL - * * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH - * * OAUTH2_APPLICATION_BOT_ABSENT - * * MAXIMUM_OAUTH2_APPLICATIONS - * * INVALID_OAUTH_STATE - * * MISSING_PERMISSIONS - * * INVALID_AUTHENTICATION_TOKEN - * * NOTE_TOO_LONG - * * INVALID_BULK_DELETE_QUANTITY - * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL - * * INVALID_OR_TAKEN_INVITE_CODE - * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE - * * INVALID_OAUTH_TOKEN - * * BULK_DELETE_MESSAGE_TOO_OLD - * * INVALID_FORM_BODY - * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT - * * INVALID_API_VERSION - * * REACTION_BLOCKED - * * RESOURCE_OVERLOADED - * @typedef {string} APIError - */ -exports.APIErrors = { - UNKNOWN_ACCOUNT: 10001, - UNKNOWN_APPLICATION: 10002, - UNKNOWN_CHANNEL: 10003, - UNKNOWN_GUILD: 10004, - UNKNOWN_INTEGRATION: 10005, - UNKNOWN_INVITE: 10006, - UNKNOWN_MEMBER: 10007, - UNKNOWN_MESSAGE: 10008, - UNKNOWN_OVERWRITE: 10009, - UNKNOWN_PROVIDER: 10010, - UNKNOWN_ROLE: 10011, - UNKNOWN_TOKEN: 10012, - UNKNOWN_USER: 10013, - UNKNOWN_EMOJI: 10014, - UNKNOWN_WEBHOOK: 10015, - BOT_PROHIBITED_ENDPOINT: 20001, - BOT_ONLY_ENDPOINT: 20002, - MAXIMUM_GUILDS: 30001, - MAXIMUM_FRIENDS: 30002, - MAXIMUM_PINS: 30003, - MAXIMUM_ROLES: 30005, - MAXIMUM_REACTIONS: 30010, - MAXIMUM_CHANNELS: 30013, - MAXIMUM_INVITES: 30016, - UNAUTHORIZED: 40001, - USER_BANNED: 40007, - MISSING_ACCESS: 50001, - INVALID_ACCOUNT_TYPE: 50002, - CANNOT_EXECUTE_ON_DM: 50003, - EMBED_DISABLED: 50004, - CANNOT_EDIT_MESSAGE_BY_OTHER: 50005, - CANNOT_SEND_EMPTY_MESSAGE: 50006, - CANNOT_MESSAGE_USER: 50007, - CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: 50008, - CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: 50009, - OAUTH2_APPLICATION_BOT_ABSENT: 50010, - MAXIMUM_OAUTH2_APPLICATIONS: 50011, - INVALID_OAUTH_STATE: 50012, - MISSING_PERMISSIONS: 50013, - INVALID_AUTHENTICATION_TOKEN: 50014, - NOTE_TOO_LONG: 50015, - INVALID_BULK_DELETE_QUANTITY: 50016, - CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019, - INVALID_OR_TAKEN_INVITE_CODE: 50020, - CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021, - INVALID_OAUTH_TOKEN: 50025, - BULK_DELETE_MESSAGE_TOO_OLD: 50034, - INVALID_FORM_BODY: 50035, - INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036, - INVALID_API_VERSION: 50041, - REACTION_BLOCKED: 90001, - RESOURCE_OVERLOADED: 130000, -}; - -/** - * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types: - * * ALL - * * MENTIONS - * @typedef {string} DefaultMessageNotifications - */ -exports.DefaultMessageNotifications = [ - 'ALL', - 'MENTIONS', -]; - -/** - * The value set for a team members's membership state: - * * INVITED - * * ACCEPTED - * @typedef {string} MembershipStates - */ -exports.MembershipStates = [ - // They start at 1 - null, - 'INVITED', - 'ACCEPTED', -]; - -/** - * The value set for a webhook's type: - * * Incoming - * * Channel Follower - * @typedef {string} WebhookTypes - */ -exports.WebhookTypes = [ - // They start at 1 - null, - 'Incoming', - 'Channel Follower', -]; diff --git a/node_modules/discord.js/src/util/MessageFlags.js b/node_modules/discord.js/src/util/MessageFlags.js deleted file mode 100644 index 88c8014..0000000 --- a/node_modules/discord.js/src/util/MessageFlags.js +++ /dev/null @@ -1,36 +0,0 @@ -const BitField = require('./BitField'); - -/** - * Data structure that makes it easy to interact with an {@link Message#flags} bitfield. - * @extends {BitField} - */ -class MessageFlags extends BitField {} - -/** - * Data that can be resolved to give a permission number. This can be: - * * A string (see {@link MessageFlags.FLAGS}) - * * A message flag - * * An instance of MessageFlags - * * An array of MessageFlagsResolvable - * @typedef {string|number|MessageFlags|MessageFlagsResolvable[]} MessageFlagsResolvable - */ - -/** - * Numeric message flags. All available properties: - * * `CROSSPOSTED` - * * `IS_CROSSPOST` - * * `SUPPRESS_EMBEDS` - * * `SOURCE_MESSAGE_DELETED` - * * `URGENT` - * @type {Object} - * @see {@link https://discordapp.com/developers/docs/resources/channel#message-object-message-flags} - */ -MessageFlags.FLAGS = { - CROSSPOSTED: 1 << 0, - IS_CROSSPOST: 1 << 1, - SUPPRESS_EMBEDS: 1 << 2, - SOURCE_MESSAGE_DELETED: 1 << 3, - URGENT: 1 << 4, -}; - -module.exports = MessageFlags; diff --git a/node_modules/discord.js/src/util/Permissions.js b/node_modules/discord.js/src/util/Permissions.js deleted file mode 100644 index fa1d0e0..0000000 --- a/node_modules/discord.js/src/util/Permissions.js +++ /dev/null @@ -1,234 +0,0 @@ -const BitField = require('./BitField'); -const util = require('util'); - -/** - * Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of - * permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member - * that override their default permissions. - * @extends {BitField} - */ -class Permissions extends BitField { - /** - * @param {GuildMember} [member] Member the permissions are for **(deprecated)** - * @param {number|PermissionResolvable} permissions Permissions or bitfield to read from - */ - constructor(member, permissions) { - super(typeof member === 'object' && !(member instanceof Array) ? permissions : member); - - Object.defineProperty(this, '_member', { - writable: true, - value: typeof member === 'object' && !(member instanceof Array) ? member : null, - }); - } - - /** - * Member the permissions are for - * @type {GuildMember} - * @deprecated - */ - get member() { - return this._member; - } - - set member(value) { - this._member = value; - } - - /** - * Bitfield of the packed permissions - * @type {number} - * @see {@link Permissions#bitfield} - * @deprecated - * @readonly - */ - get raw() { - return this.bitfield; - } - - set raw(raw) { - this.bitfield = raw; - } - - /** - * Checks whether the bitfield has a permission, or any of multiple permissions. - * @param {PermissionResolvable} permission Permission(s) to check for - * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override - * @returns {boolean} - */ - any(permission, checkAdmin = true) { - return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.any(permission); - } - - /** - * Checks whether the bitfield has a permission, or multiple permissions. - * @param {PermissionResolvable} permission Permission(s) to check for - * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override - * @returns {boolean} - */ - has(permission, checkAdmin = true) { - return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.has(permission); - } - - /** - * 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} - * @see {@link Permissions#has} - * @deprecated - */ - hasPermission(permission, explicit = false) { - return this.has(permission, !explicit); - } - - /** - * 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} - * @see {@link Permissions#has} - * @deprecated - */ - hasPermissions(permissions, explicit = false) { - return this.has(permissions, !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} - * @see {@link Permissions#missing} - * @deprecated - */ - missingPermissions(permissions, explicit = false) { - return this.missing(permissions, !explicit); - } -} - -/** - * Data that can be resolved to give a permission number. This can be: - * * A string (see {@link Permissions.FLAGS}) - * * A permission number - * @typedef {string|number|Permissions|PermissionResolvable[]} PermissionResolvable - */ - -/** - * Numeric permission flags. All available properties: - * - `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites) - * - `CREATE_INSTANT_INVITE` (create invitations to the guild) - * - `KICK_MEMBERS` - * - `BAN_MEMBERS` - * - `MANAGE_CHANNELS` (edit and reorder channels) - * - `MANAGE_GUILD` (edit the guild information, region, etc.) - * - `ADD_REACTIONS` (add new reactions to messages) - * - `VIEW_AUDIT_LOG` - * - `PRIORITY_SPEAKER` - * - `STREAM` - * - `VIEW_CHANNEL` - * - `READ_MESSAGES` **(deprecated)** - * - `SEND_MESSAGES` - * - `SEND_TTS_MESSAGES` - * - `MANAGE_MESSAGES` (delete messages and reactions) - * - `EMBED_LINKS` (links posted will have a preview embedded) - * - `ATTACH_FILES` - * - `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord) - * - `MENTION_EVERYONE` - * - `USE_EXTERNAL_EMOJIS` (use emojis from different guilds) - * - `EXTERNAL_EMOJIS` **(deprecated)** - * - `CONNECT` (connect to a voice channel) - * - `SPEAK` (speak in a voice channel) - * - `MUTE_MEMBERS` (mute members across all voice channels) - * - `DEAFEN_MEMBERS` (deafen members across all voice channels) - * - `MOVE_MEMBERS` (move members between voice channels) - * - `USE_VAD` (use voice activity detection) - * - `CHANGE_NICKNAME` - * - `MANAGE_NICKNAMES` (change other members' nicknames) - * - `MANAGE_ROLES` - * - `MANAGE_ROLES_OR_PERMISSIONS` **(deprecated)** - * - `MANAGE_WEBHOOKS` - * - `MANAGE_EMOJIS` - * @type {Object} - * @see {@link https://discordapp.com/developers/docs/topics/permissions} - */ -Permissions.FLAGS = { - 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, - VIEW_AUDIT_LOG: 1 << 7, - PRIORITY_SPEAKER: 1 << 8, - STREAM: 1 << 9, - - VIEW_CHANNEL: 1 << 10, - 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, - USE_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: 1 << 28, - MANAGE_ROLES_OR_PERMISSIONS: 1 << 28, - MANAGE_WEBHOOKS: 1 << 29, - MANAGE_EMOJIS: 1 << 30, -}; - -/** - * Bitfield representing every permission combined - * @type {number} - */ -Permissions.ALL = Object.keys(Permissions.FLAGS).reduce((all, p) => all | Permissions.FLAGS[p], 0); - -/** - * Bitfield representing the default permissions for users - * @type {number} - */ -Permissions.DEFAULT = 104324673; - -/** - * @class EvaluatedPermissions - * @classdesc The final evaluated permissions for a member in a channel - * @see {@link Permissions} - * @deprecated - */ - -Permissions.prototype.hasPermission = util.deprecate(Permissions.prototype.hasPermission, - 'EvaluatedPermissions#hasPermission is deprecated, use Permissions#has instead'); -Permissions.prototype.hasPermissions = util.deprecate(Permissions.prototype.hasPermissions, - 'EvaluatedPermissions#hasPermissions is deprecated, use Permissions#has instead'); -Permissions.prototype.missingPermissions = util.deprecate(Permissions.prototype.missingPermissions, - 'EvaluatedPermissions#missingPermissions is deprecated, use Permissions#missing instead'); -Object.defineProperty(Permissions.prototype, 'raw', { - get: util - .deprecate(Object.getOwnPropertyDescriptor(Permissions.prototype, 'raw').get, - 'EvaluatedPermissions#raw is deprecated use Permissions#bitfield instead'), - set: util.deprecate(Object.getOwnPropertyDescriptor(Permissions.prototype, 'raw').set, - 'EvaluatedPermissions#raw is deprecated use Permissions#bitfield instead'), -}); -Object.defineProperty(Permissions.prototype, 'member', { - get: util - .deprecate(Object.getOwnPropertyDescriptor(Permissions.prototype, 'member').get, - 'EvaluatedPermissions#member is deprecated'), - set: util - .deprecate(Object.getOwnPropertyDescriptor(Permissions.prototype, 'member').set, - 'EvaluatedPermissions#member is deprecated'), -}); - -module.exports = Permissions; diff --git a/node_modules/discord.js/src/util/Snowflake.js b/node_modules/discord.js/src/util/Snowflake.js deleted file mode 100644 index 2775266..0000000 --- a/node_modules/discord.js/src/util/Snowflake.js +++ /dev/null @@ -1,82 +0,0 @@ -const Long = require('long'); - -// Discord epoch (2015-01-01T00:00:00.000Z) -const EPOCH = 1420070400000; -let INCREMENT = 0; - -/** - * A container for useful snowflake-related methods. - */ -class SnowflakeUtil { - constructor() { - throw new Error(`The ${this.constructor.name} class may not be instantiated.`); - } - - /** - * A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z - * ``` - * If we have a snowflake '266241948824764416' we can represent it as binary: - * - * 64 22 17 12 0 - * 000000111011000111100001101001000101000000 00001 00000 000000000000 - * number of ms since Discord epoch worker pid increment - * ``` - * @typedef {string} Snowflake - */ - - /** - * Generates a Discord snowflake. - * <info>This hardcodes the worker ID as 1 and the process ID as 0.</info> - * @param {number|Date} [timestamp=Date.now()] Timestamp or date of the snowflake to generate - * @returns {Snowflake} The generated snowflake - */ - static generate(timestamp = Date.now()) { - if (timestamp instanceof Date) timestamp = timestamp.getTime(); - if (typeof timestamp !== 'number' || isNaN(timestamp)) { - throw new TypeError( - `"timestamp" argument must be a number (received ${isNaN(timestamp) ? 'NaN' : typeof timestamp})` - ); - } - if (INCREMENT >= 4095) INCREMENT = 0; - const BINARY = `${pad((timestamp - EPOCH).toString(2), 42)}0000100000${pad((INCREMENT++).toString(2), 12)}`; - return Long.fromString(BINARY, 2).toString(); - } - - /** - * A deconstructed snowflake. - * @typedef {Object} DeconstructedSnowflake - * @property {number} timestamp Timestamp the snowflake was created - * @property {Date} date Date the snowflake was created - * @property {number} workerID Worker ID in the snowflake - * @property {number} processID Process ID in the snowflake - * @property {number} increment Increment in the snowflake - * @property {string} binary Binary representation of the snowflake - */ - - /** - * Deconstructs a Discord snowflake. - * @param {Snowflake} snowflake Snowflake to deconstruct - * @returns {DeconstructedSnowflake} Deconstructed snowflake - */ - static deconstruct(snowflake) { - const BINARY = pad(Long.fromString(snowflake).toString(2), 64); - const res = { - timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH, - workerID: parseInt(BINARY.substring(42, 47), 2), - processID: parseInt(BINARY.substring(47, 52), 2), - increment: parseInt(BINARY.substring(52, 64), 2), - binary: BINARY, - }; - Object.defineProperty(res, 'date', { - get: function get() { return new Date(this.timestamp); }, - enumerable: true, - }); - return res; - } -} - -function pad(v, n, c = '0') { - return String(v).length >= n ? String(v) : (String(c).repeat(n) + v).slice(-n); -} - -module.exports = SnowflakeUtil; diff --git a/node_modules/discord.js/src/util/SystemChannelFlags.js b/node_modules/discord.js/src/util/SystemChannelFlags.js deleted file mode 100644 index 9f74984..0000000 --- a/node_modules/discord.js/src/util/SystemChannelFlags.js +++ /dev/null @@ -1,31 +0,0 @@ -const BitField = require('./BitField'); - -/** - * Data structure that makes it easy to interact with a {@link Guild#systemChannelFlags} bitfield. - * <info>Note that all event message types are enabled by default, - * and by setting their corresponding flags you are disabling them</info> - * @extends {BitField} - */ -class SystemChannelFlags extends BitField {} - -/** - * Data that can be resolved to give a sytem channel flag bitfield. This can be: - * * A string (see {@link SystemChannelFlags.FLAGS}) - * * A sytem channel flag - * * An instance of SystemChannelFlags - * * An Array of SystemChannelFlagsResolvable - * @typedef {string|number|SystemChannelFlags|SystemChannelFlagsResolvable[]} SystemChannelFlagsResolvable - */ - -/** - * Numeric system channel flags. All available properties: - * * `WELCOME_MESSAGE_DISABLED` - * * `BOOST_MESSAGE_DISABLED` - * @type {Object} - */ -SystemChannelFlags.FLAGS = { - WELCOME_MESSAGE_DISABLED: 1 << 0, - BOOST_MESSAGE_DISABLED: 1 << 1, -}; - -module.exports = SystemChannelFlags; diff --git a/node_modules/discord.js/src/util/Util.js b/node_modules/discord.js/src/util/Util.js deleted file mode 100644 index a286b07..0000000 --- a/node_modules/discord.js/src/util/Util.js +++ /dev/null @@ -1,238 +0,0 @@ -const snekfetch = require('snekfetch'); -const Constants = require('./Constants'); -const ConstantsHttp = Constants.DefaultOptions.http; - -/** - * Contains various general-purpose utility methods. These functions are also available on the base `Discord` object. - */ -class Util { - constructor() { - throw new Error(`The ${this.constructor.name} class may not be instantiated.`); - } - - /** - * Splits a string into multiple chunks at a designated character that do not exceed a specific length. - * @param {string} text Content to split - * @param {SplitOptions} [options] Options controlling the behaviour of the split - * @returns {string|string[]} - */ - static splitMessage(text, { maxLength = 1950, char = '\n', prepend = '', append = '' } = {}) { - if (text.length <= maxLength) return text; - const splitText = text.split(char); - if (splitText.some(chunk => chunk.length > maxLength)) { - 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; - } - - /** - * 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} - */ - static resolveString(data) { - if (typeof data === 'string') return data; - if (Array.isArray(data)) return data.join('\n'); - return String(data); - } - - /** - * Escapes any Discord-flavour markdown in a string. - * @param {string} text Content to escape - * @param {boolean} [onlyCodeBlock=false] Whether to only escape codeblocks (takes priority) - * @param {boolean} [onlyInlineCode=false] Whether to only escape inline code - * @returns {string} - */ - static 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'); - } - - /** - * Gets the recommended shard count from Discord. - * @param {string} token Discord auth token - * @param {number} [guildsPerShard=1000] Number of guilds per shard - * @returns {Promise<number>} The recommended number of shards - */ - static fetchRecommendedShards(token, guildsPerShard = 1000) { - return new Promise((resolve, reject) => { - if (!token) throw new Error('A token must be provided.'); - snekfetch.get(`${ConstantsHttp.host}/api/v${ConstantsHttp.version}${Constants.Endpoints.gateway.bot}`) - .set('Authorization', `Bot ${token.replace(/^Bot\s*/i, '')}`) - .end((err, res) => { - if (err) reject(err); - resolve(res.body.shards * (1000 / guildsPerShard)); - }); - }); - } - - /** - * Parses emoji info out of a string. The string must be one of: - * * A UTF-8 emoji (no ID) - * * A URL-encoded UTF-8 emoji (no ID) - * * A Discord custom emoji (`<:name:id>` or `<a:name:id>`) - * @param {string} text Emoji string to parse - * @returns {?Object} Object with `animated`, `name`, and `id` properties - * @private - */ - static parseEmoji(text) { - if (text.includes('%')) text = decodeURIComponent(text); - if (!text.includes(':')) return { animated: false, name: text, id: null }; - const m = text.match(/<?(a:)?(\w{2,32}):(\d{17,19})>?/); - if (!m) return null; - return { animated: Boolean(m[1]), name: m[2], id: m[3] }; - } - - /** - * Checks whether two arrays are equal or have the same elements. - * @param {Array<*>} a The first array. - * @param {Array<*>} b The second array. - * @returns {boolean} Whether the arrays are equal. - * @private - */ - static arraysEqual(a, b) { - if (a === b) return true; - if (a.length !== b.length) return false; - - const setA = new Set(a); - const setB = new Set(b); - - return a.every(e => setB.has(e)) && b.every(e => setA.has(e)); - } - - /** - * Shallow-copies an object with its class/prototype intact. - * @param {Object} obj Object to clone - * @returns {Object} - * @private - */ - static cloneObject(obj) { - return Object.assign(Object.create(obj), obj); - } - - /** - * Sets default properties on an object that aren't already specified. - * @param {Object} def Default properties - * @param {Object} given Object to assign defaults to - * @returns {Object} - * @private - */ - static mergeDefault(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] = this.mergeDefault(def[key], given[key]); - } - } - - return given; - } - - /** - * Converts an ArrayBuffer or string to a Buffer. - * @param {ArrayBuffer|string} ab ArrayBuffer to convert - * @returns {Buffer} - * @private - */ - static convertToBuffer(ab) { - if (typeof ab === 'string') ab = this.str2ab(ab); - return Buffer.from(ab); - } - - /** - * Converts a string to an ArrayBuffer. - * @param {string} str String to convert - * @returns {ArrayBuffer} - * @private - */ - static 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; - } - - /** - * Makes an Error from a plain info object. - * @param {Object} obj Error info - * @param {string} obj.name Error type - * @param {string} obj.message Message for the error - * @param {string} obj.stack Stack for the error - * @returns {Error} - * @private - */ - static makeError(obj) { - const err = new Error(obj.message); - err.name = obj.name; - err.stack = obj.stack; - return err; - } - - /** - * Makes a plain error info object from an Error. - * @param {Error} err Error to get info from - * @returns {Object} - * @private - */ - static makePlainError(err) { - const obj = {}; - obj.name = err.name; - obj.message = err.message; - obj.stack = err.stack; - return obj; - } - - /** - * Moves an element in an array *in place*. - * @param {Array<*>} array Array to modify - * @param {*} element Element to move - * @param {number} newIndex Index or offset to move the element to - * @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index - * @returns {number} - * @private - */ - static moveElementInArray(array, element, newIndex, offset = false) { - const index = array.indexOf(element); - newIndex = (offset ? index : 0) + newIndex; - if (newIndex > -1 && newIndex < array.length) { - const removedElement = array.splice(index, 1)[0]; - array.splice(newIndex, 0, removedElement); - } - return array.indexOf(element); - } - - /** - * Creates a Promise that resolves after a specified duration. - * @param {number} ms How long to wait before resolving (in milliseconds) - * @returns {Promise<void>} - * @private - */ - static delayFor(ms) { - return new Promise(resolve => { - setTimeout(resolve, ms); - }); - } -} - -module.exports = Util; |