Пример #1
0
        public static void LoadSaveFile(Stream stream, OS os)
        {
            var reader       = new StreamReader(stream);
            var saveFileText = reader.ReadToEnd();


            if (string.IsNullOrEmpty(saveFileText))
            {
                throw new FormatException("Blank account data detected! (This is a vanilla saving issue)");
            }

            var executor    = new EventExecutor(saveFileText, isPath: false);
            var subExecutor = new ParsedTreeExecutor();

            executor.AddExecutor("HacknetSave", (exec, info) =>
            {
                /* OS.loadTitleSaveData */
                MissionGenerator.generationCount = info.Attributes.GetInt("generatedMissionCount", 100);
                os.defaultUser.name  = os.username = info.Attributes.GetValue("Username");
                os.LanguageCreatedIn = info.Attributes.GetValueOrDefault("Language", "en-us");
                os.IsInDLCMode       = info.Attributes.GetBool("DLCMode") && Util.Extensions.CheckLabyrinths();
                os.DisableEmailIcon  = info.Attributes.GetBool("DisableMailIcon") && Util.Extensions.CheckLabyrinths();
            });

            /* OS.LoadExtraTitleSaveData / OS.ReadDLCSaveData */
            executor.AddExecutor("HacknetSave.DLC", (exec, info) =>
            {
                os.IsInDLCMode   = info.Attributes.GetBool("Active");
                var hasLoadedDLC = os.HasLoadedDLCContent = info.Attributes.GetBool("LoadedContent");

                if (hasLoadedDLC)
                {
                    "This save".ThrowNoLabyrinths();
                }
            });

            executor.AddExecutor("HacknetSave.DLC.Flags", (exec, info) =>
                                 os.PreDLCFaction = info.Attributes.GetValue("OriginalFaction"));

            executor.AddExecutor("HacknetSave.DLC.OriginalVisibleNodes", (exec, info) =>
                                 os.PreDLCVisibleNodesCache = info.Value, true);

            executor.AddExecutor("HacknetSave.DLC.ConditionalActions",
                                 (exec, info) => { os.ConditionalActions = ActionsLoader.LoadConditionalActions(info); }, true);

            executor.AddExecutor("HacknetSave.Flags", (exec, info) =>
            {
                /* ProgressionFlags.Load */
                var flags = os.Flags;

                flags.Flags.Clear();
                if (info.Value == null)
                {
                    return;
                }
                foreach (var flag in info.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var trueFlag = flag.Replace("[%%COMMAREPLACED%%]", ",");
                    // ReSharper disable StringLiteralTypo
                    if (trueFlag == "décrypté")
                    {
                        trueFlag = "decypher";
                    }
                    // ReSharper restore StringLiteralTypo
                    flags.AddFlag(trueFlag);
                }
            }, true);

            /* NetworkMap.load */

            executor.AddExecutor("HacknetSave.NetworkMap", (exec, info) =>
            {
                var sortAlgo = info.Attributes.GetValue("sort");
                if (!Enum.TryParse(sortAlgo, out os.netMap.SortingAlgorithm))
                {
                    /* TODO: Error reporting here */
                }

                subExecutor.Execute(info);

                foreach (var d in os.netMap.nodes.SelectMany(node => node.daemons))
                {
                    d.loadInit();
                }

                os.netMap.loadAssignGameNodes();
            }, true);

            executor.AddExecutor("HacknetSave.NetworkMap.visible", (exec, info) =>
            {
                var visibleNodes = info.Value;
                foreach (var node in visibleNodes.Split())
                {
                    os.netMap.visibleNodes.Add(Convert.ToInt32(node));
                }
            }, true);


            executor.AddExecutor("HacknetSave.NetworkMap.network.computer", (exec, info) =>
            {
                var computer = SaveLoader.LoadComputer(info, os);
                os.netMap.nodes.Add(computer);
            }, true);


            executor.AddExecutor("HacknetSave.mission",
                                 (exec, info) => { os.currentMission = SaveLoader.LoadMission(info); }, true);

            executor.AddExecutor("HacknetSave.AllFactions", (exec, info) =>
            {
                /* AllFactions.loadFromSave */
                var loadedFactions = new AllFactions();
                string curFac      = loadedFactions.currentFaction = info.Attributes.GetValue("current");
                foreach (var child in info.Children)
                {
                    Faction loaded = LoadFaction(child);
                    loadedFactions.factions.Add(loaded.idName, loaded);
                }

                os.allFactions = loadedFactions;
                if (curFac != "")
                {
                    os.currentFaction = loadedFactions.factions[curFac];
                }
            }, true);

            executor.AddExecutor("HacknetSave.other", (exec, info) =>
            {
                /* OS.loadOtherSaveData */
                MusicManager.playSongImmediatley(info.Attributes.GetValue("music"));
                os.homeNodeID        = info.Attributes.GetValueOrDefault("homeNode", "entropy00");
                os.homeAssetServerID = info.Attributes.GetValueOrDefault("homeAssetsNode", "entropy01");
            }, true);

            foreach (var exec in SaveDataLoaders)
            {
                executor.AddExecutor(exec.Key, exec.Value);
            }

            executor.OnOpenFile                   += OnOpenFile;
            executor.OnRead                       += OnRead;
            executor.OnReadElement                += OnReadElement;
            executor.OnReadEndElement             += OnReadEndElement;
            executor.OnReadDocument               += OnReadDocument;
            executor.OnReadComment                += OnReadComment;
            executor.OnReadText                   += OnReadText;
            executor.OnReadProcessingInstructions += OnReadProcessingInstructions;
            executor.OnCloseFile                  += OnCloseFile;

            executor.OnCloseFile += _ =>
            {
                OS.WillLoadSave     = false;
                os.FirstTimeStartup = false;
            };

            /* hook up child parser */
            subExecutor.delegateData = executor.delegateData;

            executor.Parse();
        }
Пример #2
0
        /* Computer.load */
        private static Computer LoadComputer(ElementInfo root, OS os)
        {
            /* Read top-level */

            var compName    = root.Attributes.GetValue("name");
            var compIP      = root.Attributes.GetValue("ip");
            var compType    = root.Attributes.GetByte("type");
            var compSpec    = root.Attributes.GetValue("spec");
            var compID      = root.Attributes.GetValue("id");
            var compDevices = root.Attributes.GetValueOrDefault("devices", null);
            var compIcon    = root.Attributes.GetValueOrDefault("icon", null);
            var compTracker = root.Attributes.GetBool("tracker");

            /* negative zeros chosen because they're unlikely to show up by accident */
            var compX = -0f;
            var compY = -0f;

            Computer result   = null;
            var      executor = new ParsedTreeExecutor(true);

            executor.AddExecutor("location", (exec, info) =>
            {
                compX = info.Attributes.GetFloat("x");
                compY = info.Attributes.GetFloat("y");
            });

            executor.AddExecutor("security", (exec, info) =>
            {
                var secLevel = info.Attributes.GetInt("level");

                /* HACK: This is THE EARLIEST we can construct the Computer instance */
                /* and other things rely on it being there, so we better get it done fast. */
                result = new Computer(compName, compIP, new Vector2(compX, compY), secLevel, compType, os)
                {
                    /* apply whatever else we've parsed so far */
                    idName             = compID,
                    attatchedDeviceIDs = compDevices,
                    icon       = compIcon,
                    HasTracker = compTracker,
                    firewall   = null, /* may be overwritten later */

                    /* now apply *our* attributes */
                    traceTime           = info.Attributes.GetFloat("traceTime"),
                    portsNeededForCrack = info.Attributes.GetInt("portsToCrack"),
                    adminIP             = info.Attributes.GetValue("adminIP")
                };

                var proxyTime = info.Attributes.GetFloat("proxyTime");
                if (proxyTime > 0.0)
                {
                    result.addProxy(proxyTime);
                }
                else
                {
                    result.hasProxy    = false;
                    result.proxyActive = false;
                }
            });

            executor.AddExecutor("admin", (exec, info) =>
            {
                Administrator admin = null;
                switch (info.Attributes.GetValue("type"))
                {
                case "fast":
                    admin = new FastBasicAdministrator();
                    break;

                case "basic":
                    admin = new BasicAdministrator();
                    break;

                case "progress":
                    admin = new FastProgressOnlyAdministrator();
                    break;
                }

                if (admin != null)
                {
                    admin.ResetsPassword = info.Attributes.GetBool("resetPass");
                    admin.IsSuper        = info.Attributes.GetBool("isSuper");
                }

                result.admin = admin;
            });

            executor.AddExecutor("links", (exec, info) =>
            {
                foreach (string idxStr in info.Value.Split((char[])null, StringSplitOptions.RemoveEmptyEntries))
                {
                    result.links.Add(Convert.ToInt32(idxStr));
                }
            }, true);

            executor.AddExecutor("firewall", (exec, info) =>
                                 result.firewall = new Firewall(
                                     info.Attributes.GetInt("complexity"),
                                     info.Attributes.GetValueOrDefault("solution", null),
                                     info.Attributes.GetFloat("additionalDelay")
                                     )
                                 );

            executor.AddExecutor("portsOpen", (exec, info) =>
            {
                if (info.Value.Length > 0)
                {
                    ComputerLoader.loadPortsIntoComputer(info.Value, result);
                }
            }, true);

            executor.AddExecutor("portRemap", (exec, info) =>
                                 result.PortRemapping = PortRemappingSerializer.Deserialize(info.Value), true);

            executor.AddExecutor("users", (exec, info) =>
            {
                foreach (var userData in info.Children.Where(e => e.Name == "user"))
                {
                    string userName = userData.Attributes.GetValue("name");
                    string userPass = userData.Attributes.GetValue("pass");
                    var user        = new UserDetail(
                        userName,
                        userPass,
                        userData.Attributes.GetByte("type")
                        )
                    {
                        known = userData.Attributes.GetBool("known")
                    };

                    if (userName.ToLower() == "admin")
                    {
                        result.adminPass = userPass;
                    }

                    result.users.Add(user);
                }
            }, true);

            executor.AddExecutor("Memory", (exec, info) =>
                                 result.Memory = ReplacementsCommon.LoadMemoryContents(info), true);

            #region Daemons

            executor.AddExecutor("daemons.MailServer", (exec, info) =>
            {
                var server = result.AddDaemon <MailServer>(info.Attributes.GetValue("name"), os);
                if (info.Attributes.TryGetValue("color", out var colorStr))
                {
                    var color = Utility.GetColorFromString(colorStr, true, null);
                    if (color.HasValue)
                    {
                        server.setThemeColor(color.Value);
                    }
                }
            });

            executor.AddExecutor("daemons.MissionListingServer", (exec, info) =>
            {
                var serviceName       = info.Attributes.GetValue("name");
                var group             = info.Attributes.GetValue("group");
                var isPublic          = info.Attributes.GetBool("public");
                var isAssign          = info.Attributes.GetBool("assign");
                var title             = info.Attributes.GetValueOrDefault("title", null);
                var iconPath          = info.Attributes.GetValueOrDefault("icon", null);
                var input             = info.Attributes.GetValueOrDefault("color", null);
                var articleFolderPath = info.Attributes.GetValueOrDefault("articles", null);

                MissionListingServer server;
                if (iconPath == null || input == null)
                {
                    server = result.AddDaemon <MissionListingServer>(serviceName, group, os, isPublic, isAssign);
                }
                else
                {
                    server = result.AddDaemon <MissionListingServer>(
                        serviceName,
                        iconPath,
                        articleFolderPath,
                        Utils.convertStringToColor(input),
                        os,
                        isPublic,
                        isAssign
                        );
                }
                if (title != null)
                {
                    server.listingTitle = title;
                }
            });

            executor.AddExecutor("daemons.AddEmailServer", (exec, info) =>
                                 result.AddDaemon <AddEmailDaemon>(info.Attributes.GetValue("name"), os));

            executor.AddExecutor("daemons.MessageBoard", (exec, info) =>
            {
                var daemon  = result.AddDaemon <MessageBoardDaemon>(os);
                daemon.name = info.Attributes.GetValue("name");
                if (info.Attributes.TryGetValue("boardName", out var boardName))
                {
                    daemon.BoardName = boardName;
                }
            });

            executor.AddExecutor("daemons.WebServer", (exec, info) =>
                                 result.AddDaemon <WebServerDaemon>(info.Attributes.GetValue("name"), os,
                                                                    info.Attributes.GetValue("url")));

            executor.AddExecutor("daemons.OnlineWebServer", (exec, info) =>
            {
                var daemon = result.AddDaemon <OnlineWebServerDaemon>(info.Attributes.GetValue("name"), os);
                daemon.setURL(info.Attributes.GetValue("url"));
            });

            /* not my typo */
            executor.AddExecutor("daemons.AcademicDatabse", (exec, info) =>
                                 result.AddDaemon <AcademicDatabaseDaemon>(info.Attributes.GetValue("name"), os));

            executor.AddExecutor("daemons.MissionHubServer", (exec, info) =>
                                 result.AddDaemon <MissionHubServer>("unknown", "unknown", os));

            executor.AddExecutor("daemons.DeathRowDatabase", (exec, info) =>
                                 result.AddDaemon <DeathRowDatabaseDaemon>("Death Row Database", os));

            executor.AddExecutor("daemons.MedicalDatabase", (exec, info) =>
                                 result.AddDaemon <MedicalDatabaseDaemon>(os));

            executor.AddExecutor("daemons.HeartMonitor", (exec, info) =>
            {
                var daemon       = result.AddDaemon <HeartMonitorDaemon>(os);
                daemon.PatientID = info.Attributes.GetValueOrDefault("patient", "UNKNOWN");
            });

            executor.AddExecutor("daemons.PointClicker", (exec, info) =>
                                 result.AddDaemon <PointClickerDaemon>("Point Clicker!", os));

            executor.AddExecutor("daemons.ispSystem", (exec, info) =>
                                 result.AddDaemon <ISPDaemon>(os));

            executor.AddExecutor("daemons.porthackheart", (exec, info) =>
                                 result.AddDaemon <PorthackHeartDaemon>(os));

            executor.AddExecutor("daemons.SongChangerDaemon", (exec, info) =>
                                 result.AddDaemon <SongChangerDaemon>(os));

            executor.AddExecutor("daemons.UploadServerDaemon", (exec, info) =>
            {
                var daemon = result.AddDaemon <UploadServerDaemon>(
                    info.Attributes.GetValueOrDefault("name", ""),
                    Utility.GetColorFromString(info.Attributes.GetValue("color"), Color.White),
                    os,
                    info.Attributes.GetValueOrDefault("foldername", ""),
                    info.Attributes.GetBool("needsAuh")
                    );

                daemon.hasReturnViewButton = info.Attributes.GetBool("hasReturnViewButton");
            });

            executor.AddExecutor("daemons.DHSDaemon", (exec, info) =>
                                 result.AddDaemon <DLCHubServer>("unknown", "unknown", os));

            executor.AddExecutor("daemons.CustomConnectDisplayDaemon", (exec, info) =>
                                 result.AddDaemon <CustomConnectDisplayDaemon>(os));

            executor.AddExecutor("daemons.DatabaseDaemon", (exec, info) =>
            {
                var daemon = new DatabaseDaemon(result,
                                                os,
                                                info.Attributes.GetValueOrDefault("Name", null),
                                                info.Attributes.GetValueOrDefault("Permissions", null),
                                                info.Attributes.GetValueOrDefault("DataType", null),
                                                info.Attributes.GetValueOrDefault("Foldername", null),
                                                Utility.GetColorFromString(info.Attributes.GetValueOrDefault("Color", null), true, null)
                                                );

                result.daemons.Add(daemon);

                var AdminEmailAccount = info.Attributes.GetValue("AdminEmailAccount");

                var adminEmailAccount = info.Attributes.GetValue("AdminEmailAccount");

                if (string.IsNullOrWhiteSpace(adminEmailAccount))
                {
                    return;
                }
                daemon.adminResetPassEmailAccount = adminEmailAccount;
                daemon.adminResetEmailHostID      = info.Attributes.GetValue("AdminEmailHostID");
            });

            executor.AddExecutor("daemons.WhiteListAuthenticatorDaemon", (exec, info) =>
            {
                var daemon = result.AddDaemon <WhitelistConnectionDaemon>(os);
                daemon.AuthenticatesItself = info.Attributes.GetBool("SelfAuthenticating");
            });

            executor.AddExecutor("daemons.IRCDaemon", (exec, info) =>
                                 result.AddDaemon <IRCDaemon>(os, "LOAD ERROR"));


            executor.AddExecutor("daemons.MarkovTextDaemon", (exec, info) =>
                                 result.AddDaemon <MarkovTextDaemon>(
                                     os,
                                     info.Attributes.GetValue("Name"),
                                     info.Attributes.GetValue("SourceFilesContentFolder")
                                     )
                                 );

            executor.AddExecutor("daemons.AircraftDaemon", (exec, info) =>
            {
                var srcVec = Vector2.Zero;
                var dstVec = Vector2.One * 0.5f;
                if (info.Attributes.ContainsKey("OriginX"))
                {
                    srcVec.X = info.Attributes.GetFloat("OriginX");
                }
                if (info.Attributes.ContainsKey("OriginY"))
                {
                    srcVec.Y = info.Attributes.GetFloat("OriginY");
                }

                if (info.Attributes.ContainsKey("DestX"))
                {
                    dstVec.X = info.Attributes.GetFloat("DestX");
                }
                if (info.Attributes.ContainsKey("DestY"))
                {
                    dstVec.Y = info.Attributes.GetFloat("DestY");
                }

                result.AddDaemon <AircraftDaemon>(
                    os,
                    info.Attributes.GetValueOrDefault("Name", "Pacific Charter Flight"),
                    srcVec,
                    dstVec,
                    info.Attributes.GetFloat("Progress", .5f)
                    );
            });

            executor.AddExecutor("daemons.LogoCustomConnectDisplayDaemon", (exec, info) =>
                                 result.AddDaemon <LogoCustomConnectDisplayDaemon>(
                                     os,
                                     info.Attributes.GetValueOrDefault("logo", null),
                                     info.Attributes.GetValueOrDefault("title", null),
                                     info.Attributes.GetBool("overdrawLogo"),
                                     info.Attributes.GetValueOrDefault("buttonAlignment", null)
                                     )
                                 );

            executor.AddExecutor("daemons.LogoDaemon", (exec, info) =>
            {
                var daemon = result.AddDaemon <LogoDaemon>(
                    os,
                    result.name,
                    info.Attributes.GetBool("ShowsTitle", true),
                    info.Attributes.GetValueOrDefault("LogoImagePath", null)
                    );

                daemon.TextColor = Utility.GetColorFromString(info.Attributes.GetValue("TextColor"), Color.White);
            });

            executor.AddExecutor("daemons.DLCCredits", (exec, info) =>
            {
                var overrideButtonText = info.Attributes.GetValueOrDefault("Button", null);
                var overrideTitle      = info.Attributes.GetValueOrDefault("Title", null);
                DLCCreditsDaemon daemon;
                if (overrideButtonText == null && overrideTitle == null)
                {
                    daemon = result.AddDaemon <DLCCreditsDaemon>(os);
                }
                else
                {
                    daemon = result.AddDaemon <DLCCreditsDaemon>(os, overrideTitle, overrideButtonText);
                }
                if (info.Attributes.TryGetValue("Action", out var buttonAction))
                {
                    daemon.ConditionalActionsToLoadOnButtonPress = buttonAction;
                }
            });

            executor.AddExecutor("daemon.FastActionHost", (exec, info) =>
                                 result.AddDaemon <FastActionHost>(os, result.name));

            #endregion

            executor.AddExecutor("filesystem", (exec, info) =>
            {
                var rootInfo = info.Children.FirstOrDefault(e => e.Name == "folder");
                if (rootInfo == null)
                {
                    /* TODO: Error reporting */
                }

                result.files = new FileSystem(true)
                {
                    root = LoadFolder(rootInfo)
                };
            }, true);

            foreach (var exec in ComputerLoaders)
            {
                executor.AddExecutor(exec.Key, exec.Value);
            }

            executor.Execute(root);

            if (compSpec == "mail")
            {
                os.netMap.mailServer = result;
            }
            if (compSpec == "player")
            {
                os.thisComputer = result;
            }
            return(result);
        }