Decompiled source of LethalBoost v1.0.0

LethalBoost.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalBoost.Config;
using LethalBoost.Core;
using LethalBoost.Core.Caching;
using LethalBoost.Core.Monitoring;
using LethalBoost.Core.Throttling;
using LethalBoost.Modules.AI;
using LethalBoost.Modules.Graphics;
using LethalBoost.Modules.Interior;
using LethalBoost.Modules.Physics;
using LethalBoost.Modules.Traps;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
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: AssemblyCompany("LethalBoost")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Next-generation performance optimization mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalBoost")]
[assembly: AssemblyTitle("LethalBoost")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 LethalBoost
{
	[BepInPlugin("com.lethalboost.performance", "LethalBoost", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private PerformanceMonitor _performanceMonitor;

		private ModuleErrorHandler _errorHandler;

		private List<IOptimizationModule> _modules;

		private Dictionary<IOptimizationModule, string> _moduleNames;

		private float _lastCleanupTime;

		private const float CLEANUP_INTERVAL = 30f;

		public static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		public static ManualLogSource Logger => Log;

		public static Harmony Harmony => Instance?._harmony;

		public static PerformanceMonitor PerformanceMonitor => Instance?._performanceMonitor;

		public static AIOptimizationModule AIOptimizationModule { get; private set; }

		public static LightCullingModule LightCullingModule { get; private set; }

		public static ParticleModule ParticleModule { get; private set; }

		public static RigidbodyModule RigidbodyModule { get; private set; }

		public static PhysicsCullingModule PhysicsCullingModule { get; private set; }

		public static RoomCullingModule RoomCullingModule { get; private set; }

		public static DoorCullingModule DoorCullingModule { get; private set; }

		public static InteriorLODModule InteriorLODModule { get; private set; }

		public static GrassLODModule GrassLODModule { get; private set; }

		public static RocksDebrisLODModule RocksDebrisLODModule { get; private set; }

		public static DecalsLODModule DecalsLODModule { get; private set; }

		public static ShadowQualityLODModule ShadowQualityLODModule { get; private set; }

		public static PostProcessingLODModule PostProcessingLODModule { get; private set; }

		public static CameraCullingModule CameraCullingModule { get; private set; }

		public static TextureQualityLODModule TextureQualityLODModule { get; private set; }

		public static ReflectionProbesLODModule ReflectionProbesLODModule { get; private set; }

		public static AnimationCullingModule AnimationCullingModule { get; private set; }

		public static NavMeshOptimizationModule NavMeshOptimizationModule { get; private set; }

		public static TurretModule TurretModule { get; private set; }

		public static LandmineModule LandmineModule { get; private set; }

		public static SpikeTrapModule SpikeTrapModule { get; private set; }

		public static bool IsServer()
		{
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return GameNetworkManager.Instance.isHostingGame;
			}
			return false;
		}

		private void Awake()
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Instance = this;
			Log = Logger ?? Logger.CreateLogSource("LethalBoost");
			if (Log == null)
			{
				Debug.LogError((object)"[LethalBoost] Failed to create logger!");
				return;
			}
			Log.LogInfo((object)"=== LethalBoost v1.0.0 Starting ===");
			GameObject val = new GameObject("LethalBoost_Core")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<LethalBoostBehaviour>().Initialize(this);
			Log.LogInfo((object)"=== LethalBoost v1.0.0 Loaded Successfully ===");
		}

		internal void InitializeCore()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			try
			{
				_modules = new List<IOptimizationModule>();
				_moduleNames = new Dictionary<IOptimizationModule, string>();
				_harmony = new Harmony("com.lethalboost.performance");
				ModConfig.Initialize(((BaseUnityPlugin)Instance).Config);
				_errorHandler = new ModuleErrorHandler(Log);
				CheckModCompatibility();
				InitializeCoreSystems();
				ApplyHarmonyPatches();
				InitializeOptimizationModules();
				InitializePerformanceMonitor();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("CRITICAL ERROR during initialization: " + ex.Message));
				Log.LogError((object)("Stack trace: " + ex.StackTrace));
			}
		}

		private void CheckModCompatibility()
		{
			Log.LogInfo((object)"Checking mod compatibility...");
			Version version = typeof(GameNetworkManager).Assembly.GetName().Version;
			if (version != null && version.Major < 80)
			{
				Log.LogWarning((object)$"Game version mismatch! Expected v{80}+, got {version}. Some features may not work correctly.");
			}
			else
			{
				Log.LogInfo((object)$"Game version: {version}");
			}
			if (Chainloader.PluginInfos.ContainsKey("StaticNetcodeLib"))
			{
				Log.LogWarning((object)"StaticNetcodeLib detected. Component caching will be disabled.");
			}
			if (Chainloader.PluginInfos.ContainsKey("LethalOptimizer"))
			{
				Log.LogWarning((object)"LethalOptimizer detected. Consider using only one optimization mod.");
			}
			if (Chainloader.PluginInfos.ContainsKey("MoreCompany"))
			{
				Log.LogInfo((object)"MoreCompany detected. Player position caching will adapt.");
			}
			Log.LogInfo((object)"Mod compatibility check complete.");
		}

		private void InitializeCoreSystems()
		{
			Log.LogInfo((object)"Initializing core systems...");
			ObjectPool.Configure(4, 16);
			ComponentCache.SetMaxCacheSize(1000);
			if (ModConfig.EnableNavMeshCaching.Value)
			{
				NavMeshCache.SetCacheExpirationTime(5f);
				NavMeshCache.SetMaxCacheSize(500);
			}
			Log.LogInfo((object)"Core systems initialized.");
		}

		private void ApplyHarmonyPatches()
		{
			Log.LogInfo((object)"Applying Harmony patches...");
			_harmony.PatchAll();
			Log.LogInfo((object)"Harmony patches applied.");
		}

		private void InitializeOptimizationModules()
		{
			Log.LogInfo((object)"Initializing optimization modules...");
			AIOptimizationModule = new AIOptimizationModule();
			InitializeModule(AIOptimizationModule, "AI Optimization");
			LightCullingModule = new LightCullingModule();
			InitializeModule(LightCullingModule, "Light Culling");
			ParticleModule = new ParticleModule();
			InitializeModule(ParticleModule, "Particle Optimization");
			RigidbodyModule = new RigidbodyModule();
			InitializeModule(RigidbodyModule, "Rigidbody Freezing");
			PhysicsCullingModule = new PhysicsCullingModule();
			InitializeModule(PhysicsCullingModule, "Physics Culling");
			RoomCullingModule = new RoomCullingModule();
			InitializeModule(RoomCullingModule, "Room Culling");
			DoorCullingModule = new DoorCullingModule();
			InitializeModule(DoorCullingModule, "Door Culling");
			InteriorLODModule = new InteriorLODModule();
			InitializeModule(InteriorLODModule, "Interior LOD");
			GrassLODModule = new GrassLODModule();
			InitializeModule(GrassLODModule, "Grass LOD");
			RocksDebrisLODModule = new RocksDebrisLODModule();
			InitializeModule(RocksDebrisLODModule, "Rocks/Debris LOD");
			DecalsLODModule = new DecalsLODModule();
			InitializeModule(DecalsLODModule, "Decals LOD");
			ShadowQualityLODModule = new ShadowQualityLODModule();
			InitializeModule(ShadowQualityLODModule, "Shadow Quality LOD");
			PostProcessingLODModule = new PostProcessingLODModule();
			InitializeModule(PostProcessingLODModule, "Post-Processing LOD");
			CameraCullingModule = new CameraCullingModule();
			InitializeModule(CameraCullingModule, "Camera Culling");
			TextureQualityLODModule = new TextureQualityLODModule();
			InitializeModule(TextureQualityLODModule, "Texture Quality LOD");
			ReflectionProbesLODModule = new ReflectionProbesLODModule();
			InitializeModule(ReflectionProbesLODModule, "Reflection Probes LOD");
			AnimationCullingModule = new AnimationCullingModule();
			InitializeModule(AnimationCullingModule, "Animation Culling");
			NavMeshOptimizationModule = new NavMeshOptimizationModule();
			InitializeModule(NavMeshOptimizationModule, "NavMesh Optimization");
			TurretModule = new TurretModule();
			InitializeModule(TurretModule, "Turret Optimization");
			LandmineModule = new LandmineModule();
			InitializeModule(LandmineModule, "Landmine Optimization");
			SpikeTrapModule = new SpikeTrapModule();
			InitializeModule(SpikeTrapModule, "Spike Trap Optimization");
			Log.LogInfo((object)$"Initialized {_modules.Count} optimization modules.");
		}

		private void InitializeModule(IOptimizationModule module, string moduleName)
		{
			if (module.IsEnabled)
			{
				if (_errorHandler.ExecuteModuleInitialize(module, moduleName))
				{
					_modules.Add(module);
					_moduleNames[module] = moduleName;
				}
			}
			else
			{
				Log.LogInfo((object)(moduleName + " module disabled."));
			}
		}

		private void InitializePerformanceMonitor()
		{
			_performanceMonitor = new PerformanceMonitor(ModConfig.EnableDetailedMetrics.Value, ModConfig.EnablePerformanceOverlay.Value, ModConfig.EnableDebugLogging.Value);
			Log.LogInfo((object)"Performance monitor initialized.");
		}

		internal void OnUpdate()
		{
			try
			{
				_performanceMonitor?.BeginFrame();
				if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)RoundManager.Instance == (Object)null)
				{
					_performanceMonitor?.EndFrame();
					return;
				}
				ComponentCache.EvictLRU();
				if (_lastCleanupTime == 0f)
				{
					_lastCleanupTime = Time.time;
				}
				if (_modules != null && _moduleNames != null && _errorHandler != null)
				{
					foreach (IOptimizationModule module in _modules)
					{
						if (module != null && _moduleNames.ContainsKey(module))
						{
							_errorHandler.ExecuteModuleUpdate(module, _moduleNames[module], Time.time);
						}
					}
				}
				float time = Time.time;
				if (time - _lastCleanupTime >= 30f)
				{
					PerformPeriodicCleanup();
					_lastCleanupTime = time;
				}
				_performanceMonitor?.EndFrame();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error in Update loop: {arg}");
			}
		}

		private void PerformPeriodicCleanup()
		{
			try
			{
				NavMeshCache.PeriodicCleanup();
				if (ModConfig.EnableDebugLogging.Value)
				{
					(int, int) stats = ComponentCache.GetStats();
					Log.LogInfo((object)$"ComponentCache: {stats.Item1}/{stats.Item2} entries");
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error during cleanup: {arg}");
			}
		}

		internal void OnGUIInternal()
		{
			try
			{
				_performanceMonitor?.RenderOverlay();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error rendering overlay: {arg}");
			}
		}

		internal void Cleanup()
		{
			Log.LogInfo((object)"LethalBoost is unloading...");
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
				Log.LogInfo((object)"Harmony patches removed.");
			}
			if (_modules != null && _moduleNames != null && _errorHandler != null)
			{
				foreach (IOptimizationModule module in _modules)
				{
					if (module != null && _moduleNames.ContainsKey(module))
					{
						_errorHandler.ExecuteModuleCleanup(module, _moduleNames[module]);
					}
				}
				_modules.Clear();
				_moduleNames.Clear();
			}
			ComponentCache.Clear();
			NavMeshCache.Clear();
			ObjectPool.Clear();
			_performanceMonitor?.Cleanup();
			_errorHandler?.Clear();
			Log.LogInfo((object)"LethalBoost unloaded successfully.");
		}
	}
	public class LethalBoostBehaviour : MonoBehaviour
	{
		private Plugin _plugin;

		private bool _initialized;

		public void Initialize(Plugin plugin)
		{
			_plugin = plugin;
			_initialized = false;
		}

		private void Start()
		{
			if (!_initialized)
			{
				_initialized = true;
				_plugin.InitializeCore();
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"LethalBoostBehaviour: Core initialized in Start()");
				}
			}
		}

		private void Update()
		{
			_plugin?.OnUpdate();
		}

		private void OnGUI()
		{
			_plugin?.OnGUIInternal();
		}

		private void OnDestroy()
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"LethalBoostBehaviour: OnDestroy called");
			}
			_plugin?.Cleanup();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.lethalboost.performance";

		public const string PLUGIN_NAME = "LethalBoost";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalBoost.Patches.Traps
{
	[HarmonyPatch(typeof(Landmine))]
	public class LandminePatches
	{
		private static LandmineModule _landmineModule;

		private static FieldInfo _mineActivatedField;

		public static void Initialize(LandmineModule landmineModule)
		{
			_landmineModule = landmineModule;
			_mineActivatedField = AccessTools.Field(typeof(Landmine), "mineActivated");
			if (_mineActivatedField == null)
			{
				Plugin.Logger.LogWarning((object)"Could not find mineActivated field in Landmine class");
			}
		}

		private static bool GetMineActivated(Landmine instance)
		{
			if (_mineActivatedField == null)
			{
				return true;
			}
			return (bool)_mineActivatedField.GetValue(instance);
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(Landmine __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				if (_landmineModule == null || !_landmineModule.IsEnabled)
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (__instance.hasExploded || !GetMineActivated(__instance))
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				bool flag = _landmineModule.ShouldLandmineUpdate(instanceID, position);
				return _landmineModule.IsInDangerRadius(position) || flag;
			}, "Landmine.Update");
		}

		[HarmonyPatch("OnTriggerEnter")]
		[HarmonyPrefix]
		private static bool OnTriggerEnter_Prefix(Landmine __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				if (_landmineModule == null || !_landmineModule.IsEnabled)
				{
					return true;
				}
				if (__instance.hasExploded)
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (_landmineModule.IsInDangerRadius(position))
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				return _landmineModule.ShouldLandmineUpdate(instanceID, position);
			}, "Landmine.OnTriggerEnter");
		}

		[HarmonyPatch("OnTriggerExit")]
		[HarmonyPrefix]
		private static bool OnTriggerExit_Prefix(Landmine __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				if (_landmineModule == null || !_landmineModule.IsEnabled)
				{
					return true;
				}
				if (__instance.hasExploded || !GetMineActivated(__instance))
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (_landmineModule.IsInDangerRadius(position))
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				return _landmineModule.ShouldLandmineUpdate(instanceID, position);
			}, "Landmine.OnTriggerExit");
		}

		[HarmonyPatch("MineHasLineOfSight")]
		[HarmonyPrefix]
		private static bool MineHasLineOfSight_Prefix(Landmine __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//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)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				if (_landmineModule == null || !_landmineModule.IsEnabled)
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (_landmineModule.IsInDangerRadius(position))
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				return _landmineModule.ShouldLandmineUpdate(instanceID, position);
			}, "Landmine.MineHasLineOfSight");
		}

		public static void CleanupLandmine(Landmine landmine)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_landmineModule != null && (Object)(object)landmine != (Object)null)
				{
					int instanceID = ((Object)landmine).GetInstanceID();
					_landmineModule.ClearLandmineData(instanceID);
				}
			}, "LandminePatches.CleanupLandmine");
		}
	}
	[HarmonyPatch(typeof(SpikeRoofTrap))]
	public class SpikeRoofTrapPatches
	{
		private static SpikeTrapModule _spikeTrapModule;

		public static void Initialize(SpikeTrapModule spikeTrapModule)
		{
			_spikeTrapModule = spikeTrapModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(SpikeRoofTrap __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0048: 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_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if (_spikeTrapModule == null || !_spikeTrapModule.IsEnabled)
				{
					return true;
				}
				if (!__instance.trapActive || __instance.slammingDown)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				bool flag = _spikeTrapModule.ShouldSpikeTrapUpdate(instanceID, position);
				return _spikeTrapModule.IsPlayerNearby(position) || flag;
			}, "SpikeRoofTrap.Update");
		}

		[HarmonyPatch("OnTriggerStay")]
		[HarmonyPrefix]
		private static bool OnTriggerStay_Prefix(SpikeRoofTrap __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: 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_0065: Unknown result type (might be due to invalid IL or missing references)
				if (_spikeTrapModule == null || !_spikeTrapModule.IsEnabled)
				{
					return true;
				}
				if (!__instance.trapActive)
				{
					return true;
				}
				if (__instance.slammingDown)
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (_spikeTrapModule.IsPlayerNearby(position))
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				return _spikeTrapModule.ShouldSpikeTrapUpdate(instanceID, position);
			}, "SpikeRoofTrap.OnTriggerStay");
		}

		[HarmonyPatch("SpikeTrapSlam")]
		[HarmonyPostfix]
		private static void SpikeTrapSlam_Postfix(SpikeRoofTrap __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_spikeTrapModule != null && _spikeTrapModule.IsEnabled)
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					_spikeTrapModule.ClearSpikeTrapData(instanceID);
				}
			}, "SpikeRoofTrap.SpikeTrapSlam");
		}

		public static void CleanupSpikeTrap(SpikeRoofTrap spikeTrap)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_spikeTrapModule != null && (Object)(object)spikeTrap != (Object)null)
				{
					int instanceID = ((Object)spikeTrap).GetInstanceID();
					_spikeTrapModule.ClearSpikeTrapData(instanceID);
				}
			}, "SpikeRoofTrapPatches.CleanupSpikeTrap");
		}
	}
	[HarmonyPatch(typeof(Turret))]
	public class TurretPatches
	{
		private static TurretModule _turretModule;

		public static void Initialize(TurretModule turretModule)
		{
			_turretModule = turretModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(Turret __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//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_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				if (_turretModule == null || !_turretModule.IsEnabled)
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (!__instance.turretActive)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				bool flag = _turretModule.ShouldTurretUpdate(instanceID, position);
				return _turretModule.IsInThreatRange(position) || flag;
			}, "Turret.Update");
		}

		[HarmonyPatch("CheckForPlayersInLineOfSight")]
		[HarmonyPrefix]
		private static bool CheckForPlayersInLineOfSight_Prefix(Turret __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				if (_turretModule == null || !_turretModule.IsEnabled)
				{
					return true;
				}
				if (!__instance.turretActive)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _turretModule.IsInThreatRange(position) || _turretModule.ShouldTurretUpdate(instanceID, position);
			}, "Turret.CheckForPlayersInLineOfSight");
		}

		[HarmonyPatch("TurnTowardsTargetIfHasLOS")]
		[HarmonyPrefix]
		private static bool TurnTowardsTargetIfHasLOS_Prefix(Turret __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: 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)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				if (_turretModule == null || !_turretModule.IsEnabled)
				{
					return true;
				}
				if ((Object)(object)__instance.targetPlayerWithRotation != (Object)null)
				{
					Vector3 position = ((Component)__instance).transform.position;
					if (_turretModule.IsInThreatRange(position))
					{
						return true;
					}
					int instanceID = ((Object)__instance).GetInstanceID();
					return _turretModule.ShouldTurretUpdate(instanceID, position);
				}
				return true;
			}, "Turret.TurnTowardsTargetIfHasLOS");
		}

		public static void CleanupTurret(Turret turret)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_turretModule != null && (Object)(object)turret != (Object)null)
				{
					int instanceID = ((Object)turret).GetInstanceID();
					_turretModule.ClearTurretData(instanceID);
				}
			}, "TurretPatches.CleanupTurret");
		}
	}
}
namespace LethalBoost.Patches.Items
{
	[HarmonyPatch(typeof(GrabbableObject))]
	public class GrabbableObjectPatches
	{
		private static RigidbodyModule _rigidbodyModule;

		public static void Initialize(RigidbodyModule rigidbodyModule)
		{
			_rigidbodyModule = rigidbodyModule;
		}

		private static bool IsFunctionalItem(GrabbableObject item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			string text = item.itemProperties?.itemName?.ToLower() ?? "";
			if (text.Contains("walkie") || text.Contains("radio"))
			{
				return true;
			}
			if (text.Contains("flashlight") || text.Contains("lantern") || text.Contains("pro-flashlight") || text.Contains("laser"))
			{
				return true;
			}
			if (text.Contains("horn") || text.Contains("clown") || text.Contains("airhorn") || text.Contains("air horn"))
			{
				return true;
			}
			if (text.Contains("key") || text.Contains("card"))
			{
				return true;
			}
			if (text.Contains("shovel") || text.Contains("sign") || text.Contains("stop sign") || text.Contains("yield"))
			{
				return true;
			}
			if (text.Contains("jetpack"))
			{
				return true;
			}
			if (text.Contains("spray") || text.Contains("paint"))
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<FlashlightItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<WalkieTalkie>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<NoisemakerProp>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<Shovel>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<SprayPaintItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)item.itemProperties != (Object)null && item.itemProperties.requiresBattery)
			{
				return true;
			}
			return false;
		}

		[HarmonyPatch("GrabItem")]
		[HarmonyPrefix]
		public static void GrabItem_Prefix(GrabbableObject __instance)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_rigidbodyModule != null && _rigidbodyModule.IsEnabled && Plugin.IsServer() && !IsFunctionalItem(__instance) && (Object)(object)__instance.itemProperties != (Object)null && __instance.itemProperties.itemSpawnsOnGround)
				{
					Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null && component.isKinematic)
					{
						component.isKinematic = false;
					}
				}
			}, "GrabbableObject.GrabItem");
		}

		[HarmonyPatch("DiscardItem")]
		[HarmonyPostfix]
		public static void DiscardItem_Postfix(GrabbableObject __instance)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_rigidbodyModule != null && _rigidbodyModule.IsEnabled && Plugin.IsServer() && !IsFunctionalItem(__instance))
				{
					Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null && !component.isKinematic)
					{
						component.WakeUp();
					}
				}
			}, "GrabbableObject.DiscardItem");
		}

		[HarmonyPatch("FallWithCurve")]
		[HarmonyPrefix]
		public static void FallWithCurve_Prefix(GrabbableObject __instance)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_rigidbodyModule != null && _rigidbodyModule.IsEnabled && Plugin.IsServer() && !IsFunctionalItem(__instance))
				{
					Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
					if ((Object)(object)component != (Object)null && component.isKinematic)
					{
						component.isKinematic = false;
					}
				}
			}, "GrabbableObject.FallWithCurve");
		}
	}
}
namespace LethalBoost.Patches.Interior
{
	[HarmonyPatch]
	internal static class DoorPatches
	{
		private static DoorCullingModule _doorCullingModule;

		public static void Initialize(DoorCullingModule doorCullingModule)
		{
			_doorCullingModule = doorCullingModule;
		}

		[HarmonyPatch(typeof(DoorLock), "LockDoor")]
		[HarmonyPostfix]
		private static void LockDoor_Postfix(DoorLock __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_doorCullingModule != null && _doorCullingModule.IsEnabled && !((Object)(object)__instance == (Object)null))
				{
					_ = (Object)(object)__instance.doorTrigger != (Object)null;
				}
			}, "DoorLock.LockDoor");
		}

		[HarmonyPatch(typeof(InteractTrigger), "Interact")]
		[HarmonyPrefix]
		private static void Interact_Prefix(InteractTrigger __instance)
		{
			PatchErrorHandler.SafeExecute(delegate
			{
				if (_doorCullingModule != null && _doorCullingModule.IsEnabled && !((Object)(object)__instance == (Object)null) && (Object)(object)((Component)__instance).GetComponent<DoorLock>() != (Object)null)
				{
					Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
					foreach (Renderer val in componentsInChildren)
					{
						if ((Object)(object)val != (Object)null && !val.enabled)
						{
							val.enabled = true;
						}
					}
				}
			}, "InteractTrigger.Interact");
		}
	}
	[HarmonyPatch]
	internal static class InteriorPropPatches
	{
		private static InteriorLODModule _interiorLODModule;

		public static void Initialize(InteriorLODModule interiorLODModule)
		{
			_interiorLODModule = interiorLODModule;
		}

		[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
		[HarmonyPostfix]
		private static void SpawnScrapInLevel_Postfix(RoundManager __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_interiorLODModule != null && _interiorLODModule.IsEnabled)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)"Scrap spawned in level, interior LOD will track new items.");
					}
				}
			}, "RoundManager.SpawnScrapInLevel");
		}

		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		private static void Terminal_Start_Postfix(Terminal __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_interiorLODModule != null && _interiorLODModule.IsEnabled && !((Object)(object)__instance == (Object)null))
				{
					_interiorLODModule.RegisterProp(((Component)__instance).gameObject, isCritical: true);
				}
			}, "Terminal.Start");
		}

		[HarmonyPatch(typeof(DoorLock), "Awake")]
		[HarmonyPostfix]
		private static void DoorLock_Awake_Postfix(DoorLock __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_interiorLODModule != null && _interiorLODModule.IsEnabled && !((Object)(object)__instance == (Object)null))
				{
					_interiorLODModule.RegisterProp(((Component)__instance).gameObject, isCritical: true);
				}
			}, "DoorLock.Awake");
		}

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		[HarmonyPostfix]
		private static void GrabbableObject_Start_Postfix(GrabbableObject __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_interiorLODModule != null && _interiorLODModule.IsEnabled && !((Object)(object)__instance == (Object)null))
				{
					_interiorLODModule.RegisterProp(((Component)__instance).gameObject, isCritical: true);
				}
			}, "GrabbableObject.Start");
		}

		[HarmonyPatch(typeof(EntranceTeleport), "Awake")]
		[HarmonyPostfix]
		private static void EntranceTeleport_Awake_Postfix(EntranceTeleport __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_interiorLODModule != null && _interiorLODModule.IsEnabled && !((Object)(object)__instance == (Object)null))
				{
					_interiorLODModule.RegisterProp(((Component)__instance).gameObject, isCritical: true);
				}
			}, "EntranceTeleport.Awake");
		}

		private static bool IsInteriorProp(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			string text = LayerMask.LayerToName(obj.layer);
			if (text.Contains("Room") || text.Contains("Props") || text.Contains("MapProps") || text.Contains("Interior"))
			{
				return true;
			}
			Transform val = obj.transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.Contains("Dungeon") || ((Object)val).name.Contains("Interior") || ((Object)val).name.Contains("Room"))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static bool IsCriticalProp(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return false;
			}
			if ((Object)(object)obj.GetComponent<Terminal>() != (Object)null || (Object)(object)obj.GetComponent<DoorLock>() != (Object)null || (Object)(object)obj.GetComponent<InteractTrigger>() != (Object)null || (Object)(object)obj.GetComponent<GrabbableObject>() != (Object)null || (Object)(object)obj.GetComponent<EntranceTeleport>() != (Object)null)
			{
				return true;
			}
			string text = ((Object)obj).name.ToLower();
			if (text.Contains("terminal") || text.Contains("door") || text.Contains("entrance") || text.Contains("exit") || text.Contains("ladder") || text.Contains("vent") || text.Contains("breaker") || text.Contains("apparatus"))
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class RoomPatches
	{
		private static RoomCullingModule _roomCullingModule;

		public static void Initialize(RoomCullingModule roomCullingModule)
		{
			_roomCullingModule = roomCullingModule;
		}

		[HarmonyPatch(typeof(AdjacentRoomCullingModified), "AddDungeon")]
		[HarmonyPostfix]
		private static void AddDungeon_Postfix(AdjacentRoomCullingModified __instance, Dungeon dungeon)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_roomCullingModule != null && _roomCullingModule.IsEnabled && !((Object)(object)dungeon == (Object)null))
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)$"Dungeon added with {dungeon.AllTiles.Count} tiles.");
					}
				}
			}, "AdjacentRoomCullingModified.AddDungeon");
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
		[HarmonyPostfix]
		private static void GenerateNewFloor_Postfix(RoundManager __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_roomCullingModule != null && _roomCullingModule.IsEnabled)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)"New floor generated, room culling will rebuild.");
					}
				}
			}, "RoundManager.GenerateNewFloor");
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPostfix]
		private static void ShipLeave_Postfix(StartOfRound __instance)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				if (_roomCullingModule != null && _roomCullingModule.IsEnabled)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)"Ship leaving, room culling state will be cleaned.");
					}
				}
			}, "StartOfRound.ShipLeave");
		}
	}
}
namespace LethalBoost.Patches.Base
{
	[HarmonyPatch]
	internal static class LightPatches
	{
		private static LightCullingModule _lightModule;

		private static readonly Dictionary<int, Component> _parentComponentCache = new Dictionary<int, Component>();

		private const int CACHE_MAX_SIZE = 500;

		private static int _cacheClearCounter = 0;

		private const int CACHE_CLEAR_INTERVAL = 1000;

		public static void Initialize(LightCullingModule lightModule)
		{
			_lightModule = lightModule;
			_parentComponentCache.Clear();
		}

		private static T GetComponentInParentCached<T>(GameObject obj) where T : Component
		{
			if ((Object)(object)obj == (Object)null)
			{
				return default(T);
			}
			int key = ((Object)obj).GetInstanceID() ^ typeof(T).GetHashCode();
			if (_parentComponentCache.TryGetValue(key, out var value))
			{
				if ((Object)(object)value != (Object)null && Object.op_Implicit((Object)(object)value))
				{
					return (T)(object)((value is T) ? value : null);
				}
				_parentComponentCache.Remove(key);
			}
			T componentInParent = obj.GetComponentInParent<T>();
			if ((Object)(object)componentInParent != (Object)null && _parentComponentCache.Count < 500)
			{
				_parentComponentCache[key] = (Component)(object)componentInParent;
			}
			return componentInParent;
		}

		public static bool IsCriticalLight(Light light)
		{
			if ((Object)(object)light == (Object)null)
			{
				return false;
			}
			GameObject gameObject = ((Component)light).gameObject;
			_cacheClearCounter++;
			if (_cacheClearCounter >= 1000)
			{
				_cacheClearCounter = 0;
				_parentComponentCache.Clear();
			}
			if ((Object)(object)GetComponentInParentCached<FlashlightItem>(gameObject) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)GetComponentInParentCached<ShipLights>(gameObject) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)GetComponentInParentCached<Terminal>(gameObject) != (Object)null)
			{
				return true;
			}
			if (((Object)gameObject).name.Contains("Emergency") || ((Object)gameObject).name.Contains("MainLight") || gameObject.CompareTag("ImportantLight"))
			{
				return true;
			}
			if (light.intensity > 5f)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class ParticlePatches
	{
		private static ParticleModule _particleModule;

		public static void Initialize(ParticleModule particleModule)
		{
			_particleModule = particleModule;
		}

		public static bool IsCriticalParticleSystem(ParticleSystem particleSystem)
		{
			if ((Object)(object)particleSystem == (Object)null)
			{
				return false;
			}
			GameObject gameObject = ((Component)particleSystem).gameObject;
			if ((Object)(object)gameObject.GetComponentInParent<PlayerControllerB>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)gameObject.GetComponentInParent<GrabbableObject>() != (Object)null)
			{
				return true;
			}
			if (((Object)gameObject).name.Contains("Player") || ((Object)gameObject).name.Contains("Critical") || gameObject.CompareTag("Important"))
			{
				return true;
			}
			return false;
		}
	}
}
namespace LethalBoost.Patches.AI
{
	public static class AIPatchManager
	{
		private static bool _patchesApplied;

		public static void ApplyPatches(Harmony harmony, AIOptimizationModule aiModule)
		{
			if (_patchesApplied)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"AI patches already applied.");
				}
				return;
			}
			if (!ModConfig.EnableAIOptimization.Value)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"AI optimization disabled in configuration. Skipping AI patches.");
				}
				return;
			}
			try
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"Applying AI optimization patches...");
				}
				EnemyAIPatches.Initialize(aiModule);
				harmony.PatchAll(typeof(EnemyAIPatches));
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)"Applied base EnemyAI patches.");
				}
				List<Type> list = new List<Type>();
				if (ModConfig.OptimizeCoilHead.Value)
				{
					CoilHeadPatches.Initialize(aiModule);
					list.Add(typeof(CoilHeadPatches));
				}
				if (ModConfig.OptimizeJester.Value)
				{
					JesterPatches.Initialize(aiModule);
					list.Add(typeof(JesterPatches));
				}
				if (ModConfig.OptimizeThumper.Value)
				{
					ThumperPatches.Initialize(aiModule);
					list.Add(typeof(ThumperPatches));
				}
				if (ModConfig.OptimizeHoardingBug.Value)
				{
					HoardingBugPatches.Initialize(aiModule);
					list.Add(typeof(HoardingBugPatches));
				}
				if (ModConfig.OptimizeSporeLizard.Value)
				{
					SporeLizardPatches.Initialize(aiModule);
					list.Add(typeof(SporeLizardPatches));
				}
				if (ModConfig.OptimizeBunkerSpider.Value)
				{
					BunkerSpiderPatches.Initialize(aiModule);
					list.Add(typeof(BunkerSpiderPatches));
				}
				if (ModConfig.OptimizeForestKeeper.Value)
				{
					ForestKeeperPatches.Initialize(aiModule);
					list.Add(typeof(ForestKeeperPatches));
				}
				if (ModConfig.OptimizeEyelessDog.Value)
				{
					EyelessDogPatches.Initialize(aiModule);
					list.Add(typeof(EyelessDogPatches));
				}
				if (ModConfig.OptimizeBaboonHawk.Value)
				{
					BaboonHawkPatches.Initialize(aiModule);
					list.Add(typeof(BaboonHawkPatches));
				}
				int count = list.Count;
				foreach (Type item in list)
				{
					harmony.PatchAll(item);
				}
				_patchesApplied = true;
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"Applied {count} enemy-specific AI patches successfully.");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log6 = Plugin.Log;
				if (log6 != null)
				{
					log6.LogError((object)$"Failed to apply AI patches: {arg}");
				}
				throw;
			}
		}

		public static void RemovePatches(Harmony harmony)
		{
			if (!_patchesApplied)
			{
				return;
			}
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Removing AI optimization patches...");
				}
				harmony.UnpatchSelf();
				_patchesApplied = false;
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"AI optimization patches removed successfully.");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)$"Error removing AI patches: {arg}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(BaboonBirdAI))]
	internal static class BaboonHawkPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(BaboonBirdAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Baboon Hawk"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex >= 1)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "BaboonBirdAI.Update");
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI))]
	internal static class BunkerSpiderPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(SandSpiderAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Bunker Spider"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "SandSpiderAI.Update");
		}
	}
	[HarmonyPatch(typeof(SpringManAI))]
	internal static class CoilHeadPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(SpringManAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: 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)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Coil-Head"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (DistanceThrottler.GetClosestPlayerDistance(position) < 10f)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "SpringManAI.Update");
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal static class EnemyAIPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(EnemyAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled)
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (__instance.isEnemyDead || __instance.inSpecialAnimation)
				{
					return true;
				}
				if ((Object)(object)__instance.enemyType != (Object)null)
				{
					string enemyName = __instance.enemyType.enemyName;
					if (!string.IsNullOrEmpty(enemyName) && !_aiModule.IsEnemyTypeOptimizationEnabled(enemyName))
					{
						return true;
					}
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "EnemyAI.Update");
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static void DoAIInterval_Prefix(EnemyAI __instance, out float __state)
		{
			__state = __instance.AIIntervalTime;
			PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled)
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (__instance.isEnemyDead || __instance.inSpecialAnimation)
				{
					return true;
				}
				if ((Object)(object)__instance.enemyType != (Object)null)
				{
					string enemyName = __instance.enemyType.enemyName;
					if (!string.IsNullOrEmpty(enemyName) && !_aiModule.IsEnemyTypeOptimizationEnabled(enemyName))
					{
						return true;
					}
				}
				Vector3 position = ((Component)__instance).transform.position;
				float aIIntervalMultiplier = _aiModule.GetAIIntervalMultiplier(position);
				EnemyType enemyType = __instance.enemyType;
				float num = ((enemyType != null && enemyType.isOutsideEnemy) ? 0.1f : 0.2f);
				__instance.AIIntervalTime = num * aIIntervalMultiplier;
				return true;
			}, "EnemyAI.DoAIInterval");
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPostfix]
		private static void DoAIInterval_Postfix(EnemyAI __instance, float __state)
		{
			PatchErrorHandler.ExecutePostfix(delegate
			{
				__instance.AIIntervalTime = __state;
			}, "EnemyAI.DoAIInterval");
		}
	}
	[HarmonyPatch(typeof(MouthDogAI))]
	internal static class EyelessDogPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(MouthDogAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Eyeless Dog"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1 || ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "MouthDogAI.Update");
		}
	}
	[HarmonyPatch(typeof(ForestGiantAI))]
	internal static class ForestKeeperPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(ForestGiantAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Forest Keeper"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "ForestGiantAI.Update");
		}
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal static class HoardingBugPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(HoarderBugAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Hoarding Bug"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				int instanceID = ((Object)__instance).GetInstanceID();
				bool flag = _aiModule.ShouldEnemyUpdate(instanceID, position);
				if (ModConfig.EnableDebugLogging.Value && !flag)
				{
					float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(position);
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)$"HoardingBug: Throttled (distance={closestPlayerDistance:F1}m)");
					}
				}
				return flag;
			}, "HoarderBugAI.Update");
		}
	}
	[HarmonyPatch(typeof(JesterAI))]
	internal static class JesterPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(JesterAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Jester"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex >= 1)
				{
					if (ModConfig.EnableDebugLogging.Value)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogDebug((object)$"Jester: In critical state ({((EnemyAI)__instance).currentBehaviourStateIndex}), always updating");
						}
					}
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(position);
				bool flag = _aiModule.ShouldEnemyUpdate(instanceID, position);
				if (ModConfig.EnableDebugLogging.Value && !flag)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogDebug((object)$"Jester: Roaming state, distance={closestPlayerDistance:F1}m, throttled");
					}
				}
				return flag;
			}, "JesterAI.Update");
		}
	}
	[HarmonyPatch(typeof(PufferAI))]
	internal static class SporeLizardPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(PufferAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//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_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Spore Lizard"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
				{
					if (ModConfig.EnableDebugLogging.Value)
					{
						ManualLogSource log = Plugin.Log;
						if (log != null)
						{
							log.LogDebug((object)"SporeLizard: In puffed state (1), always updating");
						}
					}
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(position);
				bool flag = _aiModule.ShouldEnemyUpdate(instanceID, position);
				if (ModConfig.EnableDebugLogging.Value && !flag)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogDebug((object)$"SporeLizard: Distance={closestPlayerDistance:F1}m, state={((EnemyAI)__instance).currentBehaviourStateIndex}, throttled");
					}
				}
				return flag;
			}, "PufferAI.Update");
		}
	}
	[HarmonyPatch(typeof(CrawlerAI))]
	internal static class ThumperPatches
	{
		private static AIOptimizationModule _aiModule;

		public static void Initialize(AIOptimizationModule aiModule)
		{
			_aiModule = aiModule;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool Update_Prefix(CrawlerAI __instance)
		{
			return PatchErrorHandler.ExecutePrefix(delegate
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if (_aiModule == null || !_aiModule.IsEnabled || !_aiModule.IsEnemyTypeOptimizationEnabled("Thumper"))
				{
					return true;
				}
				if (!Plugin.IsServer())
				{
					return true;
				}
				if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
				{
					return true;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				Vector3 position = ((Component)__instance).transform.position;
				return _aiModule.ShouldEnemyUpdate(instanceID, position);
			}, "CrawlerAI.Update");
		}
	}
}
namespace LethalBoost.Modules.Traps
{
	public class LandmineModule : TrapOptimizationModuleBase<LandmineModule.LandmineThrottleData>
	{
		public class LandmineThrottleData
		{
			public float LastUpdateTime;

			public float CurrentUpdateInterval;

			public bool IsInDangerRadius;
		}

		protected override float ThrottleDistance => 15f;

		protected override float DangerRange => 3f;

		protected override string ModuleName => "Landmine Optimization Module";

		public override bool IsEnabled => ModConfig.EnableLandmineOptimization?.Value ?? false;

		protected override void InitializeThrottleData(LandmineThrottleData data, float currentTime)
		{
			data.LastUpdateTime = currentTime - 1f;
			data.CurrentUpdateInterval = 0f;
			data.IsInDangerRadius = false;
		}

		protected override bool ShouldCleanupEntry(LandmineThrottleData data, float currentTime)
		{
			return currentTime - data.LastUpdateTime > 60f;
		}

		public override bool ShouldTrapUpdate(int landmineInstanceID, Vector3 landminePosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ShouldLandmineUpdate(landmineInstanceID, landminePosition);
		}

		public bool ShouldLandmineUpdate(int landmineInstanceID, Vector3 landminePosition)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			float time = Time.time;
			float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(landminePosition);
			LandmineThrottleData orCreateThrottleData = GetOrCreateThrottleData(landmineInstanceID, time);
			if (orCreateThrottleData.IsInDangerRadius = closestPlayerDistance < DangerRange)
			{
				orCreateThrottleData.LastUpdateTime = time;
				orCreateThrottleData.CurrentUpdateInterval = 1f / 30f;
				return true;
			}
			float num = (orCreateThrottleData.CurrentUpdateInterval = ((!(closestPlayerDistance < ThrottleDistance)) ? 0.2f : (1f / 30f)));
			if (time - orCreateThrottleData.LastUpdateTime >= num)
			{
				orCreateThrottleData.LastUpdateTime = time;
				return true;
			}
			return false;
		}

		public float GetCollisionSphereMultiplier(Vector3 landminePosition)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return 1f;
			}
			float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(landminePosition);
			if (closestPlayerDistance < DangerRange)
			{
				return 1f;
			}
			if (closestPlayerDistance < ThrottleDistance)
			{
				return 0.9f;
			}
			return 0.75f;
		}

		public bool IsInDangerRadius(Vector3 landminePosition)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			return DistanceThrottler.GetClosestPlayerDistance(landminePosition) < DangerRange;
		}

		public float GetLandmineIntervalMultiplier(Vector3 landminePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return GetIntervalMultiplier(landminePosition);
		}

		public void ClearLandmineData(int landmineInstanceID)
		{
			ClearTrapData(landmineInstanceID);
		}
	}
	public class SpikeTrapModule : TrapOptimizationModuleBase<SpikeTrapModule.SpikeTrapThrottleData>
	{
		public class SpikeTrapThrottleData
		{
			public float LastUpdateTime;

			public float CurrentUpdateInterval;

			public bool IsPlayerNearby;
		}

		protected override float ThrottleDistance => 15f;

		protected override float DangerRange => 15f;

		protected override string ModuleName => "Spike Trap Optimization Module";

		public override bool IsEnabled => ModConfig.EnableSpikeTrapOptimization?.Value ?? false;

		protected override void InitializeThrottleData(SpikeTrapThrottleData data, float currentTime)
		{
			data.LastUpdateTime = currentTime - 1f;
			data.CurrentUpdateInterval = 0f;
			data.IsPlayerNearby = false;
		}

		protected override bool ShouldCleanupEntry(SpikeTrapThrottleData data, float currentTime)
		{
			return currentTime - data.LastUpdateTime > 60f;
		}

		public override bool ShouldTrapUpdate(int spikeTrapInstanceID, Vector3 spikeTrapPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ShouldSpikeTrapUpdate(spikeTrapInstanceID, spikeTrapPosition);
		}

		public bool ShouldSpikeTrapUpdate(int spikeTrapInstanceID, Vector3 spikeTrapPosition)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			float time = Time.time;
			float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(spikeTrapPosition);
			SpikeTrapThrottleData orCreateThrottleData = GetOrCreateThrottleData(spikeTrapInstanceID, time);
			if (orCreateThrottleData.IsPlayerNearby = closestPlayerDistance < ThrottleDistance)
			{
				orCreateThrottleData.LastUpdateTime = time;
				orCreateThrottleData.CurrentUpdateInterval = 1f / 30f;
				return true;
			}
			float num = (orCreateThrottleData.CurrentUpdateInterval = 0.2f);
			if (time - orCreateThrottleData.LastUpdateTime >= num)
			{
				orCreateThrottleData.LastUpdateTime = time;
				return true;
			}
			return false;
		}

		public float GetCollisionDetectionMultiplier(Vector3 spikeTrapPosition)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return 1f;
			}
			if (DistanceThrottler.GetClosestPlayerDistance(spikeTrapPosition) < ThrottleDistance)
			{
				return 1f;
			}
			return 1f / 6f;
		}

		public bool IsPlayerNearby(Vector3 spikeTrapPosition)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			return DistanceThrottler.GetClosestPlayerDistance(spikeTrapPosition) < ThrottleDistance;
		}

		public float GetSpikeTrapIntervalMultiplier(Vector3 spikeTrapPosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return GetIntervalMultiplier(spikeTrapPosition);
		}

		public bool ShouldPerformRaycastDetection(int spikeTrapInstanceID, Vector3 spikeTrapPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ShouldSpikeTrapUpdate(spikeTrapInstanceID, spikeTrapPosition);
		}

		public void ClearSpikeTrapData(int spikeTrapInstanceID)
		{
			ClearTrapData(spikeTrapInstanceID);
		}
	}
	public abstract class TrapOptimizationModuleBase<TThrottleData> : IOptimizationModule where TThrottleData : class, new()
	{
		protected bool _isInitialized;

		protected Dictionary<int, TThrottleData> _trapData;

		protected float _lastCleanupTime;

		protected const float CLEANUP_INTERVAL = 30f;

		protected const float CLEANUP_EXPIRY_TIME = 60f;

		public abstract bool IsEnabled { get; }

		protected abstract float ThrottleDistance { get; }

		protected abstract float DangerRange { get; }

		protected abstract string ModuleName { get; }

		protected TrapOptimizationModuleBase()
		{
			_trapData = new Dictionary<int, TThrottleData>();
		}

		public virtual void Initialize()
		{
			if (_isInitialized)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)(ModuleName + " already initialized."));
				}
				return;
			}
			try
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("Initializing " + ModuleName + "..."));
				}
				_trapData.Clear();
				_lastCleanupTime = Time.time;
				_isInitialized = true;
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)$"{ModuleName} initialized. Throttle distance: {ThrottleDistance}m, Danger range: {DangerRange}m");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogError((object)$"Failed to initialize {ModuleName}: {arg}");
				}
				throw;
			}
		}

		public virtual void Update()
		{
			if (!IsEnabled || !_isInitialized || !Plugin.IsServer())
			{
				return;
			}
			try
			{
				DistanceThrottler.UpdatePlayerPositionCache();
				float time = Time.time;
				if (time - _lastCleanupTime >= 30f)
				{
					PerformPeriodicCleanup();
					_lastCleanupTime = time;
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Error in {ModuleName} Update: {arg}");
				}
			}
		}

		protected virtual void PerformPeriodicCleanup()
		{
			try
			{
				float time = Time.time;
				List<int> list = new List<int>();
				foreach (KeyValuePair<int, TThrottleData> trapDatum in _trapData)
				{
					if (ShouldCleanupEntry(trapDatum.Value, time))
					{
						list.Add(trapDatum.Key);
					}
				}
				foreach (int item in list)
				{
					_trapData.Remove(item);
				}
				if (ModConfig.EnableDebugLogging.Value && list.Count > 0)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)$"{ModuleName}: Cleaned up {list.Count} expired entries");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error during {ModuleName} cleanup: {arg}");
				}
			}
		}

		protected virtual bool ShouldCleanupEntry(TThrottleData data, float currentTime)
		{
			return false;
		}

		protected TThrottleData GetOrCreateThrottleData(int instanceId, float currentTime)
		{
			if (!_trapData.TryGetValue(instanceId, out var value))
			{
				value = new TThrottleData();
				InitializeThrottleData(value, currentTime);
				_trapData[instanceId] = value;
			}
			return value;
		}

		protected abstract void InitializeThrottleData(TThrottleData data, float currentTime);

		public abstract bool ShouldTrapUpdate(int trapInstanceId, Vector3 trapPosition);

		public virtual float GetIntervalMultiplier(Vector3 trapPosition)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return 1f;
			}
			float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(trapPosition);
			if (closestPlayerDistance < DangerRange)
			{
				return 1f;
			}
			if (closestPlayerDistance < ThrottleDistance)
			{
				return 1f;
			}
			return 1f / 6f;
		}

		public void ClearTrapData(int trapInstanceId)
		{
			_trapData.Remove(trapInstanceId);
		}

		public virtual void Cleanup()
		{
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Cleaning up " + ModuleName + "..."));
				}
				_trapData.Clear();
				_isInitialized = false;
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)(ModuleName + " cleaned up successfully."));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)$"Error during {ModuleName} cleanup: {arg}");
				}
			}
		}

		public virtual void Reset()
		{
			try
			{
				if (!_isInitialized)
				{
					return;
				}
				_trapData.Clear();
				_lastCleanupTime = Time.time;
				if (ModConfig.EnableDebugLogging.Value)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogDebug((object)(ModuleName + " reset for new level."));
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error during {ModuleName} reset: {arg}");
				}
			}
		}
	}
	public class TurretModule : TrapOptimizationModuleBase<TurretModule.TurretThrottleData>
	{
		public class TurretThrottleData
		{
			public float LastUpdateTime;

			public float CurrentUpdateInterval;

			public bool IsInThreatRange;
		}

		protected override float ThrottleDistance => 20f;

		protected override float DangerRange => 15f;

		protected override string ModuleName => "Turret Optimization Module";

		public override bool IsEnabled => ModConfig.EnableTurretOptimization?.Value ?? false;

		protected override void InitializeThrottleData(TurretThrottleData data, float currentTime)
		{
			data.LastUpdateTime = currentTime - 1f;
			data.CurrentUpdateInterval = 0f;
			data.IsInThreatRange = false;
		}

		protected override bool ShouldCleanupEntry(TurretThrottleData data, float currentTime)
		{
			return currentTime - data.LastUpdateTime > 60f;
		}

		public override bool ShouldTrapUpdate(int turretInstanceID, Vector3 turretPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return ShouldTurretUpdate(turretInstanceID, turretPosition);
		}

		public bool ShouldTurretUpdate(int turretInstanceID, Vector3 turretPosition)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			float time = Time.time;
			float closestPlayerDistance = DistanceThrottler.GetClosestPlayerDistance(turretPosition);
			TurretThrottleData orCreateThrottleData = GetOrCreateThrottleData(turretInstanceID, time);
			if (orCreateThrottleData.IsInThreatRange = closestPlayerDistance < DangerRange)
			{
				orCreateThrottleData.LastUpdateTime = time;
				orCreateThrottleData.CurrentUpdateInterval = 1f / 30f;
				return true;
			}
			float num = (orCreateThrottleData.CurrentUpdateInterval = ((!(closestPlayerDistance < ThrottleDistance)) ? 0.2f : (1f / 30f)));
			if (time - orCreateThrottleData.LastUpdateTime >= num)
			{
				orCreateThrottleData.LastUpdateTime = time;
				return true;
			}
			return false;
		}

		public float GetTurretIntervalMultiplier(Vector3 turretPosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return GetIntervalMultiplier(turretPosition);
		}

		public bool IsInThreatRange(Vector3 turretPosition)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !_isInitialized)
			{
				return true;
			}
			return DistanceThrottler.GetClosestPlayerDistance(turretPosition) < DangerRange;
		}

		public void ClearTurretData(int turretInstanceID)
		{
			ClearTrapData(turretInstanceID);
		}
	}
}
namespace LethalBoost.Modules.Physics
{
	public class PhysicsCullingModule : IOptimizationModule
	{
		private class PhysicsState
		{
			public bool OriginalSimulated;

			public bool IsSimulated;

			public float LastStateChangeTime;

			public float LastAccessTime;
		}

		private class RoomOccupancy
		{
			public string RoomId;

			public bool IsOccupied;

			public float LastOccupiedTime;
		}

		private readonly Dictionary<int, PhysicsState> _physicsStates = new Dictionary<int, PhysicsState>();

		private readonly Dictionary<string, RoomOccupancy> _roomOccupancy = new Dictionary<string, RoomOccupancy>();

		private List<Rigidbody> _cachedRigidbodies = new List<Rigidbody>();

		private float _lastScanTime;

		private const float SCAN_INTERVAL = 5f;

		private const float HYSTERESIS_TIME = 2f;

		private const float ROOM_CHECK_RADIUS = 15f;

		public bool IsEnabled => ModConfig.EnablePhysicsCulling?.Value ?? false;

		public void Initialize()
		{
			if (!IsEnabled)
			{
				Plugin.Logger.LogInfo((object)"PhysicsCullingModule: Disabled in configuration");
			}
			else
			{
				Plugin.Logger.LogInfo((object)"PhysicsCullingModule: Initialized");
			}
		}

		public void Update()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled || !Plugin.IsServer())
			{
				return;
			}
			try
			{
				PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
				if (array == null)
				{
					return;
				}
				UpdateRoomOccupancy(array);
				float time = Time.time;
				if (time - _lastScanTime >= 5f)
				{
					_lastScanTime = time;
					_cachedRigidbodies.Clear();
					_cachedRigidbodies.AddRange(Object.FindObjectsOfType<Rigidbody>());
				}
				foreach (Rigidbody cachedRigidbody in _cachedRigidbodies)
				{
					if (!((Object)(object)cachedRigidbody == (Object)null) && !((Object)(object)((Component)cachedRigidbody).gameObject == (Object)null) && !ShouldSkipPhysicsObject(cachedRigidbody))
					{
						int instanceID = ((Object)cachedRigidbody).GetInstanceID();
						if (!_physicsStates.ContainsKey(instanceID))
						{
							_physicsStates[instanceID] = new PhysicsState
							{
								OriginalSimulated = !cachedRigidbody.isKinematic,
								LastStateChangeTime = Time.time
							};
						}
						PhysicsState state = _physicsStates[instanceID];
						bool isInOccupiedRoom = IsInOccupiedRoom(((Component)cachedRigidbody).transform.position, array);
						ApplyPhysicsCulling(cachedRigidbody, state, isInOccupiedRoom);
					}
				}
				CleanupDeadEntries();
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("PhysicsCullingModule.Update error: " + ex.Message));
			}
		}

		private void UpdateRoomOccupancy(PlayerControllerB[] players)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			_roomOccupancy.Clear();
			foreach (PlayerControllerB val in players)
			{
				if (!((Object)(object)val == (Object)null) && !val.isPlayerDead)
				{
					string roomId = GetRoomId(((Component)val).transform.position);
					if (!_roomOccupancy.ContainsKey(roomId))
					{
						_roomOccupancy[roomId] = new RoomOccupancy
						{
							RoomId = roomId,
							LastOccupiedTime = Time.time,
							IsOccupied = true
						};
					}
					else
					{
						_roomOccupancy[roomId].LastOccupiedTime = Time.time;
						_roomOccupancy[roomId].IsOccupied = true;
					}
				}
			}
		}

		private string GetRoomId(Vector3 position)
		{
			//IL_0000: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.FloorToInt(position.x / 15f);
			int num2 = Mathf.FloorToInt(position.y / 15f);
			int num3 = Mathf.FloorToInt(position.z / 15f);
			return $"{num}_{num2}_{num3}";
		}

		private bool IsInOccupiedRoom(Vector3 position, PlayerControllerB[] players)
		{
			//IL_004d: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			foreach (PlayerControllerB val in players)
			{
				if (!((Object)(object)val == (Object)null) && !val.isPlayerDead)
				{
					Vector3 val2 = ((Component)val).transform.position - position;
					if (((Vector3)(ref val2)).sqrMagnitude < 225f)
					{
						return true;
					}
				}
			}
			string roomId = GetRoomId(position);
			if (_roomOccupancy.TryGetValue(roomId, out var value))
			{
				if (!value.IsOccupied)
				{
					return Time.time - value.LastOccupiedTime < 2f;
				}
				return true;
			}
			return false;
		}

		private bool ShouldSkipPhysicsObject(Rigidbody rb)
		{
			if ((Object)(object)rb == (Object)null || (Object)(object)((Component)rb).gameObject == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)rb).gameObject.GetComponent<PlayerControllerB>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)rb).gameObject.GetComponent<EnemyAI>() != (Object)null)
			{
				return true;
			}
			if (rb.isKinematic)
			{
				return true;
			}
			GrabbableObject component = ((Component)rb).gameObject.GetComponent<GrabbableObject>();
			if ((Object)(object)component != (Object)null && component.isHeld)
			{
				return true;
			}
			if ((Object)(object)component != (Object)null && IsFunctionalItem(component))
			{
				return true;
			}
			string text = ((Object)((Component)rb).gameObject).name.ToLower();
			if (text.Contains("ship") || text.Contains("hangar") || text.Contains("vehicle") || text.Contains("elevator"))
			{
				return true;
			}
			Transform parent = ((Component)rb).transform.parent;
			while ((Object)(object)parent != (Object)null)
			{
				string text2 = ((Object)parent).name.ToLower();
				if (text2.Contains("ship") || text2.Contains("hangar") || text2.Contains("vehicle") || text2.Contains("elevator"))
				{
					return true;
				}
				parent = parent.parent;
			}
			if ((Object)(object)((Component)rb).gameObject.GetComponent<VehicleController>() != (Object)null || (Object)(object)((Component)rb).gameObject.GetComponentInParent<VehicleController>() != (Object)null)
			{
				return true;
			}
			return false;
		}

		private bool IsFunctionalItem(GrabbableObject item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			string text = item.itemProperties?.itemName?.ToLower() ?? "";
			if (text.Contains("walkie") || text.Contains("radio"))
			{
				return true;
			}
			if (text.Contains("flashlight") || text.Contains("lantern") || text.Contains("pro-flashlight") || text.Contains("laser"))
			{
				return true;
			}
			if (text.Contains("horn") || text.Contains("clown") || text.Contains("airhorn") || text.Contains("air horn"))
			{
				return true;
			}
			if (text.Contains("key") || text.Contains("card"))
			{
				return true;
			}
			if (text.Contains("shovel") || text.Contains("sign") || text.Contains("stop sign") || text.Contains("yield"))
			{
				return true;
			}
			if (text.Contains("jetpack"))
			{
				return true;
			}
			if (text.Contains("spray") || text.Contains("paint"))
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<FlashlightItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<WalkieTalkie>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<NoisemakerProp>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<Shovel>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<SprayPaintItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)item.itemProperties != (Object)null && item.itemProperties.requiresBattery)
			{
				return true;
			}
			return false;
		}

		private void ApplyPhysicsCulling(Rigidbody rb, PhysicsState state, bool isInOccupiedRoom)
		{
			if ((Object)(object)rb == (Object)null)
			{
				return;
			}
			try
			{
				if (Time.time - state.LastStateChangeTime < 2f)
				{
					return;
				}
				if (isInOccupiedRoom)
				{
					if (!state.IsSimulated && state.OriginalSimulated)
					{
						rb.isKinematic = false;
						state.IsSimulated = true;
						state.LastStateChangeTime = Time.time;
						if (ModConfig.EnableDebugLogging.Value)
						{
							Plugin.Logger.LogDebug((object)("Enabled physics for " + ((Object)((Component)rb).gameObject).name + " (room occupied)"));
						}
					}
				}
				else if (state.IsSimulated)
				{
					rb.isKinematic = true;
					state.IsSimulated = false;
					state.LastStateChangeTime = Time.time;
					if (ModConfig.EnableDebugLogging.Value)
					{
						Plugin.Logger.LogDebug((object)("Disabled physics for " + ((Object)((Component)rb).gameObject).name + " (room unoccupied)"));
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error applying physics culling: " + ex.Message));
			}
		}

		private void CleanupDeadEntries()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, PhysicsState> physicsState in _physicsStates)
			{
				if (physicsState.Value.LastAccessTime < Time.time - 60f)
				{
					list.Add(physicsState.Key);
				}
				else
				{
					physicsState.Value.LastAccessTime = Time.time;
				}
			}
			foreach (int item in list)
			{
				_physicsStates.Remove(item);
			}
		}

		public void Cleanup()
		{
			try
			{
				Rigidbody[] array = Object.FindObjectsOfType<Rigidbody>();
				foreach (Rigidbody val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						int instanceID = ((Object)val).GetInstanceID();
						if (_physicsStates.TryGetValue(instanceID, out var value) && value.OriginalSimulated && !value.IsSimulated)
						{
							val.isKinematic = false;
						}
					}
				}
				_physicsStates.Clear();
				_roomOccupancy.Clear();
				Plugin.Logger.LogInfo((object)"PhysicsCullingModule: Cleaned up");
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("PhysicsCullingModule.Cleanup error: " + ex.Message));
			}
		}

		public void Reset()
		{
			try
			{
				_physicsStates.Clear();
				_roomOccupancy.Clear();
				_cachedRigidbodies.Clear();
				_lastScanTime = 0f;
				if (ModConfig.EnableDebugLogging.Value)
				{
					Plugin.Logger.LogDebug((object)"PhysicsCullingModule reset for new level.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("PhysicsCullingModule.Reset error: " + ex.Message));
			}
		}
	}
	public class RigidbodyModule : IOptimizationModule
	{
		private class RigidbodyState
		{
			public bool IsFrozen;

			public bool WasKinematic;

			public float StationaryTime;

			public float LastAccessTime;
		}

		private readonly Dictionary<int, RigidbodyState> _rigidbodyStates = new Dictionary<int, RigidbodyState>();

		private const float VELOCITY_THRESHOLD = 0.01f;

		private const float ANGULAR_VELOCITY_THRESHOLD = 0.01f;

		private List<Rigidbody> _cachedRigidbodies = new List<Rigidbody>();

		private float _lastScanTime;

		private const float SCAN_INTERVAL = 5f;

		public bool IsEnabled => ModConfig.EnableRigidbodyFreezing?.Value ?? false;

		public void Initialize()
		{
			if (!IsEnabled)
			{
				Plugin.Logger.LogInfo((object)"RigidbodyModule: Disabled in configuration");
			}
			else
			{
				Plugin.Logger.LogInfo((object)"RigidbodyModule: Initialized");
			}
		}

		public void Update()
		{
			if (!IsEnabled || !Plugin.IsServer())
			{
				return;
			}
			try
			{
				float time = Time.time;
				if (time - _lastScanTime >= 5f)
				{
					_lastScanTime = time;
					_cachedRigidbodies.Clear();
					_cachedRigidbodies.AddRange(Object.FindObjectsOfType<Rigidbody>());
				}
				foreach (Rigidbody cachedRigidbody in _cachedRigidbodies)
				{
					if ((Object)(object)cachedRigidbody == (Object)null || (Object)(object)((Component)cachedRigidbody).gameObject == (Object)null || ShouldSkipRigidbody(cachedRigidbody))
					{
						continue;
					}
					int instanceID = ((Object)cachedRigidbody).GetInstanceID();
					if (!_rigidbodyStates.ContainsKey(instanceID))
					{
						_rigidbodyStates[instanceID] = new RigidbodyState();
					}
					RigidbodyState rigidbodyState = _rigidbodyStates[instanceID];
					if (IsBeingInteractedWith(cachedRigidbody))
					{
						UnfreezeRigidbody(cachedRigidbody, rigidbodyState);
					}
					else if (IsStationary(cachedRigidbody))
					{
						rigidbodyState.StationaryTime += Time.deltaTime;
						float num = 2f;
						if (rigidbodyState.StationaryTime >= num && !rigidbodyState.IsFrozen)
						{
							FreezeRigidbody(cachedRigidbody, rigidbodyState);
						}
					}
					else
					{
						rigidbodyState.StationaryTime = 0f;
						if (rigidbodyState.IsFrozen)
						{
							UnfreezeRigidbody(cachedRigidbody, rigidbodyState);
						}
					}
				}
				CleanupDeadEntries();
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("RigidbodyModule.Update error: " + ex.Message));
			}
		}

		private bool IsStationary(Rigidbody rb)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rb == (Object)null)
			{
				return false;
			}
			Vector3 val = rb.velocity;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = rb.angularVelocity;
				return ((Vector3)(ref val)).sqrMagnitude < 0.0001f;
			}
			return false;
		}

		private bool ShouldSkipRigidbody(Rigidbody rb)
		{
			if ((Object)(object)rb == (Object)null || (Object)(object)((Component)rb).gameObject == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)rb).gameObject.GetComponent<PlayerControllerB>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)rb).gameObject.GetComponent<EnemyAI>() != (Object)null)
			{
				return true;
			}
			if (rb.isKinematic)
			{
				return true;
			}
			GrabbableObject component = ((Component)rb).gameObject.GetComponent<GrabbableObject>();
			if ((Object)(object)component != (Object)null && IsFunctionalItem(component))
			{
				return true;
			}
			return false;
		}

		private bool IsFunctionalItem(GrabbableObject item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			string text = item.itemProperties?.itemName?.ToLower() ?? "";
			if (text.Contains("walkie") || text.Contains("radio"))
			{
				return true;
			}
			if (text.Contains("flashlight") || text.Contains("lantern") || text.Contains("pro-flashlight") || text.Contains("laser"))
			{
				return true;
			}
			if (text.Contains("horn") || text.Contains("clown") || text.Contains("airhorn") || text.Contains("air horn"))
			{
				return true;
			}
			if (text.Contains("key") || text.Contains("card"))
			{
				return true;
			}
			if (text.Contains("shovel") || text.Contains("sign") || text.Contains("stop sign") || text.Contains("yield"))
			{
				return true;
			}
			if (text.Contains("jetpack"))
			{
				return true;
			}
			if (text.Contains("spray") || text.Contains("paint"))
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<FlashlightItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<WalkieTalkie>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<NoisemakerProp>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<Shovel>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponent<SprayPaintItem>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)item.itemProperties != (Object)null && item.itemProperties.requiresBattery)
			{
				return true;
			}
			return false;
		}

		private bool IsBeingInteractedWith(Rigidbody rb)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rb == (Object)null || (Object)(object)((Component)rb).gameObject == (Object)null)
			{
				return false;
			}
			GrabbableObject component = ((Component)rb).gameObject.GetComponent<GrabbableObject>();
			if ((Object)(object)component != (Object)null && component.isHeld)
			{
				return true;
			}
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array != null)
			{
				float num = 5f;
				PlayerControllerB[] array2 = array;
				foreach (PlayerControllerB val in array2)
				{
					if (!((Object)(object)val == (Object)null) && !val.isPlayerDead)
					{
						Vector3 val2 = ((Component)val).transform.position - ((Component)rb).transform.position;
						if (((Vector3)(ref val2)).sqrMagnitude < num * num)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		private void FreezeRigidbody(Rigidbody rb, RigidbodyState state)
		{
			if ((Object)(object)rb == (Object)null || state.IsFrozen)
			{
				return;
			}
			try
			{
				state.WasKinematic = rb.isKinematic;
				rb.isKinematic = true;
				state.IsFrozen = true;
				if (ModConfig.EnableDebugLogging.Value)
				{
					Plugin.Logger.LogDebug((object)("Froze rigidbody: " + ((Object)((Component)rb).gameObject).name));
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error freezing rigidbody: " + ex.Message));
			}
		}

		private void UnfreezeRigidbody(Rigidbody rb, RigidbodyState state)
		{
			if ((Object)(object)rb == (Object)null || !state.IsFrozen)
			{
				return;
			}
			try
			{
				rb.isKinematic = state.WasKinematic;
				state.IsFrozen = false;
				state.StationaryTime = 0f;
				if (ModConfig.EnableDebugLogging.Value)
				{
					Plugin.Logger.LogDebug((object)("Unfroze rigidbody: " + ((Object)((Component)rb).gameObject).name));
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error unfreezing rigidbody: " + ex.Message));
			}
		}

		private void CleanupDeadEntries()
		{
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, RigidbodyState> rigidbodyState in _rigidbodyStates)
			{
				if (rigidbodyState.Value.LastAccessTime < Time.time - 60f)
				{
					list.Add(rigidbodyState.Key);
				}
				else
				{
					rigidbodyState.Value.LastAccessTime = Time.time;
				}
			}
			foreach (int item in list)
			{
				_rigidbodyStates.Remove(item);
			}
		}

		public void Cleanup()
		{
			try
			{
				Rigidbody[] array = Object.FindObjectsOfType<Rigidbody>();
				foreach (Rigidbody val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						int instanceID = ((Object)val).GetInstanceID();
						if (_rigidbodyStates.TryGetValue(instanceID, out var value) && value.IsFrozen)
						{
							val.isKinematic = value.WasKinematic;
						}
					}
				}
				_rigidbodyStates.Clear();
				Plugin.Logger.LogInfo((object)"RigidbodyModule: Cleaned up");
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("RigidbodyModule.Cleanup error: " + ex.Message));
			}
		}

		public void Reset()
		{
			try
			{
				_rigidbodyStates.Clear();
				_cachedRigidbodies.Clear();
				_lastScanTime = 0f;
				if (ModConfig.EnableDebugLogging.Value)
				{
					Plugin.Logger.LogDebug((object)"RigidbodyModule reset for new level.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("RigidbodyModule.Reset error: " + ex.Message));
			}
		}
	}
}
namespace LethalBoost.Modules.Interior
{
	public class DoorCullingModule : IOptimizationModule
	{
		private class DoorState
		{
			public Door Door;

			public bool IsClosed;

			public bool WasClosedLastFrame;

			public Tile RoomA;

			public Tile RoomB;

			public List<Renderer> DoorRenderers = new List<Renderer>();
		}

		private bool _isInitialized;

		private Dictionary<Door, DoorState> _doorStates = new Dictionary<Door, DoorState>();

		private List<Door> _allDoors = new List<Door>();

		private float _lastUpdateTime;

		private const float UPDATE_INTERVAL = 0.3f;

		private Dungeon _currentDungeon;

		private HashSet<Door> _subscribedDoors = new HashSet<Door>();

		public bool IsEnabled => ModConfig.EnableDoorCulling?.Value ?? false;

		public void Initialize()
		{
			if (_isInitialized)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"DoorCullingModule already initialized.");
				}
				return;
			}
			try
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"Initializing Door Culling Module...");
				}
				_lastUpdateTime = Time.time;
				_isInitialized = true;
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"Door Culling Module initialized successfully.");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogError((object)$"Failed to initialize Door Culling Module: {arg}");
				}
				throw;
			}
		}

		public void Update()
		{
			if (!IsEnabled || !_isInitialized)
			{
				return;
			}
			try
			{
				float time = Time.time;
				if (time - _lastUpdateTime < 0.3f)
				{
					return;
				}
				_lastUpdateTime = time;
				if ((Object)(object)_currentDungeon == (Object)null)
				{
					FindDungeon();
					if ((Object)(object)_currentDungeon == (Object)null)
					{
						return;
					}
				}
				if (_doorStates.Count == 0)
				{
					BuildDoorList();
				}
				UpdateDoorStates();
				ApplyDoorCulling();
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Error in Door Culling Module Update: {arg}");
				}
			}
		}

		private void FindDungeon()
		{
			try
			{
				RoundManager instance = RoundManager.Instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					RuntimeDungeon dungeonGenerator = instance.dungeonGenerator;
					if (dungeonGenerator == null)
					{
						obj = null;
					}
					else
					{
						DungeonGenerator generator = dungeonGenerator.Generator;
						obj = ((generator != null) ? generator.CurrentDungeon : null);
					}
				}
				if ((Object)obj != (Object)null)
				{
					_currentDungeon = RoundManager.Instance.dungeonGenerator.Generator.CurrentDungeon;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"Door Culling: Found dungeon with {_currentDungeon.Doors.Count} doors.");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error finding dungeon: {arg}");
				}
			}
		}

		private void BuildDoorList()
		{
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			if ((Object)(object)_currentDungeon == (Object)null)
			{
				return;
			}
			try
			{
				_doorStates.Clear();
				_allDoors.Clear();
				foreach (GameObject door in _currentDungeon.Doors)
				{
					if ((Object)(object)door == (Object)null)
					{
						continue;
					}
					Door component = door.GetComponent<Door>();
					if ((Object)(object)component == (Object)null)
					{
						continue;
					}
					DoorState doorState = new DoorState
					{
						Door = component,
						IsClosed = !component.IsOpen,
						WasClosedLastFrame = !component.IsOpen
					};
					Doorway doorwayA = component.DoorwayA;
					if ((Object)(object)((doorwayA != null) ? doorwayA.Tile : null) != (Object)null)
					{
						doorState.RoomA = component.DoorwayA.Tile;
					}
					Doorway doorwayB = component.DoorwayB;
					if ((Object)(object)((doorwayB != null) ? doorwayB.Tile : null) != (Object)null)
					{
						doorState.RoomB = component.DoorwayB.Tile;
					}
					Renderer[] componentsInChildren = ((Component)component).GetComponentsInChildren<Renderer>();
					foreach (Renderer val in componentsInChildren)
					{
						if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy)
						{
							doorState.DoorRenderers.Add(val);
						}
					}
					_doorStates[component] = doorState;
					_allDoors.Add(component);
					if (!_subscribedDoors.Contains(component))
					{
						component.OnDoorStateChanged += new DoorStateChangedDelegate(OnDoorStateChanged);
						_subscribedDoors.Add(component);
					}
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Built door list with {_doorStates.Count} doors.");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error building door list: {arg}");
				}
			}
		}

		private void OnDoorStateChanged(Door door, bool isOpen)
		{
			if (!_doorStates.TryGetValue(door, out var value))
			{
				return;
			}
			value.IsClosed = !isOpen;
			if (ModConfig.EnableDebugLogging.Value)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)("Door state changed: " + (isOpen ? "Opened" : "Closed")));
				}
			}
		}

		private void UpdateDoorStates()
		{
			try
			{
				_allDoors.RemoveAll((Door d) => (Object)(object)d == (Object)null);
				foreach (Door allDoor in _allDoors)
				{
					if (!((Object)(object)allDoor == (Object)null) && _doorStates.ContainsKey(allDoor))
					{
						DoorState doorState = _doorStates[allDoor];
						doorState.WasClosedLastFrame = doorState.IsClosed;
						doorState.IsClosed = !allDoor.IsOpen;
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Error updating door states: {arg}");
				}
			}
		}

		private void ApplyDoorCulling()
		{
			if (!ModConfig.EnableDoorCulling.Value)
			{
				return;
			}
			try
			{
				foreach (KeyValuePair<Door, DoorState> doorState in _doorStates)
				{
					Door key = doorState.Key;
					DoorState value = doorState.Value;
					if ((Object)(object)key == (Object)null)
					{
						continue;
					}
					bool enabled = ShouldRenderDoor(value);
					foreach (Renderer doorRenderer in value.DoorRenderers)
					{
						if ((Object)(object)doorRenderer != (Object)null)
						{
							doorRenderer.enabled = enabled;
						}
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Error applying door culling: {arg}");
				}
			}
		}

		private bool ShouldRenderDoor(DoorState state)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array != null)
			{
				PlayerControllerB[] array2 = array;
				foreach (PlayerControllerB val in array2)
				{
					if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && val.isInsideFactory)
					{
						Vector3 val2 = ((Component)val).transform.position - ((Component)state.Door).transform.position;
						float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
						float num = 30f;
						if (sqrMagnitude < num * num)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		public bool IsDoorClosed(Door door)
		{
			if (_doorStates.TryGetValue(door, out var value))
			{
				return value.IsClosed;
			}
			return false;
		}

		public int GetClosedDoorCount()
		{
			int num = 0;
			foreach (DoorState value in _doorStates.Values)
			{
				if (value.IsClosed)
				{
					num++;
				}
			}
			return num;
		}

		public void Cleanup()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			try
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Cleaning up Door Culling Module...");
				}
				foreach (Door allDoor in _allDoors)
				{
					if ((Object)(object)allDoor != (Object)null && _subscribedDoors.Contains(allDoor))
					{
						allDoor.OnDoorStateChanged -= new DoorStateChangedDelegate(OnDoorStateChanged);
					}
				}