BOBUK Posted July 28, 2023 Share Posted July 28, 2023 Hi all, While developing my own mod I've stumbled upon a nasty failure. I've managed to limit the scope to the simple mod with a single file and following listing: using HarmonyLib; [HarmonyPatch(typeof(Door))] public static class ObjectEvents { [HarmonyPrefix] [HarmonyPatch(nameof(Door.OrderUnseal))] private static void ObjectEventsPostfix() { } } After having this mod compiled and install you need to: 1) Load saved game with some doors 2) Click Lock on any Door 3) un-pause game You can find player.log attached. I'm still quite confused how the empty patch (I've tried non-empty as well) does affect the game. From a glance it seems to be connected to the fact that Harmony does initialize static fields of the class while patching it. I hope someone (developers perhaps? ) could help here. Player.log Link to comment Share on other sites More sharing options...
Polycone Posted July 28, 2023 Share Posted July 28, 2023 Hi guys, We're working with the OP on the same mod and I've traced the problem with this particular Door patch. Turned out it's related to Door.OVERRIDE_ANIMS static field which is being initialized during the patch Spoiler at Assets.GetAnim (HashedString name) [0x00000] in -\Assets.cs:591 at Door..cctor () [0x00000] in <cd4b9bd5aa6c4ec38ec00dca1dc79105>:0 at System.RuntimeMethodHandle.GetFunctionPointer (System.IntPtr m) [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0 at System.RuntimeMethodHandle.GetFunctionPointer () [0x00000] in <695d1cc93cca45069c528c15c9fdd749>:0 at MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform.GetFunctionPointer (System.Reflection.MethodBase method, System.RuntimeMethodHandle handle) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform.GetNativeStart (System.Reflection.MethodBase method) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at MonoMod.RuntimeDetour.DetourHelper.GetNativeStart (System.Reflection.MethodBase method) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.Memory.GetMethodStart (System.Reflection.MethodBase method, System.Exception& exception) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.Memory.DetourMethod (System.Reflection.MethodBase original, System.Reflection.MethodBase replacement) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.Memory.DetourMethodAndPersist (System.Reflection.MethodBase original, System.Reflection.MethodBase replacement) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, HarmonyLib.PatchInfo patchInfo) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.PatchClassProcessor.ProcessPatchJob (HarmonyLib.PatchJobs`1+Job[T] job) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.PatchClassProcessor.PatchWithAttributes (System.Reflection.MethodBase& lastOriginal) [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at HarmonyLib.PatchClassProcessor.Patch () [0x00000] in <2f5aaaa000594d07b9998f4cff1e9662>:0 at MultiplayerMod.Core.Loader.ModLoader.OnLoad (HarmonyLib.Harmony harmony) [0x00000] in <0361fe183078446597d3f44f6a59d5d5>:0 at KMod.DLLLoader.LoadDLLs (KMod.Mod ownerMod, System.String harmonyId, System.String path, System.Boolean isDev) [0x0021b] in KMod\DLLLoader.cs:124 at KMod.Mod.Load (KMod.Content content) [0x000a5] in KMod\Mod.cs:656 at KMod.Manager.Load (KMod.Content content) [0x0004f] in KMod\Manager.cs:447 at Global.Awake () [0x00171] in -\Global.cs:342 at UnityEngine.Object.Internal_InstantiateSingleWithParent_Injected (UnityEngine.Object data, UnityEngine.Transform parent, UnityEngine.Vector3& pos, UnityEngine.Quaternion& rot) [0x00000] in <faa1d4bf73af4cbca302a933fa3e0da0>:0 at UnityEngine.Object.Internal_InstantiateSingleWithParent (UnityEngine.Object data, UnityEngine.Transform parent, UnityEngine.Vector3 pos, UnityEngine.Quaternion rot) [0x00000] in <faa1d4bf73af4cbca302a933fa3e0da0>:0 at UnityEngine.Object.Instantiate (UnityEngine.Object original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation, UnityEngine.Transform parent) [0x00000] in <faa1d4bf73af4cbca302a933fa3e0da0>:0 at UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation, UnityEngine.Transform parent) [0x00000] in <faa1d4bf73af4cbca302a933fa3e0da0>:0 at Util.KInstantiate (UnityEngine.GameObject original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation, UnityEngine.GameObject parent, System.String name, System.Boolean initialize_id, System.Int32 gameLayer) [0x00076] in -\Util.cs:259 at Util.KInstantiate (UnityEngine.GameObject original, UnityEngine.GameObject parent, System.String name) [0x00000] in -\Util.cs:231 at LaunchInitializer.Update () [0x000ea] in -\LaunchInitializer.cs:63 and since it called Assets.GetAnim which hadn't initialized yet a null value was written to OVERRIDE_ANIMS. Thus the game fails when it's switching to the animation with the remote (anim_use_remote_kanim) when locking / unlocking doors, because the override animation is null. Seems like we can't avoid the field initialization, because it's a part of the C# detouring mechanism. Because we actually patch a lot of classes with static initialization inside, we thought maybe from our side we can "delay" the patching process until everything that can be used in static is initialized. I think that theoretically can be done in the end of LaunchInitializer.Update(), but we still unsure if that's okay. What do you think? Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.