From c4df2502ecdae2b1989be71e3a7861da1da2437c Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Sat, 2 Sep 2017 17:57:02 -0500 Subject: [PATCH] Rewrite presence a little bit (#1853) * such presence many good * Update PresenceStore.js * Update index.js * Update ClientPresenceStore.js * Update Presence.js * Update ClientPresenceStore.js * Update ClientUser.js * Update Presence.js * add timestamps and party * Update Presence.js * Update PresenceStore.js * Update ClientPresenceStore.js * Update ClientPresenceStore.js --- src/client/Client.js | 22 +-- src/client/actions/GuildSync.js | 2 +- src/client/rest/RESTManager.js | 5 + .../packets/handlers/PresenceUpdate.js | 6 +- .../websocket/packets/handlers/Ready.js | 8 +- src/index.js | 2 +- src/stores/ClientPresenceStore.js | 57 ++++++ src/stores/PresenceStore.js | 15 ++ src/structures/ClientApplication.js | 2 +- src/structures/ClientUser.js | 98 +++-------- src/structures/Emoji.js | 3 +- src/structures/GroupDMChannel.js | 3 +- src/structures/Guild.js | 20 +-- src/structures/Presence.js | 165 ++++++++++++++---- src/structures/User.js | 5 +- src/util/Constants.js | 8 +- test/tester1000.js | 1 + 17 files changed, 263 insertions(+), 159 deletions(-) create mode 100644 src/stores/ClientPresenceStore.js create mode 100644 src/stores/PresenceStore.js diff --git a/src/client/Client.js b/src/client/Client.js index 8bbab35f8..7bdc96f6c 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -9,7 +9,6 @@ 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'); const VoiceRegion = require('../structures/VoiceRegion'); const Webhook = require('../structures/Webhook'); const Invite = require('../structures/Invite'); @@ -19,6 +18,7 @@ const VoiceBroadcast = require('./voice/VoiceBroadcast'); const UserStore = require('../stores/UserStore'); const ChannelStore = require('../stores/ChannelStore'); const GuildStore = require('../stores/GuildStore'); +const ClientPresenceStore = require('../stores/ClientPresenceStore'); const { Error, TypeError, RangeError } = require('../errors'); /** @@ -115,9 +115,9 @@ class Client extends EventEmitter { /** * Presences that have been received for the client user's friends, mapped by user IDs * This is only filled when using a user account. - * @type {Collection} + * @type {ClientPresenceStore} */ - this.presences = new Collection(); + this.presences = new ClientPresenceStore(this); Object.defineProperty(this, 'token', { writable: true }); if (!this.token && 'CLIENT_TOKEN' in process.env) { @@ -199,7 +199,7 @@ class Client extends EventEmitter { * @readonly */ get status() { - return this.ws.connection.status; + return this.ws.connection ? this.ws.connection.status : null; } /** @@ -481,20 +481,6 @@ class Client extends EventEmitter { 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)); - } - /** * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script * with the client as `this`. diff --git a/src/client/actions/GuildSync.js b/src/client/actions/GuildSync.js index 41e542027..2019c5d22 100644 --- a/src/client/actions/GuildSync.js +++ b/src/client/actions/GuildSync.js @@ -7,7 +7,7 @@ class GuildSync extends Action { const guild = client.guilds.get(data.id); if (guild) { if (data.presences) { - for (const presence of data.presences) guild._setPresence(presence.user.id, presence); + for (const presence of data.presences) guild.presences.create(presence); } if (data.members) { diff --git a/src/client/rest/RESTManager.js b/src/client/rest/RESTManager.js index 7772fa815..7ee74a607 100644 --- a/src/client/rest/RESTManager.js +++ b/src/client/rest/RESTManager.js @@ -2,6 +2,7 @@ const UserAgentManager = require('./UserAgentManager'); const handlers = require('./handlers'); const APIRequest = require('./APIRequest'); const routeBuilder = require('./APIRouter'); +const Constants = require('../../util/Constants'); const { Error } = require('../../errors'); class RESTManager { @@ -17,6 +18,10 @@ class RESTManager { return routeBuilder(this); } + get cdn() { + return Constants.Endpoints.CDN(this.client.options.http.cdn); + } + destroy() { for (const handler of Object.values(this.handlers)) { if (handler.destroy) handler.destroy(); diff --git a/src/client/websocket/packets/handlers/PresenceUpdate.js b/src/client/websocket/packets/handlers/PresenceUpdate.js index 9163e78d2..a13a813a9 100644 --- a/src/client/websocket/packets/handlers/PresenceUpdate.js +++ b/src/client/websocket/packets/handlers/PresenceUpdate.js @@ -35,17 +35,17 @@ class PresenceUpdateHandler extends AbstractHandler { } if (member) { if (client.listenerCount(Constants.Events.PRESENCE_UPDATE) === 0) { - guild._setPresence(user.id, data); + guild.presences.create(data); return; } const oldMember = member._clone(); if (member.presence) { oldMember.frozenPresence = member.presence._clone(); } - guild._setPresence(user.id, data); + guild.presences.create(data); client.emit(Constants.Events.PRESENCE_UPDATE, oldMember, member); } else { - guild._setPresence(user.id, data); + guild.presences.create(data); } } } diff --git a/src/client/websocket/packets/handlers/Ready.js b/src/client/websocket/packets/handlers/Ready.js index cf5cdcaa5..ad0885278 100644 --- a/src/client/websocket/packets/handlers/Ready.js +++ b/src/client/websocket/packets/handlers/Ready.js @@ -29,11 +29,7 @@ class ReadyHandler extends AbstractHandler { } } - data.presences = data.presences || []; - for (const presence of data.presences) { - client.users.create(presence.user); - client._setPresence(presence.user.id, presence); - } + for (const presence of data.presences || []) client.presences.create(presence); if (data.notes) { for (const user in data.notes) { @@ -52,7 +48,7 @@ class ReadyHandler extends AbstractHandler { avatar: 'https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png', bot: true, status: 'online', - game: null, + activity: null, verified: true, }); } diff --git a/src/index.js b/src/index.js index 9d1f78fa0..9c192e4f7 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ module.exports = { splitMessage: Util.splitMessage, // Structures + Activity: require('./structures/Presence').Activity, Attachment: require('./structures/Attachment'), Channel: require('./structures/Channel'), ClientUser: require('./structures/ClientUser'), @@ -33,7 +34,6 @@ module.exports = { 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'), diff --git a/src/stores/ClientPresenceStore.js b/src/stores/ClientPresenceStore.js new file mode 100644 index 000000000..537beee0d --- /dev/null +++ b/src/stores/ClientPresenceStore.js @@ -0,0 +1,57 @@ +const PresenceStore = require('./PresenceStore'); +const Collection = require('../util/Collection'); +const Constants = require('../util/Constants'); +const { Presence } = require('../structures/Presence'); + +class ClientPresenceStore extends PresenceStore { + constructor(...args) { + super(...args); + this.clientPresence = new Presence(this.client, { + status: 'online', + afk: false, + since: null, + activity: null, + }); + } + + async setClientPresence({ status, since, afk, activity }) { + const applicationID = activity && (activity.application ? activity.application.id || activity.application : null); + let assets = new Collection(); + if (activity && activity.assets && applicationID) { + try { + const a = await this.client.api.oauth2.applications(applicationID).assets.get(); + for (const asset of a) assets.set(asset.name, asset.id); + } catch (err) {} // eslint-disable-line no-empty + } + + const packet = { + afk: afk != null ? afk : false, // eslint-disable-line eqeqeq + since: since != null ? since : null, // eslint-disable-line eqeqeq + status: status || this.clientPresence.status, + game: activity ? { + type: typeof activity.type === 'number' ? activity.type : Constants.ActivityTypes.indexOf(activity.type), + name: activity.name, + url: activity.url, + details: activity.details || undefined, + state: activity.state || undefined, + assets: activity.assets ? { + large_text: activity.assets.largeText || undefined, + small_text: activity.assets.smallText || undefined, + large_image: assets.get(activity.assets.largeImage) || activity.assets.largeImage, + small_image: assets.get(activity.assets.smallImage) || activity.assets.smallImage, + } : undefined, + timestamps: activity.timestamps || undefined, + party: activity.party || undefined, + application_id: applicationID || undefined, + secrets: activity.secrets || undefined, + instance: activity.instance || undefined, + } : null, + }; + + this.clientPresence.patch(packet); + this.client.ws.send({ op: Constants.OPCodes.STATUS_UPDATE, d: packet }); + return this.clientPresence; + } +} + +module.exports = ClientPresenceStore; diff --git a/src/stores/PresenceStore.js b/src/stores/PresenceStore.js new file mode 100644 index 000000000..69569b65b --- /dev/null +++ b/src/stores/PresenceStore.js @@ -0,0 +1,15 @@ +const DataStore = require('./DataStore'); +const { Presence } = require('../structures/Presence'); + +class PresenceStore extends DataStore { + create(data) { + if (this.has(data.user.id)) { + this.get(data.user.id).patch(data); + } else { + this.set(data.user.id, new Presence(this.client, data)); + } + return this.get(data.user.id); + } +} + +module.exports = PresenceStore; diff --git a/src/structures/ClientApplication.js b/src/structures/ClientApplication.js index 50e40ac7a..27e309597 100644 --- a/src/structures/ClientApplication.js +++ b/src/structures/ClientApplication.js @@ -127,7 +127,7 @@ class ClientApplication extends Base { */ iconURL({ format, size } = {}) { if (!this.icon) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).AppIcon(this.id, this.icon, { format, size }); + return this.client.rest.cdn.AppIcon(this.id, this.icon, { format, size }); } /** diff --git a/src/structures/ClientUser.js b/src/structures/ClientUser.js index 289fd8203..85a75cefa 100644 --- a/src/structures/ClientUser.js +++ b/src/structures/ClientUser.js @@ -7,7 +7,6 @@ const Util = require('../util/Util'); const Guild = require('./Guild'); const Message = require('./Message'); const GroupDMChannel = require('./GroupDMChannel'); -const { TypeError } = require('../errors'); /** * Represents the logged in client's Discord user. @@ -28,7 +27,6 @@ class ClientUser extends User { * @type {string} */ this.email = data.email; - this.localPresence = {}; this._typing = new Map(); /** @@ -93,6 +91,15 @@ class ClientUser extends User { } } + /** + * ClientUser's presence + * @readonly + * @type {Presence} + */ + get presence() { + return this.client.presences.clientPresence; + } + edit(data, passcode) { if (!this.bot) { if (typeof passcode !== 'object') { @@ -180,70 +187,19 @@ class ClientUser extends User { * @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 {GameType|number} [game.type] Type of the game - * @property {string} [game.url] Twitch stream URL + * @property {Object} [activity] activity the user is playing + * @property {string} [activity.name] Name of the activity + * @property {ActivityType|number} [activity.type] Type of the activity + * @property {string} [activity.url] Stream url */ /** * Sets the full presence of the client user. * @param {PresenceData} data Data for the presence - * @returns {Promise} + * @returns {Promise} */ 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('INVALID_TYPE', 'status', 'string'); - if (this.bot) { - status = data.status; - } else { - this.settings.update(Constants.UserSettingsMap.status, data.status); - status = 'invisible'; - } - } - - if (data.game) { - game = data.game; - if (typeof game.type === 'string') { - game.type = Constants.GameTypes.indexOf(game.type); - if (game.type === -1) throw new TypeError('INVALID_TYPE', 'type', 'GameType'); - } else if (typeof game.type !== 'number') { - game.type = game.url ? 1 : 0; - } - } 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); - }); + return this.client.presences.setClientPresence(data); } /** @@ -258,35 +214,31 @@ class ClientUser extends User { /** * Sets the status of the client user. * @param {PresenceStatus} status Status to change to - * @returns {Promise} + * @returns {Promise} */ setStatus(status) { return this.setPresence({ status }); } /** - * Sets the game the client user is playing. - * @param {?string} game Game being played - * @param {Object} [options] Options for setting the game + * 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 {GameType|number} [options.type] Type of the game - * @returns {Promise} + * @param {ActivityType|number} [options.type] Type of the activity + * @returns {Promise} */ - setGame(game, { url, type } = {}) { - if (!game) return this.setPresence({ game: null }); + setActivity(name, { url, type } = {}) { + if (!name) return this.setPresence({ activity: null }); return this.setPresence({ - game: { - name: game, - type, - url, - }, + activity: { name, type, url }, }); } /** * Sets/removes the AFK flag for the client user. * @param {boolean} afk Whether or not the user is AFK - * @returns {Promise} + * @returns {Promise} */ setAFK(afk) { return this.setPresence({ afk }); diff --git a/src/structures/Emoji.js b/src/structures/Emoji.js index 3c0f647cc..2b258c8b4 100644 --- a/src/structures/Emoji.js +++ b/src/structures/Emoji.js @@ -1,4 +1,3 @@ -const Constants = require('../util/Constants'); const Collection = require('../util/Collection'); const Snowflake = require('../util/Snowflake'); const Base = require('./Base'); @@ -85,7 +84,7 @@ class Emoji extends Base { * @readonly */ get url() { - return Constants.Endpoints.CDN(this.client.options.http.cdn).Emoji(this.id); + return this.client.rest.cdn.Emoji(this.id); } /** diff --git a/src/structures/GroupDMChannel.js b/src/structures/GroupDMChannel.js index c49d8793f..20cef1064 100644 --- a/src/structures/GroupDMChannel.js +++ b/src/structures/GroupDMChannel.js @@ -2,7 +2,6 @@ const Channel = require('./Channel'); const TextBasedChannel = require('./interfaces/TextBasedChannel'); const Collection = require('../util/Collection'); const MessageStore = require('../stores/MessageStore'); -const Constants = require('../util/Constants'); /* { type: 3, @@ -115,7 +114,7 @@ class GroupDMChannel extends Channel { */ iconURL({ format, size } = {}) { if (!this.icon) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).GDMIcon(this.id, this.icon, format, size); + return this.client.rest.cdn.GDMIcon(this.id, this.icon, format, size); } /** diff --git a/src/structures/Guild.js b/src/structures/Guild.js index da3e73f2c..7895159cc 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -4,7 +4,6 @@ const Emoji = require('./Emoji'); const Invite = require('./Invite'); const GuildAuditLogs = require('./GuildAuditLogs'); const Webhook = require('./Webhook'); -const { Presence } = require('./Presence'); const GuildChannel = require('./GuildChannel'); const GuildMember = require('./GuildMember'); const VoiceRegion = require('./VoiceRegion'); @@ -18,6 +17,7 @@ const GuildMemberStore = require('../stores/GuildMemberStore'); const RoleStore = require('../stores/RoleStore'); const EmojiStore = require('../stores/EmojiStore'); const GuildChannelStore = require('../stores/GuildChannelStore'); +const PresenceStore = require('../stores/PresenceStore'); const Base = require('./Base'); const { Error, TypeError } = require('../errors'); @@ -51,9 +51,9 @@ class Guild extends Base { /** * A collection of presences in this guild - * @type {Collection} + * @type {PresenceStore} */ - this.presences = new Collection(); + this.presences = new PresenceStore(this.client); if (!data) return; if (data.unavailable) { @@ -201,7 +201,7 @@ class Guild extends Base { if (data.presences) { for (const presence of data.presences) { - this._setPresence(presence.user.id, presence); + this.presences.create(presence); } } @@ -261,7 +261,7 @@ class Guild extends Base { */ iconURL({ format, size } = {}) { if (!this.icon) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).Icon(this.id, this.icon, format, size); + return this.client.rest.cdn.Icon(this.id, this.icon, format, size); } /** @@ -282,7 +282,7 @@ class Guild extends Base { */ splashURL({ format, size } = {}) { if (!this.splash) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).Splash(this.id, this.splash, format, size); + return this.client.rest.cdn.Splash(this.id, this.splash, format, size); } /** @@ -1159,14 +1159,6 @@ class Guild extends Base { } } - _setPresence(id, presence) { - if (this.presences.get(id)) { - this.presences.get(id).update(presence); - return; - } - this.presences.set(id, new Presence(presence)); - } - /** * Set the position of a role in this guild. * @param {RoleResolvable} role The role to edit, can be a role object or a role ID diff --git a/src/structures/Presence.js b/src/structures/Presence.js index 77b9ee40d..38b574e83 100644 --- a/src/structures/Presence.js +++ b/src/structures/Presence.js @@ -4,33 +4,33 @@ const Constants = require('../util/Constants'); * Represents a user's presence. */ class Presence { - constructor(data = {}) { + constructor(client, data = {}) { + Object.defineProperty(this, 'client', { value: client }); + this.patch(data); + } + + patch(data) { /** * The status of the presence: * * * **`online`** - user is online * * **`offline`** - user is offline or invisible * * **`idle`** - user is AFK - * * **`dnd`** - user is in Do not Disturb + * * **`dnd`** - user is in Do Not Disturb * @type {string} */ - this.status = data.status || 'offline'; - - /** - * The game that the user is playing - * @type {?Game} - */ - this.game = data.game ? new Game(data.game) : null; - } - - update(data) { this.status = data.status || this.status; - this.game = data.game ? new Game(data.game) : null; + + const activity = data.game || data.activity; + /** + * @type {?Activity} + */ + this.activity = activity ? new Activity(this, activity) : null; } _clone() { const clone = Object.assign(Object.create(this), this); - if (this.game) clone.game = this.game._clone(); + if (this.activity) clone.activity = this.activity._clone(); return clone; } @@ -43,46 +43,91 @@ class Presence { return this === presence || ( presence && this.status === presence.status && - this.game ? this.game.equals(presence.game) : !presence.game + this.activity ? this.activity.equals(presence.activity) : !presence.activity ); } } /** - * Represents a game that is part of a user's presence. + * Represents an activity that is part of a user's presence. */ -class Game { - constructor(data) { +class Activity { + constructor(presence, data) { + Object.defineProperty(this, 'presence', { value: presence }); + /** - * The name of the game being played + * The name of the activity being played * @type {string} */ this.name = data.name; /** - * The type of the game status - * @type {GameType} + * The type of the activity status + * @type {ActivityType} */ - this.type = Constants.GameTypes[data.type]; + this.type = Constants.ActivityTypes[data.type]; /** - * If the game is being streamed, a link to the stream + * If the activity 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(data.timestamps.start) : null, + end: data.timestamps.end ? new Date(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; } /** - * Whether this game is equal to another game. - * @param {Game} game The game to compare with + * Whether this activity is equal to another activity. + * @param {Activity} activity The activity to compare with * @returns {boolean} */ - equals(game) { - return this === game || ( - game && - this.name === game.name && - this.type === game.type && - this.url === game.url + equals(activity) { + return this === activity || ( + activity && + this.name === activity.name && + this.type === activity.type && + this.url === activity.url ); } @@ -91,5 +136,61 @@ class Game { } } +/** + * Assets for a rich presence + */ +class RichPresenceAssets { + constructor(activity, assets) { + Object.defineProperty(this, 'activity', { value: activity }); + + /** + * Hover text for large image + * @type {?string} + */ + this.largeText = assets.large_text || null; + + /** + * Hover text for small image + * @type {?string} + */ + this.smallText = assets.small_text || null; + + /** + * ID of large image asset + * @type {?string} + */ + this.largeImage = assets.large_image || null; + + /** + * ID of small image asset + * @type {?string} + */ + this.smallImage = assets.small_image || null; + } + + /** + * @param {string} format Format of the image + * @param {number} size Size of the iamge + * @returns {?string} small image url + */ + smallImageURL({ format, size } = {}) { + if (!this.smallImage) return null; + return this.activity.presence.client.rest.cdn + .AppAsset(this.activity.applicationID, this.smallImage, { format, size }); + } + + /** + * @param {string} format Format of the image + * @param {number} size Size of the iamge + * @returns {?string} large image url + */ + largeImageURL({ format, size } = {}) { + if (!this.largeImage) return null; + return this.activity.presence.client.rest.cdn + .AppAsset(this.activity.applicationID, this.largeImage, { format, size }); + } +} + exports.Presence = Presence; -exports.Game = Game; +exports.Activity = Activity; +exports.RichPresenceAssets = RichPresenceAssets; diff --git a/src/structures/User.js b/src/structures/User.js index 745e2fc30..1107e8a0c 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -1,5 +1,4 @@ const TextBasedChannel = require('./interfaces/TextBasedChannel'); -const Constants = require('../util/Constants'); const { Presence } = require('./Presence'); const UserProfile = require('./UserProfile'); const Snowflake = require('../util/Snowflake'); @@ -108,7 +107,7 @@ class User extends Base { */ avatarURL({ format, size } = {}) { if (!this.avatar) return null; - return Constants.Endpoints.CDN(this.client.options.http.cdn).Avatar(this.id, this.avatar, format, size); + return this.client.rest.cdn.Avatar(this.id, this.avatar, format, size); } /** @@ -117,7 +116,7 @@ class User extends Base { * @readonly */ get defaultAvatarURL() { - return Constants.Endpoints.CDN(this.client.options.http.cdn).DefaultAvatar(this.discriminator % 5); + return this.client.rest.cdn.DefaultAvatar(this.discriminator % 5); } /** diff --git a/src/util/Constants.js b/src/util/Constants.js index e1bbc49b9..72cf435f0 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -117,6 +117,8 @@ exports.Endpoints = { makeImageUrl(`${root}/icons/${guildID}/${hash}`, { format, size }), AppIcon: (clientID, hash, { format = 'webp', size } = {}) => makeImageUrl(`${root}/app-icons/${clientID}/${hash}`, { size, format }), + AppAsset: (clientID, hash, { format = 'webp', size } = {}) => + makeImageUrl(`${root}/app-assets/${clientID}/${hash}`, { size, format }), GDMIcon: (channelID, hash, format = 'webp', size) => makeImageUrl(`${root}/channel-icons/${channelID}/${hash}`, { size, format }), Splash: (guildID, hash, format = 'webp', size) => @@ -345,14 +347,14 @@ exports.MessageTypes = [ ]; /** - * The type of a game of a users presence, e.g. `PLAYING`. Here are the available types: + * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types: * * PLAYING * * STREAMING * * LISTENING * * WATCHING - * @typedef {string} GameType + * @typedef {string} ActivityType */ -exports.GameTypes = [ +exports.ActivityTypes = [ 'PLAYING', 'STREAMING', 'LISTENING', diff --git a/test/tester1000.js b/test/tester1000.js index 45ed165d9..e884324b4 100644 --- a/test/tester1000.js +++ b/test/tester1000.js @@ -25,6 +25,7 @@ const commands = { } message.channel.send(res, { code: 'js' }); }, + ping: message => message.reply('pong'), }; client.on('message', message => {