From 07e9cb9277f6632bd3f647a8bb3d1f75b57f9af1 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Wed, 17 Aug 2022 20:31:26 -0400 Subject: [PATCH] refactor scp function --- src/NetscriptFunctions.ts | 198 +++++++++++++++++--------------------- 1 file changed, 86 insertions(+), 112 deletions(-) diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index cd128000b..d6998449e 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -829,132 +829,106 @@ const base: InternalAPI = { }, scp: (ctx: NetscriptContext) => - (_scriptname: unknown, _destination: unknown, _source: unknown = ctx.workerScript.hostname): boolean => { + (_files: unknown, _destination: unknown, _source: unknown = ctx.workerScript.hostname): boolean => { const destination = helpers.string(ctx, "destination", _destination); const source = helpers.string(ctx, "source", _source); - if (Array.isArray(_scriptname)) { - // Recursively call scp on all elements of array - const scripts: string[] = _scriptname; - if (scripts.length === 0) { - throw helpers.makeRuntimeErrorMsg(ctx, "No scripts to copy"); - } - let res = true; - scripts.forEach(function (script) { - //TODO: This array method still needs to be reworked because it is terribly inefficient. - if (!NetscriptFunctions(ctx.workerScript).scp(script, destination, source)) { - res = false; - } - }); - return res; - } - - const scriptName = helpers.string(ctx, "scriptName", _scriptname); - - // Invalid file type - if (!isValidFilePath(scriptName)) { - throw helpers.makeRuntimeErrorMsg(ctx, `Invalid filename: '${scriptName}'`); - } - - // Invalid file name - if (!scriptName.endsWith(".lit") && !isScriptFilename(scriptName) && !scriptName.endsWith("txt")) { - throw helpers.makeRuntimeErrorMsg(ctx, "Only works for scripts, .lit and .txt files"); - } - const destServer = helpers.getServer(ctx, destination); - const currServ = helpers.getServer(ctx, source); + const sourceServ = helpers.getServer(ctx, source); + const files = Array.isArray(_files) ? _files : [_files]; - // Scp for lit files - if (scriptName.endsWith(".lit")) { - let found = false; - for (let i = 0; i < currServ.messages.length; ++i) { - if (currServ.messages[i] == scriptName) { - found = true; - break; + //First loop through filenames to find all errors before moving anything. + for (const file of files) { + // Not a string + if (typeof file !== "string") + throw helpers.makeRuntimeErrorMsg(ctx, "files should be a string or an array of strings."); + + // Invalid file name + if (!isValidFilePath(file)) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid filename: '${file}'`); + + // Invalid file type + if (!file.endsWith(".lit") && !isScriptFilename(file) && !file.endsWith("txt")) { + throw helpers.makeRuntimeErrorMsg(ctx, "Only works for scripts, .lit and .txt files."); + } + } + + let noFailures = true; + //ts detects files as any[] here even though we would have thrown in the above loop if it wasn't string[] + for (const file of files as string[]) { + // Scp for lit files + if (file.endsWith(".lit")) { + const sourceMessage = sourceServ.messages.find((message) => message === file); + if (!sourceMessage) { + helpers.log(ctx, () => `File '${file}' does not exist.`); + noFailures = false; + continue; } - } - if (!found) { - helpers.log(ctx, () => `File '${scriptName}' does not exist.`); - return false; - } - - for (let i = 0; i < destServer.messages.length; ++i) { - if (destServer.messages[i] === scriptName) { - helpers.log(ctx, () => `File '${scriptName}' copied over to '${destServer?.hostname}'.`); - return true; // Already exists + const destMessage = destServer.messages.find((message) => message === file); + if (destMessage) { + helpers.log(ctx, () => `File '${file}' was already on '${destServer?.hostname}'.`); + continue; } - } - destServer.messages.push(scriptName); - helpers.log(ctx, () => `File '${scriptName}' copied over to '${destServer?.hostname}'.`); - return true; - } - // Scp for text files - if (scriptName.endsWith(".txt")) { - let txtFile; - for (let i = 0; i < currServ.textFiles.length; ++i) { - if (currServ.textFiles[i].fn === scriptName) { - txtFile = currServ.textFiles[i]; - break; + destServer.messages.push(file); + helpers.log(ctx, () => `File '${file}' copied over to '${destServer?.hostname}'.`); + continue; + } + + // Scp for text files + if (file.endsWith(".txt")) { + const sourceTextFile = sourceServ.textFiles.find((textFile) => textFile.fn === file); + if (!sourceTextFile) { + helpers.log(ctx, () => `File '${file}' does not exist.`); + noFailures = false; + continue; } - } - if (txtFile === undefined) { - helpers.log(ctx, () => `File '${scriptName}' does not exist.`); - return false; - } - for (let i = 0; i < destServer.textFiles.length; ++i) { - if (destServer.textFiles[i].fn === scriptName) { - // Overwrite - destServer.textFiles[i].text = txtFile.text; - helpers.log(ctx, () => `File '${scriptName}' copied over to '${destServer?.hostname}'.`); - return true; + const destTextFile = destServer.textFiles.find((textFile) => textFile.fn === file); + if (destTextFile) { + destTextFile.text = sourceTextFile.text; + helpers.log(ctx, () => `File '${file}' overwritten on '${destServer?.hostname}'.`); + continue; } + + const newFile = new TextFile(sourceTextFile.fn, sourceTextFile.text); + destServer.textFiles.push(newFile); + helpers.log(ctx, () => `File '${file}' copied over to '${destServer?.hostname}'.`); + continue; } - const newFile = new TextFile(txtFile.fn, txtFile.text); - destServer.textFiles.push(newFile); - helpers.log(ctx, () => `File '${scriptName}' copied over to '${destServer?.hostname}'.`); - return true; + + // Scp for script files + const sourceScript = sourceServ.scripts.find((script) => script.filename === file); + if (!sourceScript) { + helpers.log(ctx, () => `File '${file}' does not exist.`); + noFailures = false; + continue; + } + + // Overwrite script if it already exists + const destScript = destServer.scripts.find((script) => script.filename === file); + if (destScript) { + if (destScript.code === sourceScript.code) { + helpers.log(ctx, () => `Identical file '${file}' was already on '${destServer?.hostname}'`); + continue; + } + destScript.code = sourceScript.code; + destScript.ramUsage = destScript.ramUsage; + destScript.markUpdated(); + helpers.log(ctx, () => `WARNING: File '${file}' overwritten on '${destServer?.hostname}'`); + continue; + } + + // Create new script if it does not already exist + const newScript = new Script(Player, file); + newScript.code = sourceScript.code; + newScript.ramUsage = sourceScript.ramUsage; + newScript.server = destServer.hostname; + destServer.scripts.push(newScript); + helpers.log(ctx, () => `File '${file}' copied over to '${destServer?.hostname}'.`); + newScript.updateRamUsage(Player, destServer.scripts); } - // Scp for script files - 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) { - helpers.log(ctx, () => `File '${scriptName}' does not exist.`); - return false; - } - - // Overwrite script if it already exists - for (let i = 0; i < destServer.scripts.length; ++i) { - if (scriptName == destServer.scripts[i].filename) { - helpers.log(ctx, () => `WARNING: File '${scriptName}' overwritten on '${destServer?.hostname}'`); - const oldScript = destServer.scripts[i]; - // If it's the exact same file don't actually perform the - // copy to avoid recompiling uselessly. Players tend to scp - // liberally. - if (oldScript.code === sourceScript.code) return true; - oldScript.code = sourceScript.code; - oldScript.ramUsage = sourceScript.ramUsage; - oldScript.markUpdated(); - return true; - } - } - - // Create new script if it does not already exist - const newScript = new Script(Player, scriptName); - newScript.code = sourceScript.code; - newScript.ramUsage = sourceScript.ramUsage; - newScript.server = destServer.hostname; - destServer.scripts.push(newScript); - helpers.log(ctx, () => `File '${scriptName}' copied over to '${destServer?.hostname}'.`); - newScript.updateRamUsage(Player, destServer.scripts); - return true; + return noFailures; }, ls: (ctx: NetscriptContext) =>