Beispiel #1
0
        public static void ExecutePatch(CurrentInput mode, string strinput, Category cat)
        {
            try
            {
                var entry = cat == Category.Tick ? typeof(CustomProfilersTick) : typeof(CustomProfilersUpdate);
                List <MethodInfo> methods = null;

                var temp = mode switch
                {
                    CurrentInput.Method => Utility.GetMethods(strinput),
                    CurrentInput.Type => Utility.GetTypeMethods(AccessTools.TypeByName(strinput)),
                    CurrentInput.MethodHarmony => Utility.GetMethodsPatching(strinput),
                    CurrentInput.SubClasses => Utility.SubClassImplementationsOf(AccessTools.TypeByName(strinput), m => true),
                    CurrentInput.TypeHarmony => Utility.GetMethodsPatchingType(AccessTools.TypeByName(strinput)),
                    _ => null,
                };

                if (temp is null)
                {
                    if (mode == CurrentInput.InternalMethod)
                    {
                        Utility.PatchInternalMethod(strinput, cat);
                    }
                    else
                    {
                        Utility.PatchAssembly(strinput, cat);
                    }

                    return;
                }

                methods = temp.ToList();

                if (methods.Count == 0)
                {
                    Messages.Message($"Failed to find the method(s) represented by {strinput}", MessageTypeDefOf.CautionInput, false);
                    return;
                }

                Messages.Message(methods.Count != 1 ? $"Patching {methods.Count} methods in the category {cat}" : $"Patching {Utility.GetSignature(methods[0])} in the category {cat}", MessageTypeDefOf.CautionInput, false);

                MethodTransplanting.UpdateMethods(entry, methods.ToList());
                GUIController.Tab(cat).collapsed = false;

                var entryName = (cat == Category.Tick) ? "Custom Tick" : "Custom Update";
                GUIController.SwapToEntry(entryName);
            }
            catch (Exception e)
            {
                ThreadSafeLogger.ReportException(e, $"Failed to process search bar input");
            }
        }
        private static void PatchAssemblyFull(string key, List <Assembly> assemblies)
        {
            var meths = new HashSet <MethodInfo>();

            foreach (var asm in assemblies)
            {
                try
                {
                    var asmName = $"{asm.GetName().Name}.dll";
                    if (patchedAssemblies.Contains(asm.FullName))
                    {
                        Warn($"patching {asmName} failed, already patched");
                        continue;
                    }

                    patchedAssemblies.Add(asm.FullName);

                    foreach (var type in AccessTools.GetTypesFromAssembly(asm))
                    {
                        var methods = AccessTools.GetDeclaredMethods(type).ToList();
                        foreach (var m in methods)
                        {
                            try
                            {
                                if (ValidMethod(m) && m.DeclaringType == type)
                                {
                                    meths.TryAdd(m);
                                }
                            }
                            catch (Exception e)
                            {
                                ReportException(e, $"Skipping method {GetSignature(m)}");
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    ReportException(e, $"Failed to patch the assembly {asm.FullName}");
                }
            }

            var asms      = assemblies.Select(a => a.GetName().Name + ".dll").Join();
            var asmString = assemblies.Count > 1 ? "assemblies" : "assembly";

            Messages.Message($"Attempting to patch {meths.Count} methods from the {asmString} [{asms}]", MessageTypeDefOf.CautionInput, false);

            MethodTransplanting.UpdateMethods(GUIController.types[key], meths);
        }
Beispiel #3
0
        private static void PatchAssemblyFull(string key, List <Assembly> assemblies)
        {
            var meths = new HashSet <MethodInfo>();

            foreach (var assembly in assemblies)
            {
                try
                {
                    if (patchedAssemblies.Contains(assembly.FullName))
                    {
                        Warn($"patching {assembly.FullName} failed, already patched");
                        return;
                    }

                    patchedAssemblies.Add(assembly.FullName);

                    foreach (var type in assembly.GetTypes())
                    {
                        foreach (var method in AccessTools.GetDeclaredMethods(type).Where(m => ValidMethod(m) && m.DeclaringType == type))
                        {
                            if (!meths.Contains(method))
                            {
                                meths.Add(method);
                            }
                        }
                    }

                    Notify($"Patched {assembly.FullName}");
                }
                catch (Exception e)
                {
                    Error($"Patching {assembly.FullName} failed, {e.Message}");
                    return;
                }
            }

            MethodTransplanting.UpdateMethods(GUIController.types[key], meths);
        }
        public static void ExecutePatch()
        {
            try
            {
                if (patchType == Category.Tick)
                {
                    switch (input)
                    {
                    case CurrentInput.Method:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersTick), Utility.GetMethods(currentInput));
                        break;

                    case CurrentInput.Type:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersTick), Utility.GetTypeMethods(AccessTools.TypeByName(currentInput)));
                        break;

                    case CurrentInput.MethodHarmony:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersTick), Utility.GetMethodsPatching(currentInput));
                        break;

                    case CurrentInput.SubClasses:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersTick), Utility.SubClassImplementationsOf(AccessTools.TypeByName(currentInput), m => true));
                        break;

                    case CurrentInput.TypeHarmony:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersTick), Utility.GetMethodsPatchingType(AccessTools.TypeByName(currentInput)));
                        break;

                    case CurrentInput.InternalMethod:
                        Utility.PatchInternalMethod(currentInput, Category.Tick);
                        return;

                    case CurrentInput.Assembly:
                        Utility.PatchAssembly(currentInput, Category.Tick);
                        return;
                    }

                    GUIController.SwapToEntry("Custom Tick");
                }
                else
                {
                    switch (input)
                    {
                    case CurrentInput.Method:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersUpdate), Utility.GetMethods(currentInput));
                        break;

                    case CurrentInput.Type:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersUpdate), Utility.GetTypeMethods(AccessTools.TypeByName(currentInput)));
                        break;

                    case CurrentInput.MethodHarmony:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersUpdate), Utility.GetMethodsPatching(currentInput));
                        break;

                    case CurrentInput.SubClasses:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersUpdate), Utility.SubClassImplementationsOf(AccessTools.TypeByName(currentInput), m => true));
                        break;

                    case CurrentInput.TypeHarmony:
                        MethodTransplanting.UpdateMethods(typeof(CustomProfilersUpdate), Utility.GetMethodsPatchingType(AccessTools.TypeByName(currentInput)));
                        break;

                    case CurrentInput.InternalMethod:
                        Utility.PatchInternalMethod(currentInput, Category.Update);
                        return;

                    case CurrentInput.Assembly:
                        Utility.PatchAssembly(currentInput, Category.Update);
                        return;
                    }

                    GUIController.SwapToEntry("Custom Update");
                }
            }
            catch (Exception e)
            {
                ThreadSafeLogger.Error($"Failed to process input, failed with the error {e.Message}");
            }
        }
        public static void ProfilePatch()
        {
            Modbase.Harmony.Patch(AccessTools.Method(typeof(ThinkNode_Priority), nameof(ThinkNode_Priority.TryIssueJobPackage)), new HarmonyMethod(typeof(H_GetLord), nameof(Fringe)));

            MethodTransplanting.UpdateMethods(typeof(H_GetLord), Utility.GetTypeMethods(typeof(Lord)).ToList());
        }