// 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); }
// 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); }
// 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); }
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; }
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"); }