From 4bd4bcaa59867b5768a82f1d92056b364d5a704e Mon Sep 17 00:00:00 2001 From: Paulov Date: Wed, 17 Apr 2024 17:07:20 +0100 Subject: [PATCH 1/4] Refactor BSG GC and SIT GC routines into own component --- Source/Configuration/PluginConfigSettings.cs | 25 +---- .../CoopGameComponents/SITGameComponent.cs | 57 +--------- .../CoopGameComponents/SITGameGCComponent.cs | 104 ++++++++++++++++++ 3 files changed, 113 insertions(+), 73 deletions(-) create mode 100644 Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs diff --git a/Source/Configuration/PluginConfigSettings.cs b/Source/Configuration/PluginConfigSettings.cs index 44a2df70..6d9bb694 100644 --- a/Source/Configuration/PluginConfigSettings.cs +++ b/Source/Configuration/PluginConfigSettings.cs @@ -44,31 +44,18 @@ public class SITAdvancedSettings public ConfigFile Config { get; } public ManualLogSource Logger { get; } - public bool SETTING_EnableSITGC - { - get - { - return StayInTarkovPlugin.Instance.Config.Bind - (Advanced, "EnableSITGC", false, new ConfigDescription("Enable SIT's own Garbage Collector")).Value; - } - } - - public uint SETTING_SITGCMemoryThreshold - { - get - { - return StayInTarkovPlugin.Instance.Config.Bind - (Advanced, "SITGCMemoryThreshold", 90u, new ConfigDescription("SIT's Garbage Collector. System Memory % before SIT forces a Garbage Collection.")).Value; - } - } + public bool SETTING_EnableSITGC { get; set; } + public uint SETTING_SITGCMemoryThreshold { get; set; } public SITAdvancedSettings(ManualLogSource logger, ConfigFile config) { Logger = logger; Config = config; - _ = SETTING_EnableSITGC; - _ = SETTING_SITGCMemoryThreshold; + SETTING_EnableSITGC = StayInTarkovPlugin.Instance.Config.Bind + (Advanced, "EnableSITGC", false, new ConfigDescription("Enable SIT's own Garbage Collector")).Value; + SETTING_SITGCMemoryThreshold = StayInTarkovPlugin.Instance.Config.Bind + (Advanced, "SITGCMemoryThreshold", 90u, new ConfigDescription("SIT's Garbage Collector. System Memory % before SIT forces a Garbage Collection.")).Value; } } diff --git a/Source/Coop/Components/CoopGameComponents/SITGameComponent.cs b/Source/Coop/Components/CoopGameComponents/SITGameComponent.cs index 2ba41010..6b8ee802 100644 --- a/Source/Coop/Components/CoopGameComponents/SITGameComponent.cs +++ b/Source/Coop/Components/CoopGameComponents/SITGameComponent.cs @@ -331,8 +331,7 @@ private void GameWorld_AfterGameStarted() // CoopSITGame.SendPlayerDataToServer((LocalPlayer)Singleton.Instance.RegisteredPlayers.First(x => x.IsYourPlayer)); //} - GarbageCollect(); - StartCoroutine(GarbageCollectSIT()); + this.GetOrAddComponent(); StartCoroutine(SendPlayerStatePacket()); @@ -358,58 +357,7 @@ private void GameWorld_AfterGameStarted() ListOfInteractiveObjects = FindObjectsOfType(); } - private void GarbageCollect() - { - // Start the SIT Garbage Collector - Logger.LogDebug($"{nameof(GarbageCollect)}"); - BSGMemoryGC.RunHeapPreAllocation(); - BSGMemoryGC.Collect(force: true); - BSGMemoryGC.EmptyWorkingSet(); - BSGMemoryGC.GCEnabled = true; - //Resources.UnloadUnusedAssets(); - } - - /// - /// Runs the Garbage Collection every 5 minutes - /// - /// - private IEnumerator GarbageCollectSIT() - { - while(true) - { - if (PluginConfigSettings.Instance.AdvancedSettings.SETTING_EnableSITGC) - { - var nearestEnemyDist = float.MaxValue; - foreach(var p in Players) - { - if (p.Key == Singleton.Instance.MainPlayer.ProfileId) - continue; - - var dist = Vector3.Distance(p.Value.Transform.position, Singleton.Instance.MainPlayer.Transform.position); - if(dist < nearestEnemyDist) - nearestEnemyDist = dist; - } - - if (nearestEnemyDist > 10) - { - var mem = MemoryInfo.GetCurrentStatus(); - if (mem == null) - { - yield return new WaitForSeconds(1); - continue; - } - - var memPercentInUse = mem.dwMemoryLoad; - Logger.LogDebug($"Total memory used: {mem.dwMemoryLoad}%"); - if (memPercentInUse > PluginConfigSettings.Instance.AdvancedSettings.SETTING_SITGCMemoryThreshold) - GarbageCollect(); - - } - } - - yield return new WaitForSeconds(60); - } - } + /// /// This is a simple coroutine to allow methods to run every second. @@ -595,6 +543,7 @@ void OnDestroy() StopCoroutine(EverySecondCoroutine()); CoopPatches.EnableDisablePatches(); + GameObject.Destroy(this.GetComponent()); } TimeSpan LateUpdateSpan = TimeSpan.Zero; diff --git a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs new file mode 100644 index 00000000..dee92748 --- /dev/null +++ b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs @@ -0,0 +1,104 @@ +using Comfort.Common; +using EFT; +using StayInTarkov.Configuration; +using StayInTarkov.Memory; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace StayInTarkov.Coop.Components.CoopGameComponents +{ + public sealed class SITGameGCComponent : MonoBehaviour + { + private DateTime LastTimeRun { get; set; } = DateTime.MinValue; + private BepInEx.Logging.ManualLogSource Logger { get; set; } + + private int LastNumberOfPlayers { get; set; } + + private int NumberOfAlivePlayers => Singleton.Instance.AllAlivePlayersList.Count; + + #region Unity methods + + void Awake() + { + // ---------------------------------------------------- + // Create a BepInEx Logger for SITGameGCComponent + Logger = BepInEx.Logging.Logger.CreateLogSource(nameof(SITGameGCComponent)); + Logger.LogDebug($"{nameof(SITGameGCComponent)}:{nameof(Awake)}"); + } + + void Start() + { + Logger.LogDebug($"{nameof(SITGameGCComponent)}:{nameof(Start)}"); + GarbageCollect(); + } + + void Update() + { + if((DateTime.Now - LastTimeRun).Seconds > 30) + { + LastTimeRun = DateTime.Now; + GarbageCollectSIT(); + } + + if (NumberOfAlivePlayers != LastNumberOfPlayers) + { + LastNumberOfPlayers = NumberOfAlivePlayers; + BSGMemoryGC.Collect(force: false); + } + } + + #endregion + + private void GarbageCollect() + { + Logger.LogDebug($"{nameof(GarbageCollect)}"); + BSGMemoryGC.RunHeapPreAllocation(); + BSGMemoryGC.Collect(force: true); + BSGMemoryGC.EmptyWorkingSet(); + BSGMemoryGC.GCEnabled = true; + Resources.UnloadUnusedAssets(); + } + + /// + /// Runs the Garbage Collection every 5 minutes + /// + /// + private void GarbageCollectSIT() + { + if (!PluginConfigSettings.Instance.AdvancedSettings.SETTING_EnableSITGC) + return; + + var nearestEnemyDist = float.MaxValue; + foreach (var p in Singleton.Instance.AllAlivePlayersList) + { + if (p.ProfileId == Singleton.Instance.MainPlayer.ProfileId) + continue; + + var dist = Vector3.Distance(p.Transform.position, Singleton.Instance.MainPlayer.Transform.position); + if (dist < nearestEnemyDist) + nearestEnemyDist = dist; + } + + if (nearestEnemyDist > 10) + { + var mem = MemoryInfo.GetCurrentStatus(); + if (mem == null) + { + return; + } + + var memPercentInUse = mem.dwMemoryLoad; + Logger.LogDebug($"Total memory used: {mem.dwMemoryLoad}%"); + if (memPercentInUse > PluginConfigSettings.Instance.AdvancedSettings.SETTING_SITGCMemoryThreshold) + GarbageCollect(); + + } + } + + } +} From 4026eabbc1ae3f8315281b37861e01faba097f50 Mon Sep 17 00:00:00 2001 From: bullet <936368+devbence@users.noreply.github.com> Date: Wed, 17 Apr 2024 23:01:15 +0200 Subject: [PATCH 2/4] SITGC imprv - add SITGCMemoryCheckTime to for check interval - no more 105% Garbage Collector (min 50, max 95%) - move CheckTime and Threshold to Advanced Settings --- Source/Configuration/PluginConfigSettings.cs | 14 ++++++++++++-- .../CoopGameComponents/SITGameGCComponent.cs | 6 ++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Source/Configuration/PluginConfigSettings.cs b/Source/Configuration/PluginConfigSettings.cs index 6d9bb694..8d43dd53 100644 --- a/Source/Configuration/PluginConfigSettings.cs +++ b/Source/Configuration/PluginConfigSettings.cs @@ -38,6 +38,12 @@ public void GetSettings() } + internal sealed class ConfigurationManagerAttributes + { + public bool? IsAdvanced = false; + public bool? ShowRangeAsPercent; + } + public class SITAdvancedSettings { public const string Advanced = "Advanced"; @@ -46,7 +52,8 @@ public class SITAdvancedSettings public bool SETTING_EnableSITGC { get; set; } - public uint SETTING_SITGCMemoryThreshold { get; set; } + public double SETTING_SITGCMemoryThreshold { get; set; } + public uint SETTING_SITGCMemoryCheckTime { get; set; } public SITAdvancedSettings(ManualLogSource logger, ConfigFile config) { @@ -55,7 +62,10 @@ public SITAdvancedSettings(ManualLogSource logger, ConfigFile config) SETTING_EnableSITGC = StayInTarkovPlugin.Instance.Config.Bind (Advanced, "EnableSITGC", false, new ConfigDescription("Enable SIT's own Garbage Collector")).Value; SETTING_SITGCMemoryThreshold = StayInTarkovPlugin.Instance.Config.Bind - (Advanced, "SITGCMemoryThreshold", 90u, new ConfigDescription("SIT's Garbage Collector. System Memory % before SIT forces a Garbage Collection.")).Value; + (Advanced, "SITGCMemoryThreshold", 91d, new ConfigDescription("System Memory usage % limit, above that, SIT forces the run of Garbage Collection.", new AcceptableValueRange(50d, 95d), new ConfigurationManagerAttributes { IsAdvanced = true, ShowRangeAsPercent = true })).Value; + SETTING_SITGCMemoryCheckTime = StayInTarkovPlugin.Instance.Config.Bind + (Advanced, "SITGCMemoryCheckTime", 300u, new ConfigDescription("Set how many seconds to wait between SIT's Garbage Collector checks.", new AcceptableValueRange(60u, 900u), new ConfigurationManagerAttributes { IsAdvanced = true })).Value; + } } diff --git a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs index dee92748..4170352d 100644 --- a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs +++ b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs @@ -25,8 +25,6 @@ public sealed class SITGameGCComponent : MonoBehaviour void Awake() { - // ---------------------------------------------------- - // Create a BepInEx Logger for SITGameGCComponent Logger = BepInEx.Logging.Logger.CreateLogSource(nameof(SITGameGCComponent)); Logger.LogDebug($"{nameof(SITGameGCComponent)}:{nameof(Awake)}"); } @@ -39,7 +37,7 @@ void Start() void Update() { - if((DateTime.Now - LastTimeRun).Seconds > 30) + if((DateTime.Now - LastTimeRun).TotalSeconds > PluginConfigSettings.Instance.AdvancedSettings.SETTING_SITGCMemoryCheckTime) { LastTimeRun = DateTime.Now; GarbageCollectSIT(); @@ -65,7 +63,7 @@ private void GarbageCollect() } /// - /// Runs the Garbage Collection every 5 minutes + /// Runs the Garbage Collection /// /// private void GarbageCollectSIT() From 6a9efdf3c1df74c79eb9e9a0483e17d36b93ab7c Mon Sep 17 00:00:00 2001 From: bullet <936368+devbence@users.noreply.github.com> Date: Wed, 17 Apr 2024 23:50:47 +0200 Subject: [PATCH 3/4] SITGC improv2 - NumberOfAlivePlayers to inline - Threshold back to uint.. we dont need floats --- Source/Configuration/PluginConfigSettings.cs | 4 ++-- .../Components/CoopGameComponents/SITGameGCComponent.cs | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Source/Configuration/PluginConfigSettings.cs b/Source/Configuration/PluginConfigSettings.cs index 8d43dd53..3260bc35 100644 --- a/Source/Configuration/PluginConfigSettings.cs +++ b/Source/Configuration/PluginConfigSettings.cs @@ -52,7 +52,7 @@ public class SITAdvancedSettings public bool SETTING_EnableSITGC { get; set; } - public double SETTING_SITGCMemoryThreshold { get; set; } + public uint SETTING_SITGCMemoryThreshold { get; set; } public uint SETTING_SITGCMemoryCheckTime { get; set; } public SITAdvancedSettings(ManualLogSource logger, ConfigFile config) @@ -62,7 +62,7 @@ public SITAdvancedSettings(ManualLogSource logger, ConfigFile config) SETTING_EnableSITGC = StayInTarkovPlugin.Instance.Config.Bind (Advanced, "EnableSITGC", false, new ConfigDescription("Enable SIT's own Garbage Collector")).Value; SETTING_SITGCMemoryThreshold = StayInTarkovPlugin.Instance.Config.Bind - (Advanced, "SITGCMemoryThreshold", 91d, new ConfigDescription("System Memory usage % limit, above that, SIT forces the run of Garbage Collection.", new AcceptableValueRange(50d, 95d), new ConfigurationManagerAttributes { IsAdvanced = true, ShowRangeAsPercent = true })).Value; + (Advanced, "SITGCMemoryThreshold", 90u, new ConfigDescription("System Memory usage % limit, above that, SIT forces the run of Garbage Collection.", new AcceptableValueRange(50u, 95u), new ConfigurationManagerAttributes { IsAdvanced = true, ShowRangeAsPercent = true })).Value; SETTING_SITGCMemoryCheckTime = StayInTarkovPlugin.Instance.Config.Bind (Advanced, "SITGCMemoryCheckTime", 300u, new ConfigDescription("Set how many seconds to wait between SIT's Garbage Collector checks.", new AcceptableValueRange(60u, 900u), new ConfigurationManagerAttributes { IsAdvanced = true })).Value; diff --git a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs index 4170352d..c9ae3226 100644 --- a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs +++ b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs @@ -19,7 +19,13 @@ public sealed class SITGameGCComponent : MonoBehaviour private int LastNumberOfPlayers { get; set; } - private int NumberOfAlivePlayers => Singleton.Instance.AllAlivePlayersList.Count; + private int NumberOfAlivePlayers + { + get + { + return Singleton.Instance.AllAlivePlayersList.Count; + } + } #region Unity methods From 9ce9f68733a6c86d72a5ba64b77e0a2658818334 Mon Sep 17 00:00:00 2001 From: bullet <936368+devbence@users.noreply.github.com> Date: Thu, 18 Apr 2024 00:20:53 +0200 Subject: [PATCH 4/4] Update SITGameGCComponent.cs --- .../Components/CoopGameComponents/SITGameGCComponent.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs index c9ae3226..4170352d 100644 --- a/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs +++ b/Source/Coop/Components/CoopGameComponents/SITGameGCComponent.cs @@ -19,13 +19,7 @@ public sealed class SITGameGCComponent : MonoBehaviour private int LastNumberOfPlayers { get; set; } - private int NumberOfAlivePlayers - { - get - { - return Singleton.Instance.AllAlivePlayersList.Count; - } - } + private int NumberOfAlivePlayers => Singleton.Instance.AllAlivePlayersList.Count; #region Unity methods