Implement simulators leaderboard

This commit is contained in:
dpen2000 2014-04-12 22:13:26 +01:00
parent 9941607bcd
commit ec3c292b72
5 changed files with 126 additions and 1 deletions

View file

@ -0,0 +1,11 @@
CocoCollection = require 'models/CocoCollection'
User = require 'models/User'
module.exports = class SimulatorsLeaderboardCollection extends CocoCollection
url: ''
model: User
constructor: (options) ->
super()
options ?= {}
@url = "/db/user/me/simulatorLeaderboard?#{$.param(options)}"

View file

@ -28,6 +28,9 @@
.ellipsis-row
text-align: center
.simulator-leaderboard-cell
text-align: center
// friend column

View file

@ -57,4 +57,32 @@ block content
p.simulation-count
span(data-i18n="ladder.games_simulated_for") Games simulated for you:
|
span#simulated-for-you= me.get('simulatedFor') || 0
span#simulated-for-you= me.get('simulatedFor') || 0
table.table.table-bordered.table-condensed.table-hover
tr
th(data-i18n="general.name").name-col-cell Name
th(data-i18n="general.gamessimulated") Games simulated
th(data-i18n="general.gamesplayed") Games played
th(data-i18n="general.ratio") Ratio
- var topSimulators = simulatorsLeaderboardData.topSimulators.models;
- var showJustTop = simulatorsLeaderboardData.inTopSimulators() || me.get('anonymous');
- if(!showJustTop) topSimulators = topSimulators.slice(0, 10);
for user in topSimulators
- var myRow = user.id == me.id
tr(class=myRow ? "success" : "")
td.name-col-cell= user.get('name') || "Anonymous"
td.simulator-leaderboard-cell= user.get('simulatedBy')
td.simulator-leaderboard-cell= user.get('simulatedFor')
td.simulator-leaderboard-cell= Math.round((user.get('simulatedBy') / user.get('simulatedFor')) * 10) / 10
if !showJustTop && simulatorsLeaderboardData.nearbySimulators().length
tr(class="active")
td(colspan=4).ellipsis-row ...
for user in simulatorsLeaderboardData.nearbySimulators()
- var myRow = user.id == me.id
tr(class=myRow ? "success" : "")
td.name-col-cell= user.get('name') || "Anonymous"
td.simulator-leaderboard-cell= user.get('simulatedBy')
td.simulator-leaderboard-cell= user.get('simulatedFor')
td.simulator-leaderboard-cell= Math.round((user.get('simulatedBy') / user.get('simulatedFor')) * 10) / 10

View file

@ -10,6 +10,8 @@ application = require 'application'
LadderTabView = require './ladder/ladder_tab'
MyMatchesTabView = require './ladder/my_matches_tab'
LadderPlayModal = require './ladder/play_modal'
SimulatorsLeaderboardCollection = require 'collections/SimulatorsLeaderboardCollection'
CocoClass = require 'lib/CocoClass'
HIGHEST_SCORE = 1000000
@ -42,6 +44,9 @@ module.exports = class LadderView extends RootView
@sessions.fetch({})
@addResourceToLoad(@sessions, 'your_sessions')
@addResourceToLoad(@level, 'level')
@simulatorsLeaderboardData = new SimulatorsLeaderboardData(me)
@simulatorsLeaderboardData.fetch({})
@addResourceToLoad(@simulatorsLeaderboardData, 'top_simulators')
@simulator = new Simulator()
@listenTo(@simulator, 'statusUpdate', @updateSimulationStatus)
@teams = []
@ -58,6 +63,7 @@ module.exports = class LadderView extends RootView
ctx.teams = @teams
ctx.levelID = @levelID
ctx.levelDescription = marked(@level.get('description')) if @level.get('description')
ctx.simulatorsLeaderboardData = @simulatorsLeaderboardData
ctx
afterRender: ->
@ -156,3 +162,58 @@ module.exports = class LadderView extends RootView
clearInterval @refreshInterval
@simulator.destroy()
super()
class SimulatorsLeaderboardData extends CocoClass
###
Consolidates what you need to load for a leaderboard into a single Backbone Model-like object.
###
constructor: (@me) ->
super()
@fetch()
fetch: ->
@topSimulators = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: -1, limit: 20})
promises = []
promises.push @topSimulators.fetch()
if !@me.get('anonymous')
score = @me.get('simulatedBy') or 10
@playersAbove = new SimulatorsLeaderboardCollection({order:1, scoreOffset: score, limit: 4})
promises.push @playersAbove.fetch()
@playersBelow = new SimulatorsLeaderboardCollection({order:-1, scoreOffset: score, limit: 4})
promises.push @playersBelow.fetch()
@promise = $.when(promises...)
@promise.then @onLoad
@promise.fail @onFail
@promise
onLoad: =>
return if @destroyed
@loaded = true
@trigger 'sync', @
onFail: (resource, jqxhr) =>
return if @destroyed
@trigger 'error', @, jqxhr
inTopSimulators: ->
return me.id in (user.id for user in @topSimulators.models)
nearbySimulators: ->
#return [] unless @session?.get('totalScore')
l = []
above = @playersAbove.models
above.reverse()
l = l.concat(above)
l.push @me
l = l.concat(@playersBelow.models)
###
if @myRank
startRank = @myRank - 4
session.rank = startRank + i for session, i in l
###
l
allResources: ->
resources = [@topSimulators, @playersAbove, @playersBelow]
return (r for r in resources when r)

View file

@ -154,6 +154,27 @@ UserHandler = class UserHandler extends Handler
res.send(if otherUser then otherUser._id else JSON.stringify(''))
res.end()
getSimulatorLeaderboard: (req, res) ->
@validateSimulateLeaderboardRequestParameters(req)
query = {}
if(req.query.scoreOffset != -1)
simulatedByQuery = {}
simulatedByQuery[if req.query.order is 1 then "$gt" else "$lt"] = req.query.scoreOffset
query.simulatedBy = simulatedByQuery
query.simulatedFor = {"$gt": 0}
User
.find(query)
.limit(req.query.limit)
.sort('-simulatedBy').select('name simulatedBy simulatedFor').exec (err, otherUser) ->
res.send(otherUser)
res.end()
validateSimulateLeaderboardRequestParameters: (req) ->
req.query.order = parseInt(req.query.order) ? -1
req.query.scoreOffset = parseFloat(req.query.scoreOffset) ? 100000
req.query.limit = parseInt(req.query.limit) ? 20
post: (req, res) ->
return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body)
return @sendBadInputError(res, 'Must have an anonymous user to post with.') unless req.user
@ -174,6 +195,7 @@ UserHandler = class UserHandler extends Handler
return @nameToID(req, res, args[0]) if args[1] is 'nameToID'
return @getLevelSessions(req, res, args[0]) if args[1] is 'level.sessions'
return @getCandidates(req, res) if args[1] is 'candidates'
return @getSimulatorLeaderboard(req, res, args[0]) if args[1] is 'simulatorLeaderboard'
return @sendNotFoundError(res)
super(arguments...)