// Loads an Asset Pack
        private static AssetPack LoadPack(string name)
        {
            AssetPack pack = InternalLogger.HandleThrow(() => AssetLoader.LoadPack(Path.Combine(ASSETS_FOLDER, name)));

            LOGGER.Log($"- Loaded '{Path.GetFileNameWithoutExtension(name)}'");
            return(pack);
        }
        //+ HELPERS
        // Loads an assembly
        private static Assembly LoadAssembly(string name, string prefix = null)
        {
            Assembly loaded = InternalLogger.HandleThrow(() => AssemblyUtils.LoadWithSymbols(Path.Combine(ASSEM_FOLDER, name + DLL_EXTENSION)));

            if (loaded != null)
            {
                LOGGER.Log($"- {prefix ?? string.Empty}Injected '{name}'");
                MAIN_ASSEMBLIES.Add(loaded);
            }
            else
            {
                LOGGER.Log($"- Failed to Inject '{name}'");
            }

            return(loaded);
        }
        // Patches an assembly
        private static void PatchAssembly(Assembly assembly, bool late = false, Type[] ignoreLate = null)
        {
            InternalLogger.HandleThrow(() =>
            {
                if (ignoreLate != null)
                {
                    foreach (Type type in ignoreLate)
                    {
                        harmony.PatchWrapper(type);
                    }
                }

                if (late)
                {
                    harmony.LatePatchAll(assembly);
                }
                else
                {
                    harmony.PatchAll(assembly);
                }
            });

            LOGGER.Log($"- Patched '{assembly.GetName().Name}'");
        }
 private static void Awake_Prefix()
 {
     GuuCore.LOGGER.Log("Guu has been successfully loaded by the game!");
     InternalLogger.HandleThrow(GuuCore.LoadGuu);
 }
        //+ GUU INJECT
        // Loads the main system of Guu
        internal static void LoadGuu()
        {
            // Prevents the system from being loaded twice
            if (isLoaded)
            {
                LOGGER.Log(new StackTrace().ToString());
                return;
            }

            //& Removes Sentry SDK from the game
            SentrySdk sentrySdk = Object.FindObjectOfType <SentrySdk>();

            if (sentrySdk != null)
            {
                sentrySdk.Dsn = string.Empty;
                sentrySdk.GetType().GetField("_instance", BindingFlags.NonPublic | BindingFlags.Static)?.SetValue(null, null);
                sentrySdk.StopAllCoroutines();
                Application.logMessageReceived -= sentrySdk.OnLogMessageReceived;
                Object.Destroy(sentrySdk, 1);

                LOGGER.Log("Game is modded! Disabling Sentry SDK");
            }

            //& Run required system functions
            if (!CMD_ARGS.Contains("--guuLauncher") && !DEBUG)
            {
                Application.Quit();
            }

            // Generate the dynamic folders if they are not present
            foreach (string folder in DYNAMIC_FOLDERS)
            {
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
            }

            //& Starts Eden before everything else
            LogHandler.RegisterIfEmpty(LOGGER.Log, LOGGER.LogWarning, LOGGER.LogError, LOGGER.LogCritical);
            EdenUnity.Entry.EdenUnity.Init();

            // Add exceptions of types
            EdenHarmony.RegisterMethodException("SteamDLCProvider", "*");
            EdenHarmony.RegisterMethodException("EpicDLCProvider", "*");
            EdenHarmony.RegisterMethodException("DLCProvider", "*");
            EdenHarmony.RegisterMethodException("DLCDirector", "*");

            // Add exceptions of methods
            EdenHarmony.RegisterMethodException <GameContext>("Awake");

            // Add Name Resolve
            EdenHarmony.EnumNameResolve += EnumInjector.NameResolve;

            //& Starts the loading process and times it
            DateTime total = DateTime.Now;

            LOGGER.Log(LOG_MSEPARATOR);
            LOGGER.Log("GUU LOADING PROCESS STARTED");
            LOGGER.Log(LOG_SEPARATOR);

            //& Injects all assemblies, section is timed
            DateTime section = DateTime.Now;

            LOGGER.Log("[INJECTING ASSEMBLIES]");

            core     = LoadAssembly(CORE_ASSEM);
            api      = LoadAssembly(API_ASSEM);
            save     = LoadAssembly(SAVE_ASSEM);
            world    = LoadAssembly(WORLD_ASSEM);
            devTools = LoadAssembly(DEV_TOOLS_ASSEM);
            patches  = LoadAssembly(PATCHES_ASSEM);

            game = Assembly.Load("Assembly-CSharp");

            // Load Bridge Assemblies
            if (ExceptionUtils.IgnoreErrors(() => Assembly.Load(SRML_ASSEM)) != null)
            {
                srmlBridge = LoadAssembly(SRML_BRIDGE_ASSEM, "Found SRML! ");
                Loader.ModLoader.srmlLoaderBridge = srmlBridge.ObtainTypeByForce("LoaderBridge");
            }

            LOGGER.Log($"[INJECTION COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);

            //& Patches all assemblies, section is timed
            section = DateTime.Now;
            LOGGER.Log("[PATCHING ASSEMBLIES]");

            harmony = new EdenHarmony("Guu");
            if (patches != null)
            {
                PatchAssembly(patches);
            }
            if (srmlBridge != null)
            {
                PatchAssembly(srmlBridge);
            }

            LOGGER.Log($"[PATCHING COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);

            //& Loads all asset packs, section is timed
            section = DateTime.Now;
            LOGGER.Log("[LOADING ASSET PACKS]");

            guiPack = LoadPack(GUI_PACK);

            LOGGER.Log($"[LOADING COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);

            //& Loads all addon libraries
            section = DateTime.Now;
            LOGGER.Log("[LOADING ADDON LIBRARIES]");

            bool          hasAddons = false;
            DirectoryInfo addons    = new DirectoryInfo(LIBS_FOLDER);

            foreach (FileInfo file in addons.GetFiles($"*{DLL_EXTENSION}"))
            {
                hasAddons = true;

                ExceptionUtils.ThrowSuccessMessage(() =>
                {
                    Assembly loadedLib = AssemblyUtils.LoadWithSymbols(file.FullName);
                    ADDON_ASSEMBLIES.Add(loadedLib);

                    Type mainType = loadedLib.GetTypes().Single(t => t.IsSubclassOf(typeof(IAddonLoad)));

                    if (mainType == null)
                    {
                        return;
                    }

                    IAddonLoad main = Activator.CreateInstance(mainType) as IAddonLoad;
                    main?.Initialize();
                }, $"- Loaded '{file.Name}'");
            }

            if (!hasAddons)
            {
                LOGGER.Log("- No Addons were found");
            }

            LOGGER.Log($"[LOADING COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);

            //& Initializes all internal services
            section = DateTime.Now;
            LOGGER.Log("[INITIALIZING INTERNAL SERVICES]");

            GuuServices.CreateServiceObject();
            GuuServices.InitInternalServices();

            LOGGER.Log($"[INITIALIZATION COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);

            //& Finalize the loading process
            section = DateTime.Now;
            LOGGER.Log("[FINALIZING]");

            APIHandler.InitializeHandler();

            LOGGER.Log($"[FINALIZING COMPLETED] - {(DateTime.Now - section).TotalMilliseconds} ms");
            LOGGER.Log(LOG_SEPARATOR);
            LOGGER.Log($"SYSTEM IS FULLY OPERATIONAL - {(DateTime.Now - total).TotalMilliseconds} ms");
            LOGGER.Log(LOG_MSEPARATOR);

            // Marks loading completed
            isLoaded = true;

            // Finalizes
            LOGGER.Log("Starting the Mod Loader!");
            InternalLogger.HandleThrow(Loader.ModLoader.GatherMods);
        }