Decompiled source of LethalOptimizer v1.2.0

LethalOptimizer.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalOptimizer.Config;
using LethalOptimizer.Core;
using LethalOptimizer.Patches;
using LethalOptimizer.Patches.AI;
using LethalOptimizer.Patches.Traps;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalOptimizer
{
	[BepInPlugin("com.lethal.optimizer", "LethalOptimizer", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginConfig.Initialize(((BaseUnityPlugin)this).Config);
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalOptimizer is disabled via config");
				return;
			}
			_harmony = new Harmony("com.lethal.optimizer");
			_harmony.PatchAll(typeof(EnemyAIPatches));
			_harmony.PatchAll(typeof(RoundManagerPatches));
			_harmony.PatchAll(typeof(GrabbableObjectPatches));
			_harmony.PatchAll(typeof(HUDManagerPatches));
			_harmony.PatchAll(typeof(PlayerPatches));
			_harmony.PatchAll(typeof(JesterPatches));
			_harmony.PatchAll(typeof(CrawlerPatches));
			_harmony.PatchAll(typeof(SpringManPatches));
			_harmony.PatchAll(typeof(BaboonPatches));
			_harmony.PatchAll(typeof(FlowermanPatches));
			_harmony.PatchAll(typeof(GhostGirlPatches));
			_harmony.PatchAll(typeof(HoarderBugPatches));
			_harmony.PatchAll(typeof(SporeLizardPatches));
			_harmony.PatchAll(typeof(ForestGiantPatches));
			_harmony.PatchAll(typeof(NutcrackerPatches));
			_harmony.PatchAll(typeof(MouthDogPatches));
			_harmony.PatchAll(typeof(SandSpiderPatches));
			_harmony.PatchAll(typeof(MaskedPatches));
			_harmony.PatchAll(typeof(BlobPatches));
			_harmony.PatchAll(typeof(RadMechPatches));
			_harmony.PatchAll(typeof(ButlerPatches));
			_harmony.PatchAll(typeof(FlowerSnakePatches));
			_harmony.PatchAll(typeof(CaveDwellerPatches));
			_harmony.PatchAll(typeof(TurretPatches));
			_harmony.PatchAll(typeof(LandminePatches));
			_harmony.PatchAll(typeof(SpikeRoofTrapPatches));
			_harmony.PatchAll(typeof(TimeOfDayPatches));
			ObjectPool.Initialize();
			AINodeCache.Initialize();
			Benchmark.Initialize();
			GraphicsOptimizer.Initialize();
			ShipOptimizer.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalOptimizer v1.2.0 [BETA] loaded!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"18 AI optimizations + 3 trap optimizations + TimeOfDay optimizer active");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Graphics quality auto-adjusts when on ship");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Press F8 for performance overlay, F9 to run benchmark");
		}

		private void Update()
		{
			if (PluginConfig.EnableLogging.Value)
			{
				PerformanceMonitor.LogMetrics();
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			ObjectPool.Cleanup();
			ComponentCache.Clear();
			NetworkThrottle.Clear();
			PerformanceMonitor.Clear();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.lethal.optimizer";

		public const string PLUGIN_NAME = "LethalOptimizer";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace LethalOptimizer.Patches
{
	[HarmonyPatch]
	public static class AudioPatches
	{
		private static readonly Dictionary<int, float> _lastPlayTimes = new Dictionary<int, float>();

		private const float MIN_AUDIO_INTERVAL = 0.05f;

		[HarmonyPatch(typeof(RoundManager), "PlayAudibleNoise")]
		[HarmonyPrefix]
		public static bool PlayAudibleNoise_Prefix(Vector3 noisePosition, float noiseRange, float noiseLoudness)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (noiseLoudness < 0.05f)
			{
				return false;
			}
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array == null)
			{
				return true;
			}
			bool result = false;
			float num = noiseRange * noiseRange;
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].isPlayerControlled && !array[i].isPlayerDead)
				{
					Vector3 val = ((Component)array[i]).transform.position - noisePosition;
					if (((Vector3)(ref val)).sqrMagnitude < num)
					{
						result = true;
						break;
					}
				}
			}
			return result;
		}

		[HarmonyPatch(typeof(WalkieTalkie), "TransmitOneShotAudio")]
		[HarmonyPrefix]
		public static bool TransmitAudio_Prefix(AudioSource audioSource, AudioClip clip)
		{
			if ((Object)(object)audioSource == (Object)null || (Object)(object)clip == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)audioSource).GetInstanceID();
			float valueOrDefault = _lastPlayTimes.GetValueOrDefault(instanceID, 0f);
			if (Time.time - valueOrDefault < 0.05f)
			{
				return false;
			}
			_lastPlayTimes[instanceID] = Time.time;
			return true;
		}

		public static void ClearCache()
		{
			_lastPlayTimes.Clear();
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	public static class EnemyAIPatches
	{
		[HarmonyPatch("SetEnemyOutside")]
		[HarmonyPrefix]
		public static bool SetEnemyOutside_Prefix(EnemyAI __instance, bool outside)
		{
			__instance.isOutside = outside;
			GameObject[] nodes = AINodeCache.GetNodes(outside);
			if (nodes != null && nodes.Length != 0)
			{
				__instance.allAINodes = nodes;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	public static class GrabbableObjectPatches
	{
		private static readonly Collider[] _groundCheckResults = (Collider[])(object)new Collider[10];

		private static readonly Dictionary<int, Transform> _parentCache = new Dictionary<int, Transform>();

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(GrabbableObject __instance)
		{
			if (__instance.isHeld && (Object)(object)__instance.playerHeldBy != (Object)null)
			{
				return false;
			}
			if (__instance.isInShipRoom && !__instance.isHeld && Time.frameCount % 3 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("FallToGround")]
		[HarmonyPrefix]
		public static bool FallToGround_Prefix(GrabbableObject __instance, bool randomizePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.targetFloorPosition == Vector3.zero)
			{
				Physics.OverlapSphereNonAlloc(((Component)__instance).transform.position, 2f, _groundCheckResults, LayerMask.GetMask(new string[2] { "Room", "Default" }), (QueryTriggerInteraction)1);
				_ = 0;
				return true;
			}
			return true;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(GrabbableObject __instance)
		{
			if (!((Component)__instance).gameObject.activeInHierarchy)
			{
				return false;
			}
			if (!__instance.isHeld && Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	public static class HUDManagerPatches
	{
		private static float _tipUpdateTimer;

		private static float _clockUpdateTimer;

		private static string _lastTipText;

		private const float TIP_UPDATE_INTERVAL = 0.1f;

		private const float CLOCK_UPDATE_INTERVAL = 1f;

		[HarmonyPatch("DisplayTip")]
		[HarmonyPrefix]
		public static bool DisplayTip_Prefix(string headerText, string bodyText)
		{
			string text = headerText + ":" + bodyText;
			if (text == _lastTipText && _tipUpdateTimer > 0f)
			{
				return false;
			}
			_lastTipText = text;
			_tipUpdateTimer = 0.1f;
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update_Postfix()
		{
			if (_tipUpdateTimer > 0f)
			{
				_tipUpdateTimer -= Time.deltaTime;
			}
		}

		[HarmonyPatch("SetClock")]
		[HarmonyPrefix]
		public static bool SetClock_Prefix(float timeNormalized, float numberOfHours)
		{
			_clockUpdateTimer -= Time.deltaTime;
			if (_clockUpdateTimer > 0f)
			{
				return false;
			}
			_clockUpdateTimer = 1f;
			return true;
		}
	}
	[HarmonyPatch]
	public static class PhysicsPatches
	{
		private static readonly RaycastHit[] _raycastHits = (RaycastHit[])(object)new RaycastHit[20];

		private static readonly Collider[] _overlapResults = (Collider[])(object)new Collider[30];

		public static int OverlapSphereNonAlloc(Vector3 position, float radius, int layerMask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Physics.OverlapSphereNonAlloc(position, radius, _overlapResults, layerMask);
		}

		public static Collider[] GetOverlapResults()
		{
			return _overlapResults;
		}

		public static int RaycastNonAlloc(Vector3 origin, Vector3 direction, float maxDistance, int layerMask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Physics.RaycastNonAlloc(origin, direction, _raycastHits, maxDistance, layerMask);
		}

		public static RaycastHit[] GetRaycastResults()
		{
			return _raycastHits;
		}

		public static bool IsWithinDistance(Vector3 a, Vector3 b, float distance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = a - b;
			return ((Vector3)(ref val)).sqrMagnitude <= distance * distance;
		}

		public static void ClearResults()
		{
			Array.Clear(_raycastHits, 0, _raycastHits.Length);
			Array.Clear(_overlapResults, 0, _overlapResults.Length);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public static class PlayerPatches
	{
		private static readonly Dictionary<int, Vector3> _lastPositions = new Dictionary<int, Vector3>();

		private static readonly Dictionary<int, float> _syncTimers = new Dictionary<int, float>();

		private const float POSITION_SYNC_INTERVAL = 0.05f;

		private const float POSITION_THRESHOLD = 0.01f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(PlayerControllerB __instance)
		{
			if (__instance.isPlayerDead && !__instance.isPlayerControlled)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(PlayerControllerB __instance)
		{
			if (!__instance.isPlayerControlled)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")]
		[HarmonyPrefix]
		public static bool SetHoverTip_Prefix(PlayerControllerB __instance)
		{
			if (Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("PlayerLookInput")]
		[HarmonyPrefix]
		public static bool PlayerLookInput_Prefix(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance.quickMenuManager != (Object)null && __instance.quickMenuManager.isMenuOpen)
			{
				return false;
			}
			return true;
		}

		public static bool ShouldSyncPosition(PlayerControllerB player)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)player).GetInstanceID();
			if (!_syncTimers.ContainsKey(instanceID))
			{
				_syncTimers[instanceID] = 0f;
			}
			_syncTimers[instanceID] -= Time.deltaTime;
			if (_syncTimers[instanceID] > 0f)
			{
				return false;
			}
			_syncTimers[instanceID] = 0.05f;
			if (!_lastPositions.ContainsKey(instanceID))
			{
				_lastPositions[instanceID] = ((Component)player).transform.position;
				return true;
			}
			if (Vector3.Distance(((Component)player).transform.position, _lastPositions[instanceID]) < 0.01f)
			{
				return false;
			}
			_lastPositions[instanceID] = ((Component)player).transform.position;
			return true;
		}

		public static void ClearCache()
		{
			_lastPositions.Clear();
			_syncTimers.Clear();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public static class RoundManagerPatches
	{
		private static float _spawnCheckTimer;

		private const float SPAWN_CHECK_INTERVAL = 0.5f;

		[HarmonyPatch("LoadNewLevel")]
		[HarmonyPostfix]
		public static void LoadNewLevel_Postfix()
		{
			AINodeCache.CacheNodes();
			TurretPatches.ResetTimers();
			LandminePatches.ResetCache();
			SpikeRoofTrapPatches.ResetCache();
			Plugin.Log.LogDebug((object)"Level loaded - AI nodes and trap caches reset");
		}

		[HarmonyPatch("SpawnEnemyGameObject")]
		[HarmonyPrefix]
		public static void SpawnEnemy_Prefix(RoundManager __instance)
		{
			if (AINodeCache.InsideNodes == null)
			{
				AINodeCache.CacheNodes();
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(RoundManager __instance)
		{
			_spawnCheckTimer -= Time.deltaTime;
			if (_spawnCheckTimer > 0f)
			{
				return true;
			}
			_spawnCheckTimer = 0.5f;
			return true;
		}

		[HarmonyPatch("RefreshEnemiesList")]
		[HarmonyPrefix]
		public static bool RefreshEnemiesList_Prefix(RoundManager __instance)
		{
			List<EnemyAI> spawnedEnemies = __instance.SpawnedEnemies;
			if (spawnedEnemies != null)
			{
				_ = spawnedEnemies.Count;
				_ = 0;
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	public static class TimeOfDayPatches
	{
		private static float _lightingUpdateTimer;

		private const float LIGHTING_UPDATE_INTERVAL = 0.1f;

		[HarmonyPatch("SetInsideLightingDimness")]
		[HarmonyPrefix]
		public static bool SetInsideLightingDimness_Prefix(TimeOfDay __instance, bool doNotLerp)
		{
			if (!PluginConfig.EnableUIOptimizations.Value)
			{
				return true;
			}
			if (doNotLerp)
			{
				return true;
			}
			_lightingUpdateTimer += Time.deltaTime;
			if (_lightingUpdateTimer < 0.1f)
			{
				return false;
			}
			_lightingUpdateTimer = 0f;
			return true;
		}

		[HarmonyPatch("MoveTimeOfDay")]
		[HarmonyPrefix]
		public static bool MoveTimeOfDay_Prefix(TimeOfDay __instance)
		{
			if (!PluginConfig.EnableUIOptimizations.Value)
			{
				return true;
			}
			if (!__instance.currentDayTimeStarted)
			{
				return false;
			}
			return true;
		}
	}
}
namespace LethalOptimizer.Patches.Traps
{
	[HarmonyPatch(typeof(Landmine))]
	public static class LandminePatches
	{
		private static RoundManager _cachedRoundManager;

		private static bool _roundManagerCached;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(Landmine __instance, ref float ___pressMineDebounceTimer, bool ___localPlayerOnMine)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (__instance.hasExploded)
			{
				return false;
			}
			if (___pressMineDebounceTimer > 0f)
			{
				___pressMineDebounceTimer -= Time.deltaTime;
			}
			if (___localPlayerOnMine)
			{
				PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
				if ((Object)(object)val != (Object)null && val.teleportedLastFrame)
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch("StartIdleAnimation")]
		[HarmonyPrefix]
		public static void StartIdleAnimation_Prefix(Landmine __instance, ref RoundManager ___roundManager)
		{
			if (PluginConfig.EnableTrapOptimizations.Value)
			{
				if (!_roundManagerCached)
				{
					_cachedRoundManager = RoundManager.Instance;
					_roundManagerCached = true;
				}
				___roundManager = _cachedRoundManager;
			}
		}

		[HarmonyPatch("OnTriggerEnter")]
		[HarmonyPrefix]
		public static bool OnTriggerEnter_Prefix(Landmine __instance, Collider other, bool ___hasExploded, float ___pressMineDebounceTimer)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (___hasExploded || ___pressMineDebounceTimer > 0f)
			{
				return false;
			}
			string tag = ((Component)other).tag;
			if (tag != "Player" && tag != "PhysicsProp" && !tag.StartsWith("PlayerRagdoll"))
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("OnTriggerExit")]
		[HarmonyPrefix]
		public static bool OnTriggerExit_Prefix(Landmine __instance, bool ___hasExploded, bool ___mineActivated)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (___hasExploded || !___mineActivated)
			{
				return false;
			}
			return true;
		}

		public static void ResetCache()
		{
			_cachedRoundManager = null;
			_roundManagerCached = false;
		}
	}
	[HarmonyPatch(typeof(SpikeRoofTrap))]
	public static class SpikeRoofTrapPatches
	{
		private const float UPDATE_INTERVAL = 0.1f;

		private static float _updateTimer;

		private static EntranceTeleport[] _cachedEntrances;

		private static bool _entrancesCached;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(SpikeRoofTrap __instance, bool ___trapActive, bool ___slammingDown, bool ___slamOnIntervals, float ___slamInterval, ref float ___timeSinceMovingUp, EntranceTeleport ___nearEntrance, Transform ___laserEye, ref RaycastHit ___hit)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (!___trapActive || ___slammingDown)
			{
				return false;
			}
			_updateTimer += Time.deltaTime;
			if (_updateTimer < 0.1f)
			{
				return false;
			}
			_updateTimer = 0f;
			if ((Object)(object)___nearEntrance != (Object)null && Time.realtimeSinceStartup - ___nearEntrance.timeAtLastUse < 1.2f)
			{
				___timeSinceMovingUp = Time.realtimeSinceStartup;
				return false;
			}
			if (___slamOnIntervals)
			{
				return true;
			}
			if (Time.realtimeSinceStartup - ___timeSinceMovingUp < 1.2f)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("OnTriggerStay")]
		[HarmonyPrefix]
		public static bool OnTriggerStay_Prefix(SpikeRoofTrap __instance, Collider other, bool ___trapActive, bool ___slammingDown, float ___timeSinceMovingUp)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (!___trapActive || !___slammingDown)
			{
				return false;
			}
			if (Time.realtimeSinceStartup - ___timeSinceMovingUp < 0.75f)
			{
				return false;
			}
			int layer = ((Component)other).gameObject.layer;
			if (layer != 3 && layer != 19 && layer != 6)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("GetNearEntrance")]
		[HarmonyPrefix]
		public static bool GetNearEntrance_Prefix(SpikeRoofTrap __instance, ref bool __result, ref EntranceTeleport ___nearEntrance, AudioSource ___spikeTrapAudio)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (!_entrancesCached)
			{
				_cachedEntrances = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0);
				_entrancesCached = true;
			}
			if (_cachedEntrances == null || _cachedEntrances.Length == 0)
			{
				__result = false;
				return false;
			}
			Vector3 position = ((Component)___spikeTrapAudio).transform.position;
			EntranceTeleport val = null;
			for (int i = 0; i < _cachedEntrances.Length; i++)
			{
				EntranceTeleport val2 = _cachedEntrances[i];
				if (!((Object)(object)val2 == (Object)null) && !val2.isEntranceToBuilding)
				{
					Vector3 val3 = position - val2.entrancePoint.position;
					if (((Vector3)(ref val3)).sqrMagnitude < 49f)
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				__result = false;
				return false;
			}
			for (int j = 0; j < _cachedEntrances.Length; j++)
			{
				EntranceTeleport val4 = _cachedEntrances[j];
				if ((Object)(object)val4 != (Object)null && (Object)(object)val4.entrancePoint == (Object)(object)val.exitPoint)
				{
					___nearEntrance = val4;
					__result = true;
					return false;
				}
			}
			__result = false;
			return false;
		}

		public static void ResetCache()
		{
			_cachedEntrances = null;
			_entrancesCached = false;
			_updateTimer = 0f;
		}
	}
	[HarmonyPatch(typeof(Turret))]
	public static class TurretPatches
	{
		private const float DETECTION_INTERVAL = 0.3f;

		private const float FIRING_INTERVAL = 0.25f;

		private const float ROTATION_SWITCH_INTERVAL = 8f;

		private static float _detectionTimer;

		private static float _losCheckTimer;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(Turret __instance, ref float ___turretInterval, ref float ___switchRotationTimer, bool ___turretActive, TurretMode ___turretMode)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if (!___turretActive)
			{
				return true;
			}
			if ((int)___turretMode == 0)
			{
				_detectionTimer += Time.deltaTime;
				if (_detectionTimer < 0.3f)
				{
					return true;
				}
				_detectionTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("CheckForPlayersInLineOfSight")]
		[HarmonyPrefix]
		public static bool CheckForPlayersInLOS_Prefix(Turret __instance, ref PlayerControllerB __result, float radius, bool angleRangeCheck)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			_losCheckTimer += Time.deltaTime;
			if (_losCheckTimer < PluginConfig.LOSCheckInterval.Value)
			{
				__result = null;
				return false;
			}
			_losCheckTimer = 0f;
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || val.isPlayerDead)
			{
				__result = null;
				return false;
			}
			Vector3 val2 = ((Component)val).transform.position - __instance.centerPoint.position;
			if (((Vector3)(ref val2)).sqrMagnitude > 900f)
			{
				__result = null;
				return false;
			}
			return true;
		}

		[HarmonyPatch("TurnTowardsTargetIfHasLOS")]
		[HarmonyPrefix]
		public static bool TurnTowardsTarget_Prefix(Turret __instance, PlayerControllerB ___targetPlayerWithRotation, bool ___targetingDeadPlayer)
		{
			if (!PluginConfig.EnableTrapOptimizations.Value)
			{
				return true;
			}
			if ((Object)(object)___targetPlayerWithRotation == (Object)null)
			{
				return false;
			}
			if (___targetingDeadPlayer && (Object)(object)___targetPlayerWithRotation.deadBody == (Object)null)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("SwitchRotationOnInterval")]
		[HarmonyPrefix]
		public static void SwitchRotation_Prefix(ref float ___switchRotationTimer)
		{
			if (PluginConfig.EnableTrapOptimizations.Value)
			{
				___switchRotationTimer = 0f;
			}
		}

		public static void ResetTimers()
		{
			_detectionTimer = 0f;
			_losCheckTimer = 0f;
		}
	}
}
namespace LethalOptimizer.Patches.Ship
{
	[HarmonyPatch(typeof(AutoParentToShip))]
	public static class AutoParentToShipPatches
	{
		private static readonly Dictionary<int, Vector3> _lastPositions = new Dictionary<int, Vector3>();

		private static readonly Dictionary<int, Quaternion> _lastRotations = new Dictionary<int, Quaternion>();

		private static float _updateTimer;

		private const float UPDATE_INTERVAL = 0.1f;

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(AutoParentToShip __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (StartOfRound.Instance.suckingFurnitureOutOfShip)
			{
				return true;
			}
			if (__instance.disableObject)
			{
				((Component)__instance).transform.position = new Vector3(800f, -100f, 0f);
				return false;
			}
			_updateTimer += Time.deltaTime;
			if (_updateTimer < 0.1f)
			{
				return false;
			}
			_updateTimer = 0f;
			int instanceID = ((Object)__instance).GetInstanceID();
			Vector3 position = StartOfRound.Instance.elevatorTransform.position;
			Quaternion rotation = StartOfRound.Instance.elevatorTransform.rotation;
			if (_lastPositions.TryGetValue(instanceID, out var value) && _lastRotations.TryGetValue(instanceID, out var value2) && Vector3.Distance(position, value) < 0.001f && Quaternion.Angle(rotation, value2) < 0.1f)
			{
				return false;
			}
			_lastPositions[instanceID] = position;
			_lastRotations[instanceID] = rotation;
			return true;
		}

		public static void ClearCache()
		{
			_lastPositions.Clear();
			_lastRotations.Clear();
		}
	}
	[HarmonyPatch(typeof(InteractTrigger))]
	public static class InteractTriggerPatches
	{
		private static readonly Dictionary<int, float> _cooldownTimers = new Dictionary<int, float>();

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(InteractTrigger __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (!__instance.isPlayingSpecialAnimation && !__instance.usingLadder && Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("StopInteraction")]
		[HarmonyPrefix]
		public static bool StopInteraction_Prefix(InteractTrigger __instance)
		{
			if (!__instance.isBeingHeldByPlayer)
			{
				return false;
			}
			return true;
		}

		public static void ClearCache()
		{
			_cooldownTimers.Clear();
		}
	}
	[HarmonyPatch(typeof(ManualCameraRenderer))]
	public static class ManualCameraRendererPatches
	{
		private static float _renderTimer;

		private static float _targetFps = 15f;

		private static float _renderInterval;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix(ManualCameraRenderer __instance)
		{
			__instance.renderAtLowerFramerate = true;
			__instance.fps = _targetFps;
			_renderInterval = 1f / _targetFps;
			Plugin.Log.LogDebug((object)$"Radar camera set to {_targetFps} FPS");
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(ManualCameraRenderer __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (__instance.currentCameraDisabled)
			{
				return false;
			}
			_renderTimer += Time.deltaTime;
			if (_renderTimer < _renderInterval)
			{
				if ((Object)(object)__instance.cam != (Object)null)
				{
					((Behaviour)__instance.cam).enabled = false;
				}
				return false;
			}
			_renderTimer = 0f;
			if ((Object)(object)__instance.cam != (Object)null)
			{
				((Behaviour)__instance.cam).enabled = true;
			}
			return true;
		}

		[HarmonyPatch("MapCameraFocusOnPosition")]
		[HarmonyPrefix]
		public static bool MapCameraFocus_Prefix(ManualCameraRenderer __instance)
		{
			if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(OccludeAudio))]
	public static class OccludeAudioPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(OccludeAudio __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SoundManager))]
	public static class SoundManagerPatches
	{
		private static float _updateTimer;

		private const float UPDATE_INTERVAL = 0.05f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(SoundManager __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			_updateTimer += Time.deltaTime;
			if (_updateTimer < 0.05f)
			{
				return false;
			}
			_updateTimer = 0f;
			return true;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(SoundManager __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public static class StartOfRoundPatches
	{
		private static float _updateTimer;

		private const float UPDATE_INTERVAL = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(StartOfRound __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (__instance.inShipPhase)
			{
				_updateTimer += Time.deltaTime;
				if (_updateTimer < 0.2f)
				{
					return true;
				}
				_updateTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(StartOfRound __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if (__instance.inShipPhase && Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalPatches
	{
		private static float _updateTimer;

		private const float UPDATE_INTERVAL = 0.1f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(Terminal __instance)
		{
			if (!PluginConfig.EnableAllOptimizations.Value)
			{
				return true;
			}
			if ((Object)(object)HUDManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			if (!__instance.terminalInUse)
			{
				_updateTimer += Time.deltaTime;
				if (_updateTimer < 0.1f)
				{
					return false;
				}
				_updateTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("TextPostProcess")]
		[HarmonyPrefix]
		public static void TextPostProcess_Prefix(Terminal __instance)
		{
		}
	}
}
namespace LethalOptimizer.Patches.AI
{
	[HarmonyPatch(typeof(BaboonBirdAI))]
	public static class BaboonPatches
	{
		private static float _threatCheckTimer;

		private static float _scoutTimer;

		private const float THREAT_CHECK_INTERVAL = 0.3f;

		private const float SCOUT_INTERVAL = 0.5f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(BaboonBirdAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(BaboonBirdAI __instance)
		{
			_threatCheckTimer -= Time.deltaTime;
			if (_threatCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				return false;
			}
			_threatCheckTimer = 0.3f;
			return true;
		}

		[HarmonyPatch("DoLOSCheck")]
		[HarmonyPrefix]
		public static bool DoLOSCheck_Prefix(BaboonBirdAI __instance)
		{
			_scoutTimer -= Time.deltaTime;
			if (_scoutTimer > 0f)
			{
				return false;
			}
			_scoutTimer = 0.5f;
			return true;
		}

		[HarmonyPatch("CalculateThreatLevelOfPosition")]
		[HarmonyPrefix]
		public static bool CalculateThreat_Prefix(BaboonBirdAI __instance)
		{
			if (__instance.focusedThreat == null && (Object)(object)__instance.focusedThreatTransform == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(BlobAI))]
	public static class BlobPatches
	{
		private static float _moveTimer;

		private const float MOVE_CHECK_INTERVAL = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(BlobAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(BlobAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			_moveTimer -= Time.deltaTime;
			if (_moveTimer > 0f)
			{
				return false;
			}
			_moveTimer = 0.2f;
			return true;
		}
	}
	[HarmonyPatch(typeof(ButlerEnemyAI))]
	public static class ButlerPatches
	{
		private static float _aiIntervalTimer;

		private const float AI_INTERVAL_THROTTLE = 0.15f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(ButlerEnemyAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(ButlerEnemyAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_aiIntervalTimer += Time.deltaTime;
				if (_aiIntervalTimer < 0.15f)
				{
					return false;
				}
				_aiIntervalTimer = 0f;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CaveDwellerAI))]
	public static class CaveDwellerPatches
	{
		private static float _updateTimer;

		private const float UPDATE_THROTTLE = 0.1f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(CaveDwellerAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_updateTimer += Time.deltaTime;
				if (_updateTimer < 0.1f)
				{
					return false;
				}
				_updateTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(CaveDwellerAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CrawlerAI))]
	public static class CrawlerPatches
	{
		private static float _aiIntervalTimer;

		private const float AI_INTERVAL_THROTTLE = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(CrawlerAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(CrawlerAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_aiIntervalTimer += Time.deltaTime;
				if (_aiIntervalTimer < 0.2f)
				{
					return false;
				}
				_aiIntervalTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("MakeScreech")]
		[HarmonyPrefix]
		public static bool MakeScreech_Prefix(CrawlerAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(FlowermanAI))]
	public static class FlowermanPatches
	{
		private static float _angerCheckTimer;

		private const float ANGER_CHECK_INTERVAL = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(FlowermanAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(FlowermanAI __instance)
		{
			_angerCheckTimer -= Time.deltaTime;
			if (_angerCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				return false;
			}
			_angerCheckTimer = 0.2f;
			return true;
		}

		[HarmonyPatch("LookAtPlayerOfInterest")]
		[HarmonyPrefix]
		public static bool LookAtPlayer_Prefix(FlowermanAI __instance)
		{
			if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
			{
				return false;
			}
			if (Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(FlowerSnakeEnemy))]
	public static class FlowerSnakePatches
	{
		private static float _updateTimer;

		private const float UPDATE_THROTTLE = 0.1f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(FlowerSnakeEnemy __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)__instance.clingingToPlayer))
			{
				_updateTimer += Time.deltaTime;
				if (_updateTimer < 0.1f)
				{
					return false;
				}
				_updateTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(FlowerSnakeEnemy __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ForestGiantAI))]
	public static class ForestGiantPatches
	{
		private static float _searchTimer;

		private static float _losTimer;

		private const float SEARCH_INTERVAL = 0.4f;

		private const float LOS_INTERVAL = 0.15f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(ForestGiantAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(ForestGiantAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_searchTimer -= Time.deltaTime;
				if (_searchTimer > 0f)
				{
					return false;
				}
				_searchTimer = 0.4f;
			}
			return true;
		}

		[HarmonyPatch("LookForPlayers")]
		[HarmonyPrefix]
		public static bool LookForPlayers_Prefix(ForestGiantAI __instance)
		{
			_losTimer -= Time.deltaTime;
			if (_losTimer > 0f)
			{
				return false;
			}
			_losTimer = 0.15f;
			return true;
		}
	}
	[HarmonyPatch(typeof(DressGirlAI))]
	public static class GhostGirlPatches
	{
		private static float _hauntCheckTimer;

		private static float _visibilityTimer;

		private const float HAUNT_CHECK_INTERVAL = 0.5f;

		private const float VISIBILITY_CHECK_INTERVAL = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(DressGirlAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)__instance.hauntingPlayer) && Time.frameCount % 3 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(DressGirlAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if ((Object)(object)__instance.hauntingPlayer == (Object)null)
			{
				_hauntCheckTimer -= Time.deltaTime;
				if (_hauntCheckTimer > 0f)
				{
					return false;
				}
				_hauntCheckTimer = 0.5f;
			}
			return true;
		}

		[HarmonyPatch("CheckVisibility")]
		[HarmonyPrefix]
		public static bool CheckVisibility_Prefix(DressGirlAI __instance)
		{
			_visibilityTimer -= Time.deltaTime;
			if (_visibilityTimer > 0f)
			{
				return false;
			}
			_visibilityTimer = 0.2f;
			return true;
		}
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	public static class HoarderBugPatches
	{
		private static float _itemSearchTimer;

		private static float _nestCheckTimer;

		private const float ITEM_SEARCH_INTERVAL = 0.3f;

		private const float NEST_CHECK_INTERVAL = 0.5f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(HoarderBugAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (__instance.heldItem != null && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(HoarderBugAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (__instance.heldItem == null)
			{
				_itemSearchTimer -= Time.deltaTime;
				if (_itemSearchTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
				{
					return false;
				}
				_itemSearchTimer = 0.3f;
			}
			return true;
		}

		[HarmonyPatch("RefreshGrabbableObjectsInMapList")]
		[HarmonyPrefix]
		public static bool RefreshObjects_Prefix(HoarderBugAI __instance)
		{
			_nestCheckTimer -= Time.deltaTime;
			if (_nestCheckTimer > 0f)
			{
				return false;
			}
			_nestCheckTimer = 0.5f;
			return true;
		}
	}
	[HarmonyPatch(typeof(JesterAI))]
	public static class JesterPatches
	{
		private static float _popUpTimer;

		private const float POP_CHECK_INTERVAL = 0.25f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(JesterAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 4 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(JesterAI __instance)
		{
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
			{
				_popUpTimer -= Time.deltaTime;
				if (_popUpTimer > 0f)
				{
					return false;
				}
				_popUpTimer = 0.25f;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	public static class MaskedPatches
	{
		private static float _mimicTimer;

		private const float MIMIC_CHECK_INTERVAL = 0.3f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(MaskedPlayerEnemy __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(MaskedPlayerEnemy __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_mimicTimer -= Time.deltaTime;
				if (_mimicTimer > 0f)
				{
					return false;
				}
				_mimicTimer = 0.3f;
			}
			return true;
		}

		[HarmonyPatch("LookAtPlayerServerRpc")]
		[HarmonyPrefix]
		public static bool LookAtPlayer_Prefix(MaskedPlayerEnemy __instance)
		{
			if (!NetworkThrottle.CanSendForObject("animation", ((Object)__instance).GetInstanceID()))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MouthDogAI))]
	public static class MouthDogPatches
	{
		private static float _noiseCheckTimer;

		private static float _suspicionTimer;

		private const float NOISE_CHECK_INTERVAL = 0.1f;

		private const float SUSPICION_CHECK_INTERVAL = 0.25f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(MouthDogAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(MouthDogAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 2 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DetectNoise")]
		[HarmonyPrefix]
		public static bool DetectNoise_Prefix(MouthDogAI __instance, Vector3 noisePosition, float noiseLoudness)
		{
			_noiseCheckTimer -= Time.deltaTime;
			if (_noiseCheckTimer > 0f)
			{
				return false;
			}
			_noiseCheckTimer = 0.1f;
			if (noiseLoudness < 0.1f)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("CheckForPlayersInLineOfSight")]
		[HarmonyPrefix]
		public static bool CheckPlayers_Prefix(MouthDogAI __instance)
		{
			_suspicionTimer -= Time.deltaTime;
			if (_suspicionTimer > 0f)
			{
				return false;
			}
			_suspicionTimer = 0.25f;
			return true;
		}
	}
	[HarmonyPatch(typeof(NutcrackerEnemyAI))]
	public static class NutcrackerPatches
	{
		private static float _aimCheckTimer;

		private static float _patrolTimer;

		private const float AIM_CHECK_INTERVAL = 0.15f;

		private const float PATROL_CHECK_INTERVAL = 0.3f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(NutcrackerEnemyAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(NutcrackerEnemyAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_patrolTimer -= Time.deltaTime;
				if (_patrolTimer > 0f)
				{
					return false;
				}
				_patrolTimer = 0.3f;
			}
			return true;
		}

		[HarmonyPatch("AimGun")]
		[HarmonyPrefix]
		public static bool AimGun_Prefix(NutcrackerEnemyAI __instance)
		{
			_aimCheckTimer -= Time.deltaTime;
			if (_aimCheckTimer > 0f)
			{
				return false;
			}
			_aimCheckTimer = 0.15f;
			return true;
		}

		[HarmonyPatch("CheckLineOfSightForLocalPlayer")]
		[HarmonyPrefix]
		public static bool CheckLOS_Prefix(NutcrackerEnemyAI __instance)
		{
			if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(RadMechAI))]
	public static class RadMechPatches
	{
		private static float _threatCheckTimer;

		private static float _lateUpdateTimer;

		private const float THREAT_CHECK_INTERVAL = 0.2f;

		private const float LATE_UPDATE_INTERVAL = 0.05f;

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		public static bool LateUpdate_Prefix(RadMechAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			_lateUpdateTimer += Time.deltaTime;
			if (_lateUpdateTimer < 0.05f)
			{
				return false;
			}
			_lateUpdateTimer = 0f;
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(RadMechAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (!__instance.isAlerted)
			{
				_threatCheckTimer += Time.deltaTime;
				if (_threatCheckTimer < 0.2f)
				{
					return false;
				}
				_threatCheckTimer = 0f;
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(RadMechAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI))]
	public static class SandSpiderPatches
	{
		private static float _webCheckTimer;

		private static float _patrolTimer;

		private const float WEB_CHECK_INTERVAL = 0.3f;

		private const float PATROL_INTERVAL = 0.25f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(SandSpiderAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 3 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(SandSpiderAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				_patrolTimer -= Time.deltaTime;
				if (_patrolTimer > 0f)
				{
					return false;
				}
				_patrolTimer = 0.25f;
			}
			return true;
		}

		[HarmonyPatch("CheckForPlayersInLineOfSight")]
		[HarmonyPrefix]
		public static bool CheckPlayers_Prefix(SandSpiderAI __instance)
		{
			_webCheckTimer -= Time.deltaTime;
			if (_webCheckTimer > 0f)
			{
				return false;
			}
			_webCheckTimer = 0.3f;
			return true;
		}
	}
	[HarmonyPatch(typeof(PufferAI))]
	public static class SporeLizardPatches
	{
		private static float _fearCheckTimer;

		private const float FEAR_CHECK_INTERVAL = 0.2f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(PufferAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 3 != 0)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(PufferAI __instance)
		{
			if (!PluginConfig.EnableAIOptimizations.Value)
			{
				return true;
			}
			_fearCheckTimer -= Time.deltaTime;
			if (_fearCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
			{
				return false;
			}
			_fearCheckTimer = 0.2f;
			return true;
		}
	}
	[HarmonyPatch(typeof(SpringManAI))]
	public static class SpringManPatches
	{
		private static float _losCheckTimer;

		private const float LOS_CHECK_INTERVAL = 0.1f;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix(SpringManAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		public static bool DoAIInterval_Prefix(SpringManAI __instance)
		{
			_losCheckTimer -= Time.deltaTime;
			if (_losCheckTimer > 0f)
			{
				return true;
			}
			_losCheckTimer = 0.1f;
			return true;
		}

		[HarmonyPatch("SetAnimationStopServerRpc")]
		[HarmonyPrefix]
		public static bool SetAnimationStop_Prefix(SpringManAI __instance)
		{
			if (!NetworkThrottle.CanSendForObject("animation", ((Object)__instance).GetInstanceID()))
			{
				return false;
			}
			return true;
		}
	}
}
namespace LethalOptimizer.Core
{
	public static class AINodeCache
	{
		public static GameObject[] InsideNodes { get; private set; }

		public static GameObject[] OutsideNodes { get; private set; }

		public static void Initialize()
		{
			InsideNodes = null;
			OutsideNodes = null;
		}

		public static void CacheNodes()
		{
			InsideNodes = GameObject.FindGameObjectsWithTag("AINode");
			OutsideNodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
			ManualLogSource log = Plugin.Log;
			GameObject[] insideNodes = InsideNodes;
			object arg = ((insideNodes != null) ? insideNodes.Length : 0);
			GameObject[] outsideNodes = OutsideNodes;
			log.LogInfo((object)$"Cached {arg} inside, {((outsideNodes != null) ? outsideNodes.Length : 0)} outside AI nodes");
		}

		public static GameObject[] GetNodes(bool outside)
		{
			if (!outside)
			{
				return InsideNodes;
			}
			return OutsideNodes;
		}
	}
	public class Benchmark : MonoBehaviour
	{
		private readonly Queue<float> _fpsHistory = new Queue<float>();

		private const int FPS_SAMPLE_SIZE = 300;

		private float _fpsUpdateTimer;

		private float _currentFps;

		private long _lastMemory;

		private long _peakMemory;

		private readonly Queue<long> _memoryHistory = new Queue<long>();

		private readonly Queue<float> _frameTimeHistory = new Queue<float>();

		private float _worstFrameTime;

		private float _bestFrameTime = float.MaxValue;

		private float _sessionStartTime;

		private int _totalFrames;

		private float _totalFrameTime;

		private int _activeEnemies;

		private int _activeItems;

		private int _activePlayers;

		private bool _isRunning;

		private float _benchmarkDuration = 60f;

		private float _benchmarkTimer;

		private BenchmarkResult _lastResult;

		private bool _showOverlay;

		private GUIStyle _overlayStyle;

		private Rect _overlayRect;

		public static Benchmark Instance { get; private set; }

		public static void Initialize()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				GameObject val = new GameObject("LethalOptimizer_Benchmark");
				Instance = val.AddComponent<Benchmark>();
				Object.DontDestroyOnLoad((Object)val);
				Plugin.Log.LogInfo((object)"Benchmark system initialized. Press F8 to toggle overlay, F9 to run benchmark.");
			}
		}

		private void Awake()
		{
			//IL_0020: 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)
			_sessionStartTime = Time.time;
			_overlayRect = new Rect(10f, 10f, 320f, 200f);
		}

		private void Update()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.EnableBenchmark.Value)
			{
				return;
			}
			if (Input.GetKeyDown(PluginConfig.OverlayKey.Value))
			{
				_showOverlay = !_showOverlay;
				Plugin.Log.LogInfo((object)("Performance overlay: " + (_showOverlay ? "ON" : "OFF")));
			}
			if (Input.GetKeyDown(PluginConfig.BenchmarkKey.Value))
			{
				if (!_isRunning)
				{
					StartBenchmark(PluginConfig.BenchmarkDuration.Value);
				}
				else
				{
					StopBenchmark();
				}
			}
			UpdateMetrics();
			if (_isRunning)
			{
				UpdateBenchmark();
			}
		}

		private void UpdateMetrics()
		{
			_fpsUpdateTimer += Time.unscaledDeltaTime;
			if (_fpsUpdateTimer >= 0.1f)
			{
				_currentFps = 1f / Time.unscaledDeltaTime;
				_fpsUpdateTimer = 0f;
				_fpsHistory.Enqueue(_currentFps);
				if (_fpsHistory.Count > 300)
				{
					_fpsHistory.Dequeue();
				}
			}
			float num = Time.unscaledDeltaTime * 1000f;
			_frameTimeHistory.Enqueue(num);
			if (_frameTimeHistory.Count > 300)
			{
				_frameTimeHistory.Dequeue();
			}
			if (num > _worstFrameTime)
			{
				_worstFrameTime = num;
			}
			if (num < _bestFrameTime)
			{
				_bestFrameTime = num;
			}
			_totalFrames++;
			_totalFrameTime += num;
			if (Time.frameCount % 60 == 0)
			{
				long totalMemory = GC.GetTotalMemory(forceFullCollection: false);
				_memoryHistory.Enqueue(totalMemory);
				if (_memoryHistory.Count > 60)
				{
					_memoryHistory.Dequeue();
				}
				if (totalMemory > _peakMemory)
				{
					_peakMemory = totalMemory;
				}
				_lastMemory = totalMemory;
			}
			if (Time.frameCount % 120 == 0)
			{
				UpdateGameStats();
			}
		}

		private void UpdateGameStats()
		{
			try
			{
				RoundManager instance = RoundManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					_activeEnemies = instance.SpawnedEnemies?.Count ?? 0;
				}
				StartOfRound instance2 = StartOfRound.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					_activePlayers = 0;
					PlayerControllerB[] allPlayerScripts = instance2.allPlayerScripts;
					foreach (PlayerControllerB val in allPlayerScripts)
					{
						if (val.isPlayerControlled && !val.isPlayerDead)
						{
							_activePlayers++;
						}
					}
				}
				GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
				_activeItems = ((array != null) ? array.Length : 0);
			}
			catch
			{
			}
		}

		public void StartBenchmark(float duration = 60f)
		{
			_benchmarkDuration = duration;
			_benchmarkTimer = 0f;
			_isRunning = true;
			_fpsHistory.Clear();
			_frameTimeHistory.Clear();
			_memoryHistory.Clear();
			_worstFrameTime = 0f;
			_bestFrameTime = float.MaxValue;
			_totalFrames = 0;
			_totalFrameTime = 0f;
			_peakMemory = 0L;
			Plugin.Log.LogInfo((object)$"Benchmark started for {duration} seconds...");
		}

		private void UpdateBenchmark()
		{
			_benchmarkTimer += Time.unscaledDeltaTime;
			if (_benchmarkTimer >= _benchmarkDuration)
			{
				StopBenchmark();
			}
		}

		public void StopBenchmark()
		{
			if (_isRunning)
			{
				_isRunning = false;
				_lastResult = GenerateResult();
				Plugin.Log.LogInfo((object)"=== BENCHMARK RESULTS ===");
				Plugin.Log.LogInfo((object)_lastResult.ToString());
				_showOverlay = true;
			}
		}

		private BenchmarkResult GenerateResult()
		{
			BenchmarkResult benchmarkResult = new BenchmarkResult
			{
				Duration = _benchmarkTimer,
				TotalFrames = _totalFrames
			};
			if (_fpsHistory.Count > 0)
			{
				float num = 0f;
				float num2 = float.MaxValue;
				float num3 = 0f;
				foreach (float item in _fpsHistory)
				{
					num += item;
					if (item < num2)
					{
						num2 = item;
					}
					if (item > num3)
					{
						num3 = item;
					}
				}
				benchmarkResult.AvgFps = num / (float)_fpsHistory.Count;
				benchmarkResult.MinFps = num2;
				benchmarkResult.MaxFps = num3;
				List<float> list = new List<float>(_fpsHistory);
				list.Sort();
				int index = Mathf.Max(0, list.Count / 100);
				benchmarkResult.OnePercentLow = list[index];
			}
			benchmarkResult.AvgFrameTime = ((_totalFrames > 0) ? (_totalFrameTime / (float)_totalFrames) : 0f);
			benchmarkResult.WorstFrameTime = _worstFrameTime;
			benchmarkResult.BestFrameTime = _bestFrameTime;
			benchmarkResult.CurrentMemoryMB = (float)_lastMemory / 1048576f;
			benchmarkResult.PeakMemoryMB = (float)_peakMemory / 1048576f;
			benchmarkResult.ActiveEnemies = _activeEnemies;
			benchmarkResult.ActiveItems = _activeItems;
			benchmarkResult.ActivePlayers = _activePlayers;
			return benchmarkResult;
		}

		private void OnGUI()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0048: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			if (_showOverlay)
			{
				if (_overlayStyle == null)
				{
					_overlayStyle = new GUIStyle(GUI.skin.box)
					{
						fontSize = 14,
						alignment = (TextAnchor)0,
						padding = new RectOffset(10, 10, 10, 10)
					};
					_overlayStyle.normal.textColor = Color.white;
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("<b>LethalOptimizer Performance</b>");
				stringBuilder.AppendLine($"FPS: {_currentFps:F1} (Avg: {GetAverageFps():F1})");
				stringBuilder.AppendLine($"Frame Time: {Time.unscaledDeltaTime * 1000f:F2}ms");
				stringBuilder.AppendLine($"Memory: {(float)_lastMemory / 1048576f:F1} MB (Peak: {(float)_peakMemory / 1048576f:F1} MB)");
				stringBuilder.AppendLine();
				stringBuilder.AppendLine($"Enemies: {_activeEnemies} | Items: {_activeItems} | Players: {_activePlayers}");
				if (_isRunning)
				{
					stringBuilder.AppendLine();
					stringBuilder.AppendLine($"<color=yellow>BENCHMARK: {_benchmarkTimer:F1}s / {_benchmarkDuration:F0}s</color>");
				}
				else if (_lastResult != null)
				{
					stringBuilder.AppendLine();
					stringBuilder.AppendLine("<color=lime>Last Benchmark:</color>");
					stringBuilder.AppendLine($"Avg: {_lastResult.AvgFps:F1} | 1% Low: {_lastResult.OnePercentLow:F1}");
				}
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("<size=11>F8: Toggle | F9: Benchmark</size>");
				GUI.Box(_overlayRect, stringBuilder.ToString(), _overlayStyle);
			}
		}

		private float GetAverageFps()
		{
			if (_fpsHistory.Count == 0)
			{
				return 0f;
			}
			float num = 0f;
			foreach (float item in _fpsHistory)
			{
				num += item;
			}
			return num / (float)_fpsHistory.Count;
		}

		public BenchmarkResult GetLastResult()
		{
			return _lastResult;
		}
	}
	public class BenchmarkResult
	{
		public float Duration;

		public int TotalFrames;

		public float AvgFps;

		public float MinFps;

		public float MaxFps;

		public float OnePercentLow;

		public float AvgFrameTime;

		public float WorstFrameTime;

		public float BestFrameTime;

		public float CurrentMemoryMB;

		public float PeakMemoryMB;

		public int ActiveEnemies;

		public int ActiveItems;

		public int ActivePlayers;

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"Duration: {Duration:F1}s | Frames: {TotalFrames}");
			stringBuilder.AppendLine($"FPS - Avg: {AvgFps:F1} | Min: {MinFps:F1} | Max: {MaxFps:F1} | 1% Low: {OnePercentLow:F1}");
			stringBuilder.AppendLine($"Frame Time - Avg: {AvgFrameTime:F2}ms | Best: {BestFrameTime:F2}ms | Worst: {WorstFrameTime:F2}ms");
			stringBuilder.AppendLine($"Memory - Current: {CurrentMemoryMB:F1}MB | Peak: {PeakMemoryMB:F1}MB");
			stringBuilder.AppendLine($"Game State - Enemies: {ActiveEnemies} | Items: {ActiveItems} | Players: {ActivePlayers}");
			return stringBuilder.ToString();
		}
	}
	public static class ComponentCache
	{
		public struct CachedComponents
		{
			public NavMeshAgent Agent;

			public Animator Animator;

			public AudioSource AudioSource;

			public Rigidbody Rigidbody;

			public Collider Collider;
		}

		private static readonly Dictionary<int, CachedComponents> _cache = new Dictionary<int, CachedComponents>();

		public static T Get<T>(GameObject obj) where T : Component
		{
			if ((Object)(object)obj == (Object)null)
			{
				return default(T);
			}
			int instanceID = ((Object)obj).GetInstanceID();
			if (!_cache.TryGetValue(instanceID, out var value))
			{
				value = default(CachedComponents);
				_cache[instanceID] = value;
			}
			if (typeof(T) == typeof(NavMeshAgent))
			{
				if ((Object)(object)value.Agent == (Object)null)
				{
					value.Agent = obj.GetComponent<NavMeshAgent>();
					_cache[instanceID] = value;
				}
				NavMeshAgent agent = value.Agent;
				return (T)(object)((agent is T) ? agent : null);
			}
			if (typeof(T) == typeof(Animator))
			{
				if ((Object)(object)value.Animator == (Object)null)
				{
					value.Animator = obj.GetComponent<Animator>();
					_cache[instanceID] = value;
				}
				Animator animator = value.Animator;
				return (T)(object)((animator is T) ? animator : null);
			}
			if (typeof(T) == typeof(AudioSource))
			{
				if ((Object)(object)value.AudioSource == (Object)null)
				{
					value.AudioSource = obj.GetComponent<AudioSource>();
					_cache[instanceID] = value;
				}
				AudioSource audioSource = value.AudioSource;
				return (T)(object)((audioSource is T) ? audioSource : null);
			}
			if (typeof(T) == typeof(Rigidbody))
			{
				if ((Object)(object)value.Rigidbody == (Object)null)
				{
					value.Rigidbody = obj.GetComponent<Rigidbody>();
					_cache[instanceID] = value;
				}
				Rigidbody rigidbody = value.Rigidbody;
				return (T)(object)((rigidbody is T) ? rigidbody : null);
			}
			if (typeof(T) == typeof(Collider))
			{
				if ((Object)(object)value.Collider == (Object)null)
				{
					value.Collider = obj.GetComponent<Collider>();
					_cache[instanceID] = value;
				}
				Collider collider = value.Collider;
				return (T)(object)((collider is T) ? collider : null);
			}
			return obj.GetComponent<T>();
		}

		public static void Remove(GameObject obj)
		{
			if ((Object)(object)obj != (Object)null)
			{
				_cache.Remove(((Object)obj).GetInstanceID());
			}
		}

		public static void Clear()
		{
			_cache.Clear();
		}
	}
	public class GraphicsOptimizer : MonoBehaviour
	{
		private int _originalShadowDistance;

		private ShadowQuality _originalShadowQuality;

		private ShadowResolution _originalShadowResolution;

		private int _originalPixelLightCount;

		private float _originalLodBias;

		private int _originalMaxLod;

		private AnisotropicFiltering _originalAniso;

		private bool _settingsSaved;

		private bool _lowEndModeActive;

		public static GraphicsOptimizer Instance { get; private set; }

		public bool IsLowEndModeActive => _lowEndModeActive;

		public static void Initialize()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				GameObject val = new GameObject("LethalOptimizer_Graphics");
				Instance = val.AddComponent<GraphicsOptimizer>();
				Object.DontDestroyOnLoad((Object)val);
				if (PluginConfig.EnableLowEndMode != null && PluginConfig.EnableLowEndMode.Value)
				{
					Instance.ApplyLowEndOptimizations();
				}
				Plugin.Log.LogInfo((object)"Graphics optimizer initialized. Press F10 to toggle low-end mode.");
			}
		}

		private void Awake()
		{
			SaveOriginalSettings();
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(PluginConfig.LowEndModeKey.Value))
			{
				if (_lowEndModeActive)
				{
					RestoreOriginalSettings();
				}
				else
				{
					ApplyLowEndOptimizations();
				}
				Plugin.Log.LogInfo((object)("Low-end mode: " + (_lowEndModeActive ? "ON" : "OFF")));
			}
		}

		private void SaveOriginalSettings()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			_originalShadowDistance = (int)QualitySettings.shadowDistance;
			_originalShadowQuality = QualitySettings.shadows;
			_originalShadowResolution = QualitySettings.shadowResolution;
			_originalPixelLightCount = QualitySettings.pixelLightCount;
			_originalLodBias = QualitySettings.lodBias;
			_originalMaxLod = QualitySettings.maximumLODLevel;
			_originalAniso = QualitySettings.anisotropicFiltering;
			_settingsSaved = true;
			Plugin.Log.LogDebug((object)$"Original: shadows={_originalShadowDistance}, quality={_originalShadowQuality}");
		}

		public void ApplyLowEndOptimizations()
		{
			if (!_settingsSaved)
			{
				SaveOriginalSettings();
			}
			QualitySettings.shadowDistance = 20f;
			QualitySettings.shadows = (ShadowQuality)1;
			QualitySettings.shadowResolution = (ShadowResolution)0;
			QualitySettings.shadowCascades = 1;
			QualitySettings.lodBias = 0.5f;
			QualitySettings.maximumLODLevel = 1;
			QualitySettings.pixelLightCount = 1;
			QualitySettings.anisotropicFiltering = (AnisotropicFiltering)0;
			QualitySettings.masterTextureLimit = 1;
			QualitySettings.softParticles = false;
			QualitySettings.softVegetation = false;
			QualitySettings.realtimeReflectionProbes = false;
			QualitySettings.billboardsFaceCameraPosition = false;
			_lowEndModeActive = true;
			Plugin.Log.LogInfo((object)"Low-end optimizations applied!");
		}

		public void RestoreOriginalSettings()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (_settingsSaved)
			{
				QualitySettings.shadowDistance = _originalShadowDistance;
				QualitySettings.shadows = _originalShadowQuality;
				QualitySettings.shadowResolution = _originalShadowResolution;
				QualitySettings.pixelLightCount = _originalPixelLightCount;
				QualitySettings.lodBias = _originalLodBias;
				QualitySettings.maximumLODLevel = _originalMaxLod;
				QualitySettings.anisotropicFiltering = _originalAniso;
				QualitySettings.masterTextureLimit = 0;
				QualitySettings.softParticles = true;
				QualitySettings.realtimeReflectionProbes = true;
				_lowEndModeActive = false;
				Plugin.Log.LogInfo((object)"Original settings restored");
			}
		}

		private void OnDestroy()
		{
			RestoreOriginalSettings();
		}
	}
	public static class NetworkThrottle
	{
		private static readonly Dictionary<string, float> _lastCallTimes;

		private static readonly Dictionary<string, float> _intervals;

		static NetworkThrottle()
		{
			_lastCallTimes = new Dictionary<string, float>();
			_intervals = new Dictionary<string, float>();
			_intervals["position"] = 0.05f;
			_intervals["rotation"] = 0.1f;
			_intervals["animation"] = 0.1f;
			_intervals["audio"] = 0.2f;
			_intervals["damage"] = 0.5f;
			_intervals["interact"] = 0.1f;
		}

		public static bool CanSend(string rpcType)
		{
			float valueOrDefault = _intervals.GetValueOrDefault(rpcType, 0.1f);
			float valueOrDefault2 = _lastCallTimes.GetValueOrDefault(rpcType, 0f);
			if (Time.time - valueOrDefault2 < valueOrDefault)
			{
				return false;
			}
			_lastCallTimes[rpcType] = Time.time;
			return true;
		}

		public static bool CanSendForObject(string rpcType, int objectId)
		{
			string key = $"{rpcType}_{objectId}";
			float valueOrDefault = _intervals.GetValueOrDefault(rpcType, 0.1f);
			float valueOrDefault2 = _lastCallTimes.GetValueOrDefault(key, 0f);
			if (Time.time - valueOrDefault2 < valueOrDefault)
			{
				return false;
			}
			_lastCallTimes[key] = Time.time;
			return true;
		}

		public static void SetInterval(string rpcType, float interval)
		{
			_intervals[rpcType] = interval;
		}

		public static void Clear()
		{
			_lastCallTimes.Clear();
		}
	}
	public static class ObjectPool
	{
		private static readonly Dictionary<string, Queue<GameObject>> _pools = new Dictionary<string, Queue<GameObject>>();

		private static readonly Dictionary<int, Collider[]> _colliderArrays = new Dictionary<int, Collider[]>();

		public static void Initialize()
		{
			_pools.Clear();
			_colliderArrays.Clear();
			for (int i = 1; i <= 50; i++)
			{
				_colliderArrays[i] = (Collider[])(object)new Collider[i];
			}
		}

		public static Collider[] GetColliderArray(int size)
		{
			if (_colliderArrays.TryGetValue(size, out var value))
			{
				return value;
			}
			Collider[] array = (Collider[])(object)new Collider[size];
			_colliderArrays[size] = array;
			return array;
		}

		public static void Cleanup()
		{
			_pools.Clear();
		}
	}
	public static class PerformanceMonitor
	{
		private static readonly Dictionary<string, Stopwatch> _timers = new Dictionary<string, Stopwatch>();

		private static readonly Dictionary<string, float> _averages = new Dictionary<string, float>();

		private static readonly Dictionary<string, int> _counts = new Dictionary<string, int>();

		private static float _lastLogTime;

		private const float LOG_INTERVAL = 10f;

		public static void StartTimer(string name)
		{
			if (PluginConfig.EnableLogging.Value)
			{
				if (!_timers.ContainsKey(name))
				{
					_timers[name] = new Stopwatch();
				}
				_timers[name].Restart();
			}
		}

		public static void StopTimer(string name)
		{
			if (PluginConfig.EnableLogging.Value && _timers.TryGetValue(name, out var value))
			{
				value.Stop();
				float num = (float)value.ElapsedTicks / (float)Stopwatch.Frequency * 1000f;
				if (!_averages.ContainsKey(name))
				{
					_averages[name] = 0f;
					_counts[name] = 0;
				}
				_counts[name]++;
				_averages[name] += (num - _averages[name]) / (float)_counts[name];
			}
		}

		public static void LogMetrics()
		{
			if (!PluginConfig.EnableLogging.Value || Time.time - _lastLogTime < 10f)
			{
				return;
			}
			_lastLogTime = Time.time;
			Plugin.Log.LogInfo((object)"=== Performance Metrics ===");
			foreach (KeyValuePair<string, float> average in _averages)
			{
				Plugin.Log.LogInfo((object)$"{average.Key}: {average.Value:F3}ms avg ({_counts[average.Key]} samples)");
			}
			_averages.Clear();
			_counts.Clear();
		}

		public static void Clear()
		{
			_timers.Clear();
			_averages.Clear();
			_counts.Clear();
		}
	}
	public class ShipOptimizer : MonoBehaviour
	{
		private List<Light> _shipLights = new List<Light>();

		private List<ParticleSystem> _shipParticles = new List<ParticleSystem>();

		private bool _initialized;

		private float _initDelay = 5f;

		public static ShipOptimizer Instance { get; private set; }

		public static void Initialize()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				GameObject val = new GameObject("LethalOptimizer_Ship");
				Instance = val.AddComponent<ShipOptimizer>();
				Object.DontDestroyOnLoad((Object)val);
				Plugin.Log.LogInfo((object)"Ship optimizer initialized");
			}
		}

		private void Update()
		{
			if (!_initialized)
			{
				_initDelay -= Time.deltaTime;
				if (!(_initDelay > 0f))
				{
					CacheShipComponents();
					_initialized = true;
				}
			}
		}

		private void CacheShipComponents()
		{
			Light[] array = Object.FindObjectsOfType<Light>();
			foreach (Light val in array)
			{
				if (((Object)((Component)val).gameObject).name.Contains("Ship") || ((Object)((Component)val).transform.root).name.Contains("Ship"))
				{
					_shipLights.Add(val);
				}
			}
			ParticleSystem[] array2 = Object.FindObjectsOfType<ParticleSystem>();
			foreach (ParticleSystem val2 in array2)
			{
				if (((Object)((Component)val2).gameObject).name.Contains("Ship") || ((Object)((Component)val2).transform.root).name.Contains("Ship"))
				{
					_shipParticles.Add(val2);
				}
			}
			Plugin.Log.LogDebug((object)$"Cached {_shipLights.Count} ship lights, {_shipParticles.Count} particles");
		}

		public void OptimizeShipLights()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			foreach (Light shipLight in _shipLights)
			{
				if (!((Object)(object)shipLight == (Object)null) && (int)shipLight.shadows != 0)
				{
					shipLight.shadowResolution = (LightShadowResolution)0;
				}
			}
		}

		public void SetShipParticlesEnabled(bool enabled)
		{
			foreach (ParticleSystem shipParticle in _shipParticles)
			{
				if (!((Object)(object)shipParticle == (Object)null))
				{
					if (enabled && !shipParticle.isPlaying)
					{
						shipParticle.Play();
					}
					else if (!enabled && shipParticle.isPlaying)
					{
						shipParticle.Pause();
					}
				}
			}
		}

		public void ClearCache()
		{
			_shipLights.Clear();
			_shipParticles.Clear();
			_initialized = false;
			_initDelay = 5f;
		}
	}
}
namespace LethalOptimizer.Config
{
	public static class PluginConfig
	{
		public static ConfigEntry<bool> EnableAllOptimizations;

		public static ConfigEntry<bool> EnableLogging;

		public static ConfigEntry<bool> EnableAIOptimizations;

		public static ConfigEntry<float> AIUpdateInterval;

		public static ConfigEntry<float> LOSCheckInterval;

		public static ConfigEntry<bool> ThrottleIdleEnemies;

		public static ConfigEntry<bool> EnableNetworkOptimizations;

		public static ConfigEntry<float> PositionSyncRate;

		public static ConfigEntry<float> AnimationSyncRate;

		public static ConfigEntry<float> PositionThreshold;

		public static ConfigEntry<bool> EnablePlayerOptimizations;

		public static ConfigEntry<bool> ThrottleInteractionChecks;

		public static ConfigEntry<bool> EnableUIOptimizations;

		public static ConfigEntry<float> ClockUpdateInterval;

		public static ConfigEntry<bool> EnableObjectOptimizations;

		public static ConfigEntry<bool> SkipHeldItemUpdates;

		public static ConfigEntry<bool> EnableBenchmark;

		public static ConfigEntry<float> BenchmarkDuration;

		public static ConfigEntry<KeyCode> OverlayKey;

		public static ConfigEntry<KeyCode> BenchmarkKey;

		public static ConfigEntry<bool> EnableLowEndMode;

		public static ConfigEntry<KeyCode> LowEndModeKey;

		public static ConfigEntry<bool> EnableTrapOptimizations;

		public static void Initialize(ConfigFile config)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			EnableAllOptimizations = config.Bind<bool>("General", "EnableAllOptimizations", true, "Master switch for all optimizations");
			EnableLogging = config.Bind<bool>("General", "EnableLogging", false, "Enable debug logging (may impact performance)");
			EnableAIOptimizations = config.Bind<bool>("AI", "EnableAIOptimizations", true, "Enable AI-related optimizations");
			AIUpdateInterval = config.Bind<float>("AI", "AIUpdateInterval", 0.2f, new ConfigDescription("Interval between AI logic updates (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
			LOSCheckInterval = config.Bind<float>("AI", "LOSCheckInterval", 0.1f, new ConfigDescription("Interval between line-of-sight checks (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.5f), Array.Empty<object>()));
			ThrottleIdleEnemies = config.Bind<bool>("AI", "ThrottleIdleEnemies", true, "Reduce update frequency for idle/roaming enemies");
			EnableNetworkOptimizations = config.Bind<bool>("Network", "EnableNetworkOptimizations", true, "Enable network-related optimizations");
			PositionSyncRate = config.Bind<float>("Network", "PositionSyncRate", 20f, new ConfigDescription("Position sync rate per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 60f), Array.Empty<object>()));
			AnimationSyncRate = config.Bind<float>("Network", "AnimationSyncRate", 10f, new ConfigDescription("Animation sync rate per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 30f), Array.Empty<object>()));
			PositionThreshold = config.Bind<float>("Network", "PositionThreshold", 0.01f, new ConfigDescription("Minimum position change to trigger sync", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.1f), Array.Empty<object>()));
			EnablePlayerOptimizations = config.Bind<bool>("Player", "EnablePlayerOptimizations", true, "Enable player-related optimizations");
			ThrottleInteractionChecks = config.Bind<bool>("Player", "ThrottleInteractionChecks", true, "Reduce frequency of interaction raycast checks");
			EnableUIOptimizations = config.Bind<bool>("UI", "EnableUIOptimizations", true, "Enable UI-related optimizations");
			ClockUpdateInterval = config.Bind<float>("UI", "ClockUpdateInterval", 1f, new ConfigDescription("Clock UI update interval (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			EnableObjectOptimizations = config.Bind<bool>("Objects", "EnableObjectOptimizations", true, "Enable grabbable object optimizations");
			SkipHeldItemUpdates = config.Bind<bool>("Objects", "SkipHeldItemUpdates", true, "Skip physics updates for held items");
			EnableBenchmark = config.Bind<bool>("Benchmark", "EnableBenchmark", true, "Enable built-in benchmark system");
			BenchmarkDuration = config.Bind<float>("Benchmark", "BenchmarkDuration", 60f, new ConfigDescription("Benchmark duration in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 300f), Array.Empty<object>()));
			OverlayKey = config.Bind<KeyCode>("Benchmark", "OverlayKey", (KeyCode)289, "Key to toggle performance overlay");
			BenchmarkKey = config.Bind<KeyCode>("Benchmark", "BenchmarkKey", (KeyCode)290, "Key to start/stop benchmark");
			EnableLowEndMode = config.Bind<bool>("Graphics", "EnableLowEndMode", false, "Enable low-end PC mode on startup (reduces shadows, textures, LOD)");
			LowEndModeKey = config.Bind<KeyCode>("Graphics", "LowEndModeKey", (KeyCode)291, "Key to toggle low-end mode in-game");
			EnableTrapOptimizations = config.Bind<bool>("Traps", "EnableTrapOptimizations", true, "Enable optimizations for turrets, landmines, and spike traps");
		}
	}
}