mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
WIP: Improve User model performances (#10832)
* wip: define items as mixed objects * add default owned gear * mark modified * more mark modified * more mark modified * more mark modified * more mark modified * fix common tests * fix common tests * update mongoose * add itemsUtils * use new util function in hall controller * add tests for items utils * update website/server to mark all items as modified * start updating common code * update login incentives * update unlock * remove changes to package-lock.json * remove changes to package.json
This commit is contained in:
@@ -90,6 +90,8 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
|
||||
}
|
||||
|
||||
user.items.gear.owned[drop.key] = true;
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
user.flags.armoireOpened = true;
|
||||
let message = this.i18n('armoireEquipment', {
|
||||
image: `<span class="shop_${drop.key} pull-left"></span>`,
|
||||
@@ -125,6 +127,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
|
||||
|
||||
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
||||
user.items.food[drop.key] += 1;
|
||||
if (user.markModified) user.markModified('items.food');
|
||||
|
||||
if (this.analytics) {
|
||||
this._trackDropAnalytics(user._id, drop.key);
|
||||
|
||||
@@ -38,6 +38,8 @@ module.exports = function buyMysterySet (user, req = {}, analytics) {
|
||||
}
|
||||
});
|
||||
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
user.purchased.plan.consecutive.trinkets--;
|
||||
|
||||
return [
|
||||
|
||||
@@ -68,6 +68,7 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
||||
executeChanges (user, item, req) {
|
||||
if (!user.items.quests[item.key] || user.items.quests[item.key] < 0) user.items.quests[item.key] = 0;
|
||||
user.items.quests[item.key] += this.quantity;
|
||||
if (user.markModified) user.markModified('items.quests');
|
||||
|
||||
this.subtractCurrency(user, item, this.quantity);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ export class BuyQuestWithGemOperation extends AbstractGemItemOperation {
|
||||
executeChanges (user, item, req) {
|
||||
user.items.quests[item.key] = user.items.quests[item.key] || 0;
|
||||
user.items.quests[item.key] += this.quantity;
|
||||
if (user.markModified) user.markModified('items.quests');
|
||||
|
||||
this.subtractCurrency(user, item, this.quantity);
|
||||
|
||||
|
||||
@@ -36,10 +36,12 @@ module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
||||
|
||||
if (type === 'pets') {
|
||||
user.items.pets[key] = 5;
|
||||
if (user.markModified) user.markModified('items.pets');
|
||||
}
|
||||
|
||||
if (type === 'mounts') {
|
||||
user.items.mounts[key] = true;
|
||||
if (user.markModified) user.markModified('items.mounts');
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
|
||||
@@ -47,6 +47,7 @@ function purchaseItem (user, item, price, type, key) {
|
||||
|
||||
if (type === 'gear') {
|
||||
user.items.gear.owned[key] = true;
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
} else if (type === 'bundles') {
|
||||
let subType = item.type;
|
||||
forEach(item.bundleKeys, function addBundledItems (bundledKey) {
|
||||
@@ -55,11 +56,13 @@ function purchaseItem (user, item, price, type, key) {
|
||||
}
|
||||
user.items[subType][bundledKey]++;
|
||||
});
|
||||
if (user.markModified) user.markModified(`items.${subType}`);
|
||||
} else {
|
||||
if (!user.items[type][key] || user.items[type][key] < 0) {
|
||||
user.items[type][key] = 0;
|
||||
}
|
||||
user.items[type][key]++;
|
||||
if (user.markModified) user.markModified(`items.${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ module.exports = function changeClass (user, req = {}, analytics) {
|
||||
addPinnedGearByClass(user);
|
||||
|
||||
user.items.gear.owned[`weapon_${klass}_0`] = true;
|
||||
if (klass === 'rogue') user.items.gear.owned[`shield_${klass}_0`] = true;
|
||||
if (klass === 'rogue') user.items.gear.owned[`shield_${klass}_0`] = true;
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
removePinnedItemsByOwnedGear(user);
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ module.exports = function equip (user, req = {}) {
|
||||
user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
|
||||
{[item.type]: `${item.type}_base_0`}
|
||||
);
|
||||
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
|
||||
|
||||
message = i18n.t('messageUnEquipped', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
@@ -61,6 +63,8 @@ module.exports = function equip (user, req = {}) {
|
||||
user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
|
||||
{[item.type]: item.key}
|
||||
);
|
||||
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
|
||||
|
||||
message = handleTwoHanded(user, item, type, req);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -12,6 +12,11 @@ function evolve (user, pet, req) {
|
||||
user.items.pets[pet.key] = -1;
|
||||
user.items.mounts[pet.key] = true;
|
||||
|
||||
if (user.markModified) {
|
||||
user.markModified('items.pets');
|
||||
user.markModified('items.mounts');
|
||||
}
|
||||
|
||||
if (pet.key === user.items.currentPet) {
|
||||
user.items.currentPet = '';
|
||||
}
|
||||
@@ -74,12 +79,15 @@ module.exports = function feed (user, req = {}) {
|
||||
message = i18n.t('messageDontEnjoyFood', messageParams, req.language);
|
||||
}
|
||||
|
||||
if (user.markModified) user.markModified('items.pets');
|
||||
|
||||
if (userPets[pet.key] >= 50 && !user.items.mounts[pet.key]) {
|
||||
message = evolve(user, pet, req);
|
||||
}
|
||||
}
|
||||
|
||||
user.items.food[food.key]--;
|
||||
if (user.markModified) user.markModified('items.food');
|
||||
|
||||
return [
|
||||
userPets[pet.key],
|
||||
|
||||
@@ -33,6 +33,11 @@ module.exports = function hatch (user, req = {}) {
|
||||
user.items.pets[pet] = 5;
|
||||
user.items.eggs[egg]--;
|
||||
user.items.hatchingPotions[hatchingPotion]--;
|
||||
if (user.markModified) {
|
||||
user.markModified('items.pets');
|
||||
user.markModified('items.eggs');
|
||||
user.markModified('items.hatchingPotions');
|
||||
}
|
||||
|
||||
return [
|
||||
user.items,
|
||||
|
||||
@@ -26,7 +26,10 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
|
||||
item = cloneDeep(content.gear.flat[item]);
|
||||
user.items.gear.owned[item.key] = true;
|
||||
|
||||
if (user.markModified) user.markModified('purchased.plan.mysteryItems');
|
||||
if (user.markModified) {
|
||||
user.markModified('purchased.plan.mysteryItems');
|
||||
user.markModified('items.gear.owned');
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('open mystery item', {
|
||||
|
||||
@@ -98,7 +98,10 @@ function removePinnedGearAddPossibleNewOnes (user, itemPath, newItemKey) {
|
||||
// an item of the users current "new" gear was bought
|
||||
// remove the old pinned gear items and add the new gear back
|
||||
removePinnedGearByClass(user);
|
||||
|
||||
user.items.gear.owned[newItemKey] = true;
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
addPinnedGearByClass(user);
|
||||
|
||||
// update the version, so that vue can refresh the seasonal shop
|
||||
|
||||
@@ -62,6 +62,10 @@ module.exports = function releaseBoth (user, req = {}) {
|
||||
user.items.pets[animal] = 0;
|
||||
user.items.mounts[animal] = null;
|
||||
}
|
||||
if (user.markModified) {
|
||||
user.markModified('items.pets');
|
||||
user.markModified('items.mounts');
|
||||
}
|
||||
|
||||
if (giveBeastMasterAchievement) {
|
||||
if (!user.achievements.beastMasterCount) {
|
||||
|
||||
@@ -30,6 +30,7 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
|
||||
}
|
||||
user.items.mounts[mount] = null;
|
||||
}
|
||||
if (user.markModified) user.markModified('items.mounts');
|
||||
|
||||
if (giveMountMasterAchievement) {
|
||||
if (!user.achievements.mountMasterCount) {
|
||||
|
||||
@@ -30,6 +30,7 @@ module.exports = function releasePets (user, req = {}, analytics) {
|
||||
}
|
||||
user.items.pets[pet] = 0;
|
||||
}
|
||||
if (user.markModified) user.markModified('items.pets');
|
||||
|
||||
if (giveBeastMasterAchievement) {
|
||||
if (!user.achievements.beastMasterCount) {
|
||||
|
||||
@@ -87,6 +87,7 @@ module.exports = function revive (user, req = {}, analytics) {
|
||||
removePinnedGearByClass(user);
|
||||
|
||||
user.items.gear.owned[lostItem] = false;
|
||||
if (user.markModified) user.markModified('items.gear.owned');
|
||||
|
||||
addPinnedGearByClass(user);
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ module.exports = function sell (user, req = {}) {
|
||||
}
|
||||
|
||||
user.items[type][key] -= amount;
|
||||
if (user.markModified) user.markModified(`items.${type}`);
|
||||
|
||||
user.stats.gp += content[type][key].value * amount;
|
||||
|
||||
return [
|
||||
|
||||
@@ -75,6 +75,7 @@ module.exports = function unlock (user, req = {}, analytics) {
|
||||
setWith(user, pathPart, true, Object);
|
||||
let itemName = pathPart.split('.').pop();
|
||||
removeItemByPath(user, `gear.flat.${itemName}`);
|
||||
if (user.markModified && path.indexOf('gear.owned') !== -1) user.markModified('items.gear.owned');
|
||||
}
|
||||
|
||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||
@@ -96,6 +97,7 @@ module.exports = function unlock (user, req = {}, analytics) {
|
||||
if (path.indexOf('gear.') !== -1) {
|
||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||
setWith(user, path, true, Object);
|
||||
if (user.markModified && path.indexOf('gear.owned') !== -1) user.markModified('items.gear.owned');
|
||||
}
|
||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||
setWith(user, `purchased.${path}`, true, Object);
|
||||
|
||||
Reference in New Issue
Block a user