mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-27 03:25:44 +02:00
BUGFIX: More savegame loading fixes (#543)
* Fix loading issues back to pre-1.0 * Be more robust about issues with files not being maps * Avoid non-fatal error when there's no LastExportBonus
This commit is contained in:
@@ -5,8 +5,9 @@ import { Script } from "../Script/Script";
|
||||
import { TextFile } from "../TextFile";
|
||||
import { IReturnStatus } from "../types";
|
||||
|
||||
import { ScriptFilePath, hasScriptExtension } from "../Paths/ScriptFilePath";
|
||||
import { TextFilePath, hasTextExtension } from "../Paths/TextFilePath";
|
||||
import { ScriptFilePath, resolveScriptFilePath, hasScriptExtension } from "../Paths/ScriptFilePath";
|
||||
import { Directory, resolveDirectory } from "../Paths/Directory";
|
||||
import { TextFilePath, resolveTextFilePath, hasTextExtension } from "../Paths/TextFilePath";
|
||||
import { Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver";
|
||||
import { matchScriptPathExact } from "../utils/helpers/scriptKey";
|
||||
|
||||
@@ -313,9 +314,54 @@ export abstract class BaseServer implements IServer {
|
||||
// Initializes a Server Object from a JSON save state
|
||||
// Called by subclasses, not Reviver.
|
||||
static fromJSONBase<T extends BaseServer>(value: IReviverValue, ctor: new () => T, keys: readonly (keyof T)[]): T {
|
||||
const result = Generic_fromJSON(ctor, value.data, keys);
|
||||
result.savedScripts = value.data.runningScripts;
|
||||
return result;
|
||||
const server = Generic_fromJSON(ctor, value.data, keys);
|
||||
server.savedScripts = value.data.runningScripts;
|
||||
// If textFiles is not an array, we've already done the 2.3 migration to textFiles and scripts as maps + path changes.
|
||||
if (!Array.isArray(server.textFiles)) return server;
|
||||
|
||||
// Migrate to using maps for scripts and textfiles. This is done here, directly at load, instead of the
|
||||
// usual upgrade logic, for two reasons:
|
||||
// 1) Our utility functions depend on it, so the upgrade logic itself needs the data to be in maps, even the logic
|
||||
// written earlier than 2.3!
|
||||
// 2) If the upgrade logic throws, and then you soft-reset at the recovery screen (or maybe don't even see the
|
||||
// recovery screen), you can end up with a "migrated" save that still has arrays.
|
||||
const newDirectory = resolveDirectory("v2.3FileChanges/") as Directory;
|
||||
let invalidScriptCount = 0;
|
||||
// There was a brief dev window where Server.scripts was already a map but the filepath changes weren't in yet.
|
||||
// Thus, we can't skip this logic just because it's already a map.
|
||||
const oldScripts = Array.isArray(server.scripts) ? (server.scripts as Script[]) : [...server.scripts.values()];
|
||||
server.scripts = new JSONMap();
|
||||
// In case somehow there are previously valid filenames that can't be sanitized, they will go in a new directory with a note.
|
||||
for (const script of oldScripts) {
|
||||
let newFilePath = resolveScriptFilePath(script.filename);
|
||||
if (!newFilePath) {
|
||||
newFilePath = `${newDirectory}script${++invalidScriptCount}.js` as ScriptFilePath;
|
||||
script.content = `// Original path: ${script.filename}. Path was no longer valid\n` + script.content;
|
||||
}
|
||||
script.filename = newFilePath;
|
||||
server.scripts.set(newFilePath, script);
|
||||
}
|
||||
let invalidTextCount = 0;
|
||||
|
||||
const oldTextFiles = server.textFiles as (TextFile & { fn?: string })[];
|
||||
server.textFiles = new JSONMap();
|
||||
for (const textFile of oldTextFiles) {
|
||||
const oldName = textFile.fn ?? textFile.filename;
|
||||
delete textFile.fn;
|
||||
|
||||
let newFilePath = resolveTextFilePath(oldName);
|
||||
if (!newFilePath) {
|
||||
newFilePath = `${newDirectory}text${++invalidTextCount}.txt` as TextFilePath;
|
||||
textFile.content = `// Original path: ${textFile.filename}. Path was no longer valid\n` + textFile.content;
|
||||
}
|
||||
textFile.filename = newFilePath;
|
||||
server.textFiles.set(newFilePath, textFile);
|
||||
}
|
||||
if (invalidScriptCount || invalidTextCount) {
|
||||
// If we had to migrate names, don't run scripts for this server.
|
||||
server.savedScripts = [];
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
// Customize a prune list for a subclass.
|
||||
|
||||
Reference in New Issue
Block a user