Decompiled source of Sleak v1.0.0

Sleak.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("Sleak")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sleak")]
[assembly: AssemblyTitle("Sleak")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Sleak
{
	[BepInPlugin("mod_ify.sleak", "Sleak", "1.0.0")]
	public class SleakPlugin : BaseUnityPlugin
	{
		private class RendererData
		{
			public Renderer renderer;

			public int instanceId;

			public bool originalEnabled;

			public bool hiddenBySleak;

			public bool distanceCulled;

			public bool offscreenCulled;

			public float offscreenSince;

			public int hiddenChecks;

			public ShadowCastingMode originalShadowMode;

			public bool shadowChanged;
		}

		private class TerrainSettings
		{
			public Terrain terrain;

			public float treeDistance;

			public float treeBillboardDistance;

			public float detailObjectDistance;

			public float detailObjectDensity;

			public int treeMaximumFullLODCount;
		}

		private class BehaviourData
		{
			public Behaviour component;

			public int instanceId;

			public bool originalEnabled;

			public bool disabledBySleak;
		}

		private class AnimatorData
		{
			public Animator animator;

			public int instanceId;

			public AnimatorCullingMode originalCullingMode;

			public bool cullingChanged;
		}

		private class ParticleData
		{
			public ParticleSystem particles;

			public int instanceId;

			public bool wasPlaying;

			public bool pausedBySleak;
		}

		private ConfigEntry<bool> enableOcclusionCulling;

		private ConfigEntry<bool> enableRendererDistanceCulling;

		private ConfigEntry<bool> enableOffscreenRendererCulling;

		private ConfigEntry<float> rendererMaxDistance;

		private ConfigEntry<bool> enableDistantParticles;

		private ConfigEntry<bool> enableDistantAnimatorCulling;

		private ConfigEntry<bool> enableDistantAudio;

		private ConfigEntry<bool> enableDistantLights;

		private ConfigEntry<float> functionalityDistance;

		private ConfigEntry<float> restoreDistance;

		private ConfigEntry<int> componentsPerCheck;

		private Camera mainCamera;

		private readonly List<RendererData> renderers = new List<RendererData>();

		private readonly Dictionary<int, RendererData> rendererLookup = new Dictionary<int, RendererData>();

		private readonly List<TerrainSettings> terrains = new List<TerrainSettings>();

		private readonly List<GameObject> scanRoots = new List<GameObject>();

		private readonly Stack<Transform> scanStack = new Stack<Transform>();

		private readonly List<Renderer> componentBuffer = new List<Renderer>(4);

		private readonly List<Behaviour> behaviourBuffer = new List<Behaviour>(4);

		private readonly List<Animator> animatorBuffer = new List<Animator>(2);

		private readonly List<ParticleSystem> particleBuffer = new List<ParticleSystem>(2);

		private readonly List<BehaviourData> behaviours = new List<BehaviourData>();

		private readonly Dictionary<int, BehaviourData> behaviourLookup = new Dictionary<int, BehaviourData>();

		private readonly List<AnimatorData> animators = new List<AnimatorData>();

		private readonly Dictionary<int, AnimatorData> animatorLookup = new Dictionary<int, AnimatorData>();

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

		private readonly Dictionary<int, ParticleData> particleLookup = new Dictionary<int, ParticleData>();

		private readonly Plane[] frustumPlanes = (Plane[])(object)new Plane[6];

		private readonly List<RendererData> visibleRendererPriority = new List<RendererData>();

		private readonly List<RendererData> offscreenRendererPriority = new List<RendererData>();

		private float nextRefresh;

		private float nextCameraCheck;

		private float nextGraphicsCheck;

		private float nextRendererCheck;

		private float nextFunctionalityCheck;

		private float nextStatsLog;

		private float nextPriorityRefresh;

		private int scanIndex;

		private int visiblePriorityIndex;

		private int offscreenPriorityIndex;

		private int prioritySlot;

		private int functionalityIndex;

		private bool scanActive;

		private bool showStatusPanel = false;

		private bool showStatusDetails = true;

		private string lastAction = "Starting up";

		private float lastActionTime;

		private float fpsSmoothed;

		private float nextFpsUpdate;

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

		private float fpsHistorySum;

		private GUIStyle panelStyle;

		private GUIStyle headingStyle;

		private GUIStyle bodyStyle;

		private GUIStyle mutedStyle;

		private GUIStyle buttonStyle;

		private int checkedObjects;

		private int raycastCount;

		private int hiddenCount;

		private int scanTransformCount;

		private int disabledBehaviourCount;

		private int pausedParticleCount;

		private int culledAnimatorCount;

		private float originalLodBias;

		private float originalShadowDistance;

		private ShadowResolution originalShadowResolution;

		private bool originalStreamingMipmapsActive;

		private float originalStreamingMipmapsMemoryBudget;

		private bool settingsSaved;

		private const float RefreshInterval = 3f;

		private const float CameraCheckInterval = 0.5f;

		private const float GraphicsCheckInterval = 30f;

		private const float RendererCheckInterval = 0.05f;

		private const float PriorityRefreshInterval = 0.25f;

		private const float OffscreenCullDelay = 1.5f;

		private const float StatsLogInterval = 30f;

		private const float ShadowDistance = 45f;

		private const int ObjectsPerCheck = 24;

		private const int TransformsPerFrame = 200;

		private const int RequiredHiddenChecks = 3;

		private const float HideThreshold = 0.8f;

		private const float ShowThreshold = 0.4f;

		private const float TerrainTreeDistance = 180f;

		private const float TerrainBillboardDistance = 60f;

		private const float TerrainDetailDistance = 40f;

		private const float TerrainDetailDensity = 0.5f;

		private const int TerrainFullLODCount = 15;

		private void Awake()
		{
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			enableOcclusionCulling = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableOcclusionCulling", false, "Enables raycast-based occlusion culling.");
			enableRendererDistanceCulling = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableRendererDistanceCulling", true, "Disables mesh renderers beyond the configured distance and restores them when nearby.");
			rendererMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "RendererMaxDistance", 180f, "Maximum distance in world units for mesh rendering. Lower values improve performance but hide distant scenery.");
			enableOffscreenRendererCulling = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableOffscreenRendererCulling", true, "Slowly disables renderers outside the camera view and restores them quickly when they become visible. Set false if scenery or gameplay objects disappear unexpectedly.");
			enableDistantParticles = ((BaseUnityPlugin)this).Config.Bind<bool>("DistanceOptimization", "DisableDistantParticles", true, "Pauses distant particle systems and resumes them when nearby.");
			enableDistantAnimatorCulling = ((BaseUnityPlugin)this).Config.Bind<bool>("DistanceOptimization", "CullDistantAnimations", true, "Uses complete animator culling for distant animated objects.");
			enableDistantAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("DistanceOptimization", "DisableDistantAudio", false, "Disables distant audio sources. May affect positional audio.");
			enableDistantLights = ((BaseUnityPlugin)this).Config.Bind<bool>("DistanceOptimization", "DisableDistantLights", false, "Disables distant lights. Keep disabled if distant lights are important.");
			functionalityDistance = ((BaseUnityPlugin)this).Config.Bind<float>("DistanceOptimization", "DisableDistance", 150f, "Distance beyond which eligible components are optimized.");
			restoreDistance = ((BaseUnityPlugin)this).Config.Bind<float>("DistanceOptimization", "RestoreDistance", 120f, "Distance at which optimized components are restored.");
			componentsPerCheck = ((BaseUnityPlugin)this).Config.Bind<int>("DistanceOptimization", "ComponentsPerCheck", 50, "Maximum distance-optimization entries checked per interval.");
			originalLodBias = QualitySettings.lodBias;
			originalShadowDistance = QualitySettings.shadowDistance;
			originalShadowResolution = QualitySettings.shadowResolution;
			originalStreamingMipmapsActive = QualitySettings.streamingMipmapsActive;
			originalStreamingMipmapsMemoryBudget = QualitySettings.streamingMipmapsMemoryBudget;
			settingsSaved = true;
			ApplyGraphicsSettings();
			RefreshTerrains();
			BeginRendererScan();
			nextRefresh = Time.unscaledTime + 3f;
			nextStatsLog = Time.unscaledTime + 30f;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sleak 1.0.0 loaded.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Incremental world scanning enabled.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Distance-based particle and animation optimization enabled.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Distant audio optimization: " + enableDistantAudio.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Distant light optimization: " + enableDistantLights.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Occlusion culling enabled: " + enableOcclusionCulling.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Renderer distance culling: " + enableRendererDistanceCulling.Value + " (range: " + rendererMaxDistance.Value + ")"));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Graphics, terrain, LOD and texture streaming optimization enabled.");
		}

		private void ApplyGraphicsSettings()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			QualitySettings.lodBias = Mathf.Min(originalLodBias, 0.65f);
			QualitySettings.shadowDistance = Mathf.Min(originalShadowDistance, 45f);
			if ((int)QualitySettings.shadowResolution > 1)
			{
				QualitySettings.shadowResolution = (ShadowResolution)1;
			}
			QualitySettings.streamingMipmapsActive = true;
			QualitySettings.streamingMipmapsMemoryBudget = 384f;
		}

		private void Update()
		{
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_066b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0670: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			if (Input.GetKeyDown((KeyCode)284))
			{
				showStatusPanel = !showStatusPanel;
				lastAction = (showStatusPanel ? "Status panel shown" : "Status panel hidden");
				lastActionTime = unscaledTime;
			}
			if (unscaledTime >= nextFpsUpdate)
			{
				nextFpsUpdate = unscaledTime + 0.25f;
				float num = 1f / Mathf.Max(Time.unscaledDeltaTime, 0.0001f);
				fpsSmoothed = ((fpsSmoothed <= 0f) ? num : Mathf.Lerp(fpsSmoothed, num, 0.25f));
				fpsHistory.Enqueue(num);
				fpsHistorySum += num;
				while (fpsHistory.Count > 120)
				{
					fpsHistorySum -= fpsHistory.Dequeue();
				}
			}
			if (unscaledTime >= nextCameraCheck)
			{
				nextCameraCheck = unscaledTime + 0.5f;
				mainCamera = Camera.main;
			}
			if (unscaledTime >= nextGraphicsCheck)
			{
				nextGraphicsCheck = unscaledTime + 30f;
				ApplyGraphicsSettings();
			}
			if (unscaledTime >= nextRefresh && !scanActive)
			{
				nextRefresh = unscaledTime + 3f;
				BeginRendererScan();
				RefreshTerrains();
			}
			ProcessRendererScan();
			if (unscaledTime >= nextStatsLog)
			{
				nextStatsLog = unscaledTime + 30f;
				LogPerformanceStats();
			}
			if ((Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			if (unscaledTime >= nextFunctionalityCheck)
			{
				nextFunctionalityCheck = unscaledTime + 0.05f;
				ProcessDistantComponents();
			}
			if (unscaledTime < nextRendererCheck)
			{
				return;
			}
			nextRendererCheck = unscaledTime + 0.05f;
			if (renderers.Count == 0)
			{
				return;
			}
			GeometryUtility.CalculateFrustumPlanes(mainCamera, frustumPlanes);
			if (unscaledTime >= nextPriorityRefresh)
			{
				RefreshRendererPriority(unscaledTime);
			}
			Vector3 position = ((Component)mainCamera).transform.position;
			int num2 = 0;
			while (num2 < 24 && renderers.Count > 0)
			{
				RendererData nextPriorityRenderer = GetNextPriorityRenderer();
				if (nextPriorityRenderer == null)
				{
					break;
				}
				num2++;
				checkedObjects++;
				Renderer renderer = nextPriorityRenderer.renderer;
				if ((Object)(object)renderer == (Object)null)
				{
					continue;
				}
				if (!((Component)renderer).gameObject.activeInHierarchy)
				{
					Restore(nextPriorityRenderer);
					RestoreShadows(nextPriorityRenderer);
					if (nextPriorityRenderer.distanceCulled || nextPriorityRenderer.offscreenCulled)
					{
						renderer.enabled = nextPriorityRenderer.originalEnabled;
						nextPriorityRenderer.distanceCulled = false;
						nextPriorityRenderer.offscreenCulled = false;
						nextPriorityRenderer.offscreenSince = 0f;
					}
					nextPriorityRenderer.hiddenChecks = 0;
				}
				else
				{
					if (!nextPriorityRenderer.originalEnabled)
					{
						continue;
					}
					Bounds bounds = renderer.bounds;
					Vector3 val = ((Bounds)(ref bounds)).center - position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					OptimizeShadows(nextPriorityRenderer, sqrMagnitude);
					bounds = renderer.bounds;
					Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(position);
					Vector3 val3 = val2 - position;
					float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude;
					float num3 = Mathf.Max(0f, rendererMaxDistance.Value);
					float num4 = num3 * num3;
					if (enableRendererDistanceCulling.Value && sqrMagnitude2 > num4)
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						if (!nextPriorityRenderer.distanceCulled)
						{
							renderer.enabled = false;
							nextPriorityRenderer.distanceCulled = true;
							nextPriorityRenderer.offscreenCulled = false;
							nextPriorityRenderer.offscreenSince = 0f;
							lastAction = "Culled distant renderer";
							lastActionTime = Time.unscaledTime;
						}
						continue;
					}
					if (nextPriorityRenderer.distanceCulled)
					{
						renderer.enabled = nextPriorityRenderer.originalEnabled;
						nextPriorityRenderer.distanceCulled = false;
						nextPriorityRenderer.offscreenSince = 0f;
						lastAction = "Restored nearby renderer";
						lastActionTime = Time.unscaledTime;
					}
					bool flag = GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds);
					if (!enableOffscreenRendererCulling.Value)
					{
						nextPriorityRenderer.offscreenSince = 0f;
						if (nextPriorityRenderer.offscreenCulled)
						{
							renderer.enabled = nextPriorityRenderer.originalEnabled;
							nextPriorityRenderer.offscreenCulled = false;
						}
					}
					else if (flag)
					{
						nextPriorityRenderer.offscreenSince = 0f;
						if (nextPriorityRenderer.offscreenCulled)
						{
							Restore(nextPriorityRenderer);
							renderer.enabled = nextPriorityRenderer.originalEnabled;
							nextPriorityRenderer.offscreenCulled = false;
							lastAction = "Restored visible renderer";
							lastActionTime = Time.unscaledTime;
						}
					}
					else if (!nextPriorityRenderer.distanceCulled && !nextPriorityRenderer.offscreenCulled)
					{
						if (nextPriorityRenderer.offscreenSince <= 0f)
						{
							nextPriorityRenderer.offscreenSince = unscaledTime;
						}
						else if (unscaledTime - nextPriorityRenderer.offscreenSince >= 1.5f)
						{
							renderer.enabled = false;
							nextPriorityRenderer.offscreenCulled = true;
							lastAction = "Culled offscreen renderer";
							lastActionTime = unscaledTime;
						}
					}
					if (nextPriorityRenderer.offscreenCulled)
					{
						Restore(nextPriorityRenderer);
						renderer.enabled = false;
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					if (!enableOcclusionCulling.Value)
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					if (sqrMagnitude > 10000f)
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					if (!GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds))
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					bounds = renderer.bounds;
					val3 = ((Bounds)(ref bounds)).size;
					if (((Vector3)(ref val3)).sqrMagnitude > 6400f)
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					int totalSamples;
					int num5 = CountBlockedSamples(renderer, renderer.bounds, out totalSamples);
					if (totalSamples == 0)
					{
						Restore(nextPriorityRenderer);
						nextPriorityRenderer.hiddenChecks = 0;
						continue;
					}
					float num6 = (float)num5 / (float)totalSamples;
					if (num6 >= 0.8f)
					{
						nextPriorityRenderer.hiddenChecks++;
						if (nextPriorityRenderer.hiddenChecks >= 3 && !nextPriorityRenderer.hiddenBySleak && renderer.enabled)
						{
							renderer.enabled = false;
							nextPriorityRenderer.hiddenBySleak = true;
							hiddenCount++;
							lastAction = "Hid occluded renderer";
							lastActionTime = Time.unscaledTime;
						}
					}
					else
					{
						nextPriorityRenderer.hiddenChecks = 0;
						if (num6 <= 0.4f)
						{
							Restore(nextPriorityRenderer);
						}
					}
				}
			}
		}

		private void RefreshRendererPriority(float now)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			nextPriorityRefresh = now + 0.25f;
			visibleRendererPriority.Clear();
			offscreenRendererPriority.Clear();
			if ((Object)(object)mainCamera == (Object)null)
			{
				offscreenRendererPriority.AddRange(renderers);
				return;
			}
			GeometryUtility.CalculateFrustumPlanes(mainCamera, frustumPlanes);
			for (int i = 0; i < renderers.Count; i++)
			{
				RendererData rendererData = renderers[i];
				if (rendererData != null && !((Object)(object)rendererData.renderer == (Object)null))
				{
					if (GeometryUtility.TestPlanesAABB(frustumPlanes, rendererData.renderer.bounds))
					{
						visibleRendererPriority.Add(rendererData);
					}
					else
					{
						offscreenRendererPriority.Add(rendererData);
					}
				}
			}
			if (visiblePriorityIndex >= visibleRendererPriority.Count)
			{
				visiblePriorityIndex = 0;
			}
			if (offscreenPriorityIndex >= offscreenRendererPriority.Count)
			{
				offscreenPriorityIndex = 0;
			}
		}

		private RendererData GetNextPriorityRenderer()
		{
			bool flag = prioritySlot++ % 5 == 4;
			List<RendererData> list = (flag ? offscreenRendererPriority : visibleRendererPriority);
			List<RendererData> list2 = (flag ? visibleRendererPriority : offscreenRendererPriority);
			if (list.Count > 0)
			{
				if (flag)
				{
					if (offscreenPriorityIndex >= list.Count)
					{
						offscreenPriorityIndex = 0;
					}
					return list[offscreenPriorityIndex++];
				}
				if (visiblePriorityIndex >= list.Count)
				{
					visiblePriorityIndex = 0;
				}
				return list[visiblePriorityIndex++];
			}
			if (list2.Count > 0)
			{
				if (flag)
				{
					if (visiblePriorityIndex >= list2.Count)
					{
						visiblePriorityIndex = 0;
					}
					return list2[visiblePriorityIndex++];
				}
				if (offscreenPriorityIndex >= list2.Count)
				{
					offscreenPriorityIndex = 0;
				}
				return list2[offscreenPriorityIndex++];
			}
			return null;
		}

		private void BeginRendererScan()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			scanRoots.Clear();
			scanStack.Clear();
			visibleRendererPriority.Clear();
			offscreenRendererPriority.Clear();
			nextPriorityRefresh = 0f;
			for (int i = 0; i < SceneManager.sceneCount; i++)
			{
				Scene sceneAt = SceneManager.GetSceneAt(i);
				if (!((Scene)(ref sceneAt)).IsValid() || !((Scene)(ref sceneAt)).isLoaded)
				{
					continue;
				}
				GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects();
				for (int j = 0; j < rootGameObjects.Length; j++)
				{
					if ((Object)(object)rootGameObjects[j] != (Object)null)
					{
						scanRoots.Add(rootGameObjects[j]);
					}
				}
			}
			for (int num = scanRoots.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)scanRoots[num] != (Object)null)
				{
					scanStack.Push(scanRoots[num].transform);
				}
			}
			scanActive = scanStack.Count > 0;
			lastAction = (scanActive ? "Scanning world objects" : "World scan idle");
			lastActionTime = Time.unscaledTime;
			if (!scanActive)
			{
				CleanupDestroyedObjects();
			}
		}

		private void ProcessRendererScan()
		{
			if (!scanActive)
			{
				return;
			}
			int num = 0;
			while (scanStack.Count > 0 && num < 200)
			{
				Transform val = scanStack.Pop();
				num++;
				scanTransformCount++;
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				componentBuffer.Clear();
				gameObject.GetComponents<Renderer>(componentBuffer);
				for (int i = 0; i < componentBuffer.Count; i++)
				{
					RegisterRenderer(componentBuffer[i]);
				}
				animatorBuffer.Clear();
				gameObject.GetComponents<Animator>(animatorBuffer);
				for (int j = 0; j < animatorBuffer.Count; j++)
				{
					RegisterAnimator(animatorBuffer[j]);
				}
				particleBuffer.Clear();
				gameObject.GetComponents<ParticleSystem>(particleBuffer);
				for (int k = 0; k < particleBuffer.Count; k++)
				{
					RegisterParticle(particleBuffer[k]);
				}
				behaviourBuffer.Clear();
				gameObject.GetComponents<Behaviour>(behaviourBuffer);
				for (int l = 0; l < behaviourBuffer.Count; l++)
				{
					Behaviour val2 = behaviourBuffer[l];
					if (val2 is AudioSource && enableDistantAudio.Value)
					{
						RegisterBehaviour(val2);
					}
					if (val2 is Light && enableDistantLights.Value)
					{
						RegisterBehaviour(val2);
					}
				}
				for (int num2 = val.childCount - 1; num2 >= 0; num2--)
				{
					Transform child = val.GetChild(num2);
					if ((Object)(object)child != (Object)null)
					{
						scanStack.Push(child);
					}
				}
			}
			if (scanStack.Count == 0)
			{
				scanActive = false;
				lastAction = "World scan complete";
				lastActionTime = Time.unscaledTime;
				nextRefresh = Time.unscaledTime + 3f;
				CleanupDestroyedObjects();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("World scan completed. Renderers: " + renderers.Count + " | Animators: " + animators.Count + " | Particle systems: " + particles.Count + " | Behaviours: " + behaviours.Count));
			}
		}

		private void RegisterRenderer(Renderer renderer)
		{
			//IL_0095: 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)
			if (!((Object)(object)renderer == (Object)null))
			{
				int instanceID = ((Object)renderer).GetInstanceID();
				if (!rendererLookup.ContainsKey(instanceID) && (renderer is MeshRenderer || renderer is SkinnedMeshRenderer))
				{
					RendererData rendererData = new RendererData();
					rendererData.renderer = renderer;
					rendererData.instanceId = instanceID;
					rendererData.originalEnabled = renderer.enabled;
					rendererData.hiddenBySleak = false;
					rendererData.distanceCulled = false;
					rendererData.offscreenCulled = false;
					rendererData.offscreenSince = 0f;
					rendererData.hiddenChecks = 0;
					rendererData.originalShadowMode = renderer.shadowCastingMode;
					rendererData.shadowChanged = false;
					rendererLookup.Add(instanceID, rendererData);
					renderers.Add(rendererData);
				}
			}
		}

		private void RegisterAnimator(Animator animator)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)animator == (Object)null))
			{
				int instanceID = ((Object)animator).GetInstanceID();
				if (!animatorLookup.ContainsKey(instanceID))
				{
					AnimatorData animatorData = new AnimatorData();
					animatorData.animator = animator;
					animatorData.instanceId = instanceID;
					animatorData.originalCullingMode = animator.cullingMode;
					animatorData.cullingChanged = false;
					animatorLookup.Add(instanceID, animatorData);
					animators.Add(animatorData);
				}
			}
		}

		private void RegisterParticle(ParticleSystem particle)
		{
			if (!((Object)(object)particle == (Object)null))
			{
				int instanceID = ((Object)particle).GetInstanceID();
				if (!particleLookup.ContainsKey(instanceID))
				{
					ParticleData particleData = new ParticleData();
					particleData.particles = particle;
					particleData.instanceId = instanceID;
					particleData.wasPlaying = false;
					particleData.pausedBySleak = false;
					particleLookup.Add(instanceID, particleData);
					particles.Add(particleData);
				}
			}
		}

		private void RegisterBehaviour(Behaviour behaviour)
		{
			if (!((Object)(object)behaviour == (Object)null))
			{
				int instanceID = ((Object)behaviour).GetInstanceID();
				if (!behaviourLookup.ContainsKey(instanceID))
				{
					BehaviourData behaviourData = new BehaviourData();
					behaviourData.component = behaviour;
					behaviourData.instanceId = instanceID;
					behaviourData.originalEnabled = behaviour.enabled;
					behaviourData.disabledBySleak = false;
					behaviourLookup.Add(instanceID, behaviourData);
					behaviours.Add(behaviourData);
				}
			}
		}

		private void ProcessDistantComponents()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			int num = animators.Count + particles.Count + behaviours.Count;
			if (num == 0)
			{
				return;
			}
			int num2 = Mathf.Clamp(componentsPerCheck.Value, 1, 500);
			int num3 = 0;
			Vector3 position = ((Component)mainCamera).transform.position;
			while (num3 < num2 && num > 0)
			{
				if (functionalityIndex >= num)
				{
					functionalityIndex = 0;
				}
				int num4 = functionalityIndex++;
				num3++;
				if (num4 < animators.Count)
				{
					OptimizeAnimator(animators[num4], position);
					continue;
				}
				num4 -= animators.Count;
				if (num4 < particles.Count)
				{
					OptimizeParticle(particles[num4], position);
					continue;
				}
				num4 -= particles.Count;
				if (num4 < behaviours.Count)
				{
					OptimizeBehaviour(behaviours[num4], position);
				}
			}
		}

		private bool IsFar(Transform target, Vector3 cameraPosition)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			Vector3 val = target.position - cameraPosition;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			return sqrMagnitude > functionalityDistance.Value * functionalityDistance.Value;
		}

		private bool IsNearEnoughToRestore(Transform target, Vector3 cameraPosition)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return true;
			}
			Vector3 val = target.position - cameraPosition;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			return sqrMagnitude <= restoreDistance.Value * restoreDistance.Value;
		}

		private void OptimizeAnimator(AnimatorData data, Vector3 cameraPosition)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			Animator animator = data.animator;
			if ((Object)(object)animator == (Object)null)
			{
				return;
			}
			if (!enableDistantAnimatorCulling.Value)
			{
				RestoreAnimator(data);
			}
			else if (!((Behaviour)animator).enabled || !((Component)animator).gameObject.activeInHierarchy)
			{
				RestoreAnimator(data);
			}
			else if (IsFar(((Component)animator).transform, cameraPosition))
			{
				if (!data.cullingChanged && (int)animator.cullingMode != 2)
				{
					animator.cullingMode = (AnimatorCullingMode)2;
					data.cullingChanged = true;
					culledAnimatorCount++;
					lastAction = "Culled distant animation";
					lastActionTime = Time.unscaledTime;
				}
			}
			else if (IsNearEnoughToRestore(((Component)animator).transform, cameraPosition))
			{
				RestoreAnimator(data);
			}
		}

		private void RestoreAnimator(AnimatorData data)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (data.cullingChanged)
			{
				if ((Object)(object)data.animator != (Object)null)
				{
					data.animator.cullingMode = data.originalCullingMode;
				}
				data.cullingChanged = false;
				if (culledAnimatorCount > 0)
				{
					culledAnimatorCount--;
				}
			}
		}

		private void OptimizeParticle(ParticleData data, Vector3 cameraPosition)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem val = data.particles;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (!enableDistantParticles.Value)
			{
				RestoreParticle(data);
			}
			else if (!((Component)val).gameObject.activeInHierarchy)
			{
				RestoreParticle(data);
			}
			else if (IsFar(((Component)val).transform, cameraPosition))
			{
				if (!data.pausedBySleak && val.isPlaying)
				{
					data.wasPlaying = true;
					data.pausedBySleak = true;
					pausedParticleCount++;
					val.Pause(false);
					lastAction = "Paused distant particles";
					lastActionTime = Time.unscaledTime;
				}
			}
			else if (IsNearEnoughToRestore(((Component)val).transform, cameraPosition))
			{
				RestoreParticle(data);
			}
		}

		private void RestoreParticle(ParticleData data)
		{
			if (data.pausedBySleak)
			{
				if ((Object)(object)data.particles != (Object)null && data.wasPlaying && ((Component)data.particles).gameObject.activeInHierarchy)
				{
					data.particles.Play(false);
				}
				data.pausedBySleak = false;
				data.wasPlaying = false;
				if (pausedParticleCount > 0)
				{
					pausedParticleCount--;
				}
			}
		}

		private void OptimizeBehaviour(BehaviourData data, Vector3 cameraPosition)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			Behaviour component = data.component;
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (!((Component)component).gameObject.activeInHierarchy)
			{
				RestoreBehaviour(data);
				return;
			}
			bool flag = component is AudioSource;
			bool flag2 = component is Light;
			if ((flag && !enableDistantAudio.Value) || (flag2 && !enableDistantLights.Value))
			{
				RestoreBehaviour(data);
			}
			else
			{
				if (!data.originalEnabled)
				{
					return;
				}
				if (IsFar(((Component)component).transform, cameraPosition))
				{
					if (component.enabled)
					{
						component.enabled = false;
						data.disabledBySleak = true;
						disabledBehaviourCount++;
						lastAction = (flag ? "Disabled distant audio" : "Disabled distant light");
						lastActionTime = Time.unscaledTime;
					}
				}
				else if (IsNearEnoughToRestore(((Component)component).transform, cameraPosition))
				{
					RestoreBehaviour(data);
				}
			}
		}

		private void RestoreBehaviour(BehaviourData data)
		{
			if (data.disabledBySleak)
			{
				if ((Object)(object)data.component != (Object)null)
				{
					data.component.enabled = data.originalEnabled;
				}
				data.disabledBySleak = false;
				if (disabledBehaviourCount > 0)
				{
					disabledBehaviourCount--;
				}
			}
		}

		private void CleanupDestroyedObjects()
		{
			for (int num = renderers.Count - 1; num >= 0; num--)
			{
				if (!((Object)(object)renderers[num].renderer != (Object)null))
				{
					rendererLookup.Remove(renderers[num].instanceId);
					renderers.RemoveAt(num);
					if (scanIndex > num)
					{
						scanIndex--;
					}
				}
			}
			for (int num2 = animators.Count - 1; num2 >= 0; num2--)
			{
				if (!((Object)(object)animators[num2].animator != (Object)null))
				{
					animatorLookup.Remove(animators[num2].instanceId);
					animators.RemoveAt(num2);
				}
			}
			for (int num3 = particles.Count - 1; num3 >= 0; num3--)
			{
				if (!((Object)(object)particles[num3].particles != (Object)null))
				{
					particleLookup.Remove(particles[num3].instanceId);
					particles.RemoveAt(num3);
				}
			}
			for (int num4 = behaviours.Count - 1; num4 >= 0; num4--)
			{
				if (!((Object)(object)behaviours[num4].component != (Object)null))
				{
					behaviourLookup.Remove(behaviours[num4].instanceId);
					behaviours.RemoveAt(num4);
				}
			}
			if (scanIndex < 0 || scanIndex >= renderers.Count)
			{
				scanIndex = 0;
			}
			int num5 = animators.Count + particles.Count + behaviours.Count;
			if (functionalityIndex < 0 || functionalityIndex >= num5)
			{
				functionalityIndex = 0;
			}
		}

		private void RefreshTerrains()
		{
			Terrain[] activeTerrains = Terrain.activeTerrains;
			Terrain[] array = activeTerrains;
			foreach (Terrain val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				TerrainSettings terrainSettings = null;
				foreach (TerrainSettings terrain in terrains)
				{
					if ((Object)(object)terrain.terrain == (Object)(object)val)
					{
						terrainSettings = terrain;
						break;
					}
				}
				if (terrainSettings == null)
				{
					terrainSettings = new TerrainSettings();
					terrainSettings.terrain = val;
					terrainSettings.treeDistance = val.treeDistance;
					terrainSettings.treeBillboardDistance = val.treeBillboardDistance;
					terrainSettings.detailObjectDistance = val.detailObjectDistance;
					terrainSettings.detailObjectDensity = val.detailObjectDensity;
					terrainSettings.treeMaximumFullLODCount = val.treeMaximumFullLODCount;
					terrains.Add(terrainSettings);
				}
				val.treeDistance = Mathf.Min(val.treeDistance, 180f);
				val.treeBillboardDistance = Mathf.Min(val.treeBillboardDistance, 60f);
				val.detailObjectDistance = Mathf.Min(val.detailObjectDistance, 40f);
				val.detailObjectDensity = Mathf.Min(val.detailObjectDensity, 0.5f);
				val.treeMaximumFullLODCount = Mathf.Min(val.treeMaximumFullLODCount, 15);
			}
			for (int num = terrains.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)terrains[num].terrain == (Object)null)
				{
					terrains.RemoveAt(num);
				}
			}
		}

		private int CountBlockedSamples(Renderer renderer, Bounds bounds, out int totalSamples)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)mainCamera).transform.position;
			Vector3 center = ((Bounds)(ref bounds)).center;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			int blocked = 0;
			totalSamples = 0;
			CheckSample(renderer, position, center, ref blocked, ref totalSamples);
			CheckSample(renderer, position, center + new Vector3(0f, extents.y * 0.7f, 0f), ref blocked, ref totalSamples);
			CheckSample(renderer, position, center - new Vector3(0f, extents.y * 0.7f, 0f), ref blocked, ref totalSamples);
			CheckSample(renderer, position, center + new Vector3(extents.x * 0.7f, 0f, 0f), ref blocked, ref totalSamples);
			CheckSample(renderer, position, center - new Vector3(extents.x * 0.7f, 0f, 0f), ref blocked, ref totalSamples);
			return blocked;
		}

		private void CheckSample(Renderer renderer, Vector3 cameraPosition, Vector3 point, ref int blocked, ref int totalSamples)
		{
			//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_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = point - cameraPosition;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude <= 0.05f)
			{
				return;
			}
			raycastCount++;
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(cameraPosition, val / magnitude, ref val2, magnitude, -5, (QueryTriggerInteraction)1))
			{
				totalSamples++;
				return;
			}
			totalSamples++;
			if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null))
			{
				Transform transform = ((Component)((RaycastHit)(ref val2)).collider).transform;
				if (!((Object)(object)transform == (Object)(object)((Component)renderer).transform) && !transform.IsChildOf(((Component)renderer).transform) && !((Component)renderer).transform.IsChildOf(transform) && ((RaycastHit)(ref val2)).distance < magnitude - 0.5f)
				{
					blocked++;
				}
			}
		}

		private void OptimizeShadows(RendererData data, float distanceSquared)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Renderer renderer = data.renderer;
			if (!((Object)(object)renderer == (Object)null))
			{
				float num = 2025f;
				if (distanceSquared >= num && (int)renderer.shadowCastingMode > 0)
				{
					renderer.shadowCastingMode = (ShadowCastingMode)0;
					data.shadowChanged = true;
				}
				else if (distanceSquared < num && data.shadowChanged)
				{
					renderer.shadowCastingMode = data.originalShadowMode;
					data.shadowChanged = false;
				}
			}
		}

		private void Restore(RendererData data)
		{
			if (data.hiddenBySleak)
			{
				if ((Object)(object)data.renderer != (Object)null)
				{
					data.renderer.enabled = data.originalEnabled;
				}
				data.hiddenBySleak = false;
				if (hiddenCount > 0)
				{
					hiddenCount--;
				}
			}
		}

		private void RestoreShadows(RendererData data)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (data.shadowChanged)
			{
				if ((Object)(object)data.renderer != (Object)null)
				{
					data.renderer.shadowCastingMode = data.originalShadowMode;
				}
				data.shadowChanged = false;
			}
		}

		private void LogPerformanceStats()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Performance stats | Renderers: " + renderers.Count + " | Hidden by Sleak: " + hiddenCount + " | Animators culled: " + culledAnimatorCount + " | Particles paused: " + pausedParticleCount + " | Behaviours disabled: " + disabledBehaviourCount + " | Occlusion: " + enableOcclusionCulling.Value + " | Objects checked: " + checkedObjects + " | Raycasts: " + raycastCount + " | Transforms scanned: " + scanTransformCount + " | Scan active: " + scanActive));
			checkedObjects = 0;
			raycastCount = 0;
			scanTransformCount = 0;
		}

		private void OnGUI()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			if (showStatusPanel)
			{
				EnsureGuiStyles();
				float num = 14f;
				float num2 = Mathf.Max(10f, (float)Screen.height - 360f - 60f);
				GUILayout.BeginArea(new Rect(num, num2, 300f, 360f));
				GUILayout.BeginVertical(panelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("SLEAK", headingStyle, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
				GUILayout.Label("PERFORMANCE", mutedStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				GUILayout.Space(3f);
				GUILayout.Label(scanActive ? "●  Scanning world..." : "●  Optimizations active", bodyStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Last action: " + GetRecentAction(), mutedStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(5f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				DrawMetric("FPS", (fpsSmoothed > 0f) ? Mathf.RoundToInt(fpsSmoothed).ToString() : "--");
				DrawMetric("Renderers", renderers.Count.ToString());
				DrawMetric("Hidden", hiddenCount.ToString());
				GUILayout.EndHorizontal();
				float num3 = ((fpsHistory.Count > 0) ? (fpsHistorySum / (float)fpsHistory.Count) : 0f);
				string text = ((fpsHistory.Count < 20 || num3 <= 0f) ? "warming up" : (((fpsSmoothed - num3) / num3 * 100f).ToString("+0.0;-0.0;0.0") + "%"));
				GUILayout.Label("FPS vs recent 30s avg: " + text, bodyStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				DrawMetric("Animators", culledAnimatorCount.ToString());
				DrawMetric("Particles", pausedParticleCount.ToString());
				DrawMetric("Components", disabledBehaviourCount.ToString());
				GUILayout.EndHorizontal();
				if (showStatusDetails)
				{
					GUILayout.Space(4f);
					float num4 = (scanActive ? Mathf.Clamp01(1f / (1f + (float)scanStack.Count / 250f)) : 1f);
					GUILayout.Label("World scan", mutedStyle, Array.Empty<GUILayoutOption>());
					Rect rect = GUILayoutUtility.GetRect(1f, 7f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
					GUI.color = new Color(0.18f, 0.78f, 0.63f, 1f);
					GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width * num4, ((Rect)(ref rect)).height), (Texture)(object)Texture2D.whiteTexture);
					GUI.color = Color.white;
					GUILayout.Label("Tracked: " + animators.Count + " animators  •  " + particles.Count + " particle systems  •  " + behaviours.Count + " audio/light components", mutedStyle, Array.Empty<GUILayoutOption>());
					GUILayout.Label("Renderer range: " + (enableRendererDistanceCulling.Value ? (Mathf.RoundToInt(rendererMaxDistance.Value) + " m") : "OFF") + "   |   Occlusion: " + (enableOcclusionCulling.Value ? "ON" : "OFF"), mutedStyle, Array.Empty<GUILayoutOption>());
				}
				GUILayout.Space(5f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(showStatusDetails ? "Less" : "Details", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
				{
					showStatusDetails = !showStatusDetails;
				}
				if (GUILayout.Button("Rescan", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
				{
					BeginRendererScan();
					RefreshTerrains();
					lastAction = "Manual world rescan";
					lastActionTime = Time.unscaledTime;
				}
				GUILayout.FlexibleSpace();
				GUILayout.Label("F3: toggle GUI", mutedStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				GUILayout.EndVertical();
				GUILayout.EndArea();
			}
		}

		private void DrawMetric(string label, string value)
		{
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(82f) });
			GUILayout.Label(value, headingStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, mutedStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
		}

		private string GetRecentAction()
		{
			if (string.IsNullOrEmpty(lastAction))
			{
				return "Waiting";
			}
			float num = Time.unscaledTime - lastActionTime;
			return (num > 8f) ? "Monitoring scene" : lastAction;
		}

		private void EnsureGuiStyles()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0061: 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_0086: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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
			if (panelStyle == null)
			{
				panelStyle = new GUIStyle(GUI.skin.box);
				panelStyle.padding = new RectOffset(12, 12, 10, 10);
				panelStyle.normal.background = MakeGuiTexture(new Color(0.035f, 0.045f, 0.06f, 0.94f));
				headingStyle = new GUIStyle(GUI.skin.label);
				headingStyle.fontSize = 14;
				headingStyle.fontStyle = (FontStyle)1;
				headingStyle.normal.textColor = new Color(0.35f, 0.95f, 0.76f);
				bodyStyle = new GUIStyle(GUI.skin.label);
				bodyStyle.fontSize = 11;
				bodyStyle.normal.textColor = new Color(0.9f, 0.93f, 0.96f);
				mutedStyle = new GUIStyle(GUI.skin.label);
				mutedStyle.fontSize = 10;
				mutedStyle.normal.textColor = new Color(0.62f, 0.68f, 0.75f);
				mutedStyle.wordWrap = true;
				buttonStyle = new GUIStyle(GUI.skin.button);
				buttonStyle.fontSize = 10;
				buttonStyle.padding = new RectOffset(7, 7, 3, 3);
			}
		}

		private Texture2D MakeGuiTexture(Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private void RestoreTerrains()
		{
			foreach (TerrainSettings terrain in terrains)
			{
				if (!((Object)(object)terrain.terrain == (Object)null))
				{
					terrain.terrain.treeDistance = terrain.treeDistance;
					terrain.terrain.treeBillboardDistance = terrain.treeBillboardDistance;
					terrain.terrain.detailObjectDistance = terrain.detailObjectDistance;
					terrain.terrain.detailObjectDensity = terrain.detailObjectDensity;
					terrain.terrain.treeMaximumFullLODCount = terrain.treeMaximumFullLODCount;
				}
			}
			terrains.Clear();
		}

		private void OnDestroy()
		{
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			foreach (RendererData renderer in renderers)
			{
				Restore(renderer);
				RestoreShadows(renderer);
				if ((renderer.distanceCulled || renderer.offscreenCulled) && (Object)(object)renderer.renderer != (Object)null)
				{
					renderer.renderer.enabled = renderer.originalEnabled;
				}
				renderer.distanceCulled = false;
				renderer.offscreenCulled = false;
				renderer.offscreenSince = 0f;
			}
			foreach (AnimatorData animator in animators)
			{
				RestoreAnimator(animator);
			}
			foreach (ParticleData particle in particles)
			{
				RestoreParticle(particle);
			}
			foreach (BehaviourData behaviour in behaviours)
			{
				RestoreBehaviour(behaviour);
			}
			RestoreTerrains();
			if (settingsSaved)
			{
				QualitySettings.lodBias = originalLodBias;
				QualitySettings.shadowDistance = originalShadowDistance;
				QualitySettings.shadowResolution = originalShadowResolution;
				QualitySettings.streamingMipmapsActive = originalStreamingMipmapsActive;
				QualitySettings.streamingMipmapsMemoryBudget = originalStreamingMipmapsMemoryBudget;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sleak restored modified renderers, components, terrain and graphics settings.");
		}
	}
}