Achievements are now recorded in more detail such that they can be retrieved *as they were* at the time of earning
This commit is contained in:
parent
18a7a79f14
commit
16e903d4c6
|
@ -22,7 +22,10 @@ const {
|
||||||
ErrorReasons
|
ErrorReasons
|
||||||
} = require('./enig_error.js');
|
} = require('./enig_error.js');
|
||||||
const { getThemeArt } = require('./theme.js');
|
const { getThemeArt } = require('./theme.js');
|
||||||
const { pipeToAnsi } = require('./color_codes.js');
|
const {
|
||||||
|
pipeToAnsi,
|
||||||
|
stripMciColorCodes
|
||||||
|
} = require('./color_codes.js');
|
||||||
const stringFormat = require('./string_format.js');
|
const stringFormat = require('./string_format.js');
|
||||||
const StatLog = require('./stat_log.js');
|
const StatLog = require('./stat_log.js');
|
||||||
const Log = require('./logger.js').log;
|
const Log = require('./logger.js').log;
|
||||||
|
@ -127,6 +130,56 @@ class Achievements {
|
||||||
this.events = events;
|
this.events = events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAchievementsEarnedByUser(userId, cb) {
|
||||||
|
if(!this.isEnabled()) {
|
||||||
|
return cb(Errors.General('Achievements not enabled', ErrorReasons.Disabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDb.all(
|
||||||
|
`SELECT achievement_tag, timestamp, match, title, text, points
|
||||||
|
FROM user_achievement
|
||||||
|
WHERE user_id = ?
|
||||||
|
ORDER BY DATETIME(timestamp);`,
|
||||||
|
[ userId ],
|
||||||
|
(err, rows) => {
|
||||||
|
if(err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const earned = rows.map(row => {
|
||||||
|
const achievement = Achievement.factory(this.achievementConfig.achievements[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,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(earnedInfo.type) {
|
||||||
|
case [ Achievement.Types.UserStatSet ] :
|
||||||
|
case [ Achievement.Types.UserStatInc ] :
|
||||||
|
earnedInfo.statName = achievement.data.statName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return earnedInfo;
|
||||||
|
}).filter(a => a); // remove any empty records (ie: no achievement.hjson entry exists anymore).
|
||||||
|
|
||||||
|
return cb(null, earned);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
isEnabled() {
|
||||||
|
return !_.isUndefined(this.achievementConfig);
|
||||||
|
}
|
||||||
|
|
||||||
init(cb) {
|
init(cb) {
|
||||||
let achievementConfigPath = _.get(Config(), 'general.achievementFile');
|
let achievementConfigPath = _.get(Config(), 'general.achievementFile');
|
||||||
if(!achievementConfigPath) {
|
if(!achievementConfigPath) {
|
||||||
|
@ -188,14 +241,19 @@ class Achievements {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
record(info, cb) {
|
record(info, localInterruptItem, cb) {
|
||||||
StatLog.incrementUserStat(info.client.user, UserProps.AchievementTotalCount, 1);
|
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 recordData = [
|
||||||
|
info.client.user.userId, info.achievementTag, getISOTimestampString(info.timestamp), info.matchField,
|
||||||
|
stripMciColorCodes(localInterruptItem.title), stripMciColorCodes(localInterruptItem.achievText), info.details.points,
|
||||||
|
];
|
||||||
|
|
||||||
UserDb.run(
|
UserDb.run(
|
||||||
`INSERT OR IGNORE INTO user_achievement (user_id, achievement_tag, timestamp, match)
|
`INSERT OR IGNORE INTO user_achievement (user_id, achievement_tag, timestamp, match, title, text, points)
|
||||||
VALUES (?, ?, ?, ?);`,
|
VALUES (?, ?, ?, ?, ?, ?, ?);`,
|
||||||
[ info.client.user.userId, info.achievementTag, getISOTimestampString(info.timestamp), info.matchField ],
|
recordData,
|
||||||
err => {
|
err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
@ -215,12 +273,7 @@ class Achievements {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
display(info, cb) {
|
display(info, interruptItems, cb) {
|
||||||
this.createAchievementInterruptItems(info, (err, interruptItems) => {
|
|
||||||
if(err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(interruptItems.local) {
|
if(interruptItems.local) {
|
||||||
UserInterruptQueue.queue(interruptItems.local, { clients : info.client } );
|
UserInterruptQueue.queue(interruptItems.local, { clients : info.client } );
|
||||||
}
|
}
|
||||||
|
@ -230,17 +283,21 @@ class Achievements {
|
||||||
}
|
}
|
||||||
|
|
||||||
return cb(null);
|
return cb(null);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recordAndDisplayAchievement(info, cb) {
|
recordAndDisplayAchievement(info, cb) {
|
||||||
async.series(
|
async.waterfall(
|
||||||
[
|
[
|
||||||
(callback) => {
|
(callback) => {
|
||||||
return this.record(info, callback);
|
return this.createAchievementInterruptItems(info, callback);
|
||||||
},
|
},
|
||||||
(callback) => {
|
(interruptItems, callback) => {
|
||||||
return this.display(info, callback);
|
this.record(info, interruptItems.local, err => {
|
||||||
|
return callback(err, interruptItems);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(interruptItems, callback) => {
|
||||||
|
return this.display(info, interruptItems, callback);
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
err => {
|
err => {
|
||||||
|
@ -394,7 +451,7 @@ class Achievements {
|
||||||
userAffils : info.user.properties[UserProps.Affiliations],
|
userAffils : info.user.properties[UserProps.Affiliations],
|
||||||
nodeId : info.client.node,
|
nodeId : info.client.node,
|
||||||
title : info.details.title,
|
title : info.details.title,
|
||||||
text : info.global ? info.details.globalText : info.details.text,
|
//text : info.global ? info.details.globalText : info.details.text,
|
||||||
points : info.details.points,
|
points : info.details.points,
|
||||||
achievedValue : info.achievedValue,
|
achievedValue : info.achievedValue,
|
||||||
matchField : info.matchField,
|
matchField : info.matchField,
|
||||||
|
@ -480,6 +537,8 @@ class Achievements {
|
||||||
(headerArt, footerArt, callback) => {
|
(headerArt, footerArt, callback) => {
|
||||||
const itemText = 'global' === itemType ? globalText : text;
|
const itemText = 'global' === itemType ? globalText : text;
|
||||||
interruptItems[itemType] = {
|
interruptItems[itemType] = {
|
||||||
|
title,
|
||||||
|
achievText : itemText,
|
||||||
text : `${title}\r\n${itemText}`,
|
text : `${title}\r\n${itemText}`,
|
||||||
pause : true,
|
pause : true,
|
||||||
};
|
};
|
||||||
|
@ -518,5 +577,12 @@ let achievements;
|
||||||
|
|
||||||
exports.moduleInitialize = (initInfo, cb) => {
|
exports.moduleInitialize = (initInfo, cb) => {
|
||||||
achievements = new Achievements(initInfo.events);
|
achievements = new Achievements(initInfo.events);
|
||||||
return achievements.init(cb);
|
achievements.init( err => {
|
||||||
|
if(err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.achievements = achievements;
|
||||||
|
return cb(null);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -195,6 +195,9 @@ const DB_INIT_TABLE = {
|
||||||
achievement_tag VARCHAR NOT NULL,
|
achievement_tag VARCHAR NOT NULL,
|
||||||
timestamp DATETIME NOT NULL,
|
timestamp DATETIME NOT NULL,
|
||||||
match VARCHAR NOT NULL,
|
match VARCHAR NOT NULL,
|
||||||
|
title VARCHAR NOT NULL,
|
||||||
|
text VARCHAR NOT NULL,
|
||||||
|
points INTEGER NOT NULL,
|
||||||
UNIQUE(user_id, achievement_tag, match),
|
UNIQUE(user_id, achievement_tag, match),
|
||||||
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE
|
FOREIGN KEY(user_id) REFERENCES user(id) ON DELETE CASCADE
|
||||||
);`
|
);`
|
||||||
|
|
Loading…
Reference in New Issue