diff --git a/markdown/bitburner.ns.read.md b/markdown/bitburner.ns.read.md index 1fc6f505d..a0251493f 100644 --- a/markdown/bitburner.ns.read.md +++ b/markdown/bitburner.ns.read.md @@ -28,7 +28,7 @@ Data in the specified text file. RAM cost: 0 GB -This function is used to read data from a text file (.txt, .json) or script (.js, .jsx, .ts, .tsx, .script). +This function is used to read data from a text file (.txt, .json) or script (.js, .jsx, .ts, .tsx). This function will return the data in the specified file. If the file does not exist, an empty string will be returned. diff --git a/markdown/bitburner.ns.wget.md b/markdown/bitburner.ns.wget.md index ef1349b15..d5bb3e35a 100644 --- a/markdown/bitburner.ns.wget.md +++ b/markdown/bitburner.ns.wget.md @@ -30,7 +30,7 @@ True if the data was successfully retrieved from the URL, false otherwise. RAM cost: 0 GB -Retrieves data from a URL and downloads it to a file on the specified server. The data can only be downloaded to a script (.js, .jsx, .ts, .tsx, .script) or a text file (.txt, .json). If the file already exists, it will be overwritten by this command. Note that it will not be possible to download data from many websites because they do not allow cross-origin resource sharing (CORS). +Retrieves data from a URL and downloads it to a file on the specified server. The data can only be downloaded to a script (.js, .jsx, .ts, .tsx) or a text file (.txt, .json). If the file already exists, it will be overwritten by this command. Note that it will not be possible to download data from many websites because they do not allow cross-origin resource sharing (CORS). IMPORTANT: This is an asynchronous function that returns a Promise. The Promise’s resolved value will be a boolean indicating whether or not the data was successfully retrieved from the URL. Because the function is async and returns a Promise, it is recommended you use wget in NetscriptJS (Netscript 2.0). diff --git a/markdown/bitburner.ns.write.md b/markdown/bitburner.ns.write.md index 7b1233e97..97f752484 100644 --- a/markdown/bitburner.ns.write.md +++ b/markdown/bitburner.ns.write.md @@ -28,7 +28,7 @@ void RAM cost: 0 GB -This function can be used to write data to a text file (.txt, .json) or a script (.js, .jsx, .ts, .tsx, .script). +This function can be used to write data to a text file (.txt, .json) or a script (.js, .jsx, .ts, .tsx). This function will write data to that file. If the specified file does not exist, then it will be created. The third argument mode defines how the data will be written to the file. If mode is set to “w”, then the data is written in “write” mode which means that it will overwrite all existing data on the file. If mode is set to any other value then the data will be written in “append” mode which means that the data will be added at the end of the file. diff --git a/package-lock.json b/package-lock.json index ebc87d69a..53acdcf23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,6 @@ "clsx": "^1.2.1", "convert-source-map": "^2.0.0", "date-fns": "^2.30.0", - "escodegen": "^2.1.0", "jszip": "^3.10.1", "material-ui-color": "^1.2.0", "material-ui-popup-state": "^1.9.3", @@ -62,7 +61,6 @@ "@types/babel__standalone": "^7.1.7", "@types/bcryptjs": "^2.4.4", "@types/convert-source-map": "^2.0.3", - "@types/escodegen": "^0.0.7", "@types/file-saver": "^2.0.5", "@types/jest": "^29.5.5", "@types/jquery": "^3.5.22", @@ -4915,12 +4913,6 @@ "@types/ms": "*" } }, - "node_modules/@types/escodegen": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz", - "integrity": "sha512-46oENdSRNEJXCNrPJoC3vRolZJpfeEm7yvATkd2bCncKFG0PUEyfBCaoacfpcXH4Y5RRuqdVj3J7TI+wwn2SbQ==", - "dev": true - }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -8594,6 +8586,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", @@ -8614,6 +8607,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "optional": true, "engines": { "node": ">=0.10.0" @@ -8963,6 +8957,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -8999,6 +8994,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -9007,6 +9003,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "engines": { "node": ">=0.10.0" } diff --git a/package.json b/package.json index 61e26e056..a91886867 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "clsx": "^1.2.1", "convert-source-map": "^2.0.0", "date-fns": "^2.30.0", - "escodegen": "^2.1.0", "jszip": "^3.10.1", "material-ui-color": "^1.2.0", "material-ui-popup-state": "^1.9.3", @@ -63,7 +62,6 @@ "@types/babel__standalone": "^7.1.7", "@types/bcryptjs": "^2.4.4", "@types/convert-source-map": "^2.0.3", - "@types/escodegen": "^0.0.7", "@types/file-saver": "^2.0.5", "@types/jest": "^29.5.5", "@types/jquery": "^3.5.22", diff --git a/src/Documentation/doc/basic/scripts.md b/src/Documentation/doc/basic/scripts.md index f7900a0ac..66ffdd742 100644 --- a/src/Documentation/doc/basic/scripts.md +++ b/src/Documentation/doc/basic/scripts.md @@ -114,7 +114,7 @@ Check how much [RAM](ram.md) a script requires to run with "n" threads **nano [script]** Create/Edit a script. -The name of a script must end with a script extension (.js, .jsx, .ts, .tsx, .script). You can also create a text file with a text extension (.txt, .json). +The name of a script must end with a script extension (.js, .jsx, .ts, .tsx). You can also create a text file with a text extension (.txt, .json). **ps** diff --git a/src/Documentation/doc/migrations/ns2.md b/src/Documentation/doc/migrations/ns2.md index fdd1cb40b..ef37bcb69 100644 --- a/src/Documentation/doc/migrations/ns2.md +++ b/src/Documentation/doc/migrations/ns2.md @@ -1,12 +1,12 @@ # "Netscript 2" Migration Guide -The game allows two script formats: +In previous versions, the game supported two script formats: -- `.script` (also sometimes called "Netscript 1" or "NS1") files are ran through an interpreter that is based on a version of Javascript from 2009 (ES5). These files are no longer actively supported and should be converted to the newer `.js` format. +- `.script` (also sometimes called "Netscript 1" or "NS1") files are ran through an interpreter that is based on a version of Javascript from 2009 (ES5). - `.js` (also sometimes called "Netscript 2" or "NS2") files are native javascript that is ran directly by the web browser. Modern features of javascript that are supported by your web browser are supported in `.js` files, because they are run as native js. -Support for `.script` files will be completely removed in future version 3.0. Some basic autoconversion will be attempted at that time, but it is highly recommended to convert your remaining `.script` files to the `.js` format before that, to ensure correctness and, if needed, to familiarize yourself with the `.js` format requirements. +Support for running `.script` files was removed in version 3.0. ## Why do I have to change anything? @@ -75,4 +75,4 @@ export async function main(ns) { ## Additional problems or edge cases -To get additional help with the migration join the [official Discord server](https://discord.gg/TFc3hKD). +To get additional help with the migration, please join the [official Discord server](https://discord.gg/TFc3hKD). diff --git a/src/Documentation/doc/programming/game_frozen.md b/src/Documentation/doc/programming/game_frozen.md index 31f2ad2f5..5dee52cf8 100644 --- a/src/Documentation/doc/programming/game_frozen.md +++ b/src/Documentation/doc/programming/game_frozen.md @@ -39,8 +39,8 @@ Common infinite loop when translating the server purchasing script in starting g while (i < ns.getPurchasedServerLimit()) { if (ns.getServerMoneyAvailable("home") > ns.getPurchasedServerCost(ram)) { var hostname = ns.purchaseServer("pserv-" + i, ram); - ns.scp("early-hack-template.script", hostname); - ns.exec("early-hack-template.script", hostname, 3); + ns.scp("early-hack-template.js", hostname); + ns.exec("early-hack-template.js", hostname, 3); ++i; } } diff --git a/src/GameOptions/ui/SystemPage.tsx b/src/GameOptions/ui/SystemPage.tsx index e2ce09f14..fd4546e56 100644 --- a/src/GameOptions/ui/SystemPage.tsx +++ b/src/GameOptions/ui/SystemPage.tsx @@ -6,7 +6,6 @@ import { AutoexecInput } from "./AutoexecInput"; import { OptionSwitch } from "../../ui/React/OptionSwitch"; export const SystemPage = (): React.ReactElement => { - const [execTime, setExecTime] = useState(Settings.CodeInstructionRunTime); const [recentScriptsSize, setRecentScriptsSize] = useState(Settings.MaxRecentScriptsCapacity); const [logSize, setLogSize] = useState(Settings.MaxLogCapacity); const [portSize, setPortSize] = useState(Settings.MaxPortCapacity); @@ -24,11 +23,6 @@ export const SystemPage = (): React.ReactElement => { Settings.MaxTerminalCapacity = newValue as number; } - function handleExecTimeChange(_event: Event | React.SyntheticEvent, newValue: number | number[]): void { - setExecTime(newValue as number); - Settings.CodeInstructionRunTime = newValue as number; - } - function handleTailIntervalChange(_event: Event | React.SyntheticEvent, newValue: number | number[]): void { setTailRenderInterval(newValue as number); Settings.TailRenderInterval = newValue as number; @@ -62,20 +56,6 @@ export const SystemPage = (): React.ReactElement => { } />
- - The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too low can - result in poor performance if you have many scripts running. - - } - /> await mainFunc(ns); } -async function startNetscript1Script(workerScript: WorkerScript): Promise { - const code = workerScript.code; - let errorToThrow: unknown; - - //Process imports - let codeWithImports, codeLineOffset; - try { - const importProcessingRes = processNetscript1Imports(code, workerScript); - codeWithImports = importProcessingRes.code; - codeLineOffset = importProcessingRes.lineOffset; - } catch (e: unknown) { - throw `Error processing Imports in ${workerScript.name}@${workerScript.hostname}:\n\n${e}`; - } - - //TODO unplanned: Make NS1 wrapping type safe instead of using BasicObject. - type BasicObject = Record; - const wrappedNS = NetscriptFunctions(workerScript); - function wrapNS1Layer(int: Interpreter, intLayer: unknown, nsLayer = wrappedNS as BasicObject) { - for (const [name, entry] of Object.entries(nsLayer)) { - if (typeof entry === "function") { - const wrapper = async (...args: unknown[]) => { - try { - // Sent a resolver function as an extra arg. See createAsyncFunction JSInterpreter.js:3209 - const callback = args.pop() as (value: unknown) => void; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call -- NS1 is deprecated. - const result = await entry(...args.map((arg) => int.pseudoToNative(arg))); - return callback(int.nativeToPseudo(result)); - } catch (e: unknown) { - errorToThrow = e; - } - }; - int.setProperty(intLayer, name, int.createAsyncFunction(wrapper)); - } else if (Array.isArray(entry) || typeof entry !== "object") { - // args, strings on enums, etc - int.setProperty(intLayer, name, int.nativeToPseudo(entry)); - } else { - // new object layer, e.g. bladeburner - int.setProperty(intLayer, name, int.nativeToPseudo({})); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument -- NS1 is deprecated. - wrapNS1Layer(int, (intLayer as BasicObject).properties[name], nsLayer[name]); - } - } - } - - let interpreter: Interpreter; - try { - interpreter = new Interpreter(codeWithImports, wrapNS1Layer, codeLineOffset); - } catch (e: unknown) { - throw `Syntax ERROR in ${workerScript.name}@${workerScript.hostname}:\n\n${String(e)}`; - } - - let more = true; - while (more) { - if (errorToThrow) throw errorToThrow; - if (workerScript.env.stopFlag) return; - for (let i = 0; more && i < 3; i++) more = interpreter.step(); - if (more) await new Promise((r) => setTimeout(r, Settings.CodeInstructionRunTime)); - } -} - -/* Since the JS Interpreter used for Netscript 1.0 only supports ES5, the keyword - 'import' throws an error. However, since we want to support import functionality - we'll implement it ourselves by parsing the Nodes in the AST out. - - @param code - The script's code - @returns {Object} { - code: Newly-generated code with imported functions - lineOffset: Net number of lines of code added/removed due to imported functions - Should typically be positive - } -*/ -function processNetscript1Imports(code: string, workerScript: WorkerScript): { code: string; lineOffset: number } { - //allowReserved prevents 'import' from throwing error in ES5 - const ast = parse(code, { - ecmaVersion: 9, - allowReserved: true, - sourceType: "module", - }); - - const server = workerScript.getServer(); - if (server == null) { - throw new Error("Failed to find underlying Server object for script"); - } - - function getScript(scriptName: ScriptFilePath): Script | null { - return server.scripts.get(scriptName) ?? null; - } - - let generatedCode = ""; // Generated Javascript Code - let hasImports = false; - - // Walk over the tree and process ImportDeclaration nodes - walksimple(ast, { - ImportDeclaration: (node: acorn.ImportDeclaration) => { - hasImports = true; - const scriptName = resolveScriptFilePath(node.source.value as string, root, legacyScriptExtension); - if (!scriptName) throw new Error("'Import' failed due to invalid path: " + scriptName); - const script = getScript(scriptName); - if (!script) throw new Error("'Import' failed due to script not found: " + scriptName); - const scriptAst = parse(script.code, { - ecmaVersion: 9, - allowReserved: true, - sourceType: "module", - }); - - if (node.specifiers.length === 1 && node.specifiers[0].type === "ImportNamespaceSpecifier") { - // import * as namespace from script - const namespace = node.specifiers[0].local.name; - const fnNames: string[] = []; //Names only - const fnDeclarations: acorn.Node[] = []; //FunctionDeclaration Node objects - walksimple(scriptAst, { - FunctionDeclaration: (node: acorn.FunctionDeclaration | acorn.AnonymousFunctionDeclaration) => { - if (!node.id) { - return; - } - fnNames.push(node.id.name); - fnDeclarations.push(node); - }, - }); - - //Now we have to generate the code that would create the namespace - generatedCode += `var ${namespace};\n(function (namespace) {\n`; - - //Add the function declarations - fnDeclarations.forEach((fn) => { - generatedCode += generate(fn); - generatedCode += "\n"; - }); - - //Add functions to namespace - fnNames.forEach((fnName) => { - generatedCode += "namespace." + fnName + " = " + fnName; - generatedCode += "\n"; - }); - - //Finish - generatedCode += `})(${namespace} || (" + namespace + " = {}));\n`; - } else { - //import {...} from script - - //Get array of all fns to import - const fnsToImport: string[] = []; - node.specifiers.forEach((e) => { - fnsToImport.push(e.local.name); - }); - - //Walk through script and get FunctionDeclaration code for all specified fns - const fnDeclarations: acorn.Node[] = []; - walksimple(scriptAst, { - FunctionDeclaration: (node: acorn.FunctionDeclaration | acorn.AnonymousFunctionDeclaration) => { - if (!node.id) { - return; - } - if (fnsToImport.includes(node.id.name)) { - fnDeclarations.push(node); - } - }, - }); - - //Convert FunctionDeclarations into code - fnDeclarations.forEach((fn) => { - generatedCode += generate(fn); - generatedCode += "\n"; - }); - } - }, - }); - - //If there are no imports, just return the original code - if (!hasImports) { - return { code: code, lineOffset: 0 }; - } - - //Remove ImportDeclarations from AST. These ImportDeclarations must be in top-level - let linesRemoved = 0; - if (ast.type !== "Program" || ast.body == null) { - throw new Error("Code could not be properly parsed"); - } - for (let i = ast.body.length - 1; i >= 0; --i) { - if (ast.body[i].type === "ImportDeclaration") { - ast.body.splice(i, 1); - ++linesRemoved; - } - } - - //Calculated line offset - const lineOffset = (generatedCode.match(/\n/g) || []).length - linesRemoved; - - //Convert the AST back into code - code = generate(ast); - - //Add the imported code and re-generate in ES5 (JS Interpreter for NS1 only supports ES5); - code = generatedCode + code; - - const res = { - code: code, - lineOffset: lineOffset, - }; - return res; -} - /** * Used to start a RunningScript (by creating and starting its * corresponding WorkerScript), and add the RunningScript to the server on which @@ -310,6 +101,10 @@ export function startWorkerScript(runningScript: RunningScript, server: BaseServ * returns {boolean} indicating whether or not the workerScript was successfully added */ function createAndAddWorkerScript(runningScriptObj: RunningScript, server: BaseServer, parent?: WorkerScript): boolean { + if (isLegacyScript(runningScriptObj.filename)) { + deferredError(`Running .script files is unsupported.`); + return false; + } const ramUsage = roundToTwo(runningScriptObj.ramUsage * runningScriptObj.threads); const ramAvailable = server.maxRam - server.ramUsed; // Check failure conditions before generating the workersScript and return false @@ -344,7 +139,7 @@ Otherwise, this can also occur if you have attempted to launch a script from a t workerScripts.set(pid, workerScript); // Start the script's execution using the correct function for file type - (isLegacyScript(workerScript.name) ? startNetscript1Script : startNetscript2Script)(workerScript) + startNetscript2Script(workerScript) // Once the code finishes (either resolved or rejected, doesn't matter), set its // running status to false .then(function () { diff --git a/src/Paths/ScriptFilePath.ts b/src/Paths/ScriptFilePath.ts index fe05e4c93..e6e0b1809 100644 --- a/src/Paths/ScriptFilePath.ts +++ b/src/Paths/ScriptFilePath.ts @@ -8,7 +8,15 @@ export type ScriptFilePath = FilePath & WithScriptExtension; export const legacyScriptExtension = ".script"; -/** Valid extensions. Used for some error messaging. */ +/** + * Valid extensions. Used for some error messaging. + * + * Running .script is unsupported, but we still put it in the list of valid script extensions. When we remove the + * support of NS1, we only remove the ability to run it. Except the migration docs, the official documentation (help + * text, TSDoc of NS APIs, etc.) does not mention NS1 and .script anymore. However, for the player's convenience when + * migrating from NS1 to NS2, we still let them perform other actions on their unsupported scripts (e.g., open, copy, + * move, delete). + */ export const validScriptExtensions = [".js", ".jsx", ".ts", ".tsx", legacyScriptExtension] as const; export type ScriptExtension = (typeof validScriptExtensions)[number]; diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index a97118843..d16e7d595 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -7678,7 +7678,7 @@ export interface NS { * @remarks * RAM cost: 0 GB * - * This function can be used to write data to a text file (.txt, .json) or a script (.js, .jsx, .ts, .tsx, .script). + * This function can be used to write data to a text file (.txt, .json) or a script (.js, .jsx, .ts, .tsx). * * This function will write data to that file. If the specified file does not exist, * then it will be created. The third argument mode defines how the data will be written to @@ -7724,7 +7724,7 @@ export interface NS { * @remarks * RAM cost: 0 GB * - * This function is used to read data from a text file (.txt, .json) or script (.js, .jsx, .ts, .tsx, .script). + * This function is used to read data from a text file (.txt, .json) or script (.js, .jsx, .ts, .tsx). * * This function will return the data in the specified file. * If the file does not exist, an empty string will be returned. @@ -8206,7 +8206,7 @@ export interface NS { * RAM cost: 0 GB * * Retrieves data from a URL and downloads it to a file on the specified server. - * The data can only be downloaded to a script (.js, .jsx, .ts, .tsx, .script) or a text file (.txt, .json). + * The data can only be downloaded to a script (.js, .jsx, .ts, .tsx) or a text file (.txt, .json). * If the file already exists, it will be overwritten by this command. * Note that it will not be possible to download data from many websites because they * do not allow cross-origin resource sharing (CORS). diff --git a/src/ScriptEditor/ui/ScriptEditorRoot.tsx b/src/ScriptEditor/ui/ScriptEditorRoot.tsx index 6782f0650..2a7ca1cd2 100644 --- a/src/ScriptEditor/ui/ScriptEditorRoot.tsx +++ b/src/ScriptEditor/ui/ScriptEditorRoot.tsx @@ -188,14 +188,13 @@ function Root(props: IProps): React.ReactElement { // this is duplicate code with saving later. if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) { //Make sure filename + code properly follow tutorial - if (currentScript.path !== "n00dles.script" && currentScript.path !== "n00dles.js") { + if (currentScript.path !== "n00dles.js") { dialogBoxCreate("Don't change the script name for now."); return; } const cleanCode = currentScript.code.replace(/\s/g, ""); - const ns1 = "while(true){hack('n00dles');}"; - const ns2 = `/**@param{NS}ns*/exportasyncfunctionmain(ns){while(true){awaitns.hack("n00dles");}}`; - if (!cleanCode.includes(ns1) && !cleanCode.includes(ns2)) { + const expectedCleanCode = `/**@param{NS}ns*/exportasyncfunctionmain(ns){while(true){awaitns.hack("n00dles");}}`; + if (!cleanCode.includes(expectedCleanCode)) { dialogBoxCreate("Please copy and paste the code from the tutorial!"); return; } diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts index 153a5bd5b..b8e6240ae 100644 --- a/src/Settings/Settings.ts +++ b/src/Settings/Settings.ts @@ -83,8 +83,6 @@ export const Settings = { AutoexecScript: "", /** How often the game should autosave the player's progress, in seconds. */ AutosaveInterval: 60, - /** How many milliseconds between execution points for Netscript 1 statements. */ - CodeInstructionRunTime: 25, /** Whether to render city as list of buttons. */ DisableASCIIArt: false, /** Whether global keyboard shortcuts should be disabled throughout the game. */ diff --git a/src/Terminal/HelpText.ts b/src/Terminal/HelpText.ts index 06a83613f..d8dfada40 100644 --- a/src/Terminal/HelpText.ts +++ b/src/Terminal/HelpText.ts @@ -54,7 +54,7 @@ const TemplatedHelpTexts: Record string[]> = { return [ `Usage: ${command} [file names...] | [glob]`, ` `, - `Opens up the specified file(s) in the Script Editor. Only scripts (.js, .jsx, .ts, .tsx, .script) `, + `Opens up the specified file(s) in the Script Editor. Only scripts (.js, .jsx, .ts, .tsx) `, `or text files (.txt, .json) can be edited using the Script Editor. If a file does not exist, a new `, `one will be created.`, ` `, @@ -170,11 +170,11 @@ export const HelpTexts: Record = { "a space. Remember that a running script is uniquely ", "identified both by its name and the arguments that are used to start it. So, if a script was ran with the following arguments: ", " ", - " run foo.script 1 2 foodnstuff", + " run foo.js 1 2 foodnstuff", " ", "Then to run the 'check' command on this script you would have to pass the same arguments in: ", " ", - " check foo.script 1 2 foodnstuff", + " check foo.js 1 2 foodnstuff", " ", ], clear: [ @@ -209,7 +209,7 @@ export const HelpTexts: Record = { " ", "Download all scripts and text files: download *", " ", - "Download all scripts: download *.script", + "Download all JS scripts: download *.js", " ", "Download all text files: download *.txt", " ", @@ -325,11 +325,11 @@ export const HelpTexts: Record = { "uniquely identified by both its name and the arguments that are used to start ", "it. So, if a script was ran with the following arguments:", " ", - " run foo.script 1 sigma-cosmetics", + " run foo.js 1 sigma-cosmetics", " ", "Then to kill this script the same arguments would have to be used:", " ", - " kill foo.script 1 sigma-cosmetics", + " kill foo.js 1 sigma-cosmetics", " ", "If you are killing the script using its PID, then the PID argument must be numeric", " ", @@ -349,9 +349,9 @@ export const HelpTexts: Record = { " ", "Examples:", " ", - "List all files with the '.script' extension in the current directory:", + "List all files with the '.js' extension in the current directory:", " ", - " ls -l --grep .script", + " ls -l --grep .js", " ", "List all files with the '.js' extension in the root directory:", " ", @@ -371,12 +371,12 @@ export const HelpTexts: Record = { "the amount of RAM needed to run a script with multiple threads using the '-t' flag. If the '-t' flag is specified, then ", "an argument for the number of threads must be passed in afterwards. Examples:", " ", - " mem foo.script", + " mem foo.js", " ", - " mem foo.script -t 50", + " mem foo.js -t 50", " ", - "The first example above will print the amount of RAM needed to run 'foo.script' with a single thread. The second example ", - "above will print the amount of RAM needed to run 'foo.script' with 50 threads.", + "The first example above will print the amount of RAM needed to run 'foo.js' with a single thread. The second example ", + "above will print the amount of RAM needed to run 'foo.js' with 50 threads.", " ", ], mv: [ @@ -390,7 +390,7 @@ export const HelpTexts: Record = { "full filepath. ", "Examples: ", " ", - " mv hacking-controller.script scripts/hacking-controller.script", + " mv hacking-controller.js scripts/hacking-controller.js", " ", " mv myScript.js myOldScript.js", " ", @@ -461,13 +461,13 @@ export const HelpTexts: Record = { "Usage: scp [file names...] [target server]", " ", "Copies the specified file(s) from the current server to the target server. ", - "This command only works for script files (.js, .jsx, .ts, .tsx, .script), text files (.txt, .json), ", + "This command only works for script files (.js, .jsx, .ts, .tsx), text files (.txt, .json), ", "and literature files (.lit).", "The second argument passed in must be the hostname or IP of the target server. Examples:", " ", - " scp foo.script n00dles", + " scp foo.js n00dles", " ", - " scp foo.script bar.script n00dles", + " scp foo.js bar.js n00dles", " ", ], sudov: ["Usage: sudov", " ", "Prints whether or not you have root access to the current machine", " "], @@ -479,11 +479,11 @@ export const HelpTexts: Record = { "by a space. Remember that a running script is uniquely identified by both its name and the arguments that were used ", "to run it. So, if a script was ran with the following arguments: ", " ", - " run foo.script 10 50000", + " run foo.js 10 50000", " ", "Then in order to check its logs with 'tail' the same arguments must be used: ", " ", - " tail foo.script 10 50000", + " tail foo.js 10 50000", " ", ], top: [ @@ -523,7 +523,7 @@ export const HelpTexts: Record = { "Usage: wget [url] [target file]", " ", "Retrieves data from a URL and downloads it to a file on the current server. The data can only ", - "be downloaded to a script (.js, .jsx, .ts, .tsx, .script) or a text file (.txt, .json).", + "be downloaded to a script (.js, .jsx, .ts, .tsx) or a text file (.txt, .json).", "If the file already exists, it will be overwritten by this command.", " ", "Note that it will not be possible to download data from many websites because they do not allow ", diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index 5b2897e6e..ad891bdc6 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -601,7 +601,7 @@ export class Terminal { this.setcwd(root); if (!singularity) { this.print("Connected to " + `${isIPAddress(hostname) ? server.ip : server.hostname}`); - if (Player.getCurrentServer().hostname == "darkweb") { + if (Player.getCurrentServer().hostname === "darkweb") { checkIfConnectedToDarkweb(); // Posts a 'help' message if connecting to dark web } } @@ -649,7 +649,7 @@ export class Terminal { "Bad command. Please follow the tutorial or click 'Exit Tutorial' if you'd like to skip it."; switch (ITutorial.currStep) { case iTutorialSteps.TerminalHelp: - if (commandArray.length === 1 && commandArray[0] == "help") { + if (commandArray.length === 1 && commandArray[0] === "help") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -657,9 +657,9 @@ export class Terminal { } break; case iTutorialSteps.TerminalLs: - if (commandArray.length === 1 && commandArray[0] == "ls") { + if (commandArray.length === 1 && commandArray[0] === "ls") { iTutorialNextStep(); - } else if (commandArray[0] == "1s") { + } else if (commandArray[0] === "1s") { this.error("Command '1s' not found. Did you mean 'ls' with a lowercase L?"); return; } else { @@ -668,7 +668,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalScan: - if (commandArray.length === 1 && commandArray[0] == "scan") { + if (commandArray.length === 1 && commandArray[0] === "scan") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -676,7 +676,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalScanAnalyze1: - if (commandArray.length == 1 && commandArray[0] == "scan-analyze") { + if (commandArray.length === 1 && commandArray[0] === "scan-analyze") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -684,7 +684,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalScanAnalyze2: - if (commandArray.length == 2 && commandArray[0] == "scan-analyze" && commandArray[1] === 2) { + if (commandArray.length === 2 && commandArray[0] === "scan-analyze" && commandArray[1] === 2) { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -692,10 +692,10 @@ export class Terminal { } break; case iTutorialSteps.TerminalConnect: - if (commandArray.length == 2) { + if (commandArray.length === 2) { if ( - commandArray[0] == "connect" && - (commandArray[1] == "n00dles" || commandArray[1] == n00dlesServ.hostname) + commandArray[0] === "connect" && + (commandArray[1] === "n00dles" || commandArray[1] === n00dlesServ.hostname) ) { iTutorialNextStep(); } else { @@ -716,7 +716,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalNuke: - if (commandArray.length == 2 && commandArray[0] == "run" && commandArray[1] == "NUKE.exe") { + if (commandArray.length === 2 && commandArray[0] === "run" && commandArray[1] === "NUKE.exe") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -724,7 +724,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalManualHack: - if (commandArray.length == 1 && commandArray[0] == "hack") { + if (commandArray.length === 1 && commandArray[0] === "hack") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -738,7 +738,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalGoHome: - if (commandArray.length == 1 && commandArray[0] == "home") { + if (commandArray.length === 1 && commandArray[0] === "home") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -746,11 +746,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalCreateScript: - if ( - commandArray.length == 2 && - commandArray[0] == "nano" && - (commandArray[1] == "n00dles.script" || commandArray[1] == "n00dles.js") - ) { + if (commandArray.length === 2 && commandArray[0] === "nano" && commandArray[1] === "n00dles.js") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -758,7 +754,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalFree: - if (commandArray.length == 1 && commandArray[0] == "free") { + if (commandArray.length === 1 && commandArray[0] === "free") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -766,11 +762,7 @@ export class Terminal { } break; case iTutorialSteps.TerminalRunScript: - if ( - commandArray.length == 2 && - commandArray[0] == "run" && - (commandArray[1] == "n00dles.script" || commandArray[1] == "n00dles.js") - ) { + if (commandArray.length === 2 && commandArray[0] === "run" && commandArray[1] === "n00dles.js") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); @@ -778,11 +770,7 @@ export class Terminal { } break; case iTutorialSteps.ActiveScriptsToTerminal: - if ( - commandArray.length == 2 && - commandArray[0] == "tail" && - (commandArray[1] == "n00dles.script" || commandArray[1] == "n00dles.js") - ) { + if (commandArray.length === 2 && commandArray[0] === "tail" && commandArray[1] === "n00dles.js") { iTutorialNextStep(); } else { this.error(errorMessageForBadCommand); diff --git a/src/Terminal/commands/cat.ts b/src/Terminal/commands/cat.ts index 5efd2e272..ae21a6b6b 100644 --- a/src/Terminal/commands/cat.ts +++ b/src/Terminal/commands/cat.ts @@ -21,7 +21,7 @@ export function cat(args: (string | number | boolean)[], server: BaseServer): vo } if (!path.endsWith(".msg") && !path.endsWith(".lit")) { return Terminal.error( - "Invalid file extension. Filename must end with .msg, .lit, a script extension (.js, .jsx, .ts, .tsx, .script) or a text extension (.txt, .json)", + "Invalid file extension. Filename must end with .msg, .lit, a script extension (.js, .jsx, .ts, .tsx) or a text extension (.txt, .json)", ); } diff --git a/src/Terminal/commands/common/deprecation.tsx b/src/Terminal/commands/common/deprecation.tsx index c36c66dc8..4acda1b60 100644 --- a/src/Terminal/commands/common/deprecation.tsx +++ b/src/Terminal/commands/common/deprecation.tsx @@ -7,8 +7,8 @@ import { Page } from "../../../ui/Router"; export function sendDeprecationNotice() { return Terminal.printRaw( - - NOTICE: Accessing the Netscript API via .script files is deprecated and will be removed in a future update.{" "} + + Running .script files is unsupported.{" "} {item instanceof Output && } {item instanceof RawOutput && ( - + {item.raw} )} {item instanceof Link && ( - + {item.dashes} Terminal.connectToServer(item.hostname)}>{item.hostname} diff --git a/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx b/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx index 175ecc021..ed634d54f 100644 --- a/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx +++ b/src/ui/InteractiveTutorial/InteractiveTutorialRoot.tsx @@ -283,7 +283,7 @@ export function InteractiveTutorialRoot(): React.ReactElement { }, [iTutorialSteps.TerminalHackingMechanics as number]: { content: ( - + You are now attempting to hack the server. Performing a hack takes time and only has a certain percentage chance of success. This time and success chance is determined by a variety of factors, including your hacking skill and the server's security level. @@ -327,8 +327,7 @@ export function InteractiveTutorialRoot(): React.ReactElement { {"[home /]> nano"} - Scripts must end with a script extension (.js, .jsx, .ts, .tsx, .script). Let's make a script now by - entering + Scripts must end with a script extension (.js, .jsx, .ts, .tsx). Let's make a script now by entering {`[home /]> nano ${tutorialScriptName}`} @@ -343,7 +342,7 @@ export function InteractiveTutorialRoot(): React.ReactElement { into the text editor:
- + {