mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 17:45:40 -05:00
Fixed #1329.
This commit is contained in:
parent
5f11a5ecca
commit
85a9a558ef
7 changed files with 64 additions and 79 deletions
48
app/lib/aether_utils.coffee
Normal file
48
app/lib/aether_utils.coffee
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
Aether.addGlobal 'Vector', require 'lib/world/vector'
|
||||||
|
Aether.addGlobal '_', _
|
||||||
|
|
||||||
|
module.exports.createAetherOptions = (options) ->
|
||||||
|
throw new Error 'Specify a function name to create an Aether instance' unless options.functionName
|
||||||
|
throw new Error 'Specify a code language to create an Aether instance' unless options.codeLanguage
|
||||||
|
|
||||||
|
aetherOptions =
|
||||||
|
functionName: options.functionName
|
||||||
|
protectAPI: not options.skipProtectAPI
|
||||||
|
includeFlow: false
|
||||||
|
yieldConditionally: options.functionName is 'plan'
|
||||||
|
globals: ['Vector', '_']
|
||||||
|
problems:
|
||||||
|
jshint_W040: {level: 'ignore'}
|
||||||
|
jshint_W030: {level: 'ignore'} # aether_NoEffect instead
|
||||||
|
jshint_W038: {level: 'ignore'} # eliminates hoisting problems
|
||||||
|
jshint_W091: {level: 'ignore'} # eliminates more hoisting problems
|
||||||
|
jshint_E043: {level: 'ignore'} # https://github.com/codecombat/codecombat/issues/813 -- since we can't actually tell JSHint to really ignore things
|
||||||
|
jshint_Unknown: {level: 'ignore'} # E043 also triggers Unknown, so ignore that, too
|
||||||
|
aether_MissingThis: {level: 'error'}
|
||||||
|
#functionParameters: # TODOOOOO
|
||||||
|
executionLimit: 1 * 1000 * 1000
|
||||||
|
language: options.codeLanguage
|
||||||
|
parameters = functionParameters[options.functionName]
|
||||||
|
unless parameters
|
||||||
|
console.warn "Unknown method #{options.functionName}: please add function parameters to lib/aether_utils.coffee."
|
||||||
|
parameters = []
|
||||||
|
if options.functionParameters and not _.isEqual options.functionParameters, parameters
|
||||||
|
console.error "Update lib/aether_utils.coffee with the right function parameters for #{options.functionName} (had: #{parameters} but this gave #{options.functionParameters}."
|
||||||
|
parameters = options.functionParameters
|
||||||
|
aetherOptions.functionParameters = parameters.slice()
|
||||||
|
#console.log 'creating aether with options', aetherOptions
|
||||||
|
return aetherOptions
|
||||||
|
|
||||||
|
# TODO: figure out some way of saving this info dynamically so that we don't have to hard-code it: #1329
|
||||||
|
functionParameters =
|
||||||
|
hear: ['speaker', 'message', 'data']
|
||||||
|
makeBid: ['tileGroupLetter']
|
||||||
|
findCentroids: ['centroids']
|
||||||
|
isFriend: ['name']
|
||||||
|
evaluateBoard: ['board', 'player']
|
||||||
|
getPossibleMoves: ['board']
|
||||||
|
minimax_alphaBeta: ['board', 'player', 'depth', 'alpha', 'beta']
|
||||||
|
|
||||||
|
chooseAction: []
|
||||||
|
plan: []
|
||||||
|
initializeCentroids: []
|
|
@ -3,9 +3,7 @@ CocoClass = require 'lib/CocoClass'
|
||||||
LevelLoader = require 'lib/LevelLoader'
|
LevelLoader = require 'lib/LevelLoader'
|
||||||
GoalManager = require 'lib/world/GoalManager'
|
GoalManager = require 'lib/world/GoalManager'
|
||||||
God = require 'lib/God'
|
God = require 'lib/God'
|
||||||
|
{createAetherOptions} = require 'lib/aether_utils'
|
||||||
Aether.addGlobal 'Vector', require 'lib/world/vector'
|
|
||||||
Aether.addGlobal '_', _
|
|
||||||
|
|
||||||
module.exports = class Simulator extends CocoClass
|
module.exports = class Simulator extends CocoClass
|
||||||
constructor: (@options) ->
|
constructor: (@options) ->
|
||||||
|
@ -400,23 +398,7 @@ module.exports = class Simulator extends CocoClass
|
||||||
aether.transpile ''
|
aether.transpile ''
|
||||||
|
|
||||||
createAether: (methodName, method, useProtectAPI, codeLanguage) ->
|
createAether: (methodName, method, useProtectAPI, codeLanguage) ->
|
||||||
aetherOptions =
|
aetherOptions = createAetherOptions functionName: methodName, codeLanguage: codeLanguage, skipProtectAPI: not useProtectAPI
|
||||||
functionName: methodName
|
|
||||||
protectAPI: useProtectAPI
|
|
||||||
includeFlow: false
|
|
||||||
yieldConditionally: methodName is 'plan'
|
|
||||||
globals: ['Vector', '_']
|
|
||||||
problems:
|
|
||||||
jshint_W040: {level: 'ignore'}
|
|
||||||
jshint_W030: {level: 'ignore'} # aether_NoEffect instead
|
|
||||||
aether_MissingThis: {level: 'error'}
|
|
||||||
#functionParameters: # TODOOOOO
|
|
||||||
executionLimit: 1 * 1000 * 1000
|
|
||||||
language: codeLanguage
|
|
||||||
if methodName is 'hear' then aetherOptions.functionParameters = ['speaker', 'message', 'data']
|
|
||||||
if methodName is 'makeBid' then aetherOptions.functionParameters = ['tileGroupLetter']
|
|
||||||
if methodName is 'findCentroids' then aetherOptions.functionParameters = ['centroids']
|
|
||||||
#console.log 'creating aether with options', aetherOptions
|
|
||||||
return new Aether aetherOptions
|
return new Aether aetherOptions
|
||||||
|
|
||||||
class SimulationTask
|
class SimulationTask
|
||||||
|
|
|
@ -62,7 +62,7 @@ module.exports = class ThangType extends CocoModel
|
||||||
options
|
options
|
||||||
|
|
||||||
buildSpriteSheet: (options) ->
|
buildSpriteSheet: (options) ->
|
||||||
return false unless @isFullyLoaded()
|
return false unless @isFullyLoaded() and @get 'raw'
|
||||||
@options = @fillOptions options
|
@options = @fillOptions options
|
||||||
key = @spriteSheetKey(@options)
|
key = @spriteSheetKey(@options)
|
||||||
if ss = @spriteSheets[key] then return ss
|
if ss = @spriteSheets[key] then return ss
|
||||||
|
|
|
@ -122,7 +122,7 @@ _.extend LevelSessionSchema.properties,
|
||||||
type: 'object'
|
type: 'object'
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
format: 'javascript'
|
format: 'code'
|
||||||
|
|
||||||
codeLanguage:
|
codeLanguage:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -165,6 +165,7 @@ _.extend LevelSessionSchema.properties,
|
||||||
type: 'object'
|
type: 'object'
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
format: 'code'
|
||||||
|
|
||||||
submittedCodeLanguage:
|
submittedCodeLanguage:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
@ -175,6 +176,7 @@ _.extend LevelSessionSchema.properties,
|
||||||
type: 'object'
|
type: 'object'
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: 'string'
|
type: 'string'
|
||||||
|
format: 'code'
|
||||||
|
|
||||||
isRanking:
|
isRanking:
|
||||||
type: 'boolean'
|
type: 'boolean'
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
CocoView = require 'views/kinds/CocoView'
|
CocoView = require 'views/kinds/CocoView'
|
||||||
template = require 'templates/play/common/ladder_submission'
|
template = require 'templates/play/common/ladder_submission'
|
||||||
|
{createAetherOptions} = require 'lib/aether_utils'
|
||||||
|
|
||||||
module.exports = class LadderSubmissionView extends CocoView
|
module.exports = class LadderSubmissionView extends CocoView
|
||||||
className: 'ladder-submission-view'
|
className: 'ladder-submission-view'
|
||||||
|
@ -72,29 +73,15 @@ module.exports = class LadderSubmissionView extends CocoView
|
||||||
|
|
||||||
transpileSession: ->
|
transpileSession: ->
|
||||||
submittedCode = @session.get('code')
|
submittedCode = @session.get('code')
|
||||||
language = @session.get('codeLanguage') or 'javascript'
|
codeLanguage = @session.get('codeLanguage') or 'javascript'
|
||||||
@session.set('submittedCodeLanguage', language)
|
@session.set('submittedCodeLanguage', codeLanguage)
|
||||||
@session.save() # TODO: maybe actually use a callback to make sure this works?
|
@session.save() # TODO: maybe actually use a callback to make sure this works?
|
||||||
transpiledCode = {}
|
transpiledCode = {}
|
||||||
for thang, spells of submittedCode
|
for thang, spells of submittedCode
|
||||||
transpiledCode[thang] = {}
|
transpiledCode[thang] = {}
|
||||||
for spellID, spell of spells
|
for spellID, spell of spells
|
||||||
unless _.contains(@session.get('teamSpells')[@session.get('team')], thang + '/' + spellID) then continue
|
unless _.contains(@session.get('teamSpells')[@session.get('team')], thang + '/' + spellID) then continue
|
||||||
#DRY this
|
aetherOptions = createAetherOptions functionName: spellID, codeLanguage: codeLanguage
|
||||||
aetherOptions =
|
|
||||||
problems: {}
|
|
||||||
language: language
|
|
||||||
functionName: spellID
|
|
||||||
functionParameters: []
|
|
||||||
yieldConditionally: spellID is 'plan'
|
|
||||||
globals: ['Vector', '_']
|
|
||||||
protectAPI: true
|
|
||||||
includeFlow: false
|
|
||||||
executionLimit: 1 * 1000 * 1000
|
|
||||||
if spellID is 'hear' then aetherOptions.functionParameters = ['speaker', 'message', 'data']
|
|
||||||
if spellID is 'makeBid' then aetherOptions.functionParameters = ['tileGroupLetter']
|
|
||||||
if spellID is 'findCentroids' then aetherOptions.functionParameters = ['centroids']
|
|
||||||
|
|
||||||
aether = new Aether aetherOptions
|
aether = new Aether aetherOptions
|
||||||
transpiledCode[thang][spellID] = aether.transpile spell
|
transpiledCode[thang][spellID] = aether.transpile spell
|
||||||
transpiledCode
|
transpiledCode
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
SpellView = require './SpellView'
|
SpellView = require './SpellView'
|
||||||
SpellListTabEntryView = require './SpellListTabEntryView'
|
SpellListTabEntryView = require './SpellListTabEntryView'
|
||||||
{me} = require 'lib/auth'
|
{me} = require 'lib/auth'
|
||||||
|
{createAetherOptions} = require 'lib/aether_utils'
|
||||||
Aether.addGlobal 'Vector', require 'lib/world/vector'
|
|
||||||
Aether.addGlobal '_', _
|
|
||||||
|
|
||||||
module.exports = class Spell
|
module.exports = class Spell
|
||||||
loaded: false
|
loaded: false
|
||||||
|
@ -125,25 +123,8 @@ module.exports = class Spell
|
||||||
createAether: (thang) ->
|
createAether: (thang) ->
|
||||||
aceConfig = me.get('aceConfig') ? {}
|
aceConfig = me.get('aceConfig') ? {}
|
||||||
writable = @permissions.readwrite.length > 0
|
writable = @permissions.readwrite.length > 0
|
||||||
aetherOptions =
|
skipProtectAPI = @skipProtectAPI or not writable
|
||||||
problems:
|
aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI
|
||||||
jshint_W040: {level: 'ignore'}
|
|
||||||
jshint_W030: {level: 'ignore'} # aether_NoEffect instead
|
|
||||||
jshint_W038: {level: 'ignore'} # eliminates hoisting problems
|
|
||||||
jshint_W091: {level: 'ignore'} # eliminates more hoisting problems
|
|
||||||
jshint_E043: {level: 'ignore'} # https://github.com/codecombat/codecombat/issues/813 -- since we can't actually tell JSHint to really ignore things
|
|
||||||
jshint_Unknown: {level: 'ignore'} # E043 also triggers Unknown, so ignore that, too
|
|
||||||
aether_MissingThis: {level: 'error'}
|
|
||||||
language: @language
|
|
||||||
functionName: @name
|
|
||||||
functionParameters: @parameters
|
|
||||||
yieldConditionally: thang.plan?
|
|
||||||
globals: ['Vector', '_']
|
|
||||||
# TODO: Gridmancer doesn't currently work with protectAPI, so hack it off
|
|
||||||
protectAPI: not (@skipProtectAPI or window.currentView?.level.get('name').match('Gridmancer')) and writable # If anyone can write to this method, we must protect it.
|
|
||||||
includeFlow: false
|
|
||||||
executionLimit: 1 * 1000 * 1000
|
|
||||||
#console.log 'creating aether with options', aetherOptions
|
|
||||||
aether = new Aether aetherOptions
|
aether = new Aether aetherOptions
|
||||||
workerMessage =
|
workerMessage =
|
||||||
function: 'createAether'
|
function: 'createAether'
|
||||||
|
|
|
@ -8,9 +8,8 @@ async = require 'async'
|
||||||
serverSetup = require '../server_setup'
|
serverSetup = require '../server_setup'
|
||||||
Level = require '../server/levels/Level'
|
Level = require '../server/levels/Level'
|
||||||
LevelSession = require '../server/levels/sessions/LevelSession'
|
LevelSession = require '../server/levels/sessions/LevelSession'
|
||||||
|
{createAetherOptions} = require '../app/lib/aether_utils'
|
||||||
|
|
||||||
Aether.addGlobal 'Vector', require '../app/lib/world/vector'
|
|
||||||
Aether.addGlobal '_', _
|
|
||||||
i = 0
|
i = 0
|
||||||
transpileLevelSession = (sessionID, cb) ->
|
transpileLevelSession = (sessionID, cb) ->
|
||||||
query = LevelSession.findOne('_id': sessionID).select('team teamSpells submittedCode submittedCodeLanguage').lean()
|
query = LevelSession.findOne('_id': sessionID).select('team teamSpells submittedCode submittedCodeLanguage').lean()
|
||||||
|
@ -27,23 +26,9 @@ transpileLevelSession = (sessionID, cb) ->
|
||||||
transpiledCode[thang] = {}
|
transpiledCode[thang] = {}
|
||||||
for spellID, spell of spells
|
for spellID, spell of spells
|
||||||
spellName = thang + '/' + spellID
|
spellName = thang + '/' + spellID
|
||||||
|
continue if session.teamSpells and not (spellName in session.teamSpells[session.team])
|
||||||
if session.teamSpells and not (spellName in session.teamSpells[session.team]) then continue
|
|
||||||
#console.log "Transpiling spell #{spellName}"
|
#console.log "Transpiling spell #{spellName}"
|
||||||
aetherOptions =
|
aetherOptions = createAetherOptions functionName: spellID, codeLanguage: session.submittedCodeLanguage
|
||||||
problems: {}
|
|
||||||
language: session.submittedCodeLanguage
|
|
||||||
functionName: spellID
|
|
||||||
functionParameters: []
|
|
||||||
yieldConditionally: spellID is 'plan'
|
|
||||||
globals: ['Vector', '_']
|
|
||||||
protectAPI: true
|
|
||||||
includeFlow: false
|
|
||||||
executionLimit: 1 * 1000 * 1000
|
|
||||||
if spellID is 'hear' then aetherOptions.functionParameters = ['speaker', 'message', 'data']
|
|
||||||
if spellID is 'makeBid' then aetherOptions.functionParameters = ['tileGroupLetter']
|
|
||||||
if spellID is 'findCentroids' then aetherOptions.functionParameters = ['centroids']
|
|
||||||
|
|
||||||
aether = new Aether aetherOptions
|
aether = new Aether aetherOptions
|
||||||
transpiledCode[thang][spellID] = aether.transpile spell
|
transpiledCode[thang][spellID] = aether.transpile spell
|
||||||
conditions =
|
conditions =
|
||||||
|
|
Loading…
Reference in a new issue