const { Events, Status } = require('../util/Constants'); const { Error } = require('../errors'); /** * 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 * @readonly * @type {number} */ get status() { return this.connection ? this.connection.status : 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(Events.DEBUG, `Authenticated using token ${token}`); this.client.token = token; const timeout = this.client.setTimeout(() => reject(new Error('WS_CONNECTION_TIMEOUT')), 1000 * 300); this.client.api.gateway.get().then(async res => { if (this.client.options.presence != null) { // eslint-disable-line eqeqeq this.client.options.ws.presence = await this.client.presences._parse(this.client.options.presence); } const gateway = `${res.url}/`; this.client.emit(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('TOKEN_INVALID')); if (event.code === 4010) reject(new Error('SHARDING_INVALID')); if (event.code === 4011) reject(new Error('SHARDING_REQUIRED')); }); this.client.once(Events.READY, () => { resolve(token); this.client.clearTimeout(timeout); }); }, reject); } destroy() { this.client.ws.destroy(); if (!this.client.user) return Promise.resolve(); if (this.client.user.bot) { this.client.token = null; return Promise.resolve(); } else { return this.client.api.logout.post().then(() => { this.client.token = null; }); } } } module.exports = ClientManager;