<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Hacknet;
using Hacknet.Factions;
using Hacknet.Localization;
using Hacknet.PlatformAPI.Storage;
using Hacknet.Security;
using HarmonyLib;
using Microsoft.Xna.Framework;
using Pathfinder.Event;
using Pathfinder.Event.Loading;
using Pathfinder.Util;
using Pathfinder.Util.XML;

namespace Pathfinder.Replacements
{
    [HarmonyPatch]
    public static class SaveLoader
    {
        public abstract class SaveExecutor
        {
            public OS Os { get; private set; }

            public virtual void Init(OS os)
            {
                Os = os;
            }

            public abstract void Execute(EventExecutor exec, ElementInfo info);
        }

        private struct SaveExecutorHolder
        {
            public string Element;
            public Type ExecutorType;
            public ParseOption Options;
        }
        
        private static readonly List<SaveExecutorHolder> CustomExecutors = new List<SaveExecutorHolder>();

        public static void RegisterExecutor<T>(string element, ParseOption options = ParseOption.None) where T : SaveExecutor, new()
        {
            CustomExecutors.Add(new SaveExecutorHolder
            {
                Element = element,
                ExecutorType = typeof(T),
                Options = options
            });
        }

        public static void UnregisterExecutor<T>() where T : SaveExecutor, new()
        {
            var tType = typeof(T);
            CustomExecutors.RemoveAll(x => x.ExecutorType == tType);
        }

        private static void OnPluginUnload(Assembly pluginAsm)
        {
            var allTypes = AccessTools.GetTypesFromAssembly(pluginAsm);
            CustomExecutors.RemoveAll(x => allTypes.Contains(x.ExecutorType));
        }

        private static EventExecutor executor = new EventExecutor();
        private static OS os = null;

        static SaveLoader()
        {
            EventManager.onPluginUnload += OnPluginUnload;
            
            executor.RegisterExecutor("HacknetSave", (exec, info) =>
            {
                MissionGenerator.generationCount = info.Attributes.GetInt("generatedMissionCount", 100);
                os.username = os.defaultUser.name = info.Attributes.GetString("Username");
                os.LanguageCreatedIn = info.Attributes.GetString("Language", "en-us");
                os.IsInDLCMode = info.Attributes.GetBool("DLCMode") && Settings.EnableDLC;
                os.DisableEmailIcon = info.Attributes.GetBool("DisableMailIcon") && Settings.EnableDLC;

                if (os.LanguageCreatedIn != Settings.ActiveLocale)
                {
                    LocaleActivator.ActivateLocale(os.LanguageCreatedIn, os.content);
                    Settings.ActiveLocale = os.LanguageCreatedIn;
                }
            });
            executor.RegisterExecutor("HacknetSave.DLC", (exec, info) =>
            {
                os.IsDLCSave = true;

                os.IsInDLCMode = info.Attributes.GetBool("Active");
                os.HasLoadedDLCContent = info.Attributes.GetBool("LoadedContent");

                if (os.HasLoadedDLCContent && !DLC1SessionUpgrader.HasDLC1Installed)
                {
                    MainMenu.AccumErrors = "LOAD ERROR: Save " + os.SaveGameUserName +
                                           " is configured for Labyrinths DLC, but it is not installed on this computer.\n\n\n";
                    os.ExitScreen();
                    os.IsExiting = true;
                }
            });
            executor.RegisterExecutor("HacknetSave.DLC.Flags",
                (exec, info) => os.PreDLCFaction = info.Attributes.GetString("OriginalFaction"));
            executor.RegisterExecutor("HacknetSave.DLC.OriginalVisibleNodes",
                (exec, info) => os.PreDLCVisibleNodesCache = info.Content ?? "",
                ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.DLC.ConditionalActions",
                (exec, info) => ActionsLoader.LoadActionSets(info), 
                ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.Flags", (exec, info) =>
            {
                os.Flags.Flags.Clear();

                foreach (var flag in info.Content?.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) ?? new string[0])
                {
                    os.Flags.Flags.Add(flag
                        .Replace("[%%COMMAREPLACED%%]", ",")
                        .Replace("décrypté", "decypher"));
                }
            }, ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.NetworkMap",
                (exec, info) => { Enum.TryParse(info.Attributes.GetString("sort"), out os.netMap.SortingAlgorithm); });
            executor.RegisterExecutor("HacknetSave.NetworkMap", (exec, info) =>
            {
                foreach (var daemon in os.netMap.nodes.SelectMany(x => x.daemons))
                    daemon.loadInit();

                os.netMap.loadAssignGameNodes();
            }, ParseOption.FireOnEnd);
            executor.RegisterExecutor("HacknetSave.NetworkMap.network.computer",
                (exec, info) => { os.netMap.nodes.Add(LoadComputer(info, os)); },
                ParseOption.ParseInterior
            );<commit_msg>Load saved actions into OS<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Hacknet;
using Hacknet.Factions;
using Hacknet.Localization;
using Hacknet.PlatformAPI.Storage;
using Hacknet.Security;
using HarmonyLib;
using Microsoft.Xna.Framework;
using Pathfinder.Event;
using Pathfinder.Event.Loading;
using Pathfinder.Util;
using Pathfinder.Util.XML;

namespace Pathfinder.Replacements
{
    [HarmonyPatch]
    public static class SaveLoader
    {
        public abstract class SaveExecutor
        {
            public OS Os { get; private set; }

            public virtual void Init(OS os)
            {
                Os = os;
            }

            public abstract void Execute(EventExecutor exec, ElementInfo info);
        }

        private struct SaveExecutorHolder
        {
            public string Element;
            public Type ExecutorType;
            public ParseOption Options;
        }
        
        private static readonly List<SaveExecutorHolder> CustomExecutors = new List<SaveExecutorHolder>();

        public static void RegisterExecutor<T>(string element, ParseOption options = ParseOption.None) where T : SaveExecutor, new()
        {
            CustomExecutors.Add(new SaveExecutorHolder
            {
                Element = element,
                ExecutorType = typeof(T),
                Options = options
            });
        }

        public static void UnregisterExecutor<T>() where T : SaveExecutor, new()
        {
            var tType = typeof(T);
            CustomExecutors.RemoveAll(x => x.ExecutorType == tType);
        }

        private static void OnPluginUnload(Assembly pluginAsm)
        {
            var allTypes = AccessTools.GetTypesFromAssembly(pluginAsm);
            CustomExecutors.RemoveAll(x => allTypes.Contains(x.ExecutorType));
        }

        private static EventExecutor executor = new EventExecutor();
        private static OS os = null;

        static SaveLoader()
        {
            EventManager.onPluginUnload += OnPluginUnload;
            
            executor.RegisterExecutor("HacknetSave", (exec, info) =>
            {
                MissionGenerator.generationCount = info.Attributes.GetInt("generatedMissionCount", 100);
                os.username = os.defaultUser.name = info.Attributes.GetString("Username");
                os.LanguageCreatedIn = info.Attributes.GetString("Language", "en-us");
                os.IsInDLCMode = info.Attributes.GetBool("DLCMode") && Settings.EnableDLC;
                os.DisableEmailIcon = info.Attributes.GetBool("DisableMailIcon") && Settings.EnableDLC;

                if (os.LanguageCreatedIn != Settings.ActiveLocale)
                {
                    LocaleActivator.ActivateLocale(os.LanguageCreatedIn, os.content);
                    Settings.ActiveLocale = os.LanguageCreatedIn;
                }
            });
            executor.RegisterExecutor("HacknetSave.DLC", (exec, info) =>
            {
                os.IsDLCSave = true;

                os.IsInDLCMode = info.Attributes.GetBool("Active");
                os.HasLoadedDLCContent = info.Attributes.GetBool("LoadedContent");

                if (os.HasLoadedDLCContent && !DLC1SessionUpgrader.HasDLC1Installed)
                {
                    MainMenu.AccumErrors = "LOAD ERROR: Save " + os.SaveGameUserName +
                                           " is configured for Labyrinths DLC, but it is not installed on this computer.\n\n\n";
                    os.ExitScreen();
                    os.IsExiting = true;
                }
            });
            executor.RegisterExecutor("HacknetSave.DLC.Flags",
                (exec, info) => os.PreDLCFaction = info.Attributes.GetString("OriginalFaction"));
            executor.RegisterExecutor("HacknetSave.DLC.OriginalVisibleNodes",
                (exec, info) => os.PreDLCVisibleNodesCache = info.Content ?? "",
                ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.DLC.ConditionalActions",
                (exec, info) => os.ConditionalActions = ActionsLoader.LoadActionSets(info), 
                ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.Flags", (exec, info) =>
            {
                os.Flags.Flags.Clear();

                foreach (var flag in info.Content?.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) ?? new string[0])
                {
                    os.Flags.Flags.Add(flag
                        .Replace("[%%COMMAREPLACED%%]", ",")
                        .Replace("décrypté", "decypher"));
                }
            }, ParseOption.ParseInterior);
            executor.RegisterExecutor("HacknetSave.NetworkMap",
                (exec, info) => { Enum.TryParse(info.Attributes.GetString("sort"), out os.netMap.SortingAlgorithm); });
            executor.RegisterExecutor("HacknetSave.NetworkMap", (exec, info) =>
            {
                foreach (var daemon in os.netMap.nodes.SelectMany(x => x.daemons))
                    daemon.loadInit();

                os.netMap.loadAssignGameNodes();
            }, ParseOption.FireOnEnd);
            executor.RegisterExecutor("HacknetSave.NetworkMap.network.computer",
                (exec, info) => { os.netMap.nodes.Add(LoadComputer(info, os)); },
                ParseOption.ParseInterior
            );
{'fraction_non_alphanumeric': 0.10004564125969877, 'fraction_numerical': 0.0010953902327704244, 'mean_word_length': 1.9658906334596644, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2387256', 'n_tokens_mistral': 2845, 'n_tokens_neox': 2722, 'n_words': 525}