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}");
                    }
                }
            });
        }
示例#2
0
        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
                }
            });
        }
示例#5
0
        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();
                }
            }
        }