using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Agents; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Enemies; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using PerformanceTrafficControl.Api; using PerformanceTrafficControl.Core; using PerformanceTrafficControl.Modules; using PerformanceTrafficControl.Optimization; using PerformanceTrafficControl.Performance; using UnityEngine; using UnityEngine.Rendering; using WindVolume; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Performance Traffic Control")] [assembly: AssemblyProduct("Performance Traffic Control")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.1.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace PerformanceTrafficControl.Performance { internal sealed class AdaptivePerformanceModule : TrafficControlModuleBase { private const float SampleInterval = 0.25f; private const float InitialWarmupSeconds = 5f; private const float EnvironmentCheckInterval = 10f; private const float MaximumValidSampleSeconds = 1.5f; private const float MinimumValidFps = 5f; private const float MaximumValidFps = 500f; private const float FpsSmoothingAlpha = 0.35f; private const float DefaultHighTriggerRatio = 0.85f; private const float DefaultCriticalTriggerRatio = 0.75f; private const float HighRecoveryRatio = 0.9f; private const float CriticalRecoveryRatio = 0.86f; private const int HighEnterSampleCount = 6; private const int CriticalEnterSampleCount = 3; private const int HighRecoverySampleCount = 32; private const int CriticalRecoverySampleCount = 20; private const int BaselineSamplesPerWindow = 8; private const int BaselineWindowCapacity = 20; private const int MinimumBaselineWindowCount = 12; private const float StableWindowLowerRatio = 0.82f; private const float StableWindowUpperRatio = 1.18f; private const float BaselinePercentile = 0.65f; private const float BaselinePersistInterval = 60f; private const float AudioStatePruneInterval = 10f; private const float DiagnosticInterval = 30f; private readonly float[] _stableBaselineWindows = new float[20]; private readonly float[] _baselineSortScratch = new float[20]; private TrafficControlConfig? _config; private bool _profileInitialized; private bool _sampleAnchorSet; private string _environmentFingerprint = string.Empty; private float _monitoringStartsAt; private float _nextSampleAt; private float _nextEnvironmentCheckAt; private float _lastSampleRealtime; private int _lastSampleFrame; private float _latestWindowFps; private float _smoothedFps; private float _baselineFps; private float _lastPersistedBaselineFps; private float _nextBaselinePersistAt; private float _baselineWindowFpsSum; private float _baselineWindowMinFps; private float _baselineWindowMaxFps; private int _baselineWindowSampleCount; private int _stableBaselineWindowCount; private int _stableBaselineWindowWriteIndex; private int _highPressureSamples; private int _criticalPressureSamples; private int _recoverySamples; private float _nextAudioStatePruneAt; private float _nextDiagnosticAt; public override string Name => "Adaptive performance pressure"; private bool AdaptivePerformanceEnabled => _config?.AdaptivePerformanceEnabled.Value ?? true; private float HighTriggerRatio { get { float num = _config?.HighTriggerRatio.Value ?? 0.85f; if (!float.IsNaN(num)) { return Mathf.Clamp(num, 0.5f, 0.95f); } return 0.85f; } } private float CriticalTriggerRatio { get { float num = _config?.CriticalTriggerRatio.Value ?? 0.75f; if (!float.IsNaN(num)) { return Mathf.Clamp(num, 0.3f, HighTriggerRatio - 0.05f); } return 0.75f; } } public override void Initialize(TrafficControlModuleContext context) { _config = context.Config; _config.AdaptivePerformanceEnabled.SettingChanged += delegate { HandleAdaptiveSettingsChanged(); }; _config.HighTriggerRatio.SettingChanged += delegate { ResetPressureCounters(); }; _config.CriticalTriggerRatio.SettingChanged += delegate { ResetPressureCounters(); }; _config.ResetLearnedBaseline.SettingChanged += delegate { HandleResetRequested(); }; HandleResetRequested(); } public override void Tick(float now, bool isInLevel) { if (!isInLevel || !AdaptivePerformanceEnabled) { SetLevel(PerformancePressureLevel.Normal, isInLevel ? "adaptive performance disabled" : "outside an active level"); SuspendSampling(); } else if (!_profileInitialized) { InitializeEnvironmentProfile(now); } else if (_monitoringStartsAt <= 0f) { _monitoringStartsAt = now + 5f; _nextSampleAt = _monitoringStartsAt; } else { if (now < _monitoringStartsAt || now < _nextSampleAt) { return; } _nextSampleAt = now + 0.25f; if (!Application.isFocused) { ResetSampleAnchor(); ResetPressureCounters(); return; } if (now >= _nextEnvironmentCheckAt) { _nextEnvironmentCheckAt = now + 10f; string text = BuildEnvironmentFingerprint(); if (!string.Equals(text, _environmentFingerprint, StringComparison.Ordinal)) { InitializeEnvironmentProfile(now, text); return; } } SamplePerformance(now); RunMaintenance(now); } } public override void OnLevelEntered() { _monitoringStartsAt = 0f; _nextSampleAt = 0f; _nextDiagnosticAt = 0f; _nextAudioStatePruneAt = 0f; ResetSampleAnchor(); ResetPressureCounters(); ResetBaselineAccumulator(); } public override void OnLevelExited() { PersistLearnedProfile(float.MaxValue, force: true); SetLevel(PerformancePressureLevel.Normal, "level exited"); SuspendSampling(); ResetPressureCounters(); ResetBaselineAccumulator(); TrafficControlPerformance.ResetForLevelExit(); TrafficControlPerformance.UpdateMeasurements(0f, _baselineFps); } private void SamplePerformance(float now) { float realtimeSinceStartup = Time.realtimeSinceStartup; int frameCount = Time.frameCount; if (!_sampleAnchorSet) { _sampleAnchorSet = true; _lastSampleRealtime = realtimeSinceStartup; _lastSampleFrame = frameCount; return; } float num = realtimeSinceStartup - _lastSampleRealtime; int num2 = frameCount - _lastSampleFrame; _lastSampleRealtime = realtimeSinceStartup; _lastSampleFrame = frameCount; if (num <= 0.05f || num > 1.5f || num2 <= 0) { ResetPressureCounters(); ResetBaselineAccumulator(); return; } float num3 = (float)num2 / num; if (num3 < 5f || num3 > 500f) { ResetPressureCounters(); ResetBaselineAccumulator(); return; } _latestWindowFps = num3; _smoothedFps = ((_smoothedFps <= 0.01f) ? num3 : Mathf.Lerp(_smoothedFps, num3, 0.35f)); TrafficControlPerformance.UpdateMeasurements(_smoothedFps, _baselineFps); AccumulateBaselineSample(num3, now); if (_baselineFps > 0f) { EvaluatePressure(); } } private void EvaluatePressure() { float num = _baselineFps * HighTriggerRatio; float num2 = _baselineFps * CriticalTriggerRatio; _highPressureSamples = ((_smoothedFps < num) ? (_highPressureSamples + 1) : 0); _criticalPressureSamples = ((_smoothedFps < num2) ? (_criticalPressureSamples + 1) : 0); switch (TrafficControlPerformance.Level) { case PerformancePressureLevel.Normal: _recoverySamples = 0; if (_criticalPressureSamples >= 3) { SetLevel(PerformancePressureLevel.Critical, "FPS stayed below the learned critical ratio"); } else if (_highPressureSamples >= 6) { SetLevel(PerformancePressureLevel.High, "FPS stayed below the learned high ratio"); } break; case PerformancePressureLevel.High: if (_criticalPressureSamples >= 3) { SetLevel(PerformancePressureLevel.Critical, "FPS stayed below the learned critical ratio"); break; } _recoverySamples = ((_smoothedFps >= _baselineFps * 0.9f) ? (_recoverySamples + 1) : 0); if (_recoverySamples >= 32) { SetLevel(PerformancePressureLevel.Normal, "FPS recovered toward the learned baseline"); } break; case PerformancePressureLevel.Critical: _recoverySamples = ((_smoothedFps >= _baselineFps * 0.86f) ? (_recoverySamples + 1) : 0); if (_recoverySamples >= 20) { SetLevel(PerformancePressureLevel.High, "FPS recovered from critical pressure"); } break; } } private void AccumulateBaselineSample(float windowFps, float now) { if (_baselineWindowSampleCount == 0) { _baselineWindowMinFps = windowFps; _baselineWindowMaxFps = windowFps; } else { _baselineWindowMinFps = Mathf.Min(_baselineWindowMinFps, windowFps); _baselineWindowMaxFps = Mathf.Max(_baselineWindowMaxFps, windowFps); } _baselineWindowFpsSum += windowFps; _baselineWindowSampleCount++; if (_baselineWindowSampleCount < 8) { return; } float num = _baselineWindowFpsSum / (float)_baselineWindowSampleCount; bool num2 = _baselineWindowMinFps >= num * 0.82f && _baselineWindowMaxFps <= num * 1.18f; ResetBaselineAccumulator(); if (!num2) { return; } _stableBaselineWindows[_stableBaselineWindowWriteIndex] = num; _stableBaselineWindowWriteIndex = (_stableBaselineWindowWriteIndex + 1) % 20; _stableBaselineWindowCount = Math.Min(20, _stableBaselineWindowCount + 1); if (_stableBaselineWindowCount >= 12) { float num3 = CalculateBaselineCandidate(); if (_baselineFps <= 0f) { _baselineFps = num3; TrafficControlPerformance.UpdateMeasurements(_smoothedFps, _baselineFps); PersistLearnedProfile(now, force: true); TrafficControlLog.Info($"[PTC_PERF] Learned initial baseline {_baselineFps:0.0} FPS. " + $"High<{_baselineFps * HighTriggerRatio:0.0} Critical<{_baselineFps * CriticalTriggerRatio:0.0}."); } else if (!(num3 <= _baselineFps * 1.01f)) { float num4 = Mathf.Max(0.5f, _baselineFps * 0.005f); _baselineFps = Mathf.Min(num3, _baselineFps + num4); TrafficControlPerformance.UpdateMeasurements(_smoothedFps, _baselineFps); PersistLearnedProfile(now, force: false); } } } private float CalculateBaselineCandidate() { for (int i = 0; i < _stableBaselineWindowCount; i++) { _baselineSortScratch[i] = _stableBaselineWindows[i]; } Array.Sort(_baselineSortScratch, 0, _stableBaselineWindowCount); int num = Mathf.RoundToInt((float)(_stableBaselineWindowCount - 1) * 0.65f); return Mathf.Clamp(_baselineSortScratch[num], 5f, 500f); } private void InitializeEnvironmentProfile(float now, string? fingerprint = null) { if (fingerprint == null) { fingerprint = BuildEnvironmentFingerprint(); } string b = _config?.LearnedProfileFingerprint.Value ?? string.Empty; float num = _config?.LearnedBaselineFps.Value ?? 0f; bool flag = string.Equals(fingerprint, b, StringComparison.Ordinal) && !float.IsNaN(num) && num >= 5f; _environmentFingerprint = fingerprint; _profileInitialized = true; _baselineFps = (flag ? Mathf.Clamp(num, 5f, 500f) : 0f); _lastPersistedBaselineFps = _baselineFps; _latestWindowFps = 0f; _smoothedFps = 0f; _monitoringStartsAt = now + 5f; _nextSampleAt = _monitoringStartsAt; _nextEnvironmentCheckAt = now + 10f; _nextBaselinePersistAt = now + 60f; ResetSampleAnchor(); ResetPressureCounters(); ClearBaselineLearningState(); SetLevel(PerformancePressureLevel.Normal, flag ? "performance profile initialized" : "graphics profile changed; learning a new baseline"); TrafficControlPerformance.UpdateMeasurements(0f, _baselineFps); if (!flag && _config != null) { _config.LearnedBaselineFps.Value = 0f; _config.LearnedProfileFingerprint.Value = fingerprint; } TrafficControlLog.Info(flag ? $"[PTC_PERF] Loaded baseline {_baselineFps:0.0} FPS; sampling at 4 Hz." : "[PTC_PERF] No matching graphics profile; learning a baseline after warmup."); } private static string BuildEnvironmentFingerprint() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) try { return $"GPU={SystemInfo.graphicsDeviceName}|Screen={Screen.width}x{Screen.height}|" + $"Display={Screen.currentResolution}|Fullscreen={Screen.fullScreen}|" + $"Quality={QualitySettings.GetQualityLevel()}|VSync={QualitySettings.vSyncCount}|" + $"Target={Application.targetFrameRate}"; } catch (Exception ex) { TrafficControlLog.InfoRateLimited("Performance:EnvironmentFingerprint", "[PTC_PERF] Could not read graphics profile: " + ex.Message, 30f); return "GraphicsEnvironmentUnavailable"; } } private void PersistLearnedProfile(float now, bool force) { if (_config == null || !_profileInitialized || _baselineFps < 5f) { return; } bool flag = _lastPersistedBaselineFps <= 0f || Mathf.Abs(_baselineFps - _lastPersistedBaselineFps) >= Mathf.Max(2f, _lastPersistedBaselineFps * 0.02f); if (force || (!(now < _nextBaselinePersistAt) && flag)) { if (!string.Equals(_config.LearnedProfileFingerprint.Value, _environmentFingerprint, StringComparison.Ordinal)) { _config.LearnedProfileFingerprint.Value = _environmentFingerprint; } if (Mathf.Abs(_config.LearnedBaselineFps.Value - _baselineFps) >= 0.05f) { _config.LearnedBaselineFps.Value = _baselineFps; } _lastPersistedBaselineFps = _baselineFps; _nextBaselinePersistAt = now + 60f; } } private void RunMaintenance(float now) { if (now >= _nextAudioStatePruneAt) { _nextAudioStatePruneAt = now + 10f; TrafficControlPerformance.PruneAudioState(now, 10f); } TrafficControlConfig? config = _config; if (config != null && config.PerformanceDiagnosticsEnabled.Value && !(now < _nextDiagnosticAt)) { _nextDiagnosticAt = now + 30f; float num = Mathf.Clamp01((float)_stableBaselineWindowCount / 12f) * 100f; TrafficControlLog.Info($"[PTC_PERF] Level={TrafficControlPerformance.Level} FPS={_smoothedFps:0.0} " + $"WindowFPS={_latestWindowFps:0.0} Baseline={_baselineFps:0.0} Confidence={num:0}% " + $"DeniedPhysics={TrafficControlPerformance.DeniedPhysicsQueries} " + $"DeniedVisual={TrafficControlPerformance.DeniedVisualSpawns} " + $"DeniedAudio={TrafficControlPerformance.DeniedAudioEvents}."); } } private void HandleAdaptiveSettingsChanged() { ResetPressureCounters(); SuspendSampling(); if (!AdaptivePerformanceEnabled) { SetLevel(PerformancePressureLevel.Normal, "disabled by config"); } } private void HandleResetRequested() { TrafficControlConfig? config = _config; if (config != null && config.ResetLearnedBaseline.Value) { ClearLearnedProfile("config reset requested"); _config.ResetLearnedBaseline.Value = false; } } private void ClearLearnedProfile(string reason) { _profileInitialized = false; _environmentFingerprint = string.Empty; _baselineFps = 0f; _lastPersistedBaselineFps = 0f; _latestWindowFps = 0f; _smoothedFps = 0f; SuspendSampling(); ResetPressureCounters(); ClearBaselineLearningState(); if (_config != null) { _config.LearnedBaselineFps.Value = 0f; _config.LearnedProfileFingerprint.Value = string.Empty; } SetLevel(PerformancePressureLevel.Normal, reason); TrafficControlPerformance.UpdateMeasurements(0f, 0f); TrafficControlLog.Info("[PTC_PERF] Cleared learned baseline. Reason=" + reason + "."); } private void SuspendSampling() { _monitoringStartsAt = 0f; _nextSampleAt = 0f; ResetSampleAnchor(); ResetBaselineAccumulator(); } private void ResetSampleAnchor() { _sampleAnchorSet = false; _lastSampleRealtime = 0f; _lastSampleFrame = 0; } private void ResetPressureCounters() { _highPressureSamples = 0; _criticalPressureSamples = 0; _recoverySamples = 0; } private void ResetBaselineAccumulator() { _baselineWindowFpsSum = 0f; _baselineWindowMinFps = 0f; _baselineWindowMaxFps = 0f; _baselineWindowSampleCount = 0; } private void ClearBaselineLearningState() { ResetBaselineAccumulator(); Array.Clear(_stableBaselineWindows, 0, _stableBaselineWindows.Length); Array.Clear(_baselineSortScratch, 0, _baselineSortScratch.Length); _stableBaselineWindowCount = 0; _stableBaselineWindowWriteIndex = 0; } private void SetLevel(PerformancePressureLevel level, string reason) { if (TrafficControlPerformance.Level != level) { PerformancePressureLevel level2 = TrafficControlPerformance.Level; ResetPressureCounters(); TrafficControlPerformance.UpdateMeasurements(_smoothedFps, _baselineFps); TrafficControlPerformance.SetPressure(level); TrafficControlLog.Info($"[PTC_PERF] Pressure {level2} -> {level}. FPS={_smoothedFps:0.0}, " + $"Baseline={_baselineFps:0.0}. Reason={reason}."); } } } } namespace PerformanceTrafficControl.Optimization { internal sealed class EnemyVisualOptimizationModule : TrafficControlModuleBase { public override string Name => "Adaptive enemy visual optimization"; public override void Initialize(TrafficControlModuleContext context) { EnemyVisualRuntime.Configure(context.Config); context.Harmony.PatchAll(typeof(EnemyVisualPatches)); } public override void OnLevelEntered() { EnemyVisualRuntime.OnLevelEntered(); } public override void OnLevelExited() { EnemyVisualRuntime.OnLevelExited(); } } internal static class EnemyVisualRuntime { private sealed class EnemyVisualState { private readonly RendererEntry[] _renderers; private bool _shadowsSuppressed; internal EnemyAgent Enemy { get; set; } internal bool Alive { get; set; } internal bool Active { get; set; } private EnemyVisualState(EnemyAgent enemy, RendererEntry[] renderers) { Enemy = enemy; _renderers = renderers; Alive = IsEnemyAlive(enemy); } internal static EnemyVisualState Capture(EnemyAgent enemy) { try { Il2CppArrayBase componentsInChildren = ((Component)enemy).GetComponentsInChildren(true); RendererEntry[] array = new RendererEntry[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { array[i] = new RendererEntry(componentsInChildren[i]); } return new EnemyVisualState(enemy, array); } catch (Exception ex) { TrafficControlLog.InfoRateLimited("EnemyVisuals:Capture", "[EnemyVisuals] Failed to cache enemy renderers: " + ex.Message, 2f); return new EnemyVisualState(enemy, Array.Empty()); } } internal void SuppressShadows() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _renderers.Length; i++) { RendererEntry rendererEntry = _renderers[i]; Renderer renderer = rendererEntry.Renderer; if ((Object)(object)renderer != (Object)null && (int)renderer.shadowCastingMode != 0) { if (!_shadowsSuppressed) { rendererEntry.ShadowMode = renderer.shadowCastingMode; } renderer.shadowCastingMode = (ShadowCastingMode)0; } } _shadowsSuppressed = true; } internal void RestoreShadows() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!_shadowsSuppressed) { return; } for (int i = 0; i < _renderers.Length; i++) { RendererEntry rendererEntry = _renderers[i]; if ((Object)(object)rendererEntry.Renderer != (Object)null && rendererEntry.Renderer.shadowCastingMode != rendererEntry.ShadowMode) { rendererEntry.Renderer.shadowCastingMode = rendererEntry.ShadowMode; } } _shadowsSuppressed = false; } } private sealed class RagdollState { internal ES_Dead DeadState { get; } internal LinkedListNode Node { get; } internal RagdollState(ES_Dead deadState, LinkedListNode node) { DeadState = deadState; Node = node; } } private sealed class RendererEntry { internal Renderer Renderer { get; } internal ShadowCastingMode ShadowMode { get; set; } internal RendererEntry(Renderer renderer) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Renderer = renderer; ShadowMode = (ShadowCastingMode)(((Object)(object)renderer != (Object)null) ? ((int)renderer.shadowCastingMode) : 0); } } private static readonly Dictionary Enemies = new Dictionary(); private static readonly Dictionary Ragdolls = new Dictionary(); private static readonly LinkedList RagdollOrder = new LinkedList(); private static TrafficControlConfig? s_config; private static bool s_levelActive; private static bool s_pressureActive; private static int s_activeEnemyCount; internal static bool Enabled => s_config?.EnemyVisualOptimizationEnabled.Value ?? false; internal static int ActiveEnemyCount => s_activeEnemyCount; internal static int RagdollCount => Ragdolls.Count; private static int MaximumRagdolls => Math.Max(0, s_config?.MaximumRagdollsUnderPressure.Value ?? 12); internal static void Configure(TrafficControlConfig config) { s_config = config; TrafficControlPerformance.PressureChanged += OnPressureChanged; config.EnemyVisualOptimizationEnabled.SettingChanged += delegate { OnEnabledSettingChanged(); }; config.MaximumRagdollsUnderPressure.SettingChanged += delegate { ReapplyPressureSettings(); }; config.CorpseDecaySecondsUnderPressure.SettingChanged += delegate { ReapplyPressureSettings(); }; } internal static void OnLevelEntered() { s_levelActive = true; UpdatePressureMode(); } internal static void OnLevelExited() { s_levelActive = false; s_pressureActive = false; RestoreAllShadows(); Enemies.Clear(); Ragdolls.Clear(); RagdollOrder.Clear(); s_activeEnemyCount = 0; } internal static void RegisterEnemy(EnemyAgent? enemy) { if (!Enabled || (Object)(object)enemy == (Object)null) { return; } ulong enemyKey = GetEnemyKey(enemy); if (enemyKey != 0L) { if (!Enemies.TryGetValue(enemyKey, out EnemyVisualState value)) { value = EnemyVisualState.Capture(enemy); Enemies[enemyKey] = value; } else { value.Enemy = enemy; } SetActiveState(value, IsActiveEnemy(enemy)); if (s_pressureActive) { value.SuppressShadows(); } } } internal static void OnModeChanged(EnemyAI? ai) { RegisterEnemy((ai != null) ? ai.m_enemyAgent : null); } internal static void OnEnemyDamaged(EnemyAgent? enemy) { if (Enabled && !((Object)(object)enemy == (Object)null) && IsEnemyAlive(enemy)) { EnemyVisualState orRegister = GetOrRegister(enemy); if (orRegister != null) { SetActiveState(orRegister, active: true); } } } internal static void OnEnemyDead(EnemyAgent? enemy) { if ((Object)(object)enemy == (Object)null) { return; } EnemyVisualState orRegister = GetOrRegister(enemy); if (orRegister != null) { orRegister.Alive = false; SetActiveState(orRegister, active: false); if (s_pressureActive) { orRegister.SuppressShadows(); } } } internal static void OnEnemyDespawned(EnemyAgent? enemy) { ulong enemyKey = GetEnemyKey(enemy); if (enemyKey == 0L) { return; } if (Enemies.TryGetValue(enemyKey, out EnemyVisualState value)) { if (value.Active) { s_activeEnemyCount = Math.Max(0, s_activeEnemyCount - 1); } value.RestoreShadows(); Enemies.Remove(enemyKey); } RemoveRagdoll(enemyKey); } internal static void AdjustDecayDuration(ref float duration) { if (s_pressureActive) { float num = s_config?.CorpseDecaySecondsUnderPressure.Value ?? 0.01f; duration = (float.IsNaN(num) ? 0.01f : Mathf.Clamp(num, 0.01f, 30f)); } } internal static void OnDeadStateEntered(ES_Dead? deadState) { if (s_pressureActive) { GetOrRegister(TryGetDeadEnemy(deadState))?.SuppressShadows(); } } internal static void OnRagdollStateChanged(ES_Dead? deadState, bool enabled) { if (!Enabled || deadState == null) { return; } ulong enemyKey = GetEnemyKey(TryGetDeadEnemy(deadState)); if (enemyKey == 0L) { return; } if (!enabled) { RemoveRagdoll(enemyKey); return; } RemoveRagdoll(enemyKey); LinkedListNode node = RagdollOrder.AddLast(enemyKey); Ragdolls[enemyKey] = new RagdollState(deadState, node); if (s_pressureActive) { TrimRagdolls(MaximumRagdolls, disableRagdoll: true); } else { TrimRagdolls(Math.Max(64, MaximumRagdolls * 4), disableRagdoll: false); } } private static void OnPressureChanged(PerformancePressureLevel previous, PerformancePressureLevel current) { UpdatePressureMode(); } private static void OnEnabledSettingChanged() { if (!Enabled) { s_pressureActive = false; RestoreAllShadows(); Enemies.Clear(); Ragdolls.Clear(); RagdollOrder.Clear(); s_activeEnemyCount = 0; } else { UpdatePressureMode(); } } private static void ReapplyPressureSettings() { if (s_pressureActive) { TrimRagdolls(MaximumRagdolls, disableRagdoll: true); } } private static void UpdatePressureMode() { bool flag = Enabled && s_levelActive && TrafficControlPerformance.IsHighOrWorse; if (flag == s_pressureActive) { return; } s_pressureActive = flag; if (flag) { foreach (EnemyVisualState value in Enemies.Values) { value.SuppressShadows(); } TrimRagdolls(MaximumRagdolls, disableRagdoll: true); TrafficControlLog.Info($"[EnemyVisuals] Pressure mode enabled. Level={TrafficControlPerformance.Level} " + $"FPS={TrafficControlPerformance.SmoothedFps:0.0}/{TrafficControlPerformance.LearnedBaselineFps:0.0} " + $"ActiveEnemies={s_activeEnemyCount} Ragdolls={Ragdolls.Count}/{MaximumRagdolls}."); } else { RestoreAllShadows(); TrafficControlLog.Info("[EnemyVisuals] Pressure mode disabled; cached shadow modes restored."); } } private static EnemyVisualState? GetOrRegister(EnemyAgent? enemy) { if (!Enabled || (Object)(object)enemy == (Object)null) { return null; } ulong enemyKey = GetEnemyKey(enemy); if (enemyKey == 0L) { return null; } if (Enemies.TryGetValue(enemyKey, out EnemyVisualState value)) { value.Enemy = enemy; return value; } value = EnemyVisualState.Capture(enemy); Enemies[enemyKey] = value; return value; } private static void SetActiveState(EnemyVisualState state, bool active) { state.Alive = IsEnemyAlive(state.Enemy); active &= state.Alive; if (state.Active != active) { state.Active = active; s_activeEnemyCount += (active ? 1 : (-1)); if (s_activeEnemyCount < 0) { s_activeEnemyCount = 0; } } } private static bool IsActiveEnemy(EnemyAgent enemy) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if (!IsEnemyAlive(enemy) || (Object)(object)enemy.AI == (Object)null) { return false; } try { AgentMode mode = ((AgentAI)enemy.AI).Mode; return (int)mode != 4 && (int)mode > 0; } catch { return false; } } private static bool IsEnemyAlive(EnemyAgent? enemy) { if ((Object)(object)enemy == (Object)null || !((Agent)enemy).Alive) { return false; } try { return (Object)(object)enemy.Damage != (Object)null && ((Dam_SyncedDamageBase)enemy.Damage).Health > 0f; } catch { return true; } } private static ulong GetEnemyKey(EnemyAgent? enemy) { if ((Object)(object)enemy == (Object)null) { return 0uL; } try { return (uint)((Object)enemy).GetInstanceID(); } catch { return 0uL; } } private static EnemyAgent? TryGetDeadEnemy(ES_Dead? deadState) { try { object result; if (deadState == null) { result = null; } else { EnemyRagdollBodyController bodyController = deadState.m_bodyController; result = ((bodyController != null) ? bodyController.m_owner : null); } return (EnemyAgent?)result; } catch { return null; } } private static void TrimRagdolls(int maximum, bool disableRagdoll) { while (Ragdolls.Count > maximum && RagdollOrder.First != null) { ulong value = RagdollOrder.First.Value; if (!Ragdolls.TryGetValue(value, out RagdollState value2)) { RagdollOrder.RemoveFirst(); continue; } Ragdolls.Remove(value); RagdollOrder.Remove(value2.Node); if (!disableRagdoll) { continue; } try { if (value2.DeadState != null) { value2.DeadState.SetRagdollEnabled(false); } } catch (Exception ex) { TrafficControlLog.InfoRateLimited("EnemyVisuals:RagdollDisable", "[EnemyVisuals] Failed to disable an expired ragdoll: " + ex.Message, 2f); } } } private static void RemoveRagdoll(ulong key) { if (Ragdolls.TryGetValue(key, out RagdollState value)) { Ragdolls.Remove(key); RagdollOrder.Remove(value.Node); } } private static void RestoreAllShadows() { foreach (EnemyVisualState value in Enemies.Values) { value.RestoreShadows(); } } } [HarmonyPatch] internal static class EnemyVisualPatches { [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAgent), "Setup")] private static void EnemyAgentSetupPostfix(EnemyAgent __instance) { RunSafe(delegate { EnemyVisualRuntime.RegisterEnemy(__instance); }, "register enemy"); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "ModeChange")] private static void EnemyAiModeChangePostfix(EnemyAI __instance) { RunSafe(delegate { EnemyVisualRuntime.OnModeChanged(__instance); }, "update enemy mode"); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAgent), "OnTakeDamage")] private static void EnemyAgentTakeDamagePostfix(EnemyAgent __instance) { RunSafe(delegate { EnemyVisualRuntime.OnEnemyDamaged(__instance); }, "wake damaged enemy"); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyAgent), "OnDead")] private static void EnemyAgentOnDeadPrefix(EnemyAgent __instance) { RunSafe(delegate { EnemyVisualRuntime.OnEnemyDead(__instance); }, "record enemy death"); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyAgent), "OnDeSpawn")] private static void EnemyAgentOnDespawnPrefix(EnemyAgent __instance) { RunSafe(delegate { EnemyVisualRuntime.OnEnemyDespawned(__instance); }, "remove despawned enemy"); } [HarmonyPrefix] [HarmonyPatch(typeof(ES_Dead), "DecayDelayed")] private static void EnemyDecayPrefix(ref float duration) { EnemyVisualRuntime.AdjustDecayDuration(ref duration); } [HarmonyPostfix] [HarmonyPatch(typeof(ES_Dead), "CommonEnter")] private static void EnemyDeadEnterPostfix(ES_Dead __instance) { RunSafe(delegate { EnemyVisualRuntime.OnDeadStateEntered(__instance); }, "suppress corpse shadows"); } [HarmonyPostfix] [HarmonyPatch(typeof(ES_Dead), "SetRagdollEnabled")] private static void EnemyRagdollPostfix(ES_Dead __instance, bool enabled) { RunSafe(delegate { EnemyVisualRuntime.OnRagdollStateChanged(__instance, enabled); }, "update ragdoll budget"); } private static void RunSafe(Action action, string operation) { try { action(); } catch (Exception ex) { TrafficControlLog.InfoRateLimited("EnemyVisuals:" + operation, "[EnemyVisuals] Failed to " + operation + ": " + ex.Message, 2f); } } } internal sealed class WindVolumeCapacityModule : TrafficControlModuleBase { public override string Name => "WindVolume capacity guard"; public override void Initialize(TrafficControlModuleContext context) { WindVolumeCapacityPatches.Configure(context.Config); context.Harmony.PatchAll(typeof(WindVolumeCapacityPatches)); } } [HarmonyPatch(typeof(WindVolumeCamera), "UpdateVolume")] internal static class WindVolumeCapacityPatches { private static readonly List Suppressed = new List(); private static TrafficControlConfig? s_config; private static float s_nextReportAt; internal static void Configure(TrafficControlConfig config) { s_config = config; } [HarmonyPrefix] private static void Prefix() { Suppressed.Clear(); TrafficControlConfig? trafficControlConfig = s_config; if (trafficControlConfig == null || !trafficControlConfig.WindVolumeCapacityGuardEnabled.Value) { return; } HashSet instances = WindVolumeAffector.instances; if (instances == null) { return; } int mAX_AFFECTOR_COUNT = WindVolumeCamera.MAX_AFFECTOR_COUNT; if (mAX_AFFECTOR_COUNT <= 0 || instances.Count <= mAX_AFFECTOR_COUNT) { return; } int num = 0; Enumerator enumerator = instances.GetEnumerator(); while (enumerator.MoveNext()) { WindVolumeAffector current = enumerator.Current; if (!((Object)(object)current == (Object)null) && num++ >= mAX_AFFECTOR_COUNT) { Suppressed.Add(current); } } for (int i = 0; i < Suppressed.Count; i++) { instances.Remove(Suppressed[i]); } if (Time.unscaledTime >= s_nextReportAt) { TrafficControlLog.Warning($"[WindVolumeGuard] Affectors={instances.Count + Suppressed.Count}/{mAX_AFFECTOR_COUNT} " + $"suppressed={Suppressed.Count}."); s_nextReportAt = Time.unscaledTime + 30f; } } [HarmonyFinalizer] private static void Finalizer() { HashSet instances = WindVolumeAffector.instances; if (instances != null) { for (int i = 0; i < Suppressed.Count; i++) { WindVolumeAffector val = Suppressed[i]; if ((Object)(object)val != (Object)null) { instances.Add(val); } } } Suppressed.Clear(); } } } namespace PerformanceTrafficControl.Modules { internal interface ITrafficControlModule { string Name { get; } void Initialize(TrafficControlModuleContext context); void Tick(float now, bool isInLevel); void OnLevelEntered(); void OnLevelExited(); } internal abstract class TrafficControlModuleBase : ITrafficControlModule { public abstract string Name { get; } public abstract void Initialize(TrafficControlModuleContext context); public virtual void Tick(float now, bool isInLevel) { } public virtual void OnLevelEntered() { } public virtual void OnLevelExited() { } } internal sealed class TrafficControlModuleContext { internal Harmony Harmony { get; } internal TrafficControlConfig Config { get; } internal TrafficControlModuleContext(Harmony harmony, TrafficControlConfig config) { Harmony = harmony; Config = config; } } internal sealed class TrafficControlModuleHost { private sealed class ModuleSlot { internal ITrafficControlModule Module { get; } internal bool Active { get; set; } internal int ConsecutiveFaults { get; set; } internal ModuleSlot(ITrafficControlModule module) { Module = module; } } private readonly List _modules = new List(); private readonly TrafficControlModuleContext _context; internal TrafficControlModuleHost(TrafficControlModuleContext context) { _context = context; } internal void Add(ITrafficControlModule module) { _modules.Add(new ModuleSlot(module)); } internal void Initialize() { for (int i = 0; i < _modules.Count; i++) { ModuleSlot moduleSlot = _modules[i]; try { moduleSlot.Module.Initialize(_context); moduleSlot.Active = true; TrafficControlLog.Info("Module initialized: " + moduleSlot.Module.Name + "."); } catch (Exception exception) { moduleSlot.Active = false; TrafficControlLog.Error("Module initialization failed: " + moduleSlot.Module.Name + ". Other modules will continue.", exception); } } } internal void Tick(float now, bool isInLevel) { for (int i = 0; i < _modules.Count; i++) { Invoke(_modules[i], delegate(ITrafficControlModule module) { module.Tick(now, isInLevel); }, "tick"); } } internal void OnLevelEntered() { for (int i = 0; i < _modules.Count; i++) { Invoke(_modules[i], delegate(ITrafficControlModule module) { module.OnLevelEntered(); }, "level enter"); } } internal void OnLevelExited() { for (int i = 0; i < _modules.Count; i++) { Invoke(_modules[i], delegate(ITrafficControlModule module) { module.OnLevelExited(); }, "level exit"); } TrafficControlLog.ClearRateLimits(); } private static void Invoke(ModuleSlot slot, Action action, string operation) { if (!slot.Active) { return; } try { action(slot.Module); slot.ConsecutiveFaults = 0; } catch (Exception ex) { slot.ConsecutiveFaults++; TrafficControlLog.InfoRateLimited("ModuleFault:" + slot.Module.Name + ":" + operation, "Module " + slot.Module.Name + " failed during " + operation + ": " + ex.Message, 2f); if (slot.ConsecutiveFaults >= 5) { slot.Active = false; TrafficControlLog.Error("Module disabled after repeated " + operation + " failures: " + slot.Module.Name + ".", ex); } } } } } namespace PerformanceTrafficControl.Core { [BepInPlugin("kain.gtfo.performance.trafficcontrol", "Performance Traffic Control", "0.1.0")] public sealed class PerformanceTrafficControlPlugin : BasePlugin { private TrafficControlModuleHost? _moduleHost; private TrafficControlRuntimeDriver? _runtimeDriver; private bool _wasInLevel; public override void Load() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown TrafficControlLog.Bind(((BasePlugin)this).Log); TrafficControlLog.Info("Performance Traffic Control 0.1.0 loading."); TrafficControlConfig config = new TrafficControlConfig(((BasePlugin)this).Config); Harmony harmony = new Harmony("kain.gtfo.performance.trafficcontrol"); _moduleHost = new TrafficControlModuleHost(new TrafficControlModuleContext(harmony, config)); _moduleHost.Add(new AdaptivePerformanceModule()); _moduleHost.Add(new EnemyVisualOptimizationModule()); _moduleHost.Add(new WindVolumeCapacityModule()); _moduleHost.Initialize(); TrafficControlRuntimeDriver.Plugin = this; _runtimeDriver = ((BasePlugin)this).AddComponent(); TrafficControlLog.Info("Performance Traffic Control runtime driver registered."); } internal void OnRuntimeUpdate() { if (_moduleHost == null) { return; } try { bool flag = IsInLevel(); if (flag != _wasInLevel) { _wasInLevel = flag; if (flag) { _moduleHost.OnLevelEntered(); TrafficControlLog.Info("Level runtime entered."); } else { _moduleHost.OnLevelExited(); TrafficControlLog.Info("Level runtime exited; module state cleared."); } } _moduleHost.Tick(Time.unscaledTime, flag); } catch (Exception ex) { TrafficControlLog.InfoRateLimited("RuntimeDriver:Update", "Runtime update failed: " + ex.Message, 2f); } } internal void OnRuntimeDriverDestroyed(TrafficControlRuntimeDriver driver) { if (!((Object)(object)_runtimeDriver != (Object)(object)driver)) { if (_wasInLevel) { _moduleHost?.OnLevelExited(); _wasInLevel = false; } _runtimeDriver = null; TrafficControlRuntimeDriver.Plugin = null; TrafficControlLog.Warning("Performance Traffic Control runtime driver was destroyed."); } } private static bool IsInLevel() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 try { return GameStateManager.IsInExpedition && (int)GameStateManager.CurrentStateName == 10; } catch { return false; } } } public static class PluginInfo { public const string Guid = "kain.gtfo.performance.trafficcontrol"; public const string Name = "Performance Traffic Control"; public const string Version = "0.1.0"; } internal sealed class TrafficControlConfig { internal ConfigEntry AdaptivePerformanceEnabled { get; } internal ConfigEntry HighTriggerRatio { get; } internal ConfigEntry CriticalTriggerRatio { get; } internal ConfigEntry ResetLearnedBaseline { get; } internal ConfigEntry PerformanceDiagnosticsEnabled { get; } internal ConfigEntry EnemyVisualOptimizationEnabled { get; } internal ConfigEntry MaximumRagdollsUnderPressure { get; } internal ConfigEntry CorpseDecaySecondsUnderPressure { get; } internal ConfigEntry WindVolumeCapacityGuardEnabled { get; } internal ConfigEntry LearnedBaselineFps { get; } internal ConfigEntry LearnedProfileFingerprint { get; } internal TrafficControlConfig(ConfigFile config) { AdaptivePerformanceEnabled = config.Bind("Performance", "AdaptivePerformanceEnabled", true, "Learn a machine-specific in-level FPS baseline and reduce optional work under sustained pressure."); HighTriggerRatio = config.Bind("Performance", "HighTriggerRatio", 0.85f, "Enter High pressure below this fraction of the learned FPS baseline."); CriticalTriggerRatio = config.Bind("Performance", "CriticalTriggerRatio", 0.75f, "Enter Critical pressure below this fraction of the learned FPS baseline."); ResetLearnedBaseline = config.Bind("Performance", "ResetLearnedBaseline", false, "Set true once to discard the learned graphics profile and FPS baseline."); PerformanceDiagnosticsEnabled = config.Bind("Performance", "DiagnosticsEnabled", true, "Write a compact performance status line every 30 seconds while in a level."); EnemyVisualOptimizationEnabled = config.Bind("Performance.EnemyVisuals", "Enabled", true, "Under High or Critical pressure, suppress enemy shadows and reduce corpse visual cost."); MaximumRagdollsUnderPressure = config.Bind("Performance.EnemyVisuals", "MaximumRagdollsUnderPressure", 12, "Maximum enabled enemy ragdolls while adaptive pressure is High or Critical."); CorpseDecaySecondsUnderPressure = config.Bind("Performance.EnemyVisuals", "CorpseDecaySecondsUnderPressure", 0.01f, "Corpse decay delay used while adaptive pressure is High or Critical."); WindVolumeCapacityGuardEnabled = config.Bind("Compatibility", "WindVolumeCapacityGuardEnabled", true, "Temporarily suppress WindVolume affectors beyond the native fixed-capacity buffer."); LearnedBaselineFps = config.Bind("Internal", "LearnedBaselineFps", 0f, "Machine-specific FPS baseline maintained by Performance Traffic Control."); LearnedProfileFingerprint = config.Bind("Internal", "LearnedProfileFingerprint", string.Empty, "Graphics environment associated with the learned FPS baseline."); } } internal static class TrafficControlLog { private static readonly Dictionary NextLogAt = new Dictionary(StringComparer.Ordinal); private static ManualLogSource? s_log; internal static void Bind(ManualLogSource log) { s_log = log; } internal static void Info(string message) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogInfo((object)message); } } internal static void Warning(string message) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogWarning((object)message); } } internal static void Error(string message, Exception? exception = null) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogError((object)((exception == null) ? message : $"{message}\n{exception}")); } } internal static void InfoRateLimited(string key, string message, float intervalSeconds) { DateTime utcNow = DateTime.UtcNow; if (!NextLogAt.TryGetValue(key, out var value) || !(utcNow < value)) { NextLogAt[key] = utcNow.AddSeconds(Math.Max(0.1f, intervalSeconds)); ManualLogSource? obj = s_log; if (obj != null) { obj.LogInfo((object)message); } } } internal static void ClearRateLimits() { NextLogAt.Clear(); } } public sealed class TrafficControlRuntimeDriver : MonoBehaviour { internal static PerformanceTrafficControlPlugin? Plugin { get; set; } public TrafficControlRuntimeDriver(IntPtr pointer) : base(pointer) { } public void Update() { Plugin?.OnRuntimeUpdate(); } public void OnDestroy() { Plugin?.OnRuntimeDriverDestroyed(this); } } } namespace PerformanceTrafficControl.Api { public enum PerformancePressureLevel { Normal, High, Critical } public static class TrafficControlPerformance { private static readonly Dictionary AudioNextAllowedAt = new Dictionary(StringComparer.Ordinal); private static readonly List AudioKeysToRemove = new List(); private static PerformancePressureLevel s_level; private static int s_budgetFrame = -1; private static int s_physicsQueriesRemaining; private static int s_visualSpawnsRemaining; private static int s_audioEventsRemaining; public static PerformancePressureLevel Level => s_level; public static bool IsHighOrWorse => s_level >= PerformancePressureLevel.High; public static bool IsCritical => s_level == PerformancePressureLevel.Critical; public static float SmoothedFps { get; private set; } public static float LearnedBaselineFps { get; private set; } public static float SmoothedFrameMilliseconds { get { if (!(SmoothedFps > 0.01f)) { return 0f; } return 1000f / SmoothedFps; } } public static long DeniedPhysicsQueries { get; private set; } public static long DeniedVisualSpawns { get; private set; } public static long DeniedAudioEvents { get; private set; } public static int TransientVisualLimit => s_level switch { PerformancePressureLevel.Critical => 16, PerformancePressureLevel.High => 32, _ => 64, }; public static int RegisteredLightLimit => s_level switch { PerformancePressureLevel.Critical => 2, PerformancePressureLevel.High => 6, _ => 16, }; public static float VisualLifetimeScale => s_level switch { PerformancePressureLevel.Critical => 0.55f, PerformancePressureLevel.High => 0.78f, _ => 1f, }; public static float ParticleEmissionScale => s_level switch { PerformancePressureLevel.Critical => 0.3f, PerformancePressureLevel.High => 0.62f, _ => 1f, }; public static event Action? PressureChanged; public static bool TryConsumePhysicsQueries(int cost = 1, bool essential = false) { if (essential || cost <= 0) { return true; } EnsureFrameBudgets(); if (s_physicsQueriesRemaining >= cost) { s_physicsQueriesRemaining -= cost; return true; } DeniedPhysicsQueries += cost; return false; } public static int ClaimPhysicsQueries(int requested) { if (requested <= 0) { return 0; } EnsureFrameBudgets(); int num = Math.Min(requested, Math.Max(0, s_physicsQueriesRemaining)); s_physicsQueriesRemaining -= num; DeniedPhysicsQueries += requested - num; return num; } public static bool TryConsumeVisualSpawn(int cost = 1, bool essential = false) { if (essential || cost <= 0) { return true; } EnsureFrameBudgets(); if (s_visualSpawnsRemaining >= cost) { s_visualSpawnsRemaining -= cost; return true; } DeniedVisualSpawns += cost; return false; } public static bool TryConsumeAudio(string key, float minimumInterval = 0f, bool essential = false) { if (essential) { return true; } EnsureFrameBudgets(); float unscaledTime = Time.unscaledTime; float num = Mathf.Max(minimumInterval, s_level switch { PerformancePressureLevel.Critical => 0.22f, PerformancePressureLevel.High => 0.1f, _ => 0f, }); if (AudioNextAllowedAt.TryGetValue(key, out var value) && unscaledTime < value) { DeniedAudioEvents++; return false; } if (s_audioEventsRemaining <= 0) { DeniedAudioEvents++; return false; } s_audioEventsRemaining--; AudioNextAllowedAt[key] = unscaledTime + num; return true; } public static float GetUiInterval(float normalInterval) { return s_level switch { PerformancePressureLevel.Critical => Mathf.Max(normalInterval, 0.25f), PerformancePressureLevel.High => Mathf.Max(normalInterval, 0.12f), _ => normalInterval, }; } public static int GetVisualComplexity(int normal, int high, int critical) { return s_level switch { PerformancePressureLevel.Critical => critical, PerformancePressureLevel.High => high, _ => normal, }; } internal static void UpdateMeasurements(float smoothedFps, float learnedBaselineFps) { SmoothedFps = smoothedFps; LearnedBaselineFps = learnedBaselineFps; } internal static void SetPressure(PerformancePressureLevel level) { if (s_level != level) { PerformancePressureLevel previous = s_level; s_level = level; s_budgetFrame = -1; EnsureFrameBudgets(); RaisePressureChanged(previous, level); } } internal static void PruneAudioState(float now, float staleAfterSeconds) { AudioKeysToRemove.Clear(); foreach (KeyValuePair item in AudioNextAllowedAt) { if (now - item.Value > staleAfterSeconds) { AudioKeysToRemove.Add(item.Key); } } for (int i = 0; i < AudioKeysToRemove.Count; i++) { AudioNextAllowedAt.Remove(AudioKeysToRemove[i]); } AudioKeysToRemove.Clear(); } internal static void ResetForLevelExit() { SetPressure(PerformancePressureLevel.Normal); SmoothedFps = 0f; DeniedPhysicsQueries = 0L; DeniedVisualSpawns = 0L; DeniedAudioEvents = 0L; AudioNextAllowedAt.Clear(); AudioKeysToRemove.Clear(); s_budgetFrame = -1; EnsureFrameBudgets(); } private static void EnsureFrameBudgets() { int frameCount = Time.frameCount; if (s_budgetFrame != frameCount) { s_budgetFrame = frameCount; switch (s_level) { case PerformancePressureLevel.Critical: s_physicsQueriesRemaining = 24; s_visualSpawnsRemaining = 3; s_audioEventsRemaining = 3; break; case PerformancePressureLevel.High: s_physicsQueriesRemaining = 48; s_visualSpawnsRemaining = 8; s_audioEventsRemaining = 6; break; default: s_physicsQueriesRemaining = 96; s_visualSpawnsRemaining = 24; s_audioEventsRemaining = 12; break; } } } private static void RaisePressureChanged(PerformancePressureLevel previous, PerformancePressureLevel current) { Action pressureChanged = TrafficControlPerformance.PressureChanged; if (pressureChanged == null) { return; } Delegate[] invocationList = pressureChanged.GetInvocationList(); foreach (Delegate obj in invocationList) { try { ((Action)obj)(previous, current); } catch (Exception ex) { TrafficControlLog.InfoRateLimited("PerformanceApi:PressureChanged", "A performance pressure subscriber failed: " + ex.Message, 2f); } } } } }