Decompiled source of LethalSanity v3.1.0

LethalSanity.dll

Decompiled 3 weeks 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.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LethalSanity")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalSanity")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8c6b8402-d91f-45f7-96d6-ddbc764d9d83")]
[assembly: AssemblyFileVersion("3.0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("3.0.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalSanity
{
	internal class Config
	{
		private readonly string xmlPath = Path.Combine(Paths.ConfigPath, "LethalSanity.xml");

		private readonly string cfgPath = Path.Combine(Paths.ConfigPath, "LethalSanity.cfg");

		private static ConfigFile _config { get; set; }

		internal static int P_PP { get; private set; }

		internal static ItemData Vignette { get; private set; }

		internal static ItemData FilmGrain { get; private set; }

		internal static ItemData ChromaticAberation { get; private set; }

		internal static ItemData LensDistortion { get; private set; }

		internal static ItemData DOF_Start { get; private set; }

		internal static ItemData DOF_End { get; private set; }

		internal static ItemData Saturation { get; private set; }

		internal Config()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			_config = new ConfigFile(cfgPath, true, new BepInPlugin("com.Github.IGNOREDSOUL.LethalSanity", "LethalSanity", "3.0"));
			ConfigEntry<string> val = _config.Bind<string>("_Internal_", "Load", string.Empty, "Putting the Encoded XML into here rewrites your current XML settings. Keep a backup just incase. \u00af\\_(ツ)_/\u00af");
			ConfigEntry<string> val2 = _config.Bind<string>("_Internal_", "Current", string.Empty, "This is your current XML settings. You can share with others so they can have the same config as you.");
			if (!File.Exists(xmlPath))
			{
				Main.mls.LogMessage((object)"Creating XML from default");
				ApplyXmlData(null);
				SaveXML();
			}
			string text = CompressToDeflateString(Encoding.UTF8.GetString(File.ReadAllBytes(xmlPath)));
			if (text == string.Empty)
			{
				Main.mls.LogWarning((object)"An error occured while loading the current XML file. Resetting to default.");
				ApplyXmlData(null);
				SaveXML();
			}
			else
			{
				val2.Value = text;
			}
			if (!string.IsNullOrEmpty(val.Value))
			{
				Main.mls.LogMessage((object)"Loading loadXML");
				string text2 = DecompressFromDeflateString(val.Value);
				if (text2 == string.Empty)
				{
					Main.mls.LogWarning((object)"An error occured while loading the new XML file.");
					val.Value = string.Empty;
					if (CompressToDeflateString(Encoding.UTF8.GetString(File.ReadAllBytes(xmlPath))) == string.Empty)
					{
						Main.mls.LogWarning((object)"An error occured while loading the current XML file. Resetting to default.");
						ApplyXmlData(null);
						SaveXML();
					}
					else
					{
						Main.mls.LogMessage((object)"Loaded internal XML.");
					}
					return;
				}
				File.WriteAllText(xmlPath, text2);
				val2.Value = val.Value;
				val.Value = string.Empty;
			}
			_config.Save();
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(ConfigData));
			using (StreamReader textReader = new StreamReader(xmlPath))
			{
				ConfigData configData = (ConfigData)xmlSerializer.Deserialize(textReader);
				ApplyXmlData(configData);
			}
			P_PP = _config.Bind<int>("_Internal_", "Priority", 1, "In Unity, the post-processing priority value determines which volume's effects are applied first when multiple volumes overlap.\nHigher priority values take precedence, allowing for specific area effects to override global ones.\nSet the value higher if effects are being wacky.").Value;
			Vignette.Enabled = _config.Bind<bool>("Vignette", "Enabled", true, "Should this effect be enabled?").Value;
			Vignette.Kickin = _config.Bind<int>("Vignette", "Kickin", 25, "At what insanity level should this effect kick in at?").Value;
			Vignette.Offset = _config.Bind<int>("Vignette", "Offset", 3, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value;
			FilmGrain.Enabled = _config.Bind<bool>("FilmGrain", "Enabled", true, "Should this effect be enabled?").Value;
			FilmGrain.Kickin = _config.Bind<int>("FilmGrain", "Kickin", 30, "At what insanity level should this effect kick in at?").Value;
			FilmGrain.Offset = _config.Bind<int>("FilmGrain", "Offset", 5, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value;
			ChromaticAberation.Enabled = _config.Bind<bool>("ChromaticAberation", "Enabled", true, "Should this effect be enabled?").Value;
			ChromaticAberation.Kickin = _config.Bind<int>("ChromaticAberation", "Kickin", 40, "At what insanity level should this effect kick in at?").Value;
			ChromaticAberation.Offset = _config.Bind<int>("ChromaticAberation", "Offset", 5, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value;
			LensDistortion.Enabled = _config.Bind<bool>("LensDistortion", "Enabled", true, "Should this effect be enabled?").Value;
			LensDistortion.Kickin = _config.Bind<int>("LensDistortion", "Kickin", 35, "At what insanity level should this effect kick in at?").Value;
			LensDistortion.Offset = _config.Bind<int>("LensDistortion", "Offset", 4, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value;
			DOF_Start.Enabled = (DOF_End.Enabled = _config.Bind<bool>("DepthOfField", "Enabled", true, "Should this effect be enabled?").Value);
			DOF_Start.Kickin = (DOF_End.Kickin = _config.Bind<int>("DepthOfField", "Kickin", 45, "At what insanity level should this effect kick in at?").Value);
			DOF_Start.Offset = (DOF_End.Offset = _config.Bind<int>("DepthOfField", "Offset", 5, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value);
			Saturation.Enabled = _config.Bind<bool>("Saturation", "Enabled", true, "Should this effect be enabled?").Value;
			Saturation.Kickin = _config.Bind<int>("Saturation", "Kickin", 35, "At what insanity level should this effect kick in at?").Value;
			Saturation.Offset = _config.Bind<int>("Saturation", "Offset", 4, "This applies a slight randomizaton to the kickin value. (Kickin ± Offset)").Value;
			SaveXML();
		}

		private void ApplyXmlData(ConfigData configData)
		{
			Vignette = configData?.Items.Find((ItemData i) => i.Name == "Vignette") ?? new ItemData
			{
				Name = "Vignette",
				Enabled = true,
				Kickin = 20f,
				Offset = 3f,
				EaseInTimeMin = 20f,
				EaseInTimeMax = 40f,
				EaseOutTimeMin = 5f,
				EaseOutTimeMax = 10f,
				EaseInIntensityMin = 0.45f,
				EaseInIntensityMax = 0.6f,
				EaseOutIntensityMin = 0.15f,
				EaseOutIntensityMax = 0.15f
			};
			FilmGrain = configData?.Items.Find((ItemData i) => i.Name == "Film Grain") ?? new ItemData
			{
				Name = "Film Grain",
				Enabled = true,
				Kickin = 20f,
				Offset = 5f,
				EaseInTimeMin = 30f,
				EaseInTimeMax = 60f,
				EaseOutTimeMin = 8f,
				EaseOutTimeMax = 16f,
				EaseInIntensityMin = 0.4f,
				EaseInIntensityMax = 0.8f,
				EaseOutIntensityMin = 0f,
				EaseOutIntensityMax = 0f
			};
			ChromaticAberation = configData?.Items.Find((ItemData i) => i.Name == "Chromatic Aberation") ?? new ItemData
			{
				Name = "Chromatic Aberation",
				Enabled = true,
				Kickin = 30f,
				Offset = 5f,
				EaseInTimeMin = 40f,
				EaseInTimeMax = 60f,
				EaseOutTimeMin = 8f,
				EaseOutTimeMax = 16f,
				EaseInIntensityMin = 0.9f,
				EaseInIntensityMax = 1.5f,
				EaseOutIntensityMin = 0f,
				EaseOutIntensityMax = 0f
			};
			LensDistortion = configData?.Items.Find((ItemData i) => i.Name == "Lens Distortion") ?? new ItemData
			{
				Name = "Lens Distortion",
				Enabled = true,
				Kickin = 30f,
				Offset = 10f,
				EaseInTimeMin = 15f,
				EaseInTimeMax = 30f,
				EaseOutTimeMin = 8f,
				EaseOutTimeMax = 16f,
				EaseInIntensityMin = 0.4f,
				EaseInIntensityMax = 0.6f,
				EaseOutIntensityMin = 0f,
				EaseOutIntensityMax = 0f
			};
			DOF_Start = configData?.Items.Find((ItemData i) => i.Name == "DepthOfField Far") ?? new ItemData
			{
				Name = "DepthOfField Far",
				Enabled = true,
				Kickin = 40f,
				Offset = 5f,
				EaseInTimeMin = 15f,
				EaseInTimeMax = 30f,
				EaseOutTimeMin = 8f,
				EaseOutTimeMax = 16f,
				EaseInIntensityMin = 3f,
				EaseInIntensityMax = 8f,
				EaseOutIntensityMin = 2000f,
				EaseOutIntensityMax = 2000f
			};
			DOF_End = configData?.Items.Find((ItemData i) => i.Name == "DepthOfField Near") ?? new ItemData
			{
				Name = "DepthOfField Near",
				Enabled = true,
				Kickin = 40f,
				Offset = 5f,
				EaseInTimeMin = 18f,
				EaseInTimeMax = 38f,
				EaseOutTimeMin = 13f,
				EaseOutTimeMax = 20f,
				EaseInIntensityMin = 15f,
				EaseInIntensityMax = 30f,
				EaseOutIntensityMin = 2000f,
				EaseOutIntensityMax = 2000f
			};
			Saturation = configData?.Items.Find((ItemData i) => i.Name == "Saturation") ?? new ItemData
			{
				Name = "Saturation",
				Enabled = true,
				Kickin = 50f,
				Offset = 10f,
				EaseInTimeMin = 20f,
				EaseInTimeMax = 30f,
				EaseOutTimeMin = 2f,
				EaseOutTimeMax = 5f,
				EaseInIntensityMin = 50f,
				EaseInIntensityMax = 70f,
				EaseOutIntensityMin = 0f,
				EaseOutIntensityMax = 0f
			};
		}

		private void SaveXML()
		{
			ConfigData o = new ConfigData
			{
				Items = new List<ItemData>(7) { Vignette, FilmGrain, ChromaticAberation, LensDistortion, DOF_Start, DOF_End, Saturation }
			};
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(ConfigData));
			using StreamWriter textWriter = new StreamWriter(xmlPath);
			xmlSerializer.Serialize(textWriter, o);
		}

		public static string CompressToDeflateString(string input)
		{
			try
			{
				byte[] bytes = Encoding.UTF8.GetBytes(input);
				using MemoryStream memoryStream = new MemoryStream();
				using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Optimal))
				{
					deflateStream.Write(bytes, 0, bytes.Length);
				}
				return Convert.ToBase64String(memoryStream.ToArray());
			}
			catch (Exception)
			{
				return string.Empty;
			}
		}

		public static string DecompressFromDeflateString(string compressedString)
		{
			try
			{
				using MemoryStream stream = new MemoryStream(Convert.FromBase64String(compressedString));
				using DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress);
				using MemoryStream memoryStream = new MemoryStream();
				deflateStream.CopyTo(memoryStream);
				return Encoding.UTF8.GetString(memoryStream.ToArray());
			}
			catch (Exception)
			{
				return string.Empty;
			}
		}
	}
	[XmlRoot("Items")]
	public class ConfigData
	{
		[XmlElement("Item")]
		public List<ItemData> Items { get; set; } = new List<ItemData>();

	}
	[XmlRoot("Items")]
	public class ItemData
	{
		[XmlAttribute("Name")]
		public string Name { get; set; }

		[XmlElement("Enabled")]
		public bool Enabled { get; set; }

		[XmlElement("Kickin")]
		public float Kickin { get; set; }

		[XmlElement("Offset")]
		public float Offset { get; set; }

		[XmlElement("EaseInTimeMin")]
		public float EaseInTimeMin { get; set; }

		[XmlElement("EaseInTimeMax")]
		public float EaseInTimeMax { get; set; }

		[XmlElement("EaseOutTimeMin")]
		public float EaseOutTimeMin { get; set; }

		[XmlElement("EaseOutTimeMax")]
		public float EaseOutTimeMax { get; set; }

		[XmlElement("EaseInIntensityMin")]
		public float EaseInIntensityMin { get; set; }

		[XmlElement("EaseInIntensityMax")]
		public float EaseInIntensityMax { get; set; }

		[XmlElement("EaseOutIntensityMin")]
		public float EaseOutIntensityMin { get; set; }

		[XmlElement("EaseOutIntensityMax")]
		public float EaseOutIntensityMax { get; set; }
	}
	internal static class NumberUtils
	{
		internal static readonly Random random = new Random(GenerateTrulyRandomNumber());

		private static readonly Dictionary<string, CancellationTokenSource> ctsDict = new Dictionary<string, CancellationTokenSource>();

		internal static int GenerateTrulyRandomNumber()
		{
			using RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider();
			byte[] array = new byte[4];
			rNGCryptoServiceProvider.GetBytes(array);
			return Math.Abs(BitConverter.ToInt32(array, 0) % 40) + 10;
		}

		internal static int Next(int min, int max)
		{
			return random.Next(min, max + 1);
		}

		internal static float Next(float input, float offset, float max)
		{
			return Mathf.Clamp(Next(input - offset, input + offset), 0f, max);
		}

		internal static float Next(float min, float max)
		{
			return (float)(NextD() * (double)(max - min) + (double)min);
		}

		internal static double NextD()
		{
			return random.NextDouble();
		}

		internal static async void SmoothIncrementValue(string actionName, Action<float> action, float start, float target, float duration)
		{
			if (ctsDict.TryGetValue(actionName, out var value))
			{
				value.Cancel();
				value.Dispose();
				Main.mls.LogWarning((object)("Cancelling smooth increment task: " + actionName));
			}
			CancellationTokenSource cts = new CancellationTokenSource();
			ctsDict[actionName] = cts;
			float elapsedTime = 0f;
			try
			{
				while (elapsedTime < duration)
				{
					cts.Token.ThrowIfCancellationRequested();
					action(Mathf.Lerp(start, target, elapsedTime / duration));
					elapsedTime += Time.deltaTime;
					await Task.Yield();
				}
				action(target);
			}
			catch (OperationCanceledException)
			{
			}
			finally
			{
				ctsDict.Remove(actionName);
				cts.Dispose();
			}
		}
	}
	internal static class LocalPlayer
	{
		internal static PlayerControllerB? PlayerController => GameNetworkManager.Instance?.localPlayerController ?? null;

		internal static GameObject? Player
		{
			get
			{
				PlayerControllerB? playerController = PlayerController;
				if (playerController == null)
				{
					return null;
				}
				return ((Component)playerController).gameObject;
			}
		}

		internal static float Insanity
		{
			get
			{
				return PlayerController?.insanityLevel ?? (-1f);
			}
			set
			{
				PlayerController.insanityLevel = value;
			}
		}

		internal static float MaxInsanity
		{
			get
			{
				return PlayerController?.maxInsanityLevel ?? (-1f);
			}
			set
			{
				PlayerController.maxInsanityLevel = value;
			}
		}
	}
	[BepInPlugin("com.Github.IGNOREDSOUL.LethalSanity", "LethalSanity", "3.0")]
	[BepInProcess("Lethal Company.exe")]
	public class Main : BaseUnityPlugin
	{
		internal const string modVer = "3.0";

		internal const string modName = "LethalSanity";

		internal const string modGUID = "com.Github.IGNOREDSOUL.LethalSanity";

		internal static Main Instance { get; private set; }

		internal static ManualLogSource mls { get; private set; }

		internal Harmony harmony { get; private set; }

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			while (!Object.op_Implicit((Object)(object)Instance))
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("LethalSanity");
			harmony = new Harmony("com.Github.IGNOREDSOUL.LethalSanity");
			harmony.PatchAll(typeof(Patching));
			new Config();
			new SanityEventManager();
			Patching.Connect += delegate(PlayerControllerB __instance)
			{
				((Component)__instance).gameObject.AddComponent<PostProcessing>();
			};
		}
	}
	public class Patching
	{
		private static float _prev_san { get; set; } = -3.141f;


		internal static event Action<PlayerControllerB> Connect;

		internal static event Action<float> SanityChanged;

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void _CONNECT(PlayerControllerB __instance)
		{
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)__instance)
			{
				Patching.Connect?.Invoke(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SetPlayerSanityLevel")]
		[HarmonyPostfix]
		private static void _SANITY_SET()
		{
			if (Object.op_Implicit((Object)(object)LocalPlayer.Player) && !LocalPlayer.PlayerController.isPlayerDead)
			{
				float num = float.Parse(LocalPlayer.Insanity.ToString("0.0"));
				if (_prev_san != num)
				{
					_prev_san = num;
					Patching.SanityChanged?.Invoke(num);
				}
			}
		}
	}
	internal class PostProcessing : MonoBehaviour
	{
		public static PostProcessing Component { get; private set; }

		private GameObject VolumeObject { get; set; }

		private VolumeProfile VolumeProfile { get; set; }

		private void Start()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			Main.mls.LogWarning((object)"Starting to do Post Shit");
			GameObject val = GameObject.Find("Systems/Rendering/VolumeMain");
			VolumeObject = Object.Instantiate<GameObject>(val, val.transform.parent);
			((Object)VolumeObject).name = "LS-Volume";
			VolumeProfile = new VolumeProfile
			{
				name = "LS-VolumeProfile"
			};
			VolumeObject.GetComponentInChildren<Volume>().priority = Config.P_PP;
			VolumeObject.GetComponentInChildren<Volume>().profile = VolumeProfile;
			MakeDOF();
			MakeChrAb();
			MakeVignette();
			MakeLensDist();
			MakeFilmGrain();
			MakeSaturation();
			LocalPlayer.MaxInsanity = new ItemData[7]
			{
				Config.Vignette,
				Config.FilmGrain,
				Config.ChromaticAberation,
				Config.LensDistortion,
				Config.DOF_Start,
				Config.DOF_End,
				Config.Saturation
			}.ToList().Max((ItemData c) => c.Kickin + c.Offset);
		}

		private void MakeVignette()
		{
			if (Config.Vignette.Enabled)
			{
				Vignette VignetteComp = VolumeProfile.Add<Vignette>(false);
				((VolumeParameter<float>)(object)VignetteComp.smoothness).value = 1f;
				((VolumeParameter<float>)(object)VignetteComp.roundness).value = 0.842f;
				((Object)VignetteComp).name = "LS-VignetteComp";
				((VolumeParameter<float>)(object)VignetteComp.intensity).Override(0.15f);
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.Vignette.Kickin, Config.Vignette.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "Vignette",
							Action = ((VolumeParameter<float>)(object)VignetteComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)VignetteComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.Vignette.EaseInIntensityMin, Config.Vignette.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.Vignette.EaseInTimeMin, Config.Vignette.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "Vignette",
							Action = ((VolumeParameter<float>)(object)VignetteComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)VignetteComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.Vignette.EaseOutIntensityMin, Config.Vignette.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.Vignette.EaseOutTimeMin, Config.Vignette.EaseOutTimeMax)
						});
					}
				});
			}
		}

		private void MakeFilmGrain()
		{
			if (Config.FilmGrain.Enabled)
			{
				FilmGrain FilmGrainComp = VolumeProfile.Add<FilmGrain>(false);
				((Object)FilmGrainComp).name = "LS-FilmGrainComp";
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.FilmGrain.Kickin, Config.FilmGrain.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "FilmGrain",
							Action = ((VolumeParameter<float>)(object)FilmGrainComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)FilmGrainComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.FilmGrain.EaseInIntensityMin, Config.FilmGrain.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.FilmGrain.EaseInTimeMin, Config.FilmGrain.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "FilmGrain",
							Action = ((VolumeParameter<float>)(object)FilmGrainComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)FilmGrainComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.FilmGrain.EaseOutIntensityMin, Config.FilmGrain.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.FilmGrain.EaseOutTimeMin, Config.FilmGrain.EaseOutTimeMax)
						});
					}
				});
			}
		}

		private void MakeChrAb()
		{
			if (Config.ChromaticAberation.Enabled)
			{
				ChromaticAberration ChrAbComp = VolumeProfile.Add<ChromaticAberration>(false);
				((Object)ChrAbComp).name = "LS-ChrAbComp";
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.ChromaticAberation.Kickin, Config.ChromaticAberation.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "ChrAb",
							Action = ((VolumeParameter<float>)(object)ChrAbComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)ChrAbComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.ChromaticAberation.EaseInIntensityMin, Config.ChromaticAberation.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.ChromaticAberation.EaseInTimeMin, Config.ChromaticAberation.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "ChrAb",
							Action = ((VolumeParameter<float>)(object)ChrAbComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)ChrAbComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.ChromaticAberation.EaseOutIntensityMin, Config.ChromaticAberation.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.ChromaticAberation.EaseOutTimeMin, Config.ChromaticAberation.EaseOutTimeMax)
						});
					}
				});
			}
		}

		private void MakeLensDist()
		{
			if (Config.LensDistortion.Enabled)
			{
				NumberUtils.Next(Config.LensDistortion.Kickin, Config.LensDistortion.Offset, 65f);
				LensDistortion LensDistComp = VolumeProfile.Add<LensDistortion>(false);
				((Object)LensDistComp).name = "LS-LensDistComp";
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.LensDistortion.Kickin, Config.LensDistortion.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "LensDist",
							Action = ((VolumeParameter<float>)(object)LensDistComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)LensDistComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.LensDistortion.EaseInIntensityMin, Config.LensDistortion.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.LensDistortion.EaseInTimeMin, Config.LensDistortion.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "LensDist",
							Action = ((VolumeParameter<float>)(object)LensDistComp.intensity).Override,
							StartValue = ((VolumeParameter<float>)(object)LensDistComp.intensity).value,
							TargetValue = NumberUtils.Next(Config.LensDistortion.EaseOutIntensityMin, Config.LensDistortion.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.LensDistortion.EaseOutTimeMin, Config.LensDistortion.EaseOutTimeMax)
						});
					}
				});
			}
		}

		private void MakeDOF()
		{
			if (Config.DOF_Start.Enabled && !Config.DOF_End.Enabled)
			{
				NumberUtils.Next(Config.DOF_Start.Kickin, Config.DOF_Start.Offset, 65f);
				DepthOfField DOFComp = VolumeProfile.Add<DepthOfField>(false);
				((VolumeParameter<float>)(object)DOFComp.farFocusStart).Override(2000f);
				((VolumeParameter<float>)(object)DOFComp.farFocusEnd).Override(2000f);
				((Object)DOFComp).name = "LS-DOFComp";
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.DOF_Start.Kickin, Config.DOF_Start.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "DOFStart",
							Action = ((VolumeParameter<float>)(object)DOFComp.farFocusStart).Override,
							StartValue = ((VolumeParameter<float>)(object)DOFComp.farFocusStart).value,
							TargetValue = NumberUtils.Next(Config.DOF_Start.EaseInIntensityMin, Config.DOF_Start.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.DOF_Start.EaseInTimeMin, Config.DOF_Start.EaseInTimeMax)
						});
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "DOFEnd",
							Action = ((VolumeParameter<float>)(object)DOFComp.farFocusEnd).Override,
							StartValue = ((VolumeParameter<float>)(object)DOFComp.farFocusEnd).value,
							TargetValue = NumberUtils.Next(Config.DOF_End.EaseInIntensityMin, Config.DOF_End.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.DOF_End.EaseInTimeMin, Config.DOF_End.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "DOFStart",
							Action = ((VolumeParameter<float>)(object)DOFComp.farFocusStart).Override,
							StartValue = ((VolumeParameter<float>)(object)DOFComp.farFocusStart).value,
							TargetValue = NumberUtils.Next(Config.DOF_Start.EaseOutIntensityMin, Config.DOF_Start.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.DOF_Start.EaseOutTimeMin, Config.DOF_Start.EaseOutTimeMax)
						});
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "DOFEnd",
							Action = ((VolumeParameter<float>)(object)DOFComp.farFocusEnd).Override,
							StartValue = ((VolumeParameter<float>)(object)DOFComp.farFocusEnd).value,
							TargetValue = NumberUtils.Next(Config.DOF_End.EaseOutIntensityMin, Config.DOF_End.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.DOF_End.EaseOutTimeMin, Config.DOF_End.EaseOutTimeMax)
						});
					}
				});
			}
		}

		private void MakeSaturation()
		{
			if (Config.Saturation.Enabled)
			{
				ColorAdjustments CAComp = VolumeProfile.Add<ColorAdjustments>(false);
				((Object)CAComp).name = "LS-CAComp";
				SanityEventManager.Instance.AddEvent(new SanityEvent
				{
					Sanity = NumberUtils.Next(Config.Saturation.Kickin, Config.Saturation.Offset),
					OnAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "CA",
							Action = ((VolumeParameter<float>)(object)CAComp.saturation).Override,
							StartValue = ((VolumeParameter<float>)(object)CAComp.saturation).value,
							TargetValue = 0f - NumberUtils.Next(Config.Saturation.EaseInIntensityMin, Config.Saturation.EaseInIntensityMax),
							Duration = NumberUtils.Next(Config.Saturation.EaseInTimeMin, Config.Saturation.EaseInTimeMax)
						});
					},
					OffAction = delegate
					{
						SanityEventManager.Instance.SmoothIncrementValue(new SMVConfig
						{
							ActionName = "CA",
							Action = ((VolumeParameter<float>)(object)CAComp.saturation).Override,
							StartValue = ((VolumeParameter<float>)(object)CAComp.saturation).value,
							TargetValue = NumberUtils.Next(Config.Saturation.EaseOutIntensityMin, Config.Saturation.EaseOutIntensityMax),
							Duration = NumberUtils.Next(Config.Saturation.EaseOutTimeMin, Config.Saturation.EaseOutTimeMax)
						});
					}
				});
			}
		}
	}
	internal class SanityEventManager
	{
		private readonly Dictionary<string, CancellationTokenSource> ctsDict = new Dictionary<string, CancellationTokenSource>();

		internal static SanityEventManager Instance { get; private set; }

		internal List<SanityEvent> Events { get; private set; } = new List<SanityEvent>();


		internal SanityEventManager()
		{
			Instance = this;
			Patching.SanityChanged += SanityEventCheck;
		}

		internal void AddEvent(SanityEvent @event)
		{
			Events.Add(@event);
		}

		private void SanityEventCheck(float sanity)
		{
			SanityEvent[] array = Events.Where((SanityEvent i) => i.Sanity < sanity).ToArray();
			foreach (SanityEvent item in array)
			{
				int num = Events.IndexOf(item);
				if (num != -1 && !Events[num].Applied)
				{
					SanityEvent value = Events[num];
					value.Applied = true;
					Events[num] = value;
					value.OnAction?.Invoke();
				}
			}
			array = Events.Where((SanityEvent i) => i.Sanity >= sanity).ToArray();
			foreach (SanityEvent item2 in array)
			{
				int num2 = Events.IndexOf(item2);
				if (num2 != -1 && Events[num2].Applied)
				{
					SanityEvent value2 = Events[num2];
					value2.Applied = false;
					Events[num2] = value2;
					value2.OffAction?.Invoke();
				}
			}
		}

		internal async void SmoothIncrementValue(SMVConfig config)
		{
			if (ctsDict.TryGetValue(config.ActionName, out var value))
			{
				value.Cancel();
				value.Dispose();
				Main.mls.LogWarning((object)("Cancelling smooth increment task: " + config.ActionName));
			}
			CancellationTokenSource cts = new CancellationTokenSource();
			ctsDict[config.ActionName] = cts;
			float elapsedTime = 0f;
			try
			{
				while (elapsedTime < config.Duration)
				{
					cts.Token.ThrowIfCancellationRequested();
					config.Action(Mathf.Lerp(config.StartValue, config.TargetValue, elapsedTime / config.Duration));
					elapsedTime += Time.deltaTime;
					await Task.Yield();
				}
				config.Action(config.TargetValue);
			}
			catch (OperationCanceledException)
			{
			}
			finally
			{
				ctsDict.Remove(config.ActionName);
				cts.Dispose();
			}
		}
	}
	public struct SMVConfig
	{
		public string ActionName { get; set; }

		public Action<float> Action { get; set; }

		public float StartValue { get; set; }

		public float TargetValue { get; set; }

		public float Duration { get; set; }
	}
	public struct SanityEvent
	{
		public float Sanity { get; set; }

		public Action OnAction { get; set; }

		public Action OffAction { get; set; }

		public bool Applied { get; set; }
	}
}