122 lines
4.2 KiB
CoffeeScript
122 lines
4.2 KiB
CoffeeScript
content = require './content'
|
|
moment = require 'moment'
|
|
_ = require 'underscore'
|
|
lodash = require 'lodash'
|
|
derby = require 'derby'
|
|
|
|
userSchema =
|
|
# _id
|
|
stats: { gp: 0, exp: 0, lvl: 1, hp: 50 }
|
|
party: { current: null, invitation: null }
|
|
items: { armor: 0, weapon: 0 }
|
|
preferences: { gender: 'm', armorSet: 'v1' }
|
|
idLists:
|
|
habit: []
|
|
daily: []
|
|
todo: []
|
|
reward: []
|
|
apiToken: null # set in newUserObject below
|
|
lastCron: 'new' #this will be replaced with `+new Date` on first run
|
|
balance: 2
|
|
tasks: {}
|
|
flags:
|
|
partyEnabled: false
|
|
itemsEnabled: false
|
|
kickstarter: 'show'
|
|
# ads: 'show' # added on registration
|
|
|
|
module.exports.newUserObject = ->
|
|
# deep clone, else further new users get duplicate objects
|
|
newUser = lodash.cloneDeep userSchema
|
|
newUser.apiToken = derby.uuid()
|
|
for task in content.defaultTasks
|
|
guid = task.id = derby.uuid()
|
|
newUser.tasks[guid] = task
|
|
switch task.type
|
|
when 'habit' then newUser.idLists.habit.push guid
|
|
when 'daily' then newUser.idLists.daily.push guid
|
|
when 'todo' then newUser.idLists.todo.push guid
|
|
when 'reward' then newUser.idLists.reward.push guid
|
|
return newUser
|
|
|
|
module.exports.updateUser = (batch) ->
|
|
user = batch.user
|
|
obj = batch.obj()
|
|
|
|
batch.set('apiToken', derby.uuid()) unless obj.apiToken
|
|
|
|
## Task List Cleanup
|
|
# FIXME temporary hack to fix lists (Need to figure out why these are happening)
|
|
tasks = obj.tasks
|
|
_.each ['habit','daily','todo','reward'], (type) ->
|
|
# 1. remove duplicates
|
|
# 2. restore missing zombie tasks back into list
|
|
taskIds = _.pluck( _.where(tasks, {type:type}), 'id')
|
|
union = _.union obj.idLists[type], taskIds
|
|
|
|
# 2. remove empty (grey) tasks
|
|
preened = _.filter(union, (val) -> _.contains(taskIds, val))
|
|
|
|
# There were indeed issues found, set the new list
|
|
batch.set("idLists.#{type}", preened) # if _.difference(preened, userObj[path]).length != 0
|
|
|
|
module.exports.BatchUpdate = BatchUpdate = (model) ->
|
|
user = model.at("_user")
|
|
transactionInProgress = false
|
|
obj = {}
|
|
updates = {}
|
|
|
|
{
|
|
user: user
|
|
|
|
obj: ->
|
|
obj ?= user.get()
|
|
return obj
|
|
|
|
startTransaction: ->
|
|
# start a batch transaction - nothing between now and @commit() will be set immediately
|
|
transactionInProgress = true
|
|
model._dontPersist = true
|
|
|
|
# Really strange, user.get() seems to only return attributes which have previously been accessed. So in
|
|
# many cases, userObj.tasks.{taskId}.value is undefined - so we manually .get() each attribute here.
|
|
# Additionally, for some reason after getting the user object, changing properies manually (userObj.stats.hp = 50)
|
|
# seems to actually run user.set('stats.hp',50) which we don't want to do - so we deepClone here
|
|
#_.each Object.keys(userSchema), (key) -> obj[key] = lodash.cloneDeep user.get(key)
|
|
obj = model.get('users.'+user.get('id'), true)
|
|
|
|
###
|
|
Handles updating the user model. If this is an en-mass operation (eg, server cron), changes are queued
|
|
but not actually set to the model. It also modifies userObj in case you need to access properties manually later.
|
|
If transaction not in progress, it just runs standard model.set()
|
|
###
|
|
set: (path, val) ->
|
|
updates[path] = val if transactionInProgress
|
|
user.set(path, val)
|
|
|
|
###
|
|
Hack to get around dom bindings being lost if parent objects are replaced whole-sale
|
|
eg, user.set('stats', {hp:50, exp:10...}) will break dom bindings, but user.set('stats.hp',50) is ok
|
|
###
|
|
setStats: (stats) ->
|
|
stats ?= obj.stats
|
|
that = @
|
|
_.each Object.keys(stats), (key) -> that.set "stats.#{key}", stats[key]
|
|
|
|
# queue: (path, val) ->
|
|
# # Special function for setting object properties by string dot-notation. See http://stackoverflow.com/a/6394168/362790
|
|
# arr = path.split('.')
|
|
# arr.reduce (curr, next, index) ->
|
|
# if (arr.length - 1) == index
|
|
# curr[next] = val
|
|
# curr[next]
|
|
# , obj
|
|
|
|
commit: ->
|
|
model._dontPersist = false
|
|
# some hackery in our own branched racer-db-mongo, see findAndModify of lefnire/racer-db-mongo#habitrpg index.js
|
|
user.set "update__", updates
|
|
transactionInProgress = false
|
|
updates = {}
|
|
}
|