mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-21 21:12:32 -05:00
2fe28852b4
* Clients check updated achievements as well as new ones * Clients do not wait to keep checking * Update achievement points along with everything else in EarnedAchievement.upsertFor * Fix various bugs
124 lines
4.8 KiB
CoffeeScript
124 lines
4.8 KiB
CoffeeScript
mongoose = require 'mongoose'
|
|
jsonschema = require '../../app/schemas/models/achievement'
|
|
log = require 'winston'
|
|
utils = require '../../app/core/utils'
|
|
plugins = require('../plugins/plugins')
|
|
AchievablePlugin = require '../plugins/achievements'
|
|
TreemaUtils = require '../../bower_components/treema/treema-utils.js'
|
|
config = require '../../server_config'
|
|
co = require 'co'
|
|
|
|
# `pre` and `post` are not called for update operations executed directly on the database,
|
|
# including `Model.update`,`.findByIdAndUpdate`,`.findOneAndUpdate`, `.findOneAndRemove`,and `.findByIdAndRemove`.order
|
|
# to utilize `pre` or `post` middleware, you should `find()` the document, and call the `init`, `validate`, `save`,
|
|
# or `remove` functions on the document. See [explanation](http://github.com/LearnBoost/mongoose/issues/964).
|
|
|
|
AchievementSchema = new mongoose.Schema({
|
|
userField: String
|
|
}, {strict: false,read: config.mongo.readpref})
|
|
|
|
AchievementSchema.index(
|
|
{
|
|
_fts: 'text'
|
|
_ftsx: 1
|
|
},
|
|
{
|
|
name: 'search index'
|
|
sparse: true
|
|
weights: {name: 1}
|
|
default_language: 'english'
|
|
'language_override': 'language'
|
|
'textIndexVersion': 2
|
|
})
|
|
AchievementSchema.index({i18nCoverage: 1}, {name: 'translation coverage index', sparse: true})
|
|
AchievementSchema.index({slug: 1}, {name: 'slug index', sparse: true, unique: true})
|
|
AchievementSchema.index({related: 1}, {name: 'related index', sparse: true})
|
|
AchievementSchema.index({updated: 1}, {name: 'updated index'})
|
|
|
|
AchievementSchema.methods.objectifyQuery = ->
|
|
try
|
|
@set('query', JSON.parse(@get('query'))) if typeof @get('query') == 'string'
|
|
catch error
|
|
log.error "Couldn't convert query string to object because of #{error}"
|
|
@set('query', {})
|
|
|
|
AchievementSchema.methods.stringifyQuery = ->
|
|
@set('query', JSON.stringify(@get('query'))) if typeof @get('query') != 'string'
|
|
|
|
AchievementSchema.methods.getExpFunction = ->
|
|
func = @get('function') ? {}
|
|
TreemaUtils.populateDefaults(func, jsonschema.properties.function)
|
|
return utils.functionCreators[func.kind](func.parameters) if func.kind of utils.functionCreators
|
|
|
|
AchievementSchema.statics.jsonschema = jsonschema
|
|
AchievementSchema.statics.achievementCollections = {}
|
|
|
|
# Reloads all achievements into memory.
|
|
# TODO might want to tweak this to only load new achievements
|
|
AchievementSchema.statics.loadAchievements = co.wrap ->
|
|
AchievementSchema.statics.resetAchievements()
|
|
t0 = new Date()
|
|
Achievement = require('./Achievement')
|
|
achievements = yield Achievement.find({collection: {$ne: 'level.sessions'}})
|
|
return if t0 < @lastReset # if a test has run resetAchievements during the fetch, abort
|
|
for achievement in achievements
|
|
collection = achievement.get 'collection'
|
|
AchievementSchema.statics.achievementCollections[collection] ?= []
|
|
if _.find AchievementSchema.statics.achievementCollections[collection], ((a) -> a.get('_id').toHexString() is achievement.get('_id').toHexString())
|
|
log.warn "Uh oh, we tried to add another copy of the same achievement #{achievement.get('_id')} #{achievement.get('name')} to the #{collection} achievement list..."
|
|
else
|
|
AchievementSchema.statics.achievementCollections[collection].push achievement
|
|
unless achievement.get('query')
|
|
log.error "Uh oh, there is an achievement with an empty query: #{achievement}"
|
|
return AchievementSchema.statics.achievementCollections
|
|
|
|
AchievementSchema.statics.getLoadedAchievements = ->
|
|
AchievementSchema.statics.achievementCollections
|
|
|
|
AchievementSchema.statics.resetAchievements = ->
|
|
delete AchievementSchema.statics.achievementCollections[collection] for collection of AchievementSchema.statics.achievementCollections
|
|
@lastReset = new Date()
|
|
|
|
AchievementSchema.statics.editableProperties = [
|
|
'name'
|
|
'query'
|
|
'worth'
|
|
'collection'
|
|
'description'
|
|
'userField'
|
|
'proportionalTo'
|
|
'icon'
|
|
'function'
|
|
'related'
|
|
'difficulty'
|
|
'category'
|
|
'rewards'
|
|
'i18n'
|
|
'i18nCoverage'
|
|
'hidden'
|
|
]
|
|
AchievementSchema.statics.postEditableProperties = []
|
|
|
|
AchievementSchema.statics.jsonSchema = require '../../app/schemas/models/achievement'
|
|
|
|
# Queries are stored as JSON strings, objectify them upon loading
|
|
AchievementSchema.post 'init', (doc) -> doc.objectifyQuery()
|
|
|
|
AchievementSchema.pre 'save', (next) ->
|
|
@stringifyQuery()
|
|
if not @get('updated')
|
|
@set('updated', new Date().toISOString())
|
|
next()
|
|
|
|
# Reload achievements upon save
|
|
# This is going to basically not work when there is more than one application server, right?
|
|
AchievementSchema.post 'save', -> @constructor.loadAchievements()
|
|
|
|
AchievementSchema.plugin(plugins.NamedPlugin)
|
|
AchievementSchema.plugin(plugins.SearchablePlugin, {searchable: ['name']})
|
|
AchievementSchema.plugin plugins.TranslationCoveragePlugin
|
|
AchievementSchema.plugin plugins.PatchablePlugin
|
|
|
|
module.exports = Achievement = mongoose.model('Achievement', AchievementSchema, 'achievements')
|
|
|
|
AchievementSchema.statics.loadAchievements()
|