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();
+ }
+ }
}