Decompiled source of LethalSponge v1.0.1

LethalSponge/LethalSponge.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader;
using LethalLevelLoader.AssetBundles;
using Microsoft.CodeAnalysis;
using Scoops.compatibility;
using Scoops.patches;
using Scoops.rendering;
using Scoops.service;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.Rendering;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("LethalLevelLoader")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: AssemblyCompany("LethalSponge")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0-alpha.0.28+cbee1cb789f0ec7a882f2c8ebe1bd4c8c1cb02b3")]
[assembly: AssemblyProduct("LethalSponge")]
[assembly: AssemblyTitle("LethalSponge")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Scoops
{
	public class Config
	{
		public static ConfigEntry<bool> verboseLogging;

		public static ConfigEntry<bool> ignoreInactiveObjects;

		public static ConfigEntry<string> fullReportList;

		public static ConfigEntry<string> assetbundleBlacklist;

		public static ConfigEntry<string> assetbundleWhitelist;

		public static ConfigEntry<string> propertyBlacklist;

		public static ConfigEntry<bool> unloadUnused;

		public static ConfigEntry<bool> fixFoliageLOD;

		public static ConfigEntry<bool> fixInputActions;

		public static ConfigEntry<bool> fixCameraSettings;

		public static ConfigEntry<bool> patchCameraScript;

		public static ConfigEntry<int> mapCameraFramerate;

		public static ConfigEntry<int> securityCameraFramerate;

		public static ConfigEntry<bool> removePosterizationShader;

		public static ConfigEntry<bool> useCustomShader;

		public static ConfigEntry<bool> disableDOF;

		public static ConfigEntry<bool> disableMotionBlur;

		public static ConfigEntry<bool> disableBloom;

		public static ConfigEntry<bool> disableShadows;

		public static ConfigEntry<bool> disableReflections;

		public static ConfigEntry<bool> disableMotionVectors;

		public static ConfigEntry<bool> disableRefraction;

		public static ConfigEntry<bool> qualityOverrides;

		public static ConfigEntry<int> decalDrawDist;

		public static ConfigEntry<int> decalAtlasSize;

		public static ConfigEntry<string> reflectionAtlasSize;

		public static ConfigEntry<int> maxCubeReflectionProbes;

		public static ConfigEntry<int> maxPlanarReflectionProbes;

		public static ConfigEntry<int> shadowsMaxResolution;

		public static ConfigEntry<int> shadowsAtlasSize;

		public static ConfigEntry<float> fogBudget;

		public static ConfigEntry<bool> deferredOnly;

		public static ConfigEntry<bool> changeLightFadeDistance;

		public static ConfigEntry<float> lightVolumetricDistMult;

		public static ConfigEntry<float> lightVolumetricDistCap;

		public static ConfigEntry<bool> runDaily;

		public Config(ConfigFile cfg)
		{
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Expected O, but got Unknown
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Expected O, but got Unknown
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Expected O, but got Unknown
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Expected O, but got Unknown
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Expected O, but got Unknown
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Expected O, but got Unknown
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Expected O, but got Unknown
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Expected O, but got Unknown
			verboseLogging = cfg.Bind<bool>("Investigation", "verboseLogging", false, "Whether Sponge should output detailed information about possible leak sources. (COSTLY FOR PERFORMANCE, ONLY ENABLE WHILE DEBUGGING).");
			ignoreInactiveObjects = cfg.Bind<bool>("Investigation", "ignoreInactiveObjects", true, "Whether Sponge should exclude gameobjects/behaviors that are inactive from totals.");
			fullReportList = cfg.Bind<string>("Investigation", "fullReportList", "", "Bundles/Scenes in this semicolon-separated list will have all objects' Name and ID printed each check. Use 'unknown' for basegame/unknown sources.");
			assetbundleBlacklist = cfg.Bind<string>("Investigation", "assetbundleBlacklist", "", "Any objects originating from assetbundles/scenes in this list will never be reported. Use 'unknown' for basegame/unknown sources.");
			assetbundleWhitelist = cfg.Bind<string>("Investigation", "assetbundleWhitelist", "", "ONLY objects originating from assetbundles/scenes in this list will be reported. This takes precedence over the Blacklist. Use 'unknown' for basegame/unknown sources.");
			propertyBlacklist = cfg.Bind<string>("Investigation", "propertyBlacklist", "Renderer.material;Renderer.materials;LightProbes.GetInstantiatedLightProbesForScene;MeshFilter.mesh;Collider.material;TMP_Text.fontMaterial;TMP_Text.fontMaterials;TMP_Text.spriteAnimator;Graphic.materialForRendering;Volume.profile;Volume.profileRef;TMP_InputField.mesh;InputSystemUIInputModule.trackedDeviceSelect;BasePanel.dungeon;BasePanel.selectedExtendedDungeonFlow;BasePanel.selectedDungeonFlow;TMP_Text.fontSharedMaterials;RenderSettings.customReflection;NetworkManager.ConnectedClients;NetworkManager.ConnectedClientsList;NetworkManager.ConnectedClientsIds", "While crawling through objects/classes to find references, Sponge will ignore these properties. Useful if there are Getters that run unwanted code.");
			unloadUnused = cfg.Bind<bool>("Cleanup", "unloadUnused", true, "Should Sponge call UnloadUnusedAssets each day?");
			fixFoliageLOD = cfg.Bind<bool>("Cleanup", "fixFoliageLOD", true, "Should Sponge replace the base Lethal Company FoliageDetailDistance script with one that doesn't leak materials? (LethalPerformance has a similar fix as well)");
			fixInputActions = cfg.Bind<bool>("Cleanup", "fixInputActions", true, "Should Sponge fix the repeated instantiation of PlayerActions that would cause additional input lag every time a game is loaded?");
			fixCameraSettings = cfg.Bind<bool>("Cameras", "fixCameraSettings", true, "Should Sponge change the settings for the ship cameras and radar cam to improve performance?");
			patchCameraScript = cfg.Bind<bool>("Cameras", "patchCameraScript", true, "Should Sponge replace the base Lethal Company ManualCameraRenderer.MeetsCameraEnabledConditions function with one that more reliably disables ship cameras when they're not in view?");
			securityCameraFramerate = cfg.Bind<int>("Cameras", "securityCameraFramerate", 15, "What framerate should the interior and exterior cams run at? (Requires fixCameraSettings = true)");
			mapCameraFramerate = cfg.Bind<int>("Cameras", "mapCameraFramerate", 20, "What framerate should the radar map camera run at? (Requires fixCameraSettings = true)");
			removePosterizationShader = cfg.Bind<bool>("Rendering", "removePosterizationShader", true, "Should Sponge remove the expensive posterization + outline custom pass to save processing power?");
			useCustomShader = cfg.Bind<bool>("Rendering", "useCustomShader", true, "Should Sponge replace the removed shader with a faster one that looks similar? (Requires removePosterizationShader = true)");
			disableDOF = cfg.Bind<bool>("Rendering", "disableDOF", false, "Should Sponge disable Depth of Field on the player camera?");
			disableMotionBlur = cfg.Bind<bool>("Rendering", "disableMotionBlur", false, "Should Sponge disable Motion Blur on the player camera?");
			disableBloom = cfg.Bind<bool>("Rendering", "disableBloom", false, "Should Sponge disable Bloom on the player camera?");
			disableShadows = cfg.Bind<bool>("Rendering", "disableShadows", false, "Should Sponge disable Shadows on the player camera?");
			disableReflections = cfg.Bind<bool>("Rendering", "disableReflections", false, "Should Sponge disable Reflections on the player camera?");
			disableMotionVectors = cfg.Bind<bool>("Rendering", "disableReflections", false, "Should Sponge disable MotionVectors on the player camera?");
			disableRefraction = cfg.Bind<bool>("Rendering", "disableReflections", false, "Should Sponge disable Refraction on the player camera?");
			qualityOverrides = cfg.Bind<bool>("Graphics Quality", "qualityOverrides", true, "Should Sponge change the default quality settings? This must be on for any of the other Graphics Quality settings to take effect.");
			decalDrawDist = cfg.Bind<int>("Graphics Quality", "decalDrawDist", 100, new ConfigDescription("What should the maximum distance be for drawing decals like blood splatters? (LC default is 1000)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 100), Array.Empty<object>()));
			decalAtlasSize = cfg.Bind<int>("Graphics Quality", "decalAtlasSize", 2048, new ConfigDescription("What should the texture size be for the the Decal Atlas? (squared)", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[2] { 2048, 4096 }), Array.Empty<object>()));
			reflectionAtlasSize = cfg.Bind<string>("Graphics Quality", "reflectionAtlasSize", "Resolution1024x1024", new ConfigDescription("What should the texture size be for the the Decal Atlas? (LC default is 2048x1024)", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[4] { "Resolution512x512", "Resolution1024x512", "Resolution1024x1024", "Resolution2048x1024" }), Array.Empty<object>()));
			maxCubeReflectionProbes = cfg.Bind<int>("Graphics Quality", "maxCubeReflectionProbes", 12, new ConfigDescription("How many Cube Reflection Probes should be able to be on screen at once? (LC default is 48)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(6, 48), Array.Empty<object>()));
			maxPlanarReflectionProbes = cfg.Bind<int>("Graphics Quality", "maxPlanarReflectionProbes", 8, new ConfigDescription("How many Cube Reflection Probes should be able to be on screen at once? (LC default is 16)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 16), Array.Empty<object>()));
			shadowsMaxResolution = cfg.Bind<int>("Graphics Quality", "shadowsMaxResolution", 256, new ConfigDescription("What should the maximum resolution be for Shadow Maps? (LC default is 1024)", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[5] { 64, 128, 256, 512, 1024 }), Array.Empty<object>()));
			shadowsAtlasSize = cfg.Bind<int>("Graphics Quality", "shadowsAtlasSize", 2048, new ConfigDescription("What should the resolution be for the Shadow Map Atlas? (LC default is 4096)", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[3] { 1024, 2048, 4096 }), Array.Empty<object>()));
			fogBudget = cfg.Bind<float>("Graphics Quality", "fogBudget", 0.15f, new ConfigDescription("What should the budget (0-1) be for the volumetric fog? (LC default is 0.166) (WARNING: Lowering this will make fog less dangerous)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.17f), Array.Empty<object>()));
			deferredOnly = cfg.Bind<bool>("Graphics Quality", "deferredOnly", true, "Should Sponge set the Lit Shader Mode to Deferred Only? (This might free up some memory, and LC only uses Deferred anyway.)");
			changeLightFadeDistance = cfg.Bind<bool>("Graphics Quality", "changeLightFadeDistance", true, "Should Sponge change the Fade Distance for all lights so they're not visible from too far away?");
			lightVolumetricDistMult = cfg.Bind<float>("Graphics Quality", "lightVolumetricDistMult", 10f, new ConfigDescription("What should the light's Range be multiplied by to find the Fade Distance?", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>()));
			lightVolumetricDistCap = cfg.Bind<float>("Graphics Quality", "lightVolumetricDistCap", 150f, new ConfigDescription("What should the maximum Fade Distance be for lights? (LC Defaults tend to use 10000 for Fade Distance)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(25f, 1000f), Array.Empty<object>()));
			runDaily = cfg.Bind<bool>("Debug", "runDaily", true, "If false, Sponge will no longer run automatically each day and will only run when you type '/sponge' in chat. This can be toggled mid-game with '/sponge toggle'.");
		}
	}
	public static class PluginInformation
	{
		public const string PLUGIN_GUID = "LethalSponge";

		public const string PLUGIN_NAME = "LethalSponge";

		public const string PLUGIN_VERSION = "1.0.1";
	}
	[BepInPlugin("LethalSponge", "LethalSponge", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <RegisterAssetBundlesStale>d__14 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private GameObject[] <allGameObjects>5__1;

			private IEnumerable<AssetBundle> <allBundles>5__2;

			private IEnumerator<AssetBundle> <>s__3;

			private AssetBundle <bundle>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RegisterAssetBundlesStale>d__14(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<allGameObjects>5__1 = null;
				<allBundles>5__2 = null;
				<>s__3 = null;
				<bundle>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Log.LogMessage((object)"Sponge is acquiring assetbundle references, please wait.");
					<allGameObjects>5__1 = Resources.FindObjectsOfTypeAll<GameObject>();
					<allBundles>5__2 = AssetBundle.GetAllLoadedAssetBundles();
					<>s__3 = <allBundles>5__2.GetEnumerator();
					try
					{
						while (<>s__3.MoveNext())
						{
							<bundle>5__4 = <>s__3.Current;
							SpongeService.RegisterAssetBundle(<bundle>5__4);
							<bundle>5__4 = null;
						}
					}
					finally
					{
						if (<>s__3 != null)
						{
							<>s__3.Dispose();
						}
					}
					<>s__3 = null;
					((MonoBehaviour)<>4__this).StartCoroutine(SpongeService.CheckAllGameObjectDependencies(<allGameObjects>5__1));
					Log.LogMessage((object)"Assetbundle references acquired.");
					<allGameObjects>5__1 = Array.Empty<GameObject>();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static AssetBundle SpongeAssets;

		private readonly Harmony _harmony = new Harmony("LethalSponge");

		public static Plugin Instance { get; set; }

		public static Config SpongeConfig { get; internal set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
		}

		private void Awake()
		{
			Log.LogInfo((object)"Loading LethalSponge Version 1.0.1");
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string text = Path.Combine(directoryName, "spongeassets");
			SpongeAssets = AssetBundle.LoadFromFile(text);
			SpongeConfig = new Config(((BaseUnityPlugin)this).Config);
			SpongeService.PluginLoad();
			Log.LogInfo((object)"Applying base patches...");
			ApplyPluginPatch();
			Log.LogInfo((object)"Base patches applied");
			if (Config.verboseLogging.Value)
			{
				Log.LogInfo((object)"Applying verbose patches...");
				ApplyVerbosePluginPatch();
				Log.LogInfo((object)"Verbose patches applied");
				((MonoBehaviour)this).StartCoroutine(RegisterAssetBundlesStale());
				if (LLLCompat.Enabled)
				{
					Log.LogInfo((object)"Lethal Level Loader compat enabled...");
					LLLCompat.AddBundleHook();
				}
			}
			AlterQualitySettings();
		}

		[IteratorStateMachine(typeof(<RegisterAssetBundlesStale>d__14))]
		public IEnumerator RegisterAssetBundlesStale()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RegisterAssetBundlesStale>d__14(0)
			{
				<>4__this = this
			};
		}

		private void ApplyPluginPatch()
		{
			_harmony.PatchAll(typeof(StartOfRoundSpongePatch));
			if (Config.fixFoliageLOD.Value)
			{
				_harmony.PatchAll(typeof(FoliageDetailDistanceSpongePatch));
			}
			if (Config.patchCameraScript.Value)
			{
				_harmony.PatchAll(typeof(ManualCameraRendererSpongePatch));
			}
			if (Config.disableBloom.Value || Config.disableDOF.Value || Config.disableMotionBlur.Value || Config.disableShadows.Value || Config.disableMotionVectors.Value || Config.disableRefraction.Value || Config.disableReflections.Value || Config.useCustomShader.Value)
			{
				_harmony.PatchAll(typeof(PlayerControllerBSpongePatch));
			}
			if (Config.useCustomShader.Value)
			{
				_harmony.PatchAll(typeof(HDRenderPipeline_RecordRenderGraph_Patch));
			}
			if (Config.fixInputActions.Value)
			{
				InputActionSpongePatches.Init();
				_harmony.PatchAll(typeof(InputActionSpongePatches));
				Log.LogInfo((object)"Input Actions Patched");
			}
		}

		private void ApplyVerbosePluginPatch()
		{
			_harmony.PatchAll(typeof(RoundManagerSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleAsyncSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleLoadSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleLoadAsyncSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleLoadMultipleSpongePatch));
			_harmony.PatchAll(typeof(AssetBundleLoadMultipleAsyncSpongePatch));
		}

		private void AlterQualitySettings()
		{
			//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_0026: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Config.qualityOverrides.Value)
			{
				RenderPipelineSettings currentPlatformRenderPipelineSettings = ((HDRenderPipelineAsset)GraphicsSettings.currentRenderPipeline).currentPlatformRenderPipelineSettings;
				if (Config.deferredOnly.Value)
				{
					currentPlatformRenderPipelineSettings.supportedLitShaderMode = (SupportedLitShaderMode)2;
				}
				currentPlatformRenderPipelineSettings.decalSettings.drawDistance = Config.decalDrawDist.Value;
				currentPlatformRenderPipelineSettings.decalSettings.atlasHeight = Config.decalAtlasSize.Value;
				currentPlatformRenderPipelineSettings.decalSettings.atlasWidth = Config.decalAtlasSize.Value;
				currentPlatformRenderPipelineSettings.lightLoopSettings.reflectionProbeTexCacheSize = Enum.Parse<ReflectionProbeTextureCacheResolution>(Config.reflectionAtlasSize.Value);
				currentPlatformRenderPipelineSettings.lightLoopSettings.maxCubeReflectionOnScreen = Config.maxCubeReflectionProbes.Value;
				currentPlatformRenderPipelineSettings.lightLoopSettings.maxPlanarReflectionOnScreen = Config.maxPlanarReflectionProbes.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.maxPunctualShadowMapResolution = Config.shadowsMaxResolution.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.maxDirectionalShadowMapResolution = Config.shadowsMaxResolution.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.maxAreaShadowMapResolution = Config.shadowsMaxResolution.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.punctualLightShadowAtlas.shadowAtlasResolution = Config.shadowsAtlasSize.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.cachedPunctualLightShadowAtlas = Config.shadowsAtlasSize.Value / 2;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.areaLightShadowAtlas.shadowAtlasResolution = Config.shadowsAtlasSize.Value;
				currentPlatformRenderPipelineSettings.hdShadowInitParams.cachedAreaLightShadowAtlas = Config.shadowsAtlasSize.Value / 2;
				currentPlatformRenderPipelineSettings.lightingQualitySettings.Fog_Budget[QualitySettings.GetQualityLevel()] = Config.fogBudget.Value;
				((HDRenderPipelineAsset)GraphicsSettings.currentRenderPipeline).m_RenderPipelineSettings = currentPlatformRenderPipelineSettings;
				((RenderPipelineAsset)(HDRenderPipelineAsset)GraphicsSettings.currentRenderPipeline).OnValidate();
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalSponge";

		public const string PLUGIN_NAME = "LethalSponge";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Scoops.service
{
	public static class CameraService
	{
		public static Camera MapCamera;

		public static Camera ShipCamera;

		public static Camera SecurityCamera;

		public static GameObject MonitorWall;

		public static GameObject ShipInside;

		public static Terminal MainTerminal;

		public static GameObject oldVolume;

		public static GameObject newVolume;

		public static bool Init()
		{
			Plugin.Log.LogMessage((object)"Finding Ship cameras.");
			bool result = true;
			Camera val = (from x in Object.FindObjectsByType<Camera>((FindObjectsInactive)1, (FindObjectsSortMode)0)
				where ((Object)((Component)x).gameObject).name == "MapCamera" && ((Component)x).gameObject.tag == "MapCamera"
				select x).FirstOrDefault();
			if ((Object)(object)val != (Object)null)
			{
				MapCamera = val;
			}
			else
			{
				Plugin.Log.LogError((object)"Sponge could not find MapCamera. Camera fixes may not function.");
				result = false;
			}
			Camera val2 = (from x in Object.FindObjectsByType<Camera>((FindObjectsInactive)1, (FindObjectsSortMode)0)
				where ((Object)((Component)x).gameObject).name == "ShipCamera" && ((Component)x).gameObject.tag == "Untagged"
				select x).FirstOrDefault();
			if ((Object)(object)val2 != (Object)null)
			{
				ShipCamera = val2;
			}
			else
			{
				Plugin.Log.LogError((object)"Sponge could not find ShipCamera. Camera fixes may not function.");
				result = false;
			}
			Camera val3 = (from x in Object.FindObjectsByType<Camera>((FindObjectsInactive)1, (FindObjectsSortMode)0)
				where ((Object)((Component)x).gameObject).name == "SecurityCamera" && ((Component)x).gameObject.tag == "Untagged"
				select x).FirstOrDefault();
			if ((Object)(object)val3 != (Object)null)
			{
				SecurityCamera = val3;
			}
			else
			{
				Plugin.Log.LogError((object)"Sponge could not find SecurityCamera. Camera fixes may not function.");
				result = false;
			}
			GameObject val4 = (from x in Object.FindObjectsByType<GameObject>((FindObjectsInactive)1, (FindObjectsSortMode)0)
				where ((Object)x).name == "MonitorWall" && x.gameObject.tag == "Untagged"
				select x).FirstOrDefault();
			if ((Object)(object)val4 != (Object)null)
			{
				MonitorWall = val4;
			}
			else
			{
				Plugin.Log.LogError((object)"Sponge could not find MonitorWall. Camera fixes may not function.");
				result = false;
			}
			Terminal val5 = (from x in Object.FindObjectsByType<Terminal>((FindObjectsInactive)1, (FindObjectsSortMode)0)
				where ((Object)((Component)x).gameObject).name == "TerminalScript" && ((Component)x).gameObject.tag == "InteractTrigger"
				select x).FirstOrDefault();
			if ((Object)(object)val5 != (Object)null)
			{
				MainTerminal = val5;
			}
			return result;
		}

		public static void DisablePosterization()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			oldVolume = GameObject.Find("CustomPass");
			if (Config.useCustomShader.Value)
			{
				newVolume = Object.Instantiate<GameObject>((GameObject)Plugin.SpongeAssets.LoadAsset("SpongeCustomPass"), oldVolume.transform.parent);
				Plugin.SpongeAssets.LoadAsset("SpongePosterize");
				Plugin.SpongeAssets.LoadAsset("FullScreen_SpongePosterize");
				newVolume.GetComponent<CustomPassVolume>().injectionPoint = (CustomPassInjectionPoint)7;
				newVolume.GetComponent<CustomPassVolume>().customPasses.Clear();
				newVolume.GetComponent<CustomPassVolume>().customPasses.Add((CustomPass)(object)new SpongeCustomPass());
			}
			foreach (CustomPass customPass in oldVolume.GetComponent<CustomPassVolume>().customPasses)
			{
				if (customPass.name == "FS")
				{
					oldVolume.GetComponent<CustomPassVolume>().customPasses.Remove(customPass);
					break;
				}
			}
		}

		public static void ApplyCameraFixes()
		{
			SetOverrides(ShipCamera);
			SetOverrides(SecurityCamera);
			SetOverrides(MapCamera, mapCamera: true);
			ShipCamera.farClipPlane = 13f;
			SecurityCamera.farClipPlane = 20f;
			((Component)ShipCamera).GetComponent<ManualCameraRenderer>().renderAtLowerFramerate = true;
			((Component)ShipCamera).GetComponent<ManualCameraRenderer>().fps = Config.securityCameraFramerate.Value;
			((Component)SecurityCamera).GetComponent<ManualCameraRenderer>().renderAtLowerFramerate = true;
			((Component)SecurityCamera).GetComponent<ManualCameraRenderer>().fps = Config.securityCameraFramerate.Value;
			((Component)MonitorWall.transform.Find("Cube.001/CameraMonitorScript")).GetComponent<ManualCameraRenderer>().renderAtLowerFramerate = true;
			((Component)MonitorWall.transform.Find("Cube.001/CameraMonitorScript")).GetComponent<ManualCameraRenderer>().fps = Config.mapCameraFramerate.Value;
			Plugin.Log.LogMessage((object)"Ship cameras patched.");
		}

		public static void ApplyPlayerCameraPatch(PlayerControllerB player)
		{
			if (Config.disableBloom.Value || Config.disableDOF.Value || Config.disableMotionBlur.Value || Config.disableShadows.Value || Config.disableMotionVectors.Value || Config.disableRefraction.Value || Config.disableReflections.Value)
			{
				SetPlayerOverrides(player.gameplayCamera);
			}
			if (Config.useCustomShader.Value)
			{
				HDAdditionalCameraData component = ((Component)player.gameplayCamera).GetComponent<HDAdditionalCameraData>();
				UpdateCamera(player.gameplayCamera);
			}
			Plugin.Log.LogMessage((object)"Player camera patched.");
		}

		public static void UpdateCamera(Camera camera)
		{
			newVolume.GetComponent<CustomPassVolume>().targetCamera = camera;
			if ((Object)(object)camera.targetTexture != (Object)null)
			{
				if (SpongeCustomPass.posterizationRT != null)
				{
					RTHandles.Release(SpongeCustomPass.posterizationRT);
				}
				SpongeCustomPass.posterizationRT = RTHandles.Alloc(((Texture)camera.targetTexture).width, ((Texture)camera.targetTexture).height, 1, (DepthBits)0, (GraphicsFormat)4, (FilterMode)0, (TextureWrapMode)1, (TextureDimension)2, true, false, true, false, 1, 0f, (MSAASamples)1, false, false, (RenderTextureMemoryless)0, (VRTextureUsage)0, "");
			}
		}

		private static void SetOverrides(Camera camera, bool mapCamera = false)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			HDAdditionalCameraData component = ((Component)camera).GetComponent<HDAdditionalCameraData>();
			component.customRenderingSettings = true;
			((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[4u] = true;
			component.renderingPathCustomFrameSettings.msaaMode = (MSAAMode)1;
			if (!mapCamera)
			{
				((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[62u] = true;
				((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[63u] = true;
				component.renderingPathCustomFrameSettings.maximumLODLevelMode = (MaximumLODLevelMode)2;
				component.renderingPathCustomFrameSettings.maximumLODLevel = 2;
			}
			((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[66u] = true;
			component.renderingPathCustomFrameSettings.materialQuality = (MaterialQuality)1;
			if (!mapCamera)
			{
				component.DisableHDField((FrameSettingsField)3);
			}
			component.DisableHDField((FrameSettingsField)12);
			component.DisableHDField((FrameSettingsField)8);
			component.DisableHDField((FrameSettingsField)9);
			component.DisableHDField((FrameSettingsField)92);
			component.DisableHDField((FrameSettingsField)6);
			component.DisableHDField((FrameSettingsField)10);
			component.DisableHDField((FrameSettingsField)13);
			component.DisableHDField((FrameSettingsField)14);
			component.DisableHDField((FrameSettingsField)39);
			component.DisableHDField((FrameSettingsField)80);
			component.DisableHDField((FrameSettingsField)81);
			component.DisableHDField((FrameSettingsField)82);
			component.DisableHDField((FrameSettingsField)83);
			component.DisableHDField((FrameSettingsField)84);
			component.DisableHDField((FrameSettingsField)85);
			component.DisableHDField((FrameSettingsField)86);
			component.DisableHDField((FrameSettingsField)87);
			component.DisableHDField((FrameSettingsField)89);
			component.DisableHDField((FrameSettingsField)90);
			component.DisableHDField((FrameSettingsField)91);
			component.DisableHDField((FrameSettingsField)93);
			component.DisableHDField((FrameSettingsField)97);
			component.DisableHDField((FrameSettingsField)17);
			component.DisableHDField((FrameSettingsField)68);
			component.DisableHDField((FrameSettingsField)99);
			component.DisableHDField((FrameSettingsField)20);
			component.DisableHDField((FrameSettingsField)21);
			component.DisableHDField((FrameSettingsField)127);
			component.DisableHDField((FrameSettingsField)34);
			component.DisableHDField((FrameSettingsField)23);
			component.DisableHDField((FrameSettingsField)95);
			component.DisableHDField((FrameSettingsField)24);
			component.DisableHDField((FrameSettingsField)26);
			component.DisableHDField((FrameSettingsField)27);
			component.DisableHDField((FrameSettingsField)33);
			component.DisableHDField((FrameSettingsField)35);
			component.DisableHDField((FrameSettingsField)37);
			component.DisableHDField((FrameSettingsField)46);
			component.DisableHDField((FrameSettingsField)79);
			if (mapCamera)
			{
				component.DisableHDField((FrameSettingsField)38);
			}
		}

		private static void SetPlayerOverrides(Camera camera, bool potato = false)
		{
			HDAdditionalCameraData component = ((Component)camera).GetComponent<HDAdditionalCameraData>();
			component.customRenderingSettings = true;
			((BitArray128)(ref component.renderingPathCustomFrameSettingsOverrideMask.mask))[15u] = true;
			if (Config.disableBloom.Value)
			{
				component.DisableHDField((FrameSettingsField)84);
			}
			if (Config.disableDOF.Value)
			{
				component.DisableHDField((FrameSettingsField)81);
			}
			if (Config.disableMotionBlur.Value)
			{
				component.DisableHDField((FrameSettingsField)82);
			}
			if (Config.disableShadows.Value)
			{
				component.DisableHDField((FrameSettingsField)20);
				component.DisableHDField((FrameSettingsField)21);
				component.DisableHDField((FrameSettingsField)34);
			}
			if (Config.disableReflections.Value)
			{
				component.DisableHDField((FrameSettingsField)33);
				component.DisableHDField((FrameSettingsField)35);
				component.DisableHDField((FrameSettingsField)37);
				component.DisableHDField((FrameSettingsField)23);
				component.DisableHDField((FrameSettingsField)94);
			}
			if (Config.disableMotionVectors.Value)
			{
				component.DisableHDField((FrameSettingsField)10);
				component.DisableHDField((FrameSettingsField)11);
				component.DisableHDField((FrameSettingsField)16);
			}
			if (Config.disableRefraction.Value)
			{
				component.DisableHDField((FrameSettingsField)13);
			}
		}

		private static void DisableHDField(this HDAdditionalCameraData data, FrameSettingsField field)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			((BitArray128)(ref data.renderingPathCustomFrameSettingsOverrideMask.mask))[(uint)(int)field] = true;
			((FrameSettings)(ref data.renderingPathCustomFrameSettings)).SetEnabled(field, false);
		}
	}
	public static class LightService
	{
		public static void UpdateAllLights()
		{
			HDAdditionalLightData[] array = Object.FindObjectsByType<HDAdditionalLightData>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			float value = Config.lightVolumetricDistMult.Value;
			float value2 = Config.lightVolumetricDistCap.Value;
			HDAdditionalLightData[] array2 = array;
			foreach (HDAdditionalLightData val in array2)
			{
				val.fadeDistance = Math.Clamp(value * val.range, 0f, value2);
			}
		}
	}
	public enum SpongeMode
	{
		Evaluate,
		Clean,
		Full
	}
	internal class BundleLeakTracker
	{
		public Dictionary<string, int> leakCount;

		public Dictionary<string, int> objectCount;

		public BundleLeakTracker()
		{
			leakCount = new Dictionary<string, int>();
			objectCount = new Dictionary<string, int>();
		}
	}
	internal static class SpongeService
	{
		[CompilerGenerated]
		private sealed class <CheckAllGameObjectDependencies>d__35 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject[] allGameObjects;

			private List<string> <checkedObjects>5__1;

			private GameObject[] <>s__2;

			private int <>s__3;

			private GameObject <obj>5__4;

			private string <bundleName>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckAllGameObjectDependencies>d__35(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<checkedObjects>5__1 = null;
				<>s__2 = null;
				<obj>5__4 = null;
				<bundleName>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<checkedObjects>5__1 = new List<string>();
					<>s__2 = allGameObjects;
					for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++)
					{
						<obj>5__4 = <>s__2[<>s__3];
						if (!<checkedObjects>5__1.Contains(((Object)<obj>5__4).name) && (Object)(object)<obj>5__4.transform.parent == (Object)null)
						{
							if (bundleTracking.TryGetValue(((Object)<obj>5__4).name.ToLower(), out <bundleName>5__5))
							{
								<checkedObjects>5__1.Add(((Object)<obj>5__4).name);
								FindGameObjectDependenciesRecursively(<bundleName>5__5, <obj>5__4);
							}
							<bundleName>5__5 = null;
						}
						<obj>5__4 = null;
					}
					<>s__2 = null;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static bool enabled = true;

		private static readonly Dictionary<Type, List<FieldInfo>> assignableFieldsByObjectType = new Dictionary<Type, List<FieldInfo>> { 
		{
			typeof(Object),
			null
		} };

		private static readonly Dictionary<Type, List<PropertyInfo>> assignablePropertiesByObjectType = new Dictionary<Type, List<PropertyInfo>> { 
		{
			typeof(Object),
			null
		} };

		private static Object[] allObjects;

		private static List<string> ignoredProperties = new List<string>();

		private static List<string> ignoredAssetbundles = new List<string>();

		private static List<string> focusedAssetbundles = new List<string>();

		private static List<string> fullReportBundles = new List<string>();

		private static Dictionary<string, BundleLeakTracker> leakTracking = new Dictionary<string, BundleLeakTracker>();

		private static Dictionary<string, BundleLeakTracker> previousLeakTracking = new Dictionary<string, BundleLeakTracker>();

		private static Dictionary<int, ushort> referenceTracking = new Dictionary<int, ushort>();

		private static Dictionary<string, string> bundleTracking = new Dictionary<string, string>();

		private static Dictionary<string, string> streamedSceneTracking = new Dictionary<string, string>();

		private static Stopwatch stopwatch = new Stopwatch();

		private static int prevCount = 0;

		private static int initialCount = 0;

		private static int newCount = 0;

		private static readonly List<string> meshReadProperties = new List<string>
		{
			"vertices", "normals", "tangents", "uv", "uv2", "uv3", "uv4", "uv5", "uv6", "uv7",
			"uv8", "colors", "colors32", "triangles"
		};

		public static void PluginLoad()
		{
			ParseConfig();
			SceneManager.sceneLoaded += SceneLoaded;
		}

		public static void Initialize()
		{
			Plugin.Log.LogMessage((object)"---");
			Plugin.Log.LogMessage((object)"Initializing Sponge");
			allObjects = Resources.FindObjectsOfTypeAll<Object>();
			Plugin.Log.LogMessage((object)("Initial count of " + allObjects.Length + " objects loaded."));
			prevCount = allObjects.Length;
			initialCount = allObjects.Length;
			allObjects = Array.Empty<Object>();
			Plugin.Log.LogMessage((object)"Type '/sponge help' in chat for commands.");
			Plugin.Log.LogMessage((object)"Sponge Initialised.");
			Plugin.Log.LogMessage((object)"---");
		}

		public static void ParseConfig()
		{
			if (Config.propertyBlacklist.Value != "")
			{
				ignoredProperties.AddRange(Config.propertyBlacklist.Value.ToLower().Split(';'));
			}
			if (Config.assetbundleBlacklist.Value != "")
			{
				ignoredAssetbundles.AddRange(Config.assetbundleBlacklist.Value.ToLower().Split(';'));
			}
			if (Config.assetbundleWhitelist.Value != "")
			{
				focusedAssetbundles.AddRange(Config.assetbundleWhitelist.Value.ToLower().Split(';'));
			}
			if (Config.fullReportList.Value != "")
			{
				fullReportBundles.AddRange(Config.fullReportList.Value.ToLower().Split(';'));
			}
			enabled = Config.runDaily.Value;
		}

		public static bool AssetBundleValid(string bundleName)
		{
			if (focusedAssetbundles.Count > 0)
			{
				return focusedAssetbundles.Contains(bundleName.ToLower());
			}
			return !ignoredAssetbundles.Contains(bundleName.ToLower());
		}

		public static void ApplySponge(SpongeMode mode = SpongeMode.Full)
		{
			Plugin.Log.LogMessage((object)"---");
			Plugin.Log.LogMessage((object)"Applying Sponge");
			stopwatch.Restart();
			if (Config.verboseLogging.Value && (mode == SpongeMode.Evaluate || mode == SpongeMode.Full))
			{
				PerformEvaluation();
			}
			allObjects = Resources.FindObjectsOfTypeAll<Object>();
			newCount = allObjects.Length;
			Plugin.Log.LogMessage((object)("There are " + newCount + " loaded objects total."));
			if (Config.verboseLogging.Value && (mode == SpongeMode.Evaluate || mode == SpongeMode.Full) && newCount > allObjects.Length)
			{
				Plugin.Log.LogWarning((object)"More objects after evaluating than before. Property calls possibly instantiated unexpected objects.");
			}
			allObjects = Array.Empty<Object>();
			if (mode == SpongeMode.Clean || mode == SpongeMode.Full)
			{
				PerformCleanup();
			}
		}

		private static void FinishSponge()
		{
			if (Config.unloadUnused.Value)
			{
				Plugin.Log.LogMessage((object)"Resources.UnloadUnusedAssets() completed.");
				allObjects = Resources.FindObjectsOfTypeAll<Object>();
				int num = newCount;
				newCount = allObjects.Length;
				Plugin.Log.LogMessage((object)("After cleaning there are " + newCount + " loaded objects total."));
				Plugin.Log.LogMessage((object)("Resources.UnloadUnusedAssets() cleaned up " + (num - newCount) + " objects."));
				allObjects = Array.Empty<Object>();
			}
			stopwatch.Stop();
			TimeSpan elapsed = stopwatch.Elapsed;
			int num2 = newCount - initialCount;
			float num3 = (float)num2 / (float)initialCount * 100f;
			int num4 = newCount - prevCount;
			float num5 = (float)num4 / (float)prevCount * 100f;
			string text = "more";
			if (num4 < 0)
			{
				text = "less";
			}
			Plugin.Log.LogMessage((object)("Sponge took " + elapsed.TotalSeconds + " seconds to execute."));
			Plugin.Log.LogMessage((object)("There were " + num2 + " more objects than on initialization, a " + num3 + "% change."));
			Plugin.Log.LogMessage((object)("There were " + num4 + " " + text + " objects than last check, a " + num5 + "% change."));
			Plugin.Log.LogMessage((object)"---");
			prevCount = newCount;
		}

		private static void PerformEvaluation()
		{
			allObjects = Resources.FindObjectsOfTypeAll<Object>();
			referenceTracking.Clear();
			previousLeakTracking = leakTracking;
			leakTracking = new Dictionary<string, BundleLeakTracker>();
			Plugin.Log.LogMessage((object)"Evaluating loaded objects, please wait.");
			for (int i = 0; i < allObjects.Length; i++)
			{
				IncrementReferenceCounts(GetUnityObjectReferences(i));
			}
			int num = ExamineType<Mesh>();
			int num2 = ExamineType<Material>();
			int num3 = ExamineType<Texture2D>();
			int num4 = ExamineType<AudioClip>();
			int num5 = ExamineType<NavMeshData>();
			int num6 = CountType<GameObject>();
			int num7 = CountType<Camera>();
			foreach (string key in leakTracking.Keys)
			{
				if (key != "unknown")
				{
					Plugin.Log.LogMessage((object)("For AssetBundle/Scene " + key + ": "));
				}
				else
				{
					Plugin.Log.LogMessage((object)"For Base Game/unknown AssetBundle sources: ");
				}
				BundleLeakTracker bundleLeakTracker = leakTracking[key];
				BundleLeakTracker value;
				bool flag = previousLeakTracking.TryGetValue(key, out value);
				if (!flag)
				{
					Plugin.Log.LogMessage((object)" - AssetBundle/Scene was not present on previous checks.");
				}
				foreach (string key2 in bundleLeakTracker.leakCount.Keys)
				{
					int num8 = bundleLeakTracker.leakCount[key2];
					Plugin.Log.LogMessage((object)(" - " + num8 + " " + key2 + " with no known native unity references."));
					if (flag && value.leakCount.ContainsKey(key2))
					{
						int num9 = value.leakCount[key2];
						if (num8 > num9)
						{
							Plugin.Log.LogMessage((object)("   - " + (num8 - num9) + " more than last check."));
						}
					}
				}
				foreach (string key3 in bundleLeakTracker.objectCount.Keys)
				{
					int num10 = bundleLeakTracker.objectCount[key3];
					Plugin.Log.LogMessage((object)(" - " + num10 + " " + (Config.ignoreInactiveObjects.Value ? "Active " : "") + key3 + "."));
					if (flag && value.objectCount.ContainsKey(key3))
					{
						int num11 = value.objectCount[key3];
						if (num10 > num11)
						{
							Plugin.Log.LogMessage((object)("   - " + (num10 - num11) + " more than last check."));
						}
					}
				}
			}
			Plugin.Log.LogMessage((object)"The above counts may be inaccurate, use them as approximations. Objects can be attributed to the wrong bundle/scene in the case of overlapping names.");
			Plugin.Log.LogMessage((object)"Remember that Meshes, Textures, and Materials should be cleaned up manually, but if they have no native unity references they will be cleaned up by UnloadUnusedAssets.");
			Plugin.Log.LogMessage((object)"Unwanted GameObjects will never be cleaned up automatically. Large amounts of GameObjects can be fine, but if these increase day over day there may be an issue.");
		}

		private static void PerformCleanup()
		{
			if (Config.unloadUnused.Value)
			{
				Plugin.Log.LogMessage((object)"Calling Resources.UnloadUnusedAssets().");
				Resources.UnloadUnusedAssets().completed += delegate
				{
					FinishSponge();
				};
			}
			else
			{
				FinishSponge();
			}
		}

		private static int ExamineType<T>() where T : Object
		{
			int num = 0;
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			for (int i = 0; i < array.Length; i++)
			{
				int instanceID = ((Object)array[i]).GetInstanceID();
				if ((!referenceTracking.TryGetValue(instanceID, out var value) || value < 1) && HandleLeakedObject((Object)(object)array[i]))
				{
					num++;
				}
			}
			array = Array.Empty<T>();
			if (num > 0)
			{
				Plugin.Log.LogMessage((object)("Found " + num + " " + typeof(T).Name + " with no known references."));
			}
			return num;
		}

		private static int CountType<T>() where T : Object
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			for (int i = 0; i < array.Length; i++)
			{
				string text = TryGetObjectBundleName(((Object)array[i]).name);
				if (!AssetBundleValid(text))
				{
					continue;
				}
				if (typeof(GameObject).IsAssignableFrom(typeof(T)))
				{
					object obj = array[i];
					GameObject val = (GameObject)((obj is GameObject) ? obj : null);
					Scene scene = val.scene;
					if (((Scene)(ref scene)).name == null)
					{
						continue;
					}
					scene = val.scene;
					if (((Scene)(ref scene)).name == ((Object)val).name || (Config.ignoreInactiveObjects.Value && !val.activeInHierarchy))
					{
						continue;
					}
				}
				if (typeof(Component).IsAssignableFrom(typeof(T)))
				{
					object obj2 = array[i];
					Behaviour val2 = (Behaviour)((obj2 is Behaviour) ? obj2 : null);
					if (Config.ignoreInactiveObjects.Value && (!val2.enabled || !((Component)val2).gameObject.activeInHierarchy))
					{
						continue;
					}
				}
				string name = typeof(T).Name;
				if (fullReportBundles.Contains(text.ToLower()))
				{
					Plugin.Log.LogMessage((object)("Counted " + (Config.ignoreInactiveObjects.Value ? "Active " : "") + name + " with name '" + ((Object)array[i]).name + "' and ID '" + ((Object)array[i]).GetInstanceID() + "' from bundle/scene " + text + "."));
				}
				num++;
				if (leakTracking.ContainsKey(text))
				{
					leakTracking[text].objectCount.TryGetValue(name, out var value);
					leakTracking[text].objectCount[name] = value + 1;
				}
				else
				{
					leakTracking.Add(text, new BundleLeakTracker());
					leakTracking[text].objectCount.Add(name, 1);
				}
			}
			array = Array.Empty<T>();
			if (num > 0)
			{
				Plugin.Log.LogMessage((object)("Found " + num + " " + (Config.ignoreInactiveObjects.Value ? "Active " : "") + typeof(T).Name + "."));
			}
			return num;
		}

		public static void ModelCheck()
		{
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogMessage((object)"---");
			Plugin.Log.LogMessage((object)"Running Sponge Model Check.");
			int num = 0;
			int num2 = 0;
			Dictionary<string, Vector2Int> dictionary = new Dictionary<string, Vector2Int>();
			HashSet<Mesh> hashSet = new HashSet<Mesh>();
			List<MeshFilter> list = new List<MeshFilter>(10);
			MeshFilter[] array = Object.FindObjectsByType<MeshFilter>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			MeshFilter[] array2 = array;
			Vector2Int val2 = default(Vector2Int);
			foreach (MeshFilter val in array2)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null || hashSet.Contains(val.sharedMesh))
				{
					continue;
				}
				string text = TryGetObjectBundleName(((Object)val.sharedMesh).name);
				if (!AssetBundleValid(text))
				{
					continue;
				}
				Renderer component = ((Component)val).gameObject.GetComponent<Renderer>();
				if ((Object)(object)component == (Object)null || !component.isVisible)
				{
					continue;
				}
				int vertexCount = val.sharedMesh.vertexCount;
				((Vector2Int)(ref val2))..ctor(vertexCount, 1);
				num2 += vertexCount;
				num++;
				dictionary.TryGetValue(text, out var value);
				dictionary[text] = value + val2;
				hashSet.Add(val.sharedMesh);
				if ((list.Count < 10 || list[0].sharedMesh.vertexCount < vertexCount) && !list.Contains(val))
				{
					if (list.Count == 10)
					{
						list[0] = val;
					}
					else
					{
						list.Add(val);
					}
					list.Sort((MeshFilter a, MeshFilter b) => a.sharedMesh.vertexCount.CompareTo(b.sharedMesh.vertexCount));
				}
				if (vertexCount <= 1000)
				{
					continue;
				}
				Bounds bounds = component.bounds;
				float x = ((Bounds)(ref bounds)).size.x;
				bounds = component.bounds;
				float num3 = x * ((Bounds)(ref bounds)).size.y;
				bounds = component.bounds;
				float num4 = num3 * ((Bounds)(ref bounds)).size.z;
				float num5 = (float)vertexCount / num4;
				if (num5 > 5000f)
				{
					Plugin.Log.LogWarning((object)("Mesh " + ((Object)val.sharedMesh).name + " for GameObject " + ((Object)((Component)val).gameObject).name + " has vertex density of " + num5));
					Transform val3 = ((Component)val).gameObject.transform;
					while ((Object)(object)val3.parent != (Object)null)
					{
						val3 = val3.parent;
					}
					Plugin.Log.LogWarning((object)(" - " + vertexCount + " vertices over " + num4 + " cubed meters."));
					Plugin.Log.LogWarning((object)(" - On root GameObject " + ((Object)((Component)val3).gameObject).name + "."));
					if (text != "unknown")
					{
						Plugin.Log.LogWarning((object)(" - From the bundle '" + text + "'"));
					}
				}
			}
			Plugin.Log.LogMessage((object)("Found " + num + " Visible Meshes."));
			Plugin.Log.LogMessage((object)("With " + num2 + " Vertices total."));
			foreach (string key in dictionary.Keys)
			{
				if (!(key == "unknown"))
				{
					ManualLogSource log = Plugin.Log;
					string[] obj = new string[5] { " - Bundle '", key, "' contributed ", null, null };
					Vector2Int val4 = dictionary[key];
					obj[3] = ((Vector2Int)(ref val4)).y.ToString();
					obj[4] = " Visible Meshes";
					log.LogMessage((object)string.Concat(obj));
					ManualLogSource log2 = Plugin.Log;
					val4 = dictionary[key];
					log2.LogMessage((object)("   and " + ((Vector2Int)(ref val4)).x + " Vertices total."));
				}
			}
			Plugin.Log.LogMessage((object)("The " + list.Count + " largest meshes were:"));
			foreach (MeshFilter item in list)
			{
				string text2 = TryGetObjectBundleName(((Object)item.sharedMesh).name);
				Plugin.Log.LogMessage((object)(" - Mesh '" + ((Object)item.sharedMesh).name + "' with " + item.sharedMesh.vertexCount + " Vertices"));
				Plugin.Log.LogMessage((object)("   on the GameObject with the name '" + ((Object)((Component)item).gameObject).name + "'"));
				if (text2 != "unknown")
				{
					Plugin.Log.LogMessage((object)("   from the bundle '" + text2 + "'"));
				}
			}
			Plugin.Log.LogMessage((object)"The above counts may be inaccurate. Meshes can be attributed to the wrong bundle/scene in the case of overlapping names.");
			Plugin.Log.LogMessage((object)"---");
		}

		public static void TextureCheck()
		{
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Invalid comparison between Unknown and I4
			//IL_01c2: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: 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_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: 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_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogMessage((object)"---");
			Plugin.Log.LogMessage((object)"Running Sponge Texture Check.");
			int num = 0;
			int num2 = 0;
			Dictionary<string, Vector2Int> dictionary = new Dictionary<string, Vector2Int>();
			HashSet<Texture> hashSet = new HashSet<Texture>();
			List<Texture> list = new List<Texture>(10);
			Renderer[] array = Object.FindObjectsByType<Renderer>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			Renderer[] array2 = array;
			Vector2Int val3 = default(Vector2Int);
			foreach (Renderer val in array2)
			{
				if ((Object)(object)val == (Object)null || !val.isVisible)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if ((Object)(object)val2 == (Object)null || (Object)(object)val2.shader == (Object)null || val2.shader.GetPropertyCount() == 0)
					{
						continue;
					}
					List<Texture> list2 = new List<Texture>();
					for (int k = 0; k < val2.shader.GetPropertyCount(); k++)
					{
						if ((int)val2.shader.GetPropertyType(k) == 4)
						{
							Texture texture = val2.GetTexture(val2.shader.GetPropertyName(k));
							if ((Object)(object)texture != (Object)null)
							{
								list2.Add(texture);
							}
						}
					}
					foreach (Texture item in list2)
					{
						if (hashSet.Contains(item))
						{
							continue;
						}
						string text = TryGetObjectBundleName(((Object)item).name);
						if (!AssetBundleValid(text))
						{
							continue;
						}
						int num3 = item.height * item.width;
						((Vector2Int)(ref val3))..ctor(num2, 1);
						num2 += num3;
						num++;
						dictionary.TryGetValue(text, out var value);
						dictionary[text] = value + val3;
						hashSet.Add(item);
						if ((list.Count < 10 || list[0].height * list[0].width < num3) && !list.Contains(item))
						{
							if (list.Count == 10)
							{
								list[0] = item;
							}
							else
							{
								list.Add(item);
							}
							list.Sort((Texture a, Texture b) => (a.height * a.width).CompareTo(b.height * b.width));
						}
						if (num3 <= 1048576)
						{
							continue;
						}
						Bounds bounds = val.bounds;
						float x = ((Bounds)(ref bounds)).size.x;
						bounds = val.bounds;
						float y = ((Bounds)(ref bounds)).size.y;
						bounds = val.bounds;
						float num4 = Mathf.Max(x, Mathf.Max(y, ((Bounds)(ref bounds)).size.z));
						float num5 = num4 * num4 * num4;
						float num6 = (float)num3 / num5;
						if (num6 > 500000f)
						{
							Plugin.Log.LogWarning((object)("Texture " + ((Object)item).name + " for GameObject " + ((Object)((Component)val).gameObject).name + " has pixel density of " + num6));
							Transform val4 = ((Component)val).gameObject.transform;
							while ((Object)(object)val4.parent != (Object)null)
							{
								val4 = val4.parent;
							}
							Plugin.Log.LogWarning((object)(" - Dimensions " + item.width + "x" + item.height + " for " + num5 + " cubed meters."));
							Plugin.Log.LogWarning((object)(" - On root GameObject " + ((Object)((Component)val4).gameObject).name + "."));
							if (text != "unknown")
							{
								Plugin.Log.LogWarning((object)(" - From the bundle '" + text + "'"));
							}
						}
					}
				}
			}
			Plugin.Log.LogMessage((object)("Found " + num + " Visible Textures."));
			Plugin.Log.LogMessage((object)("With " + num2 + " Pixels total."));
			foreach (string key in dictionary.Keys)
			{
				if (!(key == "unknown"))
				{
					ManualLogSource log = Plugin.Log;
					string[] obj = new string[5] { " - Bundle '", key, "' contributed ", null, null };
					Vector2Int val5 = dictionary[key];
					obj[3] = ((Vector2Int)(ref val5)).y.ToString();
					obj[4] = " Visible Textures";
					log.LogMessage((object)string.Concat(obj));
					ManualLogSource log2 = Plugin.Log;
					val5 = dictionary[key];
					log2.LogMessage((object)("   and " + ((Vector2Int)(ref val5)).x + " Pixels total."));
				}
			}
			Plugin.Log.LogMessage((object)("The " + list.Count + " largest textures were:"));
			foreach (Texture item2 in list)
			{
				string text2 = TryGetObjectBundleName(((Object)item2).name);
				Plugin.Log.LogMessage((object)(" - Texture '" + ((Object)item2).name + "' with dimensions " + item2.width + "x" + item2.height));
				if (text2 != "unknown")
				{
					Plugin.Log.LogMessage((object)("   from the bundle '" + text2 + "'"));
				}
			}
			Plugin.Log.LogMessage((object)"The above counts may be inaccurate. Textures can be attributed to the wrong bundle/scene in the case of overlapping names.");
			Plugin.Log.LogMessage((object)"---");
		}

		public static void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (Config.verboseLogging.Value)
			{
				streamedSceneTracking.TryGetValue(((Scene)(ref scene)).name, out var value);
				GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
				foreach (GameObject obj in rootGameObjects)
				{
					FindGameObjectDependenciesRecursively(value ?? ((Scene)(ref scene)).name, obj);
				}
			}
		}

		public static void DungeonLoaded(DungeonGenerator generator)
		{
			bundleTracking.TryGetValue(((Object)generator.DungeonFlow).name, out var value);
			FindGameObjectDependenciesRecursively(value ?? ((Object)generator.DungeonFlow).name, generator.Root);
		}

		public static void ObjectLoaded(AssetBundle bundle, Object obj)
		{
			string bundleName = FormatBundleName(((Object)bundle).name);
			GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
			Component val2 = (Component)(object)((obj is Component) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				FindGameObjectDependenciesRecursively(bundleName, val);
			}
			else if ((Object)(object)val2 != (Object)null)
			{
				BuildBundleDependencies(bundleName, GetUnityObjectReferences((Object)(object)val2));
			}
			else
			{
				BuildBundleDependencies(bundleName, obj);
			}
		}

		public static void FindGameObjectDependenciesRecursively(string bundleName, GameObject obj)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			bundleTracking[((Object)obj).name.ToLower()] = bundleName;
			Component[] components = obj.GetComponents(typeof(Component));
			foreach (Component val in components)
			{
				if ((Object)(object)val != (Object)null)
				{
					BuildBundleDependencies(bundleName, GetUnityObjectReferences((Object)(object)val));
				}
			}
			foreach (Transform item in obj.transform)
			{
				Transform val2 = item;
				FindGameObjectDependenciesRecursively(bundleName, ((Component)val2).gameObject);
			}
		}

		public static void RegisterAssetBundle(AssetBundle bundle)
		{
			string value = FormatBundleName(((Object)bundle).name);
			if (bundle.isStreamedSceneAssetBundle)
			{
				string[] allScenePaths = bundle.GetAllScenePaths();
				foreach (string path in allScenePaths)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					streamedSceneTracking.TryAdd(fileNameWithoutExtension, value);
				}
			}
			else
			{
				string[] allAssetNames = bundle.GetAllAssetNames();
				foreach (string path2 in allAssetNames)
				{
					string key = Path.GetFileNameWithoutExtension(path2).ToLower();
					bundleTracking.TryAdd(key, value);
				}
			}
		}

		[IteratorStateMachine(typeof(<CheckAllGameObjectDependencies>d__35))]
		public static IEnumerator CheckAllGameObjectDependencies(GameObject[] allGameObjects)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckAllGameObjectDependencies>d__35(0)
			{
				allGameObjects = allGameObjects
			};
		}

		private static string FormatBundleName(string bundleName)
		{
			return ((bundleName == null || bundleName == "") ? "unknown" : bundleName).ToLower();
		}

		private static bool HandleLeakedObject(Object leakedObj)
		{
			string text = TryGetObjectBundleName(leakedObj.name);
			if (!AssetBundleValid(text))
			{
				return false;
			}
			string name = ((object)leakedObj).GetType().Name;
			if (fullReportBundles.Contains(text))
			{
				Plugin.Log.LogMessage((object)("Found suspected leaked " + name + " with name '" + leakedObj.name + "' and ID '" + leakedObj.GetInstanceID() + "' from bundle/scene " + text + "."));
			}
			if (leakTracking.ContainsKey(text))
			{
				leakTracking[text].leakCount.TryGetValue(name, out var value);
				leakTracking[text].leakCount[name] = value + 1;
			}
			else
			{
				leakTracking.Add(text, new BundleLeakTracker());
				leakTracking[text].leakCount.Add(name, 1);
			}
			return true;
		}

		private static string TryGetObjectBundleName(string name)
		{
			string text = name.ToLower();
			bundleTracking.TryGetValue(text, out var value);
			if (value == null)
			{
				bundleTracking.TryGetValue(text.Replace(" (instance)", ""), out value);
			}
			if (value == null)
			{
				bundleTracking.TryGetValue(text.Replace("(clone)", ""), out value);
			}
			if (value == null)
			{
				return "unknown";
			}
			return value;
		}

		public static List<Object> GetUnityObjectReferences(int index)
		{
			Object val = allObjects[index];
			if (val == (Object)null || val == null)
			{
				return new List<Object>();
			}
			return GetUnityObjectReferences(val);
		}

		public static List<Object> GetUnityObjectReferences(Object target)
		{
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Expected O, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Expected O, but got Unknown
			List<Object> list = new List<Object>();
			Type type = ((object)target).GetType();
			try
			{
				if (((object)target).GetType() == typeof(Camera))
				{
					return list;
				}
				if (!assignableFieldsByObjectType.TryGetValue(type, out var value))
				{
					Type type2 = type;
					List<FieldInfo> value2;
					while (true)
					{
						FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (FieldInfo item in fields)
						{
							if (value == null)
							{
								value = new List<FieldInfo>();
							}
							value.Add(item);
						}
						type2 = type2.BaseType;
						if (assignableFieldsByObjectType.TryGetValue(type2, out value2))
						{
							break;
						}
						bool flag = true;
					}
					if (value2 != null)
					{
						if (value == null)
						{
							value = new List<FieldInfo>();
						}
						value.AddRange(value2);
					}
					assignableFieldsByObjectType.Add(type, value);
				}
				if (!assignablePropertiesByObjectType.TryGetValue(type, out var value3))
				{
					Type type3 = type;
					List<PropertyInfo> value4;
					while (true)
					{
						PropertyInfo[] properties = type3.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (PropertyInfo item2 in properties)
						{
							if (value3 == null)
							{
								value3 = new List<PropertyInfo>();
							}
							value3.Add(item2);
						}
						type3 = type3.BaseType;
						if (assignablePropertiesByObjectType.TryGetValue(type3, out value4))
						{
							break;
						}
						bool flag2 = true;
					}
					if (value4 != null)
					{
						if (value3 == null)
						{
							value3 = new List<PropertyInfo>();
						}
						value3.AddRange(value4);
					}
					assignablePropertiesByObjectType.Add(type, value3);
				}
				if (value != null)
				{
					foreach (FieldInfo item3 in value)
					{
						if (!item3.FieldType.IsSubclassOf(typeof(Object)) && !(item3.FieldType == typeof(Object)) && (!typeof(IEnumerable).IsAssignableFrom(item3.FieldType) || !(item3.FieldType != typeof(string))))
						{
							continue;
						}
						if (item3.GetValue(target) is IEnumerable enumerable && !(enumerable is string))
						{
							foreach (object item4 in enumerable)
							{
								Object val = (Object)((item4 is Object) ? item4 : null);
								if (val != (Object)null)
								{
									list.Add(val);
								}
							}
						}
						else
						{
							object? value5 = item3.GetValue(target);
							Object val2 = (Object)((value5 is Object) ? value5 : null);
							if (val2 != (Object)null)
							{
								list.Add(val2);
							}
						}
					}
				}
				if (value3 != null)
				{
					foreach (PropertyInfo item5 in value3)
					{
						string text = (item5.DeclaringType.Name + "." + item5.Name).ToLower();
						if (ignoredProperties.Contains(text) || !item5.CanRead || (!item5.PropertyType.IsSubclassOf(typeof(Object)) && !(item5.PropertyType == typeof(Object)) && (!typeof(IEnumerable).IsAssignableFrom(item5.PropertyType) || !(item5.PropertyType != typeof(string)))) || item5.Name == "Item")
						{
							continue;
						}
						if (target is Material)
						{
							Material val3 = (Material)target;
							if (!val3.HasProperty("_MainTex") && item5.Name == "mainTexture")
							{
								continue;
							}
						}
						if (target is Mesh)
						{
							Mesh val4 = (Mesh)target;
							if (meshReadProperties.Contains(item5.Name))
							{
								continue;
							}
						}
						try
						{
							if (item5.GetValue(target) is IEnumerable enumerable2 && !(enumerable2 is string))
							{
								foreach (object item6 in enumerable2)
								{
									Object val5 = (Object)((item6 is Object) ? item6 : null);
									if (val5 != (Object)null)
									{
										list.Add(val5);
									}
								}
							}
							else
							{
								object? value6 = item5.GetValue(target);
								Object val6 = (Object)((value6 is Object) ? value6 : null);
								if (val6 != (Object)null)
								{
									list.Add(val6);
								}
							}
						}
						catch (Exception ex)
						{
							Plugin.Log.LogWarning((object)("Error while calling " + text + ", continuing:"));
							Plugin.Log.LogWarning((object)ex);
						}
					}
				}
				if (target is Material)
				{
					Material val7 = (Material)target;
					string[] texturePropertyNames = val7.GetTexturePropertyNames();
					foreach (string text2 in texturePropertyNames)
					{
						Texture texture = val7.GetTexture(text2);
						if ((Object)(object)texture != (Object)null)
						{
							list.Add((Object)(object)texture);
						}
					}
				}
				return list;
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("Error while retrieving object references for " + target.name + " of type " + type.Name + ", continuing:"));
				Plugin.Log.LogWarning((object)ex2);
				return list;
			}
		}

		public static void IncrementReferenceCounts(List<Object> references)
		{
			foreach (Object reference in references)
			{
				int instanceID = reference.GetInstanceID();
				referenceTracking.TryGetValue(instanceID, out var value);
				referenceTracking[instanceID] = (ushort)(value + 1);
			}
		}

		public static void BuildBundleDependencies(string bundleName, Object reference)
		{
			if (AssetBundleValid(bundleName) && !(reference == (Object)null) && !bundleTracking.ContainsKey(reference.name.ToLower()))
			{
				bundleTracking[reference.name.ToLower()] = bundleName;
				BuildBundleDependencies(bundleName, GetUnityObjectReferences(reference));
			}
		}

		public static void BuildBundleDependencies(string bundleName, List<Object> references)
		{
			if (!AssetBundleValid(bundleName))
			{
				return;
			}
			foreach (Object reference in references)
			{
				BuildBundleDependencies(bundleName, reference);
			}
		}
	}
}
namespace Scoops.rendering
{
	internal class SpongeCustomPass : CustomPass
	{
		public static Material posterizationMaterial;

		public static Shader posterizationShader;

		public static RTHandle posterizationRT;

		public override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0029: 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)
			posterizationShader = (Shader)Plugin.SpongeAssets.LoadAsset("SpongePosterize");
			posterizationMaterial = CoreUtils.CreateEngineMaterial(posterizationShader);
			posterizationRT = RTHandles.Alloc(Vector2.one, TextureXR.slices, (DepthBits)0, (GraphicsFormat)4, (FilterMode)0, (TextureWrapMode)0, TextureXR.dimension, false, false, true, false, 1, 0f, (MSAASamples)1, false, true, (RenderTextureMemoryless)0, (VRTextureUsage)0, "Posterization Buffer");
		}

		public override void Execute(CustomPassContext ctx)
		{
			//IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			CoreUtils.SetRenderTarget(ctx.cmd, posterizationRT, (ClearFlag)1, 0, (CubemapFace)(-1), -1);
			CoreUtils.DrawFullScreen(ctx.cmd, posterizationMaterial, ctx.propertyBlock, posterizationMaterial.FindPass("ReadColor"));
			ctx.propertyBlock.SetTexture("_PosterizationBuffer", RTHandle.op_Implicit(posterizationRT));
			CoreUtils.SetRenderTarget(ctx.cmd, ctx.cameraColorBuffer, (ClearFlag)0, 0, (CubemapFace)(-1), -1);
			CoreUtils.DrawFullScreen(ctx.cmd, posterizationMaterial, ctx.propertyBlock, posterizationMaterial.FindPass("WriteColor"));
		}

		public override void Cleanup()
		{
			CoreUtils.Destroy((Object)(object)posterizationMaterial);
			posterizationRT.Release();
		}
	}
}
namespace Scoops.patches
{
	[HarmonyPatch]
	public class AssetBundleSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return new MethodInfo[8]
			{
				AccessTools.Method(typeof(AssetBundle), "LoadFromFile", new Type[1] { typeof(string) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromFile", new Type[2]
				{
					typeof(string),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromFile", new Type[3]
				{
					typeof(string),
					typeof(uint),
					typeof(ulong)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromMemory", new Type[1] { typeof(byte[]) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromMemory", new Type[2]
				{
					typeof(byte[]),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStream", new Type[1] { typeof(Stream) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStream", new Type[2]
				{
					typeof(Stream),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStream", new Type[3]
				{
					typeof(Stream),
					typeof(uint),
					typeof(uint)
				}, (Type[])null)
			};
		}

		private static void Postfix(ref AssetBundle __result)
		{
			SpongeService.RegisterAssetBundle(__result);
		}
	}
	[HarmonyPatch]
	public class AssetBundleAsyncSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return new MethodInfo[8]
			{
				AccessTools.Method(typeof(AssetBundle), "LoadFromFileAsync", new Type[1] { typeof(string) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromFileAsync", new Type[2]
				{
					typeof(string),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromFileAsync", new Type[3]
				{
					typeof(string),
					typeof(uint),
					typeof(ulong)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromMemoryAsync", new Type[1] { typeof(byte[]) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromMemoryAsync", new Type[2]
				{
					typeof(byte[]),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStreamAsync", new Type[1] { typeof(Stream) }, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStreamAsync", new Type[2]
				{
					typeof(Stream),
					typeof(uint)
				}, (Type[])null),
				AccessTools.Method(typeof(AssetBundle), "LoadFromStreamAsync", new Type[3]
				{
					typeof(Stream),
					typeof(uint),
					typeof(uint)
				}, (Type[])null)
			};
		}

		private static void Postfix(ref AssetBundleCreateRequest __result)
		{
			if (((AsyncOperation)__result).isDone)
			{
				SpongeService.RegisterAssetBundle(__result.assetBundle);
				return;
			}
			((AsyncOperation)__result).completed += delegate(AsyncOperation asyncOperation)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				SpongeService.RegisterAssetBundle(((AssetBundleCreateRequest)asyncOperation).assetBundle);
			};
		}
	}
	[HarmonyPatch]
	public class AssetBundleLoadSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from x in AccessTools.GetDeclaredMethods(typeof(AssetBundle))
				where x.Name.Equals("LoadAsset")
				where !x.IsGenericMethod
				select x;
		}

		private static void Postfix(ref AssetBundle __instance, ref Object __result)
		{
			SpongeService.ObjectLoaded(__instance, __result);
		}
	}
	[HarmonyPatch]
	public class AssetBundleLoadAsyncSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from x in AccessTools.GetDeclaredMethods(typeof(AssetBundle))
				where x.Name.Equals("LoadAssetAsync")
				where !x.IsGenericMethod
				select x;
		}

		private static void Postfix(ref AssetBundle __instance, ref AssetBundleRequest __result)
		{
			AssetBundle bundle = __instance;
			if (((AsyncOperation)__result).isDone)
			{
				SpongeService.ObjectLoaded(bundle, __result.asset);
				return;
			}
			((AsyncOperation)__result).completed += delegate(AsyncOperation asyncOperation)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				SpongeService.ObjectLoaded(bundle, ((AssetBundleRequest)asyncOperation).asset);
			};
		}
	}
	[HarmonyPatch]
	public class AssetBundleLoadMultipleSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from x in AccessTools.GetDeclaredMethods(typeof(AssetBundle))
				where x.Name.Equals("LoadAllAssets") || x.Name.Equals("LoadAssetWithSubAssets")
				where !x.IsGenericMethod
				select x;
		}

		private static void Postfix(ref AssetBundle __instance, ref Object[] __result)
		{
			if (__result != null)
			{
				Object[] array = __result;
				foreach (Object obj in array)
				{
					SpongeService.ObjectLoaded(__instance, obj);
				}
			}
		}
	}
	[HarmonyPatch]
	public class AssetBundleLoadMultipleAsyncSpongePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from x in AccessTools.GetDeclaredMethods(typeof(AssetBundle))
				where x.Name.Equals("LoadAllAssetsAsync") || x.Name.Equals("LoadAssetWithSubAssetsAsync")
				where !x.IsGenericMethod
				select x;
		}

		private static void Postfix(ref AssetBundle __instance, ref AssetBundleRequest __result)
		{
			AssetBundle bundle = __instance;
			if (((AsyncOperation)__result).isDone)
			{
				Object[] allAssets = __result.allAssets;
				foreach (Object obj in allAssets)
				{
					SpongeService.ObjectLoaded(bundle, obj);
				}
				return;
			}
			((AsyncOperation)__result).completed += delegate(AsyncOperation asyncOperation)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				Object[] allAssets2 = ((AssetBundleRequest)asyncOperation).allAssets;
				foreach (Object obj2 in allAssets2)
				{
					SpongeService.ObjectLoaded(bundle, obj2);
				}
			};
		}
	}
	[HarmonyPatch(typeof(FoliageDetailDistance))]
	public class FoliageDetailDistanceSpongePatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool FoliageDetailDistance_Update(ref FoliageDetailDistance __instance)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.localPlayerTransform == (Object)null)
			{
				return false;
			}
			if (__instance.updateInterval >= 0f)
			{
				FoliageDetailDistance obj = __instance;
				obj.updateInterval -= Time.deltaTime;
			}
			else if (__instance.bushIndex < __instance.allBushRenderers.Count)
			{
				if ((Object)(object)__instance.allBushRenderers[__instance.bushIndex] == (Object)null)
				{
					return false;
				}
				Vector3 val = __instance.localPlayerTransform.position - ((Component)__instance.allBushRenderers[__instance.bushIndex]).transform.position;
				if (((Vector3)(ref val)).sqrMagnitude > 5625f)
				{
					if ((Object)(object)((Renderer)__instance.allBushRenderers[__instance.bushIndex]).sharedMaterial != (Object)(object)__instance.lowDetailMaterial)
					{
						((Renderer)__instance.allBushRenderers[__instance.bushIndex]).sharedMaterial = __instance.lowDetailMaterial;
					}
				}
				else if ((Object)(object)((Renderer)__instance.allBushRenderers[__instance.bushIndex]).sharedMaterial != (Object)(object)__instance.highDetailMaterial)
				{
					((Renderer)__instance.allBushRenderers[__instance.bushIndex]).sharedMaterial = __instance.highDetailMaterial;
				}
				FoliageDetailDistance obj2 = __instance;
				obj2.bushIndex++;
			}
			else
			{
				__instance.bushIndex = 0;
				__instance.updateInterval = 1f;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(HDRenderPipeline))]
	[HarmonyPatch("RecordRenderGraph")]
	public static class HDRenderPipeline_RecordRenderGraph_Patch
	{
		private static readonly List<CodeInstruction> instructionsToInsert = new List<CodeInstruction>
		{
			new CodeInstruction(OpCodes.Ldarg_0, (object)null),
			new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(HDRenderPipeline), "m_RenderGraph")),
			new CodeInstruction(OpCodes.Ldloc_1, (object)null),
			new CodeInstruction(OpCodes.Ldloc_S, (object)8),
			new CodeInstruction(OpCodes.Ldloca_S, (object)13),
			new CodeInstruction(OpCodes.Ldloc_3, (object)null),
			new CodeInstruction(OpCodes.Ldloc_2, (object)null),
			new CodeInstruction(OpCodes.Ldc_I4_7, (object)null),
			new CodeInstruction(OpCodes.Ldarg_2, (object)null),
			new CodeInstruction(OpCodes.Ldarg_S, (object)4),
			CodeInstruction.Call(typeof(HDRenderPipeline), "RenderCustomPass", (Type[])null, (Type[])null),
			new CodeInstruction(OpCodes.Pop, (object)null),
			new CodeInstruction(OpCodes.Ldarg_0, (object)null)
		};

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Call && CodeInstructionExtensions.Calls(list[i], AccessTools.Method(typeof(HDRenderPipeline), "RenderSubsurfaceScattering", (Type[])null, (Type[])null)) && list[i + 1].opcode == OpCodes.Ldarg_0)
				{
					num = i + 2;
					break;
				}
			}
			if (num != -1)
			{
				list.InsertRange(num, instructionsToInsert);
			}
			return list;
		}
	}
	public static class InputActionSpongePatches
	{
		public static PlayerActions Actions;

		public static void Init()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Actions = new PlayerActions();
			Actions.Enable();
			InputSystem.settings.SetInternalFeatureFlag("USE_OPTIMIZED_CONTROLS", true);
			InputSystem.settings.SetInternalFeatureFlag("USE_READ_VALUE_CACHING", true);
		}

		[HarmonyPatch(typeof(DeferBindingResolutionWrapper))]
		[HarmonyPatch("Dispose")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DeferBindingResolutionWrapper_Dispose_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 2; i++)
			{
				if (CodeInstructionExtensions.LoadsField(list[i], AccessTools.Field(typeof(InputActionMap), "s_DeferBindingResolution"), false) && list[i + 1].opcode == OpCodes.Brtrue_S && CodeInstructionExtensions.Calls(list[i + 2], AccessTools.Method(typeof(InputActionState), "DeferredResolutionOfBindings", (Type[])null, (Type[])null)))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveRange(num, 3);
			}
			return list;
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		[HarmonyPatch("Look_performed")]
		[HarmonyPrefix]
		private static bool PlayerControllerB_Look_performed(ref PlayerControllerB __instance, ref CallbackContext context)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer)
			{
				return false;
			}
			if (__instance.quickMenuManager.isMenuOpen || __instance.inSpecialMenu)
			{
				Vector2 val = ((CallbackContext)(ref context)).ReadValue<Vector2>();
				if (((Vector2)(ref val)).magnitude > 0.001f)
				{
					Cursor.visible = true;
				}
				return false;
			}
			StartOfRound.Instance.localPlayerUsingController = !InputControlPath.MatchesPrefix("<Mouse>", ((CallbackContext)(ref context)).control);
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PlayerControllerB_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(PlayerControllerB), "playerActions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		[HarmonyPatch("OnDisable")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PlayerControllerB_OnDisable_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 6; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 1], AccessTools.Field(typeof(PlayerControllerB), "playerActions"), false) && list[i + 2].opcode == OpCodes.Callvirt && list[i + 3].opcode == OpCodes.Stloc_1 && list[i + 4].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 5], AccessTools.Method(typeof(MovementActions), "Enable", (Type[])null, (Type[])null)))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveRange(num, 6);
			}
			num = -1;
			for (int j = 0; j < list.Count - 6; j++)
			{
				if (list[j].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[j + 1], AccessTools.Field(typeof(PlayerControllerB), "playerActions"), false) && list[j + 2].opcode == OpCodes.Callvirt && list[j + 3].opcode == OpCodes.Stloc_1 && list[j + 4].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[j + 5], AccessTools.Method(typeof(MovementActions), "Disable", (Type[])null, (Type[])null)))
				{
					num = j;
					break;
				}
			}
			if (num != -1)
			{
				List<Label> labels = list[num].labels;
				list.RemoveRange(num, 6);
				list[num].labels.AddRange(labels);
			}
			return list;
		}

		[HarmonyPatch(typeof(DisableMouseInMenu))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DisableMouseInMenu_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(DisableMouseInMenu), "actions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}

		[HarmonyPatch(typeof(HUDManager))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HUDManager_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(HUDManager), "playerActions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}

		[HarmonyPatch(typeof(HUDManager))]
		[HarmonyPatch("OnDisable")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HUDManager_OnDisable_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 6; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 1], AccessTools.Field(typeof(HUDManager), "playerActions"), false) && list[i + 2].opcode == OpCodes.Callvirt && list[i + 3].opcode == OpCodes.Stloc_0 && list[i + 4].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 5], AccessTools.Method(typeof(MovementActions), "Disable", (Type[])null, (Type[])null)))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveRange(num, 6);
			}
			return list;
		}

		[HarmonyPatch(typeof(InitializeGame))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InitializeGame_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(InitializeGame), "playerActions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}

		[HarmonyPatch(typeof(InitializeGame))]
		[HarmonyPatch("OnDisable")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> InitializeGame_OnDisable_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 6; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 1], AccessTools.Field(typeof(InitializeGame), "playerActions"), false) && list[i + 2].opcode == OpCodes.Callvirt && list[i + 3].opcode == OpCodes.Stloc_0 && list[i + 4].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 5], AccessTools.Method(typeof(MovementActions), "Disable", (Type[])null, (Type[])null)))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveRange(num, 6);
			}
			return list;
		}

		[HarmonyPatch(typeof(ShipBuildModeManager))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ShipBuildModeManager_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(ShipBuildModeManager), "playerActions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}

		[HarmonyPatch(typeof(ShipBuildModeManager))]
		[HarmonyPatch("OnDisable")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ShipBuildModeManager_OnDisable_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 6; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 1], AccessTools.Field(typeof(ShipBuildModeManager), "playerActions"), false) && list[i + 2].opcode == OpCodes.Callvirt && list[i + 3].opcode == OpCodes.Stloc_0 && list[i + 4].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 5], AccessTools.Method(typeof(MovementActions), "Disable", (Type[])null, (Type[])null)))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveRange(num, 6);
			}
			return list;
		}

		[HarmonyPatch(typeof(Terminal))]
		[HarmonyPatch("Awake")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Terminal_Awake_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Newobj && CodeInstructionExtensions.StoresField(list[i + 1], AccessTools.Field(typeof(Terminal), "playerActions")))
				{
					num = i;
					break;
				}
			}
			if (num != -1)
			{
				list.RemoveAt(num);
				list.Insert(num, new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(InputActionSpongePatches), "Actions")));
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(ManualCameraRenderer))]
	public class ManualCameraRendererSpongePatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void ManualCameraRenderer_Update(ref ManualCameraRenderer __instance)
		{
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !__instance.overrideCameraForOtherUse)
			{
				return;
			}
			if ((Object)(object)__instance.mesh != (Object)null && !MeshVisible(GameNetworkManager.Instance.localPlayerController.gameplayCamera, __instance.mesh))
			{
				((Behaviour)__instance.cam).enabled = false;
			}
			else if (__instance.renderAtLowerFramerate)
			{
				((Behaviour)__instance.cam).enabled = false;
				ManualCameraRenderer obj = __instance;
				obj.elapsed += Time.deltaTime;
				if (__instance.elapsed > 1f / __instance.fps)
				{
					__instance.elapsed = 0f;
					__instance.cam.Render();
				}
			}
			else
			{
				((Behaviour)__instance.cam).enabled = true;
			}
		}

		[HarmonyPatch("MeetsCameraEnabledConditions")]
		[HarmonyAfter(new string[] { "Zaggy1024.OpenBodyCams" })]
		[HarmonyPostfix]
		private static void ManualCameraRenderer_MeetsCameraEnabledConditions(ref ManualCameraRenderer __instance, ref bool __result, PlayerControllerB player)
		{
			if ((Object)(object)__instance.mesh != (Object)null && !MeshVisible(player.gameplayCamera, __instance.mesh))
			{
				__result = false;
			}
			if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance.mapScreen && !__result && !((Object)(object)CameraService.MainTerminal == (Object)null) && (Object)(object)CameraService.MainTerminal.displayingPersistentImage == (Object)(object)__instance.mapCamera.activeTexture && ((Behaviour)CameraService.MainTerminal.terminalUIScreen).isActiveAndEnabled)
			{
				__result = true;
			}
		}

		private static bool MeshVisible(Camera camera, MeshRenderer mesh)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Plane[] array = GeometryUtility.CalculateFrustumPlanes(camera);
			if (Object.op_Implicit((Object)(object)((Component)mesh).GetComponent<Collider>()))
			{
				return GeometryUtility.TestPlanesAABB(array, ((Component)mesh).GetComponent<Collider>().bounds);
			}
			if (Object.op_Implicit((Object)(object)((Component)mesh).GetComponent<Renderer>()))
			{
				return GeometryUtility.TestPlanesAABB(array, ((Component)mesh).GetComponent<Renderer>().bounds);
			}
			return !array.Any((Plane plane) => ((Plane)(ref plane)).GetDistanceToPoint(((Component)mesh).transform.position) < 0f);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class PlayerControllerBSpongePatch
	{
		[HarmonyPatch("ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void PlayerControllerB_ConnectClientToPlayerObject(ref PlayerControllerB __instance)
		{
			CameraService.ApplyPlayerCameraPatch(__instance);
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public class RoundManagerSpongePatch
	{
		[HarmonyPatch("FinishGeneratingLevel")]
		[HarmonyPostfix]
		private static void RoundManager_FinishGeneratingLevel(ref RoundManager __instance)
		{
			SpongeService.DungeonLoaded(__instance.dungeonGenerator.Generator);
			if (Config.changeLightFadeDistance.Value)
			{
				LightService.UpdateAllLights();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundSpongePatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartOfRound_Start(ref StartOfRound __instance)
		{
			SpongeService.Initialize();
			if (Config.fixCameraSettings.Value && CameraService.Init())
			{
				CameraService.ApplyCameraFixes();
			}
			if (Config.removePosterizationShader.Value)
			{
				CameraService.DisablePosterization();
			}
		}

		[HarmonyPatch("PassTimeToNextDay")]
		[HarmonyPostfix]
		private static void StartOfRound_PassTimeToNextDay(ref StartOfRound __instance)
		{
			if (SpongeService.enabled)
			{
				SpongeService.ApplySponge();
			}
		}

		[HarmonyPatch("SwitchCamera")]
		[HarmonyPostfix]
		private static void StartOfRound_SwitchCamera(ref StartOfRound __instance, Camera newCamera)
		{
			if (Config.removePosterizationShader.Value && Config.useCustomShader.Value)
			{
				CameraService.UpdateCamera(newCamera);
			}
		}

		[HarmonyPatch(typeof(HUDManager))]
		[HarmonyPatch("AddTextToChatOnServer")]
		[HarmonyPrefix]
		private static bool HUDManager_AddTextToChatOnServer(ref HUDManager __instance, string chatMessage, int playerId)
		{
			if (chatMessage.ToLower() == "/sponge help")
			{
				__instance.AddChatMessage("'/sponge': Run Sponge.\n'/sponge evaluate': Run Sponge Evaluation only.\n'/sponge clean': Run Sponge Cleanup only.\n'/sponge toggle': Toggle Sponge daily auto activate.\n'/sponge modelcheck': Ask Sponge for a readout of the meshes currently rendering.\n'/sponge texturecheck': Ask Sponge for a readout of the textures currently rendering.\n", "");
				return false;
			}
			if (chatMessage.ToLower() == "/sponge")
			{
				__instance.AddChatMessage("Applying Sponge.", "");
				SpongeService.ApplySponge();
				return false;
			}
			if (chatMessage.ToLower() == "/sponge evaluate")
			{
				__instance.AddChatMessage("Applying Sponge evaluate.", "");
				SpongeService.ApplySponge(SpongeMode.Evaluate);
				return false;
			}
			if (chatMessage.ToLower() == "/sponge clean")
			{
				__instance.AddChatMessage("Applying Sponge cleanup.", "");
				SpongeService.ApplySponge(SpongeMode.Clean);
				return false;
			}
			i