UNPKG

eris-boiler

Version:
213 lines (197 loc) 5.18 kB
const { status: { isValidType, getActivity, equalStatuses }, logger } = require('../../util') class StatusManager { /** * A class representing a StatusManager. * @param {DataClient} bot The DataClient to manage. * @param {DatabaseManager} databaseManager The DatabaseManager used to fetch statuses. * @param {StatusManagerOptions} [options={}] StatusManagerOptions. */ constructor (bot, databaseManager, { mode = 'manual', interval = 43200000, defaultStatus } = {}) { /** * @type {DataClient} * @private */ this._bot = bot /** * @type {DatabaseManager} * @private */ this._dbm = databaseManager /** * @type {string} * @private */ this._mode = mode /** * @type {number} * @private */ this._interval = interval /** * @type {Status} */ this.defaultStatus = defaultStatus /** * @type {Status} */ this.current = null /** * @type {Timeout} * @private */ this._timer = null } /** * Initialize the statuses. * @returns {Promise<void>} */ async initialize () { const [ defaultStatus ] = await this._dbm.newQuery('status') .equalTo('name', this.defaultStatus.name) .equalTo('type', this.defaultStatus.type) .find() if (!defaultStatus) { await this._dbm.newObject('status').save({ name: this.defaultStatus.name, type: this.defaultStatus.type }) } if (this._mode === 'random') { this.timerStart() } return this.setStatus(this.defaultStatus) } /** * Get the statuses for this bot. * @returns {Promise<Array<DatabaseObject>>} The search results. */ getStatuses () { return this._dbm.newQuery('status').find() } /** * Search for statuses by name. * @param {string} name The name to search by. * @returns {Promise<Array<DatabaseObject>>} The search results. */ findStatusByName (name) { return this._dbm.newQuery('status').equalTo('name', name).find() } /** * Add a status record. * @param {Status} status The status to add. * @returns {Promise<void>} */ async addStatus (status) { const [ oldStatuses, dbStatus ] = await Promise.all([ this.getStatuses(), this._dbm.add('status', status) ]) if (oldStatuses.length === 0) { this.setStatus(dbStatus.toJSON()) } else if ( oldStatuses.length === 1 && !this._timer && this._mode === 'random' ) { this.timerStart() } } /** * Delete a status record. * @param {DatabaseObject} dbStatus The status to delete (as a DatabaseObject). * @returns {Promise<void>} */ async deleteStatus (dbStatus) { if (equalStatuses(dbStatus.toJSON(), this.current)) { this.current = null } await dbStatus.delete() const statuses = await this.getStatuses() let nextStatus if (statuses.length === 0) { nextStatus = this.defaultStatus } this.setStatus(nextStatus) } /** * Set the status of the bot. * @param {Status} [status] Status to set to, if none is given and mode is random, it will randomly change. * @returns {Promise<void>} */ async setStatus (status) { if (status && typeof status.name === 'string') { if (typeof status.type !== 'number' || !isValidType(status.type)) { status.type = 0 } } else { status = null switch (this._mode) { case 'random': status = await this._randomStatus() break case 'manual': default: return } } if (status) { logger.info(getActivity(status.type), status.name) this.current = status this._bot.editStatus('online', status) } } /** * Start automatic status changing. * @returns {void} */ timerStart () { if (!this._timer) { this._timer = setInterval(() => this.setStatus(), this._interval) } } /** * Stop changing status automatically. * @returns {void} */ timerEnd () { if (this._timer) { this._timer = clearInterval(this._timer) } } async _randomStatus () { const statusQuery = this._dbm.newQuery('status') if (this.current) { statusQuery .notEqualTo('name', this.current.name) .notEqualTo('type', this.current.type) } const statuses = await statusQuery.find() if (statuses.length > 0) { this.timerStart() const dbStatus = statuses[Math.floor(Math.random() * statuses.length)] return { name: dbStatus.get('name'), type: dbStatus.get('type') } } else { this.timerEnd() } } } module.exports = StatusManager /** * @typedef StatusManagerOptions * @property {string} [mode='manual'] The mode of the StatusManager, either 'manual' or 'random'. * @property {number} [interval=43200000] The amount of time to wait before randomly changing status (requires 'random' mode). * @property {Status} defaultStatus The default status of the bot. */