internal static void UpdateMethod(Type type, MethodInfo meth) { if (patchedMeths.Contains(meth)) { if (Settings.verboseLogging) { ThreadSafeLogger.Warning($"[Analyzer] Already patched method {meth.DeclaringType.FullName + ":" + meth.Name}"); } return; } patchedMeths.Add(meth); typeInfo.TryAdd(meth, type); Task.Factory.StartNew(delegate { try { Modbase.Harmony.Patch(meth, transpiler: transpiler); } catch (Exception e) { if (Settings.verboseLogging) { ThreadSafeLogger.Warning($"[Analyzer] Failed to patch method {meth.DeclaringType.FullName}:{meth.Name} failed with the error {e.Message}"); } } }); }
private static IEnumerable <CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable <CodeInstruction> codeInstructions) { var enumerable = codeInstructions.ToList(); try { List <CodeInstruction> instructions = enumerable; for (int i = 0; i < instructions.Count; i++) { if (!IsFunctionCall(instructions[i].opcode)) { continue; } if (!(instructions[i].operand is MethodInfo meth)) { continue; } // Check for constrained if (i != 0 && instructions[i - 1].opcode == OpCodes.Constrained) { continue; } // Make sure it is not an analyzer profiling method if (meth.DeclaringType.FullName.Contains("Analyzer.Profiling")) { continue; } var key = Utility.GetMethodKey(meth); var index = MethodInfoCache.AddMethod(key, meth); var inst = MethodTransplanting.ReplaceMethodInstruction( instructions[i], key, GUIController.types[__originalMethod.DeclaringType + ":" + __originalMethod.Name + "-int"], index); instructions[i] = inst; } return(instructions); } catch (Exception e) { #if DEBUG ThreadSafeLogger.Error($"Failed to patch the internal method {__originalMethod.DeclaringType.FullName}:{__originalMethod.Name}, failed with the error " + e.Message); #else if (Settings.verboseLogging) { ThreadSafeLogger.Warning($"Failed to patch the internal method {__originalMethod.DeclaringType.FullName}:{__originalMethod.Name}, failed with the error " + e.Message); } #endif return(enumerable); } }
private static void Warn(string message) { #if DEBUG ThreadSafeLogger.Error($"[Analyzer] Patching warning: {message}"); #endif #if NDEBUG if (!displayMessages) { return; } ThreadSafeLogger.Warning($"[Analyzer] Patching warning: {message}"); #endif }
internal static void UpdateMethod(Type type, MethodInfo meth) { if (patchedMeths.Contains(meth)) { #if DEBUG ThreadSafeLogger.Warning($"[Analyzer] Already patched method {meth.DeclaringType.FullName + ":" + meth.Name}"); #else if (Settings.verboseLogging) { ThreadSafeLogger.Warning($"[Analyzer] Already patched method {Utility.GetSignature(meth, false)}"); } #endif return; } patchedMeths.Add(meth); typeInfo.TryAdd(meth, type); Task.Factory.StartNew(delegate { try { Modbase.Harmony.Patch(meth, transpiler: transpiler); } catch (Exception e) { #if DEBUG ThreadSafeLogger.ReportException(e, $"Failed to patch the method {Utility.GetSignature(meth, false)}"); #else if (Settings.verboseLogging) { ThreadSafeLogger.ReportException(e, $"Failed to patch the method {Utility.GetSignature(meth, false)}"); } #endif } }); }
public static void Draw(Listing_Standard listing, Rect win, bool settingsPage) { listing.Label(Strings.settings_dnspy); Settings.PathToDnspy = listing.TextEntry(Settings.PathToDnspy); listing.Gap(); DubGUI.LabeledSliderFloat(listing, Strings.settings_updates_per_second, ref Settings.updatesPerSecond, 1.0f, 20.0f); DubGUI.Checkbox(Strings.settings_logging, listing, ref Settings.verboseLogging); DubGUI.Checkbox(Strings.settings_disable_tps_counter, listing, ref Settings.disableTPSCounter); DubGUI.Checkbox(Strings.settings_enable_debug_log, listing, ref Settings.enableLog); DubGUI.Checkbox(Strings.settings_show_icon, listing, ref Settings.showIcon); if (DubGUI.Checkbox(Strings.settings_long_form_names, listing, ref Settings.longFormNames)) { ThreadSafeLogger.Warning("You will need to restart analyzer to see changes come into effect for tabs which are already open. (Right click on the analyzer icon, and click 'Cleanup' ; or wait 30s after closing analyzer)"); } var s = Strings.settings_disable_cleanup; var rect = listing.GetRect(Text.LineHeight); DubGUI.Checkbox(rect, s, ref Settings.disableCleanup); TooltipHandler.TipRegion(rect, Strings.settings_disable_cleanup_desc); if (settingsPage) { return; } listing.GapLine(); DubGUI.CenterText(() => listing.Label("devoptions.heading".Tr())); listing.GapLine(); var tabs = listing.GetRect(tabRect.height); tabs.width = tabRect.width; Drawtab(tabs, 0, "Patch Tools"); tabs.x = tabs.xMax; Drawtab(tabs, 1, $"Saved Patches ({Settings.SavedPatches_Tick.Count + Settings.SavedPatches_Update.Count})"); listing.Gap(4); if (PatchTab == 0) { if (listing.ButtonTextLabeled("Logging cycle", patchType.ToString())) { if (patchType == Category.Tick) { patchType = Category.Update; } else { patchType = Category.Tick; } //For if onGui gets added //var list = new List<FloatMenuOption> //{ // new FloatMenuOption("devoptions.patchtype.tick".Tr(), () => patchType = Category.Tick), // new FloatMenuOption("devoptions.patchtype.update".Tr(), () => patchType = Category.Update) // new FloatMenuOption("devoptions.patchtype.ongui".Tr(), () => patchType = Category.OnGui) //}; //Find.WindowStack.Add(new FloatMenu(list)); } if (showSearchbox) { Window_SearchBar.Control(); } var inputR = DisplayInputField(listing); Window_SearchBar.SetCurrentInput(input); Window_SearchBar.UpdateSearchString(currentInput); var searchRect = listing.GetRect(Mathf.Min(listing.curY, win.height - listing.curY)); lock (Window_SearchBar.sync) { if (showSearchbox && !Mouse.IsOver(searchRect) && Event.current.type != EventType.MouseDown) { showSearchbox = false; } if (GUI.GetNameOfFocusedControl() == "profileinput") { showSearchbox = true; } else if (Mouse.IsOver(inputR)) { showSearchbox = true; } } if (showSearchbox) { Window_SearchBar.DoWindowContents(searchRect); } } else { foreach (var patch in Settings.SavedPatches_Tick.ToList()) { var row = listing.GetRect(Text.LineHeight); if (Widgets.CloseButtonFor(row.LeftPartPixels(30f))) { Settings.SavedPatches_Tick.Remove(patch); } Widgets.Label(row.RightPartPixels(row.width - 30f), patch + " Tick"); listing.GapLine(); } foreach (var patch in Settings.SavedPatches_Update.ToList()) { var row = listing.GetRect(Text.LineHeight); if (Widgets.CloseButtonFor(row.LeftPartPixels(30f))) { Settings.SavedPatches_Update.Remove(patch); } Widgets.Label(row.RightPartPixels(row.width - 30f), patch + " Update"); listing.GapLine(); } } }