mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-24 21:13:35 -04:00
Merge branch 'master' into play-button
This commit is contained in:
commit
04895a9204
20 changed files with 259 additions and 53 deletions
app
lib
styles/play/level/modal
templates
treema-ext.coffeeviews
server
|
@ -113,7 +113,6 @@ module.exports = class LevelBus extends Bus
|
|||
@changedSessionProperties.teamSpells = true
|
||||
@session.set({'teamSpells': @teamSpellMap})
|
||||
@saveSession()
|
||||
console.log spellTeam, me.team, e.spell.spellKey
|
||||
if spellTeam is me.team
|
||||
@onSpellChanged e # Save the new spell to the session, too.
|
||||
|
||||
|
|
|
@ -110,16 +110,19 @@ module.exports = class LevelLoader extends CocoClass
|
|||
@updateCompleted = true
|
||||
|
||||
denormalizeSession: ->
|
||||
return if @session.get 'levelName'
|
||||
return if @sessionDenormalized
|
||||
patch =
|
||||
'levelName': @level.get('name')
|
||||
'levelID': @level.get('slug') or @level.id
|
||||
if me.id is @session.get 'creator'
|
||||
patch.creatorName = me.get('name')
|
||||
|
||||
@session.set key, value for key, value of patch
|
||||
tempSession = new LevelSession _id: @session.id
|
||||
tempSession.save(patch, {patch: true})
|
||||
for key, value of patch
|
||||
if @session.get(key) is value
|
||||
delete patch[key]
|
||||
unless _.isEmpty patch
|
||||
@session.set key, value for key, value of patch
|
||||
tempSession = new LevelSession _id: @session.id
|
||||
tempSession.save(patch, {patch: true})
|
||||
@sessionDenormalized = true
|
||||
|
||||
# World init
|
||||
|
|
|
@ -64,7 +64,7 @@ module.exports = class Simulator
|
|||
|
||||
setupGoalManager: ->
|
||||
@god.goalManager = new GoalManager @world
|
||||
@god.goalManager.goals = @fetchGoalsFromWorldNoteChain()
|
||||
@god.goalManager.goals = @god.level.goals
|
||||
@god.goalManager.goalStates = @manuallyGenerateGoalStates()
|
||||
|
||||
commenceSimulationAndSetupCallback: ->
|
||||
|
@ -108,17 +108,22 @@ module.exports = class Simulator
|
|||
taskResults =
|
||||
taskID: @task.getTaskID()
|
||||
receiptHandle: @task.getReceiptHandle()
|
||||
originalSessionID: @task.getFirstSessionID()
|
||||
originalSessionRank: -1
|
||||
calculationTime: 500
|
||||
sessions: []
|
||||
|
||||
for session in @task.getSessions()
|
||||
|
||||
sessionResult =
|
||||
sessionID: session.sessionID
|
||||
submitDate: session.submitDate
|
||||
creator: session.creator
|
||||
metrics:
|
||||
rank: @calculateSessionRank session.sessionID, simulationResults.goalStates, @task.generateTeamToSessionMap()
|
||||
|
||||
if session.sessionID is taskResults.originalSessionID
|
||||
taskResults.originalSessionRank = sessionResult.metrics.rank
|
||||
taskResults.originalSessionTeam = session.team
|
||||
taskResults.sessions.push sessionResult
|
||||
|
||||
return taskResults
|
||||
|
@ -137,8 +142,6 @@ module.exports = class Simulator
|
|||
else
|
||||
return 1
|
||||
|
||||
fetchGoalsFromWorldNoteChain: -> return @god.goalManager.world.scripts[0].noteChain[0].goals.add
|
||||
|
||||
manuallyGenerateGoalStates: ->
|
||||
goalStates =
|
||||
"destroy-humans":
|
||||
|
@ -190,7 +193,7 @@ module.exports = class Simulator
|
|||
spellKeyComponents[0] = _.string.slugify spellKeyComponents[0]
|
||||
spellKey = spellKeyComponents.join '/'
|
||||
spellKey
|
||||
|
||||
|
||||
|
||||
createSpellAndAssignName: (spellKey, spellName) ->
|
||||
@spells[spellKey] ?= {}
|
||||
|
@ -262,10 +265,10 @@ class SimulationTask
|
|||
fullSpellName = [thangName,spellName].join '/'
|
||||
if _.contains(teamSpells, fullSpellName)
|
||||
teamCode[fullSpellName]=spell
|
||||
|
||||
|
||||
_.merge spellKeyToSourceMap, teamCode
|
||||
commonSpells = session.teamSpells["common"]
|
||||
_.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells?
|
||||
|
||||
|
||||
|
||||
spellKeyToSourceMap
|
||||
|
|
|
@ -5,6 +5,7 @@ module.exports = class PointChooser extends CocoClass
|
|||
super()
|
||||
@buildShape()
|
||||
@options.stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@options.camera.dragDisabled = true
|
||||
|
||||
destroy: ->
|
||||
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
|
|
|
@ -7,6 +7,7 @@ module.exports = class RegionChooser extends CocoClass
|
|||
@options.stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@options.stage.addEventListener 'stagemousemove', @onMouseMove
|
||||
@options.stage.addEventListener 'stagemouseup', @onMouseUp
|
||||
@options.camera.dragDisabled = true
|
||||
|
||||
destroy: ->
|
||||
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
|
|
|
@ -25,6 +25,7 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
|
||||
constructor: (@options) ->
|
||||
super()
|
||||
@dragged = 0
|
||||
@options ?= {}
|
||||
@camera = @options.camera
|
||||
@surfaceLayer = @options.surfaceLayer
|
||||
|
@ -238,11 +239,12 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
@selectThang e.thangID, e.spellName
|
||||
|
||||
onCameraDragged: ->
|
||||
@dragged = true
|
||||
@dragged += 1
|
||||
|
||||
onSpriteMouseUp: (e) ->
|
||||
return if key.shift and @options.choosing
|
||||
return @dragged = false if @dragged
|
||||
return @dragged = 0 if @dragged > 3
|
||||
@dragged = 0
|
||||
sprite = if e.sprite?.thang?.isSelectable then e.sprite else null
|
||||
@selectSprite e, sprite
|
||||
|
||||
|
|
2
app/styles/play/level/modal/docs.sass
Normal file
2
app/styles/play/level/modal/docs.sass
Normal file
|
@ -0,0 +1,2 @@
|
|||
#docs-modal .modal-dialog
|
||||
width: 800px
|
|
@ -2,6 +2,18 @@ extends /templates/base
|
|||
|
||||
block content
|
||||
|
||||
h3 Espionage mode
|
||||
h5 Please enter the email/username of the person you want to spy on
|
||||
.form
|
||||
.form-group
|
||||
label.control-label Email
|
||||
input#user-email
|
||||
.form-group
|
||||
label.control-label Username
|
||||
input#user-username
|
||||
|
||||
button.btn.btn-primary.btn-large#enter-espionage-mode 007
|
||||
|
||||
h3(data-i18n="admin.av_title") Admin Views
|
||||
|
||||
h4(data-i18n="admin.av_entities_sub_title") Entities
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
h4.home
|
||||
|
||||
a(href="/")
|
||||
a(href=homeLink || "/")
|
||||
i.icon-home.icon-white
|
||||
span(data-i18n="play_level.home") Home
|
||||
|
||||
h4.title #{worldName}
|
||||
|
||||
button.btn.btn-xs.btn-inverse.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide
|
||||
button.btn.btn-xs.btn-success.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide
|
||||
|
||||
if ladderGame
|
||||
button.btn.btn-xs.btn-inverse.banner#multiplayer-button(title="Leaderboard", data-i18n="play_level.leaderboard") Leaderboard
|
||||
|
|
|
@ -38,12 +38,13 @@ class LiveEditingMarkup extends TreemaNode.nodeMap.ace
|
|||
url: InkBlob.url
|
||||
filename: InkBlob.filename
|
||||
mimetype: InkBlob.mimetype
|
||||
description: ''
|
||||
createdFor: []
|
||||
path: @settings.filePath
|
||||
|
||||
@uploadingPath = [@settings.filePath, InkBlob.filename].join('/')
|
||||
$.ajax('/file', { type: 'POST', data: body, success: @onFileUploaded })
|
||||
|
||||
onFileUploaded: (e) =>
|
||||
@editor.insert ""
|
||||
@editor.insert ""
|
||||
|
||||
onEditorChange: =>
|
||||
@saveChanges()
|
||||
|
|
|
@ -1,6 +1,35 @@
|
|||
{backboneFailure, genericFailure} = require 'lib/errors'
|
||||
View = require 'views/kinds/RootView'
|
||||
template = require 'templates/admin'
|
||||
storage = require 'lib/storage'
|
||||
|
||||
module.exports = class AdminView extends View
|
||||
id: "admin-view"
|
||||
template: template
|
||||
|
||||
events:
|
||||
'click #enter-espionage-mode': 'enterEspionageMode'
|
||||
|
||||
enterEspionageMode: ->
|
||||
userEmail = $("#user-email").val().toLowerCase()
|
||||
username = $("#user-username").val().toLowerCase()
|
||||
|
||||
userIdentifier = userEmail || username
|
||||
postData =
|
||||
usernameLower: username
|
||||
emailLower: userEmail
|
||||
|
||||
$.ajax
|
||||
type: "POST",
|
||||
url: "/auth/spy"
|
||||
data: postData
|
||||
success: @espionageSuccess
|
||||
error: @espionageFailure
|
||||
|
||||
espionageSuccess: (model) ->
|
||||
storage.save('whoami',model)
|
||||
window.location.reload()
|
||||
espionageFailure: (jqxhr, status,error)->
|
||||
console.log "There was an error entering espionage mode: #{error}"
|
||||
|
||||
|
|
@ -35,6 +35,7 @@ module.exports = class ArticleEditView extends View
|
|||
data = $.extend(true, {}, @article.attributes)
|
||||
options =
|
||||
data: data
|
||||
filePath: "db/thang.type/#{@article.get('original')}"
|
||||
schema: Article.schema.attributes
|
||||
callbacks:
|
||||
change: @pushChangesToPreview
|
||||
|
|
|
@ -47,12 +47,17 @@ module.exports = class ControlBarView extends View
|
|||
text += " (#{numPlayers})" if numPlayers > 1
|
||||
$('#multiplayer-button', @$el).text(text)
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
super context
|
||||
context.worldName = @worldName
|
||||
context.multiplayerEnabled = @session.get('multiplayer')
|
||||
context.ladderGame = @ladderGame
|
||||
context
|
||||
getRenderData: (c={}) ->
|
||||
super c
|
||||
c.worldName = @worldName
|
||||
c.multiplayerEnabled = @session.get('multiplayer')
|
||||
c.ladderGame = @ladderGame
|
||||
c.homeLink = "/"
|
||||
levelID = @level.get('slug')
|
||||
if levelID in ["project-dota", "brawlwood", "ladder-tutorial"]
|
||||
levelID = 'project-dota' if levelID is 'ladder-tutorial'
|
||||
c.homeLink = "/play/ladder/" + levelID
|
||||
c
|
||||
|
||||
showGuideModal: ->
|
||||
options = {docs: @level.get('documentation'), supermodel: @supermodel}
|
||||
|
|
|
@ -270,7 +270,7 @@ module.exports = class HUDView extends View
|
|||
if prop is "rotation"
|
||||
return (val * 180 / Math.PI).toFixed(0) + "˚"
|
||||
if typeof val is 'number'
|
||||
if Math.round(val) == val then return val.toFixed(0) # int
|
||||
if Math.round(val) == val or prop is 'gold' then return val.toFixed(0) # int
|
||||
if -10 < val < 10 then return val.toFixed(2)
|
||||
if -100 < val < 100 then return val.toFixed(1)
|
||||
return val.toFixed(0)
|
||||
|
|
|
@ -6,6 +6,7 @@ Article = require 'models/Article'
|
|||
|
||||
module.exports = class DocsModal extends View
|
||||
template: template
|
||||
id: 'docs-modal'
|
||||
|
||||
shortcuts:
|
||||
'enter': 'hide'
|
||||
|
|
|
@ -82,11 +82,20 @@ module.exports = class DebugView extends View
|
|||
else
|
||||
@$el.hide()
|
||||
if @variableChain?.length is 2
|
||||
Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: @variableChain[1], owner: @variableChain[0]
|
||||
clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout
|
||||
@hoveredPropertyTimeout = _.delay @notifyPropertyHovered, 500
|
||||
else
|
||||
Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: null
|
||||
@notifyPropertyHovered()
|
||||
@updateMarker()
|
||||
|
||||
notifyPropertyHovered: =>
|
||||
clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout
|
||||
@hoveredPropertyTimeout = null
|
||||
oldHoveredProperty = @hoveredProperty
|
||||
@hoveredProperty = if @variableChain?.length is 2 then owner: @variableChain[0], property: @variableChain[1] else {}
|
||||
unless _.isEqual oldHoveredProperty, @hoveredProperty
|
||||
Backbone.Mediator.publish 'tome:spell-debug-property-hovered', @hoveredProperty
|
||||
|
||||
updateMarker: ->
|
||||
if @marker
|
||||
@ace.getSession().removeMarker @marker
|
||||
|
|
|
@ -141,17 +141,13 @@ module.exports = class PlayLevelView extends View
|
|||
|
||||
otherSession = @levelLoader.opponentSession
|
||||
opponentCode = otherSession?.get('submittedCode') or {}
|
||||
console.log "otherSession", otherSession, "opponentSpells", opponentSpells
|
||||
myCode = @session.get('code') or {}
|
||||
for spell in opponentSpells
|
||||
[thang, spell] = spell.split '/'
|
||||
c = opponentCode[thang]?[spell]
|
||||
console.log "Got opponent code", c, "for", spell, "and had my code", myCode[spell]
|
||||
myCode[thang] ?= {}
|
||||
if c then myCode[thang][spell] = c else delete myCode[thang][spell]
|
||||
console.log "Going to set session code from", _.cloneDeep(myCode)
|
||||
@session.set('code', myCode)
|
||||
console.log "Just set session code to", _.cloneDeep(@session.get('code'))
|
||||
if @session.get('multiplayer') and otherSession?
|
||||
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
|
||||
@session.set 'multiplayer', false
|
||||
|
|
|
@ -139,6 +139,13 @@ _.extend LevelSessionSchema.properties,
|
|||
|
||||
submittedCode:
|
||||
type: 'object'
|
||||
|
||||
numberOfWinsAndTies:
|
||||
type: 'number'
|
||||
default: 0
|
||||
numberOfLosses:
|
||||
type: 'number'
|
||||
default: 0
|
||||
|
||||
matches:
|
||||
type: 'array'
|
||||
|
|
|
@ -12,7 +12,7 @@ TaskLog = require './task/ScoringTask'
|
|||
bayes = new (require 'bayesian-battle')()
|
||||
|
||||
scoringTaskQueue = undefined
|
||||
scoringTaskTimeoutInSeconds = 120
|
||||
scoringTaskTimeoutInSeconds = 180
|
||||
|
||||
|
||||
module.exports.setup = (app) -> connectToScoringQueue()
|
||||
|
@ -24,24 +24,27 @@ connectToScoringQueue = ->
|
|||
scoringTaskQueue = data
|
||||
log.info "Connected to scoring task queue!"
|
||||
|
||||
module.exports.addPairwiseTaskToQueue = (req, res) ->
|
||||
module.exports.addPairwiseTaskToQueueFromRequest = (req, res) ->
|
||||
taskPair = req.body.sessions
|
||||
#unless isUserAdmin req then return errors.forbidden res, "You do not have the permissions to submit that game to the leaderboard"
|
||||
#fetch both sessions
|
||||
addPairwiseTaskToQueue req.body.sessions (err, success) ->
|
||||
if err? then return errors.serverError res, "There was an error adding pairwise tasks: #{err}"
|
||||
sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
|
||||
|
||||
|
||||
addPairwiseTaskToQueue = (taskPair, cb) ->
|
||||
LevelSession.findOne(_id:taskPair[0]).lean().exec (err, firstSession) =>
|
||||
if err? then return errors.serverError res, "There was an error fetching the first session in the pair"
|
||||
if err? then return cb err, false
|
||||
LevelSession.find(_id:taskPair[1]).exec (err, secondSession) =>
|
||||
if err? then return errors.serverError res, "There was an error fetching the second session"
|
||||
if err? then return cb err, false
|
||||
try
|
||||
taskPairs = generateTaskPairs(secondSession, firstSession)
|
||||
catch e
|
||||
if e then return errors.serverError res, "There was an error generating the task pairs"
|
||||
|
||||
sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
|
||||
if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue"
|
||||
if e then return cb e, false
|
||||
|
||||
sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
|
||||
|
||||
sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
|
||||
if taskPairError? then return cb taskPairError,false
|
||||
cb null, true
|
||||
|
||||
|
||||
module.exports.createNewTask = (req, res) ->
|
||||
requestSessionID = req.body.session
|
||||
|
@ -56,8 +59,8 @@ module.exports.createNewTask = (req, res) ->
|
|||
|
||||
updateSessionToSubmit sessionToSubmit, (err, data) ->
|
||||
if err? then return errors.serverError res, "There was an error updating the session"
|
||||
|
||||
fetchSessionsToRankAgainst (err, sessionsToRankAgainst) ->
|
||||
opposingTeam = calculateOpposingTeam(sessionToSubmit.team)
|
||||
fetchInitialSessionsToRankAgainst opposingTeam, (err, sessionsToRankAgainst) ->
|
||||
if err? then return errors.serverError res, "There was an error fetching the sessions to rank against"
|
||||
|
||||
taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit)
|
||||
|
@ -114,9 +117,102 @@ module.exports.processTaskResult = (req, res) ->
|
|||
|
||||
addMatchToSessions clientResponseObject, newScoresObject, (err, data) ->
|
||||
if err? then return errors.serverError res, "There was an error updating the sessions with the match! #{JSON.stringify err}"
|
||||
console.log "Sending response object"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully!"}
|
||||
|
||||
originalSessionID = clientResponseObject.originalSessionID
|
||||
originalSessionTeam = clientResponseObject.originalSessionTeam
|
||||
originalSessionRank = parseInt clientResponseObject.originalSessionRank
|
||||
|
||||
determineIfSessionShouldContinueAndUpdateLog originalSessionID, originalSessionRank, (err, sessionShouldContinue) ->
|
||||
if err? then return errors.serverError res, "There was an error determining if the session should continue, #{err}"
|
||||
|
||||
if sessionShouldContinue
|
||||
opposingTeam = calculateOpposingTeam(originalSessionTeam)
|
||||
opponentID = _.pull(_.keys(newScoresObject), originalSessionID)
|
||||
sessionNewScore = newScoresObject[originalSessionID].totalScore
|
||||
opponentNewScore = newScoresObject[opponentID].totalScore
|
||||
findNearestBetterSessionID sessionNewScore, opponentNewScore, opponentID ,opposingTeam, (err, opponentSessionID) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the nearest sessionID!"
|
||||
unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"}
|
||||
|
||||
addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) ->
|
||||
if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
|
||||
else
|
||||
console.log "Player lost, achieved rank #{originalSessionRank}"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
|
||||
|
||||
|
||||
determineIfSessionShouldContinueAndUpdateLog = (sessionID, sessionRank, cb) ->
|
||||
queryParameters =
|
||||
_id: sessionID
|
||||
|
||||
updateParameters =
|
||||
"$inc": {}
|
||||
|
||||
if sessionRank is 0
|
||||
updateParameters["$inc"] = {numberOfWinsAndTies: 1}
|
||||
else
|
||||
updateParameters["$inc"] = {numberOfLosses: 1}
|
||||
|
||||
LevelSession.findOneAndUpdate queryParameters, updateParameters,{select: 'numberOfWinsAndTies numberOfLosses'}, (err, updatedSession) ->
|
||||
if err? then return cb err, updatedSession
|
||||
updatedSession = updatedSession.toObject()
|
||||
|
||||
totalNumberOfGamesPlayed = updatedSession.numberOfWinsAndTies + updatedSession.numberOfLosses
|
||||
if totalNumberOfGamesPlayed < 5
|
||||
console.log "Number of games played is less than 5, continuing..."
|
||||
cb null, true
|
||||
else if totalNumberOfGamesPlayed > 15
|
||||
console.log "Too many games played, ending..."
|
||||
cb null, false
|
||||
else
|
||||
ratio = (updatedSession.numberOfLosses - 5) / (totalNumberOfGamesPlayed)
|
||||
if ratio > 0.66
|
||||
cb null, false
|
||||
console.log "Ratio(#{ratio}) is bad, ending simulation"
|
||||
else
|
||||
console.log "Ratio(#{ratio}) is good, so continuing simulations"
|
||||
cb null, true
|
||||
|
||||
|
||||
findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, opponentSessionID, opposingTeam, cb) ->
|
||||
queryParameters =
|
||||
totalScore:
|
||||
$gt:opponentSessionTotalScore + 0.5
|
||||
_id:
|
||||
$ne: opponentSessionID
|
||||
levelID: "project-dota"
|
||||
submitted: true
|
||||
submittedCode:
|
||||
$exists: true
|
||||
team: opposingTeam
|
||||
|
||||
limitNumber = 1
|
||||
|
||||
sortParameters =
|
||||
totalScore: 1
|
||||
|
||||
selectString = '_id totalScore'
|
||||
|
||||
query = LevelSession.findOne(queryParameters)
|
||||
.sort(sortParameters)
|
||||
.limit(limitNumber)
|
||||
.select(selectString)
|
||||
.lean()
|
||||
|
||||
console.log "Finding session with score near #{opponentSessionTotalScore}"
|
||||
query.exec (err, session) ->
|
||||
if err? then return cb err, session
|
||||
unless session then return cb err, null
|
||||
console.log "Found session with score #{session.totalScore}"
|
||||
cb err, session._id
|
||||
|
||||
calculateOpposingTeam = (sessionTeam) ->
|
||||
teams = ['ogres','humans']
|
||||
opposingTeams = _.pull teams, sessionTeam
|
||||
return opposingTeams[0]
|
||||
|
||||
|
||||
validatePermissions = (req, sessionID, callback) ->
|
||||
if isUserAnonymous req then return callback null, false
|
||||
if isUserAdmin req then return callback null, true
|
||||
|
@ -177,15 +273,30 @@ updateSessionToSubmit = (sessionToUpdate, callback) ->
|
|||
meanStrength: 25
|
||||
standardDeviation: 25/3
|
||||
totalScore: 10
|
||||
numberOfWinsAndTies: 0
|
||||
numberOfLosses: 0
|
||||
LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, callback
|
||||
|
||||
fetchSessionsToRankAgainst = (callback) ->
|
||||
submittedSessionsQuery =
|
||||
fetchInitialSessionsToRankAgainst = (opposingTeam, callback) ->
|
||||
console.log "Fetching sessions to rank against for opposing team #{opposingTeam}"
|
||||
findParameters =
|
||||
levelID: "project-dota"
|
||||
submitted: true
|
||||
submittedCode:
|
||||
$exists: true
|
||||
LevelSession.find submittedSessionsQuery, callback
|
||||
team: opposingTeam
|
||||
|
||||
sortParameters =
|
||||
totalScore: 1
|
||||
|
||||
limitNumber = 1
|
||||
|
||||
query = LevelSession.find(findParameters)
|
||||
.sort(sortParameters)
|
||||
.limit(limitNumber)
|
||||
|
||||
|
||||
query.exec callback
|
||||
|
||||
generateTaskPairs = (submittedSessions, sessionToScore) ->
|
||||
taskPairs = []
|
||||
|
|
|
@ -28,7 +28,30 @@ module.exports.setup = (app) ->
|
|||
return done(null, user)
|
||||
)
|
||||
))
|
||||
|
||||
app.post '/auth/spy', (req, res, next) ->
|
||||
if req?.user?.isAdmin()
|
||||
|
||||
username = req.body.usernameLower
|
||||
emailLower = req.body.emailLower
|
||||
if emailLower
|
||||
query = {"emailLower":emailLower}
|
||||
else if username
|
||||
query = {"nameLower":username}
|
||||
else
|
||||
return errors.badInput res, "You need to supply one of emailLower or username"
|
||||
|
||||
User.findOne query, (err, user) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the specified user"
|
||||
|
||||
unless user then return errors.badInput res, "The specified user couldn't be found"
|
||||
|
||||
req.logIn user, (err) ->
|
||||
if err? then return errors.serverError res, "There was an error logging in with the specified"
|
||||
res.send(UserHandler.formatEntity(req, user))
|
||||
return res.end()
|
||||
else
|
||||
return errors.unauthorized res, "You must be an admin to enter espionage mode"
|
||||
|
||||
app.post('/auth/login', (req, res, next) ->
|
||||
authentication.authenticate('local', (err, user, info) ->
|
||||
return next(err) if err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue