2016-11-17 23:25:40 +01:00
/ * E v a l u a t o r
* Evaluates the Abstract Syntax Tree for Netscript
* generated by the Parser class
* /
2016-11-30 00:07:24 +01:00
// Evaluator should return a Promise, so that any call to evaluate() can just
//wait for that promise to finish before continuing
function evaluate ( exp , workerScript ) {
var env = workerScript . env ;
2017-05-01 07:39:48 +02:00
if ( exp == null ) {
2017-05-01 19:04:30 +02:00
return new Promise ( function ( resolve , reject ) {
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Error: NULL expression" ) ;
} ) ;
2017-05-01 07:39:48 +02:00
}
2016-11-17 23:25:40 +01:00
switch ( exp . type ) {
case "num" :
case "str" :
case "bool" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-11-30 00:07:24 +01:00
resolve ( exp . value ) ;
} ) ;
break ;
2016-11-17 23:25:40 +01:00
case "var" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-19 19:20:19 +01:00
try {
resolve ( env . get ( exp . value ) ) ;
} catch ( e ) {
throw new Error ( "|" + workerScript . serverIp + "|" + workerScript . name + "|" + e . toString ( ) ) ;
}
2016-11-30 00:07:24 +01:00
} ) ;
break ;
2016-11-17 23:25:40 +01:00
//Can currently only assign to "var"s
case "assign" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
if ( exp . left . type != "var" )
2016-12-15 23:22:42 +01:00
throw new Error ( "|" + workerScript . serverIp + "|" + workerScript . name + "| Cannot assign to " + JSON . stringify ( exp . left ) ) ;
2016-11-30 00:07:24 +01:00
var p = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var expRightPromise = evaluate ( exp . right , workerScript ) ;
expRightPromise . then ( function ( expRight ) {
resolve ( expRight ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime )
} ) ;
p . then ( function ( expRight ) {
2016-12-19 19:20:19 +01:00
try {
env . set ( exp . left . value , expRight ) ;
} catch ( e ) {
throw new Error ( "|" + workerScript . serverIp + "|" + workerScript . name + "|" + e . toString ( ) ) ;
}
2017-05-07 00:19:18 +02:00
resolve ( false ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
2016-11-17 23:25:40 +01:00
case "binary" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
var pLeft = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var promise = evaluate ( exp . left , workerScript ) ;
promise . then ( function ( valLeft ) {
resolve ( valLeft ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pLeft . then ( function ( valLeft ) {
var pRight = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var promise = evaluate ( exp . right , workerScript ) ;
promise . then ( function ( valRight ) {
resolve ( [ valLeft , valRight ] ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pRight . then ( function ( args ) {
2016-12-15 23:22:42 +01:00
try {
resolve ( apply _op ( exp . operator , args [ 0 ] , args [ 1 ] ) ) ;
} catch ( e ) {
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|" + e . toString ( ) ) ;
}
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
break ;
2016-11-17 23:25:40 +01:00
2016-11-30 00:07:24 +01:00
//TODO
2016-11-17 23:25:40 +01:00
case "if" :
var numConds = exp . cond . length ;
var numThens = exp . then . length ;
if ( numConds == 0 || numThens == 0 || numConds != numThens ) {
2017-05-01 07:39:48 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Number of conds and thens in if structure don't match (or there are none)" ) ;
2016-11-17 23:25:40 +01:00
}
for ( var i = 0 ; i < numConds ; i ++ ) {
2016-11-30 00:07:24 +01:00
var cond = evaluate ( exp . cond [ i ] , workerScript ) ;
if ( cond ) return evaluate ( exp . then [ i ] , workerScript ) ;
2016-11-17 23:25:40 +01:00
}
//Evaluate else if it exists, snce none of the conditionals
//were true
2016-11-30 00:07:24 +01:00
return exp . else ? evaluate ( exp . else , workerScript ) : false ;
2016-11-17 23:25:40 +01:00
case "for" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
console . log ( "for loop encountered in evaluator" ) ;
2017-04-27 22:59:57 +02:00
workerScript . scriptRef . log ( "Entering for loop" ) ;
2016-11-30 00:07:24 +01:00
var pInit = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var resInit = evaluate ( exp . init , workerScript ) ;
resInit . then ( function ( foo ) {
resolve ( resInit ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pInit . then ( function ( expInit ) {
var pForLoop = evaluateFor ( exp , workerScript ) ;
pForLoop . then ( function ( forLoopRes ) {
resolve ( "forLoopDone" ) ;
2017-04-27 22:59:57 +02:00
workerScript . scriptRef . log ( "Exiting for loop" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
2016-11-17 23:25:40 +01:00
break ;
case "while" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
var pEvaluateWhile = evaluateWhile ( exp , workerScript ) ;
pEvaluateWhile . then ( function ( whileLoopRes ) {
resolve ( "whileLoopDone" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
2016-11-17 23:25:40 +01:00
break ;
case "prog" :
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
var evaluateProgPromise = evaluateProg ( exp , workerScript , 0 ) ;
2016-12-06 17:59:20 +01:00
evaluateProgPromise . then ( function ( w ) {
resolve ( workerScript ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
2017-05-01 07:39:48 +02:00
workerScript . errorMessage = e . toString ( ) ;
reject ( workerScript ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
break ;
2016-11-17 23:25:40 +01:00
/ * C u r r e n t l y s u p p o r t e d f u n c t i o n c a l l s :
* hack ( )
* sleep ( N ) - sleep N seconds
* print ( x ) - Prints a variable or constant
*
* /
case "call" :
//Define only valid function calls here, like hack() and stuff
//var func = evaluate(exp.func, env);
//return func.apply(null, exp.args.map(function(arg){
// return evaluate(arg, env);
//}));
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-06 17:59:20 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-05 23:31:46 +01:00
2016-11-30 00:07:24 +01:00
setTimeout ( function ( ) {
if ( exp . func . value == "hack" ) {
2016-12-14 00:52:32 +01:00
if ( exp . args . length != 1 ) {
2017-05-01 07:39:48 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Hack() call has incorrect number of arguments. Takes 1 argument" ) ;
2016-12-05 23:31:46 +01:00
}
2016-12-14 00:52:32 +01:00
//IP of server to hack
var ipPromise = evaluate ( exp . args [ 0 ] , workerScript ) ;
2016-12-05 23:31:46 +01:00
2016-12-14 00:52:32 +01:00
ipPromise . then ( function ( ip ) {
2017-02-16 19:52:11 +01:00
//Check if its a valid IP address. If it's not, assume its a hostname and
//try to get the server. If its not a server, there is an error
var server = null ;
if ( ! isValidIPAddress ( ip ) ) {
//It's not an IP address, so see if its a hostanme
server = GetServerByHostname ( ip ) ;
} else {
server = AllServers [ ip ] ;
}
if ( server == null ) {
2017-05-01 19:04:30 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Invalid IP or hostname passed into hack() command" ) ;
2017-04-11 15:59:48 +02:00
workerScript . scriptRef . log ( "Cannot hack(). Invalid IP or hostname passed in: " + ip ) ;
2017-05-01 19:04:30 +02:00
return ;
2017-02-16 19:52:11 +01:00
}
2016-12-14 00:52:32 +01:00
//Calculate the hacking time
var hackingTime = scriptCalculateHackingTime ( server ) ; //This is in seconds
2017-04-28 00:01:26 +02:00
//No root access or skill level too low
2016-12-14 00:52:32 +01:00
if ( server . hasAdminRights == false ) {
2017-04-28 00:01:26 +02:00
workerScript . scriptRef . log ( "Cannot hack this server (" + server . hostname + ") because user does not have root access" ) ;
2017-05-01 07:39:48 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Script crashed because it did not have root access to " + server . hostname ) ;
2017-05-01 19:04:30 +02:00
return ;
2016-12-14 00:52:32 +01:00
}
2017-04-11 15:59:48 +02:00
2017-04-28 00:01:26 +02:00
if ( server . requiredHackingSkill > Player . hacking _skill ) {
workerScript . scriptRef . log ( "Cannot hack this server (" + server . hostaname + ") because user does not have root access" ) ;
2017-05-01 07:39:48 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Script crashed because player's hacking skill is not high enough to hack " + server . hostname ) ;
2017-05-01 19:04:30 +02:00
return ;
2017-04-28 00:01:26 +02:00
}
2017-05-02 19:06:46 +02:00
workerScript . scriptRef . log ( "Attempting to hack " + ip + " in " + hackingTime . toFixed ( 3 ) + " seconds" ) ;
2016-12-14 00:52:32 +01:00
var p = new Promise ( function ( resolve , reject ) {
2016-12-15 23:22:42 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-14 00:52:32 +01:00
console . log ( "Hacking " + server . hostname + " after " + hackingTime . toString ( ) + " seconds." ) ;
setTimeout ( function ( ) {
2017-05-05 16:21:08 +02:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-12-14 00:52:32 +01:00
var hackChance = scriptCalculateHackingChance ( server ) ;
var rand = Math . random ( ) ;
var expGainedOnSuccess = scriptCalculateExpGain ( server ) ;
2017-05-05 17:50:55 +02:00
var expGainedOnFailure = ( expGainedOnSuccess / 4 ) ;
2016-12-14 00:52:32 +01:00
if ( rand < hackChance ) { //Success!
2017-05-07 00:19:18 +02:00
if ( env . stopFlag ) { reject ( workerScript ) ; return ; }
2016-12-14 00:52:32 +01:00
var moneyGained = scriptCalculatePercentMoneyHacked ( server ) ;
moneyGained = Math . floor ( server . moneyAvailable * moneyGained ) ;
2016-12-14 21:29:40 +01:00
//Safety check
if ( moneyGained <= 0 ) { moneyGained = 0 ; }
2016-12-14 00:52:32 +01:00
server . moneyAvailable -= moneyGained ;
2016-12-19 21:59:13 +01:00
Player . gainMoney ( moneyGained ) ;
2016-12-19 19:20:19 +01:00
workerScript . scriptRef . onlineMoneyMade += moneyGained ;
2017-05-10 19:42:46 +02:00
console . log ( "About to add to moneystolenmap for " + server . hostname ) ;
workerScript . scriptRef . moneyStolenMap [ server . ip ] += moneyGained ;
2016-12-14 00:52:32 +01:00
2017-04-18 06:32:17 +02:00
Player . gainHackingExp ( expGainedOnSuccess ) ;
2016-12-19 21:59:13 +01:00
workerScript . scriptRef . onlineExpGained += expGainedOnSuccess ;
2017-05-05 17:50:55 +02:00
console . log ( "Script successfully hacked " + server . hostname + " for $" + formatNumber ( moneyGained , 2 ) + " and " + formatNumber ( expGainedOnSuccess , 4 ) + " exp" ) ;
workerScript . scriptRef . log ( "Script SUCCESSFULLY hacked " + server . hostname + " for $" + formatNumber ( moneyGained , 2 ) + " and " + formatNumber ( expGainedOnSuccess , 4 ) + " exp" ) ;
2016-12-14 00:52:32 +01:00
resolve ( "Hack success" ) ;
2017-05-07 00:19:18 +02:00
} else {
if ( env . stopFlag ) { reject ( workerScript ) ; return ; }
2016-12-14 00:52:32 +01:00
//Player only gains 25% exp for failure? TODO Can change this later to balance
2017-04-18 06:32:17 +02:00
Player . gainHackingExp ( expGainedOnFailure ) ;
2016-12-19 21:59:13 +01:00
workerScript . scriptRef . onlineExpGained += expGainedOnFailure ;
2017-05-05 17:50:55 +02:00
console . log ( "Script unsuccessful to hack " + server . hostname + ". Gained " + formatNumber ( expGainedOnFailure , 4 ) + " exp" ) ;
workerScript . scriptRef . log ( "Script FAILED to hack " + server . hostname + ". Gained " + formatNumber ( expGainedOnFailure , 4 ) + " exp" ) ;
2016-12-14 00:52:32 +01:00
resolve ( "Hack failure" ) ;
}
} , hackingTime * 1000 ) ;
} ) ;
p . then ( function ( res ) {
resolve ( "hackExecuted" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-12-14 00:52:32 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-12-05 23:31:46 +01:00
} ) ;
2016-12-14 00:52:32 +01:00
2016-11-30 00:07:24 +01:00
} else if ( exp . func . value == "sleep" ) {
2016-12-05 23:31:46 +01:00
if ( exp . args . length != 1 ) {
2017-05-02 18:28:54 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|sleep() call has incorrect number of arguments. Takes 1 argument." ) ;
2017-05-01 19:04:30 +02:00
return ;
2016-12-05 23:31:46 +01:00
}
2016-12-14 00:52:32 +01:00
var sleepTimePromise = evaluate ( exp . args [ 0 ] , workerScript ) ;
sleepTimePromise . then ( function ( sleepTime ) {
2017-04-11 15:59:48 +02:00
workerScript . scriptRef . log ( "Sleeping for " + sleepTime + " milliseconds" ) ;
2016-12-14 00:52:32 +01:00
var p = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
resolve ( "foo" ) ;
} , sleepTime ) ;
} ) ;
2016-12-05 23:31:46 +01:00
2016-12-14 00:52:32 +01:00
p . then ( function ( res ) {
resolve ( "sleepExecuted" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-12-14 00:52:32 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e )
2016-12-05 23:31:46 +01:00
} ) ;
2016-11-30 00:07:24 +01:00
} else if ( exp . func . value == "print" ) {
2016-12-05 23:31:46 +01:00
if ( exp . args . length != 1 ) {
2017-05-02 18:28:54 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|print() call has incorrect number of arguments. Takes 1 argument" ) ;
2016-12-05 23:31:46 +01:00
}
2016-11-30 00:07:24 +01:00
var p = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . args [ 0 ] , workerScript ) ;
evaluatePromise . then ( function ( res ) {
resolve ( res ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
p . then ( function ( res ) {
2017-05-02 18:28:54 +02:00
workerScript . scriptRef . log ( res . toString ( ) ) ;
2016-11-30 00:07:24 +01:00
resolve ( "printExecuted" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2017-05-02 18:28:54 +02:00
} else if ( exp . func . value == "grow" ) {
if ( exp . args . length != 1 ) {
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|grow() call has incorrect number of arguments. Takes 1 argument" ) ;
}
//IP/hostname of server to hack
var ipPromise = evaluate ( exp . args [ 0 ] , workerScript ) ;
ipPromise . then ( function ( ip ) {
//Check if its a valid IP address. If it's not, assume its a hostname and
//try to get the server. If its not a server, there is an error
var server = null ;
if ( ! isValidIPAddress ( ip ) ) {
//It's not an IP address, so see if its a hostanme
server = GetServerByHostname ( ip ) ;
} else {
server = AllServers [ ip ] ;
}
if ( server == null ) {
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Invalid IP or hostname passed into grow() command" ) ;
workerScript . scriptRef . log ( "Cannot grow(). Invalid IP or hostname passed in: " + ip ) ;
return ;
}
//No root access or skill level too low
if ( server . hasAdminRights == false ) {
workerScript . scriptRef . log ( "Cannot grow this server (" + server . hostname + ") because user does not have root access" ) ;
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Script crashed because it did not have root access to " + server . hostname ) ;
return ;
}
2017-05-03 06:38:58 +02:00
workerScript . scriptRef . log ( "Calling grow() on server " + server . hostname + " in 120 seconds" ) ;
2017-05-02 18:28:54 +02:00
var p = new Promise ( function ( resolve , reject ) {
if ( env . stopFlag ) { reject ( workerScript ) ; }
setTimeout ( function ( ) {
var growthPercentage = processSingleServerGrowth ( server , 450 ) ;
resolve ( growthPercentage ) ;
} , 120 * 1000 ) ; //grow() takes flat 2 minutes right now
} ) ;
p . then ( function ( growthPercentage ) {
resolve ( "hackExecuted" ) ;
2017-05-05 17:50:55 +02:00
workerScript . scriptRef . log ( "Using grow(), the money available on " + server . hostname + " was grown by " + ( growthPercentage * 100 - 100 ) . toFixed ( 6 ) + "%. Gained 1 hacking exp" ) ;
Player . gainHackingExp ( 1 ) ;
workerScript . scriptRef . onlineExpGained += 1 ;
2017-05-02 18:28:54 +02:00
} , function ( e ) {
reject ( e ) ;
} ) ;
} , function ( e ) {
reject ( e ) ;
} ) ;
}
2016-11-30 00:07:24 +01:00
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
2016-11-17 23:25:40 +01:00
break ;
default :
2017-05-02 18:28:54 +02:00
reject ( "|" + workerScript . serverIp + "|" + workerScript . name + "|Can't evaluate type " + exp . type ) ;
2016-11-17 23:25:40 +01:00
}
}
2016-11-30 00:07:24 +01:00
//Evaluate the looping part of a for loop (Initialization block is NOT done in here)
function evaluateFor ( exp , workerScript ) {
2016-12-15 23:22:42 +01:00
var env = workerScript . env ;
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-15 23:22:42 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-11-30 00:07:24 +01:00
var pCond = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . cond , workerScript ) ;
evaluatePromise . then ( function ( resCond ) {
resolve ( resCond ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pCond . then ( function ( resCond ) {
if ( resCond ) {
//Run the for loop code
var pCode = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . code , workerScript ) ;
evaluatePromise . then ( function ( resCode ) {
resolve ( resCode ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
//After the code executes make a recursive call
pCode . then ( function ( resCode ) {
var pPostLoop = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . postloop , workerScript ) ;
evaluatePromise . then ( function ( foo ) {
resolve ( "postLoopFinished" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pPostLoop . then ( function ( resPostloop ) {
var recursiveCall = evaluateFor ( exp , workerScript ) ;
recursiveCall . then ( function ( foo ) {
resolve ( "endForLoop" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} else {
resolve ( "endForLoop" ) ; //Doesn't need to resolve to any particular value
}
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
}
function evaluateWhile ( exp , workerScript ) {
2016-12-15 23:22:42 +01:00
var env = workerScript . env ;
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-15 23:22:42 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-11-30 00:07:24 +01:00
var pCond = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . cond , workerScript ) ;
evaluatePromise . then ( function ( resCond ) {
resolve ( resCond ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
pCond . then ( function ( resCond ) {
if ( resCond ) {
//Run the while loop code
var pCode = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . code , workerScript ) ;
evaluatePromise . then ( function ( resCode ) {
resolve ( resCode ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
//After the code executes make a recursive call
pCode . then ( function ( resCode ) {
var recursiveCall = evaluateWhile ( exp , workerScript ) ;
recursiveCall . then ( function ( foo ) {
resolve ( "endWhileLoop" ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} else {
resolve ( "endWhileLoop" ) ; //Doesn't need to resolve to any particular value
}
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} ) ;
}
function evaluateProg ( exp , workerScript , index ) {
2016-12-15 23:22:42 +01:00
var env = workerScript . env ;
2016-11-30 00:07:24 +01:00
return new Promise ( function ( resolve , reject ) {
2016-12-15 23:22:42 +01:00
if ( env . stopFlag ) { reject ( workerScript ) ; }
2016-11-30 00:07:24 +01:00
if ( index >= exp . prog . length ) {
resolve ( "progFinished" ) ;
} else {
//Evaluate this line of code in the prog
var code = new Promise ( function ( resolve , reject ) {
setTimeout ( function ( ) {
var evaluatePromise = evaluate ( exp . prog [ index ] , workerScript ) ;
evaluatePromise . then ( function ( evalRes ) {
resolve ( evalRes ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
} , CONSTANTS . CodeInstructionRunTime ) ;
} ) ;
//After the code finishes evaluating, evaluate the next line recursively
code . then ( function ( codeRes ) {
var nextLine = evaluateProg ( exp , workerScript , index + 1 ) ;
nextLine . then ( function ( nextLineRes ) {
2016-12-06 17:59:20 +01:00
resolve ( workerScript ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
2016-12-15 23:22:42 +01:00
} , function ( e ) {
reject ( e ) ;
2016-11-30 00:07:24 +01:00
} ) ;
}
} ) ;
}
2016-11-17 23:25:40 +01:00
function apply _op ( op , a , b ) {
function num ( x ) {
if ( typeof x != "number" )
throw new Error ( "Expected number but got " + x ) ;
return x ;
}
function div ( x ) {
if ( num ( x ) == 0 )
throw new Error ( "Divide by zero" ) ;
return x ;
}
switch ( op ) {
case "+" : return num ( a ) + num ( b ) ;
case "-" : return num ( a ) - num ( b ) ;
case "*" : return num ( a ) * num ( b ) ;
case "/" : return num ( a ) / div ( b ) ;
case "%" : return num ( a ) % div ( b ) ;
case "&&" : return a !== false && b ;
case "||" : return a !== false ? a : b ;
case "<" : return num ( a ) < num ( b ) ;
case ">" : return num ( a ) > num ( b ) ;
case "<=" : return num ( a ) <= num ( b ) ;
case ">=" : return num ( a ) >= num ( b ) ;
case "==" : return a === b ;
case "!=" : return a !== b ;
}
throw new Error ( "Can't apply operator " + op ) ;
2016-11-30 00:07:24 +01:00
}
2016-12-14 00:52:32 +01:00
2017-05-01 07:39:48 +02:00
function isScriptErrorMessage ( msg ) {
splitMsg = msg . split ( "|" ) ;
if ( splitMsg . length != 4 ) {
return false ;
}
var ip = splitMsg [ 1 ] ;
if ( ! isValidIPAddress ( ip ) ) {
return false ;
}
return true ;
}
2016-12-14 00:52:32 +01:00
//The same as Player's calculateHackingChance() function but takes in the server as an argument
function scriptCalculateHackingChance ( server ) {
var difficultyMult = ( 100 - server . hackDifficulty ) / 100 ;
2017-05-05 03:08:44 +02:00
var skillMult = ( 2 * Player . hacking _chance _mult * Player . hacking _skill ) ;
2016-12-14 00:52:32 +01:00
var skillChance = ( skillMult - server . requiredHackingSkill ) / skillMult ;
2017-04-17 14:26:54 +02:00
var chance = skillChance * difficultyMult ;
if ( chance < 0 ) { return 0 ; }
else { return chance ; }
2016-12-14 00:52:32 +01:00
}
//The same as Player's calculateHackingTime() function but takes in the server as an argument
function scriptCalculateHackingTime ( server ) {
var difficultyMult = server . requiredHackingSkill * server . hackDifficulty ;
2017-05-03 06:38:58 +02:00
var skillFactor = ( 2.5 * difficultyMult + 500 ) / ( Player . hacking _skill + 50 ) ;
2017-05-05 03:08:44 +02:00
var hackingTime = skillFactor * Player . hacking _speed _mult * 5 ; //This is in seconds
2016-12-14 21:29:40 +01:00
return hackingTime ;
2016-12-14 00:52:32 +01:00
}
//The same as Player's calculateExpGain() function but takes in the server as an argument
function scriptCalculateExpGain ( server ) {
2017-05-05 17:50:55 +02:00
return ( server . hackDifficulty * Player . hacking _exp _mult ) ;
2016-12-14 00:52:32 +01:00
}
//The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument
function scriptCalculatePercentMoneyHacked ( server ) {
var difficultyMult = ( 100 - server . hackDifficulty ) / 100 ;
var skillMult = ( Player . hacking _skill - ( server . requiredHackingSkill - 1 ) ) / Player . hacking _skill ;
2017-05-05 03:08:44 +02:00
var percentMoneyHacked = difficultyMult * skillMult * Player . hacking _money _mult / 1000 ;
2017-04-18 06:32:17 +02:00
if ( percentMoneyHacked < 0 ) { return 0 ; }
if ( percentMoneyHacked > 1 ) { return 1 ; }
2016-12-14 00:52:32 +01:00
return percentMoneyHacked ;
}