import { evaluateDirectoryPath, evaluateFilePath, getFirstParentDirectory, isInRootDirectory, isValidDirectoryPath, isValidFilename, removeLeadingSlash, removeTrailingSlash } from "./Terminal/DirectoryHelpers"; import { determineAllPossibilitiesForTabCompletion } from "./Terminal/determineAllPossibilitiesForTabCompletion"; import { TerminalHelpText, HelpTexts } from "./Terminal/HelpText"; import { tabCompletion } from "./Terminal/tabCompletion"; import { Aliases, GlobalAliases, parseAliasDeclaration, printAliases, removeAlias, substituteAliases } from "./Alias"; import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; import {CodingContract, CodingContractResult, CodingContractRewardType} from "./CodingContracts"; import {CONSTANTS} from "./Constants"; import { Programs } from "./Programs/Programs"; import { executeDarkwebTerminalCommand, checkIfConnectedToDarkweb } from "./DarkWeb/DarkWeb"; import { DarkWebItems } from "./DarkWeb/DarkWebItems"; import {Engine} from "./engine"; import { parseFconfSettings, createFconf } from "./Fconf/Fconf"; import { FconfSettings } from "./Fconf/FconfSettings"; import {calculateHackingChance, calculateHackingExpGain, calculatePercentMoneyHacked, calculateHackingTime, calculateGrowTime, calculateWeakenTime} from "./Hacking"; import { HacknetServer } from "./Hacknet/HacknetServer"; import {iTutorialNextStep, iTutorialSteps, ITutorial} from "./InteractiveTutorial"; import {showLiterature} from "./Literature"; import { Message } from "./Message/Message"; import { showMessage } from "./Message/MessageHelpers"; import {killWorkerScript, addWorkerScript} from "./NetscriptWorker"; import {Player} from "./Player"; import {hackWorldDaemon} from "./RedPill"; import { RunningScript } from "./Script/RunningScript"; import { findRunningScript } from "./Script/ScriptHelpers"; import { isScriptFilename } from "./Script/ScriptHelpersTS"; import { AllServers } from "./Server/AllServers"; import { Server } from "./Server/Server"; import { GetServerByHostname, getServer, getServerOnNetwork } from "./Server/ServerHelpers"; import {Settings} from "./Settings/Settings"; import { SpecialServerIps, SpecialServerNames } from "./Server/SpecialServerIps"; import {getTextFile} from "./TextFile"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; import {Page, routing} from "./ui/navigationTracking"; import {numeralWrapper} from "./ui/numeralFormat"; import {KEY} from "../utils/helpers/keyCodes"; import {addOffset} from "../utils/helpers/addOffset"; import {isString} from "../utils/helpers/isString"; import {arrayToString} from "../utils/helpers/arrayToString"; import {getTimestamp} from "../utils/helpers/getTimestamp"; import {logBoxCreate} from "../utils/LogBox"; import {yesNoBoxCreate, yesNoBoxGetYesButton, yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox"; import { post, postContent, postError, hackProgressBarPost, hackProgressPost } from "./ui/postToTerminal"; import autosize from 'autosize'; import * as JSZip from 'jszip'; import * as FileSaver from 'file-saver'; function postNetburnerText() { post("Bitburner v" + CONSTANTS.Version); } // 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)); } // Defines key commands in terminal $(document).keydown(function(event) { //Terminal if (routing.isOn(Page.Terminal)) { var terminalInput = document.getElementById("terminal-input-text-box"); if (terminalInput != null && !event.ctrlKey && !event.shiftKey && !Terminal.contractOpen) {terminalInput.focus();} if (event.keyCode === KEY.ENTER) { event.preventDefault(); //Prevent newline from being entered in Script Editor const command = terminalInput.value; const dir = Terminal.currDir; post( "[" + (FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") + Player.getCurrentServer().hostname + ` ~${dir}]> ${command}` ); if (command.length > 0) { Terminal.resetTerminalInput(); //Clear input first Terminal.executeCommands(command); } } 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 } } 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 if (terminalInput == null) {return;} var i = Terminal.commandHistoryIndex; var len = Terminal.commandHistory.length; if (len == 0) {return;} if (i < 0 || i > len) { Terminal.commandHistoryIndex = len; } if (i != 0) { --Terminal.commandHistoryIndex; } var prevCommand = Terminal.commandHistory[Terminal.commandHistoryIndex]; terminalInput.value = prevCommand; setTimeoutRef(function(){terminalInput.selectionStart = terminalInput.selectionEnd = 10000; }, 0); } 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 if (terminalInput == null) {return;} var i = Terminal.commandHistoryIndex; var len = Terminal.commandHistory.length; if (len == 0) {return;} if (i < 0 || i > len) { Terminal.commandHistoryIndex = len; } //Latest command, put nothing if (i == len || i == len-1) { Terminal.commandHistoryIndex = len; terminalInput.value = ""; } else { ++Terminal.commandHistoryIndex; var prevCommand = Terminal.commandHistory[Terminal.commandHistoryIndex]; terminalInput.value = prevCommand; } } if (event.keyCode === KEY.TAB) { event.preventDefault(); //Autocomplete if (terminalInput == null) {return;} var input = terminalInput.value; if (input == "") {return;} const semiColonIndex = input.lastIndexOf(";"); if(semiColonIndex !== -1) { input = input.slice(semiColonIndex + 1); } input = input.trim(); input = input.replace(/\s\s+/g, ' '); var commandArray = input.split(" "); var index = commandArray.length - 2; if (index < -1) {index = 0;} var allPos = determineAllPossibilitiesForTabCompletion(Player, input, index); if (allPos.length == 0) {return;} var arg = ""; var command = ""; if (commandArray.length == 0) {return;} if (commandArray.length == 1) {command = commandArray[0];} else if (commandArray.length == 2) { command = commandArray[0]; arg = commandArray[1]; } else if (commandArray.length == 3) { command = commandArray[0] + " " + commandArray[1]; arg = commandArray[2]; } else { arg = commandArray.pop(); command = commandArray.join(" "); } tabCompletion(command, arg, allPos); terminalInput.focus(); } //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 } } }); //Keep terminal in focus let terminalCtrlPressed = false, shiftKeyPressed = false; $(document).ready(function() { if (routing.isOn(Page.Terminal)) { $('.terminal-input').focus(); } }); $(document).keydown(function(e) { if (routing.isOn(Page.Terminal)) { if (e.which == KEY.CTRL) { terminalCtrlPressed = true; } else if (e.shiftKey) { shiftKeyPressed = true; } else if (terminalCtrlPressed || shiftKeyPressed || Terminal.contractOpen) { //Don't focus } else { var inputTextBox = document.getElementById("terminal-input-text-box"); if (inputTextBox != null) {inputTextBox.focus();} terminalCtrlPressed = false; shiftKeyPressed = false; } } }); $(document).keyup(function(e) { if (routing.isOn(Page.Terminal)) { if (e.which == KEY.CTRL) { terminalCtrlPressed = false; } if (e.shiftKey) { shiftKeyPressed = false; } } }); let Terminal = { // Flags to determine whether the player is currently running a hack or an analyze hackFlag: false, analyzeFlag: false, actionStarted: false, actionTime: 0, commandHistory: [], commandHistoryIndex: 0, // True if a Coding Contract prompt is opened contractOpen: false, // Full Path of current directory // Excludes the trailing forward slash currDir: "/", resetTerminalInput: function() { const dir = Terminal.currDir; if (FconfSettings.WRAP_INPUT) { document.getElementById("terminal-input-td").innerHTML = `
[${Player.getCurrentServer().hostname} ~${dir}]$
` + '