2017-08-30 19:44:29 +02:00
|
|
|
import {substituteAliases, printAliases,
|
|
|
|
parseAliasDeclaration,
|
|
|
|
removeAlias, GlobalAliases,
|
2018-09-14 23:03:31 +02:00
|
|
|
Aliases} from "./Alias";
|
|
|
|
import {CodingContract, CodingContractResult,
|
|
|
|
CodingContractRewardType} from "./CodingContracts";
|
|
|
|
import {CONSTANTS} from "./Constants";
|
2018-12-25 11:14:18 +01:00
|
|
|
import { Programs } from "./Programs/Programs";
|
|
|
|
import { executeDarkwebTerminalCommand,
|
|
|
|
checkIfConnectedToDarkweb } from "./DarkWeb/DarkWeb";
|
|
|
|
import { DarkWebItems } from "./DarkWeb/DarkWebItems";
|
|
|
|
import {Engine} from "./engine";
|
2018-03-12 20:39:04 +01:00
|
|
|
import {FconfSettings, parseFconfSettings,
|
2018-06-26 18:34:11 +02:00
|
|
|
createFconf} from "./Fconf";
|
2018-08-30 19:00:38 +02:00
|
|
|
import {calculateHackingChance,
|
|
|
|
calculateHackingExpGain,
|
|
|
|
calculatePercentMoneyHacked,
|
|
|
|
calculateHackingTime,
|
|
|
|
calculateGrowTime,
|
|
|
|
calculateWeakenTime} from "./Hacking";
|
2018-06-14 05:38:35 +02:00
|
|
|
import {TerminalHelpText, HelpTexts} from "./HelpText";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {iTutorialNextStep, iTutorialSteps,
|
2018-08-29 21:06:21 +02:00
|
|
|
ITutorial} from "./InteractiveTutorial";
|
2018-06-26 18:34:11 +02:00
|
|
|
import {showLiterature} from "./Literature";
|
|
|
|
import {showMessage, Message} from "./Message";
|
|
|
|
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker";
|
|
|
|
import {Player} from "./Player";
|
|
|
|
import {hackWorldDaemon} from "./RedPill";
|
2019-02-06 08:06:48 +01:00
|
|
|
import { findRunningScript,
|
|
|
|
RunningScript,
|
|
|
|
isScriptFilename } from "./Script";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {AllServers, GetServerByHostname,
|
2018-06-26 18:34:11 +02:00
|
|
|
getServer, Server} from "./Server";
|
2019-01-27 23:08:45 +01:00
|
|
|
import {Settings} from "./Settings/Settings";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {SpecialServerIps,
|
2018-06-26 18:34:11 +02:00
|
|
|
SpecialServerNames} from "./SpecialServerIps";
|
2018-09-27 23:49:23 +02:00
|
|
|
import {getTextFile} from "./TextFile";
|
2019-02-20 09:42:27 +01:00
|
|
|
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
2018-09-01 15:42:56 +02:00
|
|
|
import {containsAllStrings,
|
|
|
|
longestCommonStart} from "../utils/StringHelperFunctions";
|
2018-07-20 03:51:18 +02:00
|
|
|
import {Page, routing} from "./ui/navigationTracking";
|
2018-09-12 17:53:08 +02:00
|
|
|
import {numeralWrapper} from "./ui/numeralFormat";
|
2018-07-18 18:50:31 +02:00
|
|
|
import {KEY} from "../utils/helpers/keyCodes";
|
2018-07-05 19:52:37 +02:00
|
|
|
import {addOffset} from "../utils/helpers/addOffset";
|
2018-07-04 06:33:55 +02:00
|
|
|
import {isString} from "../utils/helpers/isString";
|
2018-07-05 20:12:20 +02:00
|
|
|
import {arrayToString} from "../utils/helpers/arrayToString";
|
2018-08-01 19:38:54 +02:00
|
|
|
import {getTimestamp} from "../utils/helpers/getTimestamp";
|
2018-06-26 18:34:11 +02:00
|
|
|
import {logBoxCreate} from "../utils/LogBox";
|
2018-01-27 07:52:39 +01:00
|
|
|
import {yesNoBoxCreate,
|
|
|
|
yesNoBoxGetYesButton,
|
2018-06-26 18:34:11 +02:00
|
|
|
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox";
|
2019-02-05 07:45:04 +01:00
|
|
|
import { post,
|
|
|
|
postError,
|
|
|
|
hackProgressBarPost,
|
|
|
|
hackProgressPost } from "./ui/postToTerminal";
|
2016-12-21 19:36:42 +01:00
|
|
|
|
2018-08-29 05:24:38 +02:00
|
|
|
import autosize from 'autosize';
|
2018-03-12 20:39:04 +01:00
|
|
|
import * as JSZip from 'jszip';
|
|
|
|
import * as FileSaver from 'file-saver';
|
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
function postNetburnerText() {
|
2017-04-24 21:10:35 +02:00
|
|
|
post("Bitburner v" + CONSTANTS.Version);
|
2016-10-20 23:11:01 +02:00
|
|
|
}
|
|
|
|
|
2019-02-06 03:32:15 +01:00
|
|
|
// Helper function that checks if an argument (which is a string) is a valid number
|
|
|
|
function isNumber(str) {
|
|
|
|
if (typeof str != "string") { return false; } // Only process strings
|
|
|
|
return !isNaN(str) && !isNaN(parseFloat(str));
|
|
|
|
}
|
|
|
|
|
2016-12-21 17:33:00 +01:00
|
|
|
//Defines key commands in terminal
|
2017-05-01 23:38:49 +02:00
|
|
|
$(document).keydown(function(event) {
|
2016-11-24 23:30:33 +01:00
|
|
|
//Terminal
|
2018-07-20 03:51:18 +02:00
|
|
|
if (routing.isOn(Page.Terminal)) {
|
2017-05-02 18:28:54 +02:00
|
|
|
var terminalInput = document.getElementById("terminal-input-text-box");
|
2018-09-14 23:03:31 +02:00
|
|
|
if (terminalInput != null && !event.ctrlKey && !event.shiftKey && !Terminal.contractOpen) {terminalInput.focus();}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (event.keyCode === KEY.ENTER) {
|
2017-05-16 06:37:14 +02:00
|
|
|
event.preventDefault(); //Prevent newline from being entered in Script Editor
|
2018-08-29 05:24:38 +02:00
|
|
|
var command = terminalInput.value;
|
|
|
|
post(
|
2018-09-03 14:10:00 +02:00
|
|
|
"<span class='prompt'>[" +
|
2018-08-02 17:04:21 +02:00
|
|
|
(FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") +
|
2018-07-31 02:16:39 +02:00
|
|
|
Player.getCurrentServer().hostname +
|
2018-09-03 14:10:00 +02:00
|
|
|
" ~]></span> " + command
|
2018-07-31 02:16:39 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
if (command.length > 0) {
|
2017-09-13 16:22:22 +02:00
|
|
|
Terminal.resetTerminalInput(); //Clear input first
|
2019-02-05 07:45:04 +01:00
|
|
|
Terminal.executeCommands(command);
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2016-10-17 10:24:39 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (event.keyCode === KEY.C && event.ctrlKey) {
|
|
|
|
if (Engine._actionInProgress) {
|
|
|
|
//Cancel action
|
|
|
|
post("Cancelling...");
|
|
|
|
Engine._actionInProgress = false;
|
|
|
|
Terminal.finishAction(true);
|
|
|
|
} else if (FconfSettings.ENABLE_BASH_HOTKEYS) {
|
|
|
|
//Dont prevent default so it still copies
|
|
|
|
Terminal.resetTerminalInput(); //Clear Terminal
|
|
|
|
}
|
2016-12-21 17:33:00 +01:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (event.keyCode === KEY.L && event.ctrlKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.executeCommand("clear"); //Clear screen
|
|
|
|
}
|
|
|
|
|
|
|
|
//Ctrl p same as up arrow
|
|
|
|
//Ctrl n same as down arrow
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.UPARROW ||
|
|
|
|
(FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.P && event.ctrlKey)) {
|
|
|
|
if (FconfSettings.ENABLE_BASH_HOTKEYS) {event.preventDefault();}
|
|
|
|
//Cycle through past commands
|
2017-05-03 06:38:58 +02:00
|
|
|
if (terminalInput == null) {return;}
|
2017-05-02 05:05:26 +02:00
|
|
|
var i = Terminal.commandHistoryIndex;
|
|
|
|
var len = Terminal.commandHistory.length;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-02 05:05:26 +02:00
|
|
|
if (len == 0) {return;}
|
|
|
|
if (i < 0 || i > len) {
|
|
|
|
Terminal.commandHistoryIndex = len;
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
|
|
|
|
2017-05-02 05:05:26 +02:00
|
|
|
if (i != 0) {
|
|
|
|
--Terminal.commandHistoryIndex;
|
|
|
|
}
|
2017-05-01 19:23:20 +02:00
|
|
|
var prevCommand = Terminal.commandHistory[Terminal.commandHistoryIndex];
|
2017-05-02 18:28:54 +02:00
|
|
|
terminalInput.value = prevCommand;
|
2019-02-20 09:42:27 +01:00
|
|
|
setTimeoutRef(function(){terminalInput.selectionStart = terminalInput.selectionEnd = 10000; }, 0);
|
2017-05-02 05:05:26 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (event.keyCode === KEY.DOWNARROW ||
|
|
|
|
(FconfSettings.ENABLE_BASH_HOTKEYS && event.keyCode === KEY.M && event.ctrlKey)) {
|
|
|
|
if (FconfSettings.ENABLE_BASH_HOTKEYS) {event.preventDefault();}
|
|
|
|
//Cycle through past commands
|
2017-05-03 06:38:58 +02:00
|
|
|
if (terminalInput == null) {return;}
|
2017-05-02 05:05:26 +02:00
|
|
|
var i = Terminal.commandHistoryIndex;
|
|
|
|
var len = Terminal.commandHistory.length;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-02 05:05:26 +02:00
|
|
|
if (len == 0) {return;}
|
|
|
|
if (i < 0 || i > len) {
|
|
|
|
Terminal.commandHistoryIndex = len;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-02 05:05:26 +02:00
|
|
|
//Latest command, put nothing
|
|
|
|
if (i == len || i == len-1) {
|
|
|
|
Terminal.commandHistoryIndex = len;
|
2017-05-02 18:28:54 +02:00
|
|
|
terminalInput.value = "";
|
2017-05-02 05:05:26 +02:00
|
|
|
} else {
|
|
|
|
++Terminal.commandHistoryIndex;
|
|
|
|
var prevCommand = Terminal.commandHistory[Terminal.commandHistoryIndex];
|
2017-05-02 18:28:54 +02:00
|
|
|
terminalInput.value = prevCommand;
|
2017-05-02 05:05:26 +02:00
|
|
|
}
|
2017-05-01 19:23:20 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (event.keyCode === KEY.TAB) {
|
2018-07-16 08:00:57 +02:00
|
|
|
event.preventDefault();
|
2018-07-20 16:28:03 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
//Autocomplete
|
2017-05-03 06:38:58 +02:00
|
|
|
if (terminalInput == null) {return;}
|
2017-05-02 18:28:54 +02:00
|
|
|
var input = terminalInput.value;
|
2017-05-01 23:38:49 +02:00
|
|
|
if (input == "") {return;}
|
2018-07-31 02:16:39 +02:00
|
|
|
|
|
|
|
const semiColonIndex = input.lastIndexOf(";");
|
|
|
|
if(semiColonIndex !== -1) {
|
2019-02-09 03:46:30 +01:00
|
|
|
input = input.slice(semiColonIndex + 1);
|
2018-07-31 02:16:39 +02:00
|
|
|
}
|
|
|
|
|
2017-05-02 05:05:26 +02:00
|
|
|
input = input.trim();
|
2017-05-01 23:38:49 +02:00
|
|
|
input = input.replace(/\s\s+/g, ' ');
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-30 04:02:41 +02:00
|
|
|
var commandArray = input.split(" ");
|
|
|
|
var index = commandArray.length - 2;
|
2017-06-03 03:26:17 +02:00
|
|
|
if (index < -1) {index = 0;}
|
2017-05-30 04:02:41 +02:00
|
|
|
var allPos = determineAllPossibilitiesForTabCompletion(input, index);
|
2017-05-01 23:38:49 +02:00
|
|
|
if (allPos.length == 0) {return;}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
var arg = "";
|
2017-05-30 04:02:41 +02:00
|
|
|
var command = "";
|
2017-05-01 23:38:49 +02:00
|
|
|
if (commandArray.length == 0) {return;}
|
2017-07-25 03:06:40 +02:00
|
|
|
if (commandArray.length == 1) {command = commandArray[0];}
|
2017-05-30 04:02:41 +02:00
|
|
|
else if (commandArray.length == 2) {
|
|
|
|
command = commandArray[0];
|
2017-05-01 23:38:49 +02:00
|
|
|
arg = commandArray[1];
|
2017-05-30 04:02:41 +02:00
|
|
|
} else if (commandArray.length == 3) {
|
|
|
|
command = commandArray[0] + " " + commandArray[1];
|
|
|
|
arg = commandArray[2];
|
|
|
|
} else {
|
2017-07-25 03:06:40 +02:00
|
|
|
arg = commandArray.pop();
|
|
|
|
command = commandArray.join(" ");
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-30 04:02:41 +02:00
|
|
|
tabCompletion(command, arg, allPos);
|
2018-07-16 08:00:57 +02:00
|
|
|
terminalInput.focus();
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
2018-03-12 20:39:04 +01:00
|
|
|
|
|
|
|
//Extra Bash Emulation Hotkeys, must be enabled through .fconf
|
|
|
|
if (FconfSettings.ENABLE_BASH_HOTKEYS) {
|
|
|
|
if (event.keyCode === KEY.A && event.ctrlKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("home");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.E && event.ctrlKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("end");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.B && event.ctrlKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("prevchar");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.B && event.altKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("prevword");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.F && event.ctrlKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("nextchar");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.keyCode === KEY.F && event.altKey) {
|
|
|
|
event.preventDefault();
|
|
|
|
Terminal.moveTextCursor("nextword");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((event.keyCode === KEY.H || event.keyCode === KEY.D) && event.ctrlKey) {
|
|
|
|
Terminal.modifyInput("backspace");
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO AFTER THIS:
|
|
|
|
|
|
|
|
//alt + d deletes word after cursor
|
|
|
|
//^w deletes word before cursor
|
|
|
|
//^k clears line after cursor
|
|
|
|
//^u clears line before cursor
|
|
|
|
}
|
2016-10-17 10:24:39 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-11-24 23:30:33 +01:00
|
|
|
//Keep terminal in focus
|
2018-05-06 22:27:47 +02:00
|
|
|
let terminalCtrlPressed = false, shiftKeyPressed = false;
|
2016-11-24 23:30:33 +01:00
|
|
|
$(document).ready(function() {
|
2018-07-20 03:51:18 +02:00
|
|
|
if (routing.isOn(Page.Terminal)) {
|
2016-11-24 23:30:33 +01:00
|
|
|
$('.terminal-input').focus();
|
|
|
|
}
|
|
|
|
});
|
2016-12-19 21:59:13 +01:00
|
|
|
$(document).keydown(function(e) {
|
2018-07-20 03:51:18 +02:00
|
|
|
if (routing.isOn(Page.Terminal)) {
|
|
|
|
if (e.which == KEY.CTRL) {
|
2016-12-19 21:59:13 +01:00
|
|
|
terminalCtrlPressed = true;
|
2018-05-06 22:27:47 +02:00
|
|
|
} else if (e.shiftKey) {
|
|
|
|
shiftKeyPressed = true;
|
2018-09-14 23:03:31 +02:00
|
|
|
} else if (terminalCtrlPressed || shiftKeyPressed || Terminal.contractOpen) {
|
2016-12-19 21:59:13 +01:00
|
|
|
//Don't focus
|
|
|
|
} else {
|
2017-05-03 06:38:58 +02:00
|
|
|
var inputTextBox = document.getElementById("terminal-input-text-box");
|
2018-05-06 22:27:47 +02:00
|
|
|
if (inputTextBox != null) {inputTextBox.focus();}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-12-19 21:59:13 +01:00
|
|
|
terminalCtrlPressed = false;
|
2018-05-06 22:27:47 +02:00
|
|
|
shiftKeyPressed = false;
|
2016-12-19 21:59:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
$(document).keyup(function(e) {
|
2018-07-20 03:51:18 +02:00
|
|
|
if (routing.isOn(Page.Terminal)) {
|
|
|
|
if (e.which == KEY.CTRL) {
|
2016-12-19 21:59:13 +01:00
|
|
|
terminalCtrlPressed = false;
|
|
|
|
}
|
2018-05-06 22:27:47 +02:00
|
|
|
if (e.shiftKey) {
|
|
|
|
shiftKeyPressed = false;
|
|
|
|
}
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
//Implements a tab completion feature for terminal
|
2018-06-29 07:39:05 +02:00
|
|
|
// command - Terminal command except for the last incomplete argument
|
2017-05-02 05:05:26 +02:00
|
|
|
// arg - Incomplete argument string that the function will try to complete, or will display
|
2017-05-01 23:38:49 +02:00
|
|
|
// a series of possible options for
|
|
|
|
// allPossibilities - Array of strings containing all possibilities that the
|
|
|
|
// string can complete to
|
2017-05-30 04:02:41 +02:00
|
|
|
// index - index of argument that is being "tab completed". By default is 0, the first argument
|
|
|
|
function tabCompletion(command, arg, allPossibilities, index=0) {
|
2017-05-01 23:38:49 +02:00
|
|
|
if (!(allPossibilities.constructor === Array)) {return;}
|
|
|
|
if (!containsAllStrings(allPossibilities)) {return;}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-07-03 05:35:12 +02:00
|
|
|
//if (!command.startsWith("./")) {
|
|
|
|
//command = command.toLowerCase();
|
|
|
|
//}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-07-22 00:54:55 +02:00
|
|
|
//Remove all options in allPossibilities that do not match the current string
|
|
|
|
//that we are attempting to autocomplete
|
2017-06-03 03:26:17 +02:00
|
|
|
if (arg == "") {
|
|
|
|
for (var i = allPossibilities.length-1; i >= 0; --i) {
|
2017-09-12 01:14:51 +02:00
|
|
|
if (!allPossibilities[i].toLowerCase().startsWith(command.toLowerCase())) {
|
2017-06-03 03:26:17 +02:00
|
|
|
allPossibilities.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (var i = allPossibilities.length-1; i >= 0; --i) {
|
2017-09-12 01:14:51 +02:00
|
|
|
if (!allPossibilities[i].toLowerCase().startsWith(arg.toLowerCase())) {
|
2017-06-03 03:26:17 +02:00
|
|
|
allPossibilities.splice(i, 1);
|
|
|
|
}
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-09 03:46:30 +01:00
|
|
|
const textBox = document.getElementById("terminal-input-text-box");
|
|
|
|
if (textBox == null) {
|
|
|
|
console.warn(`Couldn't find terminal input DOM element (id=terminal-input-text-box) when trying to autocomplete`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const oldValue = textBox.value;
|
|
|
|
const semiColonIndex = oldValue.lastIndexOf(";");
|
|
|
|
|
2017-06-03 03:26:17 +02:00
|
|
|
var val = "";
|
2017-05-02 18:28:54 +02:00
|
|
|
if (allPossibilities.length == 0) {
|
|
|
|
return;
|
2017-07-25 03:06:40 +02:00
|
|
|
} else if (allPossibilities.length == 1) {
|
2017-06-03 03:26:17 +02:00
|
|
|
if (arg == "") {
|
|
|
|
//Autocomplete command
|
2017-06-03 03:46:43 +02:00
|
|
|
val = allPossibilities[0] + " ";
|
2017-06-03 03:26:17 +02:00
|
|
|
} else {
|
|
|
|
val = command + " " + allPossibilities[0];
|
|
|
|
}
|
2018-07-31 02:16:39 +02:00
|
|
|
|
2019-02-09 03:46:30 +01:00
|
|
|
if (semiColonIndex === -1) {
|
2018-07-31 02:16:39 +02:00
|
|
|
// no ; replace the whole thing.
|
|
|
|
textBox.value = val;
|
|
|
|
} else {
|
|
|
|
// replace just after the last semicolon
|
|
|
|
textBox.value = textBox.value.slice(0, semiColonIndex+1)+" "+val;
|
|
|
|
}
|
|
|
|
|
2019-02-09 03:46:30 +01:00
|
|
|
textBox.focus();
|
2017-05-01 23:38:49 +02:00
|
|
|
} else {
|
|
|
|
var longestStartSubstr = longestCommonStart(allPossibilities);
|
|
|
|
//If the longest common starting substring of remaining possibilities is the same
|
|
|
|
//as whatevers already in terminal, just list all possible options. Otherwise,
|
|
|
|
//change the input in the terminal to the longest common starting substr
|
2017-06-03 03:26:17 +02:00
|
|
|
var allOptionsStr = "";
|
|
|
|
for (var i = 0; i < allPossibilities.length; ++i) {
|
|
|
|
allOptionsStr += allPossibilities[i];
|
|
|
|
allOptionsStr += " ";
|
|
|
|
}
|
|
|
|
if (arg == "") {
|
|
|
|
if (longestStartSubstr == command) {
|
|
|
|
post("> " + command);
|
|
|
|
post(allOptionsStr);
|
|
|
|
} else {
|
2019-02-09 03:46:30 +01:00
|
|
|
if (semiColonIndex === -1) {
|
|
|
|
// No ; just replace the whole thing
|
|
|
|
textBox.value = longestStartSubstr;
|
|
|
|
} else {
|
|
|
|
// Multiple commands, so only replace after the last semicolon
|
|
|
|
textBox.value = textBox.value.slice(0, semiColonIndex + 1) + " " + longestStartSubstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
textBox.focus();
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-06-03 03:26:17 +02:00
|
|
|
if (longestStartSubstr == arg) {
|
|
|
|
//List all possible options
|
|
|
|
post("> " + command + " " + arg);
|
|
|
|
post(allOptionsStr);
|
|
|
|
} else {
|
2019-02-09 03:46:30 +01:00
|
|
|
if (semiColonIndex == -1) {
|
|
|
|
// No ; so just replace the whole thing
|
|
|
|
textBox.value = command + " " + longestStartSubstr;
|
|
|
|
} else {
|
|
|
|
// Multiple commands, so only replace after the last semiclon
|
|
|
|
textBox.value = textBox.value.slice(0, semiColonIndex + 1) + " " + command + " " + longestStartSubstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
textBox.focus();
|
2017-06-03 03:26:17 +02:00
|
|
|
}
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-30 04:02:41 +02:00
|
|
|
function determineAllPossibilitiesForTabCompletion(input, index=0) {
|
2017-05-01 23:38:49 +02:00
|
|
|
var allPos = [];
|
2017-07-25 03:06:40 +02:00
|
|
|
allPos = allPos.concat(Object.keys(GlobalAliases));
|
2017-05-01 23:38:49 +02:00
|
|
|
var currServ = Player.getCurrentServer();
|
2017-06-03 03:26:17 +02:00
|
|
|
input = input.toLowerCase();
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-07-27 04:56:14 +02:00
|
|
|
//If the command starts with './' and the index == -1, then the user
|
|
|
|
//has input ./partialexecutablename so autocomplete the script or program
|
|
|
|
//Put './' in front of each script/executable
|
|
|
|
if (input.startsWith("./") && index == -1) {
|
|
|
|
//All programs and scripts
|
|
|
|
for (var i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
allPos.push("./" + currServ.scripts[i].filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Programs are on home computer
|
|
|
|
var homeComputer = Player.getHomeComputer();
|
|
|
|
for(var i = 0; i < homeComputer.programs.length; ++i) {
|
|
|
|
allPos.push("./" + homeComputer.programs[i]);
|
|
|
|
}
|
|
|
|
return allPos;
|
|
|
|
}
|
|
|
|
|
2017-06-03 03:26:17 +02:00
|
|
|
//Autocomplete the command
|
|
|
|
if (index == -1) {
|
2019-02-05 07:45:04 +01:00
|
|
|
return ["alias", "analyze", "cat", "check", "clear", "cls", "connect", "download", "expr",
|
|
|
|
"free", "hack", "help", "home", "hostname", "ifconfig", "kill", "killall",
|
2017-10-10 06:56:48 +02:00
|
|
|
"ls", "lscpu", "mem", "nano", "ps", "rm", "run", "scan", "scan-analyze",
|
2017-06-30 18:44:03 +02:00
|
|
|
"scp", "sudov", "tail", "theme", "top"].concat(Object.keys(Aliases)).concat(Object.keys(GlobalAliases));
|
2017-06-03 03:26:17 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-15 03:27:22 +02:00
|
|
|
if (input.startsWith ("buy ")) {
|
2018-06-21 00:34:39 +02:00
|
|
|
let options = [];
|
|
|
|
for(const i in DarkWebItems) {
|
|
|
|
const item = DarkWebItems[i]
|
|
|
|
options.push(item.program);
|
|
|
|
}
|
|
|
|
return options.concat(Object.keys(GlobalAliases));
|
2017-06-15 03:27:22 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-30 04:02:41 +02:00
|
|
|
if (input.startsWith("scp ") && index == 1) {
|
|
|
|
for (var iphostname in AllServers) {
|
|
|
|
if (AllServers.hasOwnProperty(iphostname)) {
|
|
|
|
allPos.push(AllServers[iphostname].ip);
|
|
|
|
allPos.push(AllServers[iphostname].hostname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-08-18 19:20:51 +02:00
|
|
|
if (input.startsWith("scp ") && index == 0) {
|
|
|
|
//All Scripts and lit files
|
|
|
|
for (var i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
|
|
|
for (var i = 0; i < currServ.messages.length; ++i) {
|
|
|
|
if (!(currServ.messages[i] instanceof Message)) {
|
|
|
|
allPos.push(currServ.messages[i]);
|
|
|
|
}
|
|
|
|
}
|
2018-02-24 23:55:06 +01:00
|
|
|
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
|
|
|
allPos.push(currServ.textFiles[i].fn);
|
|
|
|
}
|
2017-08-18 19:20:51 +02:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
if (input.startsWith("connect ") || input.startsWith("telnet ")) {
|
|
|
|
//All network connections
|
|
|
|
for (var i = 0; i < currServ.serversOnNetwork.length; ++i) {
|
|
|
|
var serv = AllServers[currServ.serversOnNetwork[i]];
|
|
|
|
if (serv == null) {continue;}
|
|
|
|
allPos.push(serv.ip); //IP
|
|
|
|
allPos.push(serv.hostname); //Hostname
|
|
|
|
}
|
|
|
|
return allPos;
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (input.startsWith("kill ") || input.startsWith("tail ") ||
|
2017-08-18 19:20:51 +02:00
|
|
|
input.startsWith("mem ") || input.startsWith("check ")) {
|
2017-05-01 23:38:49 +02:00
|
|
|
//All Scripts
|
|
|
|
for (var i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
|
|
|
return allPos;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
if (input.startsWith("nano ")) {
|
|
|
|
//Scripts and text files and .fconf
|
|
|
|
for (var i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
|
|
|
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
|
|
|
allPos.push(currServ.textFiles[i].fn);
|
|
|
|
}
|
|
|
|
allPos.push(".fconf");
|
|
|
|
return allPos;
|
|
|
|
}
|
|
|
|
|
2017-09-12 01:14:51 +02:00
|
|
|
if (input.startsWith("rm ")) {
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < currServ.scripts.length; ++i) {
|
2017-09-12 01:14:51 +02:00
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < currServ.programs.length; ++i) {
|
2017-09-12 01:14:51 +02:00
|
|
|
allPos.push(currServ.programs[i]);
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < currServ.messages.length; ++i) {
|
2017-09-12 01:14:51 +02:00
|
|
|
if (!(currServ.messages[i] instanceof Message) && isString(currServ.messages[i]) &&
|
|
|
|
currServ.messages[i].endsWith(".lit")) {
|
|
|
|
allPos.push(currServ.messages[i]);
|
|
|
|
}
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < currServ.textFiles.length; ++i) {
|
2017-10-12 04:00:22 +02:00
|
|
|
allPos.push(currServ.textFiles[i].fn);
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < currServ.contracts.length; ++i) {
|
|
|
|
allPos.push(currServ.contracts[i].fn);
|
|
|
|
}
|
2017-09-12 01:14:51 +02:00
|
|
|
return allPos;
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
if (input.startsWith("run ")) {
|
2018-09-23 02:25:48 +02:00
|
|
|
//All programs, scripts, and contracts
|
|
|
|
for (let i = 0; i < currServ.scripts.length; ++i) {
|
2017-05-01 23:38:49 +02:00
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-01 23:38:49 +02:00
|
|
|
//Programs are on home computer
|
|
|
|
var homeComputer = Player.getHomeComputer();
|
2018-09-23 02:25:48 +02:00
|
|
|
for (let i = 0; i < homeComputer.programs.length; ++i) {
|
2017-05-01 23:38:49 +02:00
|
|
|
allPos.push(homeComputer.programs[i]);
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
|
|
|
|
for (let i = 0; i < currServ.contracts.length; ++i) {
|
|
|
|
allPos.push(currServ.contracts[i].fn);
|
|
|
|
}
|
2017-05-01 23:38:49 +02:00
|
|
|
return allPos;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-02 06:15:45 +02:00
|
|
|
if (input.startsWith("cat ")) {
|
|
|
|
for (var i = 0; i < currServ.messages.length; ++i) {
|
2017-08-18 19:20:51 +02:00
|
|
|
if (currServ.messages[i] instanceof Message) {
|
|
|
|
allPos.push(currServ.messages[i].filename);
|
|
|
|
} else {
|
|
|
|
allPos.push(currServ.messages[i]);
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
|
|
|
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
|
|
|
allPos.push(currServ.textFiles[i].fn);
|
2017-06-02 06:15:45 +02:00
|
|
|
}
|
|
|
|
return allPos;
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
|
|
|
|
if (input.startsWith("download ")) {
|
|
|
|
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
|
|
|
allPos.push(currServ.textFiles[i].fn);
|
|
|
|
}
|
2018-02-15 05:26:43 +01:00
|
|
|
for (var i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
allPos.push(currServ.scripts[i].filename);
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
2017-05-01 23:38:49 +02:00
|
|
|
return allPos;
|
|
|
|
}
|
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
let Terminal = {
|
2016-11-01 06:30:59 +01:00
|
|
|
//Flags to determine whether the player is currently running a hack or an analyze
|
2018-08-30 19:00:38 +02:00
|
|
|
hackFlag: false,
|
|
|
|
analyzeFlag: false,
|
|
|
|
actionStarted: false,
|
|
|
|
actionTime: 0,
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-01 19:23:20 +02:00
|
|
|
commandHistory: [],
|
|
|
|
commandHistoryIndex: 0,
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-09-14 23:03:31 +02:00
|
|
|
contractOpen: false, //True if a Coding Contract prompt is opened
|
|
|
|
|
2017-09-13 16:22:22 +02:00
|
|
|
resetTerminalInput: function() {
|
2018-08-29 05:24:38 +02:00
|
|
|
if (FconfSettings.WRAP_INPUT) {
|
|
|
|
document.getElementById("terminal-input-td").innerHTML =
|
2018-09-08 04:53:10 +02:00
|
|
|
"<div id='terminal-input-header' class='prompt'>[" + Player.getCurrentServer().hostname + " ~]" + "$ </div>" +
|
2018-08-29 05:24:38 +02:00
|
|
|
'<textarea type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
|
|
|
|
|
|
|
//Auto re-size the line element as it wraps
|
|
|
|
autosize(document.getElementById("terminal-input-text-box"));
|
|
|
|
} else {
|
|
|
|
document.getElementById("terminal-input-td").innerHTML =
|
2018-09-08 04:53:10 +02:00
|
|
|
"<div id='terminal-input-header' class='prompt'>[" + Player.getCurrentServer().hostname + " ~]" + "$ </div>" +
|
2018-08-29 05:24:38 +02:00
|
|
|
'<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
|
|
|
}
|
2017-09-13 16:22:22 +02:00
|
|
|
var hdr = document.getElementById("terminal-input-header");
|
|
|
|
hdr.style.display = "inline";
|
2018-03-12 20:39:04 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
modifyInput: function(mod) {
|
|
|
|
try {
|
|
|
|
var terminalInput = document.getElementById("terminal-input-text-box");
|
|
|
|
if (terminalInput == null) {return;}
|
|
|
|
terminalInput.focus();
|
|
|
|
|
|
|
|
var inputLength = terminalInput.value.length;
|
|
|
|
var start = terminalInput.selectionStart;
|
|
|
|
var end = terminalInput.selectionEnd;
|
|
|
|
var inputText = terminalInput.value;
|
|
|
|
|
|
|
|
switch(mod.toLowerCase()) {
|
|
|
|
case "backspace":
|
|
|
|
if (start > 0 && start <= inputLength+1) {
|
|
|
|
terminalInput.value = inputText.substr(0, start-1) + inputText.substr(start);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "deletewordbefore": //Delete rest of word before the cursor
|
|
|
|
for (var delStart = start-1; delStart > 0; --delStart) {
|
|
|
|
if (inputText.charAt(delStart) === " ") {
|
|
|
|
terminalInput.value = inputText.substr(0, delStart) + inputText.substr(start);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "deletewordafter": //Delete rest of word after the cursor
|
|
|
|
for (var delStart = start+1; delStart <= text.length+1; ++delStart) {
|
|
|
|
if (inputText.charAt(delStart) === " ") {
|
|
|
|
terminalInput.value = inputText.substr(0, start) + inputText.substr(delStart);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "clearafter": //Deletes everything after cursor
|
|
|
|
break;
|
|
|
|
case "clearbefore:": //Deleetes everything before cursor
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} catch(e) {
|
2019-02-12 01:23:46 +01:00
|
|
|
console.error("Exception in Terminal.modifyInput: " + e);
|
2018-03-12 20:39:04 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
moveTextCursor: function(loc) {
|
|
|
|
try {
|
|
|
|
var terminalInput = document.getElementById("terminal-input-text-box");
|
|
|
|
if (terminalInput == null) {return;}
|
|
|
|
terminalInput.focus();
|
|
|
|
|
|
|
|
var inputLength = terminalInput.value.length;
|
|
|
|
var start = terminalInput.selectionStart;
|
|
|
|
var end = terminalInput.selectionEnd;
|
|
|
|
|
|
|
|
switch(loc.toLowerCase()) {
|
|
|
|
case "home":
|
|
|
|
terminalInput.setSelectionRange(0,0);
|
|
|
|
break;
|
|
|
|
case "end":
|
|
|
|
terminalInput.setSelectionRange(inputLength, inputLength);
|
|
|
|
break;
|
|
|
|
case "prevchar":
|
|
|
|
if (start > 0) {terminalInput.setSelectionRange(start-1, start-1);}
|
|
|
|
break;
|
|
|
|
case "prevword":
|
|
|
|
for (var i = start-2; i >= 0; --i) {
|
|
|
|
if (terminalInput.value.charAt(i) === " ") {
|
|
|
|
terminalInput.setSelectionRange(i+1, i+1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
terminalInput.setSelectionRange(0, 0);
|
|
|
|
break;
|
|
|
|
case "nextchar":
|
|
|
|
terminalInput.setSelectionRange(start+1, start+1);
|
|
|
|
break;
|
|
|
|
case "nextword":
|
|
|
|
for (var i = start+1; i <= inputLength; ++i) {
|
|
|
|
if (terminalInput.value.charAt(i) === " ") {
|
|
|
|
terminalInput.setSelectionRange(i, i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
terminalInput.setSelectionRange(inputLength, inputLength);
|
|
|
|
break;
|
|
|
|
default:
|
2019-02-12 01:23:46 +01:00
|
|
|
console.warn("Invalid loc argument in Terminal.moveTextCursor()");
|
2018-03-12 20:39:04 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} catch(e) {
|
2019-02-12 01:23:46 +01:00
|
|
|
console.error("Exception in Terminal.moveTextCursor: " + e);
|
2018-03-12 20:39:04 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
startHack: function() {
|
|
|
|
Terminal.hackFlag = true;
|
|
|
|
|
|
|
|
//Hacking through Terminal should be faster than hacking through a script
|
|
|
|
Terminal.actionTime = calculateHackingTime(Player.getCurrentServer()) / 4;
|
|
|
|
Terminal.startAction();
|
|
|
|
},
|
|
|
|
|
|
|
|
startAnalyze: function() {
|
|
|
|
Terminal.analyzeFlag = true;
|
|
|
|
Terminal.actionTime = 1;
|
|
|
|
post("Analyzing system...");
|
|
|
|
Terminal.startAction();
|
|
|
|
},
|
|
|
|
|
|
|
|
startAction: function() {
|
|
|
|
Terminal.actionStarted = true;
|
|
|
|
|
|
|
|
hackProgressPost("Time left:");
|
|
|
|
hackProgressBarPost("[");
|
|
|
|
|
|
|
|
//Disable terminal
|
|
|
|
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
|
|
|
|
$('input[class=terminal-input]').prop('disabled', true);
|
|
|
|
},
|
|
|
|
|
2018-03-12 20:39:04 +01:00
|
|
|
finishAction: function(cancelled = false) {
|
|
|
|
if (Terminal.hackFlag) {
|
|
|
|
Terminal.finishHack(cancelled);
|
|
|
|
} else if (Terminal.analyzeFlag) {
|
|
|
|
Terminal.finishAnalyze(cancelled);
|
|
|
|
}
|
2017-09-13 16:22:22 +02:00
|
|
|
},
|
|
|
|
|
2016-11-01 06:30:59 +01:00
|
|
|
//Complete the hack/analyze command
|
2016-12-21 17:33:00 +01:00
|
|
|
finishHack: function(cancelled = false) {
|
|
|
|
if (cancelled == false) {
|
2017-06-02 06:15:45 +02:00
|
|
|
var server = Player.getCurrentServer();
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-12-21 17:33:00 +01:00
|
|
|
//Calculate whether hack was successful
|
2018-08-30 19:00:38 +02:00
|
|
|
var hackChance = calculateHackingChance(server);
|
2016-12-21 17:33:00 +01:00
|
|
|
var rand = Math.random();
|
2018-08-30 19:00:38 +02:00
|
|
|
var expGainedOnSuccess = calculateHackingExpGain(server);
|
2017-05-05 17:50:55 +02:00
|
|
|
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
2016-12-21 17:33:00 +01:00
|
|
|
if (rand < hackChance) { //Success!
|
2017-07-22 00:54:55 +02:00
|
|
|
if (SpecialServerIps[SpecialServerNames.WorldDaemon] &&
|
|
|
|
SpecialServerIps[SpecialServerNames.WorldDaemon] == server.ip) {
|
2017-08-13 07:01:33 +02:00
|
|
|
if (Player.bitNodeN == null) {
|
|
|
|
Player.bitNodeN = 1;
|
|
|
|
}
|
|
|
|
hackWorldDaemon(Player.bitNodeN);
|
2017-07-22 00:54:55 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-06-02 16:45:33 +02:00
|
|
|
server.manuallyHacked = true;
|
2018-08-30 19:00:38 +02:00
|
|
|
var moneyGained = calculatePercentMoneyHacked(server);
|
2017-06-02 06:15:45 +02:00
|
|
|
moneyGained = Math.floor(server.moneyAvailable * moneyGained);
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-09-15 16:06:59 +02:00
|
|
|
if (moneyGained <= 0) {moneyGained = 0;} //Safety check
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-02 06:15:45 +02:00
|
|
|
server.moneyAvailable -= moneyGained;
|
2016-12-21 17:33:00 +01:00
|
|
|
Player.gainMoney(moneyGained);
|
2019-02-22 03:26:28 +01:00
|
|
|
Player.recordMoneySource(moneyGained, "hacking");
|
2017-04-18 06:32:17 +02:00
|
|
|
Player.gainHackingExp(expGainedOnSuccess)
|
2017-09-15 16:06:59 +02:00
|
|
|
Player.gainIntelligenceExp(expGainedOnSuccess / CONSTANTS.IntelligenceTerminalHackBaseExpGain);
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-02 06:15:45 +02:00
|
|
|
server.fortify(CONSTANTS.ServerFortifyAmount);
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-09-12 17:53:08 +02:00
|
|
|
post("Hack successful! Gained " + numeralWrapper.format(moneyGained, '($0,0.00)') + " and " + numeralWrapper.format(expGainedOnSuccess, '0.0000') + " hacking EXP");
|
2016-12-21 17:33:00 +01:00
|
|
|
} else { //Failure
|
|
|
|
//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)
|
2018-09-12 17:53:08 +02:00
|
|
|
post("Failed to hack " + server.hostname + ". Gained " + numeralWrapper.format(expGainedOnFailure, '0.0000') + " hacking EXP");
|
2016-12-21 17:33:00 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-11-01 06:30:59 +01:00
|
|
|
//Rename the progress bar so that the next hacks dont trigger it. Re-enable terminal
|
|
|
|
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
|
|
|
|
$("#hack-progress").attr('id', "old-hack-progress");
|
2017-09-13 16:22:22 +02:00
|
|
|
Terminal.resetTerminalInput();
|
2017-07-25 03:06:40 +02:00
|
|
|
$('input[class=terminal-input]').prop('disabled', false);
|
2016-11-01 06:30:59 +01:00
|
|
|
|
|
|
|
Terminal.hackFlag = false;
|
2016-10-27 20:26:00 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-12-21 17:33:00 +01:00
|
|
|
finishAnalyze: function(cancelled = false) {
|
|
|
|
if (cancelled == false) {
|
2018-08-30 19:00:38 +02:00
|
|
|
let currServ = Player.getCurrentServer();
|
|
|
|
post(currServ.hostname + ": ");
|
|
|
|
post("Organization name: " + currServ.organizationName);
|
2017-05-06 08:24:01 +02:00
|
|
|
var rootAccess = "";
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.hasAdminRights) {rootAccess = "YES";}
|
2017-05-06 08:24:01 +02:00
|
|
|
else {rootAccess = "NO";}
|
|
|
|
post("Root Access: " + rootAccess);
|
2018-08-30 19:00:38 +02:00
|
|
|
post("Required hacking skill: " + currServ.requiredHackingSkill);
|
2018-09-12 17:53:08 +02:00
|
|
|
post("Server security level: " + numeralWrapper.format(currServ.hackDifficulty, '0.000a'));
|
2018-09-23 02:36:28 +02:00
|
|
|
post("Chance to hack: " + numeralWrapper.format(calculateHackingChance(currServ), '0.00%'));
|
2018-09-12 17:53:08 +02:00
|
|
|
post("Time to hack: " + numeralWrapper.format(calculateHackingTime(currServ), '0.000') + " seconds");
|
2018-09-23 02:36:28 +02:00
|
|
|
post("Total money available on server: " + numeralWrapper.format(currServ.moneyAvailable, '$0,0.00'));
|
2018-08-30 19:00:38 +02:00
|
|
|
post("Required number of open ports for NUKE: " + currServ.numOpenPortsRequired);
|
2018-09-10 20:51:21 +02:00
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.sshPortOpen) {
|
2016-12-21 17:33:00 +01:00
|
|
|
post("SSH port: Open")
|
|
|
|
} else {
|
|
|
|
post("SSH port: Closed")
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.ftpPortOpen) {
|
2016-12-21 17:33:00 +01:00
|
|
|
post("FTP port: Open")
|
|
|
|
} else {
|
|
|
|
post("FTP port: Closed")
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.smtpPortOpen) {
|
2016-12-21 17:33:00 +01:00
|
|
|
post("SMTP port: Open")
|
|
|
|
} else {
|
|
|
|
post("SMTP port: Closed")
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.httpPortOpen) {
|
2016-12-21 17:33:00 +01:00
|
|
|
post("HTTP port: Open")
|
|
|
|
} else {
|
|
|
|
post("HTTP port: Closed")
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-08-30 19:00:38 +02:00
|
|
|
if (currServ.sqlPortOpen) {
|
2016-12-21 17:33:00 +01:00
|
|
|
post("SQL port: Open")
|
|
|
|
} else {
|
|
|
|
post("SQL port: Closed")
|
|
|
|
}
|
|
|
|
}
|
2016-11-01 06:30:59 +01:00
|
|
|
Terminal.analyzeFlag = false;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-06 08:06:48 +01:00
|
|
|
// Rename the progress bar so that the next hacks dont trigger it. Re-enable terminal
|
2016-11-21 07:11:14 +01:00
|
|
|
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
|
|
|
|
$("#hack-progress").attr('id', "old-hack-progress");
|
2017-09-13 16:22:22 +02:00
|
|
|
Terminal.resetTerminalInput();
|
2017-07-25 03:06:40 +02:00
|
|
|
$('input[class=terminal-input]').prop('disabled', false);
|
|
|
|
},
|
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
executeCommands : function(commands) {
|
|
|
|
// Sanitize input
|
|
|
|
commands = commands.trim();
|
|
|
|
commands = commands.replace(/\s\s+/g, ' '); //Replace all extra whitespace in command with a single space
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// Handle Terminal History - multiple commands should be saved as one
|
|
|
|
if (Terminal.commandHistory[Terminal.commandHistory.length-1] != commands) {
|
|
|
|
Terminal.commandHistory.push(commands);
|
2017-06-06 03:34:00 +02:00
|
|
|
if (Terminal.commandHistory.length > 50) {
|
|
|
|
Terminal.commandHistory.splice(0, 1);
|
|
|
|
}
|
2017-05-01 19:23:20 +02:00
|
|
|
}
|
2017-06-06 23:22:57 +02:00
|
|
|
Terminal.commandHistoryIndex = Terminal.commandHistory.length;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// Split commands and execute sequentially
|
|
|
|
commands = commands.split(";");
|
|
|
|
for (let i = 0; i < commands.length; i++) {
|
|
|
|
if(commands[i].match(/^\s*$/)) { continue; } // Don't run commands that only have whitespace
|
2019-02-06 08:06:48 +01:00
|
|
|
Terminal.executeCommand(commands[i].trim());
|
2019-02-05 07:45:04 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
parseCommandArguments : function(command) {
|
|
|
|
// This will be used to keep track of whether we're in a quote. This is for situations
|
|
|
|
// like the alias command:
|
|
|
|
// alias run="run NUKE.exe"
|
|
|
|
// We want the run="run NUKE.exe" to be parsed as a single command, so this flag
|
|
|
|
// will keep track of whether we have a quote in
|
|
|
|
let inQuote = ``;
|
|
|
|
|
|
|
|
// Returns an array with the command and its arguments in each index
|
|
|
|
// Properly handles quotation marks (e.g. `run foo.script "the sun"` will return [run, foo.script, the sun])
|
|
|
|
const args = [];
|
|
|
|
let start = 0, i = 0;
|
|
|
|
let prevChar = ''; // Previous character
|
|
|
|
while (i < command.length) {
|
|
|
|
let escaped = false; // Check for escaped quotation marks
|
|
|
|
if (i >= 1) {
|
|
|
|
prevChar = command.charAt(i - 1);
|
|
|
|
if (prevChar === "\\") { escaped = true; }
|
|
|
|
}
|
|
|
|
|
|
|
|
const c = command.charAt(i);
|
|
|
|
if (c === '"') { // Double quotes
|
|
|
|
if (!escaped && prevChar === " ") {
|
|
|
|
const endQuote = command.indexOf('"', i+1);
|
|
|
|
if (endQuote !== -1 && (endQuote === command.length-1 || command.charAt(endQuote+1) === " ")) {
|
|
|
|
args.push(command.substr(i+1, (endQuote - i - 1)));
|
|
|
|
if (endQuote === command.length-1) {
|
|
|
|
start = i = endQuote+1;
|
|
|
|
} else {
|
|
|
|
start = i = endQuote+2; //Skip the space
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (inQuote === ``) {
|
|
|
|
inQuote = `"`;
|
|
|
|
} else if (inQuote === `"`) {
|
|
|
|
inQuote = ``;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (c === "'") { // Single quotes, same thing as above
|
|
|
|
if (!escaped && prevChar === " ") {
|
|
|
|
const endQuote = command.indexOf("'", i+1);
|
|
|
|
if (endQuote !== -1 && (endQuote === command.length-1 || command.charAt(endQuote+1) === " ")) {
|
|
|
|
args.push(command.substr(i+1, (endQuote - i - 1)));
|
|
|
|
if (endQuote === command.length-1) {
|
|
|
|
start = i = endQuote+1;
|
|
|
|
} else {
|
|
|
|
start = i = endQuote+2; //Skip the space
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (inQuote === ``) {
|
|
|
|
inQuote = `'`;
|
|
|
|
} else if (inQuote === `'`) {
|
|
|
|
inQuote = ``;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (c === " " && inQuote === ``) {
|
|
|
|
let arg = command.substr(start, i-start);
|
|
|
|
|
|
|
|
// If this is a number, convert it from a string to number
|
|
|
|
if (isNumber(arg)) {
|
|
|
|
args.push(parseFloat(arg));
|
|
|
|
} else {
|
|
|
|
args.push(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
start = i+1;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the last argument
|
|
|
|
if (start !== i) {
|
|
|
|
let arg = command.substr(start, i-start);
|
|
|
|
|
|
|
|
// If this is a number, convert it from string to number
|
|
|
|
if (isNumber(arg)) {
|
|
|
|
args.push(parseFloat(arg));
|
|
|
|
} else {
|
|
|
|
args.push(arg);
|
|
|
|
}
|
|
|
|
}
|
2019-02-12 01:23:46 +01:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
return args;
|
|
|
|
},
|
|
|
|
|
|
|
|
executeCommand : function(command) {
|
2017-05-23 17:12:09 +02:00
|
|
|
//Process any aliases
|
|
|
|
command = substituteAliases(command);
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-07-22 00:54:55 +02:00
|
|
|
//Allow usage of ./
|
|
|
|
if (command.startsWith("./")) {
|
2017-07-27 04:56:14 +02:00
|
|
|
command = "run " + command.slice(2);
|
2017-07-22 00:54:55 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-23 05:50:06 +02:00
|
|
|
//Only split the first space
|
2019-02-05 07:45:04 +01:00
|
|
|
var commandArray = Terminal.parseCommandArguments(command);
|
|
|
|
if (commandArray.length == 0) { return; }
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
/****************** Interactive Tutorial Terminal Commands ******************/
|
2018-08-29 21:06:21 +02:00
|
|
|
if (ITutorial.isRunning) {
|
2017-05-06 08:24:01 +02:00
|
|
|
var foodnstuffServ = GetServerByHostname("foodnstuff");
|
|
|
|
if (foodnstuffServ == null) {throw new Error("Could not get foodnstuff server"); return;}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-08-29 21:06:21 +02:00
|
|
|
switch(ITutorial.currStep) {
|
2017-05-06 08:24:01 +02:00
|
|
|
case iTutorialSteps.TerminalHelp:
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1 && commandArray[0] == "help") {
|
2017-07-22 00:54:55 +02:00
|
|
|
post(TerminalHelpText);
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalLs:
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1 && commandArray[0] == "ls") {
|
2017-05-06 08:24:01 +02:00
|
|
|
Terminal.executeListCommand(commandArray);
|
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalScan:
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1 && commandArray[0] == "scan") {
|
2017-05-06 08:24:01 +02:00
|
|
|
Terminal.executeScanCommand(commandArray);
|
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
2017-05-25 01:23:28 +02:00
|
|
|
case iTutorialSteps.TerminalScanAnalyze1:
|
|
|
|
if (commandArray.length == 1 && commandArray[0] == "scan-analyze") {
|
|
|
|
Terminal.executeScanAnalyzeCommand(1);
|
|
|
|
iTutorialNextStep();
|
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalScanAnalyze2:
|
|
|
|
if (commandArray.length == 2 && commandArray[0] == "scan-analyze" &&
|
2019-02-05 07:45:04 +01:00
|
|
|
commandArray[1] === 2) {
|
2017-05-25 01:23:28 +02:00
|
|
|
Terminal.executeScanAnalyzeCommand(2);
|
|
|
|
iTutorialNextStep();
|
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
|
|
|
break;
|
2017-05-06 08:24:01 +02:00
|
|
|
case iTutorialSteps.TerminalConnect:
|
|
|
|
if (commandArray.length == 2) {
|
2017-05-25 01:23:28 +02:00
|
|
|
if ((commandArray[0] == "connect") &&
|
2017-05-06 08:24:01 +02:00
|
|
|
(commandArray[1] == "foodnstuff" || commandArray[1] == foodnstuffServ.ip)) {
|
|
|
|
Player.getCurrentServer().isConnectedTo = false;
|
|
|
|
Player.currentServer = foodnstuffServ.ip;
|
|
|
|
Player.getCurrentServer().isConnectedTo = true;
|
|
|
|
post("Connected to foodnstuff");
|
|
|
|
iTutorialNextStep();
|
|
|
|
} else {post("Wrong command! Try again!"); return;}
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalAnalyze:
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1 && commandArray[0] === "analyze") {
|
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
post("Incorrect usage of analyze command. Usage: analyze");
|
|
|
|
return;
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2018-08-30 19:00:38 +02:00
|
|
|
Terminal.startAnalyze();
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
|
|
|
} else {
|
2017-05-16 05:31:05 +02:00
|
|
|
post("Bad command. Please follow the tutorial");
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalNuke:
|
2017-07-25 03:06:40 +02:00
|
|
|
if (commandArray.length == 2 &&
|
2017-05-06 08:24:01 +02:00
|
|
|
commandArray[0] == "run" && commandArray[1] == "NUKE.exe") {
|
|
|
|
foodnstuffServ.hasAdminRights = true;
|
|
|
|
post("NUKE successful! Gained root access to foodnstuff");
|
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalManualHack:
|
|
|
|
if (commandArray.length == 1 && commandArray[0] == "hack") {
|
2018-08-30 19:00:38 +02:00
|
|
|
Terminal.startHack();
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalCreateScript:
|
2017-07-25 03:06:40 +02:00
|
|
|
if (commandArray.length == 2 &&
|
2017-05-06 08:24:01 +02:00
|
|
|
commandArray[0] == "nano" && commandArray[1] == "foodnstuff.script") {
|
2018-03-12 20:53:07 +01:00
|
|
|
Engine.loadScriptEditorContent("foodnstuff.script", "");
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2019-02-05 07:45:04 +01:00
|
|
|
break;
|
2017-05-06 08:24:01 +02:00
|
|
|
case iTutorialSteps.TerminalFree:
|
|
|
|
if (commandArray.length == 1 && commandArray[0] == "free") {
|
|
|
|
Terminal.executeFreeCommand(commandArray);
|
|
|
|
iTutorialNextStep();
|
2019-02-05 07:45:04 +01:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.TerminalRunScript:
|
2017-07-25 03:06:40 +02:00
|
|
|
if (commandArray.length == 2 &&
|
2017-05-06 08:24:01 +02:00
|
|
|
commandArray[0] == "run" && commandArray[1] == "foodnstuff.script") {
|
2019-02-12 01:23:46 +01:00
|
|
|
Terminal.runScript(commandArray);
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
|
|
|
case iTutorialSteps.ActiveScriptsToTerminal:
|
|
|
|
if (commandArray.length == 2 &&
|
|
|
|
commandArray[0] == "tail" && commandArray[1] == "foodnstuff.script") {
|
2017-06-18 23:01:23 +02:00
|
|
|
//Check that the script exists on this machine
|
|
|
|
var runningScript = findRunningScript("foodnstuff.script", [], Player.getCurrentServer());
|
|
|
|
if (runningScript == null) {
|
|
|
|
post("Error: No such script exists");
|
|
|
|
return;
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2017-06-18 23:01:23 +02:00
|
|
|
logBoxCreate(runningScript);
|
2017-05-06 08:24:01 +02:00
|
|
|
iTutorialNextStep();
|
2017-05-16 05:31:05 +02:00
|
|
|
} else {post("Bad command. Please follow the tutorial");}
|
2017-05-06 08:24:01 +02:00
|
|
|
break;
|
2017-07-25 03:06:40 +02:00
|
|
|
default:
|
2017-05-06 08:24:01 +02:00
|
|
|
post("Please follow the tutorial, or click 'Exit Tutorial' if you'd like to skip it");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
/****************** END INTERACTIVE TUTORIAL ******************/
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
/* Command parser */
|
2017-06-17 04:53:57 +02:00
|
|
|
var s = Player.getCurrentServer();
|
2017-06-03 02:41:46 +02:00
|
|
|
switch (commandArray[0].toLowerCase()) {
|
2017-05-23 05:50:06 +02:00
|
|
|
case "alias":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1) {
|
2017-05-23 05:50:06 +02:00
|
|
|
printAliases();
|
2017-06-30 18:44:03 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 2) {
|
|
|
|
if (parseAliasDeclaration(commandArray[1])) {
|
|
|
|
post(`Set alias ${commandArray[1]}`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (commandArray.length === 3) {
|
|
|
|
if (commandArray[1] === "-g") {
|
|
|
|
if (parseAliasDeclaration(commandArray[2], true)) {
|
|
|
|
post(`Set global alias ${commandArray[1]}`);
|
2017-07-05 19:53:51 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-05-23 15:49:20 +02:00
|
|
|
}
|
2017-05-23 05:50:06 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
postError('Incorrect usage of alias command. Usage: alias [-g] [aliasname="value"]');
|
2017-05-23 05:50:06 +02:00
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "analyze":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
post("Incorrect usage of analyze command. Usage: analyze");
|
|
|
|
return;
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2018-08-30 19:00:38 +02:00
|
|
|
Terminal.startAnalyze();
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2017-05-05 17:50:55 +02:00
|
|
|
case "buy":
|
2017-06-14 03:07:02 +02:00
|
|
|
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
|
|
|
executeDarkwebTerminalCommand(commandArray);
|
2017-06-15 03:27:22 +02:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("You need to be able to connect to the Dark Web to use the buy command. (Maybe there's a TOR router you can buy somewhere)");
|
2017-06-14 03:07:02 +02:00
|
|
|
}
|
2017-06-02 06:15:45 +02:00
|
|
|
break;
|
|
|
|
case "cat":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError("Incorrect usage of cat command. Usage: cat [file]");
|
|
|
|
return;
|
2017-06-02 06:15:45 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
let filename = commandArray[1];
|
2017-10-12 04:00:22 +02:00
|
|
|
if (!filename.endsWith(".msg") && !filename.endsWith(".lit") && !filename.endsWith(".txt")) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Only .msg, .txt, and .lit files are viewable with cat (filename must end with .msg, .txt, or .lit)");
|
|
|
|
return;
|
2017-06-02 06:15:45 +02:00
|
|
|
}
|
|
|
|
for (var i = 0; i < s.messages.length; ++i) {
|
2017-08-18 19:20:51 +02:00
|
|
|
if (filename.endsWith(".lit") && s.messages[i] == filename) {
|
|
|
|
showLiterature(s.messages[i]);
|
|
|
|
return;
|
|
|
|
} else if (filename.endsWith(".msg") && s.messages[i].filename == filename) {
|
2017-06-02 06:15:45 +02:00
|
|
|
showMessage(s.messages[i]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
for (var i = 0; i < s.textFiles.length; ++i) {
|
|
|
|
if (s.textFiles[i].fn === filename) {
|
|
|
|
s.textFiles[i].show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
postError(`No such file ${filename}`);
|
2017-06-15 03:19:52 +02:00
|
|
|
break;
|
|
|
|
case "check":
|
2017-06-17 04:53:57 +02:00
|
|
|
if (commandArray.length < 2) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect number of arguments. Usage: check [script] [arg1] [arg2]...");
|
2017-06-15 03:19:52 +02:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
var scriptName = commandArray[1];
|
|
|
|
//Can only tail script files
|
|
|
|
if (!isScriptFilename(scriptName)) {
|
|
|
|
postError("tail can only be called on .script files (filename must end with .script)");
|
|
|
|
return;
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// Get args
|
|
|
|
let args = [];
|
|
|
|
for (var i = 2; i < commandArray.length; ++i) {
|
|
|
|
args.push(commandArray[i]);
|
2017-06-15 03:19:52 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// Check that the script exists on this machine
|
2017-06-17 04:53:57 +02:00
|
|
|
var runningScript = findRunningScript(scriptName, args, s);
|
|
|
|
if (runningScript == null) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("No such script exists");
|
2017-06-17 04:53:57 +02:00
|
|
|
return;
|
2017-06-15 03:19:52 +02:00
|
|
|
}
|
2017-06-19 16:54:11 +02:00
|
|
|
runningScript.displayLog();
|
2017-06-15 03:19:52 +02:00
|
|
|
}
|
2017-05-05 17:50:55 +02:00
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "clear":
|
|
|
|
case "cls":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of clear/cls command. Usage: clear/cls");
|
|
|
|
return;
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2016-10-20 23:11:01 +02:00
|
|
|
$("#terminal tr:not(:last)").remove();
|
|
|
|
postNetburnerText();
|
2017-07-25 03:06:40 +02:00
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "connect":
|
2016-10-27 20:26:00 +02:00
|
|
|
//Disconnect from current server in terminal and connect to new one
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError("Incorrect usage of connect command. Usage: connect [ip/hostname]");
|
2016-10-24 08:34:04 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
let ip = commandArray[1];
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-12-01 23:18:18 +01:00
|
|
|
for (var i = 0; i < Player.getCurrentServer().serversOnNetwork.length; i++) {
|
|
|
|
if (Player.getCurrentServer().getServerOnNetwork(i).ip == ip || Player.getCurrentServer().getServerOnNetwork(i).hostname == ip) {
|
2017-06-23 16:23:35 +02:00
|
|
|
Terminal.connectToServer(ip);
|
2016-10-24 08:34:04 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Host not found");
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2017-10-12 04:00:22 +02:00
|
|
|
case "download":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError("Incorrect usage of download command. Usage: download [script/text file]");
|
2017-10-12 04:00:22 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
var fn = commandArray[1];
|
2018-03-12 20:39:04 +01:00
|
|
|
if (fn === "*" || fn === "*.script" || fn === "*.txt") {
|
|
|
|
//Download all scripts as a zip
|
|
|
|
var zip = new JSZip();
|
|
|
|
if (fn === "*" || fn === "*.script") {
|
|
|
|
for (var i = 0; i < s.scripts.length; ++i) {
|
|
|
|
var file = new Blob([s.scripts[i].code], {type:"text/plain"});
|
2018-06-26 19:27:57 +02:00
|
|
|
zip.file(s.scripts[i].filename + ".js", file);
|
2018-03-12 20:39:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (fn === "*" || fn === "*.txt") {
|
|
|
|
for (var i = 0; i < s.textFiles.length; ++i) {
|
|
|
|
var file = new Blob([s.textFiles[i].text], {type:"text/plain"});
|
|
|
|
zip.file(s.textFiles[i].fn, file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
let zipFn;
|
2018-03-12 20:39:04 +01:00
|
|
|
switch (fn) {
|
|
|
|
case "*.script":
|
2019-02-05 07:45:04 +01:00
|
|
|
zipFn = "bitburnerScripts.zip"; break;
|
2018-03-12 20:39:04 +01:00
|
|
|
case "*.txt":
|
2019-02-05 07:45:04 +01:00
|
|
|
zipFn = "bitburnerTexts.zip"; break;
|
2018-03-12 20:39:04 +01:00
|
|
|
default:
|
2019-02-05 07:45:04 +01:00
|
|
|
zipFn = "bitburnerFiles.zip"; break;
|
2018-03-12 20:39:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
zip.generateAsync({type:"blob"}).then(function(content) {
|
2019-02-05 07:45:04 +01:00
|
|
|
FileSaver.saveAs(content, zipFn);
|
2018-03-12 20:39:04 +01:00
|
|
|
});
|
|
|
|
return;
|
2018-05-06 00:13:35 +02:00
|
|
|
} else if (isScriptFilename(fn)) {
|
2018-03-12 20:39:04 +01:00
|
|
|
//Download a single script
|
2018-02-15 05:26:43 +01:00
|
|
|
for (var i = 0; i < s.scripts.length; ++i) {
|
|
|
|
if (s.scripts[i].filename === fn) {
|
|
|
|
return s.scripts[i].download();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (fn.endsWith(".txt")) {
|
2018-03-12 20:39:04 +01:00
|
|
|
//Download a single text file
|
2018-02-15 05:26:43 +01:00
|
|
|
var txtFile = getTextFile(fn, s);
|
|
|
|
if (txtFile !== null) {
|
|
|
|
return txtFile.download();
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
postError(`${fn} does not exist`);
|
2018-11-18 01:23:48 +01:00
|
|
|
break;
|
|
|
|
case "expr":
|
|
|
|
if (commandArray.length <= 1) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect usage of expr command. Usage: expr [math expression]");
|
2018-11-18 01:23:48 +01:00
|
|
|
return;
|
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
let expr = commandArray.slice(1).join("");
|
2018-11-18 01:23:48 +01:00
|
|
|
|
|
|
|
// Sanitize the math expression
|
2019-02-05 07:45:04 +01:00
|
|
|
let sanitizedExpr = expr.replace(/s+/g, '').replace(/[^-()\d/*+.]/g, '');
|
2018-11-18 01:23:48 +01:00
|
|
|
let result;
|
|
|
|
try {
|
|
|
|
result = eval(sanitizedExpr);
|
|
|
|
} catch(e) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError(`Could not evaluate expression: ${sanitizedExpr}`);
|
2018-11-18 01:23:48 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
post(result);
|
2017-10-12 04:00:22 +02:00
|
|
|
break;
|
2016-12-01 23:18:18 +01:00
|
|
|
case "free":
|
2017-05-06 21:12:45 +02:00
|
|
|
Terminal.executeFreeCommand(commandArray);
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
|
|
|
case "hack":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of hack command. Usage: hack");
|
|
|
|
return;
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2016-10-27 20:26:00 +02:00
|
|
|
//Hack the current PC (usually for money)
|
2016-10-20 20:26:38 +02:00
|
|
|
//You can't hack your home pc or servers you purchased
|
2016-12-01 23:18:18 +01:00
|
|
|
if (Player.getCurrentServer().purchasedByPlayer) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Cannot hack your own machines! You are currently connected to your home PC or one of your purchased servers");
|
2016-12-01 23:18:18 +01:00
|
|
|
} else if (Player.getCurrentServer().hasAdminRights == false ) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("You do not have admin rights for this machine! Cannot hack");
|
2016-12-01 23:18:18 +01:00
|
|
|
} else if (Player.getCurrentServer().requiredHackingSkill > Player.hacking_skill) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill");
|
2016-10-20 20:26:38 +02:00
|
|
|
} else {
|
2018-08-30 19:00:38 +02:00
|
|
|
Terminal.startHack();
|
2016-10-20 20:26:38 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "help":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1 && commandArray.length !== 2) {
|
|
|
|
postError("Incorrect usage of help command. Usage: help");
|
|
|
|
return;
|
2016-12-15 18:51:23 +01:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1) {
|
2017-07-22 00:54:55 +02:00
|
|
|
post(TerminalHelpText);
|
|
|
|
} else {
|
|
|
|
var cmd = commandArray[1];
|
|
|
|
var txt = HelpTexts[cmd];
|
|
|
|
if (txt == null) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("No help topics match '" + cmd + "'");
|
2017-07-22 00:54:55 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
post(txt);
|
|
|
|
}
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2016-12-14 00:52:32 +01:00
|
|
|
case "home":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of home command. Usage: home");
|
|
|
|
return;
|
2017-05-05 03:08:44 +02:00
|
|
|
}
|
|
|
|
Player.getCurrentServer().isConnectedTo = false;
|
|
|
|
Player.currentServer = Player.getHomeComputer().ip;
|
|
|
|
Player.getCurrentServer().isConnectedTo = true;
|
|
|
|
post("Connected to home");
|
2017-09-13 16:22:22 +02:00
|
|
|
Terminal.resetTerminalInput();
|
2016-12-14 00:52:32 +01:00
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "hostname":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of hostname command. Usage: hostname");
|
|
|
|
return;
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2016-12-01 23:18:18 +01:00
|
|
|
post(Player.getCurrentServer().hostname);
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
|
|
|
case "ifconfig":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of ifconfig command. Usage: ifconfig");
|
|
|
|
return;
|
2016-11-24 23:30:33 +01:00
|
|
|
}
|
2016-12-01 23:18:18 +01:00
|
|
|
post(Player.getCurrentServer().ip);
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
|
|
|
case "kill":
|
2019-02-05 07:45:04 +01:00
|
|
|
Terminal.executeKillCommand(commandArray);
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2017-06-05 19:59:30 +02:00
|
|
|
case "killall":
|
2017-06-17 04:53:57 +02:00
|
|
|
for (var i = s.runningScripts.length-1; i >= 0; --i) {
|
2017-06-05 19:59:30 +02:00
|
|
|
killWorkerScript(s.runningScripts[i], s.ip);
|
|
|
|
}
|
|
|
|
post("Killing all running scripts. May take up to a few minutes for the scripts to die...");
|
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "ls":
|
2017-05-06 08:24:01 +02:00
|
|
|
Terminal.executeListCommand(commandArray);
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2017-10-10 06:56:48 +02:00
|
|
|
case "lscpu":
|
|
|
|
post(Player.getCurrentServer().cpuCores + " Core(s)");
|
|
|
|
break;
|
2017-05-15 04:46:52 +02:00
|
|
|
case "mem":
|
2019-02-05 07:45:04 +01:00
|
|
|
Terminal.executeMemCommand(commandArray);
|
2017-05-15 04:46:52 +02:00
|
|
|
break;
|
2016-11-24 23:30:33 +01:00
|
|
|
case "nano":
|
2019-02-05 07:45:04 +01:00
|
|
|
Terminal.executeNanoCommand(commandArray);
|
2016-11-24 23:30:33 +01:00
|
|
|
break;
|
2016-10-20 20:26:38 +02:00
|
|
|
case "ps":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of ps command. Usage: ps");
|
|
|
|
return;
|
2016-12-05 23:31:46 +01:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.runningScripts.length; i++) {
|
|
|
|
let rsObj = s.runningScripts[i];
|
|
|
|
let res = rsObj.filename;
|
|
|
|
for (let j = 0; j < rsObj.args.length; ++j) {
|
2017-06-17 04:53:57 +02:00
|
|
|
res += (" " + rsObj.args[j].toString());
|
|
|
|
}
|
|
|
|
post(res);
|
2016-12-05 23:31:46 +01:00
|
|
|
}
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
|
|
|
case "rm":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError("Incorrect number of arguments. Usage: rm [program/script]");
|
|
|
|
return;
|
2017-04-13 21:36:03 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-04-13 21:36:03 +02:00
|
|
|
//Check programs
|
2019-02-05 07:45:04 +01:00
|
|
|
let delTarget = commandArray[1];
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-24 22:20:56 +01:00
|
|
|
if (delTarget.endsWith(".exe")) {
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.programs.length; ++i) {
|
|
|
|
if (s.programs[i] === delTarget) {
|
2017-10-12 04:00:22 +02:00
|
|
|
s.programs.splice(i, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2018-05-06 00:13:35 +02:00
|
|
|
} else if (isScriptFilename(delTarget)) {
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.scripts.length; ++i) {
|
|
|
|
if (s.scripts[i].filename === delTarget) {
|
2017-10-12 04:00:22 +02:00
|
|
|
//Check that the script isnt currently running
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let j = 0; j < s.runningScripts.length; ++j) {
|
2017-10-12 04:00:22 +02:00
|
|
|
if (s.runningScripts[j].filename == delTarget) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Cannot delete a script that is currently running!");
|
2017-10-12 04:00:22 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
s.scripts.splice(i, 1);
|
|
|
|
return;
|
2017-04-13 21:36:03 +02:00
|
|
|
}
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
} else if (delTarget.endsWith(".lit")) {
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.messages.length; ++i) {
|
|
|
|
let f = s.messages[i];
|
2017-10-12 04:00:22 +02:00
|
|
|
if (!(f instanceof Message) && isString(f) && f === delTarget) {
|
|
|
|
s.messages.splice(i, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (delTarget.endsWith(".txt")) {
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.textFiles.length; ++i) {
|
2017-10-12 04:00:22 +02:00
|
|
|
if (s.textFiles[i].fn === delTarget) {
|
|
|
|
s.textFiles.splice(i, 1);
|
|
|
|
return;
|
|
|
|
}
|
2017-09-12 01:14:51 +02:00
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
} else if (delTarget.endsWith(".cct")) {
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < s.contracts.length; ++i) {
|
2018-09-23 02:25:48 +02:00
|
|
|
if (s.contracts[i].fn === delTarget) {
|
|
|
|
s.contracts.splice(i, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-09-12 01:14:51 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Error: No such file exists");
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
|
|
|
case "run":
|
2016-10-24 23:16:51 +02:00
|
|
|
//Run a program or a script
|
2019-02-06 03:32:15 +01:00
|
|
|
if (commandArray.length < 2) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect number of arguments. Usage: run [program/script] [-t] [num threads] [arg1] [arg2]...");
|
2016-10-24 23:16:51 +02:00
|
|
|
} else {
|
|
|
|
var executableName = commandArray[1];
|
2018-01-09 21:48:06 +01:00
|
|
|
|
2018-02-15 05:26:43 +01:00
|
|
|
//Secret Music player!
|
2018-01-09 21:48:06 +01:00
|
|
|
if (executableName === "musicplayer") {
|
|
|
|
post('<iframe src="https://open.spotify.com/embed/user/danielyxie/playlist/1ORnnL6YNvXOracUaUV2kh" width="300" height="380" frameborder="0" allowtransparency="true"></iframe>', false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-25 03:06:40 +02:00
|
|
|
//Check if its a script or just a program/executable
|
2019-02-06 03:32:15 +01:00
|
|
|
if (isScriptFilename(executableName)) {
|
|
|
|
Terminal.runScript(commandArray);
|
2018-09-14 23:03:31 +02:00
|
|
|
} else if (executableName.endsWith(".cct")) {
|
|
|
|
Terminal.runContract(executableName);
|
2018-05-06 22:27:47 +02:00
|
|
|
} else {
|
2019-02-20 09:42:27 +01:00
|
|
|
Terminal.runProgram(commandArray);
|
2016-10-24 23:16:51 +02:00
|
|
|
}
|
|
|
|
}
|
2016-10-20 20:26:38 +02:00
|
|
|
break;
|
2017-05-23 19:36:35 +02:00
|
|
|
case "scan":
|
|
|
|
Terminal.executeScanCommand(commandArray);
|
|
|
|
break;
|
2017-05-23 18:15:17 +02:00
|
|
|
case "scan-analyze":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 1) {
|
2017-05-24 19:07:33 +02:00
|
|
|
Terminal.executeScanAnalyzeCommand(1);
|
2019-02-05 07:45:04 +01:00
|
|
|
} else {
|
|
|
|
// # of args must be 2 or 3
|
|
|
|
if (commandArray.length > 3) {
|
|
|
|
postError("Incorrect usage of scan-analyze command. usage: scan-analyze [depth]");
|
|
|
|
return;
|
2017-09-19 20:38:03 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
let all = false;
|
|
|
|
if (commandArray.length === 3 && commandArray[2] === "-a") {
|
|
|
|
all = true;
|
2017-09-19 20:38:03 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
|
|
|
|
let depth = parseInt(commandArray[1]);
|
|
|
|
|
2017-05-24 23:35:24 +02:00
|
|
|
if (isNaN(depth) || depth < 0) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect usage of scan-analyze command. depth argument must be positive numeric");
|
2017-05-24 23:35:24 +02:00
|
|
|
return;
|
|
|
|
}
|
2018-06-02 01:31:34 +02:00
|
|
|
if (depth > 3 && !Player.hasProgram(Programs.DeepscanV1.name) &&
|
|
|
|
!Player.hasProgram(Programs.DeepscanV2.name)) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("You cannot scan-analyze with that high of a depth. Maximum depth is 3");
|
2017-05-24 23:35:24 +02:00
|
|
|
return;
|
2018-06-02 01:31:34 +02:00
|
|
|
} else if (depth > 5 && !Player.hasProgram(Programs.DeepscanV2.name)) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("You cannot scan-analyze with that high of a depth. Maximum depth is 5");
|
2017-05-24 23:35:24 +02:00
|
|
|
return;
|
|
|
|
} else if (depth > 10) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("You cannot scan-analyze with that high of a depth. Maximum depth is 10");
|
2017-05-24 19:07:33 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-09-19 20:38:03 +02:00
|
|
|
Terminal.executeScanAnalyzeCommand(depth, all);
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
2017-05-23 18:15:17 +02:00
|
|
|
break;
|
2018-09-10 16:59:07 +02:00
|
|
|
/* eslint-disable no-case-declarations */
|
2016-10-20 20:26:38 +02:00
|
|
|
case "scp":
|
2019-02-05 07:45:04 +01:00
|
|
|
Terminal.executeScpCommand(commandArray);
|
2018-09-08 03:53:11 +02:00
|
|
|
break;
|
2018-09-10 16:59:07 +02:00
|
|
|
/* eslint-enable no-case-declarations */
|
2017-05-06 08:24:01 +02:00
|
|
|
case "sudov":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect number of arguments. Usage: sudov");
|
|
|
|
return;
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
if (s.hasAdminRights) {
|
2017-05-06 08:24:01 +02:00
|
|
|
post("You have ROOT access to this machine");
|
|
|
|
} else {
|
|
|
|
post("You do NOT have root access to this machine");
|
|
|
|
}
|
|
|
|
break;
|
2016-12-02 22:57:20 +01:00
|
|
|
case "tail":
|
2017-06-17 04:53:57 +02:00
|
|
|
if (commandArray.length < 2) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
|
2017-03-31 23:47:06 +02:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
let scriptName = commandArray[1];
|
|
|
|
if (!isScriptFilename(scriptName)) {
|
|
|
|
postError("tail can only be called on .script files (filename must end with .script)");
|
|
|
|
return;
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// Get script arguments
|
|
|
|
let args = [];
|
|
|
|
for (var i = 2; i < commandArray.length; ++i) {
|
|
|
|
args.push(commandArray[i]);
|
2017-03-31 23:47:06 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-03-31 23:47:06 +02:00
|
|
|
//Check that the script exists on this machine
|
2019-02-05 07:45:04 +01:00
|
|
|
let runningScript = findRunningScript(scriptName, args, s);
|
2017-06-17 04:53:57 +02:00
|
|
|
if (runningScript == null) {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("No such script exists");
|
2017-06-17 04:53:57 +02:00
|
|
|
return;
|
2017-03-31 23:47:06 +02:00
|
|
|
}
|
2017-06-17 04:53:57 +02:00
|
|
|
logBoxCreate(runningScript);
|
2017-03-31 23:47:06 +02:00
|
|
|
}
|
2016-12-02 22:57:20 +01:00
|
|
|
break;
|
2017-06-07 03:23:51 +02:00
|
|
|
case "theme":
|
2019-02-05 07:45:04 +01:00
|
|
|
let args = commandArray.slice(1);
|
|
|
|
if (args.length !== 1 && args.length !== 3) {
|
|
|
|
postError("Incorrect number of arguments.");
|
|
|
|
postError("Usage: theme [default|muted|solarized] | #[background color hex] #[text color hex] #[highlight color hex]");
|
|
|
|
} else if(args.length === 1){
|
2017-06-07 03:23:51 +02:00
|
|
|
var themeName = args[0];
|
2018-02-15 05:26:43 +01:00
|
|
|
if (themeName == "default"){
|
2017-06-07 03:23:51 +02:00
|
|
|
document.body.style.setProperty('--my-highlight-color',"#ffffff");
|
|
|
|
document.body.style.setProperty('--my-font-color',"#66ff33");
|
|
|
|
document.body.style.setProperty('--my-background-color',"#000000");
|
2018-09-21 21:47:33 +02:00
|
|
|
document.body.style.setProperty('--my-prompt-color', "#f92672");
|
2018-02-15 05:26:43 +01:00
|
|
|
} else if (themeName == "muted"){
|
2017-06-07 03:23:51 +02:00
|
|
|
document.body.style.setProperty('--my-highlight-color',"#ffffff");
|
|
|
|
document.body.style.setProperty('--my-font-color',"#66ff33");
|
|
|
|
document.body.style.setProperty('--my-background-color',"#252527");
|
2018-02-15 05:26:43 +01:00
|
|
|
} else if (themeName == "solarized"){
|
2017-06-07 03:23:51 +02:00
|
|
|
document.body.style.setProperty('--my-highlight-color',"#6c71c4");
|
|
|
|
document.body.style.setProperty('--my-font-color',"#839496");
|
|
|
|
document.body.style.setProperty('--my-background-color',"#002b36");
|
2018-02-15 05:26:43 +01:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
return postError("Theme not found");
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
2018-09-21 21:47:33 +02:00
|
|
|
FconfSettings.THEME_HIGHLIGHT_COLOR = document.body.style.getPropertyValue("--my-highlight-color");
|
|
|
|
FconfSettings.THEME_FONT_COLOR = document.body.style.getPropertyValue("--my-font-color");
|
|
|
|
FconfSettings.THEME_BACKGROUND_COLOR = document.body.style.getPropertyValue("--my-background-color");
|
|
|
|
FconfSettings.THEME_PROMPT_COLOR = document.body.style.getPropertyValue("--my-prompt-color");
|
2018-02-15 05:26:43 +01:00
|
|
|
} else {
|
2018-01-09 21:48:06 +01:00
|
|
|
var inputBackgroundHex = args[0];
|
|
|
|
var inputTextHex = args[1];
|
|
|
|
var inputHighlightHex = args[2];
|
2018-02-15 05:26:43 +01:00
|
|
|
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputBackgroundHex) &&
|
2017-06-07 03:23:51 +02:00
|
|
|
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputTextHex) &&
|
|
|
|
/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(inputHighlightHex)){
|
|
|
|
document.body.style.setProperty('--my-highlight-color',inputHighlightHex);
|
|
|
|
document.body.style.setProperty('--my-font-color',inputTextHex);
|
|
|
|
document.body.style.setProperty('--my-background-color',inputBackgroundHex);
|
2018-09-21 21:47:33 +02:00
|
|
|
FconfSettings.THEME_HIGHLIGHT_COLOR = document.body.style.getPropertyValue("--my-highlight-color");
|
|
|
|
FconfSettings.THEME_FONT_COLOR = document.body.style.getPropertyValue("--my-font-color");
|
|
|
|
FconfSettings.THEME_BACKGROUND_COLOR = document.body.style.getPropertyValue("--my-background-color");
|
2018-02-15 05:26:43 +01:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
return postError("Invalid Hex Input for theme");
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
2017-06-07 03:23:51 +02:00
|
|
|
}
|
|
|
|
break;
|
2016-12-01 23:18:18 +01:00
|
|
|
case "top":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of top command. Usage: top");
|
|
|
|
return;
|
2017-06-16 20:17:40 +02:00
|
|
|
}
|
2017-06-16 19:23:42 +02:00
|
|
|
|
2017-07-05 19:53:51 +02:00
|
|
|
post("Script Threads RAM Usage");
|
2017-06-16 19:23:42 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
let currRunningScripts = s.runningScripts;
|
2017-06-16 20:17:40 +02:00
|
|
|
//Iterate through scripts on current server
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < currRunningScripts.length; i++) {
|
|
|
|
let script = currRunningScripts[i];
|
2017-06-16 16:57:03 +02:00
|
|
|
|
2017-06-16 20:17:40 +02:00
|
|
|
//Calculate name padding
|
2019-02-05 07:45:04 +01:00
|
|
|
let numSpacesScript = 32 - script.filename.length; //26 -> width of name column
|
2017-07-05 19:53:51 +02:00
|
|
|
if (numSpacesScript < 0) {numSpacesScript = 0;}
|
2019-02-05 07:45:04 +01:00
|
|
|
let spacesScript = Array(numSpacesScript+1).join(" ");
|
2017-06-16 16:57:03 +02:00
|
|
|
|
2017-06-16 20:17:40 +02:00
|
|
|
//Calculate thread padding
|
2019-02-05 07:45:04 +01:00
|
|
|
let numSpacesThread = 16 - (script.threads + "").length; //16 -> width of thread column
|
|
|
|
let spacesThread = Array(numSpacesThread+1).join(" ");
|
2017-06-16 16:57:03 +02:00
|
|
|
|
2017-06-16 20:17:40 +02:00
|
|
|
//Calculate and transform RAM usage
|
2019-02-06 08:06:48 +01:00
|
|
|
let ramUsage = numeralWrapper.format(script.getRamUsage() * script.threads, '0.00') + " GB";
|
2017-06-16 16:57:03 +02:00
|
|
|
|
2017-06-16 20:17:40 +02:00
|
|
|
var entry = [script.filename, spacesScript, script.threads, spacesThread, ramUsage];
|
|
|
|
post(entry.join(""));
|
|
|
|
}
|
2016-11-17 23:25:40 +01:00
|
|
|
break;
|
2017-06-21 19:12:08 +02:00
|
|
|
case "unalias":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError('Incorrect usage of unalias name. Usage: unalias [alias]');
|
2017-06-21 19:12:08 +02:00
|
|
|
return;
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (removeAlias(commandArray[1])) {
|
|
|
|
post(`Removed alias ${commandArray[1]}`);
|
2017-06-21 19:12:08 +02:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError(`No such alias exists: ${commandArray[1]}`);
|
2017-06-21 19:12:08 +02:00
|
|
|
}
|
|
|
|
}
|
2018-08-29 05:24:38 +02:00
|
|
|
break;
|
2018-09-10 16:59:07 +02:00
|
|
|
/* eslint-disable no-case-declarations */
|
2018-08-29 05:24:38 +02:00
|
|
|
case "wget":
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 3) {
|
|
|
|
postError("Incorrect usage of wget command. Usage: wget [url] [target file]");
|
|
|
|
return;
|
2018-08-29 05:24:38 +02:00
|
|
|
}
|
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
let url = commandArray[1];
|
|
|
|
let target = comanndArray[2];
|
2018-09-08 03:53:11 +02:00
|
|
|
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
|
|
|
return post(`wget failed: Invalid target file. Target file must be script or text file`);
|
|
|
|
}
|
2018-08-29 05:24:38 +02:00
|
|
|
$.get(url, function(data) {
|
2018-09-08 03:53:11 +02:00
|
|
|
let res;
|
|
|
|
if (isScriptFilename(target)) {
|
2018-09-27 23:49:23 +02:00
|
|
|
res = s.writeToScriptFile(target, data);
|
2018-09-08 03:53:11 +02:00
|
|
|
} else {
|
2018-09-27 23:49:23 +02:00
|
|
|
res = s.writeToTextFile(target, data);
|
2018-09-08 03:53:11 +02:00
|
|
|
}
|
|
|
|
if (!res.success) {
|
|
|
|
return post("wget failed");
|
|
|
|
}
|
|
|
|
if (res.overwritten) {
|
|
|
|
return post(`wget successfully retrieved content and overwrote ${target}`);
|
|
|
|
}
|
|
|
|
return post(`wget successfully retrieved content to new file ${target}`);
|
2018-08-29 05:24:38 +02:00
|
|
|
}, 'text').fail(function(e) {
|
2019-02-05 07:45:04 +01:00
|
|
|
return postError("wget failed: " + JSON.stringify(e));
|
2018-08-29 05:24:38 +02:00
|
|
|
})
|
2017-06-21 19:12:08 +02:00
|
|
|
break;
|
2018-09-10 16:59:07 +02:00
|
|
|
/* eslint-enable no-case-declarations */
|
2016-10-20 20:26:38 +02:00
|
|
|
default:
|
2019-02-05 07:45:04 +01:00
|
|
|
postError(`Command ${commandArray[0]} not found`);
|
2016-10-20 20:26:38 +02:00
|
|
|
}
|
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-23 16:23:35 +02:00
|
|
|
connectToServer: function(ip) {
|
|
|
|
var serv = getServer(ip);
|
|
|
|
if (serv == null) {
|
|
|
|
post("Invalid server. Connection failed.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Player.getCurrentServer().isConnectedTo = false;
|
|
|
|
Player.currentServer = serv.ip;
|
|
|
|
Player.getCurrentServer().isConnectedTo = true;
|
|
|
|
post("Connected to " + serv.hostname);
|
|
|
|
if (Player.getCurrentServer().hostname == "darkweb") {
|
|
|
|
checkIfConnectedToDarkweb(); //Posts a 'help' message if connecting to dark web
|
|
|
|
}
|
2017-09-13 16:22:22 +02:00
|
|
|
Terminal.resetTerminalInput();
|
2017-06-23 16:23:35 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
executeFreeCommand: function(commandArray) {
|
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of free command. Usage: free");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
post("Total: " + numeralWrapper.format(Player.getCurrentServer().maxRam, '0.00') + " GB");
|
|
|
|
post("Used: " + numeralWrapper.format(Player.getCurrentServer().ramUsed, '0.00') + " GB");
|
|
|
|
post("Available: " + numeralWrapper.format(Player.getCurrentServer().maxRam - Player.getCurrentServer().ramUsed, '0.00') + " GB");
|
|
|
|
},
|
|
|
|
|
|
|
|
executeKillCommand: function(commandArray) {
|
|
|
|
if (commandArray.length < 2) {
|
|
|
|
postError("Incorrect usage of kill command. Usage: kill [scriptname] [arg1] [arg2]...");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const s = Player.getCurrentServer();
|
|
|
|
const scriptName = commandArray[1];
|
|
|
|
const args = [];
|
|
|
|
for (let i = 2; i < commandArray.length; ++i) {
|
|
|
|
args.push(commandArray[i]);
|
|
|
|
}
|
|
|
|
const runningScript = findRunningScript(scriptName, args, s);
|
|
|
|
if (runningScript == null) {
|
|
|
|
postError("No such script is running. Nothing to kill");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
killWorkerScript(runningScript, s.ip);
|
|
|
|
post(`Killing ${scriptName}. May take up to a few seconds for the scripts to die...`);
|
|
|
|
},
|
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
executeListCommand: function(commandArray) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1 && commandArray.length !== 4) {
|
|
|
|
postError("Incorrect usage of ls command. Usage: ls [| grep pattern]");
|
|
|
|
return;
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
// grep
|
2017-08-15 22:22:46 +02:00
|
|
|
var filter = null;
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length === 4) {
|
|
|
|
if (commandArray[1] === "|" && commandArray[2] === "grep") {
|
|
|
|
if (commandArray[3] !== " ") {
|
|
|
|
filter = commandArray[3];
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
postError("Incorrect usage of ls command. Usage: ls [| grep pattern]");
|
|
|
|
return;
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
//Display all programs and scripts
|
2017-07-25 03:06:40 +02:00
|
|
|
var allFiles = [];
|
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
//Get all of the programs and scripts on the machine into one temporary array
|
2019-02-05 07:45:04 +01:00
|
|
|
const s = Player.getCurrentServer();
|
|
|
|
for (const program of s.programs) {
|
2017-08-15 22:22:46 +02:00
|
|
|
if (filter) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (program.includes(filter)) {
|
|
|
|
allFiles.push(program);
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
allFiles.push(program);
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
2017-06-02 06:15:45 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
for (const script of s.scripts) {
|
2017-08-15 22:22:46 +02:00
|
|
|
if (filter) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (script.filename.includes(filter)) {
|
|
|
|
allFiles.push(script.filename);
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
allFiles.push(script.filename);
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
for (const msgOrLit of s.messages) {
|
2017-08-15 22:22:46 +02:00
|
|
|
if (filter) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (msgOrLit instanceof Message) {
|
|
|
|
if (msgOrLit.filename.includes(filter)) {
|
|
|
|
allFiles.push(msgOrLit.filename);
|
2017-08-18 19:20:51 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
} else if (msgOrLit.includes(filter)) {
|
|
|
|
allFiles.push(msgOrLit);
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (msgOrLit instanceof Message) {
|
|
|
|
allFiles.push(msgOrLit.filename);
|
2017-08-18 19:20:51 +02:00
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
allFiles.push(msgOrLit);
|
2017-08-18 19:20:51 +02:00
|
|
|
}
|
2017-08-15 22:22:46 +02:00
|
|
|
}
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
for (const txt of s.textFiles) {
|
2017-10-12 04:00:22 +02:00
|
|
|
if (filter) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (txt.fn.includes(filter)) {
|
|
|
|
allFiles.push(txt.fn);
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
allFiles.push(txt.fn);
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
for (const contract of s.contracts) {
|
2018-09-14 23:03:31 +02:00
|
|
|
if (filter) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (contract.fn.includes(filter)) {
|
|
|
|
allFiles.push(contract.fn);
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-05 07:45:04 +01:00
|
|
|
allFiles.push(contract.fn);
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
//Sort the files alphabetically then print each
|
|
|
|
allFiles.sort();
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
for (var i = 0; i < allFiles.length; i++) {
|
|
|
|
post(allFiles[i]);
|
|
|
|
}
|
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
executeMemCommand: function(commandArray) {
|
|
|
|
if (commandArray.length !== 2 && commandArray.length !== 4) {
|
|
|
|
postError("Incorrect usage of mem command. usage: mem [scriptname] [-t] [number threads]");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const s = Player.getCurrentServer();
|
|
|
|
const scriptName = commandArray[1];
|
|
|
|
let numThreads = 1;
|
|
|
|
if (commandArray.length === 4 && commandArray[2] === "-t") {
|
|
|
|
numThreads = Math.round(parseInt(commandArray[3]));
|
|
|
|
if (isNaN(numThreads) || numThreads < 1) {
|
|
|
|
postError("Invalid number of threads specified. Number of threads must be greater than 1");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < s.scripts.length; ++i) {
|
|
|
|
if (scriptName === s.scripts[i].filename) {
|
|
|
|
const scriptBaseRamUsage = s.scripts[i].ramUsage;
|
|
|
|
const ramUsage = scriptBaseRamUsage * numThreads;
|
|
|
|
|
|
|
|
post(`This script requires ${numeralWrapper.format(ramUsage, '0.00')} GB of RAM to run for ${numThreads} thread(s)`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
postError("No such script exists!");
|
|
|
|
},
|
|
|
|
|
|
|
|
executeNanoCommand: function(commandArray) {
|
|
|
|
if (commandArray.length !== 2) {
|
|
|
|
postError("Incorrect usage of nano command. Usage: nano [scriptname]");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const s = Player.getCurrentServer();
|
|
|
|
const filename = commandArray[1];
|
|
|
|
if (filename === ".fconf") {
|
|
|
|
let text = createFconf();
|
|
|
|
Engine.loadScriptEditorContent(filename, text);
|
|
|
|
return;
|
|
|
|
} else if (isScriptFilename(filename)) {
|
|
|
|
for (let i = 0; i < s.scripts.length; i++) {
|
|
|
|
if (filename == s.scripts[i].filename) {
|
|
|
|
Engine.loadScriptEditorContent(filename, s.scripts[i].code);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (filename.endsWith(".txt")) {
|
|
|
|
for (let i = 0; i < s.textFiles.length; ++i) {
|
|
|
|
if (filename === s.textFiles[i].fn) {
|
|
|
|
Engine.loadScriptEditorContent(filename, s.textFiles[i].text);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
postError("Invalid file. Only scripts (.script, .ns, .js), text files (.txt), or .fconf can be edited with nano"); return;
|
|
|
|
}
|
|
|
|
Engine.loadScriptEditorContent(filename); // Open a new file
|
|
|
|
},
|
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
executeScanCommand: function(commandArray) {
|
2019-02-05 07:45:04 +01:00
|
|
|
if (commandArray.length !== 1) {
|
|
|
|
postError("Incorrect usage of netstat/scan command. Usage: netstat/scan");
|
|
|
|
return;
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
|
|
|
//Displays available network connections using TCP
|
|
|
|
post("Hostname IP Root Access");
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < Player.getCurrentServer().serversOnNetwork.length; i++) {
|
2017-05-06 08:24:01 +02:00
|
|
|
//Add hostname
|
2019-02-05 07:45:04 +01:00
|
|
|
let entry = Player.getCurrentServer().getServerOnNetwork(i);
|
|
|
|
if (entry == null) { continue; }
|
2017-05-08 18:00:34 +02:00
|
|
|
entry = entry.hostname;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
//Calculate padding and add IP
|
2019-02-05 07:45:04 +01:00
|
|
|
let numSpaces = 21 - entry.length;
|
|
|
|
let spaces = Array(numSpaces+1).join(" ");
|
2017-05-06 08:24:01 +02:00
|
|
|
entry += spaces;
|
|
|
|
entry += Player.getCurrentServer().getServerOnNetwork(i).ip;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-05-06 08:24:01 +02:00
|
|
|
//Calculate padding and add root access info
|
2019-02-05 07:45:04 +01:00
|
|
|
let hasRoot;
|
2017-05-06 08:24:01 +02:00
|
|
|
if (Player.getCurrentServer().getServerOnNetwork(i).hasAdminRights) {
|
|
|
|
hasRoot = 'Y';
|
|
|
|
} else {
|
|
|
|
hasRoot = 'N';
|
|
|
|
}
|
|
|
|
numSpaces = 21 - Player.getCurrentServer().getServerOnNetwork(i).ip.length;
|
|
|
|
spaces = Array(numSpaces+1).join(" ");
|
|
|
|
entry += spaces;
|
|
|
|
entry += hasRoot;
|
|
|
|
post(entry);
|
|
|
|
}
|
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-09-19 20:38:03 +02:00
|
|
|
executeScanAnalyzeCommand: function(depth=1, all=false) {
|
2017-05-24 19:07:33 +02:00
|
|
|
//TODO Using array as stack for now, can make more efficient
|
2017-05-24 23:35:24 +02:00
|
|
|
post("~~~~~~~~~~ Beginning scan-analyze ~~~~~~~~~~");
|
|
|
|
post(" ");
|
2019-02-06 08:06:48 +01:00
|
|
|
|
|
|
|
// Map of all servers to keep track of which have been visited
|
|
|
|
var visited = {};
|
|
|
|
for (const ip in AllServers) {
|
|
|
|
visited[ip] = 0;
|
|
|
|
}
|
2017-09-19 20:38:03 +02:00
|
|
|
|
2017-05-24 19:07:33 +02:00
|
|
|
var stack = [];
|
|
|
|
var depthQueue = [0];
|
|
|
|
var currServ = Player.getCurrentServer();
|
|
|
|
stack.push(currServ);
|
|
|
|
while(stack.length != 0) {
|
|
|
|
var s = stack.pop();
|
|
|
|
var d = depthQueue.pop();
|
2017-09-19 20:38:03 +02:00
|
|
|
if (!all && s.purchasedByPlayer && s.hostname != "home") {
|
|
|
|
continue; //Purchased server
|
|
|
|
} else if (visited[s.ip] || d > depth) {
|
|
|
|
continue; //Already visited or out-of-depth
|
2017-05-24 19:07:33 +02:00
|
|
|
} else {
|
|
|
|
visited[s.ip] = 1;
|
|
|
|
}
|
|
|
|
for (var i = s.serversOnNetwork.length-1; i >= 0; --i) {
|
|
|
|
stack.push(s.getServerOnNetwork(i));
|
|
|
|
depthQueue.push(d+1);
|
|
|
|
}
|
|
|
|
if (d == 0) {continue;} //Don't print current server
|
2017-05-24 23:35:24 +02:00
|
|
|
var titleDashes = Array((d-1) * 4 + 1).join("-");
|
2018-06-02 01:31:34 +02:00
|
|
|
if (Player.hasProgram(Programs.AutoLink.name)) {
|
2017-06-23 16:23:35 +02:00
|
|
|
post("<strong>" + titleDashes + "> <a class='scan-analyze-link'>" + s.hostname + "</a></strong>", false);
|
|
|
|
} else {
|
|
|
|
post("<strong>" + titleDashes + ">" + s.hostname + "</strong>");
|
|
|
|
}
|
|
|
|
|
2017-05-24 23:35:24 +02:00
|
|
|
var dashes = titleDashes + "--";
|
|
|
|
//var dashes = Array(d * 2 + 1).join("-");
|
|
|
|
var c = "NO";
|
|
|
|
if (s.hasAdminRights) {c = "YES";}
|
|
|
|
post(dashes + "Root Access: " + c + ", Required hacking skill: " + s.requiredHackingSkill);
|
|
|
|
post(dashes + "Number of open ports required to NUKE: " + s.numOpenPortsRequired);
|
|
|
|
post(dashes + "RAM: " + s.maxRam);
|
2017-05-23 19:36:35 +02:00
|
|
|
post(" ");
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-23 16:23:35 +02:00
|
|
|
var links = document.getElementsByClassName("scan-analyze-link");
|
2019-02-05 07:45:04 +01:00
|
|
|
for (let i = 0; i < links.length; ++i) {
|
2017-06-23 16:23:35 +02:00
|
|
|
(function() {
|
|
|
|
var hostname = links[i].innerHTML.toString();
|
|
|
|
links[i].onclick = function() {
|
2017-09-15 16:06:59 +02:00
|
|
|
if (Terminal.analyzeFlag || Terminal.hackFlag) {return;}
|
2017-06-23 16:23:35 +02:00
|
|
|
Terminal.connectToServer(hostname);
|
|
|
|
}
|
|
|
|
}());//Immediate invocation
|
|
|
|
}
|
2017-05-23 19:36:35 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-05 07:45:04 +01:00
|
|
|
executeScpCommand(commandArray) {
|
|
|
|
if (commandArray.length !== 3) {
|
|
|
|
postError("Incorrect usage of scp command. Usage: scp [file] [destination hostname/ip]");
|
|
|
|
return;
|
2017-05-06 08:24:01 +02:00
|
|
|
}
|
2019-02-05 07:45:04 +01:00
|
|
|
const scriptname = commandArray[1];
|
|
|
|
if (!scriptname.endsWith(".lit") && !isScriptFilename(scriptname) && !scriptname.endsWith(".txt")) {
|
2019-02-12 10:14:38 +01:00
|
|
|
postError("scp only works for scripts, text files (.txt), and literature files (.lit)");
|
2019-02-05 07:45:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
const destServer = getServer(commandArray[2]);
|
|
|
|
if (destServer == null) {
|
|
|
|
postError(`Invalid destination. ${commandArray[2]} not found`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const ip = destServer.ip;
|
|
|
|
const currServ = Player.getCurrentServer();
|
|
|
|
|
|
|
|
//Scp for lit files
|
|
|
|
if (scriptname.endsWith(".lit")) {
|
|
|
|
var found = false;
|
|
|
|
for (var i = 0; i < currServ.messages.length; ++i) {
|
|
|
|
if (!(currServ.messages[i] instanceof Message) && currServ.messages[i] == scriptname) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) { return postError("No such file exists!"); }
|
|
|
|
|
|
|
|
for (var i = 0; i < destServer.messages.length; ++i) {
|
|
|
|
if (destServer.messages[i] === scriptname) {
|
|
|
|
post(scriptname + " copied over to " + destServer.hostname);
|
|
|
|
return; //Already exists
|
|
|
|
}
|
|
|
|
}
|
|
|
|
destServer.messages.push(scriptname);
|
|
|
|
return post(scriptname + " copied over to " + destServer.hostname);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Scp for txt files
|
|
|
|
if (scriptname.endsWith(".txt")) {
|
|
|
|
var found = false, txtFile;
|
|
|
|
for (var i = 0; i < currServ.textFiles.length; ++i) {
|
|
|
|
if (currServ.textFiles[i].fn === scriptname) {
|
|
|
|
found = true;
|
|
|
|
txtFile = currServ.textFiles[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) { return postError("No such file exists!"); }
|
|
|
|
|
|
|
|
let tRes = destServer.writeToTextFile(txtFile.fn, txtFile.text);
|
|
|
|
if (!tRes.success) {
|
|
|
|
postError("scp failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (tRes.overwritten) {
|
|
|
|
post(`WARNING: ${scriptname} already exists on ${destServer.hostname} and will be overwriten`);
|
|
|
|
post(`${scriptname} overwritten on ${destServer.hostname}`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
post(`${scriptname} copied over to ${destServer.hostname}`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current script
|
|
|
|
let sourceScript = null;
|
|
|
|
for (let i = 0; i < currServ.scripts.length; ++i) {
|
|
|
|
if (scriptname == currServ.scripts[i].filename) {
|
|
|
|
sourceScript = currServ.scripts[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sourceScript == null) {
|
|
|
|
postError("scp() failed. No such script exists");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let sRes = destServer.writeToScriptFile(scriptname, sourceScript.code);
|
|
|
|
if (!sRes.success) {
|
|
|
|
postError(`scp failed`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (sRes.overwritten) {
|
|
|
|
post(`WARNING: ${scriptname} already exists on ${destServer.hostname} and will be overwritten`);
|
|
|
|
post(`${scriptname} overwritten on ${destServer.hostname}`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
post(`${scriptname} copied over to ${destServer.hostname}`);
|
2017-05-06 08:24:01 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-10-27 20:26:00 +02:00
|
|
|
//First called when the "run [program]" command is called. Checks to see if you
|
|
|
|
//have the executable and, if you do, calls the executeProgram() function
|
2019-02-20 09:42:27 +01:00
|
|
|
runProgram: function(commandArray) {
|
|
|
|
if (commandArray.length < 2) { return; }
|
|
|
|
|
|
|
|
// Check if you have the program on your computer. If you do, execute it, otherwise
|
|
|
|
// display an error message
|
|
|
|
const programName = commandArray[1];
|
|
|
|
|
|
|
|
if (Player.hasProgram(programName)) {
|
|
|
|
Terminal.executeProgram(commandArray);
|
2017-06-23 16:23:35 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-02-16 19:52:11 +01:00
|
|
|
post("ERROR: No such executable on home computer (Only programs that exist on your home computer can be run)");
|
2016-10-27 20:26:00 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-10-27 20:26:00 +02:00
|
|
|
//Contains the implementations of all possible programs
|
2019-02-20 09:42:27 +01:00
|
|
|
executeProgram: function(commandArray) {
|
|
|
|
if (commandArray.length < 2) { return; }
|
|
|
|
|
2017-04-19 23:40:26 +02:00
|
|
|
var s = Player.getCurrentServer();
|
2019-02-20 09:42:27 +01:00
|
|
|
const programName = commandArray[1];
|
|
|
|
const splitArgs = commandArray.slice(1);
|
2018-01-27 07:52:39 +01:00
|
|
|
|
2018-07-31 06:18:38 +02:00
|
|
|
// TODO: refactor this/these out of Terminal. This logic could reside closer to the Programs themselves.
|
|
|
|
/**
|
|
|
|
* @typedef {function (server=, args=)} ProgramHandler
|
|
|
|
* @param {Server} server The current server the program is being executed against
|
|
|
|
* @param {string[]} args The command line arguments passed in to the program
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
/**
|
2018-08-29 21:06:21 +02:00
|
|
|
* @type {Object.<string, ProgramHandler}
|
2018-07-31 06:18:38 +02:00
|
|
|
*/
|
|
|
|
const programHandlers = {};
|
|
|
|
programHandlers[Programs.NukeProgram.name] = (server) => {
|
|
|
|
if (server.hasAdminRights) {
|
|
|
|
post("You already have root access to this computer. There is no reason to run NUKE.exe");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server.openPortCount >= Player.getCurrentServer().numOpenPortsRequired) {
|
|
|
|
server.hasAdminRights = true;
|
|
|
|
post("NUKE successful! Gained root access to " + Player.getCurrentServer().hostname);
|
|
|
|
// TODO: Make this take time rather than be instant
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
post("NUKE unsuccessful. Not enough ports have been opened");
|
|
|
|
};
|
|
|
|
programHandlers[Programs.BruteSSHProgram.name] = (server) => {
|
|
|
|
if (server.sshPortOpen) {
|
|
|
|
post("SSH Port (22) is already open!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.sshPortOpen = true;
|
|
|
|
post("Opened SSH Port(22)!")
|
|
|
|
server.openPortCount++;
|
|
|
|
};
|
|
|
|
programHandlers[Programs.FTPCrackProgram.name] = (server) => {
|
|
|
|
if (server.ftpPortOpen) {
|
|
|
|
post("FTP Port (21) is already open!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.ftpPortOpen = true;
|
|
|
|
post("Opened FTP Port (21)!");
|
|
|
|
server.openPortCount++;
|
|
|
|
};
|
|
|
|
programHandlers[Programs.RelaySMTPProgram.name] = (server) => {
|
|
|
|
if (server.smtpPortOpen) {
|
|
|
|
post("SMTP Port (25) is already open!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.smtpPortOpen = true;
|
|
|
|
post("Opened SMTP Port (25)!");
|
|
|
|
server.openPortCount++;
|
|
|
|
};
|
|
|
|
programHandlers[Programs.HTTPWormProgram.name] = (server) => {
|
2018-08-07 01:11:14 +02:00
|
|
|
if (server.httpPortOpen) {
|
2018-07-31 06:18:38 +02:00
|
|
|
post("HTTP Port (80) is already open!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.httpPortOpen = true;
|
|
|
|
post("Opened HTTP Port (80)!");
|
|
|
|
server.openPortCount++;
|
|
|
|
};
|
|
|
|
programHandlers[Programs.SQLInjectProgram.name] = (server) => {
|
|
|
|
if (server.sqlPortOpen) {
|
|
|
|
post("SQL Port (1433) is already open!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.sqlPortOpen = true;
|
|
|
|
post("Opened SQL Port (1433)!");
|
|
|
|
server.openPortCount++;
|
|
|
|
};
|
|
|
|
programHandlers[Programs.ServerProfiler.name] = (server, args) => {
|
|
|
|
if (args.length !== 2) {
|
|
|
|
post("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const targetServer = getServer(args[1]);
|
|
|
|
if (targetServer == null) {
|
|
|
|
post("Invalid server IP/hostname");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
post(targetServer.hostname + ":");
|
|
|
|
post("Server base security level: " + targetServer.baseDifficulty);
|
|
|
|
post("Server current security level: " + targetServer.hackDifficulty);
|
|
|
|
post("Server growth rate: " + targetServer.serverGrowth);
|
2018-09-14 23:03:31 +02:00
|
|
|
post("Netscript hack() execution time: " + numeralWrapper.format(calculateHackingTime(targetServer), '0.0') + "s");
|
|
|
|
post("Netscript grow() execution time: " + numeralWrapper.format(calculateGrowTime(targetServer), '0.0') + "s");
|
|
|
|
post("Netscript weaken() execution time: " + numeralWrapper.format(calculateWeakenTime(targetServer), '0.0') + "s");
|
2018-07-31 06:18:38 +02:00
|
|
|
};
|
|
|
|
programHandlers[Programs.AutoLink.name] = () => {
|
|
|
|
post("This executable cannot be run.");
|
|
|
|
post("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'.");
|
|
|
|
post("When using scan-analyze, click on a server's hostname to connect to it.");
|
|
|
|
};
|
|
|
|
programHandlers[Programs.DeepscanV1.name] = () => {
|
|
|
|
post("This executable cannot be run.");
|
|
|
|
post("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5.");
|
|
|
|
};
|
|
|
|
programHandlers[Programs.DeepscanV2.name] = () => {
|
|
|
|
post("This executable cannot be run.");
|
|
|
|
post("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
|
|
|
|
};
|
|
|
|
programHandlers[Programs.Flight.name] = () => {
|
|
|
|
const fulfilled = Player.augmentations.length >= 30 &&
|
|
|
|
Player.money.gt(1e11) &&
|
|
|
|
((Player.hacking_skill >= 2500)||
|
|
|
|
(Player.strength >= 1500 &&
|
|
|
|
Player.defense >= 1500 &&
|
|
|
|
Player.dexterity >= 1500 &&
|
|
|
|
Player.agility >= 1500));
|
|
|
|
if(!fulfilled) {
|
|
|
|
post("Augmentations: " + Player.augmentations.length + " / 30");
|
|
|
|
|
2018-09-12 17:53:08 +02:00
|
|
|
post("Money: " + numeralWrapper.format(Player.money.toNumber(), '($0.000a)') + " / " + numeralWrapper.format(1e11, '($0.000a)'));
|
2018-07-31 06:18:38 +02:00
|
|
|
post("One path below must be fulfilled...");
|
|
|
|
post("----------HACKING PATH----------");
|
|
|
|
post("Hacking skill: " + Player.hacking_skill + " / 2500");
|
|
|
|
post("----------COMBAT PATH----------");
|
|
|
|
post("Strength: " + Player.strength + " / 1500");
|
|
|
|
post("Defense: " + Player.defense + " / 1500");
|
|
|
|
post("Dexterity: " + Player.dexterity + " / 1500");
|
|
|
|
post("Agility: " + Player.agility + " / 1500");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
post("We will contact you.");
|
|
|
|
post("-- Daedalus --");
|
|
|
|
};
|
|
|
|
programHandlers[Programs.BitFlume.name] = () => {
|
|
|
|
const yesBtn = yesNoBoxGetYesButton();
|
|
|
|
const noBtn = yesNoBoxGetNoButton();
|
|
|
|
yesBtn.innerHTML = "Travel to BitNode Nexus";
|
|
|
|
noBtn.innerHTML = "Cancel";
|
|
|
|
yesBtn.addEventListener("click", function() {
|
|
|
|
hackWorldDaemon(Player.bitNodeN, true);
|
|
|
|
return yesNoBoxClose();
|
|
|
|
});
|
|
|
|
noBtn.addEventListener("click", function() {
|
|
|
|
return yesNoBoxClose();
|
|
|
|
});
|
|
|
|
yesNoBoxCreate("WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.<br><br>" +
|
|
|
|
"Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode " +
|
|
|
|
"and select a new one.");
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!programHandlers.hasOwnProperty(programName)){
|
|
|
|
post("Invalid executable. Cannot be run");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
programHandlers[programName](s, splitArgs);
|
2016-10-24 23:16:51 +02:00
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2019-02-06 03:32:15 +01:00
|
|
|
runScript: function(commandArray) {
|
|
|
|
if (commandArray.length < 2) {
|
|
|
|
dialogBoxCreate(`Bug encountered with Terminal.runScript(). Command array has a length of less than 2: ${commandArray}`);
|
|
|
|
return;
|
2017-06-11 03:46:02 +02:00
|
|
|
}
|
2019-02-06 03:32:15 +01:00
|
|
|
|
|
|
|
const server = Player.getCurrentServer();
|
|
|
|
|
|
|
|
let numThreads = 1;
|
|
|
|
const args = [];
|
|
|
|
const scriptName = commandArray[1];
|
|
|
|
|
|
|
|
if (commandArray.length > 2) {
|
|
|
|
if (commandArray.length >= 4 && commandArray[2] == "-t") {
|
|
|
|
numThreads = Math.round(parseFloat(commandArray[3]));
|
2017-06-17 04:53:57 +02:00
|
|
|
if (isNaN(numThreads) || numThreads < 1) {
|
2019-02-06 03:32:15 +01:00
|
|
|
postError("Invalid number of threads specified. Number of threads must be greater than 0");
|
2017-06-17 04:53:57 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-02-06 03:32:15 +01:00
|
|
|
for (let i = 4; i < commandArray.length; ++i) {
|
|
|
|
args.push(commandArray[i]);
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-02-06 03:32:15 +01:00
|
|
|
for (let i = 2; i < commandArray.length; ++i) {
|
|
|
|
args.push(commandArray[i])
|
2017-06-17 04:53:57 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-11 22:28:20 +02:00
|
|
|
//Check if this script is already running
|
2017-06-17 04:53:57 +02:00
|
|
|
if (findRunningScript(scriptName, args, server) != null) {
|
|
|
|
post("ERROR: This script is already running. Cannot run multiple instances");
|
|
|
|
return;
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-11-28 23:02:06 +01:00
|
|
|
//Check if the script exists and if it does run it
|
2016-12-14 21:29:40 +01:00
|
|
|
for (var i = 0; i < server.scripts.length; i++) {
|
|
|
|
if (server.scripts[i].filename == scriptName) {
|
|
|
|
//Check for admin rights and that there is enough RAM availble to run
|
2017-06-11 03:46:02 +02:00
|
|
|
var script = server.scripts[i];
|
2018-07-03 05:35:12 +02:00
|
|
|
var ramUsage = script.ramUsage * numThreads;
|
2016-12-14 21:29:40 +01:00
|
|
|
var ramAvailable = server.maxRam - server.ramUsed;
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2016-12-14 21:29:40 +01:00
|
|
|
if (server.hasAdminRights == false) {
|
2016-11-28 23:02:06 +01:00
|
|
|
post("Need root access to run script");
|
2016-12-14 00:52:32 +01:00
|
|
|
return;
|
2016-12-14 21:29:40 +01:00
|
|
|
} else if (ramUsage > ramAvailable){
|
2017-06-11 03:46:02 +02:00
|
|
|
post("This machine does not have enough RAM to run this script with " +
|
2017-06-17 04:53:57 +02:00
|
|
|
numThreads + " threads. Script requires " + ramUsage + "GB of RAM");
|
2016-12-14 21:29:40 +01:00
|
|
|
return;
|
2017-06-17 04:53:57 +02:00
|
|
|
} else {
|
2016-12-14 21:29:40 +01:00
|
|
|
//Able to run script
|
2018-07-05 20:12:20 +02:00
|
|
|
post("Running script with " + numThreads + " thread(s) and args: " + arrayToString(args) + ".");
|
2017-06-17 04:53:57 +02:00
|
|
|
post("May take a few seconds to start up the process...");
|
|
|
|
var runningScriptObj = new RunningScript(script, args);
|
|
|
|
runningScriptObj.threads = numThreads;
|
|
|
|
server.runningScripts.push(runningScriptObj);
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2017-06-17 04:53:57 +02:00
|
|
|
addWorkerScript(runningScriptObj, server);
|
2016-11-29 23:56:05 +01:00
|
|
|
return;
|
2016-11-28 23:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 03:06:40 +02:00
|
|
|
|
2018-09-08 04:21:23 +02:00
|
|
|
|
2016-11-28 23:02:06 +01:00
|
|
|
post("ERROR: No such script");
|
2018-09-14 23:03:31 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
runContract: async function(contractName) {
|
|
|
|
// There's already an opened contract
|
|
|
|
if (Terminal.contractOpen) {
|
|
|
|
return post("ERROR: There's already a Coding Contract in Progress");
|
|
|
|
}
|
|
|
|
|
|
|
|
const serv = Player.getCurrentServer();
|
|
|
|
const contract = serv.getContract(contractName);
|
|
|
|
if (contract == null) {
|
|
|
|
return post("ERROR: No such contract");
|
|
|
|
}
|
2018-09-23 02:25:48 +02:00
|
|
|
|
|
|
|
Terminal.contractOpen = true;
|
2018-09-14 23:03:31 +02:00
|
|
|
const res = await contract.prompt();
|
|
|
|
|
|
|
|
switch (res) {
|
|
|
|
case CodingContractResult.Success:
|
|
|
|
var reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());
|
|
|
|
post(`Contract SUCCESS - ${reward}`);
|
|
|
|
serv.removeContract(contract);
|
|
|
|
break;
|
|
|
|
case CodingContractResult.Failure:
|
|
|
|
++contract.tries;
|
|
|
|
if (contract.tries >= contract.getMaxNumTries()) {
|
2018-09-23 02:25:48 +02:00
|
|
|
post("Contract <p style='color:red;display:inline'>FAILED</p> - Contract is now self-destructing");
|
2018-09-14 23:03:31 +02:00
|
|
|
serv.removeContract(contract);
|
2018-09-23 02:25:48 +02:00
|
|
|
} else {
|
|
|
|
post(`Contract <p style='color:red;display:inline'>FAILED</p> - ${contract.getMaxNumTries() - contract.tries} tries remaining`);
|
2018-09-14 23:03:31 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CodingContractResult.Cancelled:
|
|
|
|
default:
|
|
|
|
post("Contract cancelled");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Terminal.contractOpen = false;
|
|
|
|
},
|
2017-07-25 03:06:40 +02:00
|
|
|
};
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2018-07-18 20:34:18 +02:00
|
|
|
export {postNetburnerText, Terminal};
|