// Entry with controller state Validated or in a running state after a game load
        // Exit with InitializationError (false) on error
        // Ok (true) if ready for game play
        // Hybernating (true) if system is ok and no frame updates are required
        public override bool                Initialize()
        {
            // Default class method for sub-classes which don't require initialization
            var errors        = false;
            var stringBuilder = new StringBuilder();

            CCL_Log.CaptureBegin(stringBuilder);

            var miniMapDefs = DefDatabase <MiniMap.MiniMapDef> .AllDefsListForReading;

            foreach (var miniMapDef in miniMapDefs)
            {
                var miniMapWorker = (MiniMap.MiniMap)Activator.CreateInstance(miniMapDef.miniMapClass, new System.Object[] { miniMapDef });
                if (miniMapWorker == null)
                {
                    CCL_Log.Trace(
                        Verbosity.NonFatalErrors,
                        string.Format("Unable to create instance of '{0}' for '{1}'", miniMapDef.miniMapClass.Name, miniMapDef.defName)
                        );
                    errors = true;
                }
                else
                {
                    Controller.Data.MiniMaps.Add(miniMapWorker);
                }
            }

            CCL_Log.CaptureEnd(stringBuilder, !errors ? "Initialized" : "Errors during intialization");
            strReturn = stringBuilder.ToString();

            State = errors ? SubControllerState.InitializationError : SubControllerState.Ok;
            return(!errors);
        }
        public override bool                Initialize()
        {
            // Don't auto-gen help if "quicktest" or "nohelp" command line switches are used
            if (
                (!GenCommandLine.CommandLineArgPassed("quicktest")) &&
                (!GenCommandLine.CommandLineArgPassed("nohelp"))
                )
            {
                LongEventHandler.SetCurrentEventText("LibraryHelpGen".Translate());

                var stringBuilder = new StringBuilder();
                CCL_Log.CaptureBegin(stringBuilder);

                var startTime = DateTime.Now;

                if (!HelpBuilder.ResolveImpliedDefs())
                {
                    strReturn = "Unexpected error in HelpBuilder.ResolveImpliedDefs()";
                    State     = SubControllerState.InitializationError;
                    return(false);
                }

                var finishTime = DateTime.Now;
                var finalTime  = finishTime - startTime;

                CCL_Log.CaptureEnd(stringBuilder, string.Format("Completed in {0}", finalTime.ToString()));
                CCL_Log.Message(stringBuilder.ToString(), "Help System");

                LongEventHandler.SetCurrentEventText("Initializing".Translate());
            }
            strReturn = "Initialized";
            State     = SubControllerState.Hybernating;
            return(true);
        }
        public override bool                Update()
        {
            var stringBuilder = new StringBuilder();

            CCL_Log.CaptureBegin(stringBuilder);

            foreach (var injector in updateInjectors)
            {
                // Inject the group into the system
                if (!Inject(injector))
                {
                    CCL_Log.CaptureEnd(stringBuilder, "Errors during injection");
                    strReturn = stringBuilder.ToString();
                    State     = SubControllerState.InitializationError;
                    return(false);
                }
#if DEBUG
                CCL_Log.Trace(
                    Verbosity.Injections,
                    injector.InjectString
                    );
#endif
            }

            // Post-load injections complete, stop calling this
            CCL_Log.CaptureEnd(stringBuilder, "Updated");
            strReturn = stringBuilder.ToString();
            State     = SubControllerState.Hybernating;
            return(true);
        }
        public override bool                Initialize()
        {
            LongEventHandler.SetCurrentEventText("LibraryInjection".Translate());

            var stringBuilder = new StringBuilder();

            CCL_Log.CaptureBegin(stringBuilder);

            // Initialize preload-MCMs
            if (!MCMHost.InitializeHosts(true))
            {
                CCL_Log.CaptureEnd(stringBuilder, "Errors initializing Mod Configuration Menus");
                strReturn = stringBuilder.ToString();
                State     = SubControllerState.InitializationError;
                return(false);
            }

            foreach (var injector in initInjectors)
            {
                // Inject the group into the system
                if (!Inject(injector))
                {
                    CCL_Log.CaptureEnd(stringBuilder, "Errors during injection");
                    strReturn = stringBuilder.ToString();
                    State     = SubControllerState.InitializationError;
                    return(false);
                }
#if DEBUG
                CCL_Log.Trace(
                    Verbosity.Injections,
                    injector.InjectString
                    );
#endif
            }

            MHD_Facilities.ReResolveDefs();

            // Everything's ok for updates
            CCL_Log.CaptureEnd(
                stringBuilder,
                "Initialized"
                );
            strReturn = stringBuilder.ToString();
            State     = SubControllerState.Ok;

            LongEventHandler.SetCurrentEventText("Initializing".Translate());

            return(true);
        }
Exemple #5
0
        // Validate ModHelperDefs, CCL load order, CCL versioning
        public override bool Validate()
        {
            // Hopefully...
            var stringBuilder = new StringBuilder();
            var rVal          = true;

            CCL_Log.CaptureBegin(stringBuilder);

            // Limit one ModHelperDef per mod
            // Create the ordered list by inserting dummies for mods which don't have one
            var allMods = LoadedModManager.LoadedMods.ToList();

            // Find Core and CCL in the mod order
            coreModIndex = -1;
            cclModIndex  = -1;
            for (int i = 0; i < allMods.Count; ++i)
            {
                LoadedMod mod = allMods[i];
                if (mod.name == "Core")
                {
                    coreModIndex = i;
                }
                if (mod.name == Controller.Data.UnityObjectName)
                {
                    cclModIndex = i;
                }
            }
            if (coreModIndex == -1)
            {
                LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow);
                stringBuilder.AppendLine("\tUnable to find 'Core' in mod load order!");
                //rVal = false; // Don't throw as an error, will be caught special
            }
            else if (coreModIndex != 0)
            {
                LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow);
                stringBuilder.AppendLine("\t'Core' must be first in mod load order!");
                //rVal = false; // Don't throw as an error, will be caught special
            }
            if (cclModIndex == -1)
            {
                LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow);
                stringBuilder.Append("\tUnable to find '");
                stringBuilder.Append(Controller.Data.UnityObjectName);
                stringBuilder.AppendLine("' in mod load order!");
                //rVal = false; // Don't throw as an error, will be caught special
            }
            else if (cclModIndex != 1)
            {
                LongEventHandler.ExecuteWhenFinished(ShowLoadOrderWindow);
                stringBuilder.Append("\t'");
                stringBuilder.Append(Controller.Data.UnityObjectName);
                stringBuilder.AppendLine("' must be second in mod load order, immediately after 'Core'! :: Current position is #" + (cclModIndex + 1).ToString());
                //rVal = false; // Don't throw as an error, will be caught special
            }
            if (rVal)
            {
                for (int i = 0; i < allMods.Count; i++)
                {
                    var modHelperDef  = (ModHelperDef)null;
                    var mod           = allMods[i];
                    var modHelperDefs = Find_Extensions.DefListOfTypeForMod <ModHelperDef>(mod);
                    if (!modHelperDefs.NullOrEmpty())
                    {
                        if (modHelperDefs.Count > 1)
                        {
                            stringBuilder.Append("\t" + mod.name);
                            CCL_Log.AppendSectionNewLine(ref stringBuilder, "Multiple ModHelperDefs detected");
                            rVal = false;
                        }
                        else
                        {
                            // Validate the def
                            modHelperDef = modHelperDefs.First();
                            if (!modHelperDef.IsValid)
                            {
                                // Don't do anything special with broken mods
                                stringBuilder.Append("\t" + mod.name);
                                CCL_Log.AppendSectionNewLine(ref stringBuilder, "ModHelperDef is invalid");
                                rVal = false;
                            }
                            else if (!modHelperDef.dummy)
                            {
                                // Don't show validation message for dummy defs
                                stringBuilder.Append("\t" + mod.name);
                                CCL_Log.AppendSection(ref stringBuilder, "ModHelperDef");
                                CCL_Log.AppendSectionNewLine(ref stringBuilder, "Passed validation, requesting v" + modHelperDef.minCCLVersion);
                            }
                        }
                    }
                    else if (rVal == true)
                    {
                        // Doesn't exist, create a dummy for logging but only
                        // create if we're not just checking for remaining errors
                        modHelperDef               = new ModHelperDef();
                        modHelperDef.defName       = mod.name + "_ModHelperDef";
                        modHelperDef.minCCLVersion = Version.Minimum.ToString();
                        modHelperDef.ModName       = mod.name;
                        modHelperDef.Verbosity     = Verbosity.NonFatalErrors;
                        modHelperDef.dummy         = true;
                    }
                    if (rVal == true)
                    {
                        // No errors, def is valid or a dummy
                        // Associate the def with the mod (the dictionary is to go the other way)
                        modHelperDef.mod = mod;
                        // Insert it into it's ordered place in the lists
                        Controller.Data.Mods.Insert(i, mod);
                        Controller.Data.ModHelperDefs.Insert(i, modHelperDef);
                        // Add a dictionary entry
                        Controller.Data.DictModHelperDefs.Add(mod, modHelperDef);
                    }
                }
                // Should now be a complete pair of lists in mod load order
                // as well as a dictionary of mods and their defs

#if DEVELOPER
                //Dump ordered list of mods and their defs
                string dump = "Mod load order:\n";
                for (int i = 0; i < Controller.Data.Mods.Count; i++)
                {
                    dump += "\t[" + i + "] - " + Controller.Data.Mods[i].name + " - " + Controller.Data.ModHelperDefs[i].defName + (Controller.Data.ModHelperDefs[i].dummy ? " - dummy" : "") + "\n";
                }
                CCL_Log.Write(dump);
#endif
                if (rVal)
                {
                    LoadedMod    CCL_Mod       = Controller.Data.Mods[cclModIndex];
                    ModHelperDef CCL_HelperDef = Find_Extensions.ModHelperDefForMod(CCL_Mod);

                    // Validate xml version with assembly version
                    var vc = Version.Compare(CCL_HelperDef.minCCLVersion);
                    if (vc != Version.VersionCompare.ExactMatch)
                    {
                        stringBuilder.AppendLine("\tModHelperDef version mismatch for Community Core Library!");
                        rVal = false;
                    }

                    // CCL rank is #2 in load order and def version matches library
                    Controller.Data.cclMod       = CCL_Mod;
                    Controller.Data.cclHelperDef = CCL_HelperDef;
                }
            }

            // Should be all good or up until the first error encountered
            CCL_Log.CaptureEnd(
                stringBuilder,
                rVal ? "Validated" : "Errors during validation"
                );
            strReturn = stringBuilder.ToString();

            // Return true if all mods OK, false if any failed validation
            State = rVal ? SubControllerState.Validated : SubControllerState.ValidationError;
            return(rVal);
        }
        // Entry with controller state Uninitialized
        // Exit with ValidationError (false) on error
        // Validated (true) if ready for initialization
        public override bool                Validate()
        {
            var errors        = false;
            var stringBuilder = new StringBuilder();

            CCL_Log.CaptureBegin(stringBuilder);

            var miniMapDefs = DefDatabase <MiniMap.MiniMapDef> .AllDefsListForReading;

            foreach (var miniMapDef in miniMapDefs)
            {
                if (
                    (miniMapDef.miniMapClass == null) ||
                    (
                        (miniMapDef.miniMapClass != typeof(MiniMap.MiniMap)) &&
                        (!miniMapDef.miniMapClass.IsSubclassOf(typeof(MiniMap.MiniMap)))
                    )
                    )
                {
                    CCL_Log.Trace(
                        Verbosity.NonFatalErrors,
                        string.Format("Unable to resolve miniMapClass for '{0}' to 'CommunityCoreLibrary.MiniMap'", miniMapDef.defName)
                        );
                    errors = true;
                }
                else
                {
                    // Make sure the minimap def has a list of overlay defs
                    if (miniMapDef.overlays == null)
                    {
                        miniMapDef.overlays = new List <MiniMap.MiniMapOverlayDef>();
                    }
                    // Fetch any overlays which may want to add-in
                    var overlayDefs =
                        DefDatabase <MiniMap.MiniMapOverlayDef>
                        .AllDefs
                        .Where(overlayDef => (
                                   (overlayDef.miniMapDef != null) &&
                                   (overlayDef.miniMapDef == miniMapDef)
                                   ));

                    if (overlayDefs.Count() > 0)
                    {   // Add-in the overlay defs
                        foreach (var overlayDef in overlayDefs)
                        {
                            miniMapDef.overlays.AddUnique(overlayDef);
                        }
                    }
                    if (miniMapDef.overlays.NullOrEmpty() && !miniMapDef.dynamicOverlays)
                    {
                        CCL_Log.Trace(
                            Verbosity.NonFatalErrors,
                            string.Format("MiniMap '{0}' has no overlays", miniMapDef.defName)
                            );
                        errors = true;
                    }
                }
            }

            CCL_Log.CaptureEnd(stringBuilder, !errors ? "Validated" : "Errors during validation");
            strReturn = stringBuilder.ToString();

            State = errors ? SubControllerState.ValidationError : SubControllerState.Validated;
            return(!errors);
        }
Exemple #7
0
        // Validate ...research...?
        public override bool                Validate()
        {
            // Hopefully...
            var stringBuilder = new StringBuilder();
            var rVal          = true;

            CCL_Log.CaptureBegin(stringBuilder);

            var AdvancedResearchDefs = Controller.Data.AdvancedResearchDefs;

            // Make sure the hidden research exists
            if (CommunityCoreLibrary.Research.Locker == null)
            {
                CCL_Log.Trace(Verbosity.FatalErrors, "Missing research locker!");
                rVal = false;
            }

            // Validate each advanced research def
            for (int index = AdvancedResearchDefs.Count - 1; index >= 0; index--)
            {
                var advancedResearchDef = AdvancedResearchDefs[index];

                if (!advancedResearchDef.IsValid())
                {
                    // Remove projects with errors from list of usable projects
                    AdvancedResearchDefs.Remove(advancedResearchDef);
                    rVal = false;
                    continue;
                }

                if (advancedResearchDef.IsLockedOut())
                {
                    // Remove locked out projects
                    CCL_Log.TraceMod(
                        advancedResearchDef,
                        Verbosity.Warnings,
                        "Def is locked out by one or more research prerequisites");
                    AdvancedResearchDefs.Remove(advancedResearchDef);
                    continue;
                }
            }

#if DEBUG
            if (rVal == true)
            {
                var allMods = Controller.Data.Mods;
                foreach (var mod in allMods)
                {
                    if (!Find_Extensions.DefListOfTypeForMod <AdvancedResearchDef>(mod).NullOrEmpty())
                    {
                        CCL_Log.TraceMod(
                            mod,
                            Verbosity.Validation,
                            "Passed validation"
                            );
                    }
                }
            }
#endif

            // Should be empty or a laundry list
            CCL_Log.CaptureEnd(
                stringBuilder,
                rVal ? "Validated" : "Errors during validation"
                );
            strReturn = stringBuilder.ToString();

            // Return true if all mods OK, false if any failed validation
            State = rVal ? SubControllerState.Validated : SubControllerState.ValidationError;
            return(rVal);
        }
Exemple #8
0
        internal static void                PreLoad()
        {
            // This is a pre-start sequence to hook some deeper level functions.
            // These functions can be hooked later but it would be after the sequence
            // of operations which call them is complete.

#if DEVELOPER
            // Open a log file for CCL specific output
            // https://www.youtube.com/watch?v=jyaLZHiJJnE
            if (CCL_Log.OpenStream() == null)
            {
                Log.Error(string.Format("Unable to open file stream for {0}!", Controller.Data.UnityObjectName));
            }
#endif

            // Log CCL version
            Version.Log();

            bool InjectionsOk  = true;
            var  stringBuilder = new StringBuilder();
            CCL_Log.CaptureBegin(stringBuilder);

            // Find all sub-controllers
            var subControllerClasses = typeof(SubController).AllSubclasses();
            var subControllerCount   = subControllerClasses.Count();
            if (subControllerCount == 0)
            {
                InjectionsOk = false;
                CCL_Log.Error(
                    "Unable to find sub-controllers",
                    "PreLoader"
                    );
            }

            // Create sub-controllers
            if (InjectionsOk)
            {
                var subControllers = new SubController[subControllerCount];
                for (int index = 0; index < subControllerCount; ++index)
                {
                    var subControllerType = subControllerClasses.ElementAt(index);
                    var subController     = (SubController)Activator.CreateInstance(subControllerType);
                    if (subController == null)
                    {
                        CCL_Log.Error(
                            string.Format("Unable to create sub-controller {0}", subControllerType.Name),
                            "PreLoader"
                            );
                        InjectionsOk = false;
                        break;
                    }
                    else
                    {
                        subControllers[index] = subController;
                    }
                }
                if (InjectionsOk)
                {
                    Controller.Data.SubControllers = subControllers;
                }
            }

            // Detour Verse.PlayDataLoader.LoadAllPlayData
            if (InjectionsOk)
            {
                MethodInfo Verse_PlayDataLoader_LoadAllPlayData = typeof(PlayDataLoader).GetMethod("LoadAllPlayData", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_PlayDataLoader_LoadAllPlayData   = typeof(Detour._PlayDataLoader).GetMethod("_LoadAllPlayData", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_PlayDataLoader_LoadAllPlayData, CCL_PlayDataLoader_LoadAllPlayData);
            }

            // Detour Verse.PlayDataLoader.ClearAllPlayData
            if (InjectionsOk)
            {
                MethodInfo Verse_PlayDataLoader_ClearAllPlayData = typeof(PlayDataLoader).GetMethod("ClearAllPlayData", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_PlayDataLoader_ClearAllPlayData   = typeof(Detour._PlayDataLoader).GetMethod("_ClearAllPlayData", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_PlayDataLoader_ClearAllPlayData, CCL_PlayDataLoader_ClearAllPlayData);
            }

            // Detour Verse.UIRoot_Entry.ShouldDoMainMenu_get
            if (InjectionsOk)
            {
                PropertyInfo Verse_UIRoot_Entry_ShouldDoMainMenu     = typeof(UIRoot_Entry).GetProperty("ShouldDoMainMenu", BindingFlags.Instance | BindingFlags.NonPublic);
                MethodInfo   Verse_UIRoot_Entry_ShouldDoMainMenu_get = Verse_UIRoot_Entry_ShouldDoMainMenu.GetGetMethod(true);
                MethodInfo   CCL_UIRoot_Entry_ShouldDoMainMenu_get   = typeof(Detour._UIRoot_Entry).GetMethod("_ShouldDoMainMenu_get", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_UIRoot_Entry_ShouldDoMainMenu_get, CCL_UIRoot_Entry_ShouldDoMainMenu_get);
            }

            // Detour RimWorld.MainMenuDrawer.MainMenuOnGUI
            if (InjectionsOk)
            {
                MethodInfo RimWorld_MainMenuDrawer_MainMenuOnGUI = typeof(MainMenuDrawer).GetMethod("MainMenuOnGUI", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_MainMenuDrawer_MainMenuOnGUI      = typeof(Detour._MainMenuDrawer).GetMethod("_MainMenuOnGUI", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_MainMenuDrawer_MainMenuOnGUI, CCL_MainMenuDrawer_MainMenuOnGUI);
            }

            // Detour RimWorld.MainMenuDrawer.DoMainMenuButtons
            if (InjectionsOk)
            {
                MethodInfo RimWorld_MainMenuDrawer_DoMainMenuButtons = typeof(MainMenuDrawer).GetMethod("DoMainMenuButtons", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_MainMenuDrawer_DoMainMenuButtons      = typeof(Detour._MainMenuDrawer).GetMethod("_DoMainMenuButtons", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_MainMenuDrawer_DoMainMenuButtons, CCL_MainMenuDrawer_DoMainMenuButtons);
            }

            // Detour RimWorld.VersionControl.DrawInfoInCorner
            if (InjectionsOk)
            {
                MethodInfo RimWorld_VersionControl_DrawInfoInCorner = typeof(VersionControl).GetMethod("DrawInfoInCorner", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_VersionControl_DrawInfoInCorner      = typeof(Detour._VersionControl).GetMethod("_DrawInfoInCorner", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_VersionControl_DrawInfoInCorner, CCL_VersionControl_DrawInfoInCorner);
            }

            // Detour Verse.PostLoadInitter.DoAllPostLoadInits

            /*
             * if( InjectionsOk )
             * {
             *  MethodInfo Verse_PostLoadInitter_DoAllPostLoadInits = typeof( PostLoadInitter ).GetMethod( "DoAllPostLoadInits", BindingFlags.Static | BindingFlags.Public );
             *  MethodInfo CCL_PostLoadInitter_DoAllPostLoadInits = typeof( Detour._PostLoadInitter ).GetMethod( "_DoAllPostLoadInits", BindingFlags.Static | BindingFlags.NonPublic );
             *  InjectionsOk &= Detours.TryDetourFromTo( Verse_PostLoadInitter_DoAllPostLoadInits, CCL_PostLoadInitter_DoAllPostLoadInits );
             * }
             */

            if (InjectionsOk)
            {
                LongEventHandler.ExecuteWhenFinished(CreateMonoBehaviour);
            }

            CCL_Log.CaptureEnd(
                stringBuilder,
                InjectionsOk ? "Initialized" : "Errors during injection"
                );
            CCL_Log.Trace(
                Verbosity.Injections,
                stringBuilder.ToString(),
                "PreLoader");

            initOk = InjectionsOk;
        }
Exemple #9
0
        private static void                 PreLoad()
        {
            // This is a pre-start sequence to hook some deeper level functions.
            // These functions can be hooked later but it would be after the sequence
            // of operations which call them is complete.

            // Log CCL version
            Version.Log();

            bool          InjectionsOk  = true;
            StringBuilder stringBuilder = new StringBuilder();

            CCL_Log.CaptureBegin(stringBuilder);

            // Find all sub-controllers
            var subControllerClasses = typeof(SubController).AllSubclasses();
            var subControllerCount   = subControllerClasses.Count();

            if (subControllerCount == 0)
            {
                InjectionsOk = false;
                CCL_Log.Error(
                    "Unable to find sub-controllers",
                    "PreLoader"
                    );
            }

            // Create sub-controllers
            if (InjectionsOk)
            {
                var subControllers = new SubController[subControllerCount];
                for (int index = 0; index < subControllerCount; ++index)
                {
                    var subControllerType = subControllerClasses.ElementAt(index);
                    var subController     = (SubController)Activator.CreateInstance(subControllerType);
                    if (subController == null)
                    {
                        CCL_Log.Error(
                            string.Format("Unable to create sub-controller {0}", subControllerType.Name),
                            "PreLoader"
                            );
                        InjectionsOk = false;
                        break;
                    }
                    else
                    {
                        subControllers[index] = subController;
                    }
                }
                if (InjectionsOk)
                {
                    Controller.Data.SubControllers = subControllers;
                }
            }

            // Detour Verse.PlayDataLoader.LoadAllPlayData
            if (InjectionsOk)
            {
                MethodInfo Verse_PlayDataLoader_LoadAllPlayData = typeof(PlayDataLoader).GetMethod("LoadAllPlayData", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_PlayDataLoader_LoadAllPlayData   = typeof(Detour._PlayDataLoader).GetMethod("_LoadAllPlayData", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_PlayDataLoader_LoadAllPlayData, CCL_PlayDataLoader_LoadAllPlayData);
            }

            // Detour Verse.PlayDataLoader.ClearAllPlayData
            if (InjectionsOk)
            {
                MethodInfo Verse_PlayDataLoader_ClearAllPlayData = typeof(PlayDataLoader).GetMethod("ClearAllPlayData", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_PlayDataLoader_ClearAllPlayData   = typeof(Detour._PlayDataLoader).GetMethod("_ClearAllPlayData", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_PlayDataLoader_ClearAllPlayData, CCL_PlayDataLoader_ClearAllPlayData);
            }

            // Detour Verse.UIRoot_Entry.ShouldShowMainMenuGUI_get
            if (InjectionsOk)
            {
                PropertyInfo Verse_UIRoot_Entry_ShouldShowMainMenuGUI     = typeof(UIRoot_Entry).GetProperty("ShouldShowMainMenuGUI", BindingFlags.Instance | BindingFlags.NonPublic);
                MethodInfo   Verse_UIRoot_Entry_ShouldShowMainMenuGUI_get = Verse_UIRoot_Entry_ShouldShowMainMenuGUI.GetGetMethod(true);
                MethodInfo   CCL_UIRoot_Entry_ShouldShowMainMenuGUI_get   = typeof(Detour._UIRoot_Entry).GetMethod("_ShouldShowMainMenuGUI_get", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(Verse_UIRoot_Entry_ShouldShowMainMenuGUI_get, CCL_UIRoot_Entry_ShouldShowMainMenuGUI_get);
            }

            // Detour RimWorld.MainMenuDrawer.MainMenuOnGUI
            if (InjectionsOk)
            {
                MethodInfo RimWorld_MainMenuDrawer_MainMenuOnGUI = typeof(MainMenuDrawer).GetMethod("MainMenuOnGUI", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_MainMenuDrawer_MainMenuOnGUI      = typeof(Detour._MainMenuDrawer).GetMethod("_MainMenuOnGUI", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_MainMenuDrawer_MainMenuOnGUI, CCL_MainMenuDrawer_MainMenuOnGUI);
            }

            // Detour RimWorld.MainMenuDrawer.DoMainMenuButtons
            if (InjectionsOk)
            {
                MethodInfo RimWorld_MainMenuDrawer_DoMainMenuButtons = typeof(MainMenuDrawer).GetMethod("DoMainMenuButtons", BindingFlags.Static | BindingFlags.Public);
                MethodInfo CCL_MainMenuDrawer_DoMainMenuButtons      = typeof(Detour._MainMenuDrawer).GetMethod("_DoMainMenuButtons", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_MainMenuDrawer_DoMainMenuButtons, CCL_MainMenuDrawer_DoMainMenuButtons);
            }

            // Detour RimWorld.BiomeDef.CommonalityOfAnimal
            if (InjectionsOk)
            {
                MethodInfo RimwWorld_BiomeDef_CommonalityOfAnimal = typeof(BiomeDef).GetMethod("CommonalityOfAnimal", BindingFlags.Instance | BindingFlags.Public);
                MethodInfo CCL_BiomeDef_CommonalityOfAnimal       = typeof(Detour._BiomeDef).GetMethod("_CommonalityOfAnimal", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimwWorld_BiomeDef_CommonalityOfAnimal, CCL_BiomeDef_CommonalityOfAnimal);
            }

            // Detour RimWorld.BiomeDef.CommonalityOfPlant
            if (InjectionsOk)
            {
                MethodInfo RimwWorld_BiomeDef_CommonalityOfPlant = typeof(BiomeDef).GetMethod("CommonalityOfPlant", BindingFlags.Instance | BindingFlags.Public);
                MethodInfo CCL_BiomeDef_CommonalityOfPlant       = typeof(Detour._BiomeDef).GetMethod("_CommonalityOfPlant", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimwWorld_BiomeDef_CommonalityOfPlant, CCL_BiomeDef_CommonalityOfPlant);
            }
            // Detour RimWorld.BiomeDef.MTBDaysOfDisease
            if (InjectionsOk)
            {
                MethodInfo RimWorld_BiomeDef_MTBDaysOfDisease = typeof(BiomeDef).GetMethod("MTBDaysOfDisease", BindingFlags.Instance | BindingFlags.Public);
                MethodInfo CCL_BiomeDef_MTBDaysOfDisease      = typeof(Detour._BiomeDef).GetMethod("_MTBDaysOfDisease", BindingFlags.Static | BindingFlags.NonPublic);
                InjectionsOk &= Detours.TryDetourFromTo(RimWorld_BiomeDef_MTBDaysOfDisease, CCL_BiomeDef_MTBDaysOfDisease);
            }

            // Detour Verse.PostLoadInitter.DoAllPostLoadInits

            /*
             * if( InjectionsOk )
             * {
             *  MethodInfo Verse_PostLoadInitter_DoAllPostLoadInits = typeof( PostLoadInitter ).GetMethod( "DoAllPostLoadInits", BindingFlags.Static | BindingFlags.Public );
             *  MethodInfo CCL_PostLoadInitter_DoAllPostLoadInits = typeof( Detour._PostLoadInitter ).GetMethod( "_DoAllPostLoadInits", BindingFlags.Static | BindingFlags.NonPublic );
             *  InjectionsOk &= Detours.TryDetourFromTo( Verse_PostLoadInitter_DoAllPostLoadInits, CCL_PostLoadInitter_DoAllPostLoadInits );
             * }
             */

            if (InjectionsOk)
            {
                var gameObject = new GameObject(Controller.Data.UnityObjectName);
                if (gameObject == null)
                {
                    InjectionsOk = false;
                    CCL_Log.Error(
                        "Unable to create GameObject",
                        "PreLoader"
                        );
                }
                else
                {
                    if (gameObject.AddComponent <Controller.MainMonoBehaviour>() == null)
                    {
                        InjectionsOk = false;
                        CCL_Log.Error(
                            "Unable to create MonoBehaviour",
                            "PreLoader"
                            );
                    }
                    else
                    {
                        UnityEngine.Object.DontDestroyOnLoad(gameObject);
                        Controller.Data.UnityObject = gameObject;
                    }
                }
            }

            if (InjectionsOk)
            {
                CCL_Log.Message(
                    "Queueing Library Initialization",
                    "PreLoader"
                    );
                LongEventHandler.QueueLongEvent(Initialize, "LibraryStartup", true, null);
            }

            CCL_Log.CaptureEnd(
                stringBuilder,
                InjectionsOk ? "Initialized" : "Errors during injection"
                );
            CCL_Log.Trace(
                Verbosity.Injections,
                stringBuilder.ToString(),
                "PreLoader");
        }