Add support for the mv command in NS

This commit is contained in:
Jeffrey A. Robinson 2022-01-12 09:53:54 -08:00
parent e9db656e13
commit bedea0ac73
6 changed files with 176 additions and 26 deletions

20
dist/bitburner.d.ts vendored

@ -4099,6 +4099,26 @@ export declare interface NS extends Singularity {
*/ */
atExit(f: () => void): void; atExit(f: () => void): void;
/**
* Move a file on the target server.
* @remarks
* RAM cost: 0 GB
*
* NS2 exclusive
*
* Move the source file to the specified destination on the target server.
*
* This command only works for scripts and text files (.txt). It cannot, however, be used
* to convert from script to text file, or vice versa.
*
* This function can also be used to rename files.
*
* @param host - Host of target server.
* @param source - Filename of the source file.
* @param destination - Filename of the destination file.
*/
mv(host: string, source: string, destination: string): void;
/** /**
* Parse command line flags. * Parse command line flags.
* @remarks * @remarks

@ -0,0 +1,38 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [bitburner](./bitburner.md) &gt; [NS](./bitburner.ns.md) &gt; [atExit](./bitburner.ns.atexit.md)
## NS.mv() method
Move a file on the target server.
<b>Signature:</b>
```typescript
mv(host: string, source: string, destination: string): void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| host | string | Host of target server. |
| source | string | Filename of the source file. |
| destination | string | Filename of the destination file. |
<b>Returns:</b>
void
## Remarks
RAM cost: 0 GB
NS2 exclusive
Move the source file to the specified destination on the target server.
This command only works for scripts and text files (.txt). It cannot, however, be used
to convert from script to text file, or vice versa.
This function can also be used to rename files.

@ -207,6 +207,7 @@ export const RamCosts: IMap<any> = {
wget: 0, wget: 0,
getFavorToDonate: RamCostConstants.ScriptGetFavorToDonate, getFavorToDonate: RamCostConstants.ScriptGetFavorToDonate,
getPlayer: RamCostConstants.ScriptSingularityFn1RamCost / 4, getPlayer: RamCostConstants.ScriptSingularityFn1RamCost / 4,
mv: 0,
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles, getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
// Singularity Functions // Singularity Functions

@ -697,8 +697,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
workerScript.log( workerScript.log(
"weaken", "weaken",
() => () =>
`'${server.hostname}' security level weakened to ${ `'${server.hostname}' security level weakened to ${server.hackDifficulty
server.hackDifficulty
}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`, }. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
); );
workerScript.scriptRef.onlineExpGained += expGain; workerScript.scriptRef.onlineExpGained += expGain;
@ -2264,6 +2263,64 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
workerScript.atExit = f; workerScript.atExit = f;
}, },
mv: function (host: string, source: string, destination: string): void {
updateDynamicRam("mv", getRamCost(Player, "mv"));
if (arguments.length != 3) throw makeRuntimeErrorMsg("mv", "Takes 3 argument.");
if (!isValidFilePath(source)) throw makeRuntimeErrorMsg("mv", `Invalid filename: '${source}'`);
if (!isValidFilePath(destination)) throw makeRuntimeErrorMsg("mv", `Invalid filename: '${destination}'`);
const source_is_txt = source.endsWith(".txt");
const dest_is_txt = destination.endsWith(".txt");
if (!isScriptFilename(source) && !source_is_txt) throw makeRuntimeErrorMsg("mv", `'mv' can only be used on scripts and text files (.txt)`);
if (source_is_txt != dest_is_txt) throw makeRuntimeErrorMsg("mv", `Source and destination files must have the same type`);
if (source === destination) {
return;
}
// This will throw if the server is not found, we do not need to validate result.
const destServer: BaseServer | null = safeGetServer(host, "mv");
if (!source_is_txt && destServer.isRunning(source)) throw makeRuntimeErrorMsg("mv", `Cannot use 'mv' on a script that is running`)
interface File {
filename: string;
}
const files = source_is_txt ? destServer.textFiles : destServer.scripts;
let source_file: File | null = null;
let dest_file: File | null = null;
for (let i = 0; i < files.length; ++i) {
const file = files[i];
if (file.filename === source) {
source_file = file;
} else if (file.filename === destination) {
dest_file = file;
}
}
if (source_file == null) throw makeRuntimeErrorMsg("mv", `Source file ${source} does not exist`)
if (dest_file != null) {
if (dest_file instanceof TextFile && source_file instanceof TextFile) {
dest_file.text = source_file.text;
} else if (dest_file instanceof Script && source_file instanceof Script) {
dest_file.code = source_file.code;
dest_file.markUpdated();
}
destServer.removeFile(source);
} else {
source_file.filename = destination;
if (source_file instanceof Script) {
source_file.markUpdated();
}
}
},
flags: Flags(workerScript.args), flags: Flags(workerScript.args),
}; };

@ -5813,6 +5813,26 @@ export interface NS extends Singularity {
*/ */
atExit(f: () => void): void; atExit(f: () => void): void;
/**
* Move a file on the target server.
* @remarks
* RAM cost: 0 GB
*
* NS2 exclusive
*
* Move the source file to the specified destination on the target server.
*
* This command only works for scripts and text files (.txt). It cannot, however, be used
* to convert from script to text file, or vice versa.
*
* This function can also be used to rename files.
*
* @param host - Host of target server.
* @param source - Filename of the source file.
* @param destination - Filename of the destination file.
*/
mv(host: string, source: string, destination: string): void;
/** /**
* Parse command line flags. * Parse command line flags.
* @remarks * @remarks

@ -17,6 +17,20 @@ export class TextFile {
*/ */
text: string; text: string;
/**
* The full file name.
*/
get filename(): string {
return this.fn;
}
/**
* The full file name.
*/
set filename(value: string) {
this.fn = value;
}
constructor(fn = "", txt = "") { constructor(fn = "", txt = "") {
this.fn = (fn.endsWith(".txt") ? fn : `${fn}.txt`).replace(/\s+/g, ""); this.fn = (fn.endsWith(".txt") ? fn : `${fn}.txt`).replace(/\s+/g, "");
this.text = txt; this.text = txt;