fix(incentives): backfill

Also adds various missing data from prior commit
This commit is contained in:
SabreCat 2017-04-26 01:04:02 +00:00
parent 6994c6769a
commit f7e2a0464f
11 changed files with 265 additions and 17 deletions

View file

@ -0,0 +1,207 @@
var migrationName = '20170425_missing_incentives';
var authorName = 'Sabe'; // in case script author needs to know when their ...
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
/*
* Award missing Royal Purple Hatching Potion to users with 55+ check-ins
* Reduce users with impossible check-in counts to a reasonable number
*/
import monk from 'monk';
import common from '../website/common';
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
var dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers(lastId) {
// specify a query to limit the affected users (empty for all users):
var query = {
'loginIncentives': {$gt:99},
'migration': {$ne: migrationName},
};
if (lastId) {
query._id = {
$gt: lastId
}
}
dbUsers.find(query, {
sort: {_id: 1},
limit: 250,
fields: [] // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch(function (err) {
console.log(err);
return exiting(1, 'ERROR! ' + err);
});
}
var progressCount = 1000;
var count = 0;
function updateUsers (users) {
if (!users || users.length === 0) {
console.warn('All appropriate users found and modified.');
displayData();
return;
}
var userPromises = users.map(updateUser);
var lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(function () {
processUsers(lastUser._id);
});
}
function updateUser (user) {
count++;
var language = user.preferences.language || 'en';
var set = {'migration': migrationName};
var inc = {
'items.eggs.BearCub': 0,
'items.eggs.Cactus': 0,
'items.eggs.Dragon': 0,
'items.eggs.FlyingPig': 0,
'items.eggs.Fox': 0,
'items.eggs.LionCub': 0,
'items.eggs.PandaCub': 0,
'items.eggs.TigerCub': 0,
'items.eggs.Wolf': 0,
'items.food.Chocolate': 0,
'items.food.CottonCandyBlue': 0,
'items.food.CottonCandyPink': 0,
'items.food.Fish': 0,
'items.food.Honey': 0,
'items.food.Meat': 0,
'items.food.Milk': 0,
'items.food.Potatoe': 0,
'items.food.RottenMeat': 0,
'items.food.Strawberry': 0,
'items.hatchingPotions.Base': 0,
'items.hatchingPotions.CottonCandyBlue': 0,
'items.hatchingPotions.CottonCandyPink': 0,
'items.hatchingPotions.Desert': 0,
'items.hatchingPotions.Golden': 0,
'items.hatchingPotions.Red': 0,
'items.hatchingPotions.RoyalPurple': 0,
'items.hatchingPotions.Shade': 0,
'items.hatchingPotions.Skeleton': 0,
'items.hatchingPotions.White': 0,
'items.hatchingPotions.Zombie': 0,
};
var nextReward;
if (user.loginIncentives >= 105) {
inc['items.hatchingPotions.RoyalPurple'] += 1;
nextReward = 110;
}
if (user.loginIncentives >= 110) {
inc['items.eggs.BearCub'] += 1;
inc['items.eggs.Cactus'] += 1;
inc['items.eggs.Dragon'] += 1;
inc['items.eggs.FlyingPig'] += 1;
inc['items.eggs.Fox'] += 1;
inc['items.eggs.LionCub'] += 1;
inc['items.eggs.PandaCub'] += 1;
inc['items.eggs.TigerCub'] += 1;
inc['items.eggs.Wolf'] += 1;
nextReward = 115;
}
if (user.loginIncentives >= 115) {
inc['items.hatchingPotions.RoyalPurple'] += 1;
nextReward = 120;
}
if (user.loginIncentives >= 120) {
inc['items.hatchingPotions.Base'] += 1;
inc['items.hatchingPotions.CottonCandyBlue'] += 1;
inc['items.hatchingPotions.CottonCandyPink'] += 1;
inc['items.hatchingPotions.Desert'] += 1;
inc['items.hatchingPotions.Golden'] += 1;
inc['items.hatchingPotions.Red'] += 1;
inc['items.hatchingPotions.Shade'] += 1;
inc['items.hatchingPotions.Skeleton'] += 1;
inc['items.hatchingPotions.White'] += 1;
inc['items.hatchingPotions.Zombie'] += 1;
nextReward = 125;
}
if (user.loginIncentives >= 125) {
inc['items.hatchingPotions.RoyalPurple'] += 1;
nextReward = 130;
}
if (user.loginIncentives >= 130) {
inc['items.food.Chocolate'] += 3;
inc['items.food.CottonCandyBlue'] += 3;
inc['items.food.CottonCandyPink'] += 3;
inc['items.food.Fish'] += 3;
inc['items.food.Honey'] += 3;
inc['items.food.Meat'] += 3;
inc['items.food.Milk'] += 3;
inc['items.food.Potatoe'] += 3;
inc['items.food.RottenMeat'] += 3;
inc['items.food.Strawberry'] += 3;
}
if (user.loginIncentives >= 135) {
inc['items.hatchingPotions.RoyalPurple'] += 1;
nextReward = 140;
}
if (user.loginIncentives >= 140) {
set['items.gear.owned.weapon_special_skeletonKey'] = true;
set['items.gear.owned.shield_special_lootBag'] = true;
nextReward = 145;
}
if (user.loginIncentives >= 145) {
inc['items.hatchingPotions.RoyalPurple'] += 1;
nextReward = 150;
}
if (user.loginIncentives >= 150) {
set['items.gear.owned.head_special_clandestineCowl'] = true;
set['items.gear.owned.armor_special_sneakthiefRobes'] = true;
nextReward = 155;
}
if (user.loginIncentives > 155) {
set.loginIncentives = 155;
nextReward = 160;
}
var push = {
'notifications': {
'type': 'LOGIN_INCENTIVE',
'data': {
'nextRewardAt': nextReward,
'rewardKey': [
'shop_armoire',
],
'rewardText': common.i18n.t('checkInRewards', language),
'reward': [],
'message': common.i18n.t('backloggedCheckInRewards', language),
},
'id': common.uuid(),
}
};
dbUsers.update({_id: user._id}, {$set:set, $push:push, $inc:inc});
if (count % progressCount == 0) console.warn(count + ' ' + user._id);
if (user._id == authorUuid) console.warn(authorName + ' processed');
}
function displayData() {
console.warn('\n' + count + ' users processed\n');
return exiting(0);
}
function exiting(code, msg) {
code = code || 0; // 0 = success
if (code && !msg) { msg = 'ERROR!'; }
if (msg) {
if (code) { console.error(msg); }
else { console.log( msg); }
}
process.exit(code);
}
module.exports = processUsers;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -97,6 +97,14 @@
"weaponSpecialPageBannerNotes": "Wave your banner high to inspire confidence! Increases Strength by <%= str %>.",
"weaponSpecialRoguishRainbowMessageText": "Roguish Rainbow Message",
"weaponSpecialRoguishRainbowMessageNotes": "This sparkly envelope contains messages of encouragement from Habiticans, and a touch of magic to help speed your deliveries! Increases Perception by <%= per %>.",
"weaponSpecialSkeletonKeyText": "Skeleton Key",
"weaponSpecialSkeletonKeyNotes": "All the best Sneakthieves carry a key that can open any lock! Increases Constitution by <%= con %>.",
"weaponSpecialNomadsScimitarText": "Nomad's Scimitar",
"weaponSpecialNomadsScimitarNotes": "The curved blade of this Scimitar is perfect for attacking Tasks from the back of a mount! Increases Intelligence by <%= int %>.",
"weaponSpecialFencingFoilText": "Fencing Foil",
"weaponSpecialFencingFoilNotes": "Should anyone dare to impugn your honor, you'll be ready with this fine foil! Increases Strength by <%= str %>.",
"weaponSpecialTachiText": "Tachi",
"weaponSpecialTachiNotes": "This light and curved sword will shred your tasks to ribbons! Increases Strength by <%= str %>.",
"weaponSpecialYetiText": "Yeti-Tamer Spear",
"weaponSpecialYetiNotes": "This spear allows its user to command any yeti. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
@ -356,6 +364,16 @@
"armorSpecialPageArmorNotes": "Carry everything you need in your perfect pack! Increases Constitution by <%= con %>.",
"armorSpecialRoguishRainbowMessengerRobesText": "Roguish Rainbow Messenger Robes",
"armorSpecialRoguishRainbowMessengerRobesNotes": "These vividly striped robes will allow you to fly through gale-force winds smoothly and safely. Increases Strength by <%= str %>.",
"armorSpecialSneakthiefRobesText": "Sneakthief Robes",
"armorSpecialSneakthiefRobesNotes": "These robes will help hide you in the dead of night, but will also allow freedom of movement as you silently sneak about! Increases Intelligence by <%= int %>.",
"armorSpecialSnowSovereignRobesText": "Snow Sovereign Robes",
"armorSpecialSnowSovereignRobesNotes": "These robes are elegant enough for court, yet warm enough for the coldest winter day. Increases Perception by <%= per %>.",
"armorSpecialNomadsCuirassText": "Nomad's Cuirass",
"armorSpecialNomadsCuirassNotes": "This armor features a strong chest-plate to protect your heart! Increases Constitution by <%= con %>.",
"armorSpecialDandySuitText": "Dandy Suit",
"armorSpecialDandySuitNotes": "You're undeniably dressed for success! Increases Perception by <%= per %>.",
"armorSpecialSamuraiArmorText": "Samurai Armor",
"armorSpecialSamuraiArmorNotes": "This strong, scaled armor is held together by elegant silk cords. Increases Perception by <%= per %>.",
"armorSpecialYetiText": "Yeti-Tamer Robe",
"armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
@ -682,6 +700,16 @@
"headSpecialPageHelmNotes": "Chainmail: for the stylish AND the practical. Increases Perception by <%= per %>.",
"headSpecialRoguishRainbowMessengerHoodText": "Roguish Rainbow Messenger Hood",
"headSpecialRoguishRainbowMessengerHoodNotes": "This bright hood emits a colorful glow that will protect you from unpleasant weather! Increases Constitution by <%= con %>.",
"headSpecialClandestineCowlText": "Clandestine Cowl",
"headSpecialClandestineCowlNotes": "Take care to conceal your face as you rob your Tasks of gold and loot! Increases Perception by <%= per %>.",
"headSpecialSnowSovereignCrownText": "Snow Sovereign Crown",
"headSpecialSnowSovereignCrownNotes": "The jewels in this crown sparkle like new-fallen snowflakes. Increases Constitution by <%= con %>.",
"headSpecialSpikedHelmText": "Spiked Helm",
"headSpecialSpikedHelmNotes": "You'll be well protected from stray Dailies and bad Habits with this functional (and neat-looking!) helm. Increases Strength by <%= str %>.",
"headSpecialDandyHatText": "Dandy Hat",
"headSpecialDandyHatNotes": "What a merry chapeau! You'll look quite fine enjoying a stroll in it. Increases Constitution by <%= con %>.",
"headSpecialKabutoText": "Kabuto",
"headSpecialKabutoNotes": "This helm is functional and beautiful! Your enemies will become distracted admiring it. Increases Intelligence by <%= int %>.",
"headSpecialNyeText": "Absurd Party Hat",
"headSpecialNyeNotes": "You've received an Absurd Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
@ -994,6 +1022,12 @@
"shieldSpecialDiamondStaveNotes": "This valuable stave has mystical powers. Increases Intelligence by <%= int %>.",
"shieldSpecialRoguishRainbowMessageText": "Roguish Rainbow Message",
"shieldSpecialRoguishRainbowMessageNotes": "This sparkly envelope contains messages of encouragement from Habiticans, and a touch of magic to help speed your deliveries! Increases Intelligence by <%= int %>.",
"shieldSpecialLootBagText": "Loot Bag",
"shieldSpecialLootBagNotes": "This bag is ideal for storing all the goodies you've stealthily removed from unsuspecting Tasks! Increases Strength by <%= str %>.",
"shieldSpecialWintryMirrorText": "Wintry Mirror",
"shieldSpecialWintryMirrorNotes": "How else to best admire your wintry look? Increases Intelligence by <%= int %>.",
"shieldSpecialWakizashiText": "Wakizashi",
"shieldSpecialWakizashiNotes": "This short sword is perfect for close-quarters battles with your Dailies! Increases Constitution by <%= con %>.",
"shieldSpecialYetiText": "Yeti-Tamer Shield",
"shieldSpecialYetiNotes": "This shield reflects light from the snow. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
@ -1156,6 +1190,8 @@
"backSpecialWonderconBlackNotes": "Spun of shadows and whispers. Confers no benefit. Special Edition Convention Item.",
"backSpecialTakeThisText": "Take This Wings",
"backSpecialTakeThisNotes": "These wings were earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all attributes by <%= attrs %>.",
"backSpecialSnowdriftVeilText": "Snowdrift Veil",
"backSpecialSnowdriftVeilNotes": "This translucent veil makes it appear you are surrounded by an elegant flurry of snow! Confers no benefit.",
"body": "Body Accessory",
"bodyBase0Text": "No Body Accessory",

View file

@ -1,6 +1,6 @@
{
"unlockedReward": "You have received <%= reward %>",
"earnedRewardForDevotion": "You have earned a <%= reward %> for being committed to improving your life.",
"earnedRewardForDevotion": "You have earned <%= reward %> for being committed to improving your life.",
"nextRewardUnlocksIn": "Check-ins until your next prize: <%= numberOfCheckinsLeft %>",
"awesome": "Awesome!",
"totalCount": "<%= count %> total count",
@ -20,5 +20,10 @@
"threeOfEachFood": "three of each standard Pet Food",
"fourOfEachFood": "four of each standard Pet Food",
"twoSaddles": "two Saddles",
"threeSaddles": "three Saddles"
"threeSaddles": "three Saddles",
"incentiveAchievement": "the Royally Loyal achievement",
"royallyLoyal": "Royally Loyal",
"royallyLoyalText": "This user has checked in over 500 times, and has earned every Check-In Prize!",
"checkInRewards": "Check-In Rewards",
"backloggedCheckInRewards": "You received Check-In Prizes! Visit your Inventory and Equipment to see what's new."
}

View file

@ -99,7 +99,7 @@ let basicAchievs = {
},
royallyLoyal: {
icon: 'achievement-royally-loyal',
titleKey: 'royallyLoyalName',
titleKey: 'royallyLoyal',
textKey: 'royallyLoyalText',
},
};

View file

@ -337,7 +337,7 @@ module.exports = function getLoginIncentives (api) {
},
},
140: {
rewardKey: ['weapon_special_skeletonKey', 'shield_special_lootBag'],
rewardKey: ['shop_weapon_special_skeletonKey', 'shop_shield_special_lootBag'],
reward: [api.gear.flat.weapon_special_skeletonKey, api.gear.flat.shield_special_lootBag],
assignReward: function assignReward (user) {
user.items.gear.owned.weapon_special_skeletonKey = true; // eslint-disable-line camelcase
@ -353,7 +353,7 @@ module.exports = function getLoginIncentives (api) {
},
},
150: {
rewardKey: ['head_special_clandestineCowl', 'broad_armor_special_sneakthiefRobes'],
rewardKey: ['shop_head_special_clandestineCowl', 'shop_armor_special_sneakthiefRobes'],
reward: [api.gear.flat.head_special_clandestineCowl, api.gear.flat.armor_special_sneakthiefRobes],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_clandestineCowl = true; // eslint-disable-line camelcase
@ -369,7 +369,7 @@ module.exports = function getLoginIncentives (api) {
},
},
170: {
rewardKey: ['head_special_snowSovereignCrown', 'broad_armor_special_snowSovereignRobes'],
rewardKey: ['shop_head_special_snowSovereignCrown', 'shop_armor_special_snowSovereignRobes'],
reward: [api.gear.flat.head_special_snowSovereignCrown, api.gear.flat.armor_special_snowSovereignRobes],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_snowSovereignCrown = true; // eslint-disable-line camelcase
@ -385,11 +385,11 @@ module.exports = function getLoginIncentives (api) {
},
},
190: {
rewardKey: ['shield_special_wintryMirror', 'back_special_snowdriftVeil'],
rewardKey: ['shop_shield_special_wintryMirror', 'shop_back_special_snowdriftVeil'],
reward: [api.gear.flat.shield_special_wintryMirror, api.gear.flat.back_special_snowdriftVeil],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_wintryMirror = true; // eslint-disable-line camelcase
user.items.gear.owned.armor_special_snowdriftVeil = true; // eslint-disable-line camelcase
user.items.gear.owned.shield_special_wintryMirror = true; // eslint-disable-line camelcase
user.items.gear.owned.back_special_snowdriftVeil = true; // eslint-disable-line camelcase
},
},
200: {
@ -409,7 +409,7 @@ module.exports = function getLoginIncentives (api) {
},
},
240: {
rewardKey: ['weapon_special_nomadsScimitar', 'broad_armor_special_nomadsCuirass'],
rewardKey: ['shop_weapon_special_nomadsScimitar', 'shop_armor_special_nomadsCuirass'],
reward: [api.gear.flat.weapon_special_nomadsScimitar, api.gear.flat.armor_special_nomadsCuirass],
assignReward: function assignReward (user) {
user.items.gear.owned.weapon_special_nomadsScimitar = true; // eslint-disable-line camelcase
@ -417,7 +417,7 @@ module.exports = function getLoginIncentives (api) {
},
},
260: {
rewardKey: ['head_special_spikedHelm'],
rewardKey: ['shop_head_special_spikedHelm'],
reward: [api.gear.flat.head_special_spikedHelm],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_spikedHelm = true; // eslint-disable-line camelcase
@ -476,14 +476,14 @@ module.exports = function getLoginIncentives (api) {
},
},
320: {
rewardKey: ['head_special_dandyHat'],
rewardKey: ['shop_head_special_dandyHat'],
reward: [api.gear.flat.head_special_dandyHat],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_dandyHat = true; // eslint-disable-line camelcase
},
},
340: {
rewardKey: ['weapon_special_fencingFoil', 'broad_armor_special_dandySuit'],
rewardKey: ['shop_weapon_special_fencingFoil', 'shop_armor_special_dandySuit'],
reward: [api.gear.flat.weapon_special_fencingFoil, api.gear.flat.armor_special_dandySuit],
assignReward: function assignReward (user) {
user.items.gear.owned.weapon_special_fencingFoil = true; // eslint-disable-line camelcase
@ -561,7 +561,7 @@ module.exports = function getLoginIncentives (api) {
},
},
450: {
rewardKey: ['weapon_special_tachi', 'broad_armor_special_samuraiArmor'],
rewardKey: ['shop_weapon_special_tachi', 'shop_armor_special_samuraiArmor'],
reward: [api.gear.flat.weapon_special_tachi, api.gear.flat.armor_special_samuraiArmor],
assignReward: function assignReward (user) {
user.items.gear.owned.weapon_special_tachi = true; // eslint-disable-line camelcase
@ -569,7 +569,7 @@ module.exports = function getLoginIncentives (api) {
},
},
475: {
rewardKey: ['head_special_kabuto', 'shield_special_wakizashi'],
rewardKey: ['shop_head_special_kabuto', 'shop_shield_special_wakizashi'],
reward: [api.gear.flat.head_special_kabuto, api.gear.flat.shield_special_wakizashi],
assignReward: function assignReward (user) {
user.items.gear.owned.head_special_kabuto = true; // eslint-disable-line camelcase
@ -579,13 +579,12 @@ module.exports = function getLoginIncentives (api) {
500: {
rewardKey: ['achievement-royally-loyal2x'],
reward: [api.achievements.royallyLoyal],
rewardName: 'incentiveAchievement',
assignReward: function assignReward (user) {
user.achievements.royallyLoyal = true; // eslint-disable-line camelcase
},
},
};
// When the final check-in prize is added here, change checkinReceivedAllRewardsMessage in website/common/locales/en/loginIncentives.json
// to say "You have received the final Check-In prize!". Confirm the message with Lemoness first.
// Add reference link to next reward and add filler days so we have a map to reference the next reward from any day
// We could also, use a list, but then we would be cloning each of the rewards.

View file

@ -179,6 +179,7 @@ function _getBasicAchievements (user, language) {
_addSimple(result, user, {path: 'partyUp', language});
_addSimple(result, user, {path: 'partyOn', language});
_addSimple(result, user, {path: 'royallyLoyal', language});
_addSimpleWithMasterCount(result, user, {path: 'beastMaster', language});
_addSimpleWithMasterCount(result, user, {path: 'mountMaster', language});