diff --git a/LazyPrune/Main.cs b/LazyPrune/Main.cs index b8a9516..019d2f4 100644 --- a/LazyPrune/Main.cs +++ b/LazyPrune/Main.cs @@ -2,6 +2,8 @@ using ABI_RC.Core.EventSystem; using ABI_RC.Core.IO; using ABI_RC.Core.Networking.API.Responses; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; using ABI_RC.Systems.GameEventSystem; using HarmonyLib; using MelonLoader; @@ -50,21 +52,37 @@ public class LazyPrune : MelonMod prefix: new HarmonyMethod(typeof(LazyPrune).GetMethod(nameof(OnObjectDestroyed), BindingFlags.NonPublic | BindingFlags.Static)) ); - - // hook into Unity's low memory warning - Application.lowMemory += OnLowMemory; + + // nuke qm debug method as there is a race condition that locks up download queue + HarmonyInstance.Patch( + typeof(CVRDownloadManager).GetMethod(nameof(CVRDownloadManager.UpdateUiDownloadStatus), + BindingFlags.Public | BindingFlags.Instance), + prefix: new HarmonyMethod(typeof(LazyPrune).GetMethod(nameof(OnUpdateUiDownloadStatus), + BindingFlags.NonPublic | BindingFlags.Static)) + ); + + // another race condition that causes instantiation queue to lock up + HarmonyInstance.Patch( + typeof(PuppetMaster).GetMethod(nameof(PuppetMaster.AvatarInstantiated), + BindingFlags.Public | BindingFlags.Instance), + prefix: new HarmonyMethod(typeof(LazyPrune).GetMethod(nameof(OnAvatarInstantiated), + BindingFlags.NonPublic | BindingFlags.Static)) + ); } - #region Application Events + #region Game Fixes + + private static bool OnUpdateUiDownloadStatus() => false; - private static void OnLowMemory() + private static bool OnAvatarInstantiated(ref GameObject ___avatarObject) { - Logger.Warning("Low memory warning received! Forcing prune of all pending objects."); - ForcePrunePendingObjects(); + if (___avatarObject != null) return true; // instantiate coroutine is try-catch'd, so purposefully throw to have it catch + Logger.Warning("Caught null avatar object in PuppetMaster.AvatarInstantiated. Throwing exception so ObjectLoader can catch."); + throw new Exception("LazyPrune: PuppetMaster Avatar instantiated with null object!"); } - #endregion Application Events - + #endregion Game Fixes + #region Game Events private static void OnInstantiateAvatarFromExistingPrefab(string objectId, string instantiationTarget, @@ -73,6 +91,12 @@ public class LazyPrune : MelonMod bool shouldFilter, bool isBlocked, CompatibilityVersions compatibilityVersion) { + if (prefabObject == MetaPort.Instance.blockedAvatarPrefab) + { + Logger.Msg($"Blocked avatar prefab is loading. Ignoring..."); + return; + } + OnObjectCreated(ref loadedObject); } @@ -80,6 +104,12 @@ public class LazyPrune : MelonMod GameObject prefabObject, CVRObjectLoader.LoadedObject loadedObject, AssetManagement.PropTags propTags, CompatibilityVersions compatibilityVersion) { + if (prefabObject == MetaPort.Instance.blockedSpawnablePrefab) + { + Logger.Msg($"Blocked spawnable prefab is loading. Ignoring..."); + return; + } + OnObjectCreated(ref loadedObject); } diff --git a/LazyPrune/format.json b/LazyPrune/format.json index 9c8187f..4dbd4de 100644 --- a/LazyPrune/format.json +++ b/LazyPrune/format.json @@ -19,6 +19,6 @@ ], "downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r32/LazyPrune.dll", "sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/LazyPrune/", - "changelog": "- Fixed killtime check, would needlessly check known non-eligible objects for pruning.\n- Moved away from using GameEventSystem as it proved unreliable for tracking remote Avatar destruction, now patching Object Loader directly as loadedObject is not assigned when object wrappers are enabled.\n- Fixed scheduled prune job being nuked as it was created before scene load.", + "changelog": "- Fixed killtime check, would needlessly check known non-eligible objects for pruning.\n- Moved away from using GameEventSystem as it proved unreliable for tracking remote Avatar destruction, now patching Object Loader directly as loadedObject is not assigned when object wrappers are enabled.\n- Fixed scheduled prune job being nuked as it was created before initial scene load.\n- Patched two race conditions in the game that would cause the object loader to lock up.", "embedcolor": "#1c75f1" } \ No newline at end of file diff --git a/NAK_CVR_Mods.sln b/NAK_CVR_Mods.sln index 3f6aa0b..2bf430e 100644 --- a/NAK_CVR_Mods.sln +++ b/NAK_CVR_Mods.sln @@ -57,6 +57,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LazyPrune", "LazyPrune\Lazy EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReconnectionSystemFix", "ReconnectionSystemFix\ReconnectionSystemFix.csproj", "{05C427DD-1261-4AAD-B316-A551FC126F2C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AASDefaultProfileFix", "AASDefaultProfileFix\AASDefaultProfileFix.csproj", "{C6794B18-E785-4F91-A517-3A2A8006E008}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -171,6 +173,10 @@ Global {05C427DD-1261-4AAD-B316-A551FC126F2C}.Debug|Any CPU.Build.0 = Debug|Any CPU {05C427DD-1261-4AAD-B316-A551FC126F2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {05C427DD-1261-4AAD-B316-A551FC126F2C}.Release|Any CPU.Build.0 = Release|Any CPU + {C6794B18-E785-4F91-A517-3A2A8006E008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6794B18-E785-4F91-A517-3A2A8006E008}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6794B18-E785-4F91-A517-3A2A8006E008}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6794B18-E785-4F91-A517-3A2A8006E008}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE