public static void PatchAssembly(string name, Category type) { var mod = LoadedModManager.RunningMods.FirstOrDefault(m => m.Name == name || m.PackageId == name.ToLower()); if (mod == null) { Error($"Failed to locate the mod {name}"); return; } Notify($"Assembly count: {mod.assemblies?.loadedAssemblies?.Count ?? 0}"); var assemblies = mod?.assemblies?.loadedAssemblies?.Where(ValidAssembly).ToList(); Notify($"Assembly count after removing Harmony/Cecil/Multiplayer/UnityEngine: {assemblies?.Count}"); if (assemblies != null && assemblies.Count() != 0) { GUIController.AddEntry(mod.Name + "-prof", type); GUIController.SwapToEntry(mod.Name + "-prof"); Task.Factory.StartNew(() => PatchAssemblyFull(mod.Name + "-prof", assemblies.ToList())); } else { Error($"Failed to patch {name} - There are no assemblies"); } }
private static void PatchInternalMethodFull(MethodInfo method, Category category) { try { var guiEntry = method.DeclaringType + ":" + method.Name + "-int"; GUIController.AddEntry(guiEntry, category); GUIController.SwapToEntry(guiEntry); InternalMethodUtility.PatchedInternals.Add(method); Task.Factory.StartNew(() => { try { Modbase.Harmony.Patch(method, transpiler: InternalMethodUtility.InternalProfiler); } catch (Exception e) { Error($"Failed to internal patch method {method.DeclaringType.FullName}:{method.Name}, failed with the exep " + e.Message); } }); } catch (Exception e) { Error("Failed to patch internal methods, failed with the error " + e.Message); InternalMethodUtility.PatchedInternals.Remove(method); } }
private static void PatchInternalMethodFull(MethodInfo method, Category category) { try { bool Valid() { var bytes = method.GetMethodBody()?.GetILAsByteArray(); if (bytes == null) { return(false); } if (bytes.Length == 0) { return(false); } if (bytes.Length == 1 && bytes.First() == 0x2A) { return(false); } return(true); } if (Valid() == false) { Error("Can not patch this method, this is likely a method which is virtually dispatched or marked as external, and thus can not be generically examined."); return; } var guiEntry = method.DeclaringType + ":" + method.Name + "-int"; GUIController.AddEntry(guiEntry, category); GUIController.SwapToEntry(guiEntry); InternalMethodUtility.PatchedInternals.Add(method); Task.Factory.StartNew(() => { try { Modbase.Harmony.Patch(method, transpiler: InternalMethodUtility.InternalProfiler); } catch (Exception e) { ReportException(e, $"Failed to patch the internal methods within {Utility.GetSignature(method, false)}"); } }); } catch (Exception e) { ReportException(e, "Failed to set up state to patch internal methods"); InternalMethodUtility.PatchedInternals.Remove(method); } }