mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-18 11:32:25 -05:00
153 lines
5.7 KiB
CoffeeScript
153 lines
5.7 KiB
CoffeeScript
CocoView = require 'views/core/CocoView'
|
|
CocoClass = require 'core/CocoClass'
|
|
SimulatorsLeaderboardCollection = require 'collections/SimulatorsLeaderboardCollection'
|
|
Simulator = require 'lib/simulator/Simulator'
|
|
{me} = require 'core/auth'
|
|
|
|
module.exports = class SimulateTabView extends CocoView
|
|
id: 'simulate-tab-view'
|
|
template: require 'templates/play/ladder/simulate_tab'
|
|
|
|
events:
|
|
'click #simulate-button': 'onSimulateButtonClick'
|
|
|
|
initialize: ->
|
|
@simulatorsLeaderboardData = new SimulatorsLeaderboardData(me)
|
|
@simulatorsLeaderboardDataRes = @supermodel.addModelResource(@simulatorsLeaderboardData, 'top_simulators', {cache: false})
|
|
@simulatorsLeaderboardDataRes.load()
|
|
require 'vendor/aether-javascript'
|
|
require 'vendor/aether-python'
|
|
require 'vendor/aether-coffeescript'
|
|
require 'vendor/aether-lua'
|
|
require 'vendor/aether-java'
|
|
|
|
onLoaded: ->
|
|
super()
|
|
@render()
|
|
if (document.location.hash is '#simulate' or @options.level.isType('course-ladder')) and not @simulator
|
|
@startSimulating()
|
|
|
|
afterRender: ->
|
|
super()
|
|
|
|
# Simulations
|
|
|
|
onSimulateButtonClick: (e) ->
|
|
application.tracker?.trackEvent 'Simulate Button Click'
|
|
@startSimulating()
|
|
|
|
startSimulating: ->
|
|
@simulationPageRefreshTimeout = _.delay @refreshAndContinueSimulating, 30 * 60 * 1000
|
|
@simulateNextGame()
|
|
$('#simulate-button').prop 'disabled', true
|
|
$('#simulate-button').text 'Simulating...'
|
|
|
|
refreshAndContinueSimulating: =>
|
|
# We refresh the page every now and again to make sure simulations haven't gotten derailed by bogus games, and that simulators don't hang on to old, stale code or data.
|
|
document.location.hash = '#simulate'
|
|
document.location.reload()
|
|
|
|
simulateNextGame: ->
|
|
unless @simulator
|
|
@simulator = new Simulator levelID: @options.level.get('slug'), leagueID: @options.leagueID
|
|
@listenTo @simulator, 'statusUpdate', @updateSimulationStatus
|
|
# Work around simulator getting super slow on Chrome
|
|
fetchAndSimulateTaskOriginal = @simulator.fetchAndSimulateTask
|
|
@simulator.fetchAndSimulateTask = =>
|
|
return if @destroyed
|
|
if @simulator.simulatedByYou >= 20
|
|
console.log '------------------- Destroying Simulator and making a new one -----------------'
|
|
@simulator.destroy()
|
|
@simulator = null
|
|
@simulateNextGame()
|
|
else
|
|
fetchAndSimulateTaskOriginal.apply @simulator
|
|
@simulator.fetchAndSimulateTask()
|
|
|
|
refresh: ->
|
|
return # Queue-based scoring is currently not active anyway, so don't keep checking this until we fix it.
|
|
success = (numberOfGamesInQueue) ->
|
|
$('#games-in-queue').text numberOfGamesInQueue
|
|
$.ajax '/queue/messagesInQueueCount', cache: false, success: success
|
|
|
|
updateSimulationStatus: (simulationStatus, sessions) ->
|
|
if simulationStatus is 'Fetching simulation data!'
|
|
@simulationMatchDescription = ''
|
|
@simulationSpectateLink = ''
|
|
@simulationStatus = _.string.escapeHTML(simulationStatus)
|
|
try
|
|
if sessions?
|
|
@simulationMatchDescription = ''
|
|
@simulationSpectateLink = "/play/spectate/#{@simulator.level.get('slug')}?"
|
|
for session, index in sessions
|
|
# TODO: Fetch names from Redis, the creatorName is denormalized
|
|
@simulationMatchDescription += "#{if index then ' vs ' else ''}#{session.creatorName or 'Anonymous'} (#{sessions[index].team})"
|
|
@simulationSpectateLink += "session-#{if index then 'two' else 'one'}=#{session.sessionID}"
|
|
@simulationMatchDescription += " on #{@simulator.level.get('name')}"
|
|
catch e
|
|
console.log "There was a problem with the named simulation status: #{e}"
|
|
link = if @simulationSpectateLink then "<a href=#{@simulationSpectateLink}>#{_.string.escapeHTML(@simulationMatchDescription)}</a>" else ''
|
|
$('#simulation-status-text').html "<h3>#{@simulationStatus}</h3>#{link}"
|
|
|
|
destroy: ->
|
|
clearTimeout @simulationPageRefreshTimeout
|
|
@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: ->
|
|
@topSimulators = new SimulatorsLeaderboardCollection({order: -1, scoreOffset: -1, limit: 20})
|
|
promises = []
|
|
promises.push @topSimulators.fetch()
|
|
unless @me.get('anonymous')
|
|
score = @me.get('simulatedBy') or 0
|
|
queueSuccess = (@numberOfGamesInQueue) =>
|
|
promises.push $.ajax '/queue/messagesInQueueCount', {success: queueSuccess, cache: false}
|
|
@playersAbove = new SimulatorsLeaderboardCollection({order: 1, scoreOffset: score, limit: 4})
|
|
promises.push @playersAbove.fetch()
|
|
if score
|
|
@playersBelow = new SimulatorsLeaderboardCollection({order: -1, scoreOffset: score, limit: 4})
|
|
promises.push @playersBelow.fetch()
|
|
success = (@myRank) =>
|
|
promises.push $.ajax("/db/user/me/simulator_leaderboard_rank?scoreOffset=#{score}", cache: false, success: success)
|
|
|
|
@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 [] if not @playersAbove?.models
|
|
l = []
|
|
above = @playersAbove.models
|
|
l = l.concat(above)
|
|
l.reverse()
|
|
l.push @me
|
|
l = l.concat(@playersBelow.models) if @playersBelow
|
|
if @myRank
|
|
startRank = @myRank - 4
|
|
user.rank = startRank + i for user, i in l
|
|
l
|
|
|
|
allResources: ->
|
|
resources = [@topSimulators, @playersAbove, @playersBelow]
|
|
return (r for r in resources when r)
|