Merge branch 'api-v3' into api-v3-client

This commit is contained in:
Matteo Pagliazzi
2016-05-11 16:01:54 +02:00
194 changed files with 19205 additions and 20873 deletions

View File

@@ -1,4 +1,9 @@
{
"presets": ["es2015"],
"plugins": ["syntax-async-functions","transform-regenerator"]
"plugins": [
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
}

View File

@@ -20,9 +20,9 @@ website/src/routes/payments.js
website/src/routes/pages.js
website/src/middlewares/apiThrottle.js
website/src/middlewares/forceRefresh.js
website/src/controllers/payments/
debug-scripts/*
scripts/*
tasks/*.js
gulpfile.js
Gruntfile.js
@@ -30,7 +30,6 @@ newrelic.js
test/api-legacy/**/*
test/common/simulations/**/*
test/common_old/
test/content/**/*
test/server_side/**/*
test/spec/**/*

View File

@@ -2,5 +2,8 @@
"extends": [
"habitrpg/server",
"habitrpg/babel"
]
],
"globals": {
"Promise": true
}
}

View File

@@ -1,9 +1,9 @@
/* Comment out for holiday events */
/* .npc_ian {
.npc_ian {
background: url("/common/img/sprites/npc_ian.gif") no-repeat;
width: 78px;
height: 135px;
} */
}
.quest_burnout {
background: url("/common/img/sprites/quest_burnout.gif") no-repeat;

View File

@@ -1,46 +1,52 @@
.2014_Fall_HealerPROMO2 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -842px -1203px;
background-position: -825px -423px;
width: 90px;
height: 90px;
}
.2014_Fall_Mage_PROMO9 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -813px -569px;
background-position: -1466px -1139px;
width: 120px;
height: 90px;
}
.2014_Fall_RoguePROMO3 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -977px -1112px;
background-position: -1096px -851px;
width: 105px;
height: 90px;
}
.2014_Fall_Warrior_PROMO {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -91px -1295px;
background-position: -669px -1157px;
width: 90px;
height: 90px;
}
.promo_android {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -593px -241px;
background-position: -1096px -508px;
width: 175px;
height: 175px;
}
.promo_backgrounds_armoire_201602 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -306px -220px;
background-position: -954px 0px;
width: 141px;
height: 294px;
}
.promo_backgrounds_armoire_201603 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -813px 0px;
background-position: -306px -220px;
width: 141px;
height: 294px;
}
.promo_backgrounds_armoire_201604 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -593px 0px;
width: 140px;
height: 441px;
}
.promo_backgrounds_armoire_201605 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -452px 0px;
width: 140px;
@@ -48,19 +54,25 @@
}
.promo_backtoschool {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -148px;
background-position: -1343px -251px;
width: 150px;
height: 150px;
}
.promo_burnout {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -593px 0px;
background-position: -734px 0px;
width: 219px;
height: 240px;
}
.promo_chairs_glasses {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -954px -569px;
width: 51px;
height: 210px;
}
.promo_classes_fall_2014 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -326px -912px;
background-position: -326px -957px;
width: 321px;
height: 100px;
}
@@ -72,13 +84,13 @@
}
.promo_dilatoryDistress {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -569px -1203px;
background-position: -734px -332px;
width: 90px;
height: 90px;
}
.promo_egg_mounts {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px 0px;
background-position: 0px -809px;
width: 280px;
height: 147px;
}
@@ -90,43 +102,43 @@
}
.promo_enchanted_armoire_201507 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -578px -1112px;
background-position: -1343px -789px;
width: 217px;
height: 90px;
}
.promo_enchanted_armoire_201508 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -796px -1112px;
background-position: -1343px -972px;
width: 180px;
height: 90px;
}
.promo_enchanted_armoire_201509 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -751px -1203px;
background-position: -825px -332px;
width: 90px;
height: 90px;
}
.promo_enchanted_armoire_201511 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -915px;
background-position: -1343px -1139px;
width: 122px;
height: 90px;
}
.promo_enchanted_armoire_201601 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1115px -1203px;
background-position: -861px -525px;
width: 90px;
height: 90px;
}
.promo_floral_potions {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -813px -295px;
background-position: -954px -295px;
width: 105px;
height: 273px;
}
.promo_habitica {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px -480px;
background-position: -1096px -332px;
width: 175px;
height: 175px;
}
@@ -138,241 +150,241 @@
}
.promo_haunted_hair {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -595px;
background-position: -1484px -402px;
width: 100px;
height: 137px;
}
.promo_item_notif {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px -656px;
background-position: -1343px 0px;
width: 249px;
height: 102px;
}
.promo_mystery_201405 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -364px -1295px;
background-position: -760px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201406 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -1295px;
background-position: -1494px -251px;
width: 90px;
height: 96px;
}
.promo_mystery_201407 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -769px -241px;
background-position: -1243px -684px;
width: 42px;
height: 62px;
}
.promo_mystery_201408 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -513px -442px;
background-position: -1272px -332px;
width: 60px;
height: 71px;
}
.promo_mystery_201409 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -933px -1203px;
background-position: -770px -525px;
width: 90px;
height: 90px;
}
.promo_mystery_201410 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1131px -586px;
background-position: -1496px -1063px;
width: 72px;
height: 63px;
}
.promo_mystery_201411 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1297px -1203px;
background-position: -1005px -809px;
width: 90px;
height: 90px;
}
.promo_mystery_201412 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1342px -809px;
background-position: -1272px -578px;
width: 42px;
height: 66px;
}
.promo_mystery_201501 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1337px -595px;
background-position: -1542px -880px;
width: 48px;
height: 63px;
}
.promo_mystery_201502 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -387px -1203px;
background-position: -1033px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201503 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -478px -1203px;
background-position: -1124px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201504 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -646px -621px;
background-position: -1272px -404px;
width: 60px;
height: 69px;
}
.promo_mystery_201505 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -660px -1203px;
background-position: -734px -423px;
width: 90px;
height: 90px;
}
.promo_mystery_201506 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1337px -659px;
background-position: -1272px -508px;
width: 42px;
height: 69px;
}
.promo_mystery_201507 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1131px -480px;
background-position: -1500px -103px;
width: 90px;
height: 105px;
}
.promo_mystery_201508 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -293px -1203px;
background-position: -828px -241px;
width: 93px;
height: 90px;
}
.promo_mystery_201509 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1024px -1203px;
background-position: -808px -706px;
width: 90px;
height: 90px;
}
.promo_mystery_201510 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -199px -1203px;
background-position: -734px -241px;
width: 93px;
height: 90px;
}
.promo_mystery_201511 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1206px -1203px;
background-position: -578px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201512 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -452px -442px;
background-position: -1524px -972px;
width: 60px;
height: 81px;
}
.promo_mystery_201601 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -1082px;
background-position: -1096px -760px;
width: 120px;
height: 90px;
}
.promo_mystery_201602 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -182px -1295px;
background-position: -851px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201603 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -273px -1295px;
background-position: -942px -1157px;
width: 90px;
height: 90px;
}
.promo_mystery_201604 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1083px -1112px;
background-position: -1202px -851px;
width: 93px;
height: 90px;
}
.promo_mystery_3014 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -593px -417px;
background-position: -1343px -698px;
width: 217px;
height: 90px;
}
.promo_orca {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -809px;
background-position: -1484px -550px;
width: 105px;
height: 105px;
}
.promo_partyhats {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px -759px;
background-position: -593px -442px;
width: 115px;
height: 47px;
}
.promo_pastel_skin {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -648px -912px;
background-position: -648px -957px;
width: 330px;
height: 83px;
}
.customize-option.promo_pastel_skin {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -673px -927px;
background-position: -673px -972px;
width: 60px;
height: 60px;
}
.promo_peppermint_flame {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -447px;
background-position: -1343px -550px;
width: 140px;
height: 147px;
}
.promo_pet_skins {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -299px;
background-position: -1343px -402px;
width: 140px;
height: 147px;
}
.customize-option.promo_pet_skins {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1261px -314px;
background-position: -1368px -417px;
width: 60px;
height: 60px;
}
.promo_shimmer_hair {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -724px -809px;
background-position: -979px -957px;
width: 330px;
height: 83px;
}
.promo_splashyskins {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -1203px;
background-position: -1343px -880px;
width: 198px;
height: 91px;
}
.customize-option.promo_splashyskins {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -25px -1218px;
background-position: -1368px -895px;
width: 60px;
height: 60px;
}
.promo_spring_classes_2016 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -809px;
background-position: -281px -809px;
width: 362px;
height: 102px;
}
.promo_springclasses2014 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -1112px;
background-position: 0px -1157px;
width: 288px;
height: 90px;
}
.promo_springclasses2015 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -289px -1112px;
background-position: -289px -1157px;
width: 288px;
height: 90px;
}
@@ -384,37 +396,37 @@
}
.promo_summer_classes_2015 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -1023px;
background-position: 0px -1068px;
width: 300px;
height: 88px;
}
.promo_updos {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px 0px;
background-position: -1343px -103px;
width: 156px;
height: 147px;
}
.promo_veteran_pets {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -1006px;
background-position: -1096px -684px;
width: 146px;
height: 75px;
}
.promo_winter_classes_2016 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -363px -809px;
background-position: -644px -809px;
width: 360px;
height: 90px;
}
.promo_winterclasses2015 {
background-image: url(spritesmith-largeSprites-0.png);
background-position: 0px -912px;
background-position: 0px -957px;
width: 325px;
height: 110px;
}
.promo_winteryhair {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -1236px -733px;
background-position: -1343px -1063px;
width: 152px;
height: 75px;
}
@@ -426,7 +438,7 @@
}
.npc_viirus {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -813px -660px;
background-position: -1217px -760px;
width: 108px;
height: 90px;
}
@@ -438,7 +450,7 @@
}
.welcome_basic_avatars {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px -148px;
background-position: -1096px 0px;
width: 246px;
height: 165px;
}
@@ -450,7 +462,7 @@
}
.welcome_sample_tasks {
background-image: url(spritesmith-largeSprites-0.png);
background-position: -955px -314px;
background-position: -1096px -166px;
width: 246px;
height: 165px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 285 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

After

Width:  |  Height:  |  Size: 312 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 146 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 153 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 99 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 129 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 134 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 KiB

After

Width:  |  Height:  |  Size: 255 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 KiB

After

Width:  |  Height:  |  Size: 286 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 145 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 148 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1,5 +1,6 @@
{
"missingAuthHeaders": "Missing authentication headers.",
"missingAuthParams": "Missing authentication parameters.",
"missingUsernameEmail": "Missing username or email.",
"missingEmail": "Missing email.",
"missingUsername": "Missing username.",
@@ -100,6 +101,8 @@
"noAdminAccess": "You don't have admin access.",
"pageMustBeNumber": "req.query.page must be a number",
"missingUnsubscriptionCode": "Missing unsubscription code.",
"missingSubscription": "User does not have a plan subscription",
"missingSubscriptionCode": "Missing subscription code. Possible values: basic_earned, basic_3mo, basic_6mo, google_6mo, basic_12mo.",
"userNotFound": "User not found.",
"spellNotFound": "Spell \"<%= spellId %>\" not found.",
"partyNotFound": "Party not found",
@@ -172,5 +175,8 @@
"resetComplete": "Reset completed",
"lvl10ChangeClass": "To change class you must be at least level 10.",
"equipmentAlreadyOwned": "You already own that piece of equipment",
"pmsMarkedRead": "Your private messages have been marked as read"
"pmsMarkedRead": "Your private messages have been marked as read",
"paymentNotSuccessful": "The payment was not successful",
"planNotActive": "The plan hasn't activated yet (due to a PayPal bug). It will begin <%= nextBillingDate %>, after which you can cancel to retain your full benefits",
"cancelingSubscription": "Canceling the subscription"
}

View File

@@ -183,6 +183,13 @@
"backgroundGiantFlowersText": "Giant Flowers",
"backgroundGiantFlowersNotes": "Frolic atop Giant Flowers.",
"backgroundRainbowsEndText": "End of the Rainbow",
"backgroundRainbowsEndNotes": "Discover gold at the End of the Rainbow."
}
"backgroundRainbowsEndNotes": "Discover gold at the End of the Rainbow.",
"backgrounds052016": "SET 24: Released May 2016",
"backgroundBeehiveText": "Beehive",
"backgroundBeehiveNotes": "Buzz and dance in a Beehive.",
"backgroundGazeboText": "Gazebo",
"backgroundGazeboNotes": "Battle a Gazebo.",
"backgroundTreeRootsText": "Tree Roots",
"backgroundTreeRootsNotes": "Explore the Tree Roots."
}

View File

@@ -208,6 +208,8 @@
"weaponArmoireMiningPickaxNotes": "Mine the maximum amount of gold from your tasks! Increases Perception by <%= per %>. Enchanted Armoire: Miner Set (Item 3 of 3).",
"weaponArmoireBasicLongbowText": "Basic Longbow",
"weaponArmoireBasicLongbowNotes": "A serviceable hand-me-down bow. Increases Strength by <%= str %>. Enchanted Armoire: Basic Archer Set (Item 1 of 3).",
"weaponArmoireHabiticanDiplomaText": "Habitican Diploma",
"weaponArmoireHabiticanDiplomaNotes": "A certificate of significant achievement -- well done! Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 1 of 3).",
"armor": "armor",
@@ -435,6 +437,8 @@
"armorArmoireMinerOverallsNotes": "They may seem worn, but they are enchanted to repel dirt. Increases Constitution by <%= con %>. Enchanted Armoire: Miner Set (Item 2 of 3).",
"armorArmoireBasicArcherArmorText": "Basic Archer Armor",
"armorArmoireBasicArcherArmorNotes": "This camouflaged vest lets you slip unnoticed through the forests. Increases Perception by <%= per %>. Enchanted Armoire: Basic Archer Set (Item 2 of 3).",
"armorArmoireGraduateRobeText": "Graduate Robe",
"armorArmoireGraduateRobeNotes": "Congratulations! This weighty robe hangs heavy with all the knowledge you have accrued. Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 2 of 3).",
"headgear": "headgear",
@@ -676,6 +680,8 @@
"headArmoireMinerHelmetNotes": "Protect your head from falling tasks! Increases Intelligence by <%= int %>. Enchanted Armoire: Miner Set (Item 1 of 3).",
"headArmoireBasicArcherCapText": "Basic Archer Cap",
"headArmoireBasicArcherCapNotes": "No archer would be complete without a jaunty cap! Increases Perception by <%= per %>. Enchanted Armoire: Basic Archer Set (Item 3 of 3).",
"headArmoireGraduateCapText": "Graduate Cap",
"headArmoireGraduateCapNotes": "Congratulations! Your deep thoughts have earned you this thinking cap. Increases Intelligence by <%= int %>. Enchanted Armoire: Graduate Set (Item 3 of 3).",
"offhand": "shield-hand item",
@@ -748,7 +754,7 @@
"shieldSpecialWinter2015HealerNotes": "This shield deflects the freezing wind. Increases Constitution by <%= con %>. Limited Edition 2014-2015 Winter Gear.",
"shieldSpecialSpring2015RogueText": "Exploding Squeak",
"shieldSpecialSpring2015RogueNotes": "Don't let the sound fool you - these explosives pack a punch. Increases Strength <%= str %>. Limited Edition 2015 Spring Gear.",
"shieldSpecialSpring2015RogueNotes": "Don't let the sound fool you - these explosives pack a punch. Increases Strength by <%= str %>. Limited Edition 2015 Spring Gear.",
"shieldSpecialSpring2015WarriorText": "Dish Discus",
"shieldSpecialSpring2015WarriorNotes": "Hurl it at your enemies.... or just hold it, because it will fill up with yummy kibble at dinnertime. Increases Constitution by <%= con %>. Limited Edition 2015 Spring Gear.",
"shieldSpecialSpring2015HealerText": "Patterned Pillow",
@@ -797,6 +803,8 @@
"shieldArmoireDragonTamerShieldNotes": "Distract enemies with this dragon-shaped shield. Increases Perception by <%= per %>. Enchanted Armoire: Dragon Tamer Set (Item 2 of 3).",
"shieldArmoireMysticLampText": "Mystic Lamp",
"shieldArmoireMysticLampNotes": "Light the darkest caves with this mystic lamp! Increases Perception by <%= per %>. Enchanted Armoire: Independent Item.",
"shieldArmoireFloralBouquetText": "Bouquet o' Flowers",
"shieldArmoireFloralBouquetNotes": "Not much help in battle, but aren't they beautiful? Increases Constitution by <%= con %>. Enchanted Armoire: Independent Item.",
"back": "Back Accessory",
"backBase0Text": "No Back Accessory",
@@ -918,6 +926,21 @@
"eyewearBase0Text": "No Eyewear",
"eyewearBase0Notes": "No Eyewear.",
"eyewearSpecialBlackTopFrameText": "Black Standard Eyeglasses",
"eyewearSpecialBlackTopFrameNotes": "Glasses with a black frame above the lenses. Confers no benefit.",
"eyewearSpecialBlueTopFrameText": "Blue Standard Eyeglasses",
"eyewearSpecialBlueTopFrameNotes": "Glasses with a blue frame above the lenses. Confers no benefit.",
"eyewearSpecialGreenTopFrameText": "Green Standard Eyeglasses",
"eyewearSpecialGreenTopFrameNotes": "Glasses with a green frame above the lenses. Confers no benefit.",
"eyewearSpecialPinkTopFrameText": "Pink Standard Eyeglasses",
"eyewearSpecialPinkTopFrameNotes": "Glasses with a pink frame above the lenses. Confers no benefit.",
"eyewearSpecialRedTopFrameText": "Red Standard Eyeglasses",
"eyewearSpecialRedTopFrameNotes": "Glasses with a red frame above the lenses. Confers no benefit.",
"eyewearSpecialWhiteTopFrameText": "White Standard Eyeglasses",
"eyewearSpecialWhiteTopFrameNotes": "Glasses with a white frame above the lenses. Confers no benefit.",
"eyewearSpecialYellowTopFrameText": "Yellow Standard Eyeglasses",
"eyewearSpecialYellowTopFrameNotes": "Glasses with a yellow frame above the lenses. Confers no benefit.",
"eyewearSpecialSummerRogueText": "Roguish Eyepatch",
"eyewearSpecialSummerRogueNotes": "It doesn't take a scallywag to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
"eyewearSpecialSummerWarriorText": "Dashing Eyepatch",

View File

@@ -325,6 +325,20 @@ let backgrounds = {
notes: t('backgroundRainbowsEndNotes'),
},
},
backgrounds052016: {
beehive: {
text: t('backgroundBeehiveText'),
notes: t('backgroundBeehiveNotes'),
},
gazebo: {
text: t('backgroundGazeboText'),
notes: t('backgroundGazeboNotes'),
},
tree_roots: {
text: t('backgroundTreeRootsText'),
notes: t('backgroundTreeRootsNotes'),
},
},
};
/* eslint-enable quote-props */

View File

@@ -3,4 +3,9 @@ import prefill from './prefill.js';
export default prefill({
none: {},
black: {},
blue: {},
green: {},
pink: {},
red: {},
yellow: {},
});

View File

@@ -126,6 +126,14 @@ let armor = {
set: 'basicArcher',
canOwn: ownsItem('armor_armoire_basicArcherArmor'),
},
graduateRobe: {
text: t('armorArmoireGraduateRobeText'),
notes: t('armorArmoireGraduateRobeNotes', { int: 10 }),
value: 100,
int: 10,
set: 'graduate',
canOwn: ownsItem('armor_armoire_graduateRobe'),
},
};
let eyewear = {
@@ -330,6 +338,14 @@ let head = {
set: 'basicArcher',
canOwn: ownsItem('head_armoire_basicArcherCap'),
},
graduateCap: {
text: t('headArmoireGraduateCapText'),
notes: t('headArmoireGraduateCapNotes', { int: 9 }),
value: 100,
int: 9,
set: 'graduate',
canOwn: ownsItem('head_armoire_graduateCap'),
},
};
let shield = {
@@ -375,6 +391,13 @@ let shield = {
per: 15,
canOwn: ownsItem('shield_armoire_mysticLamp'),
},
floralBouquet: {
text: t('shieldArmoireFloralBouquetText'),
notes: t('shieldArmoireFloralBouquetNotes', { con: 3 }),
value: 100,
con: 3,
canOwn: ownsItem('shield_armoire_floralBouquet'),
},
};
let headAccessory = {
@@ -521,6 +544,14 @@ let weapon = {
set: 'basicArcher',
canOwn: ownsItem('weapon_armoire_basicLongbow'),
},
habiticanDiploma: {
text: t('weaponArmoireHabiticanDiplomaText'),
notes: t('weaponArmoireHabiticanDiplomaNotes', { int: 11 }),
value: 100,
int: 11,
set: 'graduate',
canOwn: ownsItem('weapon_armoire_habiticanDiploma'),
},
};
let armoireSet = {

View File

@@ -62,9 +62,6 @@ let armor = {
notes: t('armorSpecialSpringRogueNotes', { per: 15 }),
value: 90,
per: 15,
canBuy: () => {
return true;
},
},
springWarrior: {
event: EVENTS.spring,
@@ -73,9 +70,6 @@ let armor = {
notes: t('armorSpecialSpringWarriorNotes', { con: 9 }),
value: 90,
con: 9,
canBuy: () => {
return true;
},
},
springMage: {
event: EVENTS.spring,
@@ -84,9 +78,6 @@ let armor = {
notes: t('armorSpecialSpringMageNotes', { int: 9 }),
value: 90,
int: 9,
canBuy: () => {
return true;
},
},
springHealer: {
event: EVENTS.spring,
@@ -95,9 +86,6 @@ let armor = {
notes: t('armorSpecialSpringHealerNotes', { con: 15 }),
value: 90,
con: 15,
canBuy: () => {
return true;
},
},
summerRogue: {
event: EVENTS.summer,
@@ -208,9 +196,6 @@ let armor = {
notes: t('armorSpecialSpring2015RogueNotes', { per: 15 }),
value: 90,
per: 15,
canBuy: () => {
return true;
},
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -219,9 +204,6 @@ let armor = {
notes: t('armorSpecialSpring2015WarriorNotes', { con: 9 }),
value: 90,
con: 9,
canBuy: () => {
return true;
},
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -230,9 +212,6 @@ let armor = {
notes: t('armorSpecialSpring2015MageNotes', { int: 9 }),
value: 90,
int: 9,
canBuy: () => {
return true;
},
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -241,9 +220,6 @@ let armor = {
notes: t('armorSpecialSpring2015HealerNotes', { con: 15 }),
value: 90,
con: 15,
canBuy: () => {
return true;
},
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -457,6 +433,48 @@ let eyewear = {
notes: t('eyewearSpecialSummerWarriorNotes'),
value: 20,
},
blackTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialBlackTopFrameText'),
notes: t('eyewearSpecialBlackTopFrameNotes'),
value: 0,
},
blueTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialBlueTopFrameText'),
notes: t('eyewearSpecialBlueTopFrameNotes'),
value: 0,
},
greenTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialGreenTopFrameText'),
notes: t('eyewearSpecialGreenTopFrameNotes'),
value: 0,
},
pinkTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialPinkTopFrameText'),
notes: t('eyewearSpecialPinkTopFrameNotes'),
value: 0,
},
redTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialRedTopFrameText'),
notes: t('eyewearSpecialRedTopFrameNotes'),
value: 0,
},
whiteTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialWhiteTopFrameText'),
notes: t('eyewearSpecialWhiteTopFrameNotes'),
value: 0,
},
yellowTopFrame: {
gearSet: 'glasses',
text: t('eyewearSpecialYellowTopFrameText'),
notes: t('eyewearSpecialYellowTopFrameNotes'),
value: 0,
},
};
let head = {
@@ -515,9 +533,6 @@ let head = {
notes: t('headSpecialSpringRogueNotes', { per: 9 }),
value: 60,
per: 9,
canBuy: () => {
return true;
},
},
springWarrior: {
event: EVENTS.spring,
@@ -526,9 +541,6 @@ let head = {
notes: t('headSpecialSpringWarriorNotes', { str: 9 }),
value: 60,
str: 9,
canBuy: () => {
return true;
},
},
springMage: {
event: EVENTS.spring,
@@ -537,9 +549,6 @@ let head = {
notes: t('headSpecialSpringMageNotes', { per: 7 }),
value: 60,
per: 7,
canBuy: () => {
return true;
},
},
springHealer: {
event: EVENTS.spring,
@@ -548,9 +557,6 @@ let head = {
notes: t('headSpecialSpringHealerNotes', { int: 7 }),
value: 60,
int: 7,
canBuy: () => {
return true;
},
},
summerRogue: {
event: EVENTS.summer,
@@ -661,9 +667,6 @@ let head = {
notes: t('headSpecialSpring2015RogueNotes', { per: 9 }),
value: 60,
per: 9,
canBuy: () => {
return true;
},
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -672,9 +675,6 @@ let head = {
notes: t('headSpecialSpring2015WarriorNotes', { str: 9 }),
value: 60,
str: 9,
canBuy: () => {
return true;
},
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -683,9 +683,6 @@ let head = {
notes: t('headSpecialSpring2015MageNotes', { per: 7 }),
value: 60,
per: 7,
canBuy: () => {
return true;
},
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -694,9 +691,6 @@ let head = {
notes: t('headSpecialSpring2015HealerNotes', { int: 7 }),
value: 60,
int: 7,
canBuy: () => {
return true;
},
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -847,9 +841,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpringRogueText'),
notes: t('headAccessorySpecialSpringRogueNotes'),
value: 20,
canBuy: () => {
return true;
},
},
springWarrior: {
event: EVENTS.spring,
@@ -857,9 +848,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpringWarriorText'),
notes: t('headAccessorySpecialSpringWarriorNotes'),
value: 20,
canBuy: () => {
return true;
},
},
springMage: {
event: EVENTS.spring,
@@ -867,9 +855,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpringMageText'),
notes: t('headAccessorySpecialSpringMageNotes'),
value: 20,
canBuy: () => {
return true;
},
},
springHealer: {
event: EVENTS.spring,
@@ -877,9 +862,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpringHealerText'),
notes: t('headAccessorySpecialSpringHealerNotes'),
value: 20,
canBuy: () => {
return true;
},
},
spring2015Rogue: {
event: EVENTS.spring2015,
@@ -887,9 +869,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015RogueText'),
notes: t('headAccessorySpecialSpring2015RogueNotes'),
value: 20,
canBuy: () => {
return true;
},
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -897,9 +876,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015WarriorText'),
notes: t('headAccessorySpecialSpring2015WarriorNotes'),
value: 20,
canBuy: () => {
return true;
},
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -907,9 +883,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015MageText'),
notes: t('headAccessorySpecialSpring2015MageNotes'),
value: 20,
canBuy: () => {
return true;
},
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -917,9 +890,6 @@ let headAccessory = {
text: t('headAccessorySpecialSpring2015HealerText'),
notes: t('headAccessorySpecialSpring2015HealerNotes'),
value: 20,
canBuy: () => {
return true;
},
},
bearEars: {
gearSet: 'animal',
@@ -1080,9 +1050,6 @@ let shield = {
notes: t('shieldSpecialSpringRogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
springWarrior: {
event: EVENTS.spring,
@@ -1091,9 +1058,6 @@ let shield = {
notes: t('shieldSpecialSpringWarriorNotes', { con: 7 }),
value: 70,
con: 7,
canBuy: () => {
return true;
},
},
springHealer: {
event: EVENTS.spring,
@@ -1102,9 +1066,6 @@ let shield = {
notes: t('shieldSpecialSpringHealerNotes', { con: 9 }),
value: 70,
con: 9,
canBuy: () => {
return true;
},
},
summerRogue: {
event: EVENTS.summer,
@@ -1137,9 +1098,6 @@ let shield = {
notes: t('shieldSpecialFallRogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
fallWarrior: {
event: EVENTS.fall,
@@ -1148,9 +1106,6 @@ let shield = {
notes: t('shieldSpecialFallWarriorNotes', { con: 7 }),
value: 70,
con: 7,
canBuy: () => {
return true;
},
},
fallHealer: {
event: EVENTS.fall,
@@ -1159,9 +1114,6 @@ let shield = {
notes: t('shieldSpecialFallHealerNotes', { con: 9 }),
value: 70,
con: 9,
canBuy: () => {
return true;
},
},
winter2015Rogue: {
event: EVENTS.winter2015,
@@ -1194,9 +1146,6 @@ let shield = {
notes: t('shieldSpecialSpring2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -1205,9 +1154,6 @@ let shield = {
notes: t('shieldSpecialSpring2015WarriorNotes', { con: 7 }),
value: 70,
con: 7,
canBuy: () => {
return true;
},
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -1216,9 +1162,6 @@ let shield = {
notes: t('shieldSpecialSpring2015HealerNotes', { con: 9 }),
value: 70,
con: 9,
canBuy: () => {
return true;
},
},
summer2015Rogue: {
event: EVENTS.summer2015,
@@ -1227,9 +1170,6 @@ let shield = {
notes: t('shieldSpecialSummer2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
summer2015Warrior: {
event: EVENTS.summer2015,
@@ -1375,9 +1315,6 @@ let weapon = {
notes: t('weaponSpecialSpringRogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
springWarrior: {
event: EVENTS.spring,
@@ -1386,9 +1323,6 @@ let weapon = {
notes: t('weaponSpecialSpringWarriorNotes', { str: 15 }),
value: 90,
str: 15,
canBuy: () => {
return true;
},
},
springMage: {
event: EVENTS.spring,
@@ -1399,9 +1333,6 @@ let weapon = {
value: 160,
int: 15,
per: 7,
canBuy: () => {
return true;
},
},
springHealer: {
event: EVENTS.spring,
@@ -1410,9 +1341,6 @@ let weapon = {
notes: t('weaponSpecialSpringHealerNotes', { int: 9 }),
value: 90,
int: 9,
canBuy: () => {
return true;
},
},
summerRogue: {
event: EVENTS.summer,
@@ -1523,9 +1451,6 @@ let weapon = {
notes: t('weaponSpecialSpring2015RogueNotes', { str: 8 }),
value: 80,
str: 8,
canBuy: () => {
return true;
},
},
spring2015Warrior: {
event: EVENTS.spring2015,
@@ -1534,9 +1459,6 @@ let weapon = {
notes: t('weaponSpecialSpring2015WarriorNotes', { str: 15 }),
value: 90,
str: 15,
canBuy: () => {
return true;
},
},
spring2015Mage: {
event: EVENTS.spring2015,
@@ -1547,9 +1469,6 @@ let weapon = {
value: 160,
int: 15,
per: 7,
canBuy: () => {
return true;
},
},
spring2015Healer: {
event: EVENTS.spring2015,
@@ -1558,9 +1477,6 @@ let weapon = {
notes: t('weaponSpecialSpring2015HealerNotes', { int: 9 }),
value: 90,
int: 9,
canBuy: () => {
return true;
},
},
summer2015Rogue: {
event: EVENTS.summer2015,

View File

@@ -49,7 +49,7 @@ module.exports = function randomDrop (user, modifiers, req = {}) {
user.markModified('party.quest.progress');
}
if (user.purchased && user.purchased.plan && user.purchased.plan.custsomerId) {
if (user.purchased && user.purchased.plan && user.purchased.plan.customerId) {
dropMultiplier = 2;
} else {
dropMultiplier = 1;

View File

@@ -1,5 +1,6 @@
{
"PORT":3000,
"ENABLE_CONSOLE_LOGS_IN_PROD":"false",
"IP":"0.0.0.0",
"CORES":1,
"BASE_URL":"http://localhost:3000",
@@ -19,6 +20,7 @@
"STRIPE_API_KEY":"aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY":"22223333444455556666777788889999",
"NEW_RELIC_LICENSE_KEY":"NEW_RELIC_LICENSE_KEY",
"NEW_RELIC_NO_CONFIG_FILE":"true",
"NEW_RELIC_APPLICATION_ID":"NEW_RELIC_APPLICATION_ID",
"NEW_RELIC_API_KEY":"NEW_RELIC_API_KEY",
"GA_ID": "GA_ID",

View File

@@ -17,6 +17,7 @@ var mongoose = require('mongoose');
var _ = require('lodash');
var uuid = require('uuid');
var consoleStamp = require('console-stamp');
var fs = require('fs');
// Add timestamps to console messages
consoleStamp(console);
@@ -29,7 +30,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models
var NewChallenge = require('../../website/src/models/challenge').model;
@@ -48,6 +49,8 @@ var BATCH_SIZE = 1000;
var processedChallenges = 0;
var totoalProcessedTasks = 0;
var newTasksIds = {}; // a map of old id -> [new id, challengeId]
// Only process challenges that fall in a interval ie -> up to 0000-4000-0000-0000
var AFTER_CHALLENGE_ID = nconf.get('AFTER_CHALLENGE_ID');
var BEFORE_CHALLENGE_ID = nconf.get('BEFORE_CHALLENGE_ID');
@@ -109,23 +112,44 @@ function processChallenges (afterId) {
if (!oldChallenge.group) throw new Error('challenge.group is required');
if (!oldChallenge.leader) throw new Error('challenge.leader is required');
if (oldChallenge.leader === '9') {
oldChallenge.leader = '00000000-0000-4000-9000-000000000000';
}
if (oldChallenge.group === 'habitrpg') {
oldChallenge.group = '00000000-0000-4000-A000-000000000000';
}
delete oldChallenge.id;
var newChallenge = new NewChallenge(oldChallenge);
newChallenge.createdAt = createdAt;
oldTasks.forEach(function (oldTask) {
oldTask._id = uuid.v4(); // TODO keep the old uuid unless duplicated
oldTask._id = uuid.v4();
oldTask.legacyId = oldTask.id; // store the old task id
delete oldTask.id;
oldTask.challenge = oldTask.challenge || {};
oldTask.challenge.id = newChallenge._id;
if (newTasksIds[oldTask.legacyId + '-' + newChallenge._id]) {
throw new Error('duplicate :(');
} else {
newTasksIds[oldTask.legacyId + '-' + newChallenge._id] = oldTask._id;
}
oldTask.tags = _.map(oldTask.tags || {}, function (tagPresent, tagId) {
return tagPresent && tagId;
}).filter(function (tag) {
return tag !== false;
});
if (!oldTask.text) oldTask.text = 'task text'; // required
oldTask.challenge = oldTask.challenge || {};
oldTask.challenge.id = oldChallenge._id;
oldTask.createdAt = oldTask.dateCreated;
newChallenge.tasksOrder[`${oldTask.type}s`].push(oldTask._id);
if (oldTask.completed) oldTask.completed = false;
@@ -141,7 +165,7 @@ function processChallenges (afterId) {
console.log(`Saving ${oldChallenges.length} challenges and ${processedTasks} tasks.`);
return Q.all([
return Bluebird.all([
batchInsertChallenges.execute(),
batchInsertTasks.execute(),
]);
@@ -155,13 +179,15 @@ function processChallenges (afterId) {
if (lastChallenge) {
return processChallenges(lastChallenge);
} else {
console.log('Writing newTasksIds.json...')
fs.writeFileSync('newTasksIds.json', JSON.stringify(newTasksIds, null, 4), 'utf8');
return console.log('Done!');
}
});
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -30,7 +30,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// To be defined later when MongoClient connects
var mongoDbOldInstance;
@@ -87,8 +87,15 @@ function processChallenges (afterId) {
}
oldChallenges.forEach(function (oldChallenge) {
// Tyler Renelle
oldChallenge.members.forEach(function (id, index) {
if (id === '9') {
oldChallenge.members[index] = '00000000-0000-4000-9000-000000000000';
}
});
promises.push(newUserCollection.updateMany({
_id: {$in: oldChallenge.members},
_id: {$in: oldChallenge.members || []},
}, {
$push: {challenges: oldChallenge._id},
}, {multi: true}));
@@ -96,7 +103,7 @@ function processChallenges (afterId) {
console.log(`Migrating members of ${oldChallenges.length} challenges.`);
return Q.all(promises);
return Bluebird.all(promises);
})
.then(function () {
processedChallenges += oldChallenges.length;
@@ -112,7 +119,7 @@ function processChallenges (afterId) {
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -29,7 +29,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models
var Coupon = require('../../website/src/models/coupon').model;
@@ -112,7 +112,7 @@ function processCoupons (afterId) {
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -29,7 +29,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models
var EmailUnsubscription = require('../../website/src/models/emailUnsubscription').model;
@@ -113,7 +113,7 @@ function processUnsubscriptions (afterId) {
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -37,7 +37,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models
var NewGroup = require('../../website/src/models/group').model;
@@ -102,9 +102,11 @@ function processGroups (afterId) {
}
oldGroups.forEach(function (oldGroup) {
if ((!oldGroup.privacy || oldGroup.privacy === 'private') && (!oldGroup.members || oldGroup.members.length === 0)) return; // delete empty private groups
if ((!oldGroup.privacy || oldGroup.privacy === 'private') && (!oldGroup.members || oldGroup.members.length === 0)) return; // delete empty private groups TODO must also delete challenges or this won't work
oldGroup.members = oldGroup.members || [];
oldGroup.memberCount = oldGroup.members ? oldGroup.members.length : 0;
oldGroup.memberCount = oldGroup.challenges ? oldGroup.challenges.length : 0;
oldGroup.challengeCount = oldGroup.challenges ? oldGroup.challenges.length : 0;
if (!oldGroup.balance <= 0) oldGroup.balance = 0;
if (!oldGroup.name) oldGroup.name = 'group name';
@@ -132,7 +134,7 @@ function processGroups (afterId) {
if (!oldGroup.privacy) {
// throw new Error('group.privacy is required');
group.privacy = 'private';
oldGroup.privacy = 'private';
}
var updateMembers = {};
@@ -144,6 +146,13 @@ function processGroups (afterId) {
}
if (oldGroup.members) {
// Tyler Renelle
oldGroup.members.forEach(function (id, index) {
if (id === '9') {
oldGroup.members[index] = '00000000-0000-4000-9000-000000000000';
}
});
promises.push(newUserCollection.updateMany({
_id: {$in: oldGroup.members},
}, updateMembers, {multi: true}));
@@ -157,7 +166,7 @@ function processGroups (afterId) {
console.log(`Saving ${oldGroups.length} groups and migrating members to users collection.`);
promises.push(batchInsertGroups.execute());
return Q.all(promises);
return Bluebird.all(promises);
})
.then(function () {
processedGroups += oldGroups.length;
@@ -173,7 +182,7 @@ function processGroups (afterId) {
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -1,52 +1,52 @@
/*
DEFINE BEFORE MIGRATING
tasks: userId (sparse?), challenge.id (sparse), challenge.taskId (sparse), type? completed?
tasks: userId OK (sparse?), challenge.id OK (sparse?), challenge.taskId OK (sparse?), type? completed?
users:
id & apiToken?,
auth.facebook.emails.value -> unique and sparse?,
auth.facebook.id - unique and sparse,
auth.local.email - unique and sparse,
auth.local.lowerCaseUsername,
auth.local.username - unique and sparse
id & apiToken, OK
auth.facebook.emails.value OK -> unique and sparse?,
auth.facebook.id - unique and sparse, OK
auth.local.email - unique and sparse, OK
auth.local.lowerCaseUsername, OK
auth.local.username - unique OK
auth.local.username & auth.local.hashed_password?,
auth.timestamps.created?,
auth.timestamps.loggedin?,
backer.tier -1
auth.timestamps.created?, OK
auth.timestamps.loggedin?, OK
backer.tier -1 OK
{ "contributor.admin" : 1 , "contributor.level" : -1 , "backer.npc" : -1 , "profile.name" : 1}
{ "contributor.admin" : 1.0}
{ "contributor.level" : 1.0}
{ "contributor.admin" : 1.0} NO, see ^
{ "contributor.level" : 1.0} OK
{ "contributor.level" : 1.0 , "purchased.plan.customerId" : 1.0} ?
{ "flags.lastWeeklyRecap" : 1 , "_id" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "preferences.emailNotifications.weeklyRecaps" : 1}
{ "invitations.guilds.id" : 1}
{ "invitations.party.id" : 1}
{ "preferences.sleep" : 1 , "_id" : 1 , "flags.lastWeeklyRecap" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "preferences.emailNotifications.weeklyRecaps" : 1}
{ "preferences.sleep" : 1 , "_id" : 1 , "lastCron" : 1 , "preferences.emailNotifications.importantAnnouncements" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "flags.recaptureEmailsPhase" : 1}
profile.name ?
{ "purchased.plan.customerId" : 1.0}
{ "purchased.plan.paymentMethod" : 1.0}
NO { "flags.lastWeeklyRecap" : 1 , "_id" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "preferences.emailNotifications.weeklyRecaps" : 1}
{ "invitations.guilds.id" : 1} OK
{ "invitations.party.id" : 1} OK
OK { "preferences.sleep" : 1 , "_id" : 1 , "flags.lastWeeklyRecap" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "preferences.emailNotifications.weeklyRecaps" : 1}
OK { "preferences.sleep" : 1 , "_id" : 1 , "lastCron" : 1 , "preferences.emailNotifications.importantAnnouncements" : 1 , "preferences.emailNotifications.unsubscribeFromAll" : 1 , "flags.recaptureEmailsPhase" : 1}
profile.name ? OK
{ "purchased.plan.customerId" : 1.0} OK
{ "purchased.plan.paymentMethod" : 1.0} OK
guilds
party.id
challenges
guilds OK
party.id OK
challenges OK
challenges:
{ "_id" : 1.0 , "__v" : 1.0} ?
{ "_id" : 1.0 , "__v" : 1.0} ? NO
{ "_id" : 1.0 , "official" : -1.0 , "timestamp" : -1.0}
{ "group" : 1.0 , "official" : -1.0 , "timestamp" : -1.0}
{ "leader" : 1.0 , "official" : -1.0 , "timestamp" : -1.0}
{ "members" : 1.0 , "official" : -1.0 , "timestamp" : -1.0} ?
{ "official" : -1 , "timestamp" : -1}
{ "group" : 1.0 , "official" : -1.0 , "timestamp" : -1.0} OK
{ "leader" : 1.0 , "official" : -1.0 , "timestamp" : -1.0} OK
{ "members" : 1.0 , "official" : -1.0 , "timestamp" : -1.0} ? NO
{ "official" : -1 , "timestamp" : -1} ?
{ "official" : -1 , "timestamp" : -1, "_id": 1} ?
groups:
{ "_id" : 1 , "quest.key" : 1}
{ "_id" : 1 , "quest.key" : 1} ?
{ "_id" : 1.0 , "__v" : 1.0} ?
{ "_id" : 1.0 , "privacy" : 1.0 , "members" : 1.0} ?
{ "members" : 1.0 , "type" : 1.0 , "memberCount" : -1.0} ?
{ "members" : 1} ?
{ "_id" : 1.0 , "privacy" : 1.0 , "members" : 1.0} ? NO
{ "members" : 1.0 , "type" : 1.0 , "memberCount" : -1.0} ? NO
{ "members" : 1} ? NO
{ "privacy" : 1.0 , "memberCount" : -1.0} ?
{ "privacy" : 1.0} ?
{ "privacy" : 1.0} OK
{ "type" : 1 , "privacy" : 1} ?
{ "type" : 1.0 , "members" : 1.0} ?
{ "type" : 1} ?
emailUnsubscriptions: email unique
{ "type" : 1.0 , "members" : 1.0} ? NO
{ "type" : 1} ? OK
emailUnsubscriptions: email unique OK
*/

View File

@@ -19,6 +19,7 @@ var _ = require('lodash');
var uuid = require('uuid');
var consoleStamp = require('console-stamp');
var common = require('../../common');
var moment = require('moment');
// Add timestamps to console messages
consoleStamp(console);
@@ -32,7 +33,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var taskDefaults = common.taskDefaults;
var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Q.Promise; // otherwise mongoose models won't work
mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models
var NewUser = require('../../website/src/models/user').model;
@@ -51,23 +52,23 @@ var BATCH_SIZE = 1000;
var processedUsers = 0;
var totoalProcessedTasks = 0;
var challengeTaskWithMatchingId = 0;
var challengeTaskNoMatchingId = 0;
// Load the new tasks ids for challenges tasks
var newTasksIds = require('./newTasksIds.json');
// Only process users that fall in a interval ie up to -> 0000-4000-0000-0000
var AFTER_USER_ID = nconf.get('AFTER_USER_ID');
var BEFORE_USER_ID = nconf.get('BEFORE_USER_ID');
/* TODO compare old and new model
- _id 9
- challenges
- groups
- invitations
- challenges' tasks
*/
function processUsers (afterId) {
var processedTasks = 0;
var lastUser = null;
var oldUsers;
var now = new Date();
var query = {};
if (BEFORE_USER_ID) {
@@ -110,6 +111,8 @@ function processUsers (afterId) {
delete oldUser.rewards;
delete oldUser.todos;
delete oldUser.id;
oldUser.tags = oldUser.tags.map(function (tag) {
return {
id: tag.id,
@@ -123,6 +126,7 @@ function processUsers (afterId) {
}
var newUser = new NewUser(oldUser);
var isSubscribed = newUser.isSubscribed();
oldTasks.forEach(function (oldTask) {
oldTask._id = uuid.v4(); // create a new unique uuid
@@ -132,21 +136,44 @@ function processUsers (afterId) {
oldTask.challenge = oldTask.challenge || {};
if (oldTask.challenge.id) {
if (oldTask.challenge.broken) {
oldTask.challenge.taskId = oldTask.legacyId;
} else {
var newId = newTasksIds[oldTask.legacyId + '-' + oldTask.challenge.id];
// Challenges' tasks ids changed
if (!newId && !oldTask.challenge.broken) {
challengeTaskNoMatchingId++;
oldTask.challenge.taskId = oldTask.legacyId;
oldTask.challenge.broken = 'CHALLENGE_TASK_NOT_FOUND';
} else {
challengeTaskWithMatchingId++;
oldTask.challenge.taskId = newId;
}
}
}
oldTask.createdAt = old.dateCreated;
// Delete old completed todos
if (oldTask.type === 'todo' && oldTask.completed && (!oldTask.challenge.id || oldTask.challenge.broken)) {
if (moment(now).subtract(isSubscribed ? 90 : 30, 'days').toDate() > moment(oldTask.dateCompleted).toDate()) {
return;
}
}
oldTask.createdAt = oldTask.dateCreated;
if (!oldTask.text) oldTask.text = 'task text'; // required
oldTask.tags = _.map(oldTask.tags, function (tagPresent, tagId) {
return tagPresent && tagId;
}).filter(function (tag) {
return tag !== false;
});
if (oldTask.type !== 'todo' || (oldTask.type === 'todo' && !oldTask.completed)) {
newUser.tasksOrder[`${oldTask.type}s`].push(oldTask._id);
}
var allTasksFields = ['_id', 'type', 'text', 'notes', 'tags', 'value', 'priority', 'attribute', 'challenge', 'reminders'];
var allTasksFields = ['_id', 'type', 'text', 'notes', 'tags', 'value', 'priority', 'attribute', 'challenge', 'reminders', 'userId', 'legacyId'];
// using mongoose models is too slow
if (oldTask.type === 'habit') {
oldTask = _.pick(oldTask, allTasksFields.concat(['history', 'up', 'down']));
@@ -169,7 +196,7 @@ function processUsers (afterId) {
console.log(`Saving ${oldUsers.length} users and ${processedTasks} tasks.`);
return Q.all([
return Bluebird.all([
batchInsertUsers.execute(),
batchInsertTasks.execute(),
]);
@@ -179,6 +206,8 @@ function processUsers (afterId) {
processedUsers += oldUsers.length;
console.log(`Saved ${oldUsers.length} users and their tasks.`);
console.log('Challenges\' tasks no matching id: ', challengeTaskNoMatchingId);
console.log('Challenges\' tasks with matching id: ', challengeTaskWithMatchingId);
if (lastUser) {
return processUsers(lastUser);
@@ -189,7 +218,7 @@ function processUsers (afterId) {
}
// Connect to the databases
Q.all([
Bluebird.all([
MongoClient.connect(MONGODB_OLD),
MongoClient.connect(MONGODB_NEW),
])

View File

@@ -1,28 +1,28 @@
{
"name": "habitrpg",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "3.0.0-alpha",
"version": "3.0.0",
"main": "./website/src/index.js",
"dependencies": {
"accepts": "^1.3.2",
"amazon-payments": "0.0.4",
"amplitude": "^2.0.3",
"apidoc": "^0.13.1",
"apidoc": "^0.16.0",
"async": "^1.5.0",
"aws-sdk": "^2.0.25",
"babel-plugin-syntax-async-functions": "^6.5.0",
"babel-plugin-transform-regenerator": "^6.6.0",
"babel-plugin-transform-async-to-module-method": "^6.8.0",
"babel-polyfill": "^6.6.1",
"babel-preset-es2015": "^6.6.0",
"babel-register": "^6.6.0",
"babelify": "^7.2.0",
"bluebird": "^3.3.5",
"body-parser": "^1.15.0",
"bower": "~1.3.12",
"browserify": "~12.0.1",
"compression": "^1.6.1",
"connect-ratelimit": "0.0.7",
"cookie-session": "^1.2.0",
"coupon-code": "~0.3.0",
"coupon-code": "^0.4.3",
"csv-stringify": "^1.0.2",
"domain-middleware": "~0.1.0",
"estraverse": "^4.1.1",
@@ -61,43 +61,42 @@
"markdown-it": "^6.0.1",
"merge-stream": "^1.0.0",
"method-override": "^2.3.5",
"moment": "~2.10.6",
"mongoose": "~4.2.3",
"moment": "^2.13.0",
"mongoose": "^4.4.16",
"mongoose-id-autoinc": "~2013.7.14-4",
"morgan": "^1.7.0",
"nconf": "~0.8.2",
"newrelic": "~1.26.1",
"uuid": "^2.0.1",
"nib": "~1.0.1",
"nodemailer": "^1.9.0",
"newrelic": "^1.27.2",
"nib": "^1.1.0",
"nodemailer": "^2.3.2",
"object-path": "^0.9.2",
"pageres": "^4.1.1",
"passport": "~0.2.1",
"passport-facebook": "2.0.0",
"paypal-ipn": "2.1.0",
"paypal-ipn": "3.0.0",
"paypal-rest-sdk": "^1.2.1",
"pretty-data": "^0.40.0",
"ps-tree": "^1.0.0",
"push-notify": "^1.1.1",
"q": "^1.4.1",
"request": "~2.44.0",
"request": "~2.72.0",
"rimraf": "^2.4.3",
"run-sequence": "^1.1.4",
"s3-upload-stream": "^1.0.6",
"serve-favicon": "^2.3.0",
"stripe": "^4.2.0",
"superagent": "~1.4.0",
"superagent": "^1.8.3",
"swagger-node-express": "lefnire/swagger-node-express#habitrpg",
"universal-analytics": "~0.3.2",
"validator": "~4.2.1",
"uuid": "^2.0.1",
"validator": "^4.9.0",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"winston": "^2.1.0",
"uuid": "^2.0.1"
"winston": "^2.1.0"
},
"private": true,
"engines": {
"node": "^4.3.1",
"npm": "^3.3.10"
"npm": "^3.8.9"
},
"scripts": {
"lint": "eslint .",
@@ -150,9 +149,9 @@
"nock": "^2.17.0",
"phantomjs": "^1.9",
"protractor": "^3.1.1",
"require-again": "^1.0.1",
"rewire": "^2.3.3",
"rimraf": "^2.4.3",
"shelljs": "^0.5.3",
"shelljs": "^0.7.0",
"sinon": "^1.17.2",
"sinon-chai": "^2.8.0",
"superagent-defaults": "^0.1.13",

View File

@@ -2,14 +2,16 @@
// payment plan definitions, instead you have to create it via their REST SDK and keep it updated the same way. So this
// file will be used once for initing your billing plan (then you get the resultant plan.id to store in config.json),
// and once for any time you need to edit the plan thereafter
var path = require('path');
var nconf = require('nconf');
_ = require('lodash');
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../../../config.json')));
var _ = require('lodash');
var paypal = require('paypal-rest-sdk');
var blocks = require('../../../../common').content.subscriptionBlocks;
var live = nconf.get('PAYPAL:mode')=='live';
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../../../config.json')));
var OP = 'create'; // list create update remove
paypal.configure({

View File

@@ -127,7 +127,7 @@ function calculateImgDimensions(img, addPadding) {
}
function checkForSpecialTreatment(name) {
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears/;
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame/;
return name.match(regex) || name === 'head_0';
}

View File

@@ -9,7 +9,7 @@ import mongoose from 'mongoose';
import { exec } from 'child_process';
import psTree from 'ps-tree';
import gulp from 'gulp';
import Q from 'q';
import Bluebird from 'bluebird';
import runSequence from 'run-sequence';
import os from 'os';
import nconf from 'nconf';
@@ -265,7 +265,7 @@ gulp.task('test:e2e', ['test:prepare', 'test:prepare:server'], (cb) => {
].map(exec);
support.push(server);
Q.all([
Bluebird.all([
awaitPort(TEST_SERVER_PORT),
awaitPort(4444)
]).then(() => {
@@ -286,7 +286,7 @@ gulp.task('test:e2e:safe', ['test:prepare', 'test:prepare:server'], (cb) => {
'npm run test:e2e:webdriver',
].map(exec);
Q.all([
Bluebird.all([
awaitPort(TEST_SERVER_PORT),
awaitPort(4444)
]).then(() => {
@@ -358,6 +358,10 @@ gulp.task('test:api-v3:unit', (done) => {
pipe(runner);
});
gulp.task('test:api-v3:unit:watch', () => {
gulp.watch(['website/src/libs/api-v3/*', 'test/api/v3/unit/**/*', 'website/src/controllers/**/*'], ['test:api-v3:unit']);
});
gulp.task('test:api-v3:integration', (done) => {
let runner = exec(
testBin('mocha test/api/v3/integration --recursive'),
@@ -369,7 +373,8 @@ gulp.task('test:api-v3:integration', (done) => {
});
gulp.task('test:api-v3:integration:watch', () => {
gulp.watch(['website/src/controllers/api-v3/**/*', 'test/api/v3/integration/**/*', 'common/script/ops/*'], ['test:api-v3:integration']);
gulp.watch(['website/src/controllers/api-v3/**/*', 'common/script/ops/*', 'website/src/libs/api-v3/*.js',
'test/api/v3/integration/**/*'], ['test:api-v3:integration']);
});
gulp.task('test:api-v3:integration:separate-server', (done) => {

View File

@@ -2,7 +2,7 @@ import { exec } from 'child_process';
import psTree from 'ps-tree';
import nconf from 'nconf';
import net from 'net';
import Q from 'q';
import Bluebird from 'bluebird';
import { post } from 'superagent';
import { sync as glob } from 'glob';
import Mocha from 'mocha';
@@ -44,12 +44,12 @@ export function kill(proc) {
* before failing.
*/
export function awaitPort (port, max=60) {
return new Bluebird((reject, resolve) => {
let socket, timeout, interval;
let deferred = Q.defer();
timeout = setTimeout(() => {
clearInterval(interval);
deferred.reject(`Timed out after ${max} seconds`);
reject(`Timed out after ${max} seconds`);
}, max * 1000);
interval = setInterval(() => {
@@ -57,11 +57,10 @@ export function awaitPort(port, max=60) {
clearInterval(interval);
clearTimeout(timeout);
socket.destroy();
deferred.resolve();
resolve();
}).on('error', () => { socket.destroy });
}, 1000);
return deferred.promise
});
};
/*

View File

@@ -6,8 +6,8 @@ superagentDefaults = require("superagent-defaults");
global.request = superagentDefaults();
global.mongoose = require("mongoose");
var Q = require('q');
mongoose.Promise = Q.Promise;
var Bluebird = require('bluebird');
mongoose.Promise = Bluebird;
global.moment = require("moment");

Some files were not shown because too many files have changed in this diff Show More