// todo support methods with arguments (currently there has been no need for it) public static SyncDelegate RegisterSyncDelegate(Type inType, string nestedType, string methodName, string[] fields, Type[] args = null) { string typeName = $"{inType}+{nestedType}"; Type type = MpReflection.GetTypeByName(typeName); if (type == null) { throw new Exception($"Couldn't find type {typeName}"); } MethodInfo method = AccessTools.Method(type, methodName, args); if (method == null) { throw new Exception($"Couldn't find method {typeName}::{methodName}"); } MpUtil.MarkNoInlining(method); SyncDelegate handler = new SyncDelegate(type, method, fields); syncMethods[handler.method] = handler; handlers.Add(handler); PatchMethodForSync(method); return(handler); }
static void PatchIfExists(string typeName, string methodName, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null) { var type = MpReflection.GetTypeByName(typeName); if (type == null) { return; } var method = AccessTools.Method(type, methodName); if (method == null) { return; } Multiplayer.harmony.Patch(method, prefix, postfix, transpiler); }
public static void Init() { var harmony = Multiplayer.harmony; // Compat with Fluffy's mod loader var fluffysModButtonType = MpReflection.GetTypeByName("ModManager.ModButton_Installed"); if (fluffysModButtonType != null) { harmony.Patch( fluffysModButtonType.GetMethod("DoModButton"), new HarmonyMethod(typeof(PageModsPatch), nameof(PageModsPatch.ModManager_ButtonPrefix)), new HarmonyMethod(typeof(PageModsPatch), nameof(PageModsPatch.Postfix)) ); } var cancelForArbiter = new HarmonyMethod(typeof(CancelForArbiter), "Prefix"); // Fix PrisonLabor breaking the arbiter { PatchIfExists("PrisonLabor.Behaviour_MotivationIcon", "Update", cancelForArbiter); PatchIfExists("PrisonLabor.Core.GUI_Components.PawnIcons", "MapComponentTick", cancelForArbiter); PatchIfExists("PrisonLabor.MapComponent_Icons", "MapComponentTick", cancelForArbiter); } // PawnsAreCapable compat // Replace workSettings.SetPriority(def, p) with (workSettings.priorities[def] = p) // Minimizes side effects and goes around syncing // Also cache the dictionary to improve performance { var pawnsAreCapablePatch = new HarmonyMethod(typeof(ModPatches), nameof(PawnsAreCapable_FloatMenu_Patch_Transpiler)); PatchIfExists("PawnsAreCapable.FloatMenuMakerMap_ChoicesAtFor", "Prefix", transpiler: pawnsAreCapablePatch); PatchIfExists("PawnsAreCapable.FloatMenuMakerMap_ChoicesAtFor", "Postfix", transpiler: pawnsAreCapablePatch); } var randPatchPrefix = new HarmonyMethod(typeof(RandPatches), "Prefix"); var randPatchPostfix = new HarmonyMethod(typeof(RandPatches), "Postfix"); // Facial Stuff compat { PatchIfExists("FacialStuff.Harmony.HarmonyPatchesFS", "TryInteractWith_Postfix", randPatchPrefix, randPatchPostfix); } }