Decompiled source of LowSpecGaming v0.2.2

LowSpecGaming.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using AK;
using AssetShards;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using ChainedPuzzles;
using CullingSystem;
using Decals;
using Enemies;
using FluffyUnderware.Curvy;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LowSpecGaming.Misc;
using LowSpecGaming.Patches;
using Microsoft.CodeAnalysis;
using ShaderValueAnimation;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("LowSpecGaming")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LowSpecGaming")]
[assembly: AssemblyTitle("LowSpecGaming")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
}
namespace LowSpecGaming
{
	[BepInPlugin("Mushroom.LowSpecGaming", "LowSpecGaming", "0.2.1")]
	public class EntryPoint : BasePlugin
	{
		public static ConfigEntry<DynamicResolution> dynamicResolution;

		public static ConfigEntry<TreeDrawing> treeDrawing;

		public static ConfigEntry<GameEnvironment> gameEnvironment;

		public static ConfigEntry<BioScanBlink> BioScanUpdate;

		public static ConfigEntry<HateSpitter> hateSpitter;

		public static ConfigEntry<EnemyBehaviourCulling> enemyBehaviourCulling;

		public static ConfigEntry<string> currentFolderPath;

		public static ConfigEntry<bool> dumpTexture;

		public static ConfigEntry<TextureSize> textureSize;

		public static ConfigEntry<Experimental> redundantComponents;

		public static ConfigFile configFile;

		public static EntryPoint e;

		public override void Load()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			e = this;
			Harmony val = new Harmony("Mushroom.LowSpecGaming");
			((BasePlugin)this).Log.LogInfo((object)"Mushroom Low Spec Gaming is IN~!!");
			GetTheSettings();
			ClassInjector.RegisterTypeInIl2Cpp<LowSpecGaming>();
			Detour_DrawMeshInstancedIndirect.CreateDetour();
			SightPatch.sightPaths = new Dictionary<string, string[]>();
			SightPatch.GetSightFolders();
			LogIt(Paths.BepInExRootPath);
			val.PatchAll();
		}

		public static void GetTheSettings()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "mushroom.lowspecgaming.cfg"), true);
			dynamicResolution = configFile.Bind<DynamicResolution>("Setup", "dynamicResolution", DynamicResolution.Stable, "Scales down your resolution whenever you move your camera, will improve this in the future");
			treeDrawing = configFile.Bind<TreeDrawing>("Setup", "treeDrawing", TreeDrawing.Draw, "whether or not to draw IRF like trees and tentacles");
			gameEnvironment = configFile.Bind<GameEnvironment>("Setup", "gameEnvironment", GameEnvironment.Full, "Reduce fog distance, shadow distance, no more dust particles (requires restart to take effect)");
			BioScanUpdate = configFile.Bind<BioScanBlink>("Setup", "BioScanUpdate", BioScanBlink.DontBlink, "Whether or not Bio Scans would blink, courtesy to McCad, this is his online code");
			hateSpitter = configFile.Bind<HateSpitter>("Setup", "hateSpitter", HateSpitter.HATE, "If you hate spitters, make them low quality");
			enemyBehaviourCulling = configFile.Bind<EnemyBehaviourCulling>("Setup", "enemyBehaviourCulling", EnemyBehaviourCulling.Full, "Reduce Enemy Update in order to save performance, will improve this feature in the future for better performance");
			textureSize = configFile.Bind<TextureSize>("Setup", "textureSize", TextureSize.Full, "Texture size, for the potata army");
			redundantComponents = configFile.Bind<Experimental>("Setup", "redundantComponents", Experimental.TurnOn, "VERY EXPERIMENTAL, turn off some redundant compenents in game || You might gain 5fps");
			currentFolderPath = configFile.Bind<string>("Setup", "currentFolderPath", "", "Manual Path to the current folder that has the plugin if it fails to load normally, This will be removed soon");
			dumpTexture = configFile.Bind<bool>("Setup", "dumpTexture", false, "Dump and extract sight textures in order to load hi res textures even at low res texture settings");
		}

		public static void LogIt(object data)
		{
			((BasePlugin)e).Log.LogInfo(data);
		}

		public override bool Unload()
		{
			return ((BasePlugin)this).Unload();
		}

		public static void DecompressFolder(string compressedFilePath, string decompressedFolderPath)
		{
			ZipFile.ExtractToDirectory(compressedFilePath, decompressedFolderPath);
			LogIt("Folder decompressed successfully.");
		}
	}
	public enum BioScanBlink
	{
		Blink,
		DontBlink
	}
	public enum GameEnvironment
	{
		Full,
		Reduced
	}
	public enum TreeDrawing
	{
		Draw,
		DontDraw
	}
	public enum DynamicResolution
	{
		Stable,
		Dynamic
	}
	public enum HateSpitter
	{
		HATE,
		LOVE
	}
	public enum EnemyBehaviourCulling
	{
		Full,
		Reduced
	}
	public enum Experimental
	{
		TurnOn,
		TurnOff
	}
	public enum TextureSize
	{
		Full,
		Half,
		Quater,
		Eigth,
		Low,
		PentaLow,
		VeryLow,
		SuperLow,
		UltraLow,
		POTATA,
		YouLiveLikeThis
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Mushroom.LowSpecGaming";

		public const string PLUGIN_NAME = "LowSpecGaming";

		public const string PLUGIN_VERSION = "0.2.1";

		public const string AUTHOR = "time1pm";

		public const string BRANCH = "beta";

		public const string INTERNAL_VERSION = "000589";
	}
	internal class LowSpecGaming : MonoBehaviour
	{
		public static List<Texture2D> lightTextures;

		public static Texture2D text;

		public void Start()
		{
			EntryPoint.GetTheSettings();
			lightTextures = new List<Texture2D>();
			LevelAPI.OnEnterLevel += HateTheGameFeel;
			LevelAPI.OnEnterLevel += ClusterRenderingOff;
			EntryPoint.LogIt("Applying settings in 10s");
			((MonoBehaviour)this).Invoke("ApplySettings", 10f);
			((MonoBehaviour)this).Invoke("GetFlashLights", 10f);
		}

		public void GetFlashLights()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (!EntryPoint.dumpTexture.Value)
			{
				return;
			}
			Il2CppArrayBase<FlashlightSettingsDataBlock> allBlocks = GameDataBlockBase<FlashlightSettingsDataBlock>.GetAllBlocks();
			foreach (FlashlightSettingsDataBlock item in allBlocks)
			{
				lightTextures.Add(((Il2CppObjectBase)AssetShardManager.GetLoadedAsset(item.cookie, false)).Cast<Texture2D>());
			}
			foreach (Texture2D lightTexture in lightTextures)
			{
				try
				{
					RenderTexture temporary = RenderTexture.GetTemporary(((Texture)lightTexture).width, ((Texture)lightTexture).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
					RenderTexture active = RenderTexture.active;
					Graphics.Blit((Texture)(object)lightTexture, temporary);
					RenderTexture.active = active;
					Texture2D val = new Texture2D(((Texture)lightTexture).width, ((Texture)lightTexture).height);
					active = RenderTexture.active;
					RenderTexture.active = temporary;
					val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
					val.Apply();
					RenderTexture.ReleaseTemporary(temporary);
					byte[] bytes = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val));
					string text = Paths.BepInExRootPath + "\\LowSpec\\";
					if (!Directory.Exists(text))
					{
						Directory.CreateDirectory(text);
					}
					if (!Directory.Exists(text + "FlashLights\\"))
					{
						Directory.CreateDirectory(text + "FlashLights\\");
					}
					File.WriteAllBytes(text + "FlashLights\\" + ((Object)lightTexture).name + ".png", bytes);
				}
				catch
				{
					EntryPoint.LogIt("Skipping Texture");
				}
			}
		}

		public void ApplySettings()
		{
			int value = 10;
			EntryPoint.LogIt("Apply Settings");
			StartUpSettings.PotatoTexture(ref value);
		}

		private static void HateTheGameFeel()
		{
			if (EntryPoint.gameEnvironment.Value != 0)
			{
				((Behaviour)((Component)PreLitVolume.Current).gameObject.GetComponent<AmbientParticles>()).enabled = false;
				PreLitVolume.Current.m_fogDistance = 45f;
				PreLitVolume.Current.FogPostBlur = 1;
				PreLitVolume.Current.FogShadowSamples = 0;
				PreLitVolume.Current.IndirectBlurSamples = 0;
				PreLitVolume.Current.IndirectDownsampling = 0;
				QualitySettings.shadowDistance = 15f;
				QualitySettings.softParticles = false;
			}
		}

		public static void ClusterRenderingOff()
		{
			if (EntryPoint.redundantComponents.Value != 0)
			{
				((Behaviour)ClusteredRendering.Current).enabled = false;
			}
		}
	}
	[HarmonyPatch]
	internal class StartUpSettings
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartMainGame), "Start")]
		public static void MakeItWork(StartMainGame __instance)
		{
			((Component)__instance).gameObject.AddComponent<LowSpecGaming>();
			QualitySettings.masterTextureLimit = 0;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CellSettingsApply), "ApplyTextureSize")]
		public static bool PotatoTexture(ref int value)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			EntryPoint.GetTheSettings();
			ResolutionPatch.dynamic = EntryPoint.dynamicResolution.Value == DynamicResolution.Dynamic;
			ResolutionPatch.markerLayer = ((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(0)).GetComponent<UI_Canvas>();
			ResolutionPatch.canvasScale = CellSettingsManager.SettingsData.Video.Resolution.Value.y / 1080f;
			SpitterPatch.hate = EntryPoint.hateSpitter.Value == HateSpitter.HATE;
			BioScanPatch.update = EntryPoint.BioScanUpdate.Value == BioScanBlink.Blink;
			Detour_DrawMeshInstancedIndirect.draw = EntryPoint.treeDrawing.Value == TreeDrawing.Draw;
			RedundantMethods.experimentalOn = EntryPoint.redundantComponents.Value == Experimental.TurnOn;
			if (EntryPoint.dumpTexture.Value)
			{
				QualitySettings.masterTextureLimit = 0;
			}
			else
			{
				value = (int)EntryPoint.textureSize.Value;
				if (QualitySettings.masterTextureLimit != value)
				{
					QualitySettings.masterTextureLimit = value;
				}
			}
			return false;
		}
	}
}
namespace LowSpecGaming.Patches
{
	[HarmonyPatch]
	internal class CullingPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(C_CullingCluster), "Show")]
		public static bool BuildItDOWN(C_CullingCluster __instance)
		{
			if (((C_Cullable)__instance).IsShown)
			{
				return false;
			}
			((C_Cullable)__instance).IsShown = true;
			foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)__instance.Renderers)
			{
				item.enabled = true;
			}
			C_CullingManager.Register((C_Cullable)(object)__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(C_CullingCluster), "Hide")]
		public static bool BuildItUP(C_CullingCluster __instance)
		{
			if (!((C_Cullable)__instance).IsShown)
			{
				return false;
			}
			((C_Cullable)__instance).IsShown = false;
			foreach (Renderer item in (Il2CppArrayBase<Renderer>)(object)__instance.Renderers)
			{
				item.enabled = false;
			}
			return false;
		}
	}
	[Harmony]
	[HarmonyPatch]
	internal static class Detour_DrawMeshInstancedIndirect
	{
		private unsafe delegate void DrawDelegate(IntPtr mesh, int submeshIndex, IntPtr material, IntPtr bounds, IntPtr bufferWithArgs, int argsOffset, IntPtr properties, int castShadows, byte receiveShadows, int layer, IntPtr camera, int lightProbeUsage, IntPtr lightProbeProxyVolume, Il2CppMethodInfo* methodInfo);

		public static IntPtr DrawMeshCamera = IntPtr.Zero;

		public static bool draw = true;

		private static DrawDelegate _Original;

		private static INativeDetour _Detour;

		public unsafe static void CreateDetour()
		{
			DetourDescription detourDescription = default(DetourDescription);
			detourDescription.Type = typeof(Graphics);
			detourDescription.MethodName = "DrawMeshInstancedIndirect";
			detourDescription.ReturnType = typeof(void);
			detourDescription.ArgTypes = new Type[1] { typeof(Camera) };
			detourDescription.IsGeneric = false;
			DetourDescription description = detourDescription;
			Detour.TryCreate<DrawDelegate>(description, Detour_Draw, out _Original, out _Detour);
		}

		private unsafe static void Detour_Draw(IntPtr mesh, int submeshIndex, IntPtr material, IntPtr bounds, IntPtr bufferWithArgs, int argsOffset, IntPtr properties, int castShadows, byte receiveShadows, int layer, IntPtr camera, int lightProbeUsage, IntPtr lightProbeProxyVolume, Il2CppMethodInfo* methodInfo)
		{
			if (draw)
			{
				camera = DrawMeshCamera;
				_Original(mesh, submeshIndex, material, bounds, bufferWithArgs, argsOffset, properties, castShadows, receiveShadows, layer, camera, lightProbeUsage, lightProbeProxyVolume, methodInfo);
			}
		}
	}
	public static class Detour
	{
		public unsafe delegate void StaticVoidDelegate(Il2CppMethodInfo* methodInfo);

		public unsafe delegate void InstanceVoidDelegate(IntPtr instance, Il2CppMethodInfo* methodInfo);

		public static bool TryCreate<T>(DetourDescription description, T to, out T originalCall, out INativeDetour detourInstance) where T : Delegate
		{
			try
			{
				detourInstance = INativeDetour.CreateAndApply<T>((IntPtr)description.GetMethodPointer(), to, ref originalCall);
				return detourInstance != null;
			}
			catch
			{
			}
			originalCall = null;
			detourInstance = null;
			return false;
		}
	}
	public struct DetourDescription
	{
		public Type Type;

		public Type ReturnType;

		public Type[] ArgTypes;

		public string MethodName;

		public bool IsGeneric;

		public unsafe nint GetMethodPointer()
		{
			if (Type == null)
			{
				throw new MissingFieldException("Field Type is not set!");
			}
			if (ReturnType == null)
			{
				throw new MissingFieldException("Field ReturnType is not set! If you mean 'void' do typeof(void)");
			}
			if (string.IsNullOrEmpty(MethodName))
			{
				throw new MissingFieldException("Field MethodName is not set or valid!");
			}
			Type val = Il2CppType.From(Type, true);
			IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(Type);
			Type val2 = Il2CppType.From(ReturnType, true);
			Type[] array;
			if (ArgTypes == null || ArgTypes.Length == 0)
			{
				array = Array.Empty<Type>();
			}
			else
			{
				int num = ArgTypes.Length;
				array = (Type[])(object)new Type[num];
				for (int i = 0; i < num; i++)
				{
					Type type = ArgTypes[i];
					array[i] = Il2CppType.From(type, true);
				}
			}
			string[] array2 = array.Select((Type t) => t.FullName).ToArray();
			void** ptr = (void**)IL2CPP.GetIl2CppMethod(nativeClassPointer, IsGeneric, MethodName, val2.FullName, array2).ToPointer();
			if (ptr == null)
			{
				return (nint)ptr;
			}
			return (nint)(*ptr);
		}
	}
	[HarmonyPatch]
	internal class EnemyPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(EnemyUpdateManager), "Setup")]
		public static bool EnemyCulling(EnemyUpdateManager __instance)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			if (EntryPoint.enemyBehaviourCulling.Value == EnemyBehaviourCulling.Full)
			{
				return true;
			}
			ShaderValueAnimator.ManagerSetup();
			__instance.m_nodeUpdates = new UpdateNodeGroup();
			((SteppedUpdateGroup<AIG_CourseNode>)(object)__instance.m_nodeUpdates).Setup(1, (SteppedUpdateGroup)null);
			__instance.m_locomotionUpdatesClose = new UpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_locomotionUpdatesClose).Setup(12, (SteppedUpdateGroup)null);
			__instance.m_locomotionUpdatesNear = new UpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_locomotionUpdatesNear).Setup(5, (SteppedUpdateGroup)(object)__instance.m_locomotionUpdatesClose);
			__instance.m_locomotionUpdatesFar = new UpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_locomotionUpdatesFar).Setup(5, (SteppedUpdateGroup)(object)__instance.m_locomotionUpdatesNear);
			__instance.m_fixedLocomotionUpdatesClose = new FixedUpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_fixedLocomotionUpdatesClose).Setup(3, (SteppedUpdateGroup)null);
			__instance.m_fixedLocomotionUpdatesNear = new FixedUpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_fixedLocomotionUpdatesNear).Setup(1, (SteppedUpdateGroup)(object)__instance.m_fixedLocomotionUpdatesClose);
			__instance.m_fixedLocomotionUpdatesFar = new FixedUpdateLocomotionGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_fixedLocomotionUpdatesFar).Setup(1, (SteppedUpdateGroup)(object)__instance.m_fixedLocomotionUpdatesNear);
			__instance.m_behaviourUpdatesClose = new UpdateBehaviourGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_behaviourUpdatesClose).Setup(2, (SteppedUpdateGroup)null);
			__instance.m_behaviourUpdatesNear = new UpdateBehaviourGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_behaviourUpdatesNear).Setup(1, (SteppedUpdateGroup)(object)__instance.m_behaviourUpdatesClose);
			__instance.m_behaviourUpdatesFar = new UpdateBehaviourGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_behaviourUpdatesFar).Setup(1, (SteppedUpdateGroup)(object)__instance.m_behaviourUpdatesNear);
			__instance.m_detectionUpdatesClose = new UpdateDetectionGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_detectionUpdatesClose).Setup(10, (SteppedUpdateGroup)null);
			__instance.m_detectionUpdatesNear = new UpdateDetectionGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_detectionUpdatesNear).Setup(3, (SteppedUpdateGroup)(object)__instance.m_detectionUpdatesNear);
			__instance.m_detectionUpdatesFar = new UpdateDetectionGroup();
			((SteppedUpdateGroup<EnemyBehaviour>)(object)__instance.m_detectionUpdatesFar).Setup(1, (SteppedUpdateGroup)(object)__instance.m_detectionUpdatesFar);
			__instance.m_networkUpdatesClose = new UpdateNetworkGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_networkUpdatesClose).Setup(12, (SteppedUpdateGroup)null);
			__instance.m_networkUpdatesNear = new UpdateNetworkGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_networkUpdatesNear).Setup(3, (SteppedUpdateGroup)(object)__instance.m_networkUpdatesClose);
			__instance.m_networkUpdatesFar = new UpdateNetworkGroup();
			((SteppedUpdateGroup<EnemyLocomotion>)(object)__instance.m_networkUpdatesFar).Setup(1, (SteppedUpdateGroup)(object)__instance.m_networkUpdatesNear);
			return false;
		}
	}
	[HarmonyPatch]
	internal class RedundantMethods
	{
		public static bool experimentalOn = true;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CL_Light), "UpdateData")]
		public static bool LightCull()
		{
			return false;
		}
	}
	[HarmonyPatch]
	internal class ResolutionPatch
	{
		public static bool dynamic = false;

		public static UI_Canvas markerLayer = null;

		public static float canvasScale;

		private static float scale = 0.8f;

		private static float offset = 0.1f;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(LookCameraController), "MouseLookUpdate")]
		public static void Mouse(ref float axisHor, ref float axisVer)
		{
			float num = Mathf.Abs(axisHor + axisVer);
			if (num < 1f)
			{
				scale = 1f;
				offset = 0f;
			}
			else if (num < 2f)
			{
				scale = 0.8f;
				offset = 0.1f;
			}
			else
			{
				scale = 0.6f;
				offset = 0.2f;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FPSCamera), "Update")]
		public static void ScaleDown(FPSCamera __instance)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (dynamic)
			{
				markerLayer.CanvasScale = canvasScale * scale;
				((CameraController)__instance).m_camera.rect = new Rect(offset, offset, scale, scale);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FPSCamera), "OnPostRender")]
		public static void ScaleUp(FPSCamera __instance)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			markerLayer.CanvasScale = canvasScale;
			((CameraController)__instance).m_camera.rect = new Rect(0f, 0f, 1f, 1f);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(FPSCamera), "Awake")]
		public static void DrawDetour(FPSCamera __instance)
		{
			Detour_DrawMeshInstancedIndirect.DrawMeshCamera = ((Il2CppObjectBase)((CameraController)__instance).m_camera).Pointer;
		}
	}
	[HarmonyPatch]
	internal class SightPatch
	{
		public static byte[] flashLightData;

		public static Dictionary<string, string[]> sightPaths;

		public static Dictionary<string, string> flashlights;

		public static Color newColor = new Color(10f, 0.5f, 0f);

		public static void GetSightFolders()
		{
			flashlights = new Dictionary<string, string>();
			string[] array = null;
			string path = Paths.BepInExRootPath + "\\LowSpec\\";
			if (!Directory.Exists(path) || EntryPoint.dumpTexture.Value)
			{
				return;
			}
			EntryPoint.LogIt("Trying to find sights");
			if (EntryPoint.currentFolderPath.Value.Equals("") || EntryPoint.currentFolderPath.Value == null)
			{
				EntryPoint.LogIt("Auto loaded and found sights");
			}
			else
			{
				EntryPoint.LogIt("Manually Loaded");
				path = EntryPoint.currentFolderPath.Value;
			}
			array = Directory.GetDirectories(path);
			if (array == null)
			{
				return;
			}
			try
			{
				string[] array2 = array;
				foreach (string text in array2)
				{
					string key = text.Split("\\")[text.Split("\\").Count() - 1];
					sightPaths[key] = Directory.GetFiles(text);
				}
			}
			catch
			{
				EntryPoint.LogIt("NO GEAR SIGHT FOUND, MOVING ON");
			}
			try
			{
				string[] array3 = sightPaths["FlashLights"];
				foreach (string text2 in array3)
				{
					string text3 = text2.Split("\\")[text2.Split("\\").Count() - 1];
					string text4 = text3;
					text3 = text4.Substring(0, text4.Length - 4);
					flashlights[text3] = text2;
				}
			}
			catch
			{
				EntryPoint.LogIt("NO FLASHLIGHT FOUND, MOVING ON");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GearMaterialFeeder), "ScanAndSetupParts")]
		private static void MySight(GearMaterialFeeder __instance)
		{
			try
			{
				if (EntryPoint.dumpTexture.Value)
				{
					DumpTexture(__instance);
				}
				else
				{
					SetTexture(__instance);
				}
			}
			catch
			{
				EntryPoint.LogIt("Skipping texture for" + ((Object)((Component)((Component)__instance).transform.parent).gameObject).name + "..");
			}
		}

		private static void DumpTexture(GearMaterialFeeder __instance)
		{
			for (int i = 0; i < ((Il2CppArrayBase<Renderer>)(object)__instance.m_allRenderers).Count; i++)
			{
				Renderer val = ((IEnumerable<Renderer>)__instance.m_allRenderers).ElementAt(i);
				if (((Object)val.material.shader).name.ToLower().Contains("unlit"))
				{
					string[] array = new string[4] { "_MainTex", "_ReticuleA", "_ReticuleB", "_ReticuleC" };
					string[] array2 = array;
					foreach (string textName in array2)
					{
						SaveTexture(((Object)((Component)((Component)__instance).transform.parent).gameObject).name, i, val.material, textName);
					}
					EntryPoint.LogIt(((Object)((Component)((Component)__instance).transform.parent).gameObject).name + " Dumped");
					break;
				}
			}
		}

		private static void SaveTexture(string weaponName, int index, Material mat, string TextName)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = ((Il2CppObjectBase)mat.GetTexture(TextName)).Cast<Texture2D>();
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)val).width, ((Texture)val).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit((Texture)(object)val, temporary);
			RenderTexture.active = active;
			Texture2D val2 = new Texture2D(((Texture)val).width, ((Texture)val).height);
			active = RenderTexture.active;
			RenderTexture.active = temporary;
			val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
			val2.Apply();
			if (TextName == "_MainTex")
			{
				for (int i = 0; i < ((Texture)val2).width; i++)
				{
					for (int j = 0; j < ((Texture)val2).height; j++)
					{
						Color val3 = val2.GetPixel(i, j) * newColor;
						val2.SetPixel(i, j, val3);
					}
				}
				val2.Apply();
			}
			RenderTexture.ReleaseTemporary(temporary);
			byte[] bytes = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val2));
			string text = "";
			text = ((index >= 10) ? (index + TextName) : ("0" + index + TextName));
			string text2 = Paths.BepInExRootPath + "\\LowSpec\\";
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
			}
			if (!Directory.Exists(text2 + weaponName))
			{
				Directory.CreateDirectory(text2 + weaponName);
			}
			File.WriteAllBytes(text2 + weaponName + "\\" + text + ".png", bytes);
		}

		private static void SetTexture(GearMaterialFeeder __instance)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			if (!sightPaths.TryGetValue(((Object)((Component)((Component)__instance).transform.parent).gameObject).name, out string[] value))
			{
				return;
			}
			Material val = null;
			val = ((IEnumerable<Renderer>)__instance.m_allRenderers).ElementAt(int.Parse(Path.GetFileNameWithoutExtension(value[0]).Substring(0, 2))).material;
			if (!((Object)(object)val == (Object)null))
			{
				string[] array = value;
				foreach (string path in array)
				{
					Texture2D val2 = new Texture2D(1024, 1024, (TextureFormat)4, false);
					ImageConversion.LoadImage(val2, Il2CppStructArray<byte>.op_Implicit(File.ReadAllBytes(path)));
					val2.Apply();
					Material obj = val;
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					obj.SetTexture(fileNameWithoutExtension.Substring(2, fileNameWithoutExtension.Length - 2), (Texture)(object)val2);
					val.SetFloat("_SightDirt", 0f);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CL_ShadowGenerator), "SetCookie")]
		private static void MyFlashLight(ref Texture2D cookie)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (((Object)cookie).name.Contains("FlashlightRegular"))
			{
				try
				{
					Texture2D val = new Texture2D(512, 512, (TextureFormat)4, false);
					ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(File.ReadAllBytes(flashlights[((Object)cookie).name])));
					cookie = val;
				}
				catch
				{
				}
			}
		}
	}
}
namespace LowSpecGaming.Misc
{
	[HarmonyPatch]
	internal static class BioScanPatch
	{
		public static bool update;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Holopath_Spline), "Reveal")]
		private static void Holopath_Spline_Reveal(CP_Holopath_Spline __instance)
		{
			__instance.CurvySpline.UseThreading = true;
			__instance.CurvySpline.UpdateIn = (CurvyUpdateMethod)(-1);
			__instance.CurvyExtrusion.Optimize = true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CP_Bioscan_Graphics), "Update")]
		private static bool Bioscan_Graphics_Update()
		{
			return update;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CP_Bioscan_Graphics), "Setup")]
		private static void Bioscan_Graphics_Setup(CP_Bioscan_Graphics __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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)
			if (!__instance.m_colorsByMode.ContainsKey((eChainedPuzzleGraphicsColorMode)4))
			{
				__instance.m_colorsByMode.Add((eChainedPuzzleGraphicsColorMode)4, __instance.m_currentCol);
			}
			if (!__instance.m_colorsByMode.ContainsKey((eChainedPuzzleGraphicsColorMode)6))
			{
				__instance.m_colorsByMode.Add((eChainedPuzzleGraphicsColorMode)6, __instance.m_colorsByMode[(eChainedPuzzleGraphicsColorMode)4]);
			}
			if (!__instance.m_colorsByMode.ContainsKey((eChainedPuzzleGraphicsColorMode)5))
			{
				__instance.m_colorsByMode.Add((eChainedPuzzleGraphicsColorMode)5, __instance.m_colorsByMode[(eChainedPuzzleGraphicsColorMode)4] * new Color(1.1f, 1.1f, 1.1f, 1.1f));
			}
			Dictionary<eChainedPuzzleGraphicsColorMode, Color> colorsByMode = __instance.m_colorsByMode;
			colorsByMode[(eChainedPuzzleGraphicsColorMode)5] = colorsByMode[(eChainedPuzzleGraphicsColorMode)5] * new Color(1.1f, 1.1f, 1.1f, 1.1f);
		}
	}
	[HarmonyPatch]
	internal static class SpitterPatch
	{
		public static bool hate = true;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InfectionSpitter), "Awake")]
		public static void ShutUpSpitter(InfectionSpitter __instance)
		{
			if (hate)
			{
				Material material = __instance.m_renderer.material;
				material.GetTexture(1).mipMapBias = 10f;
				material.GetTexture("_MetallicGlossMap").mipMapBias = 10f;
				material.GetTexture("_SSSMap").mipMapBias = 10f;
				material.GetTexture("_MainTex_B").mipMapBias = 10f;
				Object.Destroy((Object)(object)((Component)__instance).gameObject.GetComponentInChildren<Decal>());
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InfectionSpitter), "StopPurring")]
		public static void StopPurring(InfectionSpitter __instance)
		{
			__instance.m_purrLoopPlaying = true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InfectionSpitter), "TryPlaySound")]
		public static bool StopPurringSeriously(ref uint id)
		{
			if (id == EVENTS.INFECTION_SPITTER_PURR_LOOP)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class WeaponPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ShellCasing), "Awake")]
		private static bool MyMags(ShellCasing __instance)
		{
			((Component)__instance).gameObject.active = false;
			Object.Destroy((Object)(object)((Component)((Component)__instance).transform.GetChild(0)).gameObject);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(DisableAfterDelay), "Awake")]
		private static void MyBullets(DisableAfterDelay __instance)
		{
			__instance.delay = 0f;
		}
	}
}