Decompiled source of PEAK Visuals v1.1.1

com.github.glarmer.PEAK_Visuals.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAK_Visuals.Configuration;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.glarmer.PEAK_Visuals")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+83841475b78d78699b7c845dba57b049ff31ddb1")]
[assembly: AssemblyProduct("com.github.glarmer.PEAK_Visuals")]
[assembly: AssemblyTitle("PEAK_Visuals")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PEAK_Visuals
{
	[BepInPlugin("com.github.glarmer.PEAK_Visuals", "PEAK_Visuals", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.glarmer.PEAK_Visuals");

		private ModConfigurationUI _ui;

		public const string Id = "com.github.glarmer.PEAK_Visuals";

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		public ConfigurationHandler ConfigurationHandler { get; private set; }

		public Settings Settings { get; private set; }

		public static string Name => "PEAK_Visuals";

		public static string Version => "1.1.0";

		private void Awake()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			ConfigurationHandler = new ConfigurationHandler(((BaseUnityPlugin)this).Config);
			Settings = new Settings();
			_harmony.PatchAll();
			GameObject val = new GameObject("PEAKScaledUI");
			Object.DontDestroyOnLoad((Object)(object)val);
			_ui = val.AddComponent<ModConfigurationUI>();
			_ui.Init(new List<Option>(11)
			{
				Option.Float("Render Scale", ConfigurationHandler.ConfigRenderScale, 0.1f, 2f, 0.1f),
				Option.Int("Upscaling Filter", ConfigurationHandler.ConfigUpscalingFilter, 0, 4, 1, null, () => ConfigurationHandler.ConfigUpscalingFilter.Value switch
				{
					0 => "Auto", 
					1 => "Linear", 
					2 => "Nearest Neighbor", 
					3 => "FSR 1.0", 
					4 => "STP", 
					_ => "???", 
				}),
				Option.Bool("Anisotropic Filtering", ConfigurationHandler.ConfigAnisotropicFiltering),
				Option.Float("LOD Quality", ConfigurationHandler.ConfigLODQuality, 0.1f, 10f, 0.1f),
				Option.Int("Shadowmap Resolution", ConfigurationHandler.ConfigShadowmapResolution, 0, 10240, 1024),
				Option.Int("Shadow Distance", ConfigurationHandler.ConfigShadowDistance, 0, 1000, 25),
				Option.Int("Shadow Cascades", ConfigurationHandler.ConfigShadowCascades, 1, 10),
				Option.Bool("Soft Shadows", ConfigurationHandler.ConfigSoftShadows),
				Option.Int("Camera Antialiasing", ConfigurationHandler.ConfigCameraAA, 0, 3, 1, null, () => ConfigurationHandler.ConfigCameraAA.Value switch
				{
					0 => "None", 
					1 => "FXAA", 
					2 => "SMAA", 
					3 => "TAA", 
					_ => "???", 
				}),
				Option.Int("MSAA", ConfigurationHandler.ConfigMSAA, 0, 8, 2, null, () => ConfigurationHandler.ConfigMSAA.Value switch
				{
					0 => "Off", 
					2 => "2x", 
					4 => "4x", 
					8 => "8x", 
					_ => ConfigurationHandler.ConfigMSAA.Value + "x", 
				}),
				Option.InputAction("Menu Key", ConfigurationHandler.ConfigMenuKey)
			});
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}
	}
	public class Settings
	{
		private ConfigurationHandler _configurationHandler = Plugin.Instance.ConfigurationHandler;

		public void SetAllSettings()
		{
			SetResolutionScale();
			SetUpscaler();
			SetLODQuality();
			SetShadowDistance();
			SetShadowCascades();
			SetAnisotropicFiltering();
			SetSoftShadows();
			SetShadowmapResolution();
		}

		public void SetAllCameraSettings()
		{
			SetPostProcessAA();
			SetMSAA();
		}

		public void SetSoftShadows()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
				FieldInfo field = ((object)val).GetType().GetField("m_SoftShadowsSupported", bindingAttr);
				field.SetValue(val, _configurationHandler.SoftShadows);
				Plugin.Log.LogInfo((object)("Soft Shadows applied: " + _configurationHandler.ShadowmapResolution));
			}
		}

		public void SetShadowmapResolution()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.mainLightShadowmapResolution = _configurationHandler.ShadowmapResolution;
				Plugin.Log.LogInfo((object)("Shadowmap Resolution applied: " + _configurationHandler.ShadowmapResolution));
			}
		}

		public void SetAnisotropicFiltering()
		{
			QualitySettings.anisotropicFiltering = (AnisotropicFiltering)(_configurationHandler.AnisotropicFiltering ? 2 : 0);
			Plugin.Log.LogInfo((object)("Anisotropic Filtering applied: " + _configurationHandler.AnisotropicFiltering));
		}

		public void SetPostProcessAA()
		{
			UniversalAdditionalCameraData val = default(UniversalAdditionalCameraData);
			if (((Component)MainCamera.instance.cam).TryGetComponent<UniversalAdditionalCameraData>(ref val))
			{
				val.antialiasing = (AntialiasingMode)Plugin.Instance.ConfigurationHandler.CameraAA;
			}
			Plugin.Log.LogInfo((object)("Camera AA applied: " + _configurationHandler.CameraAA));
		}

		public void SetMSAA()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.msaaSampleCount = Plugin.Instance.ConfigurationHandler.MSAA;
			}
			Plugin.Log.LogInfo((object)("MSAA applied: " + _configurationHandler.MSAA));
		}

		public void SetResolutionScale()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.renderScale = _configurationHandler.RenderScale;
				Plugin.Log.LogInfo((object)("Render Scale applied: " + _configurationHandler.RenderScale));
			}
		}

		public void SetUpscaler()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.upscalingFilter = (UpscalingFilterSelection)_configurationHandler.UpscalingFilter;
				Plugin.Log.LogInfo((object)("Upscaling Filter applied: " + _configurationHandler.UpscalingFilter));
			}
		}

		public void SetLODQuality()
		{
			QualitySettings.lodBias = _configurationHandler.LodQuality;
			Plugin.Log.LogInfo((object)("LOD Bias applied: " + _configurationHandler.LodQuality));
		}

		public void SetShadowDistance()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.shadowDistance = _configurationHandler.ShadowDistance;
				Plugin.Log.LogInfo((object)("Shadow Distance applied: " + _configurationHandler.ShadowDistance));
			}
		}

		public void SetShadowCascades()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			UniversalRenderPipelineAsset val = (UniversalRenderPipelineAsset)(object)((currentRenderPipeline is UniversalRenderPipelineAsset) ? currentRenderPipeline : null);
			if (val != null)
			{
				val.shadowCascadeCount = _configurationHandler.ShadowCascades;
				Plugin.Log.LogInfo((object)("Shadow Cascades applied: " + _configurationHandler.ShadowCascades));
			}
		}
	}
}
namespace PEAK_Visuals.Patches
{
	public static class MainCameraPatch
	{
		[HarmonyPatch(typeof(MainCamera), "Awake")]
		private class AwakePatch
		{
			[HarmonyPostfix]
			private static void Postfix(MainCamera __instance)
			{
				Plugin.Instance.Settings.SetAllCameraSettings();
			}
		}
	}
	public static class SettingsHandlerPatches
	{
		[HarmonyPatch(typeof(SettingsHandler))]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private class ConstructorPatch
		{
			[HarmonyPostfix]
			private static void Postfix(SettingsHandler __instance)
			{
				Plugin.Instance.Settings.SetAllSettings();
			}
		}

		[HarmonyPatch(typeof(SettingsHandler), "SaveSetting")]
		private class SaveSettingPatch
		{
			[HarmonyPostfix]
			private static void Postfix(SettingsHandler __instance)
			{
				Plugin.Instance.Settings.SetAllSettings();
			}
		}
	}
}
namespace PEAK_Visuals.Configuration
{
	public class ConfigurationHandler
	{
		private ConfigFile _config;

		public ConfigEntry<float> ConfigRenderScale;

		public ConfigEntry<int> ConfigUpscalingFilter;

		public ConfigEntry<float> ConfigLODQuality;

		public ConfigEntry<string> ConfigMenuKey;

		public ConfigEntry<int> ConfigShadowDistance;

		public ConfigEntry<int> ConfigShadowCascades;

		public ConfigEntry<int> ConfigShadowmapResolution;

		public ConfigEntry<bool> ConfigSoftShadows;

		public ConfigEntry<bool> ConfigAnisotropicFiltering;

		public ConfigEntry<int> ConfigCameraAA;

		public ConfigEntry<int> ConfigMSAA;

		public InputAction MenuAction { get; set; }

		public float RenderScale => ConfigRenderScale.Value;

		public int UpscalingFilter => ConfigUpscalingFilter.Value;

		public float LodQuality => ConfigLODQuality.Value;

		public int ShadowDistance => ConfigShadowDistance.Value;

		public int ShadowCascades => ConfigShadowCascades.Value;

		public int ShadowmapResolution => ConfigShadowmapResolution.Value;

		public bool SoftShadows => ConfigSoftShadows.Value;

		public bool AnisotropicFiltering => ConfigAnisotropicFiltering.Value;

		public int CameraAA => ConfigCameraAA.Value;

		public int MSAA => ConfigMSAA.Value;

		public ConfigurationHandler(ConfigFile configFile)
		{
			_config = configFile;
			Plugin.Log.LogInfo((object)"ConfigurationHandler initialising");
			ConfigRenderScale = Bind("Scaling", "RenderScale", 1f, "Controls the render scale of the game. Native is 1.0 (100%). Range 0.1-2.0", delegate
			{
				Plugin.Instance.Settings.SetResolutionScale();
			}, (float v) => Mathf.Clamp(v, 0.1f, 2f));
			ConfigUpscalingFilter = Bind("Scaling", "UpscalingFilter", 1, "Controls what filter the game uses to scale to your monitor resolution. 0 = auto, 1 = linear, 2 = point, 3 = FSR 1.0, 4 = STP", delegate
			{
				Plugin.Instance.Settings.SetUpscaler();
			}, (int v) => Mathf.Clamp(v, 0, 4));
			ConfigLODQuality = Bind("LOD", "LODQuality", 2.5f, "Controls the LOD bias of the game. PEAK's High equates to 1.0. Higher values increase detail distance. Range 0.1-10", delegate
			{
				Plugin.Instance.Settings.SetLODQuality();
			}, (float v) => Mathf.Clamp(v, 0.1f, 10f));
			ConfigShadowDistance = Bind("Shadows", "ShadowDistance", 300, "Controls the maximum distance shadows are rendered. PEAK's High option equates to 200. Higher values improve distant shadows but reduce performance. Range 0-1000", delegate
			{
				Plugin.Instance.Settings.SetShadowDistance();
			}, (int v) => Mathf.Clamp(v, 0, 1000));
			ConfigShadowCascades = Bind("Shadows", "ShadowCascades", 4, "Controls the number of shadow cascades used by the directional light. PEAK's High option equates to 2. Higher values improve shadow stability. Range 1-10", delegate
			{
				Plugin.Instance.Settings.SetShadowCascades();
			}, (int v) => Mathf.Clamp(v, 1, 4));
			ConfigShadowmapResolution = Bind("Shadows", "ShadowmapResolution", 4096, "Controls the quality of the shadows, can reduce performance so turn it down if you're having issues. Makes the trees less wobbly", delegate
			{
				Plugin.Instance.Settings.SetShadowmapResolution();
			}, (int v) => Mathf.Clamp(v, 1024, 20480));
			ConfigSoftShadows = Bind("Shadows", "SoftShadows", defaultValue: true, "Allows shadows to be soft, if your PC is too low spec for a high shadowmap setting this to false can stop the wobblyness of the shadows (but will result in a pixelly effect if the shadowmap res is low)", delegate
			{
				Plugin.Instance.Settings.SetSoftShadows();
			});
			ConfigAnisotropicFiltering = Bind("Quality", "AnisotropicFiltering", defaultValue: true, "Helps texture sharpness at angles (set to on)", delegate
			{
				Plugin.Instance.Settings.SetAnisotropicFiltering();
			});
			ConfigCameraAA = Bind("AntiAliasing", "CameraAA", 2, "Controls what type of AA the Camera uses. By default PEAK uses Temporal Antialiasing (TAA). All of these options are essentially clever blur filters and sometimes people find them unpleasant. 0 = None, 1 = FXAA, 2 = SMAA, 3 = TAA.", delegate
			{
				Plugin.Instance.Settings.SetPostProcessAA();
			}, (int v) => Mathf.Clamp(v, 0, 3));
			ConfigMSAA = Bind("AntiAliasing", "MSAA", 8, "Controls whether Multi-Sample Anti-Aliasing (MSAA) is enabled. MSAA smooths jagged edges on geometry by sampling pixels multiple times. It is generally sharper than post-process AA methods but only affects object edges and can slightly reduce performance. PEAK does not use it by default. Higher values = better quality but worse performance. Valid values = 0, 2, 4, 8.", delegate
			{
				Plugin.Instance.Settings.SetMSAA();
			}, (int v) => Mathf.Clamp(v, 0, 8));
			ConfigMenuKey = Bind("General", "Config Menu Key", "<Keyboard>/f11", "Control path for opening the mod configuration menu (e.g. <Keyboard>/f2, <Keyboard>/space, <Keyboard>/escape)", SetupInputAction);
			SetupInputAction();
			Plugin.Log.LogInfo((object)"ConfigurationHandler initialised");
		}

		private ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, Action onChanged = null, Func<T, T> clamp = null)
		{
			Func<T, T> clamp2 = clamp;
			Action onChanged2 = onChanged;
			ConfigEntry<T> entry = _config.Bind<T>(section, key, defaultValue, description);
			if (clamp2 != null)
			{
				entry.Value = clamp2(entry.Value);
			}
			Plugin.Log.LogInfo((object)$"{key} set to: {entry.Value}");
			if (onChanged2 != null)
			{
				entry.SettingChanged += delegate
				{
					if (clamp2 != null)
					{
						entry.Value = clamp2(entry.Value);
					}
					onChanged2();
				};
			}
			return entry;
		}

		private void SetupInputAction()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			InputAction menuAction = MenuAction;
			if (menuAction != null)
			{
				menuAction.Dispose();
			}
			MenuAction = new InputAction((string)null, (InputActionType)1, (string)null, (string)null, (string)null, (string)null);
			InputActionSetupExtensions.AddBinding(MenuAction, ConfigMenuKey.Value, (string)null, (string)null, (string)null);
			MenuAction.Enable();
		}
	}
	public class ModConfigurationUI : MonoBehaviour
	{
		private List<Option> _options;

		private bool _visible;

		private int _selectedIndex;

		private bool _prevCursorVisible;

		private CursorLockMode _prevCursorLock;

		private bool _waitingForBinding;

		private Option _bindingTarget;

		private Texture2D _whiteTex;

		private GUIStyle _titleStyle;

		private GUIStyle _rowStyle;

		private GUIStyle _hintStyle;

		private string titleText = "PEAK Visuals Settings | v " + Plugin.Version;

		private string hintText = "F2: Open/Close • Tab or ↑/↓: Move • Enter/Click: Change • Scroll Wheel or ←/→ Arrows: Adjust Numerical Values • +/-: Scale Menu";

		private int RowHeight = 32;

		private int PanelWidth = 460;

		private int Pad = 12;

		private int TitleFontSize = 22;

		private int OptionFontSize = 16;

		private int HintFontSize = 14;

		private Color GetColor(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)SystemInfo.graphicsDeviceType == 21)
			{
				return ((Color)(ref c)).linear;
			}
			return c;
		}

		private void CalculatePanelWidth()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			float num = _titleStyle.CalcSize(new GUIContent(titleText)).x;
			foreach (Option option in _options)
			{
				float x = _rowStyle.CalcSize(new GUIContent(option.Label + ": " + option.DisplayValue())).x;
				if (x > num)
				{
					num = x;
				}
			}
			int num2 = CalculateHintWidth();
			num = Mathf.Max(num, (float)num2);
			PanelWidth = Mathf.Clamp((int)num + Pad * 2, 460, Screen.width - Pad * 2);
		}

		private int CalculateHintWidth()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			float num = _hintStyle.CalcHeight(new GUIContent("Test"), 9999f);
			float num2 = num * 2f;
			for (int i = 200; i < Screen.width - Pad * 2; i += 20)
			{
				float num3 = _hintStyle.CalcHeight(new GUIContent(hintText), (float)i);
				if (num3 <= num2)
				{
					return i;
				}
			}
			return Screen.width - Pad * 2;
		}

		private void Scale(int scale)
		{
			if (scale >= 0 || HintFontSize >= 2)
			{
				TitleFontSize += scale * 2;
				OptionFontSize += scale * 2;
				HintFontSize += scale * 2;
				RowHeight = OptionFontSize + 16;
				CalculatePanelWidth();
			}
		}

		public void Init(List<Option> options)
		{
			_options = options ?? new List<Option>();
			_selectedIndex = 0;
			hintText = Plugin.Instance.ConfigurationHandler.ConfigMenuKey.Value.Split("/")[^1].ToUpper() + ": Open/Close • Tab or ↑/↓: Move • Enter/Click: Change • Scroll Wheel or ←/→ Arrows: Adjust Numerical Values • +/-: Scale Menu";
		}

		private void EnsureStyles()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a8: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_whiteTex == (Object)null)
			{
				_whiteTex = new Texture2D(1, 1, (TextureFormat)4, false);
				_whiteTex.SetPixel(0, 0, GetColor(Color.white));
				_whiteTex.Apply();
			}
			_titleStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = TitleFontSize,
				alignment = (TextAnchor)3,
				fontStyle = (FontStyle)1
			};
			_rowStyle = new GUIStyle(GUI.skin.button)
			{
				alignment = (TextAnchor)3,
				fontSize = OptionFontSize,
				padding = new RectOffset(10, 10, 4, 4)
			};
			_hintStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = HintFontSize,
				alignment = (TextAnchor)3,
				wordWrap = true
			};
		}

		private void Update()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			if (_waitingForBinding && ((ButtonControl)Keyboard.current.anyKey).wasPressedThisFrame)
			{
				Enumerator<KeyControl> enumerator = Keyboard.current.allKeys.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						KeyControl current = enumerator.Current;
						if (((ButtonControl)current).wasPressedThisFrame)
						{
							string path = ((InputControl)current).path;
							_bindingTarget.StringEntry.Value = path;
							Plugin.Log.LogInfo((object)("Rebound " + _bindingTarget.Label + " to " + path));
							_waitingForBinding = false;
							hintText = _bindingTarget.DisplayValue() + ": Open/Close • Tab or ↑/↓: Move • Enter/Click: Change • Scroll Wheel or ←/→ Arrows: Adjust Numerical Values • +/-: Scale Menu";
							_bindingTarget = null;
							break;
						}
					}
					return;
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			if (Plugin.Instance.ConfigurationHandler.MenuAction != null && Plugin.Instance.ConfigurationHandler.MenuAction.WasPerformedThisFrame())
			{
				_visible = !_visible;
				if (_visible)
				{
					OnOpened();
				}
				else
				{
					OnClosed();
				}
			}
			if (_visible && _options.Count != 0)
			{
				if (Input.GetKeyDown((KeyCode)9))
				{
					bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
					CycleSelection((!flag) ? 1 : (-1));
				}
				if (Input.GetKeyDown((KeyCode)61) || Input.GetKeyDown((KeyCode)43))
				{
					Scale(1);
				}
				if (Input.GetKeyDown((KeyCode)45))
				{
					Scale(-1);
				}
				if (Input.GetKeyDown((KeyCode)273))
				{
					CycleSelection(-1);
				}
				if (Input.GetKeyDown((KeyCode)274))
				{
					CycleSelection(1);
				}
				if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
				{
					ToggleSelected();
				}
				if (Input.GetKeyDown((KeyCode)276))
				{
					AdjustNumerical(-1);
				}
				if (Input.GetKeyDown((KeyCode)275))
				{
					AdjustNumerical(1);
				}
				float y = ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y;
				if (y > 0f)
				{
					AdjustNumerical(1);
				}
				else if (y < 0f)
				{
					AdjustNumerical(-1);
				}
			}
		}

		private void ToggleSelected()
		{
			Option option = _options[_selectedIndex];
			if (option.IsDisabled())
			{
				return;
			}
			switch (option.Type)
			{
			case Option.OptionType.Bool:
				option.BoolEntry.Value = !option.BoolEntry.Value;
				break;
			case Option.OptionType.Int:
			{
				int num2 = option.IntEntry.Value + option.Step;
				if (num2 > option.MaxInt)
				{
					num2 = option.MinInt;
				}
				option.IntEntry.Value = num2;
				break;
			}
			case Option.OptionType.Float:
			{
				float num = option.FloatEntry.Value + option.FloatStep;
				if (num > option.MaxFloat)
				{
					num = option.MinFloat;
				}
				option.FloatEntry.Value = num;
				break;
			}
			case Option.OptionType.InputAction:
				_waitingForBinding = true;
				_bindingTarget = option;
				break;
			case Option.OptionType.String:
				break;
			}
		}

		private void AdjustNumerical(int delta)
		{
			Option option = _options[_selectedIndex];
			if (!option.IsDisabled())
			{
				if (option.Type == Option.OptionType.Int)
				{
					int value = Mathf.Clamp(option.IntEntry.Value + delta * option.Step, option.MinInt, option.MaxInt);
					option.IntEntry.Value = value;
				}
				else if (option.Type == Option.OptionType.Float)
				{
					float value2 = Mathf.Clamp(option.FloatEntry.Value + (float)delta * option.FloatStep, option.MinFloat, option.MaxFloat);
					option.FloatEntry.Value = value2;
				}
			}
		}

		private void OnOpened()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_prevCursorVisible = Cursor.visible;
			_prevCursorLock = Cursor.lockState;
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
			if (_options.Count > 0 && _options[_selectedIndex].IsDisabled())
			{
				CycleSelection(1);
			}
		}

		private void OnClosed()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Cursor.visible = _prevCursorVisible;
			Cursor.lockState = _prevCursorLock;
		}

		private void CycleSelection(int delta)
		{
			if (_options.Count == 0)
			{
				return;
			}
			int selectedIndex = _selectedIndex;
			do
			{
				_selectedIndex = (_selectedIndex + delta) % _options.Count;
				if (_selectedIndex < 0)
				{
					_selectedIndex += _options.Count;
				}
			}
			while (_options[_selectedIndex].IsDisabled() && _selectedIndex != selectedIndex);
		}

		private void OnGUI()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			if (!_visible)
			{
				return;
			}
			EnsureStyles();
			CalculatePanelWidth();
			float num = _titleStyle.CalcHeight(new GUIContent(titleText), (float)(PanelWidth - Pad * 2));
			float num2 = _options.Count * (RowHeight + 4);
			float num3 = _hintStyle.CalcHeight(new GUIContent("Test"), 9999f);
			float num4 = num3 * 2f;
			int num5 = Pad + (int)num + 8 + (int)num2 + Pad + (int)num4;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(20f, 20f, (float)PanelWidth, (float)num5);
			GUI.color = GetColor(new Color(0f, 0f, 0f, 0.75f));
			GUI.DrawTexture(val, (Texture)(object)_whiteTex);
			GUI.color = Color.white;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + (float)Pad, ((Rect)(ref val)).y + (float)Pad, ((Rect)(ref val)).width - (float)(Pad * 2), num);
			GUI.Label(val2, titleText, _titleStyle);
			float num6 = ((Rect)(ref val2)).yMax + 8f;
			Rect val3 = default(Rect);
			for (int i = 0; i < _options.Count; i++)
			{
				((Rect)(ref val3))..ctor(((Rect)(ref val)).x + (float)Pad, num6, ((Rect)(ref val)).width - (float)(Pad * 2), (float)RowHeight);
				Option option = _options[i];
				if (((Rect)(ref val3)).Contains(Event.current.mousePosition) && !option.IsDisabled())
				{
					_selectedIndex = i;
				}
				if (i == _selectedIndex && !option.IsDisabled())
				{
					GUI.color = GetColor(new Color(1f, 1f, 1f, 0.24f));
					GUI.DrawTexture(val3, (Texture)(object)_whiteTex);
					GUI.color = Color.white;
				}
				GUI.enabled = !option.IsDisabled();
				if (option.Label == "Menu Key" && _waitingForBinding)
				{
					GUI.color = GetColor(new Color(0f, 0f, 0f, 0.6f));
					GUI.DrawTexture(val3, (Texture)(object)_whiteTex);
					GUI.color = Color.white;
					GUI.Button(val3, "Press any key...", _rowStyle);
				}
				else if (GUI.Button(val3, option.Label + ": " + option.DisplayValue(), _rowStyle) && !option.IsDisabled())
				{
					ToggleSelected();
				}
				GUI.enabled = true;
				num6 += (float)(RowHeight + 4);
			}
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(((Rect)(ref val)).x + (float)Pad, ((Rect)(ref val)).yMax - (float)Pad - num4, ((Rect)(ref val)).width - (float)(Pad * 2), num4);
			GUI.Label(val4, hintText, _hintStyle);
		}

		private void OnDestroy()
		{
			if ((Object)(object)_whiteTex != (Object)null)
			{
				Object.Destroy((Object)(object)_whiteTex);
				_whiteTex = null;
			}
		}
	}
	public class Option
	{
		public enum OptionType
		{
			Bool,
			Int,
			String,
			InputAction,
			Float
		}

		public string Label { get; set; }

		public OptionType Type { get; set; }

		public ConfigEntry<bool> BoolEntry { get; set; }

		public ConfigEntry<int> IntEntry { get; set; }

		public ConfigEntry<string> StringEntry { get; set; }

		public int MinInt { get; set; }

		public int MaxInt { get; set; }

		public int Step { get; set; }

		public Func<bool> IsDisabled { get; set; } = () => false;


		public Func<string> DisplayValue { get; set; } = () => "";


		public ConfigEntry<float> FloatEntry { get; set; }

		public float MinFloat { get; set; }

		public float MaxFloat { get; set; }

		public float FloatStep { get; set; }

		private Option(string label, OptionType type)
		{
			Label = label;
			Type = type;
		}

		public static Option Float(string label, ConfigEntry<float> entry, float min, float max, float step = 0.05f, Func<bool>? isDisabled = null)
		{
			ConfigEntry<float> entry2 = entry;
			return new Option(label, OptionType.Float)
			{
				FloatEntry = entry2,
				MinFloat = min,
				MaxFloat = max,
				FloatStep = step,
				IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
				DisplayValue = () => entry2.Value.ToString("F3")
			};
		}

		public static Option Bool(string label, ConfigEntry<bool> entry, Func<bool>? isDisabled = null)
		{
			ConfigEntry<bool> entry2 = entry;
			return new Option(label, OptionType.Bool)
			{
				BoolEntry = entry2,
				IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
				DisplayValue = () => (!entry2.Value) ? "OFF" : "ON"
			};
		}

		public static Option InputAction(string label, ConfigEntry<string> entry, Func<bool>? isDisabled = null)
		{
			ConfigEntry<string> entry2 = entry;
			return new Option(label, OptionType.InputAction)
			{
				StringEntry = entry2,
				IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
				DisplayValue = delegate
				{
					string[] array = entry2.Value.Split("/");
					return (array.Length <= 1) ? entry2.Value : array[^1].ToUpper();
				}
			};
		}

		public static Option Int(string label, ConfigEntry<int> entry, int min, int max, int step = 1, Func<bool>? isDisabled = null, Func<string>? displayValue = null)
		{
			ConfigEntry<int> entry2 = entry;
			return new Option(label, OptionType.Int)
			{
				IntEntry = entry2,
				MinInt = min,
				MaxInt = max,
				Step = step,
				IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
				DisplayValue = (displayValue ?? ((Func<string>)(() => entry2.Value.ToString())))
			};
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}