huge cron fixes which should solve streak, dayStart, "timezone" issues

This commit is contained in:
Tyler Renelle
2013-05-14 17:33:15 +01:00
parent 2c7492709c
commit 92b178b4a4
3 changed files with 36 additions and 36 deletions
+16 -15
View File
@@ -4,13 +4,22 @@ relative = require 'relative-date'
algos = require './algos'
items = require('./items').items
# Absolute diff between two dates
daysBetween = (yesterday, now, dayStart) ->
sod = (timestamp, dayStart=0) ->
#sanity-check reset-time (is it 24h time?)
dayStart = 0 unless (dayStart? and (dayStart = parseInt(dayStart)) and dayStart >= 0 and dayStart <= 24)
Math.abs moment(yesterday).startOf('day').add('h', dayStart).diff(moment(now), 'days')
dayStart = 0 unless (dayStart = parseInt(dayStart)) and (0 <= dayStart <= 24)
moment(timestamp).startOf('day').add('h', dayStart)
dayMapping = dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s',7:'su'}
# Absolute diff between two dates
daysBetween = (yesterday, now, dayStart) -> Math.abs sod(yesterday, dayStart).diff(now, 'days')
dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s'}
shouldDo = (day, repeat, dayStart=0) ->
now = +new Date
selected = repeat[dayMapping[sod(day, dayStart).day()]]
if moment(day).isSame(now,'d')
return selected and dayStart <= moment(now).hour()
return selected
# http://stackoverflow.com/questions/2532218/pick-random-property-from-a-javascript-object
# obj: object
@@ -139,17 +148,9 @@ viewHelpers = (view) ->
classes = type
now = moment().day()
# calculate the current contextual day (e.g. if it's 12 AM Fri and the user's custom day start is 4 AM, then we should still act like it's Thursday)
dayStart = 0 unless (dayStart? and (dayStart = parseInt(dayStart)) and dayStart >= 0 and dayStart <= 24)
hourDiff = Math.abs moment(lastCron).startOf('day').add('h', dayStart).diff(moment(now), 'hours')
dayStamp = moment(now).add('h', hourDiff)
day = dayStamp.day()
# show as completed if completed (naturally) or not required for today
if type in ['todo', 'daily']
if completed or (repeat and (repeat[dayMapping[day]] == false))
if completed or !shouldDo(+new Date, task.repeat, dayStart)
classes += " completed"
else
classes += " uncompleted"
@@ -216,4 +217,4 @@ viewHelpers = (view) ->
module.exports = { viewHelpers, removeWhitespace, randomVal, daysBetween, dayMapping, username }
module.exports = { viewHelpers, removeWhitespace, randomVal, daysBetween, shouldDo, username }
-4
View File
@@ -118,10 +118,6 @@ ready (model) ->
user = model.at('_user')
model.setNull '_user.apiToken', derby.uuid()
#set cron immediately
lastCron = user.get('lastCron')
user.set('lastCron', +new Date) if (!lastCron? or lastCron == 'new')
require('./scoring').cron(model)
require('./character').app(exports, model)
+20 -17
View File
@@ -19,14 +19,13 @@ randomDrop = (model, delta, priority, streak=0) ->
user.setNull 'items.lastDrop',
date: +moment().subtract('d',1) # trick - set it to yesterday on first run, that way they can get drops today
count: 0
reachedDropLimit = (helpers.daysBetween(user.get('items.lastDrop.date'), +new Date) is 0) and user.get('items.lastDrop.count') >= 2
reachedDropLimit = (helpers.daysBetween(user.get('items.lastDrop.date'), +new Date, user.get('preferences.dayStart')) is 0) and user.get('items.lastDrop.count') >= 2
return if reachedDropLimit
# % chance of getting a pet or meat
chanceMultiplier = Math.abs(delta)
chanceMultiplier *= algos.priorityValue(priority) # multiply chance by reddness
chanceMultiplier += streak # streak bonus
console.log chanceMultiplier
if user.get('flags.dropsEnabled') and Math.random() < (.05 * chanceMultiplier)
# current breakdown - 3% (adjustable) chance on drop
@@ -273,8 +272,15 @@ updateStats = (model, newStats, batch) ->
cron = (model) ->
user = model.at '_user'
today = +new Date
daysPassed = helpers.daysBetween(user.get('lastCron'), today, user.get('preferences.dayStart'))
if daysPassed > 0
lastCron = user.get('lastCron')
# New user (!lastCron, lastCron==new) or it got busted somehow, maybe they went to a different timezone
if !lastCron? or lastCron is 'new' or moment(lastCron).isAfter(today)
user.set('lastCron', +new Date)
return
daysMissed = helpers.daysBetween(user.get('lastCron'), today, user.get('preferences.dayStart'))
if daysMissed > 0
# User is resting at the inn. Used to be we un-checked each daily without performing calculation (see commits before fb29e35)
# but to prevent abusing the inn (http://goo.gl/GDb9x) we now do *not* calculate dailies, and simply set lastCron to today
@@ -292,20 +298,17 @@ cron = (model) ->
_.each obj.tasks, (taskObj) ->
{id, type, completed, repeat} = taskObj
if type in ['todo', 'daily']
# Deduct experience for missed Daily tasks,
# but not for Todos (just increase todo's value)
# Deduct experience for missed Daily tasks, but not for Todos (just increase todo's value)
unless completed
# for todos & typical dailies, these are equivalent
daysFailed = daysPassed
# however, for dailys which have repeat dates, need
# to calculate how many they've missed according to their own schedule
if type=='daily' && repeat
daysFailed = 0
_.times daysPassed, (n) ->
thatDay = moment().subtract('days', n+1)
if repeat[helpers.dayMapping[thatDay.day()]]==true
daysFailed++
score model, id, 'down', daysFailed, batch, true
scheduleMisses = daysMissed
# for dailys which have repeat dates, need to calculate how many they've missed according to their own schedule
if (type is 'daily') and repeat
scheduleMisses = 0
_.times daysMissed, (n) ->
thatDay = moment(today).subtract('days', n+1)
scheduleMisses++ if helpers.shouldDo(thatDay, repeat, obj.preferences?.dayStart) is true
score(model, id, 'down', scheduleMisses, batch, true) if scheduleMisses > 0
if type == 'daily'
if completed #set OHV for completed dailies
newValue = taskObj.value + algos.taskDeltaFormula(taskObj.value,'up')