public void revertDetours() { if (DetourInited) { Log.Info("Reverting manual detours"); Detours.Reverse(); foreach (Detour d in Detours) { RedirectionHelper.RevertRedirect(d.OriginalMethod, d.Redirect); } Detours.Clear(); Log.Info("Reverting attribute-driven detours"); AssemblyRedirector.Revert(); Log.Info("Reverting Harmony detours"); foreach (MethodBase m in HarmonyMethodStates.Keys) { HarmonyInst.Unpatch(m, HarmonyPatchType.All, HARMONY_ID); } DetourInited = false; Log.Info("Reverting detours finished."); } }
internal void ApplyHarmonyPatches() { if (HarmonyAutoPatch) { var harmonyId = HarmonyInstancePrefix + ModIdentifier; try { if (HugsLibController.Instance.ShouldHarmonyAutoPatch(GetType().Assembly, ModIdentifier)) { HarmonyInst = HarmonyInstance.Create(harmonyId); HarmonyInst.PatchAll(GetType().Assembly); } } catch (Exception e) { HugsLibController.Logger.Error("Failed to apply Harmony patches for {0}. Exception was: {1}", harmonyId, e); } } }
private void IntegrateWithOutfitter() { try { var outfitterBillsPatcher = GenTypes.GetTypeInAnyAssembly("Outfitter.TabPatch.ITab_Bills_Patch"); if (outfitterBillsPatcher == null) { return; } Logger.Message("Adding support for Outfitter"); var outfitterPatchedMethod = outfitterBillsPatcher.GetMethod("DoListing"); var ourPrefix = typeof(BillStack_DoListing_Detour).GetMethod("Prefix"); var ourPostfix = typeof(BillStack_DoListing_Detour).GetMethod("Postfix"); HarmonyInst.Patch(outfitterPatchedMethod, new HarmonyMethod(ourPrefix), new HarmonyMethod(ourPostfix)); } catch (Exception e) { Logger.Error("Exception while trying to detect Outfitter:"); Logger.Error(e.Message); Logger.Error(e.StackTrace); } }
public void initDetours() { // TODO realize detouring with annotations if (!DetourInited) { Log.Info("Init detours"); bool detourFailed = false; try { Log.Info("Deploying Harmony patches"); #if DEBUG HarmonyInstance.DEBUG = true; #endif Assembly assembly = Assembly.GetExecutingAssembly(); HarmonyMethodStates.Clear(); // Harmony attribute-driven patching Log.Info($"Performing Harmony attribute-driven patching"); HarmonyInst = HarmonyInstance.Create(HARMONY_ID); HarmonyInst.PatchAll(assembly); foreach (Type type in assembly.GetTypes()) { object[] attributes = type.GetCustomAttributes(typeof(HarmonyPatch), true); if (attributes.Length <= 0) { continue; } foreach (object attr in attributes) { HarmonyPatch harmonyPatchAttr = (HarmonyPatch)attr; MethodBase info = HarmonyUtil.GetOriginalMethod(harmonyPatchAttr.info); IntPtr ptr = info.MethodHandle.GetFunctionPointer(); RedirectCallsState state = RedirectionHelper.GetState(ptr); HarmonyMethodStates[info] = state; } } // Harmony manual patching Log.Info($"Performing Harmony manual patching"); foreach (ManualHarmonyPatch manualPatch in ManualHarmonyPatches) { Log.Info($"Manually patching method {manualPatch.method.DeclaringType.FullName}.{manualPatch.method.Name}. Prefix: {manualPatch.prefix?.method}, Postfix: {manualPatch.postfix?.method}, Transpiler: {manualPatch.transpiler?.method}"); HarmonyInst.Patch(manualPatch.method, manualPatch.prefix, manualPatch.postfix, manualPatch.transpiler); IntPtr ptr = manualPatch.method.MethodHandle.GetFunctionPointer(); RedirectCallsState state = RedirectionHelper.GetState(ptr); HarmonyMethodStates[manualPatch.method] = state; } } catch (Exception e) { Log.Error("Could not deploy Harmony patches"); Log.Info(e.ToString()); Log.Info(e.StackTrace); detourFailed = true; } try { Log.Info("Deploying attribute-driven detours"); DetouredMethodStates = AssemblyRedirector.Deploy(); } catch (Exception e) { Log.Error("Could not deploy attribute-driven detours"); Log.Info(e.ToString()); Log.Info(e.StackTrace); detourFailed = true; } if (detourFailed) { Log.Info("Detours failed"); Singleton <SimulationManager> .instance.m_ThreadingWrapper.QueueMainThread(() => { UIView.library.ShowModal <ExceptionPanel>("ExceptionPanel").SetMessage("TM:PE failed to load", "Traffic Manager: President Edition failed to load. You can continue playing but it's NOT recommended. Traffic Manager will not work as expected.", true); }); } else { Log.Info("Detours successful"); } DetourInited = true; } }
public override void DefsLoaded() { base.DefsLoaded(); _modEnabled = Settings.GetHandle( "enabled", "FALCFF.EnableMod".Translate(), "FALCFF.EnableModDesc".Translate(), true); _showOverlay = Settings.GetHandle( "showOverlay", "FALCFF.ShowTargetingOverlay".Translate(), "FALCFF.ShowTargetingOverlayDesc".Translate(), true); _protectPets = Settings.GetHandle( "protectPets", "FALCFF.ProtectPets".Translate(), "FALCFF.ProtectPetsDesc".Translate(), true); _protectColonyAnimals = Settings.GetHandle( "protectColonyAnimals", "FALCFF.ProtectColonyAnimals".Translate(), "FALCFF.ProtectColonyAnimalsDesc".Translate(), false); _ignoreShieldedPawns = Settings.GetHandle( "ignoreShieldedPawns", "FALCFF.IgnoreShieldedPawns".Translate(), "FALCFF.IgnoreShieldedPawnsDesc".Translate(), true); _enableWhenUndrafted = Settings.GetHandle( "enableWhenUndrafted", "FALCFF.EnableWhenUndrafted".Translate(), "FALCFF.EnableWhenUndraftedDesc".Translate(), false); _enableAccurateMissRadius = Settings.GetHandle( "enableAccurateMissRadius", "FALCFF.EnableAccurateMissRadius".Translate(), "FALCFF.EnableAccurateMissRadiusDesc".Translate(), true); try { var ceVerb = GenTypes.GetTypeInAnyAssembly("CombatExtended.Verb_LaunchProjectileCE"); if (ceVerb == null) { return; } Logger.Message("Patching CombatExtended methods"); var vecType = GenTypes.GetTypeInAnyAssembly("Verse.IntVec3"); var ltiType = GenTypes.GetTypeInAnyAssembly("Verse.LocalTargetInfo"); var original = ceVerb.GetMethod("CanHitTargetFrom", new [] { vecType, ltiType }); var postfix = typeof(Verb_CanHitTargetFrom_Patch).GetMethod("Postfix"); HarmonyInst.Patch(original, null, new HarmonyMethod(postfix)); } catch (Exception e) { Logger.Error("Exception while trying to detect CombatExtended:"); Logger.Error(e.Message); Logger.Error(e.StackTrace); } }
public override void Initialize() { base.Initialize(); HarmonyInst.PatchAll(Assembly.GetExecutingAssembly()); Log = Logger; }