diff --git a/Source/Mods/WorkTab.cs b/Source/Mods/WorkTab.cs index 80cceab..05bda9f 100644 --- a/Source/Mods/WorkTab.cs +++ b/Source/Mods/WorkTab.cs @@ -11,14 +11,18 @@ namespace Multiplayer.Compat /// Work Tab by Fluffy /// /// + /// + /// [MpCompatFor("Fluffy.WorkTab")] + [MpCompatFor("arof.fluffy.worktab")] + [MpCompatFor("arof.fluffy.worktab.continued")] internal class WorkTab { // Delegates private delegate void PasteTo(PawnColumnWorker_CopyPasteWorkPriorities instance, Pawn pawn); // Changing priorities - private static ConstructorInfo copyPasteColumnWorkerConstructor; + private static Type copyPasteColumnWorkerType; private static AccessTools.FieldRef> clipboardField; private static PasteTo pasteToMethod; @@ -29,10 +33,10 @@ public WorkTab(ModContentPack mod) MP.RegisterSyncMethod(AccessTools.PropertySetter(type, "ShowPriorities")); type = AccessTools.TypeByName("WorkTab.Pawn_Extensions"); - MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(List) })); - MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(int), typeof(bool) })); - MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(List) })); - MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(int), typeof(bool) })); + MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", [typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(List)])); + MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", [typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(int), typeof(bool)])); + MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", [typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(List)])); + MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", [typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(int), typeof(bool)])); // This one not needed as it calls SetPriority, but it'll // end up calling it numerous times - let's just do it in one command. MP.RegisterSyncMethod(type, "DisableAll"); @@ -41,8 +45,7 @@ public WorkTab(ModContentPack mod) // But well, it ends up being called almost 2000 times in vanilla with DLCs alone... // So I felt like it'll be smarter to sync it as a single command instead of potentially // couple thousand with mods. - type = AccessTools.TypeByName("WorkTab.PawnColumnWorker_CopyPasteDetailedWorkPriorities"); - copyPasteColumnWorkerConstructor = AccessTools.DeclaredConstructor(type); + type = copyPasteColumnWorkerType = AccessTools.TypeByName("WorkTab.PawnColumnWorker_CopyPasteDetailedWorkPriorities"); clipboardField = AccessTools.StaticFieldRefAccess>(AccessTools.Field(type, "clipboard")); var method = AccessTools.Method(type, "PasteTo"); pasteToMethod = AccessTools.MethodDelegate(method); @@ -56,15 +59,15 @@ public WorkTab(ModContentPack mod) // Sadly, there isn't a call like that in case of checkbox priorities - only numeric ones var types = new (string typeName, Type parameterType)[] { - ("WorkTab.WorkType_Extensions", typeof(WorkTypeDef)), - ("WorkTab.WorkGiver_Extensions", typeof(WorkGiverDef)), + ("WorkTab.WorkType_Extensions", typeof(WorkTypeDef)), + ("WorkTab.WorkGiver_Extensions", typeof(WorkGiverDef)), }; foreach (var (typeName, parameterType) in types) { type = AccessTools.TypeByName(typeName); - MP.RegisterSyncMethod(AccessTools.Method(type, "DecrementPriority", new[] { parameterType, typeof(List), typeof(int), typeof(List), typeof(bool) })); - MP.RegisterSyncMethod(AccessTools.Method(type, "IncrementPriority", new[] { parameterType, typeof(List), typeof(int), typeof(List), typeof(bool) })); + MP.RegisterSyncMethod(AccessTools.Method(type, "DecrementPriority", [parameterType, typeof(List), typeof(int), typeof(List), typeof(bool)])); + MP.RegisterSyncMethod(AccessTools.Method(type, "IncrementPriority", [parameterType, typeof(List), typeof(int), typeof(List), typeof(bool)])); } // Same deal as before, stops the call from being synced hundreds of times @@ -90,18 +93,25 @@ private static bool PrePasteTo(Pawn pawn) private static void SyncedPasteTo(Pawn pawn, Dictionary targetClipboard) { var current = clipboardField(); - clipboardField() = targetClipboard; - // Too much effort to try and find the existing instance, so create one - // It doesn't really matter, as it doesn't have anything important - // besides the static field - var tab = (PawnColumnWorker_CopyPasteWorkPriorities)copyPasteColumnWorkerConstructor.Invoke(Array.Empty()); - pasteToMethod(tab, pawn); - clipboardField() = current; + try + { + clipboardField() = targetClipboard; + // Too much effort to try and find the existing instance, so create one + // It doesn't really matter, as it doesn't have anything important + // besides the static field + var tab = (PawnColumnWorker_CopyPasteWorkPriorities)Activator.CreateInstance(copyPasteColumnWorkerType); + pasteToMethod(tab, pawn); + } + finally + { + clipboardField() = current; + } } // Blank sync worker - we don't have anything to sync and only care about the // object being initialized so we can call the synced method on something private static void SyncPawnColumnLabel(SyncWorker sync, ref PawnColumnWorker_Label obj) - { } + { + } } -} +} \ No newline at end of file