From 8260ad4d6ecd8fce65e5fe0cf73d07db2cb6d0e1 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 1 Jan 2025 01:19:14 -0800 Subject: [PATCH] Update performance patches (#14) * Add new transpilers * Cleanup --------- Co-authored-by: Chomp <27521899+chompDev@users.noreply.github.com> --- .../BotOwner_ManualUpdate_Transpiler.cs | 45 ++++++ .../CoverPointMaster_method_0_Transpiler.cs | 38 +++++ .../RaidFix/BotOwnerManualUpdatePatch.cs | 81 ---------- .../SPT.SinglePlayer/SPTSingleplayerPlugin.cs | 140 +++++++++--------- 4 files changed, 154 insertions(+), 150 deletions(-) create mode 100644 project/SPT.SinglePlayer/Patches/Performance/BotOwner_ManualUpdate_Transpiler.cs create mode 100644 project/SPT.SinglePlayer/Patches/Performance/CoverPointMaster_method_0_Transpiler.cs delete mode 100644 project/SPT.SinglePlayer/Patches/RaidFix/BotOwnerManualUpdatePatch.cs diff --git a/project/SPT.SinglePlayer/Patches/Performance/BotOwner_ManualUpdate_Transpiler.cs b/project/SPT.SinglePlayer/Patches/Performance/BotOwner_ManualUpdate_Transpiler.cs new file mode 100644 index 0000000..2c36633 --- /dev/null +++ b/project/SPT.SinglePlayer/Patches/Performance/BotOwner_ManualUpdate_Transpiler.cs @@ -0,0 +1,45 @@ +using EFT; +using HarmonyLib; +using SPT.Reflection.Patching; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Diagnostics; + +namespace SPT.SinglePlayer.Patches.Performance +{ + /// + /// Transpiler used to stop the allocation of a new every frame for all active AI
+ /// To update transpiler, look for:
+ /// - New allocation of
+ /// - and
+ /// - Unnecessary run of + ///
+ public class BotOwner_ManualUpdate_Transpiler : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(BotOwner), nameof(BotOwner.UpdateManual)); + } + + [PatchTranspiler] + public static IEnumerable Transpile(IEnumerable instructions) + { + List codeList = instructions.ToList(); + + // These 3 lines remove BotUnityEditorRunChecker.ManualLateUpdate() + codeList[109] = new CodeInstruction(OpCodes.Nop); + codeList[108] = new CodeInstruction(OpCodes.Nop); + codeList[107].opcode = OpCodes.Nop; + + // These 4 remove the allocation of the Stopwatch and the Start() and Stop() + codeList[18] = new CodeInstruction(OpCodes.Nop); + codeList[14] = new CodeInstruction(OpCodes.Nop); + codeList[13] = new CodeInstruction(OpCodes.Nop); + codeList[12] = new CodeInstruction(OpCodes.Nop); + + return codeList; + } + } +} diff --git a/project/SPT.SinglePlayer/Patches/Performance/CoverPointMaster_method_0_Transpiler.cs b/project/SPT.SinglePlayer/Patches/Performance/CoverPointMaster_method_0_Transpiler.cs new file mode 100644 index 0000000..6c031ff --- /dev/null +++ b/project/SPT.SinglePlayer/Patches/Performance/CoverPointMaster_method_0_Transpiler.cs @@ -0,0 +1,38 @@ +using HarmonyLib; +using SPT.Reflection.Patching; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +namespace SPT.SinglePlayer.Patches.Performance +{ + /// + /// Transpiler used to stop the allocation of a new during
+ /// To update transpiler, look for:
+ /// - New allocation of
+ /// - and
+ ///
+ internal class CoverPointMaster_method_0_Transpiler : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(CoverPointMaster), nameof(CoverPointMaster.method_0)); + } + + [PatchTranspiler] + public static IEnumerable Transpile(IEnumerable instructions) + { + List codeList = instructions.ToList(); + // This is the line that stops the Stopwatch + codeList[69].opcode = OpCodes.Nop; + + // These lines stops the allocation and Start() of the Stopwatch + codeList[12].opcode = OpCodes.Nop; + codeList[11].opcode = OpCodes.Nop; + codeList[10].opcode = OpCodes.Nop; + + return codeList; + } + } +} diff --git a/project/SPT.SinglePlayer/Patches/RaidFix/BotOwnerManualUpdatePatch.cs b/project/SPT.SinglePlayer/Patches/RaidFix/BotOwnerManualUpdatePatch.cs deleted file mode 100644 index 23cc261..0000000 --- a/project/SPT.SinglePlayer/Patches/RaidFix/BotOwnerManualUpdatePatch.cs +++ /dev/null @@ -1,81 +0,0 @@ -using EFT; -using EFT.Game.Spawning; -using SPT.Reflection.Patching; -using System.Reflection; -using UnityEngine; -using UnityEngine.AI; - -namespace SPT.SinglePlayer.Patches.RaidFix -{ - /// - /// Patch used to stop the allocation of a new every frame for all active AI - /// - public class BotOwnerManualUpdatePatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return typeof(BotOwner).GetMethod(nameof(BotOwner.UpdateManual)); - } - - [PatchPrefix] - public static bool Prefix(BotOwner __instance, float ____nextGetGoalTime, ref float ____nextTimeCheckBorn) - { - if (__instance.BotState == EBotState.Active && __instance.GetPlayer.HealthController.IsAlive) - { - __instance.StandBy.Update(); - __instance.LookSensor.ManualUpdate(); - if (__instance.StandBy.StandByType != BotStandByType.paused) - { - if (____nextGetGoalTime < Time.time) - { - __instance.CalcGoal(); - } - __instance.SuppressShoot.ManualUpdate(); - __instance.HeadData.ManualUpdate(); - __instance.ShootData.ManualUpdate(); - __instance.Tilt.ManualUpdate(); - __instance.NightVision.ManualUpdate(); - __instance.NearDoorData.Update(); - __instance.DogFight.ManualUpdate(); - __instance.FriendChecker.ManualUpdate(); - __instance.RecoilData.LosingRecoil(); - __instance.Mover.ManualUpdate(); - __instance.AimingManager.ManualUpdate(); - __instance.Medecine.ManualUpdate(); - __instance.Boss.ManualUpdate(); - __instance.BotTalk.ManualUpdate(); - __instance.WeaponManager.ManualUpdate(); - __instance.BotRequestController.Update(); - __instance.GrenadeToPortal.ManualUpdate(); - __instance.Tactic.UpdateChangeTactics(); - __instance.Memory.ManualUpdate(Time.deltaTime); - __instance.Settings.UpdateManual(); - __instance.BotRequestController.TryToFind(); - __instance.ArtilleryDangerPlace.ManualUpdate(); - if (__instance.GetPlayer.UpdateQueue == EUpdateQueue.Update) - { - __instance.Mover.ManualFixedUpdate(); - __instance.Steering.ManualFixedUpdate(); - } - __instance.UnityEditorRunChecker.ManualLateUpdate(); - } - return false; - } - if (__instance.BotState == EBotState.PreActive && __instance.WeaponManager.IsReady) - { - if (NavMesh.SamplePosition(__instance.GetPlayer.Position, out _, 0.6f, -1)) - { - __instance.method_10(); - return false; - } - if (____nextTimeCheckBorn < Time.time) - { - ____nextTimeCheckBorn = Time.time + 1f; - __instance.Transform.position = __instance.BotsGroup.BotZone.SpawnPoints.RandomElement().Position + Vector3.up * 0.5f; - __instance.method_10(); - } - } - return false; - } - } -} diff --git a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs index 8f22d64..3bcab8f 100644 --- a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs +++ b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs @@ -1,88 +1,90 @@ -using System; +using BepInEx; using SPT.Common; using SPT.SinglePlayer.Patches.MainMenu; +using SPT.SinglePlayer.Patches.Performance; using SPT.SinglePlayer.Patches.Progression; using SPT.SinglePlayer.Patches.RaidFix; using SPT.SinglePlayer.Patches.ScavMode; -using BepInEx; using SPT.SinglePlayer.Utils.MainMenu; +using System; namespace SPT.SinglePlayer { - [BepInPlugin("com.SPT.singleplayer", "SPT.Singleplayer", SPTPluginInfo.PLUGIN_VERSION)] - public class SPTSingleplayerPlugin : BaseUnityPlugin - { - public void Awake() - { - Logger.LogInfo("Loading: SPT.SinglePlayer"); + [BepInPlugin("com.SPT.singleplayer", "SPT.Singleplayer", SPTPluginInfo.PLUGIN_VERSION)] + public class SPTSingleplayerPlugin : BaseUnityPlugin + { + public void Awake() + { + Logger.LogInfo("Loading: SPT.SinglePlayer"); - try - { - // TODO: check if these patches are needed - new TinnitusFixPatch().Enable(); // Probably needed - new EmptyInfilFixPatch().Enable(); - new OverrideMaxAiAliveInRaidValuePatch().Enable(); - //new PostRaidHealingPricePatch().Enable(); // Client handles this now - //new HideoutQuestIgnorePatch().Enable(); // Was only needed because FixQuestAchieveControllersPatch was causing issues - //new SpawnProcessNegativeValuePatch().Enable(); // Client handles this edge case, revisit if bot count keeps going up - //new SpawnPmcPatch().Enable(); // 2.5+ years old, PMC spawn system very different, likely not needed - //new FixQuestAchieveControllersPatch().Enable(); // Likely not needed, if cheevos don't appear, revisit patch + try + { + // TODO: check if these patches are needed + new TinnitusFixPatch().Enable(); // Probably needed + new EmptyInfilFixPatch().Enable(); + new OverrideMaxAiAliveInRaidValuePatch().Enable(); + //new PostRaidHealingPricePatch().Enable(); // Client handles this now + //new HideoutQuestIgnorePatch().Enable(); // Was only needed because FixQuestAchieveControllersPatch was causing issues + //new SpawnProcessNegativeValuePatch().Enable(); // Client handles this edge case, revisit if bot count keeps going up + //new SpawnPmcPatch().Enable(); // 2.5+ years old, PMC spawn system very different, likely not needed + //new FixQuestAchieveControllersPatch().Enable(); // Likely not needed, if cheevos don't appear, revisit patch - // Still need - new FixPostScavRaidXpShowingZeroPatch().Enable(); - new DisablePMCExtractsForScavsPatch().Enable(); - new ScavExfilPatch().Enable(); - new ScavProfileLoadPatch().Enable(); - new ScavPrefabLoadPatch().Enable(); - new DisableReadyLocationReadyPatch().Enable(); - //new BotTemplateLimitPatch().Enable(); // Not necessary, controls how many 'respawns' the wave has, different to what the original patches intent was when written - new LoadOfflineRaidScreenPatch().Enable(); - new AmmoUsedCounterPatch().Enable(); // Necessary for fixing bug #773 - new PluginErrorNotifierPatch().Enable(); - new GetNewBotTemplatesPatch().Enable(); - new MapReadyButtonPatch().Enable(); - new RemoveUsedBotProfilePatch().Enable(); - new ScavLateStartPatch().Enable(); - new ScavSellAllPriceStorePatch().Enable(); - new ScavSellAllRequestPatch().Enable(); - new ScavRepAdjustmentPatch().Enable(); - new QuestAddedAutoSelectPatch().Enable(); + // Still need + new FixPostScavRaidXpShowingZeroPatch().Enable(); + new DisablePMCExtractsForScavsPatch().Enable(); + new ScavExfilPatch().Enable(); + new ScavProfileLoadPatch().Enable(); + new ScavPrefabLoadPatch().Enable(); + new DisableReadyLocationReadyPatch().Enable(); + //new BotTemplateLimitPatch().Enable(); // Not necessary, controls how many 'respawns' the wave has, different to what the original patches intent was when written + new LoadOfflineRaidScreenPatch().Enable(); + new AmmoUsedCounterPatch().Enable(); // Necessary for fixing bug #773 + new PluginErrorNotifierPatch().Enable(); + new GetNewBotTemplatesPatch().Enable(); + new MapReadyButtonPatch().Enable(); + new RemoveUsedBotProfilePatch().Enable(); + new ScavLateStartPatch().Enable(); + new ScavSellAllPriceStorePatch().Enable(); + new ScavSellAllRequestPatch().Enable(); + new ScavRepAdjustmentPatch().Enable(); + new QuestAddedAutoSelectPatch().Enable(); - // 3.10.0 - new DisableWelcomeToPVEModeMessagePatch().Enable(); - new DisableMatchmakerPlayerPreviewButtonsPatch().Enable(); - new EnableRefForPVEPatch().Enable(); - new EnableRefIntermScreenPatch().Enable(); - new EnablePlayerScavPatch().Enable(); - new ScavFoundInRaidPatch().Enable(); - new GetProfileAtEndOfRaidPatch().Enable(); - new SendPlayerScavProfileToServerAfterRaidPatch().Enable(); - //new InsuranceScreenPatch().Enable(); - new RemoveStashUpgradeLabelPatch().Enable(); + // 3.10.0 + new DisableWelcomeToPVEModeMessagePatch().Enable(); + new DisableMatchmakerPlayerPreviewButtonsPatch().Enable(); + new EnableRefForPVEPatch().Enable(); + new EnableRefIntermScreenPatch().Enable(); + new EnablePlayerScavPatch().Enable(); + new ScavFoundInRaidPatch().Enable(); + new GetProfileAtEndOfRaidPatch().Enable(); + new SendPlayerScavProfileToServerAfterRaidPatch().Enable(); + //new InsuranceScreenPatch().Enable(); + new RemoveStashUpgradeLabelPatch().Enable(); new RemoveClothingItemExternalObtainLabelPatch().Enable(); new ForceRaidModeToLocalPatch().Enable(); new ScavIsPlayerEnemyPatch().Enable(); - new BotOwnerManualUpdatePatch().Enable(); new FirearmControllerShowIncompatibleNotificationClass().Enable(); - new FixKeyAlreadyExistsErrorOnAchievementPatch().Enable(); - - // 4.0.0 - new ScavPrestigeFixPatch().Enable(); - new DisableDevMaskCheckPatch().Enable(); - } - catch (Exception ex) - { - Logger.LogError($"A PATCH IN {GetType().Name} FAILED. SUBSEQUENT PATCHES HAVE NOT LOADED"); - Logger.LogError($"{GetType().Name}: {ex}"); - throw; - } + new FixKeyAlreadyExistsErrorOnAchievementPatch().Enable(); - Logger.LogInfo("Completed: SPT.SinglePlayer"); - } + // 4.0.0 + new ScavPrestigeFixPatch().Enable(); + new DisableDevMaskCheckPatch().Enable(); + new BotOwner_ManualUpdate_Transpiler().Enable(); + new CoverPointMaster_method_0_Transpiler().Enable(); + } + catch (Exception ex) + { + Logger.LogError($"A PATCH IN {GetType().Name} FAILED. SUBSEQUENT PATCHES HAVE NOT LOADED"); + Logger.LogError($"{GetType().Name}: {ex}"); + throw; + } - public void Start() - { - TraderServiceManager.GetModdedTraderData(); - } - } + Logger.LogInfo("Completed: SPT.SinglePlayer"); + } + + public void Start() + { + TraderServiceManager.GetModdedTraderData(); + } + } }