2017-08-30 19:44:29 +02:00
|
|
|
import {loadAliases, loadGlobalAliases,
|
|
|
|
Aliases, GlobalAliases} from "./Alias.js";
|
|
|
|
import {loadCompanies, Companies,
|
|
|
|
CompanyPositions} from "./Company.js";
|
|
|
|
import {CONSTANTS} from "./Constants.js";
|
|
|
|
import {Engine} from "./engine.js";
|
|
|
|
import {loadFactions, Factions,
|
|
|
|
processPassiveFactionRepGain} from "./Faction.js";
|
2018-03-12 20:39:04 +01:00
|
|
|
import {FconfSettings, loadFconf} from "./Fconf.js";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {loadAllGangs, AllGangs} from "./Gang.js";
|
2018-06-03 03:37:56 +02:00
|
|
|
import {processAllHacknetNodeEarnings,
|
|
|
|
createPlayerHacknetNodeWrappers} from "./HacknetNode.js";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {loadMessages, initMessages, Messages} from "./Message.js";
|
|
|
|
import {Player, loadPlayer} from "./Player.js";
|
|
|
|
import {loadAllRunningScripts} from "./Script.js";
|
|
|
|
import {AllServers, loadAllServers} from "./Server.js";
|
|
|
|
import {loadSettings, initSettings, Settings} from "./Settings.js";
|
|
|
|
import {loadSpecialServerIps, SpecialServerIps} from "./SpecialServerIps.js";
|
|
|
|
import {loadStockMarket, StockMarket} from "./StockMarket.js";
|
|
|
|
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
|
|
|
import {gameOptionsBoxClose} from "../utils/GameOptions.js";
|
2018-05-02 19:38:11 +02:00
|
|
|
import {clearEventListeners, createElement,
|
|
|
|
createPopup, removeElementById} from "../utils/HelperFunctions.js";
|
2017-08-30 19:44:29 +02:00
|
|
|
import {Reviver, Generic_toJSON,
|
|
|
|
Generic_fromJSON} from "../utils/JSONReviver.js";
|
|
|
|
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
|
|
|
|
2018-05-30 19:41:17 +02:00
|
|
|
import Decimal from "decimal.js";
|
2017-08-30 19:44:29 +02:00
|
|
|
|
2017-07-25 16:39:56 +02:00
|
|
|
/* SaveObject.js
|
|
|
|
* Defines the object used to save/load games
|
2017-05-05 03:08:44 +02:00
|
|
|
*/
|
2017-08-30 19:44:29 +02:00
|
|
|
let saveObject = new BitburnerSaveObject();
|
2017-05-05 03:08:44 +02:00
|
|
|
|
|
|
|
function BitburnerSaveObject() {
|
|
|
|
this.PlayerSave = "";
|
|
|
|
this.AllServersSave = "";
|
|
|
|
this.CompaniesSave = "";
|
|
|
|
this.FactionsSave = "";
|
|
|
|
this.SpecialServerIpsSave = "";
|
2017-05-23 17:12:09 +02:00
|
|
|
this.AliasesSave = "";
|
2017-06-30 18:44:03 +02:00
|
|
|
this.GlobalAliasesSave = "";
|
2017-06-02 06:15:45 +02:00
|
|
|
this.MessagesSave = "";
|
2017-07-03 21:42:11 +02:00
|
|
|
this.StockMarketSave = "";
|
2017-07-25 16:39:56 +02:00
|
|
|
this.SettingsSave = "";
|
2018-03-12 20:39:04 +01:00
|
|
|
this.FconfSettingsSave = "";
|
2017-06-07 02:04:18 +02:00
|
|
|
this.VersionSave = "";
|
2018-02-18 04:08:54 +01:00
|
|
|
this.AllGangsSave = "";
|
2017-05-05 03:08:44 +02:00
|
|
|
}
|
|
|
|
|
2017-10-12 04:00:22 +02:00
|
|
|
BitburnerSaveObject.prototype.saveGame = function(db) {
|
2017-05-05 03:08:44 +02:00
|
|
|
this.PlayerSave = JSON.stringify(Player);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
|
|
|
//Delete all logs from all running scripts
|
2017-06-19 16:54:11 +02:00
|
|
|
var TempAllServers = JSON.parse(JSON.stringify(AllServers), Reviver);
|
2017-06-18 11:31:14 +02:00
|
|
|
for (var ip in TempAllServers) {
|
|
|
|
var server = TempAllServers[ip];
|
|
|
|
if (server == null) {continue;}
|
|
|
|
for (var i = 0; i < server.runningScripts.length; ++i) {
|
|
|
|
var runningScriptObj = server.runningScripts[i];
|
|
|
|
runningScriptObj.logs.length = 0;
|
|
|
|
runningScriptObj.logs = [];
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-18 11:31:14 +02:00
|
|
|
this.AllServersSave = JSON.stringify(TempAllServers);
|
2017-05-05 03:08:44 +02:00
|
|
|
this.CompaniesSave = JSON.stringify(Companies);
|
|
|
|
this.FactionsSave = JSON.stringify(Factions);
|
|
|
|
this.SpecialServerIpsSave = JSON.stringify(SpecialServerIps);
|
2017-05-23 17:12:09 +02:00
|
|
|
this.AliasesSave = JSON.stringify(Aliases);
|
2017-06-30 18:44:03 +02:00
|
|
|
this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
|
2017-06-02 06:15:45 +02:00
|
|
|
this.MessagesSave = JSON.stringify(Messages);
|
2017-07-03 21:42:11 +02:00
|
|
|
this.StockMarketSave = JSON.stringify(StockMarket);
|
2017-07-25 16:39:56 +02:00
|
|
|
this.SettingsSave = JSON.stringify(Settings);
|
2018-03-12 20:39:04 +01:00
|
|
|
this.FconfSettingsSave = JSON.stringify(FconfSettings);
|
2017-06-07 02:04:18 +02:00
|
|
|
this.VersionSave = JSON.stringify(CONSTANTS.Version);
|
2017-08-13 07:01:33 +02:00
|
|
|
if (Player.bitNodeN == 2 && Player.inGang()) {
|
|
|
|
this.AllGangsSave = JSON.stringify(AllGangs);
|
|
|
|
}
|
2017-05-05 06:54:40 +02:00
|
|
|
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
|
2017-10-12 04:00:22 +02:00
|
|
|
|
|
|
|
//We'll save to both localstorage and indexedDb
|
|
|
|
var objectStore = db.transaction(["savestring"], "readwrite").objectStore("savestring");
|
|
|
|
var request = objectStore.put(saveString, "save");
|
|
|
|
|
|
|
|
request.onerror = function(e) {
|
|
|
|
console.log("Error saving game to IndexedDB: " + e);
|
|
|
|
}
|
|
|
|
|
|
|
|
request.onsuccess = function(e) {
|
2017-11-02 22:47:09 +01:00
|
|
|
//console.log("Saved game to IndexedDB!");
|
2017-10-12 04:00:22 +02:00
|
|
|
}
|
|
|
|
|
2017-09-19 20:38:03 +02:00
|
|
|
try {
|
|
|
|
window.localStorage.setItem("bitburnerSave", saveString);
|
2017-11-02 22:47:09 +01:00
|
|
|
//console.log("Saved game to LocalStorage!");
|
2017-09-19 20:38:03 +02:00
|
|
|
} catch(e) {
|
|
|
|
if (e.code == 22) {
|
2017-10-20 23:59:54 +02:00
|
|
|
Engine.createStatusText("Save failed for localStorage! Check console(F12)");
|
2017-10-12 04:00:22 +02:00
|
|
|
console.log("Failed to save game to localStorage because the size of the save file " +
|
|
|
|
"is too large. However, the game will still be saved to IndexedDb if your browser " +
|
|
|
|
"supports it. If you would like to save to localStorage as well, then " +
|
|
|
|
"consider killing several of your scripts to " +
|
|
|
|
"fix this, or increasing the size of your browsers localStorage");
|
2017-09-19 20:38:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-15 18:54:23 +02:00
|
|
|
Engine.createStatusText("Game saved!");
|
2017-05-05 03:08:44 +02:00
|
|
|
}
|
|
|
|
|
2017-10-12 04:00:22 +02:00
|
|
|
function loadGame(saveString) {
|
2017-10-26 00:05:12 +02:00
|
|
|
if (saveString === "" || saveString == null || saveString === undefined) {
|
2017-10-12 04:00:22 +02:00
|
|
|
if (!window.localStorage.getItem("bitburnerSave")) {
|
|
|
|
console.log("No save file to load");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
saveString = decodeURIComponent(escape(atob(window.localStorage.getItem("bitburnerSave"))));
|
|
|
|
console.log("Loading game from localStorage");
|
|
|
|
} else {
|
|
|
|
saveString = decodeURIComponent(escape(atob(saveString)));
|
|
|
|
console.log("Loading game from IndexedDB");
|
2017-05-05 03:08:44 +02:00
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
|
|
|
|
var saveObj = JSON.parse(saveString, Reviver);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
loadPlayer(saveObj.PlayerSave);
|
|
|
|
loadAllServers(saveObj.AllServersSave);
|
|
|
|
loadCompanies(saveObj.CompaniesSave);
|
|
|
|
loadFactions(saveObj.FactionsSave);
|
|
|
|
loadSpecialServerIps(saveObj.SpecialServerIpsSave);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-05-23 19:36:35 +02:00
|
|
|
if (saveObj.hasOwnProperty("AliasesSave")) {
|
2017-05-23 18:15:17 +02:00
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadAliases(saveObj.AliasesSave);
|
2017-05-23 18:15:17 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadAliases("");
|
2017-05-23 18:15:17 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadAliases("");
|
2017-05-23 18:15:17 +02:00
|
|
|
}
|
2017-06-30 18:44:03 +02:00
|
|
|
if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
|
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadGlobalAliases(saveObj.GlobalAliasesSave);
|
2017-06-30 18:44:03 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadGlobalAliases("");
|
2017-06-30 18:44:03 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadGlobalAliases("");
|
2017-06-30 18:44:03 +02:00
|
|
|
}
|
2017-06-02 06:15:45 +02:00
|
|
|
if (saveObj.hasOwnProperty("MessagesSave")) {
|
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadMessages(saveObj.MessagesSave);
|
2017-06-02 06:15:45 +02:00
|
|
|
} catch(e) {
|
|
|
|
initMessages();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initMessages();
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
if (saveObj.hasOwnProperty("StockMarketSave")) {
|
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadStockMarket(saveObj.StockMarketSave);
|
2017-07-03 21:42:11 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadStockMarket("");
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadStockMarket("");
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
if (saveObj.hasOwnProperty("SettingsSave")) {
|
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadSettings(saveObj.SettingsSave);
|
2017-07-25 16:39:56 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("ERROR: Failed to parse Settings. Re-initing default values");
|
2017-07-25 16:39:56 +02:00
|
|
|
initSettings();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initSettings();
|
|
|
|
}
|
2018-03-12 20:39:04 +01:00
|
|
|
if (saveObj.hasOwnProperty("FconfSettingsSave")) {
|
|
|
|
try {
|
|
|
|
loadFconf(saveObj.FconfSettingsSave);
|
|
|
|
} catch(e) {
|
|
|
|
console.log("ERROR: Failed to parse .fconf Settings.");
|
|
|
|
}
|
|
|
|
}
|
2017-06-07 02:04:18 +02:00
|
|
|
if (saveObj.hasOwnProperty("VersionSave")) {
|
|
|
|
try {
|
|
|
|
var ver = JSON.parse(saveObj.VersionSave, Reviver);
|
2017-10-26 00:05:12 +02:00
|
|
|
if (Player.bitNodeN == null || Player.bitNodeN === 0) {
|
2017-09-01 18:59:11 +02:00
|
|
|
Player.setBitNodeNumber(1);
|
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
|
2017-08-20 03:38:27 +02:00
|
|
|
console.log("Evaluating changes needed for version compatibility");
|
2017-09-01 18:59:11 +02:00
|
|
|
if (Player.augmentations.length > 0 || Player.queuedAugmentations.length > 0 ||
|
|
|
|
Player.sourceFiles.length > 0) {
|
|
|
|
//If you have already purchased an Aug...you are far enough in the game
|
|
|
|
//that everything should be available
|
|
|
|
Player.firstFacInvRecvd = true;
|
|
|
|
Player.firstAugPurchased = true;
|
|
|
|
Player.firstJobRecvd = true;
|
|
|
|
Player.firstTimeTraveled = true;
|
|
|
|
Player.firstProgramAvailable = true;
|
|
|
|
} else {
|
|
|
|
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
|
|
|
|
Player.firstFacInvRecvd = true;
|
|
|
|
}
|
|
|
|
if (Player.companyName !== "" || Player.companyPosition !== "") {
|
|
|
|
Player.firstJobRecvd = true;
|
|
|
|
}
|
|
|
|
if (Player.hacking_skill >= 25) {
|
|
|
|
Player.firstScriptAvailable = true;
|
|
|
|
}
|
2017-08-13 07:01:33 +02:00
|
|
|
}
|
|
|
|
}
|
2017-06-07 02:04:18 +02:00
|
|
|
if (ver != CONSTANTS.Version) {
|
2017-06-07 02:28:20 +02:00
|
|
|
createNewUpdateText();
|
2017-06-07 02:04:18 +02:00
|
|
|
}
|
|
|
|
} catch(e) {
|
2017-06-07 02:28:20 +02:00
|
|
|
createNewUpdateText();
|
2017-06-07 02:04:18 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-06-07 02:28:20 +02:00
|
|
|
createNewUpdateText();
|
2017-06-07 02:04:18 +02:00
|
|
|
}
|
2017-08-13 07:01:33 +02:00
|
|
|
if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
|
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
loadAllGangs(saveObj.AllGangsSave);
|
2017-08-13 07:01:33 +02:00
|
|
|
} catch(e) {
|
|
|
|
console.log("ERROR: Failed to parse AllGangsSave: " + e);
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2018-06-03 03:37:56 +02:00
|
|
|
//Re-initialize Hacknet Node Wrappers
|
|
|
|
createPlayerHacknetNodeWrappers();
|
2017-05-05 03:08:44 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
function loadImportedGame(saveObj, saveString) {
|
2017-06-08 06:57:40 +02:00
|
|
|
var tempSaveObj = null;
|
|
|
|
var tempPlayer = null;
|
|
|
|
var tempAllServers = null;
|
|
|
|
var tempCompanies = null;
|
|
|
|
var tempFactions = null;
|
|
|
|
var tempSpecialServerIps = null;
|
|
|
|
var tempAliases = null;
|
2017-06-30 18:44:03 +02:00
|
|
|
var tempGlobalAliases = null;
|
2017-06-08 06:57:40 +02:00
|
|
|
var tempMessages = null;
|
2017-07-03 21:42:11 +02:00
|
|
|
var tempStockMarket = null;
|
2018-02-18 04:08:54 +01:00
|
|
|
var tempAllGangs = null;
|
2017-08-30 19:44:29 +02:00
|
|
|
|
|
|
|
//Check to see if the imported save file can be parsed. If any
|
|
|
|
//errors are caught it will fail
|
2017-06-08 06:57:40 +02:00
|
|
|
try {
|
2017-08-30 19:44:29 +02:00
|
|
|
var decodedSaveString = decodeURIComponent(escape(atob(saveString)));
|
2017-06-08 06:57:40 +02:00
|
|
|
tempSaveObj = new BitburnerSaveObject();
|
2017-08-30 19:44:29 +02:00
|
|
|
tempSaveObj = JSON.parse(decodedSaveString, Reviver);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
tempPlayer = JSON.parse(tempSaveObj.PlayerSave, Reviver);
|
2017-08-01 21:10:21 +02:00
|
|
|
|
|
|
|
//Parse Decimal.js objects
|
|
|
|
tempPlayer.money = new Decimal(tempPlayer.money);
|
|
|
|
tempPlayer.total_money = new Decimal(tempPlayer.total_money);
|
|
|
|
tempPlayer.lifetime_money = new Decimal(tempPlayer.lifetime_money);
|
|
|
|
|
2017-06-08 06:57:40 +02:00
|
|
|
tempAllServers = JSON.parse(tempSaveObj.AllServersSave, Reviver);
|
|
|
|
tempCompanies = JSON.parse(tempSaveObj.CompaniesSave, Reviver);
|
|
|
|
tempFactions = JSON.parse(tempSaveObj.FactionsSave, Reviver);
|
|
|
|
tempSpecialServerIps = JSON.parse(tempSaveObj.SpecialServerIpsSave, Reviver);
|
|
|
|
if (tempSaveObj.hasOwnProperty("AliasesSave")) {
|
|
|
|
try {
|
|
|
|
tempAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver);
|
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Parsing Aliases save failed: " + e);
|
2017-06-08 06:57:40 +02:00
|
|
|
tempAliases = {};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tempAliases = {};
|
|
|
|
}
|
2017-06-30 18:44:03 +02:00
|
|
|
if (tempSaveObj.hasOwnProperty("GlobalAliases")) {
|
|
|
|
try {
|
|
|
|
tempGlobalAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver);
|
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Parsing Global Aliases save failed: " + e);
|
2017-06-30 18:44:03 +02:00
|
|
|
tempGlobalAliases = {};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tempGlobalAliases = {};
|
|
|
|
}
|
2017-06-08 06:57:40 +02:00
|
|
|
if (tempSaveObj.hasOwnProperty("MessagesSave")) {
|
|
|
|
try {
|
|
|
|
tempMessages = JSON.parse(tempSaveObj.MessagesSave, Reviver);
|
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Parsing Messages save failed: " + e);
|
2017-06-08 06:57:40 +02:00
|
|
|
initMessages();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initMessages();
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
if (saveObj.hasOwnProperty("StockMarketSave")) {
|
|
|
|
try {
|
2018-02-18 04:08:54 +01:00
|
|
|
tempStockMarket = JSON.parse(tempSaveObj.StockMarketSave, Reviver);
|
2017-07-03 21:42:11 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Parsing StockMarket save failed: " + e);
|
2017-07-03 21:42:11 +02:00
|
|
|
tempStockMarket = {};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tempStockMarket = {};
|
|
|
|
}
|
2017-06-08 06:57:40 +02:00
|
|
|
if (tempSaveObj.hasOwnProperty("VersionSave")) {
|
|
|
|
try {
|
|
|
|
var ver = JSON.parse(tempSaveObj.VersionSave, Reviver);
|
2017-08-30 19:44:29 +02:00
|
|
|
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
|
2017-08-13 07:01:33 +02:00
|
|
|
if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) {
|
|
|
|
tempPlayer.bitNodeN = 1;
|
|
|
|
}
|
|
|
|
if (tempPlayer.sourceFiles == null) {
|
|
|
|
tempPlayer.sourceFiles = [];
|
|
|
|
}
|
2017-06-08 06:57:40 +02:00
|
|
|
}
|
2017-06-17 09:21:42 +02:00
|
|
|
if (ver != CONSTANTS.Version) {
|
2017-08-30 19:44:29 +02:00
|
|
|
//createNewUpdateText();
|
2017-06-17 09:21:42 +02:00
|
|
|
}
|
2017-06-08 06:57:40 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Parsing Version save failed: " + e);
|
|
|
|
//createNewUpdateText();
|
2017-06-08 06:57:40 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-30 19:44:29 +02:00
|
|
|
//createNewUpdateText();
|
2017-06-08 06:57:40 +02:00
|
|
|
}
|
2018-02-18 04:08:54 +01:00
|
|
|
if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && tempSaveObj.hasOwnProperty("AllGangsSave")) {
|
2017-08-13 07:01:33 +02:00
|
|
|
try {
|
2018-02-18 04:08:54 +01:00
|
|
|
loadAllGangs(tempSaveObj.AllGangsSave);
|
2017-08-13 07:01:33 +02:00
|
|
|
} catch(e) {
|
|
|
|
console.log("ERROR: Failed to parse AllGangsSave: " + e);
|
|
|
|
}
|
|
|
|
}
|
2017-06-08 06:57:40 +02:00
|
|
|
} catch(e) {
|
2017-08-30 19:44:29 +02:00
|
|
|
dialogBoxCreate("Error importing game: " + e.toString());
|
2017-06-08 06:57:40 +02:00
|
|
|
return false;
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
//Since the save file is valid, load everything for real
|
|
|
|
saveString = decodeURIComponent(escape(atob(saveString)));
|
|
|
|
saveObj = JSON.parse(saveString, Reviver);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
loadPlayer(saveObj.PlayerSave);
|
|
|
|
loadAllServers(saveObj.AllServersSave);
|
|
|
|
loadCompanies(saveObj.CompaniesSave);
|
|
|
|
loadFactions(saveObj.FactionsSave);
|
|
|
|
loadSpecialServerIps(saveObj.SpecialServerIpsSave);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
if (saveObj.hasOwnProperty("AliasesSave")) {
|
|
|
|
try {
|
|
|
|
loadAliases(saveObj.AliasesSave);
|
|
|
|
} catch(e) {
|
|
|
|
loadAliases("");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
loadAliases("");
|
2017-06-08 06:57:40 +02:00
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
|
|
|
|
try {
|
|
|
|
loadGlobalAliases(saveObj.GlobalAliasesSave);
|
|
|
|
} catch(e) {
|
|
|
|
loadGlobalAliases("");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
loadGlobalAliases("");
|
|
|
|
}
|
|
|
|
if (saveObj.hasOwnProperty("MessagesSave")) {
|
|
|
|
try {
|
|
|
|
loadMessages(saveObj.MessagesSave);
|
|
|
|
} catch(e) {
|
|
|
|
initMessages();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initMessages();
|
|
|
|
}
|
|
|
|
if (saveObj.hasOwnProperty("StockMarketSave")) {
|
|
|
|
try {
|
|
|
|
loadStockMarket(saveObj.StockMarketSave);
|
|
|
|
} catch(e) {
|
|
|
|
loadStockMarket("");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
loadStockMarket("");
|
|
|
|
}
|
|
|
|
if (saveObj.hasOwnProperty("SettingsSave")) {
|
|
|
|
try {
|
|
|
|
loadSettings(saveObj.SettingsSave);
|
|
|
|
} catch(e) {
|
|
|
|
initSettings();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
initSettings();
|
|
|
|
}
|
2018-03-12 20:39:04 +01:00
|
|
|
if (saveObj.hasOwnProperty("FconfSettingsSave")) {
|
|
|
|
try {
|
|
|
|
loadFconf(saveObj.FconfSettingsSave);
|
|
|
|
} catch(e) {
|
|
|
|
console.log("ERROR: Failed to load .fconf settings when importing");
|
|
|
|
}
|
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
if (saveObj.hasOwnProperty("VersionSave")) {
|
|
|
|
try {
|
|
|
|
var ver = JSON.parse(saveObj.VersionSave, Reviver);
|
2017-09-01 18:59:11 +02:00
|
|
|
if (Player.bitNodeN == null || Player.bitNodeN == 0) {
|
|
|
|
Player.setBitNodeNumber(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
|
2017-08-30 19:44:29 +02:00
|
|
|
console.log("Evaluating changes needed for version compatibility");
|
2017-09-01 18:59:11 +02:00
|
|
|
if (Player.augmentations.length > 0 || Player.queuedAugmentations.length > 0 ||
|
|
|
|
Player.sourceFiles.length > 0) {
|
|
|
|
//If you have already purchased an Aug...you are far enough in the game
|
|
|
|
//that everything should be available
|
|
|
|
Player.firstFacInvRecvd = true;
|
|
|
|
Player.firstAugPurchased = true;
|
|
|
|
Player.firstJobRecvd = true;
|
|
|
|
Player.firstTimeTraveled = true;
|
|
|
|
Player.firstProgramAvailable = true;
|
|
|
|
} else {
|
|
|
|
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
|
|
|
|
Player.firstFacInvRecvd = true;
|
|
|
|
}
|
|
|
|
if (Player.companyName !== "" || Player.companyPosition !== "") {
|
|
|
|
Player.firstJobRecvd = true;
|
|
|
|
}
|
|
|
|
if (Player.hacking_skill >= 25) {
|
|
|
|
Player.firstScriptAvailable = true;
|
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ver != CONSTANTS.Version) {
|
|
|
|
createNewUpdateText();
|
|
|
|
}
|
|
|
|
} catch(e) {
|
|
|
|
createNewUpdateText();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
createNewUpdateText();
|
|
|
|
}
|
|
|
|
if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
|
|
|
|
try {
|
|
|
|
loadAllGangs(saveObj.AllGangsSave);
|
|
|
|
} catch(e) {
|
|
|
|
console.log("ERROR: Failed to parse AllGangsSave: " + e);
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2018-06-03 03:37:56 +02:00
|
|
|
//Re-initialize Hacknet Node Wrappers
|
|
|
|
createPlayerHacknetNodeWrappers();
|
|
|
|
|
2018-05-02 19:38:11 +02:00
|
|
|
var popupId = "import-game-restart-game-notice";
|
|
|
|
var txt = createElement("p", {
|
|
|
|
innerText:"Imported game! I would suggest saving the game and then reloading the page " +
|
|
|
|
"to make sure everything runs smoothly"
|
|
|
|
});
|
|
|
|
var gotitBtn = createElement("a", {
|
|
|
|
class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
|
|
|
|
clickListener:()=>{
|
|
|
|
removeElementById(popupId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
createPopup(popupId, [txt, gotitBtn]);
|
2017-06-08 07:08:53 +02:00
|
|
|
gameOptionsBoxClose();
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
//Re-start game
|
|
|
|
console.log("Importing game");
|
|
|
|
Engine.setDisplayElements(); //Sets variables for important DOM elements
|
|
|
|
Engine.init(); //Initialize buttons, work, etc.
|
|
|
|
CompanyPositions.init();
|
|
|
|
|
|
|
|
//Calculate the number of cycles have elapsed while offline
|
|
|
|
Engine._lastUpdate = new Date().getTime();
|
|
|
|
var lastUpdate = Player.lastUpdate;
|
|
|
|
var numCyclesOffline = Math.floor((Engine._lastUpdate - lastUpdate) / Engine._idleSpeed);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
/* Process offline progress */
|
|
|
|
var offlineProductionFromScripts = loadAllRunningScripts(); //This also takes care of offline production for those scripts
|
|
|
|
if (Player.isWorking) {
|
|
|
|
console.log("work() called in load() for " + numCyclesOffline * Engine._idleSpeed + " milliseconds");
|
|
|
|
if (Player.workType == CONSTANTS.WorkTypeFaction) {
|
|
|
|
Player.workForFaction(numCyclesOffline);
|
|
|
|
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
|
|
|
|
Player.createProgramWork(numCyclesOffline);
|
|
|
|
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
|
|
|
|
Player.takeClass(numCyclesOffline);
|
|
|
|
} else if (Player.workType == CONSTANTS.WorkTypeCrime) {
|
|
|
|
Player.commitCrime(numCyclesOffline);
|
|
|
|
} else if (Player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
|
|
|
Player.workPartTime(numCyclesOffline);
|
|
|
|
} else {
|
|
|
|
Player.work(numCyclesOffline);
|
|
|
|
}
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
//Hacknet Nodes offline progress
|
|
|
|
var offlineProductionFromHacknetNodes = processAllHacknetNodeEarnings(numCyclesOffline);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
//Passive faction rep gain offline
|
|
|
|
processPassiveFactionRepGain(numCyclesOffline);
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
//Update total playtime
|
|
|
|
var time = numCyclesOffline * Engine._idleSpeed;
|
|
|
|
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
|
2017-06-17 19:47:04 +02:00
|
|
|
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
|
2017-06-08 17:59:22 +02:00
|
|
|
Player.totalPlaytime += time;
|
2017-06-17 19:47:04 +02:00
|
|
|
Player.playtimeSinceLastAug += time;
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
//Re-apply augmentations
|
|
|
|
Player.reapplyAllAugmentations();
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 20:32:38 +02:00
|
|
|
//Clear terminal
|
|
|
|
$("#terminal tr:not(:last)").remove();
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 17:59:22 +02:00
|
|
|
Player.lastUpdate = Engine._lastUpdate;
|
|
|
|
Engine.start(); //Run main game loop and Scripts loop
|
2017-07-25 16:39:56 +02:00
|
|
|
dialogBoxCreate("While you were offline, your scripts generated $" +
|
|
|
|
formatNumber(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
|
2017-06-08 17:59:22 +02:00
|
|
|
formatNumber(offlineProductionFromHacknetNodes, 2));
|
2017-06-08 06:57:40 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:35:56 +02:00
|
|
|
BitburnerSaveObject.prototype.exportGame = function() {
|
2017-06-08 06:57:40 +02:00
|
|
|
this.PlayerSave = JSON.stringify(Player);
|
|
|
|
this.AllServersSave = JSON.stringify(AllServers);
|
|
|
|
this.CompaniesSave = JSON.stringify(Companies);
|
|
|
|
this.FactionsSave = JSON.stringify(Factions);
|
|
|
|
this.SpecialServerIpsSave = JSON.stringify(SpecialServerIps);
|
|
|
|
this.AliasesSave = JSON.stringify(Aliases);
|
2017-07-07 04:24:59 +02:00
|
|
|
this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
|
2017-06-08 06:57:40 +02:00
|
|
|
this.MessagesSave = JSON.stringify(Messages);
|
2018-01-09 21:48:06 +01:00
|
|
|
this.StockMarketSave = JSON.stringify(StockMarket);
|
|
|
|
this.SettingsSave = JSON.stringify(Settings);
|
2017-06-08 06:57:40 +02:00
|
|
|
this.VersionSave = JSON.stringify(CONSTANTS.Version);
|
2018-01-09 21:48:06 +01:00
|
|
|
if (Player.bitNodeN == 2 && Player.inGang()) {
|
|
|
|
this.AllGangsSave = JSON.stringify(AllGangs);
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 06:57:40 +02:00
|
|
|
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
|
2017-09-13 16:22:22 +02:00
|
|
|
var filename = "bitburnerSave.json";
|
2017-06-08 06:57:40 +02:00
|
|
|
var file = new Blob([saveString], {type: 'text/plain'});
|
|
|
|
if (window.navigator.msSaveOrOpenBlob) {// IE10+
|
2017-07-25 16:39:56 +02:00
|
|
|
window.navigator.msSaveOrOpenBlob(file, filename);
|
2017-06-08 06:57:40 +02:00
|
|
|
} else { // Others
|
|
|
|
var a = document.createElement("a"),
|
|
|
|
url = URL.createObjectURL(file);
|
|
|
|
a.href = url;
|
|
|
|
a.download = "bitburnerSave.json";
|
|
|
|
document.body.appendChild(a);
|
|
|
|
a.click();
|
|
|
|
setTimeout(function() {
|
|
|
|
document.body.removeChild(a);
|
2017-07-25 16:39:56 +02:00
|
|
|
window.URL.revokeObjectURL(url);
|
|
|
|
}, 0);
|
2017-06-08 06:57:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BitburnerSaveObject.prototype.importGame = function() {
|
|
|
|
if (window.File && window.FileReader && window.FileList && window.Blob) {
|
|
|
|
var fileSelector = clearEventListeners("import-game-file-selector");
|
|
|
|
fileSelector.addEventListener("change", openImportFileHandler, false);
|
|
|
|
$("#import-game-file-selector").click();
|
|
|
|
} else {
|
|
|
|
dialogBoxCreate("ERR: Your browser does not support HTML5 File API. Cannot import.");
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 01:35:56 +02:00
|
|
|
}
|
|
|
|
|
2017-10-12 04:00:22 +02:00
|
|
|
BitburnerSaveObject.prototype.deleteGame = function(db) {
|
|
|
|
//Delete from local storage
|
2017-05-05 03:08:44 +02:00
|
|
|
if (window.localStorage.getItem("bitburnerSave")) {
|
|
|
|
window.localStorage.removeItem("bitburnerSave");
|
|
|
|
}
|
2017-10-12 04:00:22 +02:00
|
|
|
|
|
|
|
//Delete from indexedDB
|
|
|
|
var request = db.transaction(["savestring"], "readwrite").objectStore("savestring").delete("save");
|
|
|
|
request.onsuccess = function(e) {
|
|
|
|
console.log("Successfully deleted save from indexedDb");
|
|
|
|
}
|
|
|
|
request.onerror = function(e) {
|
|
|
|
console.log("Failed to delete save from indexedDb: " + e);
|
|
|
|
}
|
2017-05-15 18:54:23 +02:00
|
|
|
Engine.createStatusText("Game deleted!");
|
2017-05-05 03:08:44 +02:00
|
|
|
}
|
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
function createNewUpdateText() {
|
2017-07-25 16:39:56 +02:00
|
|
|
dialogBoxCreate("New update!<br>" +
|
|
|
|
"Please report any bugs/issues through the github repository " +
|
|
|
|
"or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
|
2017-06-07 02:28:20 +02:00
|
|
|
CONSTANTS.LatestUpdate);
|
|
|
|
}
|
|
|
|
|
2017-05-05 03:08:44 +02:00
|
|
|
|
|
|
|
BitburnerSaveObject.prototype.toJSON = function() {
|
|
|
|
return Generic_toJSON("BitburnerSaveObject", this);
|
|
|
|
}
|
|
|
|
|
|
|
|
BitburnerSaveObject.fromJSON = function(value) {
|
|
|
|
return Generic_fromJSON(BitburnerSaveObject, value.data);
|
|
|
|
}
|
|
|
|
|
2017-06-08 06:57:40 +02:00
|
|
|
Reviver.constructors.BitburnerSaveObject = BitburnerSaveObject;
|
|
|
|
|
2017-07-25 16:39:56 +02:00
|
|
|
//Import game
|
2017-06-08 06:57:40 +02:00
|
|
|
|
|
|
|
function openImportFileHandler(evt) {
|
|
|
|
var file = evt.target.files[0];
|
|
|
|
if (!file) {
|
|
|
|
dialogBoxCreate("Invalid file selected");
|
|
|
|
return;
|
|
|
|
}
|
2017-07-25 16:39:56 +02:00
|
|
|
|
2017-06-08 06:57:40 +02:00
|
|
|
var reader = new FileReader();
|
|
|
|
reader.onload = function(e) {
|
|
|
|
var contents = e.target.result;
|
|
|
|
loadImportedGame(saveObject, contents);
|
|
|
|
};
|
|
|
|
reader.readAsText(file);
|
2017-07-25 16:39:56 +02:00
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
|
|
|
|
export {saveObject, loadGame};
|