First pass formatting with Prettier

* Added .prettierrc.json
* Added .prettierignore
* Formatted
This commit is contained in:
Bryan Ashby
2022-06-05 14:04:25 -06:00
parent eecfb33ad5
commit 4881c2123a
172 changed files with 23696 additions and 18029 deletions

View File

@@ -2,38 +2,28 @@
'use strict';
// ENiGMA½
const Events = require('./events.js');
const Config = require('./config.js').get;
const ConfigLoader = require('./config_loader');
const { getConfigPath } = require('./config_util');
const UserDb = require('./database.js').dbs.user;
const {
getISOTimestampString
} = require('./database.js');
const UserInterruptQueue = require('./user_interrupt_queue.js');
const {
getConnectionByUserId
} = require('./client_connections.js');
const UserProps = require('./user_property.js');
const {
Errors,
ErrorReasons
} = require('./enig_error.js');
const { getThemeArt } = require('./theme.js');
const {
pipeToAnsi,
stripMciColorCodes
} = require('./color_codes.js');
const stringFormat = require('./string_format.js');
const StatLog = require('./stat_log.js');
const Log = require('./logger.js').log;
const Events = require('./events.js');
const Config = require('./config.js').get;
const ConfigLoader = require('./config_loader');
const { getConfigPath } = require('./config_util');
const UserDb = require('./database.js').dbs.user;
const { getISOTimestampString } = require('./database.js');
const UserInterruptQueue = require('./user_interrupt_queue.js');
const { getConnectionByUserId } = require('./client_connections.js');
const UserProps = require('./user_property.js');
const { Errors, ErrorReasons } = require('./enig_error.js');
const { getThemeArt } = require('./theme.js');
const { pipeToAnsi, stripMciColorCodes } = require('./color_codes.js');
const stringFormat = require('./string_format.js');
const StatLog = require('./stat_log.js');
const Log = require('./logger.js').log;
// deps
const _ = require('lodash');
const async = require('async');
const moment = require('moment');
const _ = require('lodash');
const async = require('async');
const moment = require('moment');
exports.getAchievementsEarnedByUser = getAchievementsEarnedByUser;
exports.getAchievementsEarnedByUser = getAchievementsEarnedByUser;
class Achievement {
constructor(data) {
@@ -44,59 +34,65 @@ class Achievement {
}
static factory(data) {
if(!data) {
if (!data) {
return;
}
let achievement;
switch(data.type) {
case Achievement.Types.UserStatSet :
case Achievement.Types.UserStatInc :
case Achievement.Types.UserStatIncNewVal :
switch (data.type) {
case Achievement.Types.UserStatSet:
case Achievement.Types.UserStatInc:
case Achievement.Types.UserStatIncNewVal:
achievement = new UserStatAchievement(data);
break;
default : return;
default:
return;
}
if(achievement.isValid()) {
if (achievement.isValid()) {
return achievement;
}
}
static get Types() {
return {
UserStatSet : 'userStatSet',
UserStatInc : 'userStatInc',
UserStatIncNewVal : 'userStatIncNewVal',
UserStatSet: 'userStatSet',
UserStatInc: 'userStatInc',
UserStatIncNewVal: 'userStatIncNewVal',
};
}
isValid() {
switch(this.data.type) {
case Achievement.Types.UserStatSet :
case Achievement.Types.UserStatInc :
case Achievement.Types.UserStatIncNewVal :
if(!_.isString(this.data.statName)) {
switch (this.data.type) {
case Achievement.Types.UserStatSet:
case Achievement.Types.UserStatInc:
case Achievement.Types.UserStatIncNewVal:
if (!_.isString(this.data.statName)) {
return false;
}
if(!_.isObject(this.data.match)) {
if (!_.isObject(this.data.match)) {
return false;
}
break;
default : return false;
default:
return false;
}
return true;
}
getMatchDetails(/*matchAgainst*/) {
}
getMatchDetails(/*matchAgainst*/) {}
isValidMatchDetails(details) {
if(!details || !_.isString(details.title) || !_.isString(details.text) || !_.isNumber(details.points)) {
if (
!details ||
!_.isString(details.title) ||
!_.isString(details.text) ||
!_.isNumber(details.points)
) {
return false;
}
return (_.isString(details.globalText) || !details.globalText);
return _.isString(details.globalText) || !details.globalText;
}
}
@@ -105,11 +101,13 @@ class UserStatAchievement extends Achievement {
super(data);
// sort match keys for quick match lookup
this.matchKeys = Object.keys(this.data.match || {}).map(k => parseInt(k)).sort( (a, b) => b - a);
this.matchKeys = Object.keys(this.data.match || {})
.map(k => parseInt(k))
.sort((a, b) => b - a);
}
isValid() {
if(!super.isValid()) {
if (!super.isValid()) {
return false;
}
return !Object.keys(this.data.match).some(k => !parseInt(k));
@@ -118,11 +116,11 @@ class UserStatAchievement extends Achievement {
getMatchDetails(matchValue) {
let ret = [];
let matchField = this.matchKeys.find(v => matchValue >= v);
if(matchField) {
if (matchField) {
const match = this.data.match[matchField];
matchField = parseInt(matchField);
if(this.isValidMatchDetails(match) && !isNaN(matchField)) {
ret = [ match, matchField, matchValue ];
if (this.isValidMatchDetails(match) && !isNaN(matchField)) {
ret = [match, matchField, matchValue];
}
}
return ret;
@@ -151,7 +149,7 @@ class Achievements {
}
const configLoaded = () => {
if(true !== this.config.get().enabled) {
if (true !== this.config.get().enabled) {
Log.info('Achievements are not enabled');
this.enabled = false;
this.stopMonitoringUserStatEvents();
@@ -163,11 +161,11 @@ class Achievements {
};
this.config = new ConfigLoader({
onReload : err => {
onReload: err => {
if (!err) {
configLoaded();
}
}
},
});
this.config.init(configPath, err => {
@@ -182,10 +180,10 @@ class Achievements {
_getConfigPath() {
const path = _.get(Config(), 'general.achievementFile');
if(!path) {
if (!path) {
return;
}
return getConfigPath(path); // qualify
return getConfigPath(path); // qualify
}
loadAchievementHitCount(user, achievementTag, field, cb) {
@@ -193,7 +191,7 @@ class Achievements {
`SELECT COUNT() AS count
FROM user_achievement
WHERE user_id = ? AND achievement_tag = ? AND match = ?;`,
[ user.userId, achievementTag, field],
[user.userId, achievementTag, field],
(err, row) => {
return cb(err, row ? row.count : 0);
}
@@ -202,14 +200,23 @@ class Achievements {
record(info, localInterruptItem, cb) {
StatLog.incrementUserStat(info.client.user, UserProps.AchievementTotalCount, 1);
StatLog.incrementUserStat(info.client.user, UserProps.AchievementTotalPoints, info.details.points);
StatLog.incrementUserStat(
info.client.user,
UserProps.AchievementTotalPoints,
info.details.points
);
const cleanTitle = stripMciColorCodes(localInterruptItem.title);
const cleanText = stripMciColorCodes(localInterruptItem.achievText);
const cleanTitle = stripMciColorCodes(localInterruptItem.title);
const cleanText = stripMciColorCodes(localInterruptItem.achievText);
const recordData = [
info.client.user.userId, info.achievementTag, getISOTimestampString(info.timestamp), info.matchField,
cleanTitle, cleanText, info.details.points,
info.client.user.userId,
info.achievementTag,
getISOTimestampString(info.timestamp),
info.matchField,
cleanTitle,
cleanText,
info.details.points,
];
UserDb.run(
@@ -217,20 +224,17 @@ class Achievements {
VALUES (?, ?, ?, ?, ?, ?, ?);`,
recordData,
err => {
if(err) {
if (err) {
return cb(err);
}
this.events.emit(
Events.getSystemEvents().UserAchievementEarned,
{
user : info.client.user,
achievementTag : info.achievementTag,
points : info.details.points,
title : cleanTitle,
text : cleanText,
}
);
this.events.emit(Events.getSystemEvents().UserAchievementEarned, {
user: info.client.user,
achievementTag: info.achievementTag,
points: info.details.points,
title: cleanTitle,
text: cleanText,
});
return cb(null);
}
@@ -238,12 +242,12 @@ class Achievements {
}
display(info, interruptItems, cb) {
if(interruptItems.local) {
UserInterruptQueue.queue(interruptItems.local, { clients : info.client } );
if (interruptItems.local) {
UserInterruptQueue.queue(interruptItems.local, { clients: info.client });
}
if(interruptItems.global) {
UserInterruptQueue.queue(interruptItems.global, { omit : info.client } );
if (interruptItems.global) {
UserInterruptQueue.queue(interruptItems.global, { omit: info.client });
}
return cb(null);
@@ -252,7 +256,7 @@ class Achievements {
recordAndDisplayAchievement(info, cb) {
async.waterfall(
[
(callback) => {
callback => {
return this.createAchievementInterruptItems(info, callback);
},
(interruptItems, callback) => {
@@ -262,7 +266,7 @@ class Achievements {
},
(interruptItems, callback) => {
return this.display(info, interruptItems, callback);
}
},
],
err => {
return cb(err);
@@ -271,164 +275,228 @@ class Achievements {
}
monitorUserStatEvents() {
if(this.userStatEventListeners) {
if (this.userStatEventListeners) {
return; // already listening
}
const listenEvents = [
Events.getSystemEvents().UserStatSet,
Events.getSystemEvents().UserStatIncrement
Events.getSystemEvents().UserStatIncrement,
];
this.userStatEventListeners = this.events.addMultipleEventListener(listenEvents, userStatEvent => {
if([ UserProps.AchievementTotalCount, UserProps.AchievementTotalPoints ].includes(userStatEvent.statName)) {
return;
}
if(!_.isNumber(userStatEvent.statValue) && !_.isNumber(userStatEvent.statIncrementBy)) {
return;
}
// :TODO: Make this code generic - find + return factory created object
const achievementTags = Object.keys(_.pickBy(
_.get(this.config.get(), 'achievements', {}),
achievement => {
if(false === achievement.enabled) {
return false;
}
const acceptedTypes = [
Achievement.Types.UserStatSet,
Achievement.Types.UserStatInc,
Achievement.Types.UserStatIncNewVal,
];
return acceptedTypes.includes(achievement.type) && achievement.statName === userStatEvent.statName;
}
));
if(0 === achievementTags.length) {
return;
}
async.eachSeries(achievementTags, (achievementTag, nextAchievementTag) => {
const achievement = Achievement.factory(this.getAchievementByTag(achievementTag));
if(!achievement) {
return nextAchievementTag(null);
}
const statValue = parseInt(
[ Achievement.Types.UserStatSet, Achievement.Types.UserStatIncNewVal ].includes(achievement.data.type) ?
userStatEvent.statValue :
userStatEvent.statIncrementBy
);
if(isNaN(statValue)) {
return nextAchievementTag(null);
}
const [ details, matchField, matchValue ] = achievement.getMatchDetails(statValue);
if(!details) {
return nextAchievementTag(null);
}
async.waterfall(
this.userStatEventListeners = this.events.addMultipleEventListener(
listenEvents,
userStatEvent => {
if (
[
(callback) => {
this.loadAchievementHitCount(userStatEvent.user, achievementTag, matchField, (err, count) => {
if(err) {
return callback(err);
}
return callback(count > 0 ? Errors.General('Achievement already acquired', ErrorReasons.TooMany) : null);
});
},
(callback) => {
const client = getConnectionByUserId(userStatEvent.user.userId);
if(!client) {
return callback(Errors.UnexpectedState('Failed to get client for user ID'));
UserProps.AchievementTotalCount,
UserProps.AchievementTotalPoints,
].includes(userStatEvent.statName)
) {
return;
}
if (
!_.isNumber(userStatEvent.statValue) &&
!_.isNumber(userStatEvent.statIncrementBy)
) {
return;
}
// :TODO: Make this code generic - find + return factory created object
const achievementTags = Object.keys(
_.pickBy(
_.get(this.config.get(), 'achievements', {}),
achievement => {
if (false === achievement.enabled) {
return false;
}
const acceptedTypes = [
Achievement.Types.UserStatSet,
Achievement.Types.UserStatInc,
Achievement.Types.UserStatIncNewVal,
];
return (
acceptedTypes.includes(achievement.type) &&
achievement.statName === userStatEvent.statName
);
}
)
);
const info = {
achievementTag,
achievement,
details,
client,
matchField, // match - may be in odd format
matchValue, // actual value
achievedValue : matchField, // achievement value met
user : userStatEvent.user,
timestamp : moment(),
};
if (0 === achievementTags.length) {
return;
}
const achievementsInfo = [ info ];
return callback(null, achievementsInfo, info);
},
(achievementsInfo, basicInfo, callback) => {
if(true !== achievement.data.retroactive) {
return callback(null, achievementsInfo);
}
async.eachSeries(
achievementTags,
(achievementTag, nextAchievementTag) => {
const achievement = Achievement.factory(
this.getAchievementByTag(achievementTag)
);
if (!achievement) {
return nextAchievementTag(null);
}
const index = achievement.matchKeys.findIndex(v => v < matchField);
if(-1 === index || !Array.isArray(achievement.matchKeys)) {
return callback(null, achievementsInfo);
}
const statValue = parseInt(
[
Achievement.Types.UserStatSet,
Achievement.Types.UserStatIncNewVal,
].includes(achievement.data.type)
? userStatEvent.statValue
: userStatEvent.statIncrementBy
);
if (isNaN(statValue)) {
return nextAchievementTag(null);
}
// For userStat, any lesser match keys(values) are also met. Example:
// matchKeys: [ 500, 200, 100, 20, 10, 2 ]
// ^---- we met here
// ^------------^ retroactive range
//
async.eachSeries(achievement.matchKeys.slice(index), (k, nextKey) => {
const [ det, fld, val ] = achievement.getMatchDetails(k);
if(!det) {
return nextKey(null);
}
const [details, matchField, matchValue] =
achievement.getMatchDetails(statValue);
if (!details) {
return nextAchievementTag(null);
}
this.loadAchievementHitCount(userStatEvent.user, achievementTag, fld, (err, count) => {
if(!err || count && 0 === count) {
achievementsInfo.push(Object.assign(
{},
basicInfo,
{
details : det,
matchField : fld,
achievedValue : fld,
matchValue : val,
async.waterfall(
[
callback => {
this.loadAchievementHitCount(
userStatEvent.user,
achievementTag,
matchField,
(err, count) => {
if (err) {
return callback(err);
}
));
return callback(
count > 0
? Errors.General(
'Achievement already acquired',
ErrorReasons.TooMany
)
: null
);
}
);
},
callback => {
const client = getConnectionByUserId(
userStatEvent.user.userId
);
if (!client) {
return callback(
Errors.UnexpectedState(
'Failed to get client for user ID'
)
);
}
return nextKey(null);
});
},
() => {
return callback(null, achievementsInfo);
});
},
(achievementsInfo, callback) => {
// reverse achievementsInfo so we display smallest > largest
achievementsInfo.reverse();
const info = {
achievementTag,
achievement,
details,
client,
matchField, // match - may be in odd format
matchValue, // actual value
achievedValue: matchField, // achievement value met
user: userStatEvent.user,
timestamp: moment(),
};
async.eachSeries(achievementsInfo, (achInfo, nextAchInfo) => {
return this.recordAndDisplayAchievement(achInfo, err => {
return nextAchInfo(err);
});
},
const achievementsInfo = [info];
return callback(null, achievementsInfo, info);
},
(achievementsInfo, basicInfo, callback) => {
if (true !== achievement.data.retroactive) {
return callback(null, achievementsInfo);
}
const index = achievement.matchKeys.findIndex(
v => v < matchField
);
if (
-1 === index ||
!Array.isArray(achievement.matchKeys)
) {
return callback(null, achievementsInfo);
}
// For userStat, any lesser match keys(values) are also met. Example:
// matchKeys: [ 500, 200, 100, 20, 10, 2 ]
// ^---- we met here
// ^------------^ retroactive range
//
async.eachSeries(
achievement.matchKeys.slice(index),
(k, nextKey) => {
const [det, fld, val] =
achievement.getMatchDetails(k);
if (!det) {
return nextKey(null);
}
this.loadAchievementHitCount(
userStatEvent.user,
achievementTag,
fld,
(err, count) => {
if (!err || (count && 0 === count)) {
achievementsInfo.push(
Object.assign({}, basicInfo, {
details: det,
matchField: fld,
achievedValue: fld,
matchValue: val,
})
);
}
return nextKey(null);
}
);
},
() => {
return callback(null, achievementsInfo);
}
);
},
(achievementsInfo, callback) => {
// reverse achievementsInfo so we display smallest > largest
achievementsInfo.reverse();
async.eachSeries(
achievementsInfo,
(achInfo, nextAchInfo) => {
return this.recordAndDisplayAchievement(
achInfo,
err => {
return nextAchInfo(err);
}
);
},
err => {
return callback(err);
}
);
},
],
err => {
return callback(err);
});
}
],
err => {
if(err && ErrorReasons.TooMany !== err.reasonCode) {
Log.warn( { error : err.message, userStatEvent }, 'Error handling achievement for user stat event');
}
return nextAchievementTag(null); // always try the next, regardless
if (err && ErrorReasons.TooMany !== err.reasonCode) {
Log.warn(
{ error: err.message, userStatEvent },
'Error handling achievement for user stat event'
);
}
return nextAchievementTag(null); // always try the next, regardless
}
);
}
);
});
});
}
);
}
stopMonitoringUserStatEvents() {
if(this.userStatEventListeners) {
if (this.userStatEventListeners) {
this.events.removeMultipleEventListener(this.userStatEventListeners);
delete this.userStatEventListeners;
}
@@ -436,34 +504,38 @@ class Achievements {
getFormatObject(info) {
return {
userName : info.user.username,
userRealName : info.user.properties[UserProps.RealName],
userLocation : info.user.properties[UserProps.Location],
userAffils : info.user.properties[UserProps.Affiliations],
nodeId : info.client.node,
title : info.details.title,
userName: info.user.username,
userRealName: info.user.properties[UserProps.RealName],
userLocation: info.user.properties[UserProps.Location],
userAffils: info.user.properties[UserProps.Affiliations],
nodeId: info.client.node,
title: info.details.title,
//text : info.global ? info.details.globalText : info.details.text,
points : info.details.points,
achievedValue : info.achievedValue,
matchField : info.matchField,
matchValue : info.matchValue,
timestamp : moment(info.timestamp).format(info.dateTimeFormat),
boardName : Config().general.boardName,
points: info.details.points,
achievedValue: info.achievedValue,
matchField: info.matchField,
matchValue: info.matchValue,
timestamp: moment(info.timestamp).format(info.dateTimeFormat),
boardName: Config().general.boardName,
};
}
getFormattedTextFor(info, textType, defaultSgr = '|07') {
const themeDefaults = _.get(info.client.currentTheme, 'achievements.defaults', {});
const textTypeSgr = themeDefaults[`${textType}SGR`] || defaultSgr;
const themeDefaults = _.get(
info.client.currentTheme,
'achievements.defaults',
{}
);
const textTypeSgr = themeDefaults[`${textType}SGR`] || defaultSgr;
const formatObj = this.getFormatObject(info);
const wrap = (input) => {
const wrap = input => {
const re = new RegExp(`{(${Object.keys(formatObj).join('|')})([^}]*)}`, 'g');
return input.replace(re, (m, formatVar, formatOpts) => {
const varSgr = themeDefaults[`${formatVar}SGR`] || textTypeSgr;
let r = `${varSgr}{${formatVar}`;
if(formatOpts) {
if (formatOpts) {
r += formatOpts;
}
return `${r}}${textTypeSgr}`;
@@ -480,10 +552,10 @@ class Achievements {
info.client.currentTheme.helpers.getDateTimeFormat();
const title = this.getFormattedTextFor(info, 'title');
const text = this.getFormattedTextFor(info, 'text');
const text = this.getFormattedTextFor(info, 'text');
let globalText;
if(info.details.globalText) {
if (info.details.globalText) {
globalText = this.getFormattedTextFor(info, 'globalText');
}
@@ -492,13 +564,13 @@ class Achievements {
_.get(info.details, `art.${name}`) ||
_.get(info.achievement, `art.${name}`) ||
_.get(this.config.get(), `art.${name}`);
if(!spec) {
if (!spec) {
return callback(null);
}
const getArtOpts = {
name : spec,
client : this.client,
random : false,
name: spec,
client: this.client,
random: false,
};
getThemeArt(getArtOpts, (err, artInfo) => {
// ignore errors
@@ -507,67 +579,86 @@ class Achievements {
};
const interruptItems = {};
let itemTypes = [ 'local' ];
if(globalText) {
let itemTypes = ['local'];
if (globalText) {
itemTypes.push('global');
}
async.each(itemTypes, (itemType, nextItemType) => {
async.waterfall(
[
(callback) => {
getArt(`${itemType}Header`, headerArt => {
return callback(null, headerArt);
});
},
(headerArt, callback) => {
getArt(`${itemType}Footer`, footerArt => {
return callback(null, headerArt, footerArt);
});
},
(headerArt, footerArt, callback) => {
const itemText = 'global' === itemType ? globalText : text;
interruptItems[itemType] = {
title,
achievText : itemText,
text : `${title}\r\n${itemText}`,
pause : true,
};
if(headerArt || footerArt) {
const themeDefaults = _.get(info.client.currentTheme, 'achievements.defaults', {});
const defaultContentsFormat = '{title}\r\n{message}';
const contentsFormat = 'global' === itemType ?
themeDefaults.globalFormat || defaultContentsFormat :
themeDefaults.format || defaultContentsFormat;
const formatObj = Object.assign(this.getFormatObject(info), {
title : this.getFormattedTextFor(info, 'title', ''), // ''=defaultSgr
message : itemText,
async.each(
itemTypes,
(itemType, nextItemType) => {
async.waterfall(
[
callback => {
getArt(`${itemType}Header`, headerArt => {
return callback(null, headerArt);
});
},
(headerArt, callback) => {
getArt(`${itemType}Footer`, footerArt => {
return callback(null, headerArt, footerArt);
});
},
(headerArt, footerArt, callback) => {
const itemText = 'global' === itemType ? globalText : text;
interruptItems[itemType] = {
title,
achievText: itemText,
text: `${title}\r\n${itemText}`,
pause: true,
};
if (headerArt || footerArt) {
const themeDefaults = _.get(
info.client.currentTheme,
'achievements.defaults',
{}
);
const defaultContentsFormat = '{title}\r\n{message}';
const contentsFormat =
'global' === itemType
? themeDefaults.globalFormat ||
defaultContentsFormat
: themeDefaults.format || defaultContentsFormat;
const contents = pipeToAnsi(stringFormat(contentsFormat, formatObj));
const formatObj = Object.assign(
this.getFormatObject(info),
{
title: this.getFormattedTextFor(
info,
'title',
''
), // ''=defaultSgr
message: itemText,
}
);
interruptItems[itemType].contents =
`${headerArt || ''}\r\n${contents}\r\n${footerArt || ''}`;
}
return callback(null);
const contents = pipeToAnsi(
stringFormat(contentsFormat, formatObj)
);
interruptItems[itemType].contents = `${
headerArt || ''
}\r\n${contents}\r\n${footerArt || ''}`;
}
return callback(null);
},
],
err => {
return nextItemType(err);
}
],
err => {
return nextItemType(err);
}
);
},
err => {
return cb(err, interruptItems);
});
);
},
err => {
return cb(err, interruptItems);
}
);
}
}
let achievementsInstance;
function getAchievementsEarnedByUser(userId, cb) {
if(!achievementsInstance) {
if (!achievementsInstance) {
return cb(Errors.UnexpectedState('Achievements not initialized'));
}
@@ -576,39 +667,42 @@ function getAchievementsEarnedByUser(userId, cb) {
FROM user_achievement
WHERE user_id = ?
ORDER BY DATETIME(timestamp);`,
[ userId ],
[userId],
(err, rows) => {
if(err) {
if (err) {
return cb(err);
}
const earned = rows.map(row => {
const earned = rows
.map(row => {
const achievement = Achievement.factory(
achievementsInstance.getAchievementByTag(row.achievement_tag)
);
if (!achievement) {
return;
}
const achievement = Achievement.factory(achievementsInstance.getAchievementByTag(row.achievement_tag));
if(!achievement) {
return;
}
const earnedInfo = {
achievementTag: row.achievement_tag,
type: achievement.data.type,
retroactive: achievement.data.retroactive,
title: row.title,
text: row.text,
points: row.points,
timestamp: moment(row.timestamp),
};
const earnedInfo = {
achievementTag : row.achievement_tag,
type : achievement.data.type,
retroactive : achievement.data.retroactive,
title : row.title,
text : row.text,
points : row.points,
timestamp : moment(row.timestamp),
};
switch (earnedInfo.type) {
case [Achievement.Types.UserStatSet]:
case [Achievement.Types.UserStatInc]:
case [Achievement.Types.UserStatIncNewVal]:
earnedInfo.statName = achievement.data.statName;
break;
}
switch(earnedInfo.type) {
case [ Achievement.Types.UserStatSet ] :
case [ Achievement.Types.UserStatInc ] :
case [ Achievement.Types.UserStatIncNewVal ] :
earnedInfo.statName = achievement.data.statName;
break;
}
return earnedInfo;
}).filter(a => a); // remove any empty records (ie: no achievement.hjson entry exists anymore).
return earnedInfo;
})
.filter(a => a); // remove any empty records (ie: no achievement.hjson entry exists anymore).
return cb(null, earned);
}
@@ -617,8 +711,8 @@ function getAchievementsEarnedByUser(userId, cb) {
exports.moduleInitialize = (initInfo, cb) => {
achievementsInstance = new Achievements(initInfo.events);
achievementsInstance.init( err => {
if(err) {
achievementsInstance.init(err => {
if (err) {
return cb(err);
}