mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 23:27:26 +01:00
Merge branch 'release' into sabrecat/veggie-potions
This commit is contained in:
1906
package-lock.json
generated
1906
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
54
package.json
54
package.json
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "habitica",
|
"name": "habitica",
|
||||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||||
"version": "4.91.1",
|
"version": "4.91.2",
|
||||||
"main": "./website/server/index.js",
|
"main": "./website/server/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google-cloud/trace-agent": "^3.5.2",
|
"@google-cloud/trace-agent": "^3.6.0",
|
||||||
"@slack/client": "^3.8.1",
|
"@slack/client": "^3.8.1",
|
||||||
"accepts": "^1.3.5",
|
"accepts": "^1.3.5",
|
||||||
"amazon-payments": "^0.2.7",
|
"amazon-payments": "^0.2.7",
|
||||||
"amplitude": "^3.5.0",
|
"amplitude": "^3.5.0",
|
||||||
"amplitude-js": "^4.6.0-beta.2",
|
"amplitude-js": "^5.0.0",
|
||||||
"apidoc": "^0.17.5",
|
"apidoc": "^0.17.5",
|
||||||
"apn": "^2.2.0",
|
"apn": "^2.2.0",
|
||||||
"autoprefixer": "^8.5.0",
|
"autoprefixer": "^9.4.0",
|
||||||
"aws-sdk": "^2.400.0",
|
"aws-sdk": "^2.432.0",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"axios-progress-bar": "^1.2.0",
|
"axios-progress-bar": "^1.2.0",
|
||||||
"babel-core": "^6.26.3",
|
"babel-core": "^6.26.3",
|
||||||
@@ -28,16 +28,16 @@
|
|||||||
"babel-preset-es2015": "^6.6.0",
|
"babel-preset-es2015": "^6.6.0",
|
||||||
"babel-register": "^6.6.0",
|
"babel-register": "^6.6.0",
|
||||||
"babel-runtime": "^6.11.6",
|
"babel-runtime": "^6.11.6",
|
||||||
"bcrypt": "^3.0.1",
|
"bcrypt": "^3.0.5",
|
||||||
"body-parser": "^1.18.3",
|
"body-parser": "^1.18.3",
|
||||||
"bootstrap": "^4.1.1",
|
"bootstrap": "^4.1.1",
|
||||||
"bootstrap-vue": "^2.0.0-rc.13",
|
"bootstrap-vue": "^2.0.0-rc.16",
|
||||||
"compression": "^1.7.2",
|
"compression": "^1.7.4",
|
||||||
"cookie-session": "^1.2.0",
|
"cookie-session": "^1.3.3",
|
||||||
"coupon-code": "^0.4.5",
|
"coupon-code": "^0.4.5",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"css-loader": "^0.28.11",
|
"css-loader": "^0.28.11",
|
||||||
"csv-stringify": "^4.3.1",
|
"csv-stringify": "^5.1.0",
|
||||||
"cwait": "^1.1.1",
|
"cwait": "^1.1.1",
|
||||||
"domain-middleware": "~0.1.0",
|
"domain-middleware": "~0.1.0",
|
||||||
"express": "^4.16.3",
|
"express": "^4.16.3",
|
||||||
@@ -52,10 +52,10 @@
|
|||||||
"gulp-nodemon": "^2.4.1",
|
"gulp-nodemon": "^2.4.1",
|
||||||
"gulp.spritesmith": "^6.9.0",
|
"gulp.spritesmith": "^6.9.0",
|
||||||
"habitica-markdown": "^1.3.0",
|
"habitica-markdown": "^1.3.0",
|
||||||
"hellojs": "^1.15.1",
|
"hellojs": "^1.18.1",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"image-size": "^0.6.2",
|
"image-size": "^0.7.0",
|
||||||
"in-app-purchase": "^1.10.2",
|
"in-app-purchase": "^1.11.3",
|
||||||
"intro.js": "^2.9.3",
|
"intro.js": "^2.9.3",
|
||||||
"jquery": ">=3.0.0",
|
"jquery": ">=3.0.0",
|
||||||
"js2xmlparser": "^3.0.0",
|
"js2xmlparser": "^3.0.0",
|
||||||
@@ -64,13 +64,13 @@
|
|||||||
"method-override": "^3.0.0",
|
"method-override": "^3.0.0",
|
||||||
"moment": "^2.22.1",
|
"moment": "^2.22.1",
|
||||||
"moment-recur": "^1.0.7",
|
"moment-recur": "^1.0.7",
|
||||||
"mongoose": "^5.4.11",
|
"mongoose": "^5.4.19",
|
||||||
"morgan": "^1.7.0",
|
"morgan": "^1.7.0",
|
||||||
"nconf": "^0.10.0",
|
"nconf": "^0.10.0",
|
||||||
"node-gcm": "^1.0.2",
|
"node-gcm": "^1.0.2",
|
||||||
"node-sass": "^4.9.0",
|
"node-sass": "^4.9.0",
|
||||||
"nodemailer": "^5.0.0",
|
"nodemailer": "^6.0.0",
|
||||||
"ora": "^3.0.0",
|
"ora": "^3.2.0",
|
||||||
"pageres": "^4.1.1",
|
"pageres": "^4.1.1",
|
||||||
"passport": "^0.4.0",
|
"passport": "^0.4.0",
|
||||||
"passport-facebook": "^2.0.0",
|
"passport-facebook": "^2.0.0",
|
||||||
@@ -85,12 +85,12 @@
|
|||||||
"sass-loader": "^7.0.3",
|
"sass-loader": "^7.0.3",
|
||||||
"shelljs": "^0.8.2",
|
"shelljs": "^0.8.2",
|
||||||
"short-uuid": "^3.0.0",
|
"short-uuid": "^3.0.0",
|
||||||
"smartbanner.js": "^1.9.1",
|
"smartbanner.js": "^1.11.0",
|
||||||
"stripe": "^5.9.0",
|
"stripe": "^5.9.0",
|
||||||
"superagent": "^4.0.0",
|
"superagent": "^5.0.2",
|
||||||
"svg-inline-loader": "^0.8.0",
|
"svg-inline-loader": "^0.8.0",
|
||||||
"svg-url-loader": "^2.3.2",
|
"svg-url-loader": "^2.3.2",
|
||||||
"svgo": "^1.0.5",
|
"svgo": "^1.2.0",
|
||||||
"svgo-loader": "^2.1.0",
|
"svgo-loader": "^2.1.0",
|
||||||
"universal-analytics": "^0.4.17",
|
"universal-analytics": "^0.4.17",
|
||||||
"update": "^0.7.4",
|
"update": "^0.7.4",
|
||||||
@@ -100,13 +100,13 @@
|
|||||||
"uuid": "^3.0.1",
|
"uuid": "^3.0.1",
|
||||||
"validator": "^10.5.0",
|
"validator": "^10.5.0",
|
||||||
"vinyl-buffer": "^1.0.1",
|
"vinyl-buffer": "^1.0.1",
|
||||||
"vue": "^2.6.4",
|
"vue": "^2.6.10",
|
||||||
"vue-loader": "^14.2.2",
|
"vue-loader": "^14.2.2",
|
||||||
"vue-mugen-scroll": "^0.2.1",
|
"vue-mugen-scroll": "^0.2.1",
|
||||||
"vue-router": "^3.0.0",
|
"vue-router": "^3.0.0",
|
||||||
"vue-style-loader": "^4.1.0",
|
"vue-style-loader": "^4.1.0",
|
||||||
"vue-template-compiler": "^2.6.4",
|
"vue-template-compiler": "^2.6.10",
|
||||||
"vuedraggable": "^2.15.0",
|
"vuedraggable": "^2.20.0",
|
||||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||||
"webpack": "^3.12.0",
|
"webpack": "^3.12.0",
|
||||||
"webpack-merge": "^4.1.3",
|
"webpack-merge": "^4.1.3",
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
"chalk": "^2.4.1",
|
"chalk": "^2.4.1",
|
||||||
"chromedriver": "^2.40.0",
|
"chromedriver": "^2.40.0",
|
||||||
"connect-history-api-fallback": "^1.1.0",
|
"connect-history-api-fallback": "^1.1.0",
|
||||||
"coveralls": "^3.0.1",
|
"coveralls": "^3.0.3",
|
||||||
"cross-spawn": "^6.0.5",
|
"cross-spawn": "^6.0.5",
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-habitrpg": "^4.0.0",
|
"eslint-config-habitrpg": "^4.0.0",
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
"expect.js": "^0.3.1",
|
"expect.js": "^0.3.1",
|
||||||
"http-proxy-middleware": "^0.19.0",
|
"http-proxy-middleware": "^0.19.0",
|
||||||
"istanbul": "^1.1.0-alpha.1",
|
"istanbul": "^1.1.0-alpha.1",
|
||||||
"karma": "^3.1.3",
|
"karma": "^4.0.1",
|
||||||
"karma-babel-preprocessor": "^7.0.0",
|
"karma-babel-preprocessor": "^7.0.0",
|
||||||
"karma-chai-plugins": "^0.9.0",
|
"karma-chai-plugins": "^0.9.0",
|
||||||
"karma-chrome-launcher": "^2.2.0",
|
"karma-chrome-launcher": "^2.2.0",
|
||||||
@@ -181,11 +181,11 @@
|
|||||||
"lcov-result-merger": "^3.0.0",
|
"lcov-result-merger": "^3.0.0",
|
||||||
"mocha": "^5.1.1",
|
"mocha": "^5.1.1",
|
||||||
"monk": "^6.0.6",
|
"monk": "^6.0.6",
|
||||||
"nightwatch": "^0.9.21",
|
"nightwatch": "^1.0.16",
|
||||||
"puppeteer": "^1.5.0",
|
"puppeteer": "^1.14.0",
|
||||||
"require-again": "^2.0.0",
|
"require-again": "^2.0.0",
|
||||||
"selenium-server": "^3.12.0",
|
"selenium-server": "^3.12.0",
|
||||||
"sinon": "^6.3.5",
|
"sinon": "^7.2.4",
|
||||||
"sinon-chai": "^3.0.0",
|
"sinon-chai": "^3.0.0",
|
||||||
"sinon-stub-promise": "^4.0.0",
|
"sinon-stub-promise": "^4.0.0",
|
||||||
"webpack-bundle-analyzer": "^2.12.0",
|
"webpack-bundle-analyzer": "^2.12.0",
|
||||||
|
|||||||
67
test/api/unit/libs/items/utils.test.js
Normal file
67
test/api/unit/libs/items/utils.test.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
import {
|
||||||
|
validateItemPath,
|
||||||
|
getDefaultOwnedGear,
|
||||||
|
} from '../../../../../website/server/libs/items/utils';
|
||||||
|
|
||||||
|
describe('Items Utils', () => {
|
||||||
|
describe('getDefaultOwnedGear', () => {
|
||||||
|
it('clones the result object', () => {
|
||||||
|
const res1 = getDefaultOwnedGear();
|
||||||
|
res1.extraProperty = true;
|
||||||
|
|
||||||
|
const res2 = getDefaultOwnedGear();
|
||||||
|
expect(res2).not.to.have.property('extraProperty');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateItemPath', () => {
|
||||||
|
it('returns false if not an item path', () => {
|
||||||
|
expect(validateItemPath('notitems.gear.owned.item')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns true if a valid schema path', () => {
|
||||||
|
expect(validateItemPath('items.gear.equipped.weapon')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.currentPet')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.special.snowball')).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with owned gear paths', () => {
|
||||||
|
expect(validateItemPath('items.gear.owned.head_armoire_crownOfHearts')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.gear.owned.head_invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with pets paths', () => {
|
||||||
|
expect(validateItemPath('items.pets.Wolf-CottonCandyPink')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.pets.Wolf-Invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with eggs paths', () => {
|
||||||
|
expect(validateItemPath('items.eggs.LionCub')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.eggs.Armadillo')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.eggs.NotAnArmadillo')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with hatching potions paths', () => {
|
||||||
|
expect(validateItemPath('items.hatchingPotions.Base')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.hatchingPotions.StarryNight')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.hatchingPotions.Invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with food paths', () => {
|
||||||
|
expect(validateItemPath('items.food.Cake_Base')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.food.Cake_Invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with mounts paths', () => {
|
||||||
|
expect(validateItemPath('items.mounts.Cactus-Base')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.mounts.Aether-Invisible')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.mounts.Aether-Invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with quests paths', () => {
|
||||||
|
expect(validateItemPath('items.quests.atom3')).to.equal(true);
|
||||||
|
expect(validateItemPath('items.quests.invalid')).to.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -27,8 +27,6 @@ describe('GET /inbox/messages', () => {
|
|||||||
toUserId: user.id,
|
toUserId: user.id,
|
||||||
message: 'fourth',
|
message: 'fourth',
|
||||||
});
|
});
|
||||||
|
|
||||||
await user.sync();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns the user inbox messages as an array of ordered messages (from most to least recent)', async () => {
|
it('returns the user inbox messages as an array of ordered messages (from most to least recent)', async () => {
|
||||||
@@ -45,4 +43,21 @@ describe('GET /inbox/messages', () => {
|
|||||||
expect(messages[2].text).to.equal('second');
|
expect(messages[2].text).to.equal('second');
|
||||||
expect(messages[3].text).to.equal('first');
|
expect(messages[3].text).to.equal('first');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns four messages when using page-query ', async () => {
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
promises.push(user.post('/members/send-private-message', {
|
||||||
|
toUserId: user.id,
|
||||||
|
message: 'fourth',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
const messages = await user.get('/inbox/messages?page=1');
|
||||||
|
|
||||||
|
expect(messages.length).to.equal(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ describe('inAppRewards', () => {
|
|||||||
expect(result[9].path).to.eql('potion');
|
expect(result[9].path).to.eql('potion');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ignores null/undefined entries', () => {
|
||||||
|
user.pinnedItems = testPinnedItems;
|
||||||
|
user.pinnedItems.push(null);
|
||||||
|
user.pinnedItems.push(undefined);
|
||||||
|
user.pinnedItemsOrder = testPinnedItemsOrder;
|
||||||
|
|
||||||
|
let result = inAppRewards(user);
|
||||||
|
|
||||||
|
expect(result[2].path).to.eql('armoire');
|
||||||
|
expect(result[9].path).to.eql('potion');
|
||||||
|
});
|
||||||
|
|
||||||
it('does not return seasonal items which have been unpinned', () => {
|
it('does not return seasonal items which have been unpinned', () => {
|
||||||
if (officialPinnedItems.length === 0) {
|
if (officialPinnedItems.length === 0) {
|
||||||
return; // if no seasonal items, this test is not applicable
|
return; // if no seasonal items, this test is not applicable
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
import content from '../../../../website/common/script/content/index';
|
import content from '../../../../website/common/script/content/index';
|
||||||
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
import { defaultsDeep } from 'lodash';
|
||||||
|
|
||||||
describe('shared.ops.buy', () => {
|
describe('shared.ops.buy', () => {
|
||||||
let user;
|
let user;
|
||||||
@@ -16,6 +17,10 @@ describe('shared.ops.buy', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = generateUser({
|
user = generateUser({
|
||||||
|
stats: { gp: 200 },
|
||||||
|
});
|
||||||
|
|
||||||
|
defaultsDeep(user, {
|
||||||
items: {
|
items: {
|
||||||
gear: {
|
gear: {
|
||||||
owned: {
|
owned: {
|
||||||
@@ -26,7 +31,6 @@ describe('shared.ops.buy', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
stats: { gp: 200 },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.stub(analytics, 'track');
|
sinon.stub(analytics, 'track');
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from '../../../../website/common/script/libs/errors';
|
} from '../../../../website/common/script/libs/errors';
|
||||||
import i18n from '../../../../website/common/script/i18n';
|
import i18n from '../../../../website/common/script/i18n';
|
||||||
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
import errorMessage from '../../../../website/common/script/libs/errorMessage';
|
||||||
|
import { defaultsDeep } from 'lodash';
|
||||||
|
|
||||||
function buyGear (user, req, analytics) {
|
function buyGear (user, req, analytics) {
|
||||||
let buyOp = new BuyMarketGearOperation(user, req, analytics);
|
let buyOp = new BuyMarketGearOperation(user, req, analytics);
|
||||||
@@ -24,6 +25,10 @@ describe('shared.ops.buyMarketGear', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
user = generateUser({
|
user = generateUser({
|
||||||
|
stats: { gp: 200 },
|
||||||
|
});
|
||||||
|
|
||||||
|
defaultsDeep(user, {
|
||||||
items: {
|
items: {
|
||||||
gear: {
|
gear: {
|
||||||
owned: {
|
owned: {
|
||||||
@@ -34,7 +39,6 @@ describe('shared.ops.buyMarketGear', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
stats: { gp: 200 },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.stub(shared, 'randomVal');
|
sinon.stub(shared, 'randomVal');
|
||||||
|
|||||||
18
test/common/ops/pinnedGearUtils.js
Normal file
18
test/common/ops/pinnedGearUtils.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
import {addPinnedGear} from '../../../website/common/script/ops/pinnedGearUtils';
|
||||||
|
|
||||||
|
describe('shared.ops.pinnedGearUtils.addPinnedGear', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('not adds an item with empty properties to pinnedItems', () => {
|
||||||
|
addPinnedGear(user, undefined, undefined);
|
||||||
|
|
||||||
|
expect(user.pinnedItems.length).to.be.eql(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from '../../website/server/models/task';
|
} from '../../website/server/models/task';
|
||||||
export {translate} from './translate';
|
export {translate} from './translate';
|
||||||
|
|
||||||
|
|
||||||
export function generateUser (options = {}) {
|
export function generateUser (options = {}) {
|
||||||
let user = new User(options).toObject();
|
let user = new User(options).toObject();
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@
|
|||||||
a(href='https://www.facebook.com/Habitica', target='_blank') {{ $t('communityFacebook') }}
|
a(href='https://www.facebook.com/Habitica', target='_blank') {{ $t('communityFacebook') }}
|
||||||
li
|
li
|
||||||
a(href='https://www.instagram.com/habitica', target='_blank') {{ $t('communityInstagram') }}
|
a(href='https://www.instagram.com/habitica', target='_blank') {{ $t('communityInstagram') }}
|
||||||
li
|
|
||||||
a(href='https://www.reddit.com/r/habitrpg/', target='_blank') {{ $t('communityReddit') }}
|
|
||||||
.col-12.col-md-6
|
.col-12.col-md-6
|
||||||
.row
|
.row
|
||||||
.col-6
|
.col-6
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ export default {
|
|||||||
this.$root.$emit('habitica:show-member-modal', {
|
this.$root.$emit('habitica:show-member-modal', {
|
||||||
challengeId: this.challenge._id,
|
challengeId: this.challenge._id,
|
||||||
groupId: 'challenge', // @TODO: change these terrible settings
|
groupId: 'challenge', // @TODO: change these terrible settings
|
||||||
group: this.group,
|
group: this.challenge.group,
|
||||||
memberCount: this.challenge.memberCount,
|
memberCount: this.challenge.memberCount,
|
||||||
viewingMembers: this.members,
|
viewingMembers: this.members,
|
||||||
fetchMoreMembers: this.loadMembers,
|
fetchMoreMembers: this.loadMembers,
|
||||||
|
|||||||
@@ -269,7 +269,8 @@ export default {
|
|||||||
return highlightUsers(text, this.user.auth.local.username, this.user.profile.name);
|
return highlightUsers(text, this.user.auth.local.username, this.user.profile.name);
|
||||||
},
|
},
|
||||||
parseMarkdown (text) {
|
parseMarkdown (text) {
|
||||||
return habiticaMarkdown.render(text);
|
if (!text) return;
|
||||||
|
return habiticaMarkdown.render(String(text));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,6 +93,10 @@
|
|||||||
padding: 0rem;
|
padding: 0rem;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-scroll .d-flex {
|
||||||
|
min-width: 1px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -174,7 +174,9 @@ export default {
|
|||||||
let minPaddingBottom = 20;
|
let minPaddingBottom = 20;
|
||||||
let drawerHeight = this.$el.offsetHeight;
|
let drawerHeight = this.$el.offsetHeight;
|
||||||
let standardPage = document.getElementsByClassName('standard-page')[0];
|
let standardPage = document.getElementsByClassName('standard-page')[0];
|
||||||
|
if (standardPage) {
|
||||||
standardPage.style.paddingBottom = `${drawerHeight + minPaddingBottom}px`;
|
standardPage.style.paddingBottom = `${drawerHeight + minPaddingBottom}px`;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
toggle () {
|
toggle () {
|
||||||
this.open = !this.isOpen;
|
this.open = !this.isOpen;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import habiticaMarkdown from 'habitica-markdown';
|
|||||||
export default function markdown (el, {value, oldValue}) {
|
export default function markdown (el, {value, oldValue}) {
|
||||||
if (value === oldValue) return;
|
if (value === oldValue) return;
|
||||||
|
|
||||||
el.innerHTML = habiticaMarkdown.render(value);
|
if (value) {
|
||||||
|
el.innerHTML = habiticaMarkdown.render(String(value));
|
||||||
|
}
|
||||||
el.classList.add('markdown');
|
el.classList.add('markdown');
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ export default {
|
|||||||
},
|
},
|
||||||
markdown (val) {
|
markdown (val) {
|
||||||
if (!val) return;
|
if (!val) return;
|
||||||
let parsedMarkdown = habiticaMarkdown.render(val);
|
let parsedMarkdown = habiticaMarkdown.render(String(val));
|
||||||
this.notify(parsedMarkdown, 'info');
|
this.notify(parsedMarkdown, 'info');
|
||||||
},
|
},
|
||||||
mp (val) {
|
mp (val) {
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ function buyItem (store, params) {
|
|||||||
|
|
||||||
let opResult = buyOp(user, {params, quantity});
|
let opResult = buyOp(user, {params, quantity});
|
||||||
|
|
||||||
user.pinnedItems = opResult[0].pinnedItems;
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
result: opResult,
|
result: opResult,
|
||||||
httpCall: axios.post(`/api/v4/user/buy/${params.key}`),
|
httpCall: axios.post(`/api/v4/user/buy/${params.key}`),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.armor_special_bardRobes],
|
reward: [api.gear.flat.armor_special_bardRobes],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.armor_special_bardRobes = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_bardRobes = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
@@ -30,6 +31,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.head_special_bardHat],
|
reward: [api.gear.flat.head_special_bardHat],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_bardHat = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_bardHat = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
4: {
|
4: {
|
||||||
@@ -38,6 +40,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
5: {
|
5: {
|
||||||
@@ -50,6 +53,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.Meat += 1;
|
user.items.food.Meat += 1;
|
||||||
if (!user.items.food.CottonCandyPink) user.items.food.CottonCandyPink = 0;
|
if (!user.items.food.CottonCandyPink) user.items.food.CottonCandyPink = 0;
|
||||||
user.items.food.CottonCandyPink += 1;
|
user.items.food.CottonCandyPink += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
7: {
|
7: {
|
||||||
@@ -58,6 +62,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.quests.moon1) user.items.quests.moon1 = 0;
|
if (!user.items.quests.moon1) user.items.quests.moon1 = 0;
|
||||||
user.items.quests.moon1 += 1;
|
user.items.quests.moon1 += 1;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
10: {
|
10: {
|
||||||
@@ -66,6 +71,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
14: {
|
14: {
|
||||||
@@ -78,6 +84,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.Potatoe += 1;
|
user.items.food.Potatoe += 1;
|
||||||
if (!user.items.food.CottonCandyBlue) user.items.food.CottonCandyBlue = 0;
|
if (!user.items.food.CottonCandyBlue) user.items.food.CottonCandyBlue = 0;
|
||||||
user.items.food.CottonCandyBlue += 1;
|
user.items.food.CottonCandyBlue += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
18: {
|
18: {
|
||||||
@@ -85,6 +92,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.weapon_special_bardInstrument],
|
reward: [api.gear.flat.weapon_special_bardInstrument],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_bardInstrument = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_bardInstrument = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
22: {
|
22: {
|
||||||
@@ -93,6 +101,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.quests.moon2) user.items.quests.moon2 = 0;
|
if (!user.items.quests.moon2) user.items.quests.moon2 = 0;
|
||||||
user.items.quests.moon2 += 1;
|
user.items.quests.moon2 += 1;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
26: {
|
26: {
|
||||||
@@ -101,6 +110,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
30: {
|
30: {
|
||||||
@@ -115,6 +125,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.RottenMeat += 1;
|
user.items.food.RottenMeat += 1;
|
||||||
if (!user.items.food.Honey) user.items.food.Honey = 0;
|
if (!user.items.food.Honey) user.items.food.Honey = 0;
|
||||||
user.items.food.Honey += 1;
|
user.items.food.Honey += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
35: {
|
35: {
|
||||||
@@ -123,6 +134,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
40: {
|
40: {
|
||||||
@@ -131,6 +143,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.quests.moon3) user.items.quests.moon3 = 0;
|
if (!user.items.quests.moon3) user.items.quests.moon3 = 0;
|
||||||
user.items.quests.moon3 += 1;
|
user.items.quests.moon3 += 1;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
45: {
|
45: {
|
||||||
@@ -139,6 +152,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
50: {
|
50: {
|
||||||
@@ -147,6 +161,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
||||||
user.items.food.Saddle += 1;
|
user.items.food.Saddle += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
55: {
|
55: {
|
||||||
@@ -155,6 +170,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
60: {
|
60: {
|
||||||
@@ -162,6 +178,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.armor_special_pageArmor],
|
reward: [api.gear.flat.armor_special_pageArmor],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.armor_special_pageArmor = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_pageArmor = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
65: {
|
65: {
|
||||||
@@ -170,6 +187,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
70: {
|
70: {
|
||||||
@@ -177,6 +195,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.head_special_pageHelm],
|
reward: [api.gear.flat.head_special_pageHelm],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_pageHelm = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_pageHelm = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
75: {
|
75: {
|
||||||
@@ -185,6 +204,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
80: {
|
80: {
|
||||||
@@ -192,6 +212,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.weapon_special_pageBanner],
|
reward: [api.gear.flat.weapon_special_pageBanner],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_pageBanner = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_pageBanner = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
85: {
|
85: {
|
||||||
@@ -200,6 +221,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
90: {
|
90: {
|
||||||
@@ -207,6 +229,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.shield_special_diamondStave],
|
reward: [api.gear.flat.shield_special_diamondStave],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.shield_special_diamondStave = true; // eslint-disable-line camelcase
|
user.items.gear.owned.shield_special_diamondStave = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
95: {
|
95: {
|
||||||
@@ -215,6 +238,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
100: {
|
100: {
|
||||||
@@ -223,6 +247,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
||||||
user.items.food.Saddle += 1;
|
user.items.food.Saddle += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
105: {
|
105: {
|
||||||
@@ -231,6 +256,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
110: {
|
110: {
|
||||||
@@ -256,6 +282,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.eggs.TigerCub += 1;
|
user.items.eggs.TigerCub += 1;
|
||||||
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
||||||
user.items.eggs.Wolf += 1;
|
user.items.eggs.Wolf += 1;
|
||||||
|
if (user.markModified) user.markModified('items.eggs');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
115: {
|
115: {
|
||||||
@@ -264,6 +291,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
120: {
|
120: {
|
||||||
@@ -291,6 +319,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.hatchingPotions.White += 1;
|
user.items.hatchingPotions.White += 1;
|
||||||
if (!user.items.hatchingPotions.Zombie) user.items.hatchingPotions.Zombie = 0;
|
if (!user.items.hatchingPotions.Zombie) user.items.hatchingPotions.Zombie = 0;
|
||||||
user.items.hatchingPotions.Zombie += 1;
|
user.items.hatchingPotions.Zombie += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
125: {
|
125: {
|
||||||
@@ -299,6 +328,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
130: {
|
130: {
|
||||||
@@ -326,6 +356,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.Milk += 3;
|
user.items.food.Milk += 3;
|
||||||
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
||||||
user.items.food.RottenMeat += 3;
|
user.items.food.RottenMeat += 3;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
135: {
|
135: {
|
||||||
@@ -334,6 +365,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
140: {
|
140: {
|
||||||
@@ -342,6 +374,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_skeletonKey = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_skeletonKey = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.shield_special_lootBag = true; // eslint-disable-line camelcase
|
user.items.gear.owned.shield_special_lootBag = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
145: {
|
145: {
|
||||||
@@ -350,6 +383,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
150: {
|
150: {
|
||||||
@@ -358,6 +392,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_clandestineCowl = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_clandestineCowl = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.armor_special_sneakthiefRobes = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_sneakthiefRobes = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
160: {
|
160: {
|
||||||
@@ -366,6 +401,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
170: {
|
170: {
|
||||||
@@ -374,6 +410,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_snowSovereignCrown = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_snowSovereignCrown = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.armor_special_snowSovereignRobes = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_snowSovereignRobes = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
180: {
|
180: {
|
||||||
@@ -382,6 +419,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
190: {
|
190: {
|
||||||
@@ -390,6 +428,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.shield_special_wintryMirror = 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
|
user.items.gear.owned.back_special_snowdriftVeil = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
200: {
|
200: {
|
||||||
@@ -398,6 +437,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
if (!user.items.hatchingPotions.RoyalPurple) user.items.hatchingPotions.RoyalPurple = 0;
|
||||||
user.items.hatchingPotions.RoyalPurple += 1;
|
user.items.hatchingPotions.RoyalPurple += 1;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
220: {
|
220: {
|
||||||
@@ -406,6 +446,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
||||||
user.items.food.Saddle += 1;
|
user.items.food.Saddle += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
240: {
|
240: {
|
||||||
@@ -414,6 +455,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_nomadsScimitar = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_nomadsScimitar = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.armor_special_nomadsCuirass = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_nomadsCuirass = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
260: {
|
260: {
|
||||||
@@ -421,6 +463,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.head_special_spikedHelm],
|
reward: [api.gear.flat.head_special_spikedHelm],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_spikedHelm = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_spikedHelm = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
280: {
|
280: {
|
||||||
@@ -448,6 +491,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.Milk += 3;
|
user.items.food.Milk += 3;
|
||||||
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
||||||
user.items.food.RottenMeat += 3;
|
user.items.food.RottenMeat += 3;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
300: {
|
300: {
|
||||||
@@ -473,6 +517,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.eggs.TigerCub += 2;
|
user.items.eggs.TigerCub += 2;
|
||||||
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
||||||
user.items.eggs.Wolf += 2;
|
user.items.eggs.Wolf += 2;
|
||||||
|
if (user.markModified) user.markModified('items.eggs');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
320: {
|
320: {
|
||||||
@@ -480,6 +525,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
reward: [api.gear.flat.head_special_dandyHat],
|
reward: [api.gear.flat.head_special_dandyHat],
|
||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_dandyHat = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_dandyHat = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
340: {
|
340: {
|
||||||
@@ -488,6 +534,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_fencingFoil = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_fencingFoil = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.armor_special_dandySuit = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_dandySuit = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
360: {
|
360: {
|
||||||
@@ -497,6 +544,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
||||||
user.items.food.Saddle += 2;
|
user.items.food.Saddle += 2;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
380: {
|
380: {
|
||||||
@@ -522,6 +570,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.eggs.TigerCub += 3;
|
user.items.eggs.TigerCub += 3;
|
||||||
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
if (!user.items.eggs.Wolf) user.items.eggs.Wolf = 0;
|
||||||
user.items.eggs.Wolf += 3;
|
user.items.eggs.Wolf += 3;
|
||||||
|
if (user.markModified) user.markModified('items.eggs');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
@@ -549,6 +598,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
user.items.food.Milk += 4;
|
user.items.food.Milk += 4;
|
||||||
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
if (!user.items.food.RottenMeat) user.items.food.RottenMeat = 0;
|
||||||
user.items.food.RottenMeat += 4;
|
user.items.food.RottenMeat += 4;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
425: {
|
425: {
|
||||||
@@ -558,6 +608,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
if (!user.items.food.Saddle) user.items.food.Saddle = 0;
|
||||||
user.items.food.Saddle += 3;
|
user.items.food.Saddle += 3;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
450: {
|
450: {
|
||||||
@@ -566,6 +617,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.weapon_special_tachi = true; // eslint-disable-line camelcase
|
user.items.gear.owned.weapon_special_tachi = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.armor_special_samuraiArmor = true; // eslint-disable-line camelcase
|
user.items.gear.owned.armor_special_samuraiArmor = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
475: {
|
475: {
|
||||||
@@ -574,6 +626,7 @@ module.exports = function getLoginIncentives (api) {
|
|||||||
assignReward: function assignReward (user) {
|
assignReward: function assignReward (user) {
|
||||||
user.items.gear.owned.head_special_kabuto = true; // eslint-disable-line camelcase
|
user.items.gear.owned.head_special_kabuto = true; // eslint-disable-line camelcase
|
||||||
user.items.gear.owned.shield_special_wakizashi = true; // eslint-disable-line camelcase
|
user.items.gear.owned.shield_special_wakizashi = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
500: {
|
500: {
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
|
|||||||
|
|
||||||
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
||||||
user.items.food[drop.key] += 1;
|
user.items.food[drop.key] += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
|
|
||||||
drop.type = 'Food';
|
drop.type = 'Food';
|
||||||
drop.dialog = i18n.t('messageDropFood', {
|
drop.dialog = i18n.t('messageDropFood', {
|
||||||
dropText: drop.textA(req.language),
|
dropText: drop.textA(req.language),
|
||||||
@@ -82,8 +84,11 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
|
|||||||
}, req.language);
|
}, req.language);
|
||||||
} else if (rarity > 0.3) { // eggs 30% chance
|
} else if (rarity > 0.3) { // eggs 30% chance
|
||||||
drop = cloneDropItem(randomVal(content.dropEggs));
|
drop = cloneDropItem(randomVal(content.dropEggs));
|
||||||
|
|
||||||
user.items.eggs[drop.key] = user.items.eggs[drop.key] || 0;
|
user.items.eggs[drop.key] = user.items.eggs[drop.key] || 0;
|
||||||
user.items.eggs[drop.key]++;
|
user.items.eggs[drop.key]++;
|
||||||
|
if (user.markModified) user.markModified('items.eggs');
|
||||||
|
|
||||||
drop.type = 'Egg';
|
drop.type = 'Egg';
|
||||||
drop.dialog = i18n.t('messageDropEgg', {
|
drop.dialog = i18n.t('messageDropEgg', {
|
||||||
dropText: drop.text(req.language),
|
dropText: drop.text(req.language),
|
||||||
@@ -102,8 +107,11 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
|
|||||||
drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => {
|
drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => {
|
||||||
return acceptableDrops.indexOf(k) >= 0;
|
return acceptableDrops.indexOf(k) >= 0;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
user.items.hatchingPotions[drop.key] = user.items.hatchingPotions[drop.key] || 0;
|
user.items.hatchingPotions[drop.key] = user.items.hatchingPotions[drop.key] || 0;
|
||||||
user.items.hatchingPotions[drop.key]++;
|
user.items.hatchingPotions[drop.key]++;
|
||||||
|
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||||
|
|
||||||
drop.type = 'HatchingPotion';
|
drop.type = 'HatchingPotion';
|
||||||
drop.dialog = i18n.t('messageDropPotion', {
|
drop.dialog = i18n.t('messageDropPotion', {
|
||||||
dropText: drop.text(req.language),
|
dropText: drop.text(req.language),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ module.exports = function resetGear (user) {
|
|||||||
gear[type].shield = 'shield_base_0';
|
gear[type].shield = 'shield_base_0';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gear.owned is a Mongo object so the _.each function iterates over hidden properties.
|
// Gear.owned is (was) a Mongo object so the _.each function iterates over hidden properties.
|
||||||
// The content.gear.flat[k] check should prevent this causing an error
|
// The content.gear.flat[k] check should prevent this causing an error
|
||||||
each(gear.owned, function resetOwnedGear (v, k) {
|
each(gear.owned, function resetOwnedGear (v, k) {
|
||||||
if (gear.owned[k] && content.gear.flat[k] && content.gear.flat[k].value) {
|
if (gear.owned[k] && content.gear.flat[k] && content.gear.flat[k].value) {
|
||||||
@@ -21,5 +21,7 @@ module.exports = function resetGear (user) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gear.owned.weapon_warrior_0 = true; // eslint-disable-line camelcase
|
gear.owned.weapon_warrior_0 = true; // eslint-disable-line camelcase
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
|
|
||||||
user.preferences.costume = false;
|
user.preferences.costume = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import reduce from 'lodash/reduce';
|
|||||||
import includes from 'lodash/includes';
|
import includes from 'lodash/includes';
|
||||||
|
|
||||||
module.exports = function ultimateGear (user) {
|
module.exports = function ultimateGear (user) {
|
||||||
let owned = typeof window !== 'undefined' ? user.items.gear.owned : user.items.gear.owned.toObject();
|
let owned = user.items.gear.owned.toObject ? user.items.gear.owned.toObject() : user.items.gear.owned;
|
||||||
|
|
||||||
content.classes.forEach((klass) => {
|
content.classes.forEach((klass) => {
|
||||||
if (user.achievements.ultimateGearSets[klass] !== true) {
|
if (user.achievements.ultimateGearSets[klass] !== true) {
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
|
|||||||
} else {
|
} else {
|
||||||
user.items.eggs.Wolf = 1;
|
user.items.eggs.Wolf = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.markModified) user.markModified('items.eggs');
|
||||||
}
|
}
|
||||||
each({
|
each({
|
||||||
vice1: 30,
|
vice1: 30,
|
||||||
@@ -84,10 +86,12 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
|
|||||||
}, (lvl, k) => {
|
}, (lvl, k) => {
|
||||||
if (user.stats.lvl >= lvl && !user.flags.levelDrops[k]) {
|
if (user.stats.lvl >= lvl && !user.flags.levelDrops[k]) {
|
||||||
user.flags.levelDrops[k] = true;
|
user.flags.levelDrops[k] = true;
|
||||||
if (!user.items.quests[k])
|
|
||||||
user.items.quests[k] = 0;
|
|
||||||
user.items.quests[k]++;
|
|
||||||
if (user.markModified) user.markModified('flags.levelDrops');
|
if (user.markModified) user.markModified('flags.levelDrops');
|
||||||
|
|
||||||
|
if (!user.items.quests[k]) user.items.quests[k] = 0;
|
||||||
|
user.items.quests[k]++;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
|
|
||||||
if (analytics) {
|
if (analytics) {
|
||||||
analytics.track('acquire item', {
|
analytics.track('acquire item', {
|
||||||
uuid: user._id,
|
uuid: user._id,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import getOfficialPinnedItems from './getOfficialPinnedItems';
|
|||||||
import compactArray from 'lodash/compact';
|
import compactArray from 'lodash/compact';
|
||||||
|
|
||||||
import getItemByPathAndType from './getItemByPathAndType';
|
import getItemByPathAndType from './getItemByPathAndType';
|
||||||
|
import {checkPinnedAreasForNullEntries} from '../ops/pinnedGearUtils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orders the pinned items so we always get our inAppRewards in the order
|
* Orders the pinned items so we always get our inAppRewards in the order
|
||||||
@@ -32,6 +33,8 @@ function sortInAppRewards (user, items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function getPinnedItems (user) {
|
module.exports = function getPinnedItems (user) {
|
||||||
|
checkPinnedAreasForNullEntries(user);
|
||||||
|
|
||||||
let officialPinnedItems = getOfficialPinnedItems(user);
|
let officialPinnedItems = getOfficialPinnedItems(user);
|
||||||
|
|
||||||
const officialPinnedItemsNotUnpinned = officialPinnedItems.filter(officialPin => {
|
const officialPinnedItemsNotUnpinned = officialPinnedItems.filter(officialPin => {
|
||||||
@@ -41,7 +44,8 @@ module.exports = function getPinnedItems (user) {
|
|||||||
|
|
||||||
const pinnedItems = officialPinnedItemsNotUnpinned.concat(user.pinnedItems);
|
const pinnedItems = officialPinnedItemsNotUnpinned.concat(user.pinnedItems);
|
||||||
|
|
||||||
let items = pinnedItems.map(({type, path}) => {
|
let items = pinnedItems
|
||||||
|
.map(({type, path}) => {
|
||||||
let item = getItemByPathAndType(type, path);
|
let item = getItemByPathAndType(type, path);
|
||||||
|
|
||||||
return getItemInfo(user, type, item, officialPinnedItems);
|
return getItemInfo(user, type, item, officialPinnedItems);
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ function getClassName (classType, language) {
|
|||||||
// TODO Refactor the `.locked` logic
|
// TODO Refactor the `.locked` logic
|
||||||
shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) {
|
shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) {
|
||||||
let result = filter(items, ['pinType', 'marketGear']);
|
let result = filter(items, ['pinType', 'marketGear']);
|
||||||
let availableGear = map(updateStore(user), (item) => getItemInfo(user, 'marketGear', item).path);
|
const officialPinnedItems = getOfficialPinnedItems(user);
|
||||||
|
let availableGear = map(updateStore(user), (item) => getItemInfo(user, 'marketGear', item, officialPinnedItems).path);
|
||||||
for (let gear of result) {
|
for (let gear of result) {
|
||||||
if (gear.klass !== user.stats.class) {
|
if (gear.klass !== user.stats.class) {
|
||||||
gear.locked = true;
|
gear.locked = true;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ function equipmentStatBonusComputed (stat, user) {
|
|||||||
let classBonus = 0;
|
let classBonus = 0;
|
||||||
|
|
||||||
// toObject is required here due to lodash values not working well with mongoose doc objects.
|
// toObject is required here due to lodash values not working well with mongoose doc objects.
|
||||||
// if toObject doesn't exist, we're on the client side and can assume the object is already plain JSON
|
// if toObject doesn't exist, we can assume the object is already plain JSON
|
||||||
// see http://stackoverflow.com/questions/25767334/underscore-js-keys-and-omit-not-working-as-expected
|
// see http://stackoverflow.com/questions/25767334/underscore-js-keys-and-omit-not-working-as-expected
|
||||||
let equipped = user.items.gear.equipped;
|
let equipped = user.items.gear.equipped;
|
||||||
let equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject());
|
let equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject());
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.items.gear.owned[drop.key] = true;
|
user.items.gear.owned[drop.key] = true;
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
|
|
||||||
user.flags.armoireOpened = true;
|
user.flags.armoireOpened = true;
|
||||||
let message = this.i18n('armoireEquipment', {
|
let message = this.i18n('armoireEquipment', {
|
||||||
image: `<span class="shop_${drop.key} pull-left"></span>`,
|
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] = user.items.food[drop.key] || 0;
|
||||||
user.items.food[drop.key] += 1;
|
user.items.food[drop.key] += 1;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
|
|
||||||
if (this.analytics) {
|
if (this.analytics) {
|
||||||
this._trackDropAnalytics(user._id, drop.key);
|
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--;
|
user.purchased.plan.consecutive.trinkets--;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
|
|||||||
executeChanges (user, item, req) {
|
executeChanges (user, item, req) {
|
||||||
if (!user.items.quests[item.key] || user.items.quests[item.key] < 0) user.items.quests[item.key] = 0;
|
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;
|
user.items.quests[item.key] += this.quantity;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
|
|
||||||
this.subtractCurrency(user, item, this.quantity);
|
this.subtractCurrency(user, item, this.quantity);
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export class BuyQuestWithGemOperation extends AbstractGemItemOperation {
|
|||||||
executeChanges (user, item, req) {
|
executeChanges (user, item, req) {
|
||||||
user.items.quests[item.key] = user.items.quests[item.key] || 0;
|
user.items.quests[item.key] = user.items.quests[item.key] || 0;
|
||||||
user.items.quests[item.key] += this.quantity;
|
user.items.quests[item.key] += this.quantity;
|
||||||
|
if (user.markModified) user.markModified('items.quests');
|
||||||
|
|
||||||
this.subtractCurrency(user, item, this.quantity);
|
this.subtractCurrency(user, item, this.quantity);
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ module.exports = function purchaseHourglass (user, req = {}, analytics) {
|
|||||||
|
|
||||||
if (type === 'pets') {
|
if (type === 'pets') {
|
||||||
user.items.pets[key] = 5;
|
user.items.pets[key] = 5;
|
||||||
|
if (user.markModified) user.markModified('items.pets');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'mounts') {
|
if (type === 'mounts') {
|
||||||
user.items.mounts[key] = true;
|
user.items.mounts[key] = true;
|
||||||
|
if (user.markModified) user.markModified('items.mounts');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (analytics) {
|
if (analytics) {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ function purchaseItem (user, item, price, type, key) {
|
|||||||
|
|
||||||
if (type === 'gear') {
|
if (type === 'gear') {
|
||||||
user.items.gear.owned[key] = true;
|
user.items.gear.owned[key] = true;
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
} else if (type === 'bundles') {
|
} else if (type === 'bundles') {
|
||||||
let subType = item.type;
|
let subType = item.type;
|
||||||
forEach(item.bundleKeys, function addBundledItems (bundledKey) {
|
forEach(item.bundleKeys, function addBundledItems (bundledKey) {
|
||||||
@@ -55,11 +56,13 @@ function purchaseItem (user, item, price, type, key) {
|
|||||||
}
|
}
|
||||||
user.items[subType][bundledKey]++;
|
user.items[subType][bundledKey]++;
|
||||||
});
|
});
|
||||||
|
if (user.markModified) user.markModified(`items.${subType}`);
|
||||||
} else {
|
} else {
|
||||||
if (!user.items[type][key] || user.items[type][key] < 0) {
|
if (!user.items[type][key] || user.items[type][key] < 0) {
|
||||||
user.items[type][key] = 0;
|
user.items[type][key] = 0;
|
||||||
}
|
}
|
||||||
user.items[type][key]++;
|
user.items[type][key]++;
|
||||||
|
if (user.markModified) user.markModified(`items.${type}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ module.exports = function changeClass (user, req = {}, analytics) {
|
|||||||
|
|
||||||
user.items.gear.owned[`weapon_${klass}_0`] = true;
|
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);
|
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],
|
user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
|
||||||
{[item.type]: `${item.type}_base_0`}
|
{[item.type]: `${item.type}_base_0`}
|
||||||
);
|
);
|
||||||
|
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
|
||||||
|
|
||||||
message = i18n.t('messageUnEquipped', {
|
message = i18n.t('messageUnEquipped', {
|
||||||
itemText: item.text(req.language),
|
itemText: item.text(req.language),
|
||||||
}, 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],
|
user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type],
|
||||||
{[item.type]: item.key}
|
{[item.type]: item.key}
|
||||||
);
|
);
|
||||||
|
if (user.markModified && type === 'owned') user.markModified('items.gear.owned');
|
||||||
|
|
||||||
message = handleTwoHanded(user, item, type, req);
|
message = handleTwoHanded(user, item, type, req);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ function evolve (user, pet, req) {
|
|||||||
user.items.pets[pet.key] = -1;
|
user.items.pets[pet.key] = -1;
|
||||||
user.items.mounts[pet.key] = true;
|
user.items.mounts[pet.key] = true;
|
||||||
|
|
||||||
|
if (user.markModified) {
|
||||||
|
user.markModified('items.pets');
|
||||||
|
user.markModified('items.mounts');
|
||||||
|
}
|
||||||
|
|
||||||
if (pet.key === user.items.currentPet) {
|
if (pet.key === user.items.currentPet) {
|
||||||
user.items.currentPet = '';
|
user.items.currentPet = '';
|
||||||
}
|
}
|
||||||
@@ -74,12 +79,15 @@ module.exports = function feed (user, req = {}) {
|
|||||||
message = i18n.t('messageDontEnjoyFood', messageParams, req.language);
|
message = i18n.t('messageDontEnjoyFood', messageParams, req.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.markModified) user.markModified('items.pets');
|
||||||
|
|
||||||
if (userPets[pet.key] >= 50 && !user.items.mounts[pet.key]) {
|
if (userPets[pet.key] >= 50 && !user.items.mounts[pet.key]) {
|
||||||
message = evolve(user, pet, req);
|
message = evolve(user, pet, req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
user.items.food[food.key]--;
|
user.items.food[food.key]--;
|
||||||
|
if (user.markModified) user.markModified('items.food');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
userPets[pet.key],
|
userPets[pet.key],
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ module.exports = function hatch (user, req = {}) {
|
|||||||
user.items.pets[pet] = 5;
|
user.items.pets[pet] = 5;
|
||||||
user.items.eggs[egg]--;
|
user.items.eggs[egg]--;
|
||||||
user.items.hatchingPotions[hatchingPotion]--;
|
user.items.hatchingPotions[hatchingPotion]--;
|
||||||
|
if (user.markModified) {
|
||||||
|
user.markModified('items.pets');
|
||||||
|
user.markModified('items.eggs');
|
||||||
|
user.markModified('items.hatchingPotions');
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
user.items,
|
user.items,
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
|
|||||||
item = cloneDeep(content.gear.flat[item]);
|
item = cloneDeep(content.gear.flat[item]);
|
||||||
user.items.gear.owned[item.key] = true;
|
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) {
|
if (analytics) {
|
||||||
analytics.track('open mystery item', {
|
analytics.track('open mystery item', {
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ function pathExistsInArray (array, path) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkForNullEntries (array) {
|
||||||
|
return array.filter(e => Boolean(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPinnedAreasForNullEntries (user) {
|
||||||
|
user.pinnedItems = checkForNullEntries(user.pinnedItems);
|
||||||
|
user.unpinnedItems = checkForNullEntries(user.unpinnedItems);
|
||||||
|
}
|
||||||
|
|
||||||
function selectGearToPin (user) {
|
function selectGearToPin (user) {
|
||||||
let changes = [];
|
let changes = [];
|
||||||
|
|
||||||
@@ -41,11 +50,10 @@ function selectGearToPin (user) {
|
|||||||
return sortBy(changes, (change) => sortOrder[change.type]);
|
return sortBy(changes, (change) => sortOrder[change.type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addPinnedGear (user, type, path) {
|
function addPinnedGear (user, type, path) {
|
||||||
const foundIndex = pathExistsInArray(user.pinnedItems, path);
|
const foundIndex = pathExistsInArray(user.pinnedItems, path);
|
||||||
|
|
||||||
if (foundIndex === -1) {
|
if (foundIndex === -1 && type && path) {
|
||||||
user.pinnedItems.push({
|
user.pinnedItems.push({
|
||||||
type,
|
type,
|
||||||
path,
|
path,
|
||||||
@@ -90,7 +98,10 @@ function removePinnedGearAddPossibleNewOnes (user, itemPath, newItemKey) {
|
|||||||
// an item of the users current "new" gear was bought
|
// an item of the users current "new" gear was bought
|
||||||
// remove the old pinned gear items and add the new gear back
|
// remove the old pinned gear items and add the new gear back
|
||||||
removePinnedGearByClass(user);
|
removePinnedGearByClass(user);
|
||||||
|
|
||||||
user.items.gear.owned[newItemKey] = true;
|
user.items.gear.owned[newItemKey] = true;
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
|
|
||||||
addPinnedGearByClass(user);
|
addPinnedGearByClass(user);
|
||||||
|
|
||||||
// update the version, so that vue can refresh the seasonal shop
|
// update the version, so that vue can refresh the seasonal shop
|
||||||
@@ -176,5 +187,6 @@ module.exports = {
|
|||||||
togglePinnedItem,
|
togglePinnedItem,
|
||||||
removeItemByPath,
|
removeItemByPath,
|
||||||
selectGearToPin,
|
selectGearToPin,
|
||||||
|
checkPinnedAreasForNullEntries,
|
||||||
isPinned,
|
isPinned,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ module.exports = function releaseBoth (user, req = {}) {
|
|||||||
user.items.pets[animal] = 0;
|
user.items.pets[animal] = 0;
|
||||||
user.items.mounts[animal] = null;
|
user.items.mounts[animal] = null;
|
||||||
}
|
}
|
||||||
|
if (user.markModified) {
|
||||||
|
user.markModified('items.pets');
|
||||||
|
user.markModified('items.mounts');
|
||||||
|
}
|
||||||
|
|
||||||
if (giveBeastMasterAchievement) {
|
if (giveBeastMasterAchievement) {
|
||||||
if (!user.achievements.beastMasterCount) {
|
if (!user.achievements.beastMasterCount) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
|
|||||||
}
|
}
|
||||||
user.items.mounts[mount] = null;
|
user.items.mounts[mount] = null;
|
||||||
}
|
}
|
||||||
|
if (user.markModified) user.markModified('items.mounts');
|
||||||
|
|
||||||
if (giveMountMasterAchievement) {
|
if (giveMountMasterAchievement) {
|
||||||
if (!user.achievements.mountMasterCount) {
|
if (!user.achievements.mountMasterCount) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ module.exports = function releasePets (user, req = {}, analytics) {
|
|||||||
}
|
}
|
||||||
user.items.pets[pet] = 0;
|
user.items.pets[pet] = 0;
|
||||||
}
|
}
|
||||||
|
if (user.markModified) user.markModified('items.pets');
|
||||||
|
|
||||||
if (giveBeastMasterAchievement) {
|
if (giveBeastMasterAchievement) {
|
||||||
if (!user.achievements.beastMasterCount) {
|
if (!user.achievements.beastMasterCount) {
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ module.exports = function revive (user, req = {}, analytics) {
|
|||||||
removePinnedGearByClass(user);
|
removePinnedGearByClass(user);
|
||||||
|
|
||||||
user.items.gear.owned[lostItem] = false;
|
user.items.gear.owned[lostItem] = false;
|
||||||
|
if (user.markModified) user.markModified('items.gear.owned');
|
||||||
|
|
||||||
addPinnedGearByClass(user);
|
addPinnedGearByClass(user);
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ module.exports = function sell (user, req = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.items[type][key] -= amount;
|
user.items[type][key] -= amount;
|
||||||
|
if (user.markModified) user.markModified(`items.${type}`);
|
||||||
|
|
||||||
user.stats.gp += content[type][key].value * amount;
|
user.stats.gp += content[type][key].value * amount;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ module.exports = function unlock (user, req = {}, analytics) {
|
|||||||
setWith(user, pathPart, true, Object);
|
setWith(user, pathPart, true, Object);
|
||||||
let itemName = pathPart.split('.').pop();
|
let itemName = pathPart.split('.').pop();
|
||||||
removeItemByPath(user, `gear.flat.${itemName}`);
|
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}}
|
// 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) {
|
if (path.indexOf('gear.') !== -1) {
|
||||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||||
setWith(user, path, true, Object);
|
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}}
|
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||||
setWith(user, `purchased.${path}`, true, Object);
|
setWith(user, `purchased.${path}`, true, Object);
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ api.updateUsername = {
|
|||||||
} else {
|
} else {
|
||||||
user.items.pets['Wolf-Veteran'] = 5;
|
user.items.pets['Wolf-Veteran'] = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.markModified('items.pets');
|
||||||
}
|
}
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ api.modifyInventory = {
|
|||||||
|
|
||||||
if (gear) {
|
if (gear) {
|
||||||
user.items.gear.owned = gear;
|
user.items.gear.owned = gear;
|
||||||
|
user.markModified('items.gear.owned');
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
@@ -148,6 +149,7 @@ api.modifyInventory = {
|
|||||||
].forEach((type) => {
|
].forEach((type) => {
|
||||||
if (req.body[type]) {
|
if (req.body[type]) {
|
||||||
user.items[type] = req.body[type];
|
user.items[type] = req.body[type];
|
||||||
|
user.markModified(`items.${type}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -595,6 +595,7 @@ api.joinGroup = {
|
|||||||
inviter.items.quests.basilist = 0;
|
inviter.items.quests.basilist = 0;
|
||||||
}
|
}
|
||||||
inviter.items.quests.basilist++;
|
inviter.items.quests.basilist++;
|
||||||
|
inviter.markModified('items.quests');
|
||||||
}
|
}
|
||||||
promises.push(inviter.save());
|
promises.push(inviter.save());
|
||||||
}
|
}
|
||||||
@@ -890,6 +891,7 @@ api.removeGroupMember = {
|
|||||||
|
|
||||||
if (group.quest && group.quest.active && group.quest.leader === member._id) {
|
if (group.quest && group.quest.active && group.quest.leader === member._id) {
|
||||||
member.items.quests[group.quest.key] += 1;
|
member.items.quests[group.quest.key] += 1;
|
||||||
|
member.markModified('items.quests');
|
||||||
}
|
}
|
||||||
} else if (isInvited) {
|
} else if (isInvited) {
|
||||||
if (isInvited === 'guild') {
|
if (isInvited === 'guild') {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import apiError from '../../libs/apiError';
|
import apiError from '../../libs/apiError';
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
|
import { validateItemPath } from '../../libs/items/utils';
|
||||||
|
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -264,10 +266,11 @@ api.updateHero = {
|
|||||||
if (updateData.purchased && updateData.purchased.ads) hero.purchased.ads = updateData.purchased.ads;
|
if (updateData.purchased && updateData.purchased.ads) hero.purchased.ads = updateData.purchased.ads;
|
||||||
|
|
||||||
// give them the Dragon Hydra pet if they're above level 6
|
// give them the Dragon Hydra pet if they're above level 6
|
||||||
if (hero.contributor.level >= 6) hero.items.pets['Dragon-Hydra'] = 5;
|
if (hero.contributor.level >= 6) {
|
||||||
if (updateData.itemPath && updateData.itemVal &&
|
hero.items.pets['Dragon-Hydra'] = 5;
|
||||||
updateData.itemPath.indexOf('items.') === 0 &&
|
hero.markModified('items.pets');
|
||||||
User.schema.paths[updateData.itemPath]) {
|
}
|
||||||
|
if (updateData.itemPath && updateData.itemVal && validateItemPath(updateData.itemPath)) {
|
||||||
_.set(hero, updateData.itemPath, updateData.itemVal); // Sanitization at 5c30944 (deemed unnecessary)
|
_.set(hero, updateData.itemPath, updateData.itemVal); // Sanitization at 5c30944 (deemed unnecessary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ let api = {};
|
|||||||
* @apiGroup Inbox
|
* @apiGroup Inbox
|
||||||
* @apiDescription Get inbox messages for a user
|
* @apiDescription Get inbox messages for a user
|
||||||
*
|
*
|
||||||
|
* @apiParam (Query) {Number} page Load the messages of the selected Page - 10 Messages per Page
|
||||||
|
*
|
||||||
* @apiSuccess {Array} data An array of inbox messages
|
* @apiSuccess {Array} data An array of inbox messages
|
||||||
*/
|
*/
|
||||||
api.getInboxMessages = {
|
api.getInboxMessages = {
|
||||||
@@ -19,8 +21,11 @@ api.getInboxMessages = {
|
|||||||
middlewares: [authWithHeaders()],
|
middlewares: [authWithHeaders()],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
const user = res.locals.user;
|
const user = res.locals.user;
|
||||||
|
const page = req.query.page;
|
||||||
|
|
||||||
const userInbox = await inboxLib.getUserInbox(user);
|
const userInbox = await inboxLib.getUserInbox(user, {
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
|
||||||
res.respond(200, userInbox);
|
res.respond(200, userInbox);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1421,7 +1421,7 @@ api.deleteMessage = {
|
|||||||
|
|
||||||
await inboxLib.deleteMessage(user, req.params.id);
|
await inboxLib.deleteMessage(user, req.params.id);
|
||||||
|
|
||||||
res.respond(200, ...[await inboxLib.getUserInbox(user, false)]);
|
res.respond(200, ...[await inboxLib.getUserInbox(user, {asArray: false})]);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ async function _getUserDataForExport (user, xmlMode = false) {
|
|||||||
userId: user._id,
|
userId: user._id,
|
||||||
}).exec(),
|
}).exec(),
|
||||||
|
|
||||||
inboxLib.getUserInbox(user, false),
|
inboxLib.getUserInbox(user, { asArray: false }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
userData.inbox.messages = messages;
|
userData.inbox.messages = messages;
|
||||||
|
|||||||
@@ -165,6 +165,8 @@ let bannedWords = [
|
|||||||
|
|
||||||
'heroin',
|
'heroin',
|
||||||
'cocaine',
|
'cocaine',
|
||||||
|
|
||||||
|
'pewdiepie',
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = bannedWords;
|
module.exports = bannedWords;
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
import { inboxModel as Inbox } from '../../models/message';
|
import { inboxModel as Inbox } from '../../models/message';
|
||||||
|
|
||||||
export async function getUserInbox (user, asArray = true) {
|
const PM_PER_PAGE = 10;
|
||||||
const messages = (await Inbox
|
|
||||||
.find({ownerId: user._id})
|
|
||||||
.sort({timestamp: -1})
|
|
||||||
.exec()).map(msg => msg.toJSON());
|
|
||||||
|
|
||||||
if (asArray) {
|
export async function getUserInbox (user, options = {asArray: true, page: 0}) {
|
||||||
|
if (typeof options.asArray === 'undefined') {
|
||||||
|
options.asArray = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let query = Inbox
|
||||||
|
.find({ownerId: user._id})
|
||||||
|
.sort({timestamp: -1});
|
||||||
|
|
||||||
|
if (typeof options.page !== 'undefined') {
|
||||||
|
query = query
|
||||||
|
.limit(PM_PER_PAGE)
|
||||||
|
.skip(PM_PER_PAGE * Number(options.page));
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = (await query.exec()).map(msg => msg.toJSON());
|
||||||
|
|
||||||
|
if (options.asArray) {
|
||||||
return messages;
|
return messages;
|
||||||
} else {
|
} else {
|
||||||
const messagesObj = {};
|
const messagesObj = {};
|
||||||
|
|||||||
57
website/server/libs/items/utils.js
Normal file
57
website/server/libs/items/utils.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import shared from '../../../common';
|
||||||
|
import { model as User } from '../../models/user';
|
||||||
|
import { last } from 'lodash';
|
||||||
|
|
||||||
|
// Build a list of gear items owned by default
|
||||||
|
const defaultOwnedGear = {};
|
||||||
|
|
||||||
|
Object.keys(shared.content.gear.flat).forEach(key => {
|
||||||
|
const item = shared.content.gear.flat[key];
|
||||||
|
if (item.key.match(/(armor|head|shield)_warrior_0/) || item.gearSet === 'glasses' || item.gearSet === 'headband') {
|
||||||
|
defaultOwnedGear[item.key] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getDefaultOwnedGear () {
|
||||||
|
// Clone to avoid modifications to the original object
|
||||||
|
return Object.assign({}, defaultOwnedGear);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When passed a path to an item in the user object it'll return true if
|
||||||
|
// it's valid, false otherwsie
|
||||||
|
// Example of an item path: `items.gear.owned.head_warrior_0`
|
||||||
|
export function validateItemPath (itemPath) {
|
||||||
|
// The item path must start with `items.`
|
||||||
|
if (itemPath.indexOf('items.') !== 0) return false;
|
||||||
|
if (User.schema.paths[itemPath]) return true;
|
||||||
|
|
||||||
|
const key = last(itemPath.split('.'));
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.gear.owned') === 0) {
|
||||||
|
return Boolean(shared.content.gear.flat[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.pets') === 0) {
|
||||||
|
return Boolean(shared.content.petInfo[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.eggs') === 0) {
|
||||||
|
return Boolean(shared.content.eggs[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.hatchingPotions') === 0) {
|
||||||
|
return Boolean(shared.content.hatchingPotions[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.food') === 0) {
|
||||||
|
return Boolean(shared.content.food[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.mounts') === 0) {
|
||||||
|
return Boolean(shared.content.mountInfo[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPath.indexOf('items.quests') === 0) {
|
||||||
|
return Boolean(shared.content.quests[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -170,6 +170,7 @@ async function addSubToGroupUser (member, group) {
|
|||||||
|
|
||||||
member.purchased.plan = plan;
|
member.purchased.plan = plan;
|
||||||
member.items.mounts['Jackalope-RoyalPurple'] = true;
|
member.items.mounts['Jackalope-RoyalPurple'] = true;
|
||||||
|
member.markModified('items.mounts');
|
||||||
|
|
||||||
data.user = member;
|
data.user = member;
|
||||||
await this.createSubscription(data);
|
await this.createSubscription(data);
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ async function createSubscription (data) {
|
|||||||
|
|
||||||
if (recipient !== group) {
|
if (recipient !== group) {
|
||||||
recipient.items.pets['Jackalope-RoyalPurple'] = 5;
|
recipient.items.pets['Jackalope-RoyalPurple'] = 5;
|
||||||
|
recipient.markModified('items.pets');
|
||||||
revealMysteryItems(recipient);
|
revealMysteryItems(recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function sendNotification (user, details = {}) {
|
|||||||
|
|
||||||
fcmSender.send(message, {
|
fcmSender.send(message, {
|
||||||
registrationTokens: [pushDevice.regId],
|
registrationTokens: [pushDevice.regId],
|
||||||
}, 10, (err) => logger.error('FCM Error', err));
|
}, 10, (err) => logger.error(err, 'FCM Error'));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ schema.statics.apply = async function applyCoupon (user, req, code) {
|
|||||||
user.items.gear.owned.body_special_wondercon_red = true;
|
user.items.gear.owned.body_special_wondercon_red = true;
|
||||||
user.items.gear.owned.body_special_wondercon_black = true;
|
user.items.gear.owned.body_special_wondercon_black = true;
|
||||||
user.items.gear.owned.body_special_wondercon_gold = true;
|
user.items.gear.owned.body_special_wondercon_gold = true;
|
||||||
|
user.markModified('items.gear.owned');
|
||||||
|
|
||||||
user.extra = {signupEvent: 'wondercon'};
|
user.extra = {signupEvent: 'wondercon'};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,8 @@ function _setUpNewUser (user) {
|
|||||||
let iterableFlags = user.flags.toObject();
|
let iterableFlags = user.flags.toObject();
|
||||||
|
|
||||||
user.items.quests.dustbunnies = 1;
|
user.items.quests.dustbunnies = 1;
|
||||||
|
user.markModified('items.quests');
|
||||||
|
|
||||||
user.purchased.background.violet = true;
|
user.purchased.background.violet = true;
|
||||||
user.preferences.background = 'violet';
|
user.preferences.background = 'violet';
|
||||||
|
|
||||||
@@ -217,6 +219,7 @@ schema.pre('save', true, function preSaveUser (next, done) {
|
|||||||
// automatically granted an item during a certain time period:
|
// automatically granted an item during a certain time period:
|
||||||
// if (!this.items.pets['JackOLantern-Base'] && moment().isBefore('2014-11-01'))
|
// if (!this.items.pets['JackOLantern-Base'] && moment().isBefore('2014-11-01'))
|
||||||
// this.items.pets['JackOLantern-Base'] = 5;
|
// this.items.pets['JackOLantern-Base'] = 5;
|
||||||
|
// this.markModified('items.pets');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter notifications, remove unvalid and not necessary, handle the ones that have special requirements
|
// Filter notifications, remove unvalid and not necessary, handle the ones that have special requirements
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ schema.methods.toJSONWithInbox = async function userToJSONWithInbox () {
|
|||||||
const toJSON = user.toJSON();
|
const toJSON = user.toJSON();
|
||||||
|
|
||||||
if (toJSON.inbox) {
|
if (toJSON.inbox) {
|
||||||
toJSON.inbox.messages = await inboxLib.getUserInbox(user, false);
|
toJSON.inbox.messages = await inboxLib.getUserInbox(user, {asArray: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
return toJSON;
|
return toJSON;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import shared from '../../../common';
|
import shared from '../../../common';
|
||||||
import _ from 'lodash';
|
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
import { schema as TagSchema } from '../tag';
|
import { schema as TagSchema } from '../tag';
|
||||||
import { schema as PushDeviceSchema } from '../pushDevice';
|
import { schema as PushDeviceSchema } from '../pushDevice';
|
||||||
@@ -11,6 +10,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
schema as SubscriptionPlanSchema,
|
schema as SubscriptionPlanSchema,
|
||||||
} from '../subscriptionPlan';
|
} from '../subscriptionPlan';
|
||||||
|
import {
|
||||||
|
getDefaultOwnedGear,
|
||||||
|
} from '../../libs/items/utils';
|
||||||
|
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
@@ -251,12 +253,12 @@ let schema = new Schema({
|
|||||||
|
|
||||||
items: {
|
items: {
|
||||||
gear: {
|
gear: {
|
||||||
owned: _.transform(shared.content.gear.flat, (m, v) => {
|
owned: {
|
||||||
m[v.key] = {$type: Boolean};
|
$type: Schema.Types.Mixed,
|
||||||
if (v.key.match(/(armor|head|shield)_warrior_0/) || v.gearSet === 'glasses' || v.gearSet === 'headband') {
|
default: () => {
|
||||||
m[v.key].default = true;
|
return getDefaultOwnedGear();
|
||||||
}
|
},
|
||||||
}),
|
},
|
||||||
|
|
||||||
equipped: {
|
equipped: {
|
||||||
weapon: String,
|
weapon: String,
|
||||||
@@ -310,56 +312,52 @@ let schema = new Schema({
|
|||||||
// 'PandaCub-Red': 10, // Number represents "Growth Points"
|
// 'PandaCub-Red': 10, // Number represents "Growth Points"
|
||||||
// etc...
|
// etc...
|
||||||
// }
|
// }
|
||||||
pets: _.defaults(
|
pets: {$type: Schema.Types.Mixed, default: () => {
|
||||||
// First transform to a 1D eggs/potions mapping
|
return {};
|
||||||
_.transform(shared.content.pets, (m, v, k) => m[k] = Number),
|
}},
|
||||||
// Then add additional pets (quest, backer, contributor, premium)
|
|
||||||
_.transform(shared.content.questPets, (m, v, k) => m[k] = Number),
|
|
||||||
_.transform(shared.content.specialPets, (m, v, k) => m[k] = Number),
|
|
||||||
_.transform(shared.content.premiumPets, (m, v, k) => m[k] = Number),
|
|
||||||
_.transform(shared.content.wackyPets, (m, v, k) => m[k] = Number)
|
|
||||||
),
|
|
||||||
currentPet: String, // Cactus-Desert
|
currentPet: String, // Cactus-Desert
|
||||||
|
|
||||||
// eggs: {
|
// eggs: {
|
||||||
// 'PandaCub': 0, // 0 indicates "doesn't own"
|
// 'PandaCub': 0, // 0 indicates "doesn't own"
|
||||||
// 'Wolf': 5 // Number indicates "stacking"
|
// 'Wolf': 5 // Number indicates "stacking"
|
||||||
// }
|
// }
|
||||||
eggs: _.transform(shared.content.eggs, (m, v, k) => m[k] = Number),
|
eggs: {$type: Schema.Types.Mixed, default: () => {
|
||||||
|
return {};
|
||||||
|
}},
|
||||||
|
|
||||||
// hatchingPotions: {
|
// hatchingPotions: {
|
||||||
// 'Desert': 0, // 0 indicates "doesn't own"
|
// 'Desert': 0, // 0 indicates "doesn't own"
|
||||||
// 'CottonCandyBlue': 5 // Number indicates "stacking"
|
// 'CottonCandyBlue': 5 // Number indicates "stacking"
|
||||||
// }
|
// }
|
||||||
hatchingPotions: _.transform(shared.content.hatchingPotions, (m, v, k) => m[k] = Number),
|
hatchingPotions: {$type: Schema.Types.Mixed, default: () => {
|
||||||
|
return {};
|
||||||
|
}},
|
||||||
|
|
||||||
// Food: {
|
// Food: {
|
||||||
// 'Watermelon': 0, // 0 indicates "doesn't own"
|
// 'Watermelon': 0, // 0 indicates "doesn't own"
|
||||||
// 'RottenMeat': 5 // Number indicates "stacking"
|
// 'RottenMeat': 5 // Number indicates "stacking"
|
||||||
// }
|
// }
|
||||||
food: _.transform(shared.content.food, (m, v, k) => m[k] = Number),
|
food: {$type: Schema.Types.Mixed, default: () => {
|
||||||
|
return {};
|
||||||
|
}},
|
||||||
|
|
||||||
// mounts: {
|
// mounts: {
|
||||||
// 'Wolf-Desert': true,
|
// 'Wolf-Desert': true,
|
||||||
// 'PandaCub-Red': false,
|
// 'PandaCub-Red': false,
|
||||||
// etc...
|
// etc...
|
||||||
// }
|
// }
|
||||||
mounts: _.defaults(
|
mounts: {$type: Schema.Types.Mixed, default: () => {
|
||||||
// First transform to a 1D eggs/potions mapping
|
return {};
|
||||||
_.transform(shared.content.pets, (m, v, k) => m[k] = Boolean),
|
}},
|
||||||
// Then add quest and premium pets
|
|
||||||
_.transform(shared.content.questPets, (m, v, k) => m[k] = Boolean),
|
|
||||||
_.transform(shared.content.premiumPets, (m, v, k) => m[k] = Boolean),
|
|
||||||
// Then add additional mounts (backer, contributor)
|
|
||||||
_.transform(shared.content.specialMounts, (m, v, k) => m[k] = Boolean)
|
|
||||||
),
|
|
||||||
currentMount: String,
|
currentMount: String,
|
||||||
|
|
||||||
// Quests: {
|
// Quests: {
|
||||||
// 'boss_0': 0, // 0 indicates "doesn't own"
|
// 'boss_0': 0, // 0 indicates "doesn't own"
|
||||||
// 'collection_honey': 5 // Number indicates "stacking"
|
// 'collection_honey': 5 // Number indicates "stacking"
|
||||||
// }
|
// }
|
||||||
quests: _.transform(shared.content.quests, (m, v, k) => m[k] = Number),
|
quests: {$type: Schema.Types.Mixed, default: () => {
|
||||||
|
return {};
|
||||||
|
}},
|
||||||
|
|
||||||
lastDrop: {
|
lastDrop: {
|
||||||
date: {$type: Date, default: Date.now},
|
date: {$type: Date, default: Date.now},
|
||||||
|
|||||||
Reference in New Issue
Block a user