Decompiled source of Multiplayer Pause v1.0.0

com.github.glarmer.Vote_Pause.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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 Mirror;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using Vote_Pause.Configuration;
using Vote_Pause.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Mirror")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.glarmer.Vote_Pause")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+e6be22d40b52164f31d93989474a2d422db9de2e")]
[assembly: AssemblyProduct("com.github.glarmer.Vote_Pause")]
[assembly: AssemblyTitle("Vote Pause")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 Vote_Pause
{
	public struct ClientPausedMessage : NetworkMessage
	{
		public bool IsPaused;
	}
	public static class Networker
	{
		public static void RegisterNetwork()
		{
			RegisterSerialisers();
			if (NetworkClient.active)
			{
				RegisterClient();
			}
			if (NetworkServer.active)
			{
				RegisterServer();
			}
		}

		private static void RegisterSerialisers()
		{
			Writer<ClientPausedMessage>.write = delegate(NetworkWriter writer, ClientPausedMessage message)
			{
				NetworkWriterExtensions.WriteBool(writer, message.IsPaused);
			};
			Reader<ClientPausedMessage>.read = (NetworkReader reader) => new ClientPausedMessage
			{
				IsPaused = NetworkReaderExtensions.ReadBool(reader)
			};
			Writer<ServerPausedMessage>.write = delegate(NetworkWriter writer, ServerPausedMessage message)
			{
				NetworkWriterExtensions.WriteBool(writer, message.IsPaused);
			};
			Reader<ServerPausedMessage>.read = (NetworkReader reader) => new ServerPausedMessage
			{
				IsPaused = NetworkReaderExtensions.ReadBool(reader)
			};
		}

		private static void RegisterServer()
		{
			PauseManager.Instance.Pauses.Clear();
			NetworkServer.RegisterHandler<ClientPausedMessage>((Action<NetworkConnectionToClient, ClientPausedMessage>)OnClientPauseChanged, true);
			NetworkServer.OnDisconnectedEvent = (Action<NetworkConnectionToClient>)Delegate.Combine(NetworkServer.OnDisconnectedEvent, new Action<NetworkConnectionToClient>(OnClientDisconnected));
		}

		private static void RegisterClient()
		{
			NetworkClient.RegisterHandler<ServerPausedMessage>((Action<ServerPausedMessage>)OnServerPauseChanged, true);
		}

		private static void OnClientPauseChanged(NetworkConnectionToClient sender, ClientPausedMessage message)
		{
			PauseManager.Instance.Pauses[sender.connectionId] = message.IsPaused;
			PauseManager.Instance.DecideAndPause();
		}

		private static void OnServerPauseChanged(ServerPausedMessage message)
		{
			PauseManager.Instance.PauseGame(message.IsPaused);
		}

		private static void OnClientDisconnected(NetworkConnectionToClient conn)
		{
			if (Enumerable.Contains(PauseManager.Instance.Pauses.Keys, conn.connectionId))
			{
				PauseManager.Instance.Pauses.Remove(conn.connectionId);
			}
		}

		public static void SendServerPausedState(bool paused)
		{
			if (NetworkServer.active)
			{
				NetworkServer.SendToAll<ServerPausedMessage>(new ServerPausedMessage
				{
					IsPaused = paused
				}, 0, false);
			}
		}

		public static void SendClientPausedState(bool paused)
		{
			if (NetworkClient.isConnected)
			{
				NetworkClient.Send<ClientPausedMessage>(new ClientPausedMessage
				{
					IsPaused = paused
				}, 0);
			}
		}
	}
	public class PauseManager : MonoBehaviour
	{
		public static PauseManager Instance;

		public readonly Dictionary<int, bool> Pauses = new Dictionary<int, bool>();

		public void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)Instance);
			}
			InputManager.Instance.OnPauseMenuOpen += OnPauseMenuOpen;
			InputManager.Instance.OnPauseMenuClose += OnPauseMenuClose;
		}

		private void OnPauseMenuOpen()
		{
			if (NetworkServer.active)
			{
				Plugin.Log.LogInfo((object)"Paused server 1");
			}
			if (NetworkClient.active)
			{
				Plugin.Log.LogInfo((object)"Paused client 1");
				Networker.SendClientPausedState(paused: true);
			}
		}

		private void OnPauseMenuClose()
		{
			if (NetworkServer.active)
			{
				Plugin.Log.LogInfo((object)"Unpaused server 1");
			}
			if (NetworkClient.active)
			{
				Plugin.Log.LogInfo((object)"Unpaused client 1");
				Networker.SendClientPausedState(paused: false);
			}
		}

		public void DecideAndPause()
		{
			Plugin.Log.LogInfo((object)"DecideAndPause");
			float num = NetworkManager.singleton.numPlayers;
			float num2 = 0f;
			float num3 = 0.45f;
			foreach (KeyValuePair<int, bool> pause in Pauses)
			{
				if (pause.Value)
				{
					num2 += 1f;
				}
			}
			Plugin.Log.LogInfo((object)$"Paused players: {num2}/{num}");
			bool flag = num2 / num > num3;
			if (flag)
			{
				Plugin.Log.LogInfo((object)"Paused players is enough to pause!");
			}
			Networker.SendServerPausedState(flag);
		}

		public void PauseGame(bool shouldPause)
		{
			Time.timeScale = ((!shouldPause) ? 1 : 0);
		}

		public void OnDestroy()
		{
			InputManager.Instance.OnPauseMenuOpen -= OnPauseMenuOpen;
			InputManager.Instance.OnPauseMenuClose -= OnPauseMenuClose;
		}
	}
	[BepInPlugin("com.github.glarmer.Vote_Pause", "Vote Pause", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private ModConfigurationUI _ui;

		public GameObject VoteObject;

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

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		public static ConfigurationHandler ConfigurationHandler { get; private set; }

		public static string Name => "Vote Pause";

		public static string Version => "0.1.0";

		private void Awake()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			ConfigurationHandler = new ConfigurationHandler(((BaseUnityPlugin)this).Config);
			GameObject val = new GameObject(Name);
			Object.DontDestroyOnLoad((Object)(object)val);
			_ui = val.AddComponent<ModConfigurationUI>();
			_ui.Init(new List<Option>(2)
			{
				Option.Bool("Enabled", ConfigurationHandler.ConfigEnabled),
				Option.InputAction("Menu Key", ConfigurationHandler.ConfigMenuKey)
			});
			Log.LogInfo((object)"Configuration UI loaded");
			_harmony = new Harmony("com.github.glarmer.Vote_Pause");
			_harmony.PatchAll(typeof(StoneWardsNetworkManagerPatches));
			VoteObject = new GameObject("VoteObject");
			Object.DontDestroyOnLoad((Object)(object)VoteObject);
			Log.LogInfo((object)("Plugin " + Name + " is loaded."));
		}

		private void Update()
		{
			if (ConfigurationHandler.MenuAction.WasPressedThisFrame())
			{
				_ui.ToggleMenu();
			}
			if (Input.GetKeyDown((KeyCode)112))
			{
				Time.timeScale = 0f;
			}
			else if (Input.GetKeyDown((KeyCode)108))
			{
				Time.timeScale = 1f;
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			ConfigurationHandler?.Dispose();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	public struct ServerPausedMessage : NetworkMessage
	{
		public bool IsPaused;
	}
}
namespace Vote_Pause.Patches
{
	public static class StoneWardsNetworkManagerPatches
	{
		[HarmonyPatch(typeof(NetworkHelper), "OnStartClient")]
		[HarmonyPostfix]
		private static void OnStartClientPostfix(NetworkHelper __instance)
		{
			Plugin.Log.LogInfo((object)"Start client postfix");
			Plugin.Instance.VoteObject.AddComponent<PauseManager>();
			Networker.RegisterNetwork();
		}
	}
}
namespace Vote_Pause.Configuration
{
	public sealed class ConfigurationHandler
	{
		private readonly ConfigFile _config;

		public ConfigEntry<string> ConfigMenuKey { get; }

		public ConfigEntry<bool> ConfigEnabled { get; }

		public InputAction MenuAction { get; private set; }

		public bool Enabled => ConfigEnabled.Value;

		public ConfigurationHandler(ConfigFile configFile)
		{
			_config = configFile;
			ConfigMenuKey = _config.Bind<string>("General", "Config Menu Key", "<Keyboard>/f2", "Control path for opening the mod configuration menu (e.g. <Keyboard>/f2, <Keyboard>/space, <Keyboard>/escape)");
			ConfigEnabled = _config.Bind<bool>("General", "Enabled", true, "Whether or not the mod is enabled.");
			SetupInputAction();
			ConfigMenuKey.SettingChanged += OnMenuKeyChanged;
			Plugin.Log.LogInfo((object)"ConfigurationHandler initialised");
		}

		private void OnMenuKeyChanged(object sender, EventArgs e)
		{
			SetupInputAction();
		}

		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 void Dispose()
		{
			ConfigMenuKey.SettingChanged -= OnMenuKeyChanged;
			InputAction menuAction = MenuAction;
			if (menuAction != null)
			{
				menuAction.Dispose();
			}
			_config.Save();
		}
	}
	public class ModConfigurationUI : MonoBehaviour
	{
		private List<Option> _options = new List<Option>();

		public bool _visible;

		private int _selectedIndex;

		private bool _waitingForBinding;

		private Option? _bindingTarget;

		private Texture2D? _whiteTex;

		private GUIStyle _titleStyle;

		private GUIStyle _rowStyle;

		private GUIStyle _hintStyle;

		private GUIStyle _buttonStyle;

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

		private string hintText = "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 const int ButtonWidth = 30;

		private const int ButtonHeight = 30;

		private const int ButtonHintSpacing = 4;

		public static ModConfigurationUI? Instance;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)Instance);
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			StartClosed();
		}

		private void StartClosed()
		{
			_visible = false;
		}

		private void Open()
		{
			_visible = true;
		}

		private void Close()
		{
			_visible = false;
			_waitingForBinding = false;
			_bindingTarget = null;
		}

		public void ToggleMenu()
		{
			_visible = !_visible;
			if (_visible)
			{
				Open();
				if (_options != null && _options.Count > 0 && _options[_selectedIndex].IsDisabled())
				{
					CycleSelection(1);
				}
			}
			else
			{
				Close();
			}
		}

		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.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_0043: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00a0: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_whiteTex == (Object)null)
			{
				_whiteTex = new Texture2D(1, 1);
				_whiteTex.SetPixel(0, 0, Color.white);
				_whiteTex.Apply();
			}
			_titleStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = TitleFontSize,
				alignment = (TextAnchor)3,
				fontStyle = (FontStyle)1
			};
			_rowStyle = new GUIStyle(GUI.skin.label)
			{
				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
			};
			_buttonStyle = new GUIStyle(GUI.skin.button)
			{
				fontSize = OptionFontSize,
				alignment = (TextAnchor)4
			};
		}

		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_01be: 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/*cast due to .constrained prefix*/).Dispose();
				}
			}
			if (_visible && _options != null && _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 CycleSelection(int delta)
		{
			if (_options == null || _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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: 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_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			if (!_visible)
			{
				return;
			}
			EnsureStyles();
			if (_options == null)
			{
				_options = new List<Option>();
			}
			CalculatePanelWidth();
			float num = _titleStyle.CalcHeight(new GUIContent(titleText), (float)(PanelWidth - Pad * 2));
			float num2 = _options.Count * (RowHeight + 4);
			float num3 = _hintStyle.CalcHeight(new GUIContent(hintText), (float)(PanelWidth - Pad * 2));
			int num4 = Pad + (int)num + 8 + (int)num2 + Pad + (int)num3 + 30 + 4 + Pad;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(20f, 20f, (float)PanelWidth, (float)num4);
			GUI.color = 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 num5 = ((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, num5, ((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;
				}
				DrawOptionBackground(val3);
				if (i == _selectedIndex && !option.IsDisabled())
				{
					DrawSelectedOverlay(val3);
				}
				GUI.enabled = !option.IsDisabled();
				if (option.Label == "Menu Key" && _waitingForBinding)
				{
					DrawWaitingOverlay(val3);
					GUI.Button(val3, "Press any key...", _rowStyle);
				}
				else if (GUI.Button(val3, option.Label + ": " + option.DisplayValue(), _rowStyle) && !option.IsDisabled())
				{
					ToggleSelected();
				}
				GUI.enabled = true;
				num5 += (float)(RowHeight + 4);
			}
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(((Rect)(ref val)).x + (float)Pad, num5 + (float)Pad, ((Rect)(ref val)).width - (float)(Pad * 2), num3);
			GUI.Label(val4, hintText, _hintStyle);
			float num6 = ((Rect)(ref val4)).yMax + 4f;
			if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 60f - (float)Pad, num6, 30f, 30f), "+", _buttonStyle))
			{
				Scale(1);
			}
			if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 30f - (float)Pad, num6, 30f, 30f), "-", _buttonStyle))
			{
				Scale(-1);
			}
		}

		private void DrawOptionBackground(Rect rect)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = new Color(0.3f, 0.3f, 0.3f, 0.8f);
			GUI.DrawTexture(rect, (Texture)(object)_whiteTex);
			GUI.color = Color.white;
		}

		private void DrawSelectedOverlay(Rect rect)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = new Color(1f, 1f, 1f, 0.24f);
			GUI.DrawTexture(rect, (Texture)(object)_whiteTex);
			GUI.color = Color.white;
		}

		private void DrawWaitingOverlay(Rect rect)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = new Color(0f, 0f, 0f, 0.6f);
			GUI.DrawTexture(rect, (Texture)(object)_whiteTex);
			GUI.color = Color.white;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_whiteTex != (Object)null)
			{
				Object.Destroy((Object)(object)_whiteTex);
				_whiteTex = null;
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = 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)
		{
			return new Option(label, OptionType.Float)
			{
				FloatEntry = entry,
				MinFloat = min,
				MaxFloat = max,
				FloatStep = step,
				IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
				DisplayValue = () => entry.Value.ToString("F3")
			};
		}

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

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

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