2012-09-24 20:45:37 +00:00
derby = require ' derby '
2013-03-23 20:03:12 +00:00
2013-04-26 21:27:20 +00:00
# Include library components
2013-03-17 04:48:00 +00:00
derby . use require ( ' derby-ui-boot ' ) , { styles: [ ] }
2013-02-12 00:27:35 +00:00
derby . use require ' ../../ui '
derby . use require ' derby-auth/components '
2012-07-27 23:38:28 +00:00
2013-04-26 21:27:20 +00:00
# Init app & reference its functions
app = derby . createApp module
{ get , view , ready } = app
2013-03-23 20:03:12 +00:00
# Translations
i18n = require ' ./i18n '
i18n . localize app ,
2013-05-12 17:58:50 +00:00
availableLocales: [ ' en ' , ' he ' , ' bg ' , ' nl ' ]
2013-03-23 20:03:12 +00:00
defaultLocale: ' en '
2013-05-09 17:07:54 +00:00
urlScheme: false
checkHeader: true
2013-03-23 20:03:12 +00:00
2013-05-22 10:07:56 +00:00
misc = require ( ' ./misc ' )
misc . viewHelpers view
2013-02-08 07:01:48 +00:00
2013-05-19 23:53:18 +00:00
_ = require ( ' lodash ' )
algos = require ' habitrpg-shared/script/algos '
2013-04-10 22:32:38 +00:00
2013-04-11 15:33:50 +00:00
2013-05-08 14:04:10 +00:00
# ##
Subscribe to the user , the users ' s party (meta info like party name, member ids, etc), and the party ' s members . 3 subscriptions .
# ##
setupSubscriptions = (page, model, params, next, cb) ->
uuid = model . get ( ' _userId ' ) or model . session . userId # see http://goo.gl/TPYIt
selfQ = model . query ( ' users ' ) . withId ( uuid ) #keep this for later
2013-05-18 11:22:54 +00:00
groupsQ = model . query ( ' groups ' ) . withMember ( uuid )
2013-05-08 14:04:10 +00:00
2013-05-26 14:29:54 +00:00
groupsQ . fetch (err, groups) ->
2013-05-08 14:04:10 +00:00
return next ( err ) if err
finished = (descriptors, paths) ->
2013-06-01 16:35:20 +00:00
# Add public "Tavern" guild in
descriptors . push ( ' groups.habitrpg ' ) ; paths . push ( ' _habitRPG ' )
# Subscribe to each descriptor
2013-05-08 14:04:10 +00:00
model . subscribe . apply model , descriptors . concat ->
[ err , refs ] = [ arguments [ 0 ] , arguments ]
return next ( err ) if err
2013-05-19 23:53:18 +00:00
_ . each paths , (path, idx) -> model . ref path , refs [ idx + 1 ] ; true
2013-05-08 14:04:10 +00:00
unless model . get ( ' _user ' )
console . error " User not found - this shouldn ' t be happening! "
return page . redirect ( ' /logout ' ) #delete model.session.userId
2013-06-01 16:35:20 +00:00
# Fetch public groups as _publicGroups - not it has to come at very end due to racer bug
model . query ( ' groups ' ) . publicGroups ( ) . fetch (err, pg) ->
return next ( err ) if err
model . set ' _publicGroups ' , _ . sortBy pg . get ( ) , (g) -> - _ . size ( g . members )
2013-05-08 14:04:10 +00:00
return cb ( )
2013-05-18 11:22:54 +00:00
groupsObj = groups . get ( )
2013-05-08 14:04:10 +00:00
# (1) Solo player
2013-06-01 16:35:20 +00:00
return finished ( [ selfQ ] , [ ' _user ' ] ) if _ . isEmpty ( groupsObj )
2013-05-08 14:04:10 +00:00
2013-05-18 11:22:54 +00:00
## (2) Party or Guild has members, fetch those users too
2013-05-26 14:29:54 +00:00
# Subscribe to the groups themselves. We separate them by _party, _guilds, and _habitRPG (the "global" guild).
2013-05-18 11:22:54 +00:00
groupsInfo = _ . reduce groupsObj , ( (m,g)->
if g . type is ' guild ' then m . guildIds . push ( g . id ) else m.partyId = g . id
m.members = m . members . concat ( g . members )
m
) , { guildIds : [ ] , partyId : null , members : [ ] }
2013-05-11 11:13:48 +00:00
2013-05-18 11:22:54 +00:00
# Fetch, not subscribe. There's nothing dynamic we need from members, just the the Group (below) which includes chat, challenges, etc
model . query ( ' users ' ) . publicInfo ( groupsInfo . members ) . fetch (err, members) ->
2013-05-11 11:13:48 +00:00
return next ( err ) if err
2013-05-18 11:22:54 +00:00
# we need _members as an object in the view, so we can iterate over _party.members as :id, and access _members[:id] for the info
mObj = members . get ( )
model . set " _members " , _ . object ( _ . pluck ( mObj , ' id ' ) , mObj )
2013-05-26 21:36:30 +00:00
model . set " _membersArray " , mObj
2013-05-11 11:13:48 +00:00
2013-05-11 23:56:02 +00:00
# Note - selfQ *must* come after membersQ in subscribe, otherwise _user will only get the fields restricted by party-members in store.coffee. Strang bug, but easy to get around
2013-05-18 11:22:54 +00:00
partyQ = model . query ( ' groups ' ) . withIds ( groupsInfo . partyId )
if _ . isEmpty ( groupsInfo . guildIds )
2013-06-01 16:35:20 +00:00
finished [ partyQ , selfQ ] , [ ' _party ' , ' _user ' ]
2013-05-18 11:22:54 +00:00
else
guildsQ = model . query ( ' groups ' ) . withIds ( groupsInfo . guildIds )
2013-06-01 16:35:20 +00:00
finished [ partyQ , guildsQ , selfQ ] , [ ' _party ' , ' _guilds ' , ' _user ' ]
2013-05-08 14:04:10 +00:00
# ========== ROUTES ==========
2013-02-25 23:59:14 +00:00
get ' / ' , (page, model, params, next) ->
2013-02-21 18:40:03 +00:00
return page . redirect ' / ' if page . params ? . query ? . play ?
2013-04-18 20:53:59 +00:00
# removed force-ssl (handled in nginx), see git for code
2013-05-08 14:04:10 +00:00
setupSubscriptions page , model , params , next , ->
2013-04-11 15:39:54 +00:00
require ( ' ./items ' ) . server ( model )
2013-04-04 19:36:52 +00:00
#refLists
_ . each [ ' habit ' , ' daily ' , ' todo ' , ' reward ' ] , (type) ->
model . refList " _ #{ type } List " , " _user.tasks " , " _user. #{ type } Ids "
2013-05-19 23:53:18 +00:00
true
2013-02-18 17:49:53 +00:00
page . render ( )
2012-04-27 02:19:31 +00:00
2013-05-08 14:04:10 +00:00
2012-07-28 01:11:53 +00:00
# ========== CONTROLLER FUNCTIONS ==========
2012-04-27 02:19:31 +00:00
ready (model) ->
2013-05-29 21:47:07 +00:00
exports.removeAt = (e) -> e . at ( ) . remove ( ) # used for things like remove website, chat, etc
2013-05-30 22:43:39 +00:00
user = model . at ( ' _user ' )
misc . fixCorruptUser ( model ) # https://github.com/lefnire/habitrpg/issues/634
browser = require ' ./browser '
2013-04-04 20:44:54 +00:00
require ( ' ./tasks ' ) . app ( exports , model )
require ( ' ./items ' ) . app ( exports , model )
2013-05-26 19:25:15 +00:00
require ( ' ./groups ' ) . app ( exports , model , app )
2013-04-04 20:44:54 +00:00
require ( ' ./profile ' ) . app ( exports , model )
require ( ' ./pets ' ) . app ( exports , model )
2013-01-15 19:35:10 +00:00
require ( ' ../server/private ' ) . app ( exports , model )
2013-04-08 15:24:45 +00:00
require ( ' ./debug ' ) . app ( exports , model ) if model . flags . nodeEnv != ' production '
2013-05-20 09:56:38 +00:00
browser . app ( exports , model , app )
2013-04-16 17:46:44 +00:00
require ( ' ./unlock ' ) . app ( exports , model )
2013-05-06 13:01:43 +00:00
require ( ' ./filters ' ) . app ( exports , model )
2013-05-11 23:05:13 +00:00
require ( ' ./challenges ' ) . app ( exports , model )
2013-05-19 23:53:18 +00:00
2013-05-27 13:37:57 +00:00
# ##
Cron
# ##
2013-05-29 09:23:23 +00:00
misc . batchTxn model , (uObj, paths) ->
# habitrpg-shared/algos requires uObj.habits, uObj.dailys etc instead of uObj.tasks
_ . each [ ' habit ' , ' daily ' , ' todo ' , ' reward ' ] , (type) -> uObj [ " #{ type } s " ] = _ . where ( uObj . tasks , { type } ) ; true
algos . cron uObj , { paths }
return if _ . isEmpty ( paths ) or ( paths [ ' lastCron ' ] and _ . size ( paths ) is 1 )
if lostHp = delete paths [ ' stats.hp ' ] # we'll set this manually so we can get a cool animation
setTimeout ->
2013-05-27 13:37:57 +00:00
browser . resetDom ( model )
2013-05-29 09:23:23 +00:00
user . set ' stats.hp ' , uObj . stats . hp
, 750
, { cron : true }