using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalOptimizer.Config;
using LethalOptimizer.Core;
using LethalOptimizer.Patches;
using LethalOptimizer.Patches.AI;
using LethalOptimizer.Patches.Traps;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace LethalOptimizer
{
[BepInPlugin("com.lethal.optimizer", "LethalOptimizer", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
private Harmony _harmony;
public static Plugin Instance { get; private set; }
public static ManualLogSource Log { get; private set; }
private void Awake()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
PluginConfig.Initialize(((BaseUnityPlugin)this).Config);
if (!PluginConfig.EnableAllOptimizations.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalOptimizer is disabled via config");
return;
}
_harmony = new Harmony("com.lethal.optimizer");
_harmony.PatchAll(typeof(EnemyAIPatches));
_harmony.PatchAll(typeof(RoundManagerPatches));
_harmony.PatchAll(typeof(GrabbableObjectPatches));
_harmony.PatchAll(typeof(HUDManagerPatches));
_harmony.PatchAll(typeof(PlayerPatches));
_harmony.PatchAll(typeof(JesterPatches));
_harmony.PatchAll(typeof(CrawlerPatches));
_harmony.PatchAll(typeof(SpringManPatches));
_harmony.PatchAll(typeof(BaboonPatches));
_harmony.PatchAll(typeof(FlowermanPatches));
_harmony.PatchAll(typeof(GhostGirlPatches));
_harmony.PatchAll(typeof(HoarderBugPatches));
_harmony.PatchAll(typeof(SporeLizardPatches));
_harmony.PatchAll(typeof(ForestGiantPatches));
_harmony.PatchAll(typeof(NutcrackerPatches));
_harmony.PatchAll(typeof(MouthDogPatches));
_harmony.PatchAll(typeof(SandSpiderPatches));
_harmony.PatchAll(typeof(MaskedPatches));
_harmony.PatchAll(typeof(BlobPatches));
_harmony.PatchAll(typeof(RadMechPatches));
_harmony.PatchAll(typeof(ButlerPatches));
_harmony.PatchAll(typeof(FlowerSnakePatches));
_harmony.PatchAll(typeof(CaveDwellerPatches));
_harmony.PatchAll(typeof(TurretPatches));
_harmony.PatchAll(typeof(LandminePatches));
_harmony.PatchAll(typeof(SpikeRoofTrapPatches));
_harmony.PatchAll(typeof(TimeOfDayPatches));
ObjectPool.Initialize();
AINodeCache.Initialize();
Benchmark.Initialize();
GraphicsOptimizer.Initialize();
ShipOptimizer.Initialize();
((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalOptimizer v1.2.0 [BETA] loaded!");
((BaseUnityPlugin)this).Logger.LogInfo((object)"18 AI optimizations + 3 trap optimizations + TimeOfDay optimizer active");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Graphics quality auto-adjusts when on ship");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Press F8 for performance overlay, F9 to run benchmark");
}
private void Update()
{
if (PluginConfig.EnableLogging.Value)
{
PerformanceMonitor.LogMetrics();
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
ObjectPool.Cleanup();
ComponentCache.Clear();
NetworkThrottle.Clear();
PerformanceMonitor.Clear();
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.lethal.optimizer";
public const string PLUGIN_NAME = "LethalOptimizer";
public const string PLUGIN_VERSION = "1.2.0";
}
}
namespace LethalOptimizer.Patches
{
[HarmonyPatch]
public static class AudioPatches
{
private static readonly Dictionary<int, float> _lastPlayTimes = new Dictionary<int, float>();
private const float MIN_AUDIO_INTERVAL = 0.05f;
[HarmonyPatch(typeof(RoundManager), "PlayAudibleNoise")]
[HarmonyPrefix]
public static bool PlayAudibleNoise_Prefix(Vector3 noisePosition, float noiseRange, float noiseLoudness)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
if (noiseLoudness < 0.05f)
{
return false;
}
PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
if (array == null)
{
return true;
}
bool result = false;
float num = noiseRange * noiseRange;
for (int i = 0; i < array.Length; i++)
{
if (array[i].isPlayerControlled && !array[i].isPlayerDead)
{
Vector3 val = ((Component)array[i]).transform.position - noisePosition;
if (((Vector3)(ref val)).sqrMagnitude < num)
{
result = true;
break;
}
}
}
return result;
}
[HarmonyPatch(typeof(WalkieTalkie), "TransmitOneShotAudio")]
[HarmonyPrefix]
public static bool TransmitAudio_Prefix(AudioSource audioSource, AudioClip clip)
{
if ((Object)(object)audioSource == (Object)null || (Object)(object)clip == (Object)null)
{
return false;
}
int instanceID = ((Object)audioSource).GetInstanceID();
float valueOrDefault = _lastPlayTimes.GetValueOrDefault(instanceID, 0f);
if (Time.time - valueOrDefault < 0.05f)
{
return false;
}
_lastPlayTimes[instanceID] = Time.time;
return true;
}
public static void ClearCache()
{
_lastPlayTimes.Clear();
}
}
[HarmonyPatch(typeof(EnemyAI))]
public static class EnemyAIPatches
{
[HarmonyPatch("SetEnemyOutside")]
[HarmonyPrefix]
public static bool SetEnemyOutside_Prefix(EnemyAI __instance, bool outside)
{
__instance.isOutside = outside;
GameObject[] nodes = AINodeCache.GetNodes(outside);
if (nodes != null && nodes.Length != 0)
{
__instance.allAINodes = nodes;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(GrabbableObject))]
public static class GrabbableObjectPatches
{
private static readonly Collider[] _groundCheckResults = (Collider[])(object)new Collider[10];
private static readonly Dictionary<int, Transform> _parentCache = new Dictionary<int, Transform>();
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(GrabbableObject __instance)
{
if (__instance.isHeld && (Object)(object)__instance.playerHeldBy != (Object)null)
{
return false;
}
if (__instance.isInShipRoom && !__instance.isHeld && Time.frameCount % 3 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("FallToGround")]
[HarmonyPrefix]
public static bool FallToGround_Prefix(GrabbableObject __instance, bool randomizePosition)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (__instance.targetFloorPosition == Vector3.zero)
{
Physics.OverlapSphereNonAlloc(((Component)__instance).transform.position, 2f, _groundCheckResults, LayerMask.GetMask(new string[2] { "Room", "Default" }), (QueryTriggerInteraction)1);
_ = 0;
return true;
}
return true;
}
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(GrabbableObject __instance)
{
if (!((Component)__instance).gameObject.activeInHierarchy)
{
return false;
}
if (!__instance.isHeld && Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(HUDManager))]
public static class HUDManagerPatches
{
private static float _tipUpdateTimer;
private static float _clockUpdateTimer;
private static string _lastTipText;
private const float TIP_UPDATE_INTERVAL = 0.1f;
private const float CLOCK_UPDATE_INTERVAL = 1f;
[HarmonyPatch("DisplayTip")]
[HarmonyPrefix]
public static bool DisplayTip_Prefix(string headerText, string bodyText)
{
string text = headerText + ":" + bodyText;
if (text == _lastTipText && _tipUpdateTimer > 0f)
{
return false;
}
_lastTipText = text;
_tipUpdateTimer = 0.1f;
return true;
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void Update_Postfix()
{
if (_tipUpdateTimer > 0f)
{
_tipUpdateTimer -= Time.deltaTime;
}
}
[HarmonyPatch("SetClock")]
[HarmonyPrefix]
public static bool SetClock_Prefix(float timeNormalized, float numberOfHours)
{
_clockUpdateTimer -= Time.deltaTime;
if (_clockUpdateTimer > 0f)
{
return false;
}
_clockUpdateTimer = 1f;
return true;
}
}
[HarmonyPatch]
public static class PhysicsPatches
{
private static readonly RaycastHit[] _raycastHits = (RaycastHit[])(object)new RaycastHit[20];
private static readonly Collider[] _overlapResults = (Collider[])(object)new Collider[30];
public static int OverlapSphereNonAlloc(Vector3 position, float radius, int layerMask)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return Physics.OverlapSphereNonAlloc(position, radius, _overlapResults, layerMask);
}
public static Collider[] GetOverlapResults()
{
return _overlapResults;
}
public static int RaycastNonAlloc(Vector3 origin, Vector3 direction, float maxDistance, int layerMask)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return Physics.RaycastNonAlloc(origin, direction, _raycastHits, maxDistance, layerMask);
}
public static RaycastHit[] GetRaycastResults()
{
return _raycastHits;
}
public static bool IsWithinDistance(Vector3 a, Vector3 b, float distance)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = a - b;
return ((Vector3)(ref val)).sqrMagnitude <= distance * distance;
}
public static void ClearResults()
{
Array.Clear(_raycastHits, 0, _raycastHits.Length);
Array.Clear(_overlapResults, 0, _overlapResults.Length);
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
public static class PlayerPatches
{
private static readonly Dictionary<int, Vector3> _lastPositions = new Dictionary<int, Vector3>();
private static readonly Dictionary<int, float> _syncTimers = new Dictionary<int, float>();
private const float POSITION_SYNC_INTERVAL = 0.05f;
private const float POSITION_THRESHOLD = 0.01f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(PlayerControllerB __instance)
{
if (__instance.isPlayerDead && !__instance.isPlayerControlled)
{
return false;
}
return true;
}
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(PlayerControllerB __instance)
{
if (!__instance.isPlayerControlled)
{
return false;
}
return true;
}
[HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")]
[HarmonyPrefix]
public static bool SetHoverTip_Prefix(PlayerControllerB __instance)
{
if (Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("PlayerLookInput")]
[HarmonyPrefix]
public static bool PlayerLookInput_Prefix(PlayerControllerB __instance)
{
if ((Object)(object)__instance.quickMenuManager != (Object)null && __instance.quickMenuManager.isMenuOpen)
{
return false;
}
return true;
}
public static bool ShouldSyncPosition(PlayerControllerB player)
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
int instanceID = ((Object)player).GetInstanceID();
if (!_syncTimers.ContainsKey(instanceID))
{
_syncTimers[instanceID] = 0f;
}
_syncTimers[instanceID] -= Time.deltaTime;
if (_syncTimers[instanceID] > 0f)
{
return false;
}
_syncTimers[instanceID] = 0.05f;
if (!_lastPositions.ContainsKey(instanceID))
{
_lastPositions[instanceID] = ((Component)player).transform.position;
return true;
}
if (Vector3.Distance(((Component)player).transform.position, _lastPositions[instanceID]) < 0.01f)
{
return false;
}
_lastPositions[instanceID] = ((Component)player).transform.position;
return true;
}
public static void ClearCache()
{
_lastPositions.Clear();
_syncTimers.Clear();
}
}
[HarmonyPatch(typeof(RoundManager))]
public static class RoundManagerPatches
{
private static float _spawnCheckTimer;
private const float SPAWN_CHECK_INTERVAL = 0.5f;
[HarmonyPatch("LoadNewLevel")]
[HarmonyPostfix]
public static void LoadNewLevel_Postfix()
{
AINodeCache.CacheNodes();
TurretPatches.ResetTimers();
LandminePatches.ResetCache();
SpikeRoofTrapPatches.ResetCache();
Plugin.Log.LogDebug((object)"Level loaded - AI nodes and trap caches reset");
}
[HarmonyPatch("SpawnEnemyGameObject")]
[HarmonyPrefix]
public static void SpawnEnemy_Prefix(RoundManager __instance)
{
if (AINodeCache.InsideNodes == null)
{
AINodeCache.CacheNodes();
}
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(RoundManager __instance)
{
_spawnCheckTimer -= Time.deltaTime;
if (_spawnCheckTimer > 0f)
{
return true;
}
_spawnCheckTimer = 0.5f;
return true;
}
[HarmonyPatch("RefreshEnemiesList")]
[HarmonyPrefix]
public static bool RefreshEnemiesList_Prefix(RoundManager __instance)
{
List<EnemyAI> spawnedEnemies = __instance.SpawnedEnemies;
if (spawnedEnemies != null)
{
_ = spawnedEnemies.Count;
_ = 0;
return true;
}
return true;
}
}
[HarmonyPatch(typeof(TimeOfDay))]
public static class TimeOfDayPatches
{
private static float _lightingUpdateTimer;
private const float LIGHTING_UPDATE_INTERVAL = 0.1f;
[HarmonyPatch("SetInsideLightingDimness")]
[HarmonyPrefix]
public static bool SetInsideLightingDimness_Prefix(TimeOfDay __instance, bool doNotLerp)
{
if (!PluginConfig.EnableUIOptimizations.Value)
{
return true;
}
if (doNotLerp)
{
return true;
}
_lightingUpdateTimer += Time.deltaTime;
if (_lightingUpdateTimer < 0.1f)
{
return false;
}
_lightingUpdateTimer = 0f;
return true;
}
[HarmonyPatch("MoveTimeOfDay")]
[HarmonyPrefix]
public static bool MoveTimeOfDay_Prefix(TimeOfDay __instance)
{
if (!PluginConfig.EnableUIOptimizations.Value)
{
return true;
}
if (!__instance.currentDayTimeStarted)
{
return false;
}
return true;
}
}
}
namespace LethalOptimizer.Patches.Traps
{
[HarmonyPatch(typeof(Landmine))]
public static class LandminePatches
{
private static RoundManager _cachedRoundManager;
private static bool _roundManagerCached;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(Landmine __instance, ref float ___pressMineDebounceTimer, bool ___localPlayerOnMine)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (__instance.hasExploded)
{
return false;
}
if (___pressMineDebounceTimer > 0f)
{
___pressMineDebounceTimer -= Time.deltaTime;
}
if (___localPlayerOnMine)
{
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)val != (Object)null && val.teleportedLastFrame)
{
return true;
}
}
return false;
}
[HarmonyPatch("StartIdleAnimation")]
[HarmonyPrefix]
public static void StartIdleAnimation_Prefix(Landmine __instance, ref RoundManager ___roundManager)
{
if (PluginConfig.EnableTrapOptimizations.Value)
{
if (!_roundManagerCached)
{
_cachedRoundManager = RoundManager.Instance;
_roundManagerCached = true;
}
___roundManager = _cachedRoundManager;
}
}
[HarmonyPatch("OnTriggerEnter")]
[HarmonyPrefix]
public static bool OnTriggerEnter_Prefix(Landmine __instance, Collider other, bool ___hasExploded, float ___pressMineDebounceTimer)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (___hasExploded || ___pressMineDebounceTimer > 0f)
{
return false;
}
string tag = ((Component)other).tag;
if (tag != "Player" && tag != "PhysicsProp" && !tag.StartsWith("PlayerRagdoll"))
{
return false;
}
return true;
}
[HarmonyPatch("OnTriggerExit")]
[HarmonyPrefix]
public static bool OnTriggerExit_Prefix(Landmine __instance, bool ___hasExploded, bool ___mineActivated)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (___hasExploded || !___mineActivated)
{
return false;
}
return true;
}
public static void ResetCache()
{
_cachedRoundManager = null;
_roundManagerCached = false;
}
}
[HarmonyPatch(typeof(SpikeRoofTrap))]
public static class SpikeRoofTrapPatches
{
private const float UPDATE_INTERVAL = 0.1f;
private static float _updateTimer;
private static EntranceTeleport[] _cachedEntrances;
private static bool _entrancesCached;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(SpikeRoofTrap __instance, bool ___trapActive, bool ___slammingDown, bool ___slamOnIntervals, float ___slamInterval, ref float ___timeSinceMovingUp, EntranceTeleport ___nearEntrance, Transform ___laserEye, ref RaycastHit ___hit)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (!___trapActive || ___slammingDown)
{
return false;
}
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.1f)
{
return false;
}
_updateTimer = 0f;
if ((Object)(object)___nearEntrance != (Object)null && Time.realtimeSinceStartup - ___nearEntrance.timeAtLastUse < 1.2f)
{
___timeSinceMovingUp = Time.realtimeSinceStartup;
return false;
}
if (___slamOnIntervals)
{
return true;
}
if (Time.realtimeSinceStartup - ___timeSinceMovingUp < 1.2f)
{
return false;
}
return true;
}
[HarmonyPatch("OnTriggerStay")]
[HarmonyPrefix]
public static bool OnTriggerStay_Prefix(SpikeRoofTrap __instance, Collider other, bool ___trapActive, bool ___slammingDown, float ___timeSinceMovingUp)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (!___trapActive || !___slammingDown)
{
return false;
}
if (Time.realtimeSinceStartup - ___timeSinceMovingUp < 0.75f)
{
return false;
}
int layer = ((Component)other).gameObject.layer;
if (layer != 3 && layer != 19 && layer != 6)
{
return false;
}
return true;
}
[HarmonyPatch("GetNearEntrance")]
[HarmonyPrefix]
public static bool GetNearEntrance_Prefix(SpikeRoofTrap __instance, ref bool __result, ref EntranceTeleport ___nearEntrance, AudioSource ___spikeTrapAudio)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (!_entrancesCached)
{
_cachedEntrances = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0);
_entrancesCached = true;
}
if (_cachedEntrances == null || _cachedEntrances.Length == 0)
{
__result = false;
return false;
}
Vector3 position = ((Component)___spikeTrapAudio).transform.position;
EntranceTeleport val = null;
for (int i = 0; i < _cachedEntrances.Length; i++)
{
EntranceTeleport val2 = _cachedEntrances[i];
if (!((Object)(object)val2 == (Object)null) && !val2.isEntranceToBuilding)
{
Vector3 val3 = position - val2.entrancePoint.position;
if (((Vector3)(ref val3)).sqrMagnitude < 49f)
{
val = val2;
break;
}
}
}
if ((Object)(object)val == (Object)null)
{
__result = false;
return false;
}
for (int j = 0; j < _cachedEntrances.Length; j++)
{
EntranceTeleport val4 = _cachedEntrances[j];
if ((Object)(object)val4 != (Object)null && (Object)(object)val4.entrancePoint == (Object)(object)val.exitPoint)
{
___nearEntrance = val4;
__result = true;
return false;
}
}
__result = false;
return false;
}
public static void ResetCache()
{
_cachedEntrances = null;
_entrancesCached = false;
_updateTimer = 0f;
}
}
[HarmonyPatch(typeof(Turret))]
public static class TurretPatches
{
private const float DETECTION_INTERVAL = 0.3f;
private const float FIRING_INTERVAL = 0.25f;
private const float ROTATION_SWITCH_INTERVAL = 8f;
private static float _detectionTimer;
private static float _losCheckTimer;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(Turret __instance, ref float ___turretInterval, ref float ___switchRotationTimer, bool ___turretActive, TurretMode ___turretMode)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if (!___turretActive)
{
return true;
}
if ((int)___turretMode == 0)
{
_detectionTimer += Time.deltaTime;
if (_detectionTimer < 0.3f)
{
return true;
}
_detectionTimer = 0f;
}
return true;
}
[HarmonyPatch("CheckForPlayersInLineOfSight")]
[HarmonyPrefix]
public static bool CheckForPlayersInLOS_Prefix(Turret __instance, ref PlayerControllerB __result, float radius, bool angleRangeCheck)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
_losCheckTimer += Time.deltaTime;
if (_losCheckTimer < PluginConfig.LOSCheckInterval.Value)
{
__result = null;
return false;
}
_losCheckTimer = 0f;
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)val == (Object)null || val.isPlayerDead)
{
__result = null;
return false;
}
Vector3 val2 = ((Component)val).transform.position - __instance.centerPoint.position;
if (((Vector3)(ref val2)).sqrMagnitude > 900f)
{
__result = null;
return false;
}
return true;
}
[HarmonyPatch("TurnTowardsTargetIfHasLOS")]
[HarmonyPrefix]
public static bool TurnTowardsTarget_Prefix(Turret __instance, PlayerControllerB ___targetPlayerWithRotation, bool ___targetingDeadPlayer)
{
if (!PluginConfig.EnableTrapOptimizations.Value)
{
return true;
}
if ((Object)(object)___targetPlayerWithRotation == (Object)null)
{
return false;
}
if (___targetingDeadPlayer && (Object)(object)___targetPlayerWithRotation.deadBody == (Object)null)
{
return false;
}
return true;
}
[HarmonyPatch("SwitchRotationOnInterval")]
[HarmonyPrefix]
public static void SwitchRotation_Prefix(ref float ___switchRotationTimer)
{
if (PluginConfig.EnableTrapOptimizations.Value)
{
___switchRotationTimer = 0f;
}
}
public static void ResetTimers()
{
_detectionTimer = 0f;
_losCheckTimer = 0f;
}
}
}
namespace LethalOptimizer.Patches.Ship
{
[HarmonyPatch(typeof(AutoParentToShip))]
public static class AutoParentToShipPatches
{
private static readonly Dictionary<int, Vector3> _lastPositions = new Dictionary<int, Vector3>();
private static readonly Dictionary<int, Quaternion> _lastRotations = new Dictionary<int, Quaternion>();
private static float _updateTimer;
private const float UPDATE_INTERVAL = 0.1f;
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(AutoParentToShip __instance)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (StartOfRound.Instance.suckingFurnitureOutOfShip)
{
return true;
}
if (__instance.disableObject)
{
((Component)__instance).transform.position = new Vector3(800f, -100f, 0f);
return false;
}
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.1f)
{
return false;
}
_updateTimer = 0f;
int instanceID = ((Object)__instance).GetInstanceID();
Vector3 position = StartOfRound.Instance.elevatorTransform.position;
Quaternion rotation = StartOfRound.Instance.elevatorTransform.rotation;
if (_lastPositions.TryGetValue(instanceID, out var value) && _lastRotations.TryGetValue(instanceID, out var value2) && Vector3.Distance(position, value) < 0.001f && Quaternion.Angle(rotation, value2) < 0.1f)
{
return false;
}
_lastPositions[instanceID] = position;
_lastRotations[instanceID] = rotation;
return true;
}
public static void ClearCache()
{
_lastPositions.Clear();
_lastRotations.Clear();
}
}
[HarmonyPatch(typeof(InteractTrigger))]
public static class InteractTriggerPatches
{
private static readonly Dictionary<int, float> _cooldownTimers = new Dictionary<int, float>();
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(InteractTrigger __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (!__instance.isPlayingSpecialAnimation && !__instance.usingLadder && Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("StopInteraction")]
[HarmonyPrefix]
public static bool StopInteraction_Prefix(InteractTrigger __instance)
{
if (!__instance.isBeingHeldByPlayer)
{
return false;
}
return true;
}
public static void ClearCache()
{
_cooldownTimers.Clear();
}
}
[HarmonyPatch(typeof(ManualCameraRenderer))]
public static class ManualCameraRendererPatches
{
private static float _renderTimer;
private static float _targetFps = 15f;
private static float _renderInterval;
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void Start_Postfix(ManualCameraRenderer __instance)
{
__instance.renderAtLowerFramerate = true;
__instance.fps = _targetFps;
_renderInterval = 1f / _targetFps;
Plugin.Log.LogDebug((object)$"Radar camera set to {_targetFps} FPS");
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(ManualCameraRenderer __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (__instance.currentCameraDisabled)
{
return false;
}
_renderTimer += Time.deltaTime;
if (_renderTimer < _renderInterval)
{
if ((Object)(object)__instance.cam != (Object)null)
{
((Behaviour)__instance.cam).enabled = false;
}
return false;
}
_renderTimer = 0f;
if ((Object)(object)__instance.cam != (Object)null)
{
((Behaviour)__instance.cam).enabled = true;
}
return true;
}
[HarmonyPatch("MapCameraFocusOnPosition")]
[HarmonyPrefix]
public static bool MapCameraFocus_Prefix(ManualCameraRenderer __instance)
{
if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(OccludeAudio))]
public static class OccludeAudioPatches
{
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(OccludeAudio __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(SoundManager))]
public static class SoundManagerPatches
{
private static float _updateTimer;
private const float UPDATE_INTERVAL = 0.05f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(SoundManager __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.05f)
{
return false;
}
_updateTimer = 0f;
return true;
}
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(SoundManager __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(StartOfRound))]
public static class StartOfRoundPatches
{
private static float _updateTimer;
private const float UPDATE_INTERVAL = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(StartOfRound __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (__instance.inShipPhase)
{
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.2f)
{
return true;
}
_updateTimer = 0f;
}
return true;
}
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(StartOfRound __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if (__instance.inShipPhase && Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Terminal))]
public static class TerminalPatches
{
private static float _updateTimer;
private const float UPDATE_INTERVAL = 0.1f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(Terminal __instance)
{
if (!PluginConfig.EnableAllOptimizations.Value)
{
return true;
}
if ((Object)(object)HUDManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
{
return false;
}
if (!__instance.terminalInUse)
{
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.1f)
{
return false;
}
_updateTimer = 0f;
}
return true;
}
[HarmonyPatch("TextPostProcess")]
[HarmonyPrefix]
public static void TextPostProcess_Prefix(Terminal __instance)
{
}
}
}
namespace LethalOptimizer.Patches.AI
{
[HarmonyPatch(typeof(BaboonBirdAI))]
public static class BaboonPatches
{
private static float _threatCheckTimer;
private static float _scoutTimer;
private const float THREAT_CHECK_INTERVAL = 0.3f;
private const float SCOUT_INTERVAL = 0.5f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(BaboonBirdAI __instance)
{
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(BaboonBirdAI __instance)
{
_threatCheckTimer -= Time.deltaTime;
if (_threatCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
return false;
}
_threatCheckTimer = 0.3f;
return true;
}
[HarmonyPatch("DoLOSCheck")]
[HarmonyPrefix]
public static bool DoLOSCheck_Prefix(BaboonBirdAI __instance)
{
_scoutTimer -= Time.deltaTime;
if (_scoutTimer > 0f)
{
return false;
}
_scoutTimer = 0.5f;
return true;
}
[HarmonyPatch("CalculateThreatLevelOfPosition")]
[HarmonyPrefix]
public static bool CalculateThreat_Prefix(BaboonBirdAI __instance)
{
if (__instance.focusedThreat == null && (Object)(object)__instance.focusedThreatTransform == (Object)null)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(BlobAI))]
public static class BlobPatches
{
private static float _moveTimer;
private const float MOVE_CHECK_INTERVAL = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(BlobAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(BlobAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
_moveTimer -= Time.deltaTime;
if (_moveTimer > 0f)
{
return false;
}
_moveTimer = 0.2f;
return true;
}
}
[HarmonyPatch(typeof(ButlerEnemyAI))]
public static class ButlerPatches
{
private static float _aiIntervalTimer;
private const float AI_INTERVAL_THROTTLE = 0.15f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(ButlerEnemyAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(ButlerEnemyAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_aiIntervalTimer += Time.deltaTime;
if (_aiIntervalTimer < 0.15f)
{
return false;
}
_aiIntervalTimer = 0f;
}
return true;
}
}
[HarmonyPatch(typeof(CaveDwellerAI))]
public static class CaveDwellerPatches
{
private static float _updateTimer;
private const float UPDATE_THROTTLE = 0.1f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(CaveDwellerAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.1f)
{
return false;
}
_updateTimer = 0f;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(CaveDwellerAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(CrawlerAI))]
public static class CrawlerPatches
{
private static float _aiIntervalTimer;
private const float AI_INTERVAL_THROTTLE = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(CrawlerAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(CrawlerAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_aiIntervalTimer += Time.deltaTime;
if (_aiIntervalTimer < 0.2f)
{
return false;
}
_aiIntervalTimer = 0f;
}
return true;
}
[HarmonyPatch("MakeScreech")]
[HarmonyPrefix]
public static bool MakeScreech_Prefix(CrawlerAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(FlowermanAI))]
public static class FlowermanPatches
{
private static float _angerCheckTimer;
private const float ANGER_CHECK_INTERVAL = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(FlowermanAI __instance)
{
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(FlowermanAI __instance)
{
_angerCheckTimer -= Time.deltaTime;
if (_angerCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
return false;
}
_angerCheckTimer = 0.2f;
return true;
}
[HarmonyPatch("LookAtPlayerOfInterest")]
[HarmonyPrefix]
public static bool LookAtPlayer_Prefix(FlowermanAI __instance)
{
if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
{
return false;
}
if (Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(FlowerSnakeEnemy))]
public static class FlowerSnakePatches
{
private static float _updateTimer;
private const float UPDATE_THROTTLE = 0.1f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(FlowerSnakeEnemy __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (!Object.op_Implicit((Object)(object)__instance.clingingToPlayer))
{
_updateTimer += Time.deltaTime;
if (_updateTimer < 0.1f)
{
return false;
}
_updateTimer = 0f;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(FlowerSnakeEnemy __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ForestGiantAI))]
public static class ForestGiantPatches
{
private static float _searchTimer;
private static float _losTimer;
private const float SEARCH_INTERVAL = 0.4f;
private const float LOS_INTERVAL = 0.15f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(ForestGiantAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(ForestGiantAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_searchTimer -= Time.deltaTime;
if (_searchTimer > 0f)
{
return false;
}
_searchTimer = 0.4f;
}
return true;
}
[HarmonyPatch("LookForPlayers")]
[HarmonyPrefix]
public static bool LookForPlayers_Prefix(ForestGiantAI __instance)
{
_losTimer -= Time.deltaTime;
if (_losTimer > 0f)
{
return false;
}
_losTimer = 0.15f;
return true;
}
}
[HarmonyPatch(typeof(DressGirlAI))]
public static class GhostGirlPatches
{
private static float _hauntCheckTimer;
private static float _visibilityTimer;
private const float HAUNT_CHECK_INTERVAL = 0.5f;
private const float VISIBILITY_CHECK_INTERVAL = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(DressGirlAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (!Object.op_Implicit((Object)(object)__instance.hauntingPlayer) && Time.frameCount % 3 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(DressGirlAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if ((Object)(object)__instance.hauntingPlayer == (Object)null)
{
_hauntCheckTimer -= Time.deltaTime;
if (_hauntCheckTimer > 0f)
{
return false;
}
_hauntCheckTimer = 0.5f;
}
return true;
}
[HarmonyPatch("CheckVisibility")]
[HarmonyPrefix]
public static bool CheckVisibility_Prefix(DressGirlAI __instance)
{
_visibilityTimer -= Time.deltaTime;
if (_visibilityTimer > 0f)
{
return false;
}
_visibilityTimer = 0.2f;
return true;
}
}
[HarmonyPatch(typeof(HoarderBugAI))]
public static class HoarderBugPatches
{
private static float _itemSearchTimer;
private static float _nestCheckTimer;
private const float ITEM_SEARCH_INTERVAL = 0.3f;
private const float NEST_CHECK_INTERVAL = 0.5f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(HoarderBugAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (__instance.heldItem != null && ((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(HoarderBugAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (__instance.heldItem == null)
{
_itemSearchTimer -= Time.deltaTime;
if (_itemSearchTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
return false;
}
_itemSearchTimer = 0.3f;
}
return true;
}
[HarmonyPatch("RefreshGrabbableObjectsInMapList")]
[HarmonyPrefix]
public static bool RefreshObjects_Prefix(HoarderBugAI __instance)
{
_nestCheckTimer -= Time.deltaTime;
if (_nestCheckTimer > 0f)
{
return false;
}
_nestCheckTimer = 0.5f;
return true;
}
}
[HarmonyPatch(typeof(JesterAI))]
public static class JesterPatches
{
private static float _popUpTimer;
private const float POP_CHECK_INTERVAL = 0.25f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(JesterAI __instance)
{
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 4 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(JesterAI __instance)
{
if (((EnemyAI)__instance).currentBehaviourStateIndex == 1)
{
_popUpTimer -= Time.deltaTime;
if (_popUpTimer > 0f)
{
return false;
}
_popUpTimer = 0.25f;
}
return true;
}
}
[HarmonyPatch(typeof(MaskedPlayerEnemy))]
public static class MaskedPatches
{
private static float _mimicTimer;
private const float MIMIC_CHECK_INTERVAL = 0.3f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(MaskedPlayerEnemy __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(MaskedPlayerEnemy __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_mimicTimer -= Time.deltaTime;
if (_mimicTimer > 0f)
{
return false;
}
_mimicTimer = 0.3f;
}
return true;
}
[HarmonyPatch("LookAtPlayerServerRpc")]
[HarmonyPrefix]
public static bool LookAtPlayer_Prefix(MaskedPlayerEnemy __instance)
{
if (!NetworkThrottle.CanSendForObject("animation", ((Object)__instance).GetInstanceID()))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(MouthDogAI))]
public static class MouthDogPatches
{
private static float _noiseCheckTimer;
private static float _suspicionTimer;
private const float NOISE_CHECK_INTERVAL = 0.1f;
private const float SUSPICION_CHECK_INTERVAL = 0.25f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(MouthDogAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(MouthDogAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 2 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DetectNoise")]
[HarmonyPrefix]
public static bool DetectNoise_Prefix(MouthDogAI __instance, Vector3 noisePosition, float noiseLoudness)
{
_noiseCheckTimer -= Time.deltaTime;
if (_noiseCheckTimer > 0f)
{
return false;
}
_noiseCheckTimer = 0.1f;
if (noiseLoudness < 0.1f)
{
return false;
}
return true;
}
[HarmonyPatch("CheckForPlayersInLineOfSight")]
[HarmonyPrefix]
public static bool CheckPlayers_Prefix(MouthDogAI __instance)
{
_suspicionTimer -= Time.deltaTime;
if (_suspicionTimer > 0f)
{
return false;
}
_suspicionTimer = 0.25f;
return true;
}
}
[HarmonyPatch(typeof(NutcrackerEnemyAI))]
public static class NutcrackerPatches
{
private static float _aimCheckTimer;
private static float _patrolTimer;
private const float AIM_CHECK_INTERVAL = 0.15f;
private const float PATROL_CHECK_INTERVAL = 0.3f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(NutcrackerEnemyAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(NutcrackerEnemyAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_patrolTimer -= Time.deltaTime;
if (_patrolTimer > 0f)
{
return false;
}
_patrolTimer = 0.3f;
}
return true;
}
[HarmonyPatch("AimGun")]
[HarmonyPrefix]
public static bool AimGun_Prefix(NutcrackerEnemyAI __instance)
{
_aimCheckTimer -= Time.deltaTime;
if (_aimCheckTimer > 0f)
{
return false;
}
_aimCheckTimer = 0.15f;
return true;
}
[HarmonyPatch("CheckLineOfSightForLocalPlayer")]
[HarmonyPrefix]
public static bool CheckLOS_Prefix(NutcrackerEnemyAI __instance)
{
if ((Object)(object)((EnemyAI)__instance).targetPlayer == (Object)null)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(RadMechAI))]
public static class RadMechPatches
{
private static float _threatCheckTimer;
private static float _lateUpdateTimer;
private const float THREAT_CHECK_INTERVAL = 0.2f;
private const float LATE_UPDATE_INTERVAL = 0.05f;
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static bool LateUpdate_Prefix(RadMechAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
_lateUpdateTimer += Time.deltaTime;
if (_lateUpdateTimer < 0.05f)
{
return false;
}
_lateUpdateTimer = 0f;
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(RadMechAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (!__instance.isAlerted)
{
_threatCheckTimer += Time.deltaTime;
if (_threatCheckTimer < 0.2f)
{
return false;
}
_threatCheckTimer = 0f;
}
return true;
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(RadMechAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(SandSpiderAI))]
public static class SandSpiderPatches
{
private static float _webCheckTimer;
private static float _patrolTimer;
private const float WEB_CHECK_INTERVAL = 0.3f;
private const float PATROL_INTERVAL = 0.25f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(SandSpiderAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 3 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(SandSpiderAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
_patrolTimer -= Time.deltaTime;
if (_patrolTimer > 0f)
{
return false;
}
_patrolTimer = 0.25f;
}
return true;
}
[HarmonyPatch("CheckForPlayersInLineOfSight")]
[HarmonyPrefix]
public static bool CheckPlayers_Prefix(SandSpiderAI __instance)
{
_webCheckTimer -= Time.deltaTime;
if (_webCheckTimer > 0f)
{
return false;
}
_webCheckTimer = 0.3f;
return true;
}
}
[HarmonyPatch(typeof(PufferAI))]
public static class SporeLizardPatches
{
private static float _fearCheckTimer;
private const float FEAR_CHECK_INTERVAL = 0.2f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(PufferAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
if (((EnemyAI)__instance).currentBehaviourStateIndex == 0 && Time.frameCount % 3 != 0)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(PufferAI __instance)
{
if (!PluginConfig.EnableAIOptimizations.Value)
{
return true;
}
_fearCheckTimer -= Time.deltaTime;
if (_fearCheckTimer > 0f && ((EnemyAI)__instance).currentBehaviourStateIndex == 0)
{
return false;
}
_fearCheckTimer = 0.2f;
return true;
}
}
[HarmonyPatch(typeof(SpringManAI))]
public static class SpringManPatches
{
private static float _losCheckTimer;
private const float LOS_CHECK_INTERVAL = 0.1f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static bool Update_Prefix(SpringManAI __instance)
{
if (((EnemyAI)__instance).isEnemyDead)
{
return false;
}
return true;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
public static bool DoAIInterval_Prefix(SpringManAI __instance)
{
_losCheckTimer -= Time.deltaTime;
if (_losCheckTimer > 0f)
{
return true;
}
_losCheckTimer = 0.1f;
return true;
}
[HarmonyPatch("SetAnimationStopServerRpc")]
[HarmonyPrefix]
public static bool SetAnimationStop_Prefix(SpringManAI __instance)
{
if (!NetworkThrottle.CanSendForObject("animation", ((Object)__instance).GetInstanceID()))
{
return false;
}
return true;
}
}
}
namespace LethalOptimizer.Core
{
public static class AINodeCache
{
public static GameObject[] InsideNodes { get; private set; }
public static GameObject[] OutsideNodes { get; private set; }
public static void Initialize()
{
InsideNodes = null;
OutsideNodes = null;
}
public static void CacheNodes()
{
InsideNodes = GameObject.FindGameObjectsWithTag("AINode");
OutsideNodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
ManualLogSource log = Plugin.Log;
GameObject[] insideNodes = InsideNodes;
object arg = ((insideNodes != null) ? insideNodes.Length : 0);
GameObject[] outsideNodes = OutsideNodes;
log.LogInfo((object)$"Cached {arg} inside, {((outsideNodes != null) ? outsideNodes.Length : 0)} outside AI nodes");
}
public static GameObject[] GetNodes(bool outside)
{
if (!outside)
{
return InsideNodes;
}
return OutsideNodes;
}
}
public class Benchmark : MonoBehaviour
{
private readonly Queue<float> _fpsHistory = new Queue<float>();
private const int FPS_SAMPLE_SIZE = 300;
private float _fpsUpdateTimer;
private float _currentFps;
private long _lastMemory;
private long _peakMemory;
private readonly Queue<long> _memoryHistory = new Queue<long>();
private readonly Queue<float> _frameTimeHistory = new Queue<float>();
private float _worstFrameTime;
private float _bestFrameTime = float.MaxValue;
private float _sessionStartTime;
private int _totalFrames;
private float _totalFrameTime;
private int _activeEnemies;
private int _activeItems;
private int _activePlayers;
private bool _isRunning;
private float _benchmarkDuration = 60f;
private float _benchmarkTimer;
private BenchmarkResult _lastResult;
private bool _showOverlay;
private GUIStyle _overlayStyle;
private Rect _overlayRect;
public static Benchmark Instance { get; private set; }
public static void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
GameObject val = new GameObject("LethalOptimizer_Benchmark");
Instance = val.AddComponent<Benchmark>();
Object.DontDestroyOnLoad((Object)val);
Plugin.Log.LogInfo((object)"Benchmark system initialized. Press F8 to toggle overlay, F9 to run benchmark.");
}
}
private void Awake()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
_sessionStartTime = Time.time;
_overlayRect = new Rect(10f, 10f, 320f, 200f);
}
private void Update()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if (!PluginConfig.EnableBenchmark.Value)
{
return;
}
if (Input.GetKeyDown(PluginConfig.OverlayKey.Value))
{
_showOverlay = !_showOverlay;
Plugin.Log.LogInfo((object)("Performance overlay: " + (_showOverlay ? "ON" : "OFF")));
}
if (Input.GetKeyDown(PluginConfig.BenchmarkKey.Value))
{
if (!_isRunning)
{
StartBenchmark(PluginConfig.BenchmarkDuration.Value);
}
else
{
StopBenchmark();
}
}
UpdateMetrics();
if (_isRunning)
{
UpdateBenchmark();
}
}
private void UpdateMetrics()
{
_fpsUpdateTimer += Time.unscaledDeltaTime;
if (_fpsUpdateTimer >= 0.1f)
{
_currentFps = 1f / Time.unscaledDeltaTime;
_fpsUpdateTimer = 0f;
_fpsHistory.Enqueue(_currentFps);
if (_fpsHistory.Count > 300)
{
_fpsHistory.Dequeue();
}
}
float num = Time.unscaledDeltaTime * 1000f;
_frameTimeHistory.Enqueue(num);
if (_frameTimeHistory.Count > 300)
{
_frameTimeHistory.Dequeue();
}
if (num > _worstFrameTime)
{
_worstFrameTime = num;
}
if (num < _bestFrameTime)
{
_bestFrameTime = num;
}
_totalFrames++;
_totalFrameTime += num;
if (Time.frameCount % 60 == 0)
{
long totalMemory = GC.GetTotalMemory(forceFullCollection: false);
_memoryHistory.Enqueue(totalMemory);
if (_memoryHistory.Count > 60)
{
_memoryHistory.Dequeue();
}
if (totalMemory > _peakMemory)
{
_peakMemory = totalMemory;
}
_lastMemory = totalMemory;
}
if (Time.frameCount % 120 == 0)
{
UpdateGameStats();
}
}
private void UpdateGameStats()
{
try
{
RoundManager instance = RoundManager.Instance;
if ((Object)(object)instance != (Object)null)
{
_activeEnemies = instance.SpawnedEnemies?.Count ?? 0;
}
StartOfRound instance2 = StartOfRound.Instance;
if ((Object)(object)instance2 != (Object)null)
{
_activePlayers = 0;
PlayerControllerB[] allPlayerScripts = instance2.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (val.isPlayerControlled && !val.isPlayerDead)
{
_activePlayers++;
}
}
}
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
_activeItems = ((array != null) ? array.Length : 0);
}
catch
{
}
}
public void StartBenchmark(float duration = 60f)
{
_benchmarkDuration = duration;
_benchmarkTimer = 0f;
_isRunning = true;
_fpsHistory.Clear();
_frameTimeHistory.Clear();
_memoryHistory.Clear();
_worstFrameTime = 0f;
_bestFrameTime = float.MaxValue;
_totalFrames = 0;
_totalFrameTime = 0f;
_peakMemory = 0L;
Plugin.Log.LogInfo((object)$"Benchmark started for {duration} seconds...");
}
private void UpdateBenchmark()
{
_benchmarkTimer += Time.unscaledDeltaTime;
if (_benchmarkTimer >= _benchmarkDuration)
{
StopBenchmark();
}
}
public void StopBenchmark()
{
if (_isRunning)
{
_isRunning = false;
_lastResult = GenerateResult();
Plugin.Log.LogInfo((object)"=== BENCHMARK RESULTS ===");
Plugin.Log.LogInfo((object)_lastResult.ToString());
_showOverlay = true;
}
}
private BenchmarkResult GenerateResult()
{
BenchmarkResult benchmarkResult = new BenchmarkResult
{
Duration = _benchmarkTimer,
TotalFrames = _totalFrames
};
if (_fpsHistory.Count > 0)
{
float num = 0f;
float num2 = float.MaxValue;
float num3 = 0f;
foreach (float item in _fpsHistory)
{
num += item;
if (item < num2)
{
num2 = item;
}
if (item > num3)
{
num3 = item;
}
}
benchmarkResult.AvgFps = num / (float)_fpsHistory.Count;
benchmarkResult.MinFps = num2;
benchmarkResult.MaxFps = num3;
List<float> list = new List<float>(_fpsHistory);
list.Sort();
int index = Mathf.Max(0, list.Count / 100);
benchmarkResult.OnePercentLow = list[index];
}
benchmarkResult.AvgFrameTime = ((_totalFrames > 0) ? (_totalFrameTime / (float)_totalFrames) : 0f);
benchmarkResult.WorstFrameTime = _worstFrameTime;
benchmarkResult.BestFrameTime = _bestFrameTime;
benchmarkResult.CurrentMemoryMB = (float)_lastMemory / 1048576f;
benchmarkResult.PeakMemoryMB = (float)_peakMemory / 1048576f;
benchmarkResult.ActiveEnemies = _activeEnemies;
benchmarkResult.ActiveItems = _activeItems;
benchmarkResult.ActivePlayers = _activePlayers;
return benchmarkResult;
}
private void OnGUI()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_0048: Expected O, but got Unknown
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
if (_showOverlay)
{
if (_overlayStyle == null)
{
_overlayStyle = new GUIStyle(GUI.skin.box)
{
fontSize = 14,
alignment = (TextAnchor)0,
padding = new RectOffset(10, 10, 10, 10)
};
_overlayStyle.normal.textColor = Color.white;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("<b>LethalOptimizer Performance</b>");
stringBuilder.AppendLine($"FPS: {_currentFps:F1} (Avg: {GetAverageFps():F1})");
stringBuilder.AppendLine($"Frame Time: {Time.unscaledDeltaTime * 1000f:F2}ms");
stringBuilder.AppendLine($"Memory: {(float)_lastMemory / 1048576f:F1} MB (Peak: {(float)_peakMemory / 1048576f:F1} MB)");
stringBuilder.AppendLine();
stringBuilder.AppendLine($"Enemies: {_activeEnemies} | Items: {_activeItems} | Players: {_activePlayers}");
if (_isRunning)
{
stringBuilder.AppendLine();
stringBuilder.AppendLine($"<color=yellow>BENCHMARK: {_benchmarkTimer:F1}s / {_benchmarkDuration:F0}s</color>");
}
else if (_lastResult != null)
{
stringBuilder.AppendLine();
stringBuilder.AppendLine("<color=lime>Last Benchmark:</color>");
stringBuilder.AppendLine($"Avg: {_lastResult.AvgFps:F1} | 1% Low: {_lastResult.OnePercentLow:F1}");
}
stringBuilder.AppendLine();
stringBuilder.AppendLine("<size=11>F8: Toggle | F9: Benchmark</size>");
GUI.Box(_overlayRect, stringBuilder.ToString(), _overlayStyle);
}
}
private float GetAverageFps()
{
if (_fpsHistory.Count == 0)
{
return 0f;
}
float num = 0f;
foreach (float item in _fpsHistory)
{
num += item;
}
return num / (float)_fpsHistory.Count;
}
public BenchmarkResult GetLastResult()
{
return _lastResult;
}
}
public class BenchmarkResult
{
public float Duration;
public int TotalFrames;
public float AvgFps;
public float MinFps;
public float MaxFps;
public float OnePercentLow;
public float AvgFrameTime;
public float WorstFrameTime;
public float BestFrameTime;
public float CurrentMemoryMB;
public float PeakMemoryMB;
public int ActiveEnemies;
public int ActiveItems;
public int ActivePlayers;
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"Duration: {Duration:F1}s | Frames: {TotalFrames}");
stringBuilder.AppendLine($"FPS - Avg: {AvgFps:F1} | Min: {MinFps:F1} | Max: {MaxFps:F1} | 1% Low: {OnePercentLow:F1}");
stringBuilder.AppendLine($"Frame Time - Avg: {AvgFrameTime:F2}ms | Best: {BestFrameTime:F2}ms | Worst: {WorstFrameTime:F2}ms");
stringBuilder.AppendLine($"Memory - Current: {CurrentMemoryMB:F1}MB | Peak: {PeakMemoryMB:F1}MB");
stringBuilder.AppendLine($"Game State - Enemies: {ActiveEnemies} | Items: {ActiveItems} | Players: {ActivePlayers}");
return stringBuilder.ToString();
}
}
public static class ComponentCache
{
public struct CachedComponents
{
public NavMeshAgent Agent;
public Animator Animator;
public AudioSource AudioSource;
public Rigidbody Rigidbody;
public Collider Collider;
}
private static readonly Dictionary<int, CachedComponents> _cache = new Dictionary<int, CachedComponents>();
public static T Get<T>(GameObject obj) where T : Component
{
if ((Object)(object)obj == (Object)null)
{
return default(T);
}
int instanceID = ((Object)obj).GetInstanceID();
if (!_cache.TryGetValue(instanceID, out var value))
{
value = default(CachedComponents);
_cache[instanceID] = value;
}
if (typeof(T) == typeof(NavMeshAgent))
{
if ((Object)(object)value.Agent == (Object)null)
{
value.Agent = obj.GetComponent<NavMeshAgent>();
_cache[instanceID] = value;
}
NavMeshAgent agent = value.Agent;
return (T)(object)((agent is T) ? agent : null);
}
if (typeof(T) == typeof(Animator))
{
if ((Object)(object)value.Animator == (Object)null)
{
value.Animator = obj.GetComponent<Animator>();
_cache[instanceID] = value;
}
Animator animator = value.Animator;
return (T)(object)((animator is T) ? animator : null);
}
if (typeof(T) == typeof(AudioSource))
{
if ((Object)(object)value.AudioSource == (Object)null)
{
value.AudioSource = obj.GetComponent<AudioSource>();
_cache[instanceID] = value;
}
AudioSource audioSource = value.AudioSource;
return (T)(object)((audioSource is T) ? audioSource : null);
}
if (typeof(T) == typeof(Rigidbody))
{
if ((Object)(object)value.Rigidbody == (Object)null)
{
value.Rigidbody = obj.GetComponent<Rigidbody>();
_cache[instanceID] = value;
}
Rigidbody rigidbody = value.Rigidbody;
return (T)(object)((rigidbody is T) ? rigidbody : null);
}
if (typeof(T) == typeof(Collider))
{
if ((Object)(object)value.Collider == (Object)null)
{
value.Collider = obj.GetComponent<Collider>();
_cache[instanceID] = value;
}
Collider collider = value.Collider;
return (T)(object)((collider is T) ? collider : null);
}
return obj.GetComponent<T>();
}
public static void Remove(GameObject obj)
{
if ((Object)(object)obj != (Object)null)
{
_cache.Remove(((Object)obj).GetInstanceID());
}
}
public static void Clear()
{
_cache.Clear();
}
}
public class GraphicsOptimizer : MonoBehaviour
{
private int _originalShadowDistance;
private ShadowQuality _originalShadowQuality;
private ShadowResolution _originalShadowResolution;
private int _originalPixelLightCount;
private float _originalLodBias;
private int _originalMaxLod;
private AnisotropicFiltering _originalAniso;
private bool _settingsSaved;
private bool _lowEndModeActive;
public static GraphicsOptimizer Instance { get; private set; }
public bool IsLowEndModeActive => _lowEndModeActive;
public static void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
GameObject val = new GameObject("LethalOptimizer_Graphics");
Instance = val.AddComponent<GraphicsOptimizer>();
Object.DontDestroyOnLoad((Object)val);
if (PluginConfig.EnableLowEndMode != null && PluginConfig.EnableLowEndMode.Value)
{
Instance.ApplyLowEndOptimizations();
}
Plugin.Log.LogInfo((object)"Graphics optimizer initialized. Press F10 to toggle low-end mode.");
}
}
private void Awake()
{
SaveOriginalSettings();
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(PluginConfig.LowEndModeKey.Value))
{
if (_lowEndModeActive)
{
RestoreOriginalSettings();
}
else
{
ApplyLowEndOptimizations();
}
Plugin.Log.LogInfo((object)("Low-end mode: " + (_lowEndModeActive ? "ON" : "OFF")));
}
}
private void SaveOriginalSettings()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
_originalShadowDistance = (int)QualitySettings.shadowDistance;
_originalShadowQuality = QualitySettings.shadows;
_originalShadowResolution = QualitySettings.shadowResolution;
_originalPixelLightCount = QualitySettings.pixelLightCount;
_originalLodBias = QualitySettings.lodBias;
_originalMaxLod = QualitySettings.maximumLODLevel;
_originalAniso = QualitySettings.anisotropicFiltering;
_settingsSaved = true;
Plugin.Log.LogDebug((object)$"Original: shadows={_originalShadowDistance}, quality={_originalShadowQuality}");
}
public void ApplyLowEndOptimizations()
{
if (!_settingsSaved)
{
SaveOriginalSettings();
}
QualitySettings.shadowDistance = 20f;
QualitySettings.shadows = (ShadowQuality)1;
QualitySettings.shadowResolution = (ShadowResolution)0;
QualitySettings.shadowCascades = 1;
QualitySettings.lodBias = 0.5f;
QualitySettings.maximumLODLevel = 1;
QualitySettings.pixelLightCount = 1;
QualitySettings.anisotropicFiltering = (AnisotropicFiltering)0;
QualitySettings.masterTextureLimit = 1;
QualitySettings.softParticles = false;
QualitySettings.softVegetation = false;
QualitySettings.realtimeReflectionProbes = false;
QualitySettings.billboardsFaceCameraPosition = false;
_lowEndModeActive = true;
Plugin.Log.LogInfo((object)"Low-end optimizations applied!");
}
public void RestoreOriginalSettings()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if (_settingsSaved)
{
QualitySettings.shadowDistance = _originalShadowDistance;
QualitySettings.shadows = _originalShadowQuality;
QualitySettings.shadowResolution = _originalShadowResolution;
QualitySettings.pixelLightCount = _originalPixelLightCount;
QualitySettings.lodBias = _originalLodBias;
QualitySettings.maximumLODLevel = _originalMaxLod;
QualitySettings.anisotropicFiltering = _originalAniso;
QualitySettings.masterTextureLimit = 0;
QualitySettings.softParticles = true;
QualitySettings.realtimeReflectionProbes = true;
_lowEndModeActive = false;
Plugin.Log.LogInfo((object)"Original settings restored");
}
}
private void OnDestroy()
{
RestoreOriginalSettings();
}
}
public static class NetworkThrottle
{
private static readonly Dictionary<string, float> _lastCallTimes;
private static readonly Dictionary<string, float> _intervals;
static NetworkThrottle()
{
_lastCallTimes = new Dictionary<string, float>();
_intervals = new Dictionary<string, float>();
_intervals["position"] = 0.05f;
_intervals["rotation"] = 0.1f;
_intervals["animation"] = 0.1f;
_intervals["audio"] = 0.2f;
_intervals["damage"] = 0.5f;
_intervals["interact"] = 0.1f;
}
public static bool CanSend(string rpcType)
{
float valueOrDefault = _intervals.GetValueOrDefault(rpcType, 0.1f);
float valueOrDefault2 = _lastCallTimes.GetValueOrDefault(rpcType, 0f);
if (Time.time - valueOrDefault2 < valueOrDefault)
{
return false;
}
_lastCallTimes[rpcType] = Time.time;
return true;
}
public static bool CanSendForObject(string rpcType, int objectId)
{
string key = $"{rpcType}_{objectId}";
float valueOrDefault = _intervals.GetValueOrDefault(rpcType, 0.1f);
float valueOrDefault2 = _lastCallTimes.GetValueOrDefault(key, 0f);
if (Time.time - valueOrDefault2 < valueOrDefault)
{
return false;
}
_lastCallTimes[key] = Time.time;
return true;
}
public static void SetInterval(string rpcType, float interval)
{
_intervals[rpcType] = interval;
}
public static void Clear()
{
_lastCallTimes.Clear();
}
}
public static class ObjectPool
{
private static readonly Dictionary<string, Queue<GameObject>> _pools = new Dictionary<string, Queue<GameObject>>();
private static readonly Dictionary<int, Collider[]> _colliderArrays = new Dictionary<int, Collider[]>();
public static void Initialize()
{
_pools.Clear();
_colliderArrays.Clear();
for (int i = 1; i <= 50; i++)
{
_colliderArrays[i] = (Collider[])(object)new Collider[i];
}
}
public static Collider[] GetColliderArray(int size)
{
if (_colliderArrays.TryGetValue(size, out var value))
{
return value;
}
Collider[] array = (Collider[])(object)new Collider[size];
_colliderArrays[size] = array;
return array;
}
public static void Cleanup()
{
_pools.Clear();
}
}
public static class PerformanceMonitor
{
private static readonly Dictionary<string, Stopwatch> _timers = new Dictionary<string, Stopwatch>();
private static readonly Dictionary<string, float> _averages = new Dictionary<string, float>();
private static readonly Dictionary<string, int> _counts = new Dictionary<string, int>();
private static float _lastLogTime;
private const float LOG_INTERVAL = 10f;
public static void StartTimer(string name)
{
if (PluginConfig.EnableLogging.Value)
{
if (!_timers.ContainsKey(name))
{
_timers[name] = new Stopwatch();
}
_timers[name].Restart();
}
}
public static void StopTimer(string name)
{
if (PluginConfig.EnableLogging.Value && _timers.TryGetValue(name, out var value))
{
value.Stop();
float num = (float)value.ElapsedTicks / (float)Stopwatch.Frequency * 1000f;
if (!_averages.ContainsKey(name))
{
_averages[name] = 0f;
_counts[name] = 0;
}
_counts[name]++;
_averages[name] += (num - _averages[name]) / (float)_counts[name];
}
}
public static void LogMetrics()
{
if (!PluginConfig.EnableLogging.Value || Time.time - _lastLogTime < 10f)
{
return;
}
_lastLogTime = Time.time;
Plugin.Log.LogInfo((object)"=== Performance Metrics ===");
foreach (KeyValuePair<string, float> average in _averages)
{
Plugin.Log.LogInfo((object)$"{average.Key}: {average.Value:F3}ms avg ({_counts[average.Key]} samples)");
}
_averages.Clear();
_counts.Clear();
}
public static void Clear()
{
_timers.Clear();
_averages.Clear();
_counts.Clear();
}
}
public class ShipOptimizer : MonoBehaviour
{
private List<Light> _shipLights = new List<Light>();
private List<ParticleSystem> _shipParticles = new List<ParticleSystem>();
private bool _initialized;
private float _initDelay = 5f;
public static ShipOptimizer Instance { get; private set; }
public static void Initialize()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
GameObject val = new GameObject("LethalOptimizer_Ship");
Instance = val.AddComponent<ShipOptimizer>();
Object.DontDestroyOnLoad((Object)val);
Plugin.Log.LogInfo((object)"Ship optimizer initialized");
}
}
private void Update()
{
if (!_initialized)
{
_initDelay -= Time.deltaTime;
if (!(_initDelay > 0f))
{
CacheShipComponents();
_initialized = true;
}
}
}
private void CacheShipComponents()
{
Light[] array = Object.FindObjectsOfType<Light>();
foreach (Light val in array)
{
if (((Object)((Component)val).gameObject).name.Contains("Ship") || ((Object)((Component)val).transform.root).name.Contains("Ship"))
{
_shipLights.Add(val);
}
}
ParticleSystem[] array2 = Object.FindObjectsOfType<ParticleSystem>();
foreach (ParticleSystem val2 in array2)
{
if (((Object)((Component)val2).gameObject).name.Contains("Ship") || ((Object)((Component)val2).transform.root).name.Contains("Ship"))
{
_shipParticles.Add(val2);
}
}
Plugin.Log.LogDebug((object)$"Cached {_shipLights.Count} ship lights, {_shipParticles.Count} particles");
}
public void OptimizeShipLights()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
foreach (Light shipLight in _shipLights)
{
if (!((Object)(object)shipLight == (Object)null) && (int)shipLight.shadows != 0)
{
shipLight.shadowResolution = (LightShadowResolution)0;
}
}
}
public void SetShipParticlesEnabled(bool enabled)
{
foreach (ParticleSystem shipParticle in _shipParticles)
{
if (!((Object)(object)shipParticle == (Object)null))
{
if (enabled && !shipParticle.isPlaying)
{
shipParticle.Play();
}
else if (!enabled && shipParticle.isPlaying)
{
shipParticle.Pause();
}
}
}
}
public void ClearCache()
{
_shipLights.Clear();
_shipParticles.Clear();
_initialized = false;
_initDelay = 5f;
}
}
}
namespace LethalOptimizer.Config
{
public static class PluginConfig
{
public static ConfigEntry<bool> EnableAllOptimizations;
public static ConfigEntry<bool> EnableLogging;
public static ConfigEntry<bool> EnableAIOptimizations;
public static ConfigEntry<float> AIUpdateInterval;
public static ConfigEntry<float> LOSCheckInterval;
public static ConfigEntry<bool> ThrottleIdleEnemies;
public static ConfigEntry<bool> EnableNetworkOptimizations;
public static ConfigEntry<float> PositionSyncRate;
public static ConfigEntry<float> AnimationSyncRate;
public static ConfigEntry<float> PositionThreshold;
public static ConfigEntry<bool> EnablePlayerOptimizations;
public static ConfigEntry<bool> ThrottleInteractionChecks;
public static ConfigEntry<bool> EnableUIOptimizations;
public static ConfigEntry<float> ClockUpdateInterval;
public static ConfigEntry<bool> EnableObjectOptimizations;
public static ConfigEntry<bool> SkipHeldItemUpdates;
public static ConfigEntry<bool> EnableBenchmark;
public static ConfigEntry<float> BenchmarkDuration;
public static ConfigEntry<KeyCode> OverlayKey;
public static ConfigEntry<KeyCode> BenchmarkKey;
public static ConfigEntry<bool> EnableLowEndMode;
public static ConfigEntry<KeyCode> LowEndModeKey;
public static ConfigEntry<bool> EnableTrapOptimizations;
public static void Initialize(ConfigFile config)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Expected O, but got Unknown
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Expected O, but got Unknown
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Expected O, but got Unknown
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Expected O, but got Unknown
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Expected O, but got Unknown
//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Expected O, but got Unknown
EnableAllOptimizations = config.Bind<bool>("General", "EnableAllOptimizations", true, "Master switch for all optimizations");
EnableLogging = config.Bind<bool>("General", "EnableLogging", false, "Enable debug logging (may impact performance)");
EnableAIOptimizations = config.Bind<bool>("AI", "EnableAIOptimizations", true, "Enable AI-related optimizations");
AIUpdateInterval = config.Bind<float>("AI", "AIUpdateInterval", 0.2f, new ConfigDescription("Interval between AI logic updates (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
LOSCheckInterval = config.Bind<float>("AI", "LOSCheckInterval", 0.1f, new ConfigDescription("Interval between line-of-sight checks (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.5f), Array.Empty<object>()));
ThrottleIdleEnemies = config.Bind<bool>("AI", "ThrottleIdleEnemies", true, "Reduce update frequency for idle/roaming enemies");
EnableNetworkOptimizations = config.Bind<bool>("Network", "EnableNetworkOptimizations", true, "Enable network-related optimizations");
PositionSyncRate = config.Bind<float>("Network", "PositionSyncRate", 20f, new ConfigDescription("Position sync rate per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 60f), Array.Empty<object>()));
AnimationSyncRate = config.Bind<float>("Network", "AnimationSyncRate", 10f, new ConfigDescription("Animation sync rate per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 30f), Array.Empty<object>()));
PositionThreshold = config.Bind<float>("Network", "PositionThreshold", 0.01f, new ConfigDescription("Minimum position change to trigger sync", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.1f), Array.Empty<object>()));
EnablePlayerOptimizations = config.Bind<bool>("Player", "EnablePlayerOptimizations", true, "Enable player-related optimizations");
ThrottleInteractionChecks = config.Bind<bool>("Player", "ThrottleInteractionChecks", true, "Reduce frequency of interaction raycast checks");
EnableUIOptimizations = config.Bind<bool>("UI", "EnableUIOptimizations", true, "Enable UI-related optimizations");
ClockUpdateInterval = config.Bind<float>("UI", "ClockUpdateInterval", 1f, new ConfigDescription("Clock UI update interval (seconds)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
EnableObjectOptimizations = config.Bind<bool>("Objects", "EnableObjectOptimizations", true, "Enable grabbable object optimizations");
SkipHeldItemUpdates = config.Bind<bool>("Objects", "SkipHeldItemUpdates", true, "Skip physics updates for held items");
EnableBenchmark = config.Bind<bool>("Benchmark", "EnableBenchmark", true, "Enable built-in benchmark system");
BenchmarkDuration = config.Bind<float>("Benchmark", "BenchmarkDuration", 60f, new ConfigDescription("Benchmark duration in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 300f), Array.Empty<object>()));
OverlayKey = config.Bind<KeyCode>("Benchmark", "OverlayKey", (KeyCode)289, "Key to toggle performance overlay");
BenchmarkKey = config.Bind<KeyCode>("Benchmark", "BenchmarkKey", (KeyCode)290, "Key to start/stop benchmark");
EnableLowEndMode = config.Bind<bool>("Graphics", "EnableLowEndMode", false, "Enable low-end PC mode on startup (reduces shadows, textures, LOD)");
LowEndModeKey = config.Bind<KeyCode>("Graphics", "LowEndModeKey", (KeyCode)291, "Key to toggle low-end mode in-game");
EnableTrapOptimizations = config.Bind<bool>("Traps", "EnableTrapOptimizations", true, "Enable optimizations for turrets, landmines, and spike traps");
}
}
}