diff --git a/migrations/archive/mystery-items-old.js b/migrations/archive/mystery-items-old.js deleted file mode 100644 index d298d9b7e7..0000000000 --- a/migrations/archive/mystery-items-old.js +++ /dev/null @@ -1,110 +0,0 @@ -import monk from 'monk'; -import nconf from 'nconf'; - -const migrationName = 'mystery-items-201808.js'; // Update per month -const authorName = 'Sabe'; // in case script author needs to know when their ... -const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done - -/* - * Award this month's mystery items to subscribers - */ -const MYSTERY_ITEMS = ['armor_mystery_201810', 'head_mystery_201810']; -const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING'); - -let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false }); -let UserNotification = require('../../website/server/models/userNotification').model; - -function processUsers (lastId) { - // specify a query to limit the affected users (empty for all users): - let query = { - migration: {$ne: migrationName}, - 'purchased.plan.customerId': { $ne: null }, - $or: [ - { 'purchased.plan.dateTerminated': { $gte: new Date() } }, - { 'purchased.plan.dateTerminated': { $exists: false } }, - { 'purchased.plan.dateTerminated': { $eq: null } }, - ], - }; - - if (lastId) { - query._id = { - $gt: lastId, - }; - } - - dbUsers.find(query, { - sort: {_id: 1}, - limit: 250, - fields: [ - ], // specify fields we are interested in to limit retrieved data (empty if we're not reading data): - }) - .then(updateUsers) - .catch((err) => { - console.log(err); - return exiting(1, `ERROR! ${ err}`); - }); -} - -let progressCount = 1000; -let count = 0; - -function updateUsers (users) { - if (!users || users.length === 0) { - console.warn('All appropriate users found and modified.'); - displayData(); - return; - } - - let userPromises = users.map(updateUser); - let lastUser = users[users.length - 1]; - - return Promise.all(userPromises) - .then(() => { - processUsers(lastUser._id); - }); -} - -function updateUser (user) { - count++; - - const addToSet = { - 'purchased.plan.mysteryItems': { - $each: MYSTERY_ITEMS, - }, - }; - const push = { - notifications: (new UserNotification({ - type: 'NEW_MYSTERY_ITEMS', - data: { - MYSTERY_ITEMS, - }, - })).toJSON(), - }; - - dbUsers.update({_id: user._id}, {$addToSet: addToSet, $push: push}); - - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); -} - -function displayData () { - console.warn(`\n${ count } users processed\n`); - return exiting(0); -} - -function exiting (code, msg) { - code = code || 0; // 0 = success - if (code && !msg) { - msg = 'ERROR!'; - } - if (msg) { - if (code) { - console.error(msg); - } else { - console.log(msg); - } - } - process.exit(code); -} - -module.exports = processUsers; diff --git a/migrations/users/mystery-items.js b/migrations/users/mystery-items.js deleted file mode 100644 index 60357445b8..0000000000 --- a/migrations/users/mystery-items.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable no-console */ -import { model as User } from '../../website/server/models/user'; -import { model as UserNotification } from '../../website/server/models/userNotification'; - -const MIGRATION_NAME = 'mystery_items_201911'; -const MYSTERY_ITEMS = ['weapon_mystery_201911', 'head_mystery_201911']; - -const progressCount = 1000; -let count = 0; - -async function updateUser (user) { - count += 1; - - const addToSet = { - 'purchased.plan.mysteryItems': { - $each: MYSTERY_ITEMS, - }, - }; - const push = { - notifications: (new UserNotification({ - type: 'NEW_MYSTERY_ITEMS', - data: { - MYSTERY_ITEMS, - }, - })).toJSON(), - }; - const set = { - migration: MIGRATION_NAME, - }; - - if (count % progressCount === 0) console.warn(`${count} ${user._id}`); - - return User.update({ _id: user._id }, { $set: set, $push: push, $addToSet: addToSet }).exec(); -} - -export default async function processUsers () { - const query = { - migration: { $ne: MIGRATION_NAME }, - 'purchased.plan.customerId': { $ne: null }, - $or: [ - { 'purchased.plan.dateTerminated': { $gte: new Date() } }, - { 'purchased.plan.dateTerminated': { $exists: false } }, - { 'purchased.plan.dateTerminated': { $eq: null } }, - ], - }; - - const fields = { - _id: 1, - }; - - while (true) { // eslint-disable-line no-constant-condition - const users = await User // eslint-disable-line no-await-in-loop - .find(query) - .limit(250) - .sort({ _id: 1 }) - .select(fields) - .lean() - .exec(); - - if (users.length === 0) { - console.warn('All appropriate users found and modified.'); - console.warn(`\n${count} users processed\n`); - break; - } else { - query._id = { - $gt: users[users.length - 1], - }; - } - - await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop - } -} diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index 4c70bfb3ff..cefcd8e2c0 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -1411,6 +1411,8 @@ "headMystery201910Notes": "These flames reveal arcane secrets before your very eyes! Confers no benefit. October 2019 Subscriber Item.", "headMystery201911Text": "Charmed Crystal Hat", "headMystery201911Notes": "Each of the crystal points attached to this hat endows you with a special power: mystic clairvoyance, arcane wisdom, and... sorcerous plate spinning? All right then. Confers no benefit. December 2019 Subscriber Item.", + "headMystery201912Text": "Polar Pixie Crown", + "headMystery201912Notes": "This glittering snowflake grants you resistance to the biting cold no matter how high you fly! Confers no benefit. December 2019 Subscriber Item.", "headMystery301404Text": "Fancy Top Hat", "headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.", "headMystery301405Text": "Basic Top Hat", @@ -1876,6 +1878,8 @@ "backMystery201805Notes": "This gorgeous feathery tail is perfect for a strut down a lovely garden path! Confers no benefit. May 2018 Subscriber Item.", "backMystery201905Text": "Dazzling Dragon Wings", "backMystery201905Notes": "Fly to untold realms with these iridescent wings. Confers no benefit. May 2019 Subscriber Item.", + "backMystery201912Text": "Polar Pixie Wings", + "backMystery201912Notes": "Glide silently across sparkling snowfields and shimmering mountains with these icy wings. Confers no benefit. December 2019 Subscriber Item.", "backSpecialWonderconRedText": "Mighty Cape", "backSpecialWonderconRedNotes": "Swishes with strength and beauty. Confers no benefit. Special Edition Convention Item.", diff --git a/website/common/locales/en/subscriber.json b/website/common/locales/en/subscriber.json index fd310139a4..94d85761eb 100644 --- a/website/common/locales/en/subscriber.json +++ b/website/common/locales/en/subscriber.json @@ -165,6 +165,7 @@ "mysterySet201909": "Affable Acorn Set", "mysterySet201910": "Cryptic Flame Set", "mysterySet201911": "Crystal Charmer Set", + "mysterySet201912": "Polar Pixie Set", "mysterySet301404": "Steampunk Standard Set", "mysterySet301405": "Steampunk Accessories Set", "mysterySet301703": "Peacock Steampunk Set", diff --git a/website/common/script/content/gear/sets/mystery.js b/website/common/script/content/gear/sets/mystery.js index 28c8800783..f7e9b2c898 100644 --- a/website/common/script/content/gear/sets/mystery.js +++ b/website/common/script/content/gear/sets/mystery.js @@ -394,6 +394,12 @@ const back = { mystery: '201905', value: 0, }, + 201912: { + text: t('backMystery201912Text'), + notes: t('backMystery201912Notes'), + mystery: '201912', + value: 0, + }, }; const body = { @@ -763,6 +769,12 @@ const head = { mystery: '201911', value: 0, }, + 201912: { + text: t('headMystery201912Text'), + notes: t('headMystery201912Notes'), + mystery: '201912', + value: 0, + }, 301404: { text: t('headMystery301404Text'), notes: t('headMystery301404Notes'), diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201912/back_mystery_201912.png b/website/raw_sprites/spritesmith/gear/events/mystery_201912/back_mystery_201912.png new file mode 100644 index 0000000000..26105949fe Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201912/back_mystery_201912.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201912/head_mystery_201912.png b/website/raw_sprites/spritesmith/gear/events/mystery_201912/head_mystery_201912.png new file mode 100644 index 0000000000..20f8a594f2 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201912/head_mystery_201912.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_back_mystery_201912.png b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_back_mystery_201912.png new file mode 100644 index 0000000000..ecc8a3be4d Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_back_mystery_201912.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_head_mystery_201912.png b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_head_mystery_201912.png new file mode 100644 index 0000000000..e2a8b8f975 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_head_mystery_201912.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_set_mystery_201912.png b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_set_mystery_201912.png new file mode 100644 index 0000000000..1b9076992a Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/mystery_201912/shop_set_mystery_201912.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_mystery_201912.png b/website/raw_sprites/spritesmith_large/promo_mystery_201912.png new file mode 100644 index 0000000000..3cee5d819b Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_mystery_201912.png differ