brussell98/node-osu

View on GitHub
lib/Base/Score.js

Summary

Maintainability
A
0 mins
Test Coverage
const { getNumeric } = require('../utils.js');
const { Mods, AccuracyMethods } = require('../Constants.js');

/**
 * A score for a beatmap
 * @prop {String|Number} score
 * @prop {Object} user
 * @prop {?String} user.name Username of the player. Will be null if using a getUserX method
 * @prop {String} user.id
 * @prop {?String} beatmapId
 * @prop {Object} counts
 * @prop {String|Number} counts.300
 * @prop {String|Number} counts.100
 * @prop {String|Number} counts.50
 * @prop {String|Number} counts.geki
 * @prop {String|Number} counts.katu
 * @prop {String|Number} counts.miss
 * @prop {String|Number} maxCombo
 * @prop {Boolean} perfect
 * @prop {String} raw_date
 * @prop {String} rank
 * @prop {?String|?Number} pp
 * @prop {Boolean} hasReplay
 * @prop {Number} raw_mods bitwise representation of mods used
 * @prop {?Beatmap} beatmap
 * @prop {Date} date
 * @prop {String[]} mods
 * @prop {Number|undefined} accuracy The score's accuracy, if beatmap is defined, otherwise undefined
 */
class Score {
    constructor(config, data, beatmap) {
        const num = getNumeric(config.parseNumeric);

        this.score = num(data.score);
        this.user = {
            'name': data.username || null,
            'id': data.user_id
        };
        this.beatmapId = data.beatmap_id || (beatmap ? beatmap.id : null);
        this.counts = {
            '300': num(data.count300),
            '100': num(data.count100),
            '50': num(data.count50),
            'geki': num(data.countgeki),
            'katu': num(data.countkatu),
            'miss': num(data.countmiss)
        };
        this.maxCombo = num(data.maxcombo);
        this.perfect = data.perfect === '1';
        this.raw_date = data.date;
        this.rank = data.rank;
        this.pp = num(data.pp || null);
        this.hasReplay = data.replay_available === '1';

        this.raw_mods = parseInt(data.enabled_mods);

        this._beatmap = beatmap; // Optional
    }

    get beatmap() {
        return this._beatmap;
    }

    set beatmap(beatmap) {
        this.beatmapId = beatmap.id;
        this._beatmap = beatmap;
    }

    get date() {
        if (this._date !== undefined)
            return this._date;

        this._date = new Date(this.raw_date + ' UTC');
        return this._date;
    }

    get mods() {
        if (this._mods !== undefined)
            return this._mods;

        this._mods = [];
        for (const mod in Mods)
            if (this.raw_mods & Mods[mod])
                this._mods.push(mod);

        return this._mods;
    }

    get accuracy() {
        if (!this.beatmap)
            return undefined;

        if (this._accuracy !== undefined)
            return this._accuracy;

        const intCounts = { };
        for (const c in this.counts)
            intCounts[c] = parseInt(this.counts[c], 10);

        this._accuracy = AccuracyMethods[this.beatmap.mode](intCounts);
        return this._accuracy;
    }
}

module.exports = Score;