const { Structures } = require('discord.js'); const User = Structures.extend('User', (User) => { class ExtendedUser extends User { constructor(...args) { super(...args); this._settings = null; //internal cache of current users' settings; should ALWAYS stay the same as database. this._cached = Date.now(); this._points = {}; } async settings() { if (!this._settings) this._settings = this.client.storageManager.mongodb.users.findOne({ userId: this.id }); if (this._settings instanceof Promise) this._settings = await this._settings || {}; if(!this._settings) this._settings = { userId: this.id, ...this.defaultConfig }; else this._settings = { ...this.defaultConfig, ...this._settings }; return this._settings; } async totalPoints(guild, point) { // point = { points: x, expiration: x, timestamp: x} let index = this._points[guild.id]; if(!index) { this._points[guild.id] = { expirations: [], points: null }; index = this._points[guild.id]; } if(index.points === null) { const find = await this.client.storageManager.mongodb.infractions.find( { guild: guild.id, target: this.id, resolved: false, points: { $gt: 0 }, $or: [ { expiration: 0 }, { expiration: { $gte: Date.now() } }] }, { projection: { points: "$points", expiration: "$expiration", timestamp: "$timestamp" } } ); index.points = 0; if(find && find.length > 0) { for(const { points, expiration, timestamp } of find) { if(expiration > 0) { index.expirations.push({ points, expiration: expiration*1000+timestamp }); } else { index.points += points; } } } } if(point) { if(point.expiration > 0) { index.expirations.push({ points: point.points, expiration: point.expiration*1000+point.timestamp }); } else { index.points += point.points; } } let expirationPoints = index.expirations.map((e) => { if(e.expiration >= Date.now()) return e.points; return 0; }); if(expirationPoints.length === 0) expirationPoints = [0]; return expirationPoints.reduce((p, v) => p+v) + index.points; } /* Settings Wrapper */ async _updateSettings(data) { //Update property (upsert true) - updateOne if(!this._settings) await this.settings(); try { await this.client.storageManager.mongodb.users.updateOne( { guildId: this.id }, data ); this._settings = { ...this._settings, ...data }; this._storageLog(`Database Update (guild:${this.id}).`); } catch(error) { this._storageError(error); } return true; } /* Logging */ _storageLog(log) { this.client.logger.debug(log); } _storageError(error) { this.client.logger.error(`Database Error (user:${this.id}) : \n${error.stack || error}`); } /* Lazy Getters */ get defaultConfig() { return JSON.parse(JSON.stringify(this.client.defaultConfig('USER'))); } get developer() { return this.client._options.bot.owners.includes(this.id); } get timeSinceCached() { return Date.now()-this._cached; } get prefix() { return this.client._options.bot.prefix; } get display() { return this.tag; } get mention() { return `<@${this.id}>`; } } return ExtendedUser; }); module.exports = User;