Decompiled source of BoneFPS v1.2.5

Mods/BoneFPS.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneFPS;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BoneFPSMod), "BoneFPS", "1.2.5", "Zooks", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Zooks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.5.0")]
[assembly: AssemblyInformationalVersion("1.2.5")]
[assembly: AssemblyProduct("BoneFPS")]
[assembly: AssemblyTitle("BoneFPS")]
[assembly: AssemblyVersion("1.2.5.0")]
[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 BoneFPS
{
	public class BoneFPSMod : MelonMod
	{
		public static BoneFPSMod Instance;

		public static MelonPreferences_Category Prefs;

		public static MelonPreferences_Entry<bool> EnableMod;

		public static MelonPreferences_Entry<int> PerfLevel;

		public static MelonPreferences_Entry<bool> OptLODBias;

		public static MelonPreferences_Entry<bool> OptShadowDistance;

		public static MelonPreferences_Entry<bool> OptShadowCascades;

		public static MelonPreferences_Entry<bool> OptParticleLimits;

		public static MelonPreferences_Entry<bool> OptLightCulling;

		public static MelonPreferences_Entry<bool> OptCameraCulling;

		public static MelonPreferences_Entry<bool> OptAnimThrottle;

		public static MelonPreferences_Entry<bool> OptOcclusionCulling;

		public static MelonPreferences_Entry<bool> OptStutterFix;

		public static MelonPreferences_Entry<bool> OptDistanceShadowCull;

		public static MelonPreferences_Entry<bool> OptParticleDistPause;

		public static MelonPreferences_Entry<bool> OptTrailCull;

		public static MelonPreferences_Entry<bool> OptHybridLOD;

		public static MelonPreferences_Entry<bool> OptAdaptiveShadowDist;

		public static MelonPreferences_Entry<bool> OptMSAA;

		public static MelonPreferences_Entry<bool> OptSoftShadows;

		public static MelonPreferences_Entry<bool> OptPixelLightCount;

		public static MelonPreferences_Entry<bool> OptAsyncUpload;

		public static MelonPreferences_Entry<float> NearDist;

		public static MelonPreferences_Entry<float> MidDist;

		public static MelonPreferences_Entry<float> FarDist;

		public static MelonPreferences_Entry<int> MaxShadowCasters;

		public static MelonPreferences_Entry<float> GPUSaverIdleTime;

		public PerformanceManager PerfManager;

		public RenderOptimizer RenderOpt;

		private float _sceneLoadDelay = -1f;

		private bool _applied;

		private float _statsTimer;

		private int _frameCount;

		private float _currentFPS;

		public override void OnInitializeMelon()
		{
			Instance = this;
			((MelonBase)this).LoggerInstance.Msg("");
			((MelonBase)this).LoggerInstance.Msg("  ==========================================================");
			((MelonBase)this).LoggerInstance.Msg("  ██████╗  ██████╗ ███╗   ██╗███████╗███████╗██████╗ ███████╗");
			((MelonBase)this).LoggerInstance.Msg("  ██╔══██╗██╔═══██╗████╗  ██║██╔════╝██╔════╝██╔══██╗██╔════╝");
			((MelonBase)this).LoggerInstance.Msg("  ██████╔╝██║   ██║██╔██╗ ██║█████╗  █████╗  ██████╔╝███████╗");
			((MelonBase)this).LoggerInstance.Msg("  ██╔══██╗██║   ██║██║╚██╗██║██╔══╝  ██╔══╝  ██╔═══╝ ╚════██║");
			((MelonBase)this).LoggerInstance.Msg("  ██████╔╝╚██████╔╝██║ ╚████║███████╗██║     ██║     ███████║");
			((MelonBase)this).LoggerInstance.Msg("  ╚═════╝  ╚═════╝ ╚═╝  ╚═══╝╚══════╝╚═╝     ╚═╝     ╚══════╝");
			((MelonBase)this).LoggerInstance.Msg("                        v1.2.5                                 ");
			((MelonBase)this).LoggerInstance.Msg("  ==========================================================");
			((MelonBase)this).LoggerInstance.Msg("                 High FPS  - by Zooks");
			((MelonBase)this).LoggerInstance.Msg("  ==========================================================");
			((MelonBase)this).LoggerInstance.Msg("");
			SetupPreferences();
			SetupBoneMenu();
			PerfManager = new PerformanceManager(this);
			RenderOpt = new RenderOptimizer(this);
			try
			{
				QualitySettings.vSyncCount = 0;
				Application.targetFrameRate = -1;
				Application.backgroundLoadingPriority = (ThreadPriority)0;
			}
			catch (Exception)
			{
			}
			((MelonBase)this).LoggerInstance.Msg("[BoneFPS] Ready!");
		}

		private void SetupPreferences()
		{
			Prefs = MelonPreferences.CreateCategory("BoneFPS");
			EnableMod = Prefs.CreateEntry<bool>("EnableMod", true, "Enable Mod", (string)null, false, false, (ValueValidator)null, (string)null);
			PerfLevel = Prefs.CreateEntry<int>("PerfLevel", 1, "Performance Level 0-3", (string)null, false, false, (ValueValidator)null, (string)null);
			OptLODBias = Prefs.CreateEntry<bool>("OptLODBias", true, "LOD Bias Adjustment", (string)null, false, false, (ValueValidator)null, (string)null);
			OptShadowDistance = Prefs.CreateEntry<bool>("OptShadowDistance", true, "Shadow Distance Limit", (string)null, false, false, (ValueValidator)null, (string)null);
			OptShadowCascades = Prefs.CreateEntry<bool>("OptShadowCascades", true, "Shadow Cascade Reduce", (string)null, false, false, (ValueValidator)null, (string)null);
			OptParticleLimits = Prefs.CreateEntry<bool>("OptParticleLimits", true, "Particle Count Limits", (string)null, false, false, (ValueValidator)null, (string)null);
			OptLightCulling = Prefs.CreateEntry<bool>("OptLightCulling", true, "Light Distance Culling", (string)null, false, false, (ValueValidator)null, (string)null);
			OptCameraCulling = Prefs.CreateEntry<bool>("OptCameraCulling", true, "Secondary Camera Culling", (string)null, false, false, (ValueValidator)null, (string)null);
			OptAnimThrottle = Prefs.CreateEntry<bool>("OptAnimThrottle", true, "Animation Distance Throttle", (string)null, false, false, (ValueValidator)null, (string)null);
			OptOcclusionCulling = Prefs.CreateEntry<bool>("OptOcclusionCulling", true, "Occlusion Culling Boost", (string)null, false, false, (ValueValidator)null, (string)null);
			OptStutterFix = Prefs.CreateEntry<bool>("OptStutterFix", true, "Shader Warmup Stutter Fix", (string)null, false, false, (ValueValidator)null, (string)null);
			OptDistanceShadowCull = Prefs.CreateEntry<bool>("OptDistanceShadowCull", true, "Distance Shadow Culling", (string)null, false, false, (ValueValidator)null, (string)null);
			OptParticleDistPause = Prefs.CreateEntry<bool>("OptParticleDistPause", true, "Particle Distance Pause", (string)null, false, false, (ValueValidator)null, (string)null);
			OptTrailCull = Prefs.CreateEntry<bool>("OptTrailCull", true, "Trail Distance Culling", (string)null, false, false, (ValueValidator)null, (string)null);
			OptHybridLOD = Prefs.CreateEntry<bool>("OptHybridLOD", true, "LOD Group Force at Distance", (string)null, false, false, (ValueValidator)null, (string)null);
			OptAdaptiveShadowDist = Prefs.CreateEntry<bool>("OptAdaptiveShadowDist", true, "FPS Adaptive Shadow Dist", (string)null, false, false, (ValueValidator)null, (string)null);
			OptMSAA = Prefs.CreateEntry<bool>("OptMSAA", true, "Reduce MSAA", (string)null, false, false, (ValueValidator)null, (string)null);
			OptSoftShadows = Prefs.CreateEntry<bool>("OptSoftShadows", true, "Disable Soft Shadows", (string)null, false, false, (ValueValidator)null, (string)null);
			OptPixelLightCount = Prefs.CreateEntry<bool>("OptPixelLightCount", true, "Limit Pixel Light Count", (string)null, false, false, (ValueValidator)null, (string)null);
			OptAsyncUpload = Prefs.CreateEntry<bool>("OptAsyncUpload", true, "Optimize Async Upload", (string)null, false, false, (ValueValidator)null, (string)null);
			NearDist = Prefs.CreateEntry<float>("NearDist", 12f, "Near Distance", (string)null, false, false, (ValueValidator)null, (string)null);
			MidDist = Prefs.CreateEntry<float>("MidDist", 35f, "Mid Distance", (string)null, false, false, (ValueValidator)null, (string)null);
			FarDist = Prefs.CreateEntry<float>("FarDist", 70f, "Far Distance", (string)null, false, false, (ValueValidator)null, (string)null);
			MaxShadowCasters = Prefs.CreateEntry<int>("MaxShadowCasters", 20, "Max Shadow Casters", (string)null, false, false, (ValueValidator)null, (string)null);
			GPUSaverIdleTime = Prefs.CreateEntry<float>("GPUSaverIdleTime", 5f, "GPU Saver Idle Seconds", (string)null, false, false, (ValueValidator)null, (string)null);
		}

		private void SetupBoneMenu()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("BoneFPS 1.2.5", Color.cyan, 0, true);
			obj.CreateBool("Enable Mod", Color.green, EnableMod.Value, (Action<bool>)delegate(bool v)
			{
				EnableMod.Value = v;
				Save();
			});
			obj.CreateInt("Perf Level (0-3)", Color.yellow, PerfLevel.Value, 1, 0, 3, (Action<int>)delegate(int v)
			{
				PerfLevel.Value = v;
				Save();
				if (EnableMod.Value)
				{
					ApplyAll();
				}
			});
			Page page = obj.CreatePage("Optimizations", Color.yellow, 0, true);
			CreateToggle(page, "LOD Bias", OptLODBias);
			CreateToggle(page, "Shadow Distance", OptShadowDistance);
			CreateToggle(page, "Shadow Cascades", OptShadowCascades);
			CreateToggle(page, "Particle Limits", OptParticleLimits);
			CreateToggle(page, "Light Culling", OptLightCulling);
			CreateToggle(page, "Camera Culling", OptCameraCulling);
			CreateToggle(page, "Anim Throttle", OptAnimThrottle);
			CreateToggle(page, "Occlusion Culling", OptOcclusionCulling);
			CreateToggle(page, "Stutter Fix", OptStutterFix);
			CreateToggle(page, "Dist Shadow Cull", OptDistanceShadowCull);
			CreateToggle(page, "Particle Dist Pause", OptParticleDistPause);
			CreateToggle(page, "Trail Cull", OptTrailCull);
			CreateToggle(page, "Hybrid LOD", OptHybridLOD);
			CreateToggle(page, "Adaptive Shadow Dist", OptAdaptiveShadowDist);
			CreateToggle(page, "Reduce MSAA", OptMSAA);
			CreateToggle(page, "Soft Shadows Off", OptSoftShadows);
			CreateToggle(page, "Pixel Light Limit", OptPixelLightCount);
			CreateToggle(page, "Async Upload", OptAsyncUpload);
			Page obj2 = obj.CreatePage("Distances", Color.white, 0, true);
			obj2.CreateFloat("Near Distance", Color.white, NearDist.Value, 2f, 5f, 25f, (Action<float>)delegate(float v)
			{
				NearDist.Value = v;
				Save();
			});
			obj2.CreateFloat("Mid Distance", Color.white, MidDist.Value, 5f, 15f, 60f, (Action<float>)delegate(float v)
			{
				MidDist.Value = v;
				Save();
			});
			obj2.CreateFloat("Far Distance", Color.white, FarDist.Value, 10f, 30f, 120f, (Action<float>)delegate(float v)
			{
				FarDist.Value = v;
				Save();
			});
			obj2.CreateInt("Max Shadow Casters", Color.white, MaxShadowCasters.Value, 5, 5, 50, (Action<int>)delegate(int v)
			{
				MaxShadowCasters.Value = v;
				Save();
			});
			obj.CreateFunction("MAX FPS", Color.red, (Action)delegate
			{
				PerfLevel.Value = 3;
				SetAllToggles(val: true);
				NearDist.Value = 8f;
				MidDist.Value = 25f;
				FarDist.Value = 50f;
				MaxShadowCasters.Value = 10;
				Save();
				ApplyAll();
			});
			obj.CreateFunction("BALANCED", Color.yellow, (Action)delegate
			{
				PerfLevel.Value = 1;
				SetAllToggles(val: true);
				NearDist.Value = 12f;
				MidDist.Value = 35f;
				FarDist.Value = 70f;
				MaxShadowCasters.Value = 20;
				Save();
				ApplyAll();
			});
			obj.CreateFunction("QUALITY+", Color.green, (Action)delegate
			{
				PerfLevel.Value = 0;
				SetAllToggles(val: true);
				OptShadowCascades.Value = false;
				OptMSAA.Value = false;
				OptPixelLightCount.Value = false;
				NearDist.Value = 15f;
				MidDist.Value = 45f;
				FarDist.Value = 90f;
				MaxShadowCasters.Value = 30;
				Save();
				ApplyAll();
			});
			obj.CreateFunction("Apply Now", Color.green, (Action)delegate
			{
				ApplyAll();
			});
		}

		private void SetAllToggles(bool val)
		{
			OptLODBias.Value = val;
			OptShadowDistance.Value = val;
			OptShadowCascades.Value = val;
			OptParticleLimits.Value = val;
			OptLightCulling.Value = val;
			OptCameraCulling.Value = val;
			OptAnimThrottle.Value = val;
			OptOcclusionCulling.Value = val;
			OptStutterFix.Value = val;
			OptDistanceShadowCull.Value = val;
			OptParticleDistPause.Value = val;
			OptTrailCull.Value = val;
			OptHybridLOD.Value = val;
			OptAdaptiveShadowDist.Value = val;
			OptMSAA.Value = val;
			OptSoftShadows.Value = val;
			OptPixelLightCount.Value = val;
			OptAsyncUpload.Value = val;
		}

		private void CreateToggle(Page page, string name, MelonPreferences_Entry<bool> entry)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			page.CreateBool(name, Color.white, entry.Value, (Action<bool>)delegate(bool v)
			{
				entry.Value = v;
				Save();
				if (EnableMod.Value)
				{
					ApplyAll();
				}
			});
		}

		private void Save()
		{
			Prefs.SaveToFile(false);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (EnableMod.Value)
			{
				((MelonBase)this).LoggerInstance.Msg("[BoneFPS] Scene: " + sceneName);
				_sceneLoadDelay = 4f;
				_applied = false;
				RenderOpt.OnSceneChanged();
			}
		}

		public override void OnUpdate()
		{
			if (!EnableMod.Value)
			{
				return;
			}
			_frameCount++;
			_statsTimer += Time.unscaledDeltaTime;
			if (_statsTimer >= 2f)
			{
				_currentFPS = (float)_frameCount / _statsTimer;
				_frameCount = 0;
				_statsTimer = 0f;
			}
			if (_sceneLoadDelay > 0f)
			{
				_sceneLoadDelay -= Time.unscaledDeltaTime;
				if (_sceneLoadDelay <= 0f && !_applied)
				{
					_applied = true;
					ApplyAll();
				}
			}
		}

		public void ApplyAll()
		{
			((MelonBase)this).LoggerInstance.Msg("[BoneFPS] Applying...");
			try
			{
				PerfManager.ApplyAllOptimizations();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("[Perf] " + ex.Message);
			}
			try
			{
				RenderOpt.ApplyAllRenderOptimizations();
			}
			catch (Exception ex2)
			{
				((MelonBase)this).LoggerInstance.Error("[Render] " + ex2.Message);
			}
			((MelonBase)this).LoggerInstance.Msg("[BoneFPS] Done!");
		}
	}
	public class PerformanceManager
	{
		private readonly BoneFPSMod _mod;

		private float _origShadowDistance = -1f;

		private ShadowQuality _origShadowQuality = (ShadowQuality)2;

		private ShadowResolution _origShadowResolution = (ShadowResolution)2;

		private int _origShadowCascades = 4;

		private int _origPixelLightCount = 4;

		private int _origAntiAliasing = 4;

		private bool _savedOriginals;

		public PerformanceManager(BoneFPSMod mod)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			_mod = mod;
		}

		private void SaveOriginals()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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 (_savedOriginals)
			{
				return;
			}
			try
			{
				_origShadowDistance = QualitySettings.shadowDistance;
				_origShadowQuality = QualitySettings.shadows;
				_origShadowResolution = QualitySettings.shadowResolution;
				_origShadowCascades = QualitySettings.shadowCascades;
				_origPixelLightCount = QualitySettings.pixelLightCount;
				_origAntiAliasing = QualitySettings.antiAliasing;
				_savedOriginals = true;
			}
			catch
			{
			}
		}

		public void ApplyAllOptimizations()
		{
			SaveOriginals();
			int value = BoneFPSMod.PerfLevel.Value;
			if (BoneFPSMod.OptLODBias.Value)
			{
				ApplyLODBias(value);
			}
			if (BoneFPSMod.OptShadowDistance.Value)
			{
				ApplyShadowDistance(value);
			}
			else
			{
				RestoreShadowDistance();
			}
			if (BoneFPSMod.OptShadowCascades.Value)
			{
				ApplyShadowCascades(value);
			}
			if (BoneFPSMod.OptParticleLimits.Value)
			{
				ApplyParticleLimits(value);
			}
			if (BoneFPSMod.OptOcclusionCulling.Value)
			{
				ApplyOcclusionCulling(value);
			}
			if (BoneFPSMod.OptStutterFix.Value)
			{
				ApplyStutterFix();
			}
			if (BoneFPSMod.OptMSAA.Value)
			{
				ApplyMSAA(value);
			}
			else
			{
				RestoreMSAA();
			}
			if (BoneFPSMod.OptSoftShadows.Value)
			{
				ApplySoftShadows();
			}
			if (BoneFPSMod.OptPixelLightCount.Value)
			{
				ApplyPixelLightCount(value);
			}
			else
			{
				RestorePixelLightCount();
			}
			if (BoneFPSMod.OptAsyncUpload.Value)
			{
				ApplyAsyncUpload();
			}
			ApplyBasicSettings(value);
		}

		public void RestoreShadowDistance()
		{
			//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)
			if (!_savedOriginals)
			{
				return;
			}
			try
			{
				QualitySettings.shadowDistance = _origShadowDistance;
				QualitySettings.shadows = _origShadowQuality;
				QualitySettings.shadowResolution = _origShadowResolution;
			}
			catch
			{
			}
		}

		private void RestoreMSAA()
		{
			if (!_savedOriginals)
			{
				return;
			}
			try
			{
				QualitySettings.antiAliasing = _origAntiAliasing;
			}
			catch
			{
			}
		}

		private void RestorePixelLightCount()
		{
			if (!_savedOriginals)
			{
				return;
			}
			try
			{
				QualitySettings.pixelLightCount = _origPixelLightCount;
			}
			catch
			{
			}
		}

		private void ApplyLODBias(int level)
		{
			try
			{
				QualitySettings.lodBias = (new float[4] { 1.5f, 1.2f, 0.9f, 0.6f })[Mathf.Clamp(level, 0, 3)];
			}
			catch
			{
			}
		}

		private void ApplyShadowDistance(int level)
		{
			try
			{
				QualitySettings.shadowDistance = (new float[4] { 80f, 55f, 35f, 20f })[Mathf.Clamp(level, 0, 3)];
				QualitySettings.shadows = (ShadowQuality)1;
				QualitySettings.shadowResolution = (new ShadowResolution[4]
				{
					(ShadowResolution)1,
					(ShadowResolution)1,
					default(ShadowResolution),
					default(ShadowResolution)
				})[Mathf.Clamp(level, 0, 3)];
			}
			catch
			{
			}
		}

		private void ApplyShadowCascades(int level)
		{
			try
			{
				QualitySettings.shadowCascades = (new int[4] { 2, 2, 1, 1 })[Mathf.Clamp(level, 0, 3)];
			}
			catch
			{
			}
		}

		private void ApplyParticleLimits(int level)
		{
			try
			{
				Il2CppArrayBase<ParticleSystem> val = Object.FindObjectsOfType<ParticleSystem>(true);
				if (val == null)
				{
					return;
				}
				foreach (ParticleSystem item in val)
				{
					if (!IsValid((Object)(object)item))
					{
						continue;
					}
					try
					{
						MainModule main = item.main;
						int num = (new int[4] { 1000, 500, 250, 100 })[Mathf.Clamp(level, 0, 3)];
						if (main.maxParticles > num)
						{
							main.maxParticles = num;
						}
						if (level >= 2)
						{
							ParticleSystemRenderer component = ((Component)item).GetComponent<ParticleSystemRenderer>();
							if (IsValid((Object)(object)component))
							{
								((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
								((Renderer)component).receiveShadows = false;
							}
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private void ApplyOcclusionCulling(int level)
		{
			try
			{
				Il2CppArrayBase<Camera> val = Object.FindObjectsOfType<Camera>(true);
				if (val == null)
				{
					return;
				}
				foreach (Camera item in val)
				{
					if (!IsValid((Object)(object)item))
					{
						continue;
					}
					try
					{
						item.useOcclusionCulling = true;
						item.layerCullSpherical = true;
						if (level >= 3)
						{
							item.farClipPlane = Mathf.Min(item.farClipPlane, 300f);
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private void ApplyStutterFix()
		{
			try
			{
				Shader.WarmupAllShaders();
			}
			catch
			{
			}
		}

		private void ApplyMSAA(int level)
		{
			try
			{
				if (level >= 2)
				{
					QualitySettings.antiAliasing = 0;
				}
				else if (level >= 1)
				{
					QualitySettings.antiAliasing = 2;
				}
				RenderPipelineAsset uRPAsset = GetURPAsset();
				if ((Object)(object)uRPAsset != (Object)null)
				{
					int num = ((level >= 2) ? 1 : ((level >= 1) ? 2 : 4));
					SetField(uRPAsset, "m_MSAA", num);
				}
			}
			catch
			{
			}
		}

		private void ApplySoftShadows()
		{
			try
			{
				RenderPipelineAsset uRPAsset = GetURPAsset();
				if ((Object)(object)uRPAsset != (Object)null)
				{
					SetField(uRPAsset, "m_SoftShadowsSupported", false);
				}
			}
			catch
			{
			}
		}

		private void ApplyPixelLightCount(int level)
		{
			try
			{
				QualitySettings.pixelLightCount = (new int[4] { 4, 3, 2, 1 })[Mathf.Clamp(level, 0, 3)];
			}
			catch
			{
			}
		}

		private void ApplyAsyncUpload()
		{
			try
			{
				QualitySettings.asyncUploadTimeSlice = 4;
				QualitySettings.asyncUploadBufferSize = 16;
				QualitySettings.asyncUploadPersistentBuffer = true;
			}
			catch
			{
			}
		}

		private void ApplyBasicSettings(int level)
		{
			try
			{
				QualitySettings.softParticles = level < 2;
			}
			catch
			{
			}
			try
			{
				QualitySettings.anisotropicFiltering = (AnisotropicFiltering)1;
			}
			catch
			{
			}
			try
			{
				RenderPipelineAsset uRPAsset = GetURPAsset();
				if ((Object)(object)uRPAsset != (Object)null)
				{
					SetField(uRPAsset, "m_UseSRPBatcher", true);
				}
			}
			catch
			{
			}
		}

		public RenderPipelineAsset GetURPAsset()
		{
			RenderPipelineAsset val = null;
			try
			{
				val = GraphicsSettings.currentRenderPipeline;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				try
				{
					val = QualitySettings.renderPipeline;
				}
				catch
				{
				}
			}
			return val;
		}

		public void SetField(object obj, string fieldName, object value)
		{
			if (obj == null)
			{
				return;
			}
			try
			{
				Type type = obj.GetType();
				FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(obj, value);
					return;
				}
				PropertyInfo property = type.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite)
				{
					property.SetValue(obj, value);
				}
			}
			catch
			{
			}
		}

		public float GetFieldFloat(object obj, string fieldName, float defaultVal)
		{
			if (obj == null)
			{
				return defaultVal;
			}
			try
			{
				Type type = obj.GetType();
				FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object value = field.GetValue(obj);
					if (value != null)
					{
						return (float)value;
					}
				}
				PropertyInfo property = type.GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanRead)
				{
					object value2 = property.GetValue(obj);
					if (value2 != null)
					{
						return (float)value2;
					}
				}
			}
			catch
			{
			}
			return defaultVal;
		}

		private bool IsValid(Object obj)
		{
			try
			{
				return obj != (Object)null && Object.op_Implicit(obj);
			}
			catch
			{
				return false;
			}
		}
	}
	public class RenderOptimizer
	{
		private struct ShadowRendererData
		{
			public Renderer renderer;

			public Transform transform;

			public ShadowCastingMode origShadow;

			public bool origReceiveShadow;

			public bool shadowDisabled;
		}

		private struct AnimData
		{
			public Animator animator;

			public Transform transform;

			public bool origEnabled;

			public bool isThrottled;

			public bool isCharacter;
		}

		private struct LightData
		{
			public Light light;

			public Transform transform;

			public bool origEnabled;

			public LightShadows origShadows;

			public LightRenderMode origRenderMode;

			public bool isCharacterLight;

			public int tier;
		}

		private struct CameraData
		{
			public Camera camera;

			public Transform transform;

			public bool origEnabled;

			public bool isDisabled;
		}

		private struct ParticleData
		{
			public ParticleSystem ps;

			public Transform transform;

			public bool isPaused;
		}

		private struct TrailData
		{
			public TrailRenderer trail;

			public Transform transform;

			public bool origEnabled;

			public bool isDisabled;
		}

		private struct LODData
		{
			public LODGroup lodGroup;

			public Transform transform;

			public int lodCount;

			public int forcedLevel;
		}

		private readonly BoneFPSMod _mod;

		private Camera _mainCam;

		private float _camSearchTimer;

		private readonly List<ShadowRendererData> _shadowRenderers = new List<ShadowRendererData>();

		private readonly List<AnimData> _trackedAnims = new List<AnimData>();

		private readonly List<LightData> _trackedLights = new List<LightData>();

		private readonly List<CameraData> _trackedCameras = new List<CameraData>();

		private readonly List<ParticleData> _trackedParticles = new List<ParticleData>();

		private readonly List<TrailData> _trackedTrails = new List<TrailData>();

		private readonly List<LODData> _trackedLODs = new List<LODData>();

		private float _shadowCullTimer;

		private float _animTimer;

		private int _animFrameCounter;

		private float _lightTimer;

		private float _cameraTimer;

		private float _particleTimer;

		private float _trailTimer;

		private float _lodTimer;

		private float _adaptiveShadowTimer;

		private bool _cachesBuilt;

		public RenderOptimizer(BoneFPSMod mod)
		{
			_mod = mod;
		}

		private bool IsAlive(Object obj)
		{
			try
			{
				if (obj == (Object)null)
				{
					return false;
				}
				if (!Object.op_Implicit(obj))
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private bool IsTransformAlive(Transform t)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)t == (Object)null)
				{
					return false;
				}
				if (!Object.op_Implicit((Object)(object)t))
				{
					return false;
				}
				_ = t.position;
				return true;
			}
			catch
			{
				return false;
			}
		}

		private float SafeDistance(Transform t, Vector3 camPos)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsTransformAlive(t))
				{
					return float.MaxValue;
				}
				return Vector3.Distance(t.position, camPos);
			}
			catch
			{
				return float.MaxValue;
			}
		}

		private bool HasSkinnedMeshInHierarchy(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			try
			{
				SkinnedMeshRenderer component = go.GetComponent<SkinnedMeshRenderer>();
				if (IsAlive((Object)(object)component))
				{
					return true;
				}
				Transform transform = go.transform;
				if (!IsTransformAlive(transform))
				{
					return false;
				}
				for (int i = 0; i < transform.childCount && i < 10; i++)
				{
					try
					{
						Transform child = transform.GetChild(i);
						if (IsTransformAlive(child))
						{
							component = ((Component)child).GetComponent<SkinnedMeshRenderer>();
							if (IsAlive((Object)(object)component))
							{
								return true;
							}
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private bool IsCharacterRenderer(Renderer r)
		{
			if ((Object)(object)r == (Object)null)
			{
				return false;
			}
			try
			{
				if (r is SkinnedMeshRenderer)
				{
					return true;
				}
				string text = ((Object)((Component)r).gameObject).name.ToLower();
				if (text.Contains("hair") || text.Contains("head") || text.Contains("body") || text.Contains("hand") || text.Contains("foot") || text.Contains("feet") || text.Contains("leg") || text.Contains("arm") || text.Contains("torso") || text.Contains("chest") || text.Contains("pelvis") || text.Contains("spine") || text.Contains("eye") || text.Contains("face") || text.Contains("weapon") || text.Contains("gun"))
				{
					return true;
				}
				Transform parent = ((Component)r).transform.parent;
				if (IsTransformAlive(parent) && HasSkinnedMeshInHierarchy(((Component)parent).gameObject))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private bool IsCharacterLight(Light light)
		{
			if ((Object)(object)light == (Object)null)
			{
				return false;
			}
			try
			{
				string text = ((Object)((Component)light).gameObject).name.ToLower();
				if (text.Contains("hair") || text.Contains("head") || text.Contains("face") || text.Contains("eye") || text.Contains("character") || text.Contains("npc") || text.Contains("ford") || text.Contains("avatar") || text.Contains("body") || text.Contains("rim") || text.Contains("fill") || text.Contains("key"))
				{
					return true;
				}
				Transform parent = ((Component)light).transform.parent;
				int num = 0;
				while ((Object)(object)parent != (Object)null && num < 5)
				{
					try
					{
						if (!IsTransformAlive(parent))
						{
							break;
						}
						if (HasSkinnedMeshInHierarchy(((Component)parent).gameObject))
						{
							return true;
						}
						string text2 = ((Object)((Component)parent).gameObject).name.ToLower();
						if (text2.Contains("character") || text2.Contains("npc") || text2.Contains("ford") || text2.Contains("avatar") || text2.Contains("head") || text2.Contains("hair") || text2.Contains("body"))
						{
							return true;
						}
						parent = parent.parent;
						num++;
						continue;
					}
					catch
					{
					}
					break;
				}
			}
			catch
			{
			}
			return false;
		}

		private bool IsCharacterAnimator(Animator anim)
		{
			if ((Object)(object)anim == (Object)null)
			{
				return false;
			}
			try
			{
				if (HasSkinnedMeshInHierarchy(((Component)anim).gameObject))
				{
					return true;
				}
				try
				{
					Transform transform = ((Component)anim).transform;
					if (IsTransformAlive(transform))
					{
						for (int i = 0; i < transform.childCount && i < 15; i++)
						{
							try
							{
								Transform child = transform.GetChild(i);
								if (!IsTransformAlive(child) || !HasSkinnedMeshInHierarchy(((Component)child).gameObject))
								{
									continue;
								}
								return true;
							}
							catch
							{
							}
						}
					}
				}
				catch
				{
				}
				try
				{
					PropertyInfo property = ((object)anim).GetType().GetProperty("isHuman");
					if (property != null)
					{
						object value = property.GetValue(anim);
						if (value != null && (bool)value)
						{
							return true;
						}
					}
				}
				catch
				{
				}
				string text = ((Object)((Component)anim).gameObject).name.ToLower();
				if (text.Contains("npc") || text.Contains("enemy") || text.Contains("ford") || text.Contains("avatar") || text.Contains("player") || text.Contains("character") || text.Contains("nullbody") || text.Contains("crablet") || text.Contains("skeleton") || text.Contains("omni") || text.Contains("body") || text.Contains("humanoid") || text.Contains("rig") || text.Contains("puppet"))
				{
					return true;
				}
				Transform parent = ((Component)anim).transform.parent;
				int num = 0;
				while ((Object)(object)parent != (Object)null && num < 5)
				{
					try
					{
						if (!IsTransformAlive(parent))
						{
							break;
						}
						string text2 = ((Object)((Component)parent).gameObject).name.ToLower();
						if (text2.Contains("npc") || text2.Contains("enemy") || text2.Contains("ford") || text2.Contains("avatar") || text2.Contains("player") || text2.Contains("character") || text2.Contains("nullbody") || text2.Contains("body") || text2.Contains("rig") || text2.Contains("puppet"))
						{
							return true;
						}
						parent = parent.parent;
						num++;
						continue;
					}
					catch
					{
					}
					break;
				}
			}
			catch
			{
			}
			return false;
		}

		public void OnSceneChanged()
		{
			ClearAllCaches();
			_mainCam = null;
			_cachesBuilt = false;
		}

		public void ApplyAllRenderOptimizations()
		{
			BuildAllCaches();
			_cachesBuilt = true;
		}

		private void ClearAllCaches()
		{
			_shadowRenderers.Clear();
			_trackedAnims.Clear();
			_trackedLights.Clear();
			_trackedCameras.Clear();
			_trackedParticles.Clear();
			_trackedTrails.Clear();
			_trackedLODs.Clear();
		}

		private void BuildAllCaches()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Invalid comparison between Unknown and I4
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			((MelonBase)_mod).LoggerInstance.Msg("[BoneFPS] Building caches...");
			ClearAllCaches();
			try
			{
				Il2CppArrayBase<Renderer> val = Object.FindObjectsOfType<Renderer>(true);
				if (val != null)
				{
					foreach (Renderer item in val)
					{
						if (!IsAlive((Object)(object)item))
						{
							continue;
						}
						try
						{
							if ((int)item.shadowCastingMode != 0 && item.enabled)
							{
								Transform transform = ((Component)item).transform;
								if (IsTransformAlive(transform) && !IsCharacterRenderer(item))
								{
									_shadowRenderers.Add(new ShadowRendererData
									{
										renderer = item,
										transform = transform,
										origShadow = item.shadowCastingMode,
										origReceiveShadow = item.receiveShadows,
										shadowDisabled = false
									});
								}
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Shadow renderers (env only): " + _shadowRenderers.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Animator> val2 = Object.FindObjectsOfType<Animator>(true);
				if (val2 != null)
				{
					foreach (Animator item2 in val2)
					{
						if (!IsAlive((Object)(object)item2))
						{
							continue;
						}
						try
						{
							Transform transform2 = ((Component)item2).transform;
							if (IsTransformAlive(transform2))
							{
								_trackedAnims.Add(new AnimData
								{
									animator = item2,
									transform = transform2,
									origEnabled = ((Behaviour)item2).enabled,
									isThrottled = false,
									isCharacter = IsCharacterAnimator(item2)
								});
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Animators: " + _trackedAnims.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Light> val3 = Object.FindObjectsOfType<Light>(true);
				if (val3 != null)
				{
					foreach (Light item3 in val3)
					{
						if (!IsAlive((Object)(object)item3))
						{
							continue;
						}
						try
						{
							if ((int)item3.type != 1)
							{
								Transform transform3 = ((Component)item3).transform;
								if (IsTransformAlive(transform3))
								{
									_trackedLights.Add(new LightData
									{
										light = item3,
										transform = transform3,
										origEnabled = ((Behaviour)item3).enabled,
										origShadows = item3.shadows,
										origRenderMode = item3.renderMode,
										isCharacterLight = IsCharacterLight(item3),
										tier = 0
									});
								}
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Lights: " + _trackedLights.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Camera> val4 = Object.FindObjectsOfType<Camera>(true);
				if (val4 != null)
				{
					foreach (Camera item4 in val4)
					{
						if (!IsAlive((Object)(object)item4))
						{
							continue;
						}
						try
						{
							GameObject gameObject = ((Component)item4).gameObject;
							if (!IsAlive((Object)(object)gameObject))
							{
								continue;
							}
							string text = ((Object)gameObject).name.ToLower();
							if (text.Contains("mirror") || text.Contains("reflection") || text.Contains("security") || text.Contains("monitor") || text.Contains("screen") || text.Contains("preview") || (Object)(object)item4.targetTexture != (Object)null)
							{
								Transform transform4 = ((Component)item4).transform;
								if (IsTransformAlive(transform4))
								{
									_trackedCameras.Add(new CameraData
									{
										camera = item4,
										transform = transform4,
										origEnabled = ((Behaviour)item4).enabled,
										isDisabled = false
									});
								}
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Cameras: " + _trackedCameras.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<ParticleSystem> val5 = Object.FindObjectsOfType<ParticleSystem>(true);
				if (val5 != null)
				{
					foreach (ParticleSystem item5 in val5)
					{
						if (!IsAlive((Object)(object)item5))
						{
							continue;
						}
						try
						{
							Transform transform5 = ((Component)item5).transform;
							if (IsTransformAlive(transform5))
							{
								_trackedParticles.Add(new ParticleData
								{
									ps = item5,
									transform = transform5,
									isPaused = false
								});
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Particles: " + _trackedParticles.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<TrailRenderer> val6 = Object.FindObjectsOfType<TrailRenderer>(true);
				if (val6 != null)
				{
					foreach (TrailRenderer item6 in val6)
					{
						if (!IsAlive((Object)(object)item6))
						{
							continue;
						}
						try
						{
							Transform transform6 = ((Component)item6).transform;
							if (IsTransformAlive(transform6))
							{
								_trackedTrails.Add(new TrailData
								{
									trail = item6,
									transform = transform6,
									origEnabled = ((Renderer)item6).enabled,
									isDisabled = false
								});
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  Trails: " + _trackedTrails.Count);
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<LODGroup> val7 = Object.FindObjectsOfType<LODGroup>(true);
				if (val7 != null)
				{
					foreach (LODGroup item7 in val7)
					{
						if (!IsAlive((Object)(object)item7))
						{
							continue;
						}
						try
						{
							Transform transform7 = ((Component)item7).transform;
							if (IsTransformAlive(transform7))
							{
								int lodCount = item7.lodCount;
								if (lodCount > 0)
								{
									_trackedLODs.Add(new LODData
									{
										lodGroup = item7,
										transform = transform7,
										lodCount = lodCount,
										forcedLevel = -1
									});
								}
							}
						}
						catch
						{
						}
					}
				}
				((MelonBase)_mod).LoggerInstance.Msg("  LODs: " + _trackedLODs.Count);
			}
			catch
			{
			}
			((MelonBase)_mod).LoggerInstance.Msg("[BoneFPS] Cache complete!");
		}

		public void UpdateDynamicSystems(float currentFPS)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (!_cachesBuilt)
			{
				return;
			}
			_camSearchTimer += Time.unscaledDeltaTime;
			if ((Object)(object)_mainCam == (Object)null || !IsAlive((Object)(object)_mainCam))
			{
				_mainCam = null;
				if (_camSearchTimer > 1.5f)
				{
					_camSearchTimer = 0f;
					try
					{
						_mainCam = Camera.main;
					}
					catch
					{
					}
				}
				if ((Object)(object)_mainCam == (Object)null)
				{
					return;
				}
			}
			Vector3 position;
			try
			{
				if (!IsAlive((Object)(object)_mainCam))
				{
					_mainCam = null;
					return;
				}
				Transform transform = ((Component)_mainCam).transform;
				if (!IsTransformAlive(transform))
				{
					_mainCam = null;
					return;
				}
				position = transform.position;
			}
			catch
			{
				_mainCam = null;
				return;
			}
			if (BoneFPSMod.OptDistanceShadowCull.Value)
			{
				try
				{
					UpdateDistanceShadowCulling(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptAnimThrottle.Value)
			{
				try
				{
					UpdateAnimThrottle(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptLightCulling.Value)
			{
				try
				{
					UpdateLightCulling(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptCameraCulling.Value)
			{
				try
				{
					UpdateCameraCulling(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptParticleDistPause.Value)
			{
				try
				{
					UpdateParticleDistPause(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptTrailCull.Value)
			{
				try
				{
					UpdateTrailCull(position);
				}
				catch
				{
				}
			}
			if (BoneFPSMod.OptHybridLOD.Value)
			{
				try
				{
					UpdateHybridLOD(position);
				}
				catch
				{
				}
			}
			if (!BoneFPSMod.OptAdaptiveShadowDist.Value)
			{
				return;
			}
			try
			{
				UpdateAdaptiveShadowDistance(currentFPS);
			}
			catch
			{
			}
		}

		private void UpdateDistanceShadowCulling(Vector3 camPos)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			_shadowCullTimer += Time.unscaledDeltaTime;
			if (_shadowCullTimer < 0.3f)
			{
				return;
			}
			_shadowCullTimer = 0f;
			float shadowDistance = QualitySettings.shadowDistance;
			float num = shadowDistance * 0.75f;
			float num2 = shadowDistance * 1f;
			int value = BoneFPSMod.MaxShadowCasters.Value;
			List<KeyValuePair<int, float>> list = new List<KeyValuePair<int, float>>();
			for (int num3 = _shadowRenderers.Count - 1; num3 >= 0; num3--)
			{
				ShadowRendererData value2 = _shadowRenderers[num3];
				if (!IsAlive((Object)(object)value2.renderer) || !IsTransformAlive(value2.transform))
				{
					_shadowRenderers.RemoveAt(num3);
				}
				else
				{
					try
					{
						float num4 = SafeDistance(value2.transform, camPos);
						if (num4 == float.MaxValue)
						{
							_shadowRenderers.RemoveAt(num3);
						}
						else if (num4 < 5f)
						{
							if (value2.shadowDisabled)
							{
								value2.renderer.shadowCastingMode = value2.origShadow;
								value2.renderer.receiveShadows = value2.origReceiveShadow;
								value2.shadowDisabled = false;
								_shadowRenderers[num3] = value2;
							}
						}
						else if (num4 > num2)
						{
							if (!value2.shadowDisabled)
							{
								value2.renderer.shadowCastingMode = (ShadowCastingMode)0;
								value2.renderer.receiveShadows = false;
								value2.shadowDisabled = true;
								_shadowRenderers[num3] = value2;
							}
						}
						else if (num4 < num)
						{
							list.Add(new KeyValuePair<int, float>(num3, num4));
						}
					}
					catch
					{
						_shadowRenderers.RemoveAt(num3);
					}
				}
			}
			if (list.Count > value)
			{
				list.Sort((KeyValuePair<int, float> a, KeyValuePair<int, float> b) => a.Value.CompareTo(b.Value));
				for (int i = 0; i < list.Count; i++)
				{
					int key = list[i].Key;
					if (key >= _shadowRenderers.Count)
					{
						continue;
					}
					ShadowRendererData value3 = _shadowRenderers[key];
					if (!IsAlive((Object)(object)value3.renderer))
					{
						continue;
					}
					try
					{
						if (i < value)
						{
							if (value3.shadowDisabled)
							{
								value3.renderer.shadowCastingMode = value3.origShadow;
								value3.renderer.receiveShadows = value3.origReceiveShadow;
								value3.shadowDisabled = false;
								_shadowRenderers[key] = value3;
							}
						}
						else if (!value3.shadowDisabled)
						{
							value3.renderer.shadowCastingMode = (ShadowCastingMode)0;
							value3.shadowDisabled = true;
							_shadowRenderers[key] = value3;
						}
					}
					catch
					{
					}
				}
				return;
			}
			for (int j = 0; j < list.Count; j++)
			{
				int key2 = list[j].Key;
				if (key2 >= _shadowRenderers.Count)
				{
					continue;
				}
				ShadowRendererData value4 = _shadowRenderers[key2];
				if (!IsAlive((Object)(object)value4.renderer))
				{
					continue;
				}
				try
				{
					if (value4.shadowDisabled)
					{
						value4.renderer.shadowCastingMode = value4.origShadow;
						value4.renderer.receiveShadows = value4.origReceiveShadow;
						value4.shadowDisabled = false;
						_shadowRenderers[key2] = value4;
					}
				}
				catch
				{
				}
			}
		}

		private void UpdateAnimThrottle(Vector3 camPos)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			_animTimer += Time.unscaledDeltaTime;
			if (_animTimer < 0.25f)
			{
				return;
			}
			_animTimer = 0f;
			_animFrameCounter++;
			float value = BoneFPSMod.NearDist.Value;
			float value2 = BoneFPSMod.MidDist.Value;
			float value3 = BoneFPSMod.FarDist.Value;
			for (int num = _trackedAnims.Count - 1; num >= 0; num--)
			{
				AnimData value4 = _trackedAnims[num];
				if (!IsAlive((Object)(object)value4.animator) || !IsTransformAlive(value4.transform))
				{
					_trackedAnims.RemoveAt(num);
				}
				else
				{
					try
					{
						if (value4.isCharacter)
						{
							if (value4.isThrottled)
							{
								((Behaviour)value4.animator).enabled = value4.origEnabled;
								value4.isThrottled = false;
								_trackedAnims[num] = value4;
							}
						}
						else
						{
							float num2 = SafeDistance(value4.transform, camPos);
							if (num2 == float.MaxValue)
							{
								_trackedAnims.RemoveAt(num);
							}
							else if (num2 < value)
							{
								if (value4.isThrottled)
								{
									((Behaviour)value4.animator).enabled = value4.origEnabled;
									value4.isThrottled = false;
									_trackedAnims[num] = value4;
								}
							}
							else if (num2 < value2)
							{
								((Behaviour)value4.animator).enabled = value4.origEnabled && _animFrameCounter % 2 == 0;
								value4.isThrottled = true;
								_trackedAnims[num] = value4;
							}
							else if (num2 < value3)
							{
								((Behaviour)value4.animator).enabled = value4.origEnabled && _animFrameCounter % 4 == 0;
								value4.isThrottled = true;
								_trackedAnims[num] = value4;
							}
							else
							{
								((Behaviour)value4.animator).enabled = false;
								value4.isThrottled = true;
								_trackedAnims[num] = value4;
							}
						}
					}
					catch
					{
						_trackedAnims.RemoveAt(num);
					}
				}
			}
		}

		private void UpdateLightCulling(Vector3 camPos)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			_lightTimer += Time.unscaledDeltaTime;
			if (_lightTimer < 0.35f)
			{
				return;
			}
			_lightTimer = 0f;
			float value = BoneFPSMod.NearDist.Value;
			float value2 = BoneFPSMod.MidDist.Value;
			float value3 = BoneFPSMod.FarDist.Value;
			for (int num = _trackedLights.Count - 1; num >= 0; num--)
			{
				LightData value4 = _trackedLights[num];
				if (!IsAlive((Object)(object)value4.light) || !IsTransformAlive(value4.transform))
				{
					_trackedLights.RemoveAt(num);
				}
				else
				{
					try
					{
						if (value4.isCharacterLight)
						{
							if (!((Behaviour)value4.light).enabled && value4.origEnabled)
							{
								((Behaviour)value4.light).enabled = true;
							}
						}
						else
						{
							float num2 = SafeDistance(value4.transform, camPos);
							if (num2 == float.MaxValue)
							{
								_trackedLights.RemoveAt(num);
							}
							else
							{
								int num3 = ((!(num2 < value)) ? ((num2 < value2) ? 1 : ((!(num2 < value3)) ? 3 : 2)) : 0);
								if (num3 != value4.tier)
								{
									value4.tier = num3;
									switch (num3)
									{
									case 0:
										((Behaviour)value4.light).enabled = value4.origEnabled;
										value4.light.shadows = value4.origShadows;
										value4.light.renderMode = value4.origRenderMode;
										break;
									case 1:
										((Behaviour)value4.light).enabled = value4.origEnabled;
										value4.light.shadows = (LightShadows)0;
										value4.light.renderMode = (LightRenderMode)2;
										break;
									case 2:
										((Behaviour)value4.light).enabled = value4.origEnabled;
										value4.light.shadows = (LightShadows)0;
										value4.light.renderMode = (LightRenderMode)2;
										break;
									case 3:
										((Behaviour)value4.light).enabled = false;
										break;
									}
									_trackedLights[num] = value4;
								}
							}
						}
					}
					catch
					{
						_trackedLights.RemoveAt(num);
					}
				}
			}
		}

		private void UpdateCameraCulling(Vector3 camPos)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			_cameraTimer += Time.unscaledDeltaTime;
			if (_cameraTimer < 0.6f)
			{
				return;
			}
			_cameraTimer = 0f;
			float value = BoneFPSMod.MidDist.Value;
			float num = value * 0.7f;
			for (int num2 = _trackedCameras.Count - 1; num2 >= 0; num2--)
			{
				CameraData value2 = _trackedCameras[num2];
				if (!IsAlive((Object)(object)value2.camera) || !IsTransformAlive(value2.transform))
				{
					_trackedCameras.RemoveAt(num2);
				}
				else if (!((Object)(object)_mainCam != (Object)null) || !((Object)(object)value2.camera == (Object)(object)_mainCam))
				{
					try
					{
						float num3 = SafeDistance(value2.transform, camPos);
						if (num3 == float.MaxValue)
						{
							_trackedCameras.RemoveAt(num2);
						}
						else if (num3 > value && !value2.isDisabled)
						{
							((Behaviour)value2.camera).enabled = false;
							value2.isDisabled = true;
							_trackedCameras[num2] = value2;
						}
						else if (num3 < num && value2.isDisabled)
						{
							((Behaviour)value2.camera).enabled = value2.origEnabled;
							value2.isDisabled = false;
							_trackedCameras[num2] = value2;
						}
					}
					catch
					{
						_trackedCameras.RemoveAt(num2);
					}
				}
			}
		}

		private void UpdateParticleDistPause(Vector3 camPos)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			_particleTimer += Time.unscaledDeltaTime;
			if (_particleTimer < 0.5f)
			{
				return;
			}
			_particleTimer = 0f;
			float value = BoneFPSMod.FarDist.Value;
			float num = value * 0.7f;
			for (int num2 = _trackedParticles.Count - 1; num2 >= 0; num2--)
			{
				ParticleData value2 = _trackedParticles[num2];
				if (!IsAlive((Object)(object)value2.ps) || !IsTransformAlive(value2.transform))
				{
					_trackedParticles.RemoveAt(num2);
				}
				else
				{
					try
					{
						float num3 = SafeDistance(value2.transform, camPos);
						if (num3 == float.MaxValue)
						{
							_trackedParticles.RemoveAt(num2);
						}
						else if (num3 > value && !value2.isPaused)
						{
							value2.ps.Pause();
							value2.isPaused = true;
							_trackedParticles[num2] = value2;
						}
						else if (num3 < num && value2.isPaused)
						{
							value2.ps.Play();
							value2.isPaused = false;
							_trackedParticles[num2] = value2;
						}
					}
					catch
					{
						_trackedParticles.RemoveAt(num2);
					}
				}
			}
		}

		private void UpdateTrailCull(Vector3 camPos)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			_trailTimer += Time.unscaledDeltaTime;
			if (_trailTimer < 0.5f)
			{
				return;
			}
			_trailTimer = 0f;
			float value = BoneFPSMod.FarDist.Value;
			float value2 = BoneFPSMod.NearDist.Value;
			for (int num = _trackedTrails.Count - 1; num >= 0; num--)
			{
				TrailData value3 = _trackedTrails[num];
				if (!IsAlive((Object)(object)value3.trail) || !IsTransformAlive(value3.transform))
				{
					_trackedTrails.RemoveAt(num);
				}
				else
				{
					try
					{
						float num2 = SafeDistance(value3.transform, camPos);
						if (num2 == float.MaxValue)
						{
							_trackedTrails.RemoveAt(num);
						}
						else if (num2 > value && !value3.isDisabled)
						{
							((Renderer)value3.trail).enabled = false;
							value3.isDisabled = true;
							_trackedTrails[num] = value3;
						}
						else if (num2 < value2 && value3.isDisabled)
						{
							((Renderer)value3.trail).enabled = value3.origEnabled;
							value3.isDisabled = false;
							_trackedTrails[num] = value3;
						}
					}
					catch
					{
						_trackedTrails.RemoveAt(num);
					}
				}
			}
		}

		private void UpdateHybridLOD(Vector3 camPos)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			_lodTimer += Time.unscaledDeltaTime;
			if (_lodTimer < 0.4f)
			{
				return;
			}
			_lodTimer = 0f;
			float value = BoneFPSMod.NearDist.Value;
			float value2 = BoneFPSMod.FarDist.Value;
			for (int num = _trackedLODs.Count - 1; num >= 0; num--)
			{
				LODData value3 = _trackedLODs[num];
				if (!IsAlive((Object)(object)value3.lodGroup) || !IsTransformAlive(value3.transform))
				{
					_trackedLODs.RemoveAt(num);
				}
				else
				{
					try
					{
						float num2 = SafeDistance(value3.transform, camPos);
						if (num2 == float.MaxValue)
						{
							_trackedLODs.RemoveAt(num);
						}
						else
						{
							int num3 = ((num2 < value) ? (-1) : ((!(num2 > value2)) ? Mathf.Clamp(Mathf.FloorToInt((num2 - value) / (value2 - value) * (float)value3.lodCount), 0, value3.lodCount - 1) : (value3.lodCount - 1)));
							if (num3 != value3.forcedLevel)
							{
								value3.forcedLevel = num3;
								value3.lodGroup.ForceLOD(num3);
								_trackedLODs[num] = value3;
							}
						}
					}
					catch
					{
						_trackedLODs.RemoveAt(num);
					}
				}
			}
		}

		private void UpdateAdaptiveShadowDistance(float fps)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			_adaptiveShadowTimer += Time.unscaledDeltaTime;
			if (_adaptiveShadowTimer < 3f)
			{
				return;
			}
			_adaptiveShadowTimer = 0f;
			if (fps <= 0f || !BoneFPSMod.OptShadowDistance.Value)
			{
				return;
			}
			int value = BoneFPSMod.PerfLevel.Value;
			float num = (new float[4] { 80f, 55f, 35f, 20f })[Mathf.Clamp(value, 0, 3)];
			try
			{
				if (fps > 72f)
				{
					QualitySettings.shadowDistance = num;
				}
				else if (fps > 55f)
				{
					QualitySettings.shadowDistance = num * 0.75f;
				}
				else if (fps > 40f)
				{
					QualitySettings.shadowDistance = num * 0.5f;
				}
				else
				{
					QualitySettings.shadowDistance = num * 0.3f;
				}
				if ((int)QualitySettings.shadows == 0)
				{
					QualitySettings.shadows = (ShadowQuality)1;
				}
			}
			catch
			{
			}
		}
	}
}