Decompiled source of InFalsusJudgementCounter v1.0.1

BepInEx/plugins/InFalsusJudgementCounter.dll

Decompiled 14 hours ago
using System;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo;
using Il2CppInterop.Runtime.Startup;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using UnityEngine;
using _E;
using _K;
using _b;
using ifapp.Game;
using ifapp.Game.Input;
using ifapp.Game.Scenes;
using ifapp.Game.Scenes.Game;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: AssemblyTitle("In Falsus Judgement Counter")]
[assembly: AssemblyCompany("SkyFrozen")]
[assembly: AssemblyCopyright("Copyright © SkyFrozen")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace InFalsusJudgementCounter
{
	public sealed class CounterBehaviour : MonoBehaviour
	{
		private static CounterBehaviour _instance;

		private readonly CounterCapture _capture = new CounterCapture();

		private readonly CounterView _view = new CounterView();

		private readonly CounterSettingsView _settingsView = new CounterSettingsView();

		private readonly CounterLifetime _life = new CounterLifetime();

		private readonly Stopwatch _clock = Stopwatch.StartNew();

		private ReferenceBackground _reference;

		private ResultsScene _results;

		private SongSelectScene _selection;

		private CounterShortcuts _shortcuts;

		private readonly CounterInputGate _inputGate = new CounterInputGate();

		private readonly Func<int, bool> _readKeys = Down;

		private int _polledFrame = -1;

		private string _notice = "";

		private bool _manualHidden;

		private bool _officialCapture;

		private bool _savePending;

		private double _hideUntil;

		private double _nextError;

		private double _nextCaptureAttempt;

		private double _saveAt;

		private double _noticeUntil;

		public CounterBehaviour(System.IntPtr pointer)
			: base(pointer)
		{
		}

		public void Awake()
		{
			_instance = this;
			_shortcuts = new CounterShortcuts(_readKeys, Plugin.SaveBindings);
			_shortcuts.Load(Plugin.PanelKey.Value, Plugin.VisibilityKey.Value);
			_settingsView.Shortcuts = _shortcuts;
			_reference = new ReferenceBackground(Path.Combine(Paths.ConfigPath, "InFalsusJudgementCounter", "custom-preview.png"), Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "InFalsusJudgementCounter-preview.png"));
			_reference.Load();
		}

		[DllImport("user32.dll")]
		private static extern short GetAsyncKeyState(int key);

		[HideFromIl2Cpp]
		private static bool Down(int key)
		{
			return (GetAsyncKeyState(key) & 0x8000) != 0;
		}

		[HideFromIl2Cpp]
		private void NewRun(GameScene scene)
		{
			_selection = null;
			_inputGate.Reset();
			_life.Begin(((Il2CppObjectBase)scene).Pointer.ToInt64());
			_capture.Reset();
			_results = null;
			_settingsView.Close();
		}

		[HideFromIl2Cpp]
		private void Clear()
		{
			_life.Clear();
			_capture.Reset();
			_results = null;
			_settingsView.Close();
		}

		[HideFromIl2Cpp]
		private void ObserveGame(GameScene scene)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			if (scene != null && ((Behaviour)scene).isActiveAndEnabled && _life.ObserveGame(((Il2CppObjectBase)scene).Pointer.ToInt64(), (int)scene._lN))
			{
				_capture.Reset();
				_results = null;
				_settingsView.Close();
			}
		}

		[HideFromIl2Cpp]
		public static void SceneEntered(GameScene __instance)
		{
			_instance?.NewRun(__instance);
		}

		[HideFromIl2Cpp]
		public static void SceneLeaving(GameScene __instance)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			CounterBehaviour instance = _instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance._settingsView.Close();
				instance._life.LeaveGame(((Il2CppObjectBase)__instance).Pointer.ToInt64(), (int)__instance._lN >= 4);
				if (!instance._life.Visible)
				{
					instance._capture.Reset();
				}
			}
		}

		[HideFromIl2Cpp]
		public static void ResultsObserved(ResultsScene __instance)
		{
			CounterBehaviour instance = _instance;
			if (!((Object)(object)instance == (Object)null) && __instance != null && ((Behaviour)__instance).isActiveAndEnabled)
			{
				instance._life.ObserveResults(((Il2CppObjectBase)__instance).Pointer.ToInt64());
				if (instance._life.InResults && instance._life.ResultsOwner == ((Il2CppObjectBase)__instance).Pointer.ToInt64())
				{
					instance._results = __instance;
				}
			}
		}

		[HideFromIl2Cpp]
		public static void ResultsLeaving(ResultsScene __instance)
		{
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance != (Object)null && instance._life.CloseResults(((Il2CppObjectBase)__instance).Pointer.ToInt64()))
			{
				instance.Clear();
			}
		}

		[HideFromIl2Cpp]
		public static void SelectionObserved(SongSelectScene __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance == (Object)null || __instance == null || !((Behaviour)__instance).isActiveAndEnabled)
			{
				return;
			}
			GameScene xn = GameScene._xn;
			if ((Object)(object)xn == (Object)null || !((Behaviour)xn).isActiveAndEnabled || (int)xn._lN >= 4)
			{
				if (instance._life.Visible)
				{
					instance.Clear();
				}
				SongSelectScene selection = instance._selection;
				System.IntPtr? intPtr = ((selection != null) ? new System.IntPtr?(((Il2CppObjectBase)selection).Pointer) : ((System.IntPtr?)null));
				System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
				if (!intPtr.HasValue || (intPtr.HasValue && intPtr.GetValueOrDefault() != pointer))
				{
					instance._settingsView.Close();
					instance._inputGate.Reset();
				}
				instance._selection = __instance;
			}
		}

		[HideFromIl2Cpp]
		public static void SelectionLeaving(SongSelectScene __instance)
		{
			CounterBehaviour instance = _instance;
			if (!((Object)(object)instance == (Object)null))
			{
				SongSelectScene selection = instance._selection;
				System.IntPtr? intPtr = ((selection != null) ? new System.IntPtr?(((Il2CppObjectBase)selection).Pointer) : ((System.IntPtr?)null));
				System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
				if (intPtr.HasValue && (!intPtr.HasValue || !(intPtr.GetValueOrDefault() != pointer)))
				{
					instance._selection = null;
					instance._settingsView.Close();
					instance._inputGate.Reset();
				}
			}
		}

		[HideFromIl2Cpp]
		public static void ScreenshotBegin()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance._officialCapture = true;
			}
		}

		[HideFromIl2Cpp]
		public static void ScreenshotStep(bool __result)
		{
			if (!__result)
			{
				ScreenshotEnd();
			}
		}

		[HideFromIl2Cpp]
		public static void ScreenshotEnd()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance._officialCapture = false;
			}
		}

		[HideFromIl2Cpp]
		public static void ScreenshotFailed(System.Exception __exception)
		{
			if (__exception != null)
			{
				ScreenshotEnd();
			}
		}

		[HideFromIl2Cpp]
		private void Report(System.Exception ex)
		{
			//IL_0006: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			TimeSpan elapsed = _clock.Elapsed;
			if (!(((TimeSpan)(ref elapsed)).TotalSeconds < _nextError))
			{
				elapsed = _clock.Elapsed;
				_nextError = ((TimeSpan)(ref elapsed)).TotalSeconds + 5.0;
				Plugin.Logger.LogWarning((object)("Counter observation skipped: " + (object)ex));
			}
		}

		[HideFromIl2Cpp]
		public static void JudgementsObserved(_VD __instance)
		{
			//IL_00e6: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_004d: Invalid comparison between Unknown and I4
			//IL_00c9: 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)
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance == (Object)null || __instance == null)
			{
				return;
			}
			TimeSpan elapsed = instance._clock.Elapsed;
			if (((TimeSpan)(ref elapsed)).TotalSeconds < instance._nextCaptureAttempt)
			{
				return;
			}
			try
			{
				GameScene xn = GameScene._xn;
				if ((Object)(object)xn == (Object)null || !((Behaviour)xn).isActiveAndEnabled || (int)xn._lN != 3)
				{
					return;
				}
				_VD dN = GameScene._DN;
				System.IntPtr? intPtr = ((dN != null) ? new System.IntPtr?(((Il2CppObjectBase)dN).Pointer) : ((System.IntPtr?)null));
				System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer;
				if (intPtr.HasValue && (!intPtr.HasValue || !(intPtr.GetValueOrDefault() != pointer)))
				{
					instance.ObserveGame(xn);
					if (instance._life.Current == CounterLifetime.Page.Playing)
					{
						CounterCapture capture = instance._capture;
						LogicalNotePlayer qe = LogicalNotePlayer._Qe;
						elapsed = instance._clock.Elapsed;
						capture.Observe(qe, ((TimeSpan)(ref elapsed)).TotalSeconds);
					}
				}
			}
			catch (System.Exception ex)
			{
				elapsed = instance._clock.Elapsed;
				instance._nextCaptureAttempt = ((TimeSpan)(ref elapsed)).TotalSeconds + 1.0;
				instance.Report(ex);
			}
		}

		[HideFromIl2Cpp]
		private void ObserveScreenshotKeys()
		{
			//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)
			if (Plugin.HideOnScreenshot.Value && Application.isFocused && (Down(123) || Down(44)))
			{
				TimeSpan elapsed = _clock.Elapsed;
				_hideUntil = ((TimeSpan)(ref elapsed)).TotalSeconds + 1.5;
			}
		}

		[HideFromIl2Cpp]
		private bool CanEdit(GameScene scene)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			SongSelectScene selection = _selection;
			if (selection == null || !((Behaviour)selection).isActiveAndEnabled || (scene != null && ((Behaviour)scene).isActiveAndEnabled && (int)scene._lN < 4))
			{
				if (_life.InResults)
				{
					ResultsScene results = _results;
					if (results != null && ((Behaviour)results).isActiveAndEnabled)
					{
						goto IL_0077;
					}
				}
				if (scene != null && ((Behaviour)scene).isActiveAndEnabled && (int)scene._lN == 3)
				{
					GamePauseLayer pauseLayer = scene.pauseLayer;
					if (pauseLayer == null)
					{
						return false;
					}
					return ((Behaviour)pauseLayer).isActiveAndEnabled;
				}
				return false;
			}
			goto IL_0077;
			IL_0077:
			return true;
		}

		[HideFromIl2Cpp]
		private bool AnyInputHeld()
		{
			for (int i = 1; i < 256; i++)
			{
				if (_readKeys.Invoke(i))
				{
					return true;
				}
			}
			return false;
		}

		[HideFromIl2Cpp]
		private void PrepareUiInput()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			int frameCount = Time.frameCount;
			if (_polledFrame == frameCount || _shortcuts == null)
			{
				return;
			}
			_polledFrame = frameCount;
			bool flag = CanEdit(GameScene._xn);
			bool isFocused = Application.isFocused;
			int num = _shortcuts.Poll(isFocused, flag, _settingsView.Open);
			if (_shortcuts.CloseRequested)
			{
				_settingsView.Close();
			}
			if (num == 1)
			{
				_manualHidden = !_manualHidden;
				_settingsView.Close();
			}
			TimeSpan elapsed;
			if (num == 0)
			{
				if (_settingsView.Open)
				{
					_settingsView.Close();
				}
				else if (flag && Plugin.InputBlockReady)
				{
					_settingsView.Open = true;
				}
				else
				{
					_notice = (Plugin.InputBlockReady ? "请在选歌、暂停或结算时打开设置" : "输入隔离初始化失败,请检查模组日志");
					elapsed = _clock.Elapsed;
					_noticeUntil = ((TimeSpan)(ref elapsed)).TotalSeconds + 2.5;
				}
			}
			if (_settingsView.Open && (!flag || !isFocused))
			{
				_settingsView.Close();
			}
			bool held = (_settingsView.Open || _inputGate.Blocked) && isFocused && AnyInputHeld();
			CounterInputGate inputGate = _inputGate;
			bool open = _settingsView.Open;
			elapsed = _clock.Elapsed;
			inputGate.Observe(open, isFocused, flag, held, ((TimeSpan)(ref elapsed)).TotalSeconds, frameCount);
		}

		[HideFromIl2Cpp]
		public static void BeforeNativeInput()
		{
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				instance.PrepareUiInput();
			}
			catch (System.Exception ex)
			{
				instance._settingsView.Close();
				instance._inputGate.Reset();
				instance.Report(ex);
			}
		}

		[HideFromIl2Cpp]
		public static void InputBarrierFailed(System.Exception error)
		{
			Plugin.InputBlockReady = false;
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance._settingsView.Close();
				instance._inputGate.Reset();
			}
			Plugin.Logger.LogWarning((object)("Input barrier disabled: " + error.Message));
		}

		[HideFromIl2Cpp]
		public static bool AllowNativeDispatch()
		{
			CounterBehaviour instance = _instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			try
			{
				BeforeNativeInput();
				if (!Application.isFocused || !instance.CanEdit(GameScene._xn))
				{
					instance._inputGate.Reset();
				}
				return !instance._inputGate.Blocked;
			}
			catch (System.Exception ex)
			{
				instance._settingsView.Close();
				instance._inputGate.Reset();
				instance.Report(ex);
				return true;
			}
		}

		public void Update()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameScene xn = GameScene._xn;
				ObserveGame(xn);
				if (_life.InResults)
				{
					ResultsScene results = _results;
					if (results == null || !((Behaviour)results).isActiveAndEnabled)
					{
						Clear();
					}
				}
				PrepareUiInput();
				ObserveScreenshotKeys();
				if (!_savePending)
				{
					return;
				}
				TimeSpan elapsed = _clock.Elapsed;
				if (((TimeSpan)(ref elapsed)).TotalSeconds >= _saveAt)
				{
					_savePending = false;
					try
					{
						Plugin.Save();
						return;
					}
					catch (System.Exception ex)
					{
						Plugin.Logger.LogWarning((object)("Counter settings save failed: " + ex.Message));
						return;
					}
				}
			}
			catch (System.Exception ex2)
			{
				Report(ex2);
			}
		}

		public void OnGUI()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GUI.depth = (_settingsView.Open ? (-31000) : (-9000));
				TimeSpan elapsed;
				if (!_life.Visible && !_settingsView.Open)
				{
					elapsed = _clock.Elapsed;
					if (((TimeSpan)(ref elapsed)).TotalSeconds >= _noticeUntil)
					{
						return;
					}
				}
				ObserveScreenshotKeys();
				if (Plugin.HideOnScreenshot.Value)
				{
					if (_officialCapture)
					{
						return;
					}
					elapsed = _clock.Elapsed;
					if (((TimeSpan)(ref elapsed)).TotalSeconds < _hideUntil)
					{
						return;
					}
				}
				GameScene xn = GameScene._xn;
				if (_life.InResults)
				{
					ResultsScene results = _results;
					if (results == null || !((Behaviour)results).isActiveAndEnabled)
					{
						Clear();
						return;
					}
				}
				if (_settingsView.Open)
				{
					if (!CanEdit(xn))
					{
						_settingsView.Close();
						return;
					}
					CounterOptions options = Plugin.Options;
					bool released;
					CounterOptions counterOptions = _settingsView.Draw(options, _capture.Counts, _reference, out released);
					if (counterOptions != options)
					{
						Plugin.Apply(counterOptions);
						_savePending = true;
						elapsed = _clock.Elapsed;
						_saveAt = ((TimeSpan)(ref elapsed)).TotalSeconds + 0.5;
					}
					if (released && _savePending)
					{
						_saveAt = 0.0;
					}
					return;
				}
				elapsed = _clock.Elapsed;
				if (((TimeSpan)(ref elapsed)).TotalSeconds < _noticeUntil)
				{
					_view.DrawPlan(new CounterInk[1]
					{
						new CounterInk((float)Screen.width * 0.3f, (float)Screen.height * 0.22f, (float)Screen.width * 0.65f, 32f, 3588878847u, _notice, 20)
					});
				}
				if (!_life.Visible || !Plugin.Enabled.Value || _manualHidden)
				{
					return;
				}
				if (!_life.InResults && Plugin.HideWhenPaused.Value && xn != null)
				{
					GamePauseLayer pauseLayer = xn.pauseLayer;
					if (((pauseLayer != null) ? new bool?(((Behaviour)pauseLayer).isActiveAndEnabled) : ((bool?)null)) == true)
					{
						return;
					}
				}
				CounterView view = _view;
				JudgementCounts counts = _capture.Counts;
				bool ready = _capture.Ready;
				float value = Plugin.Scale.Value;
				float value2 = Plugin.PositionX.Value;
				float value3 = Plugin.PositionY.Value;
				bool value4 = Plugin.Horizontal.Value;
				bool value5 = Plugin.BreakOnRight.Value;
				float value6 = Plugin.WidthScale.Value;
				float value7 = Plugin.HeightScale.Value;
				view.Draw(counts, ready, value, value2, value3, value4, null, value5, value6, value7);
			}
			catch (System.Exception ex)
			{
				Report(ex);
			}
		}

		public void OnDestroy()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			if (_savePending)
			{
				try
				{
					Plugin.Save();
				}
				catch
				{
				}
			}
			_inputGate.Reset();
			_reference?.Dispose();
			_settingsView.Dispose();
			_view.Dispose();
			Clear();
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_instance = null;
			}
		}
	}
	public static class CounterBindingPanel
	{
		public static CounterPanel Create(CounterShortcuts keys, int width, int height)
		{
			CounterRect b = CounterPanel.Create(CounterOptions.Default, width, height).Bounds;
			float s = b.W / 368f;
			CounterPanel p = new CounterPanel
			{
				Bounds = b
			};
			Box(0f, 0f, 368f, 430f, 118562303u);
			Box(0f, 0f, 368f, 2f, 2464017407u);
			Text(16f, 12f, 220f, 30f, "快捷键设置", 22);
			Button(104, 256f, 12f, 96f, "返回");
			Text(16f, 58f, 336f, 22f, "Ctrl / Alt / Shift 组合键均可使用", 13, 2293614847u);
			Text(16f, 94f, 336f, 24f, "打开 / 关闭设置面板", 16);
			Button(101, 16f, 124f, 336f, keys.Label(0), keys.Capturing == 0);
			Text(16f, 178f, 336f, 24f, "隐藏 / 恢复局内统计", 16);
			Button(102, 16f, 208f, 336f, keys.Label(1), keys.Capturing == 1);
			Text(16f, 262f, 336f, 22f, keys.Message, 12, 2464017407u);
			Text(16f, 294f, 336f, 20f, "Esc 取消录入 / 返回;整组松开后保存。", 12, 2293614847u);
			if (keys.Capturing >= 0)
			{
				Button(105, 16f, 332f, 336f, "取消本次修改");
			}
			else
			{
				Button(103, 16f, 332f, 336f, "恢复默认 F4 / Shift+F4");
			}
			Text(16f, 388f, 336f, 20f, "编辑时游戏输入已隔离,不会误选歌曲。", 12, 2293614847u);
			return p;
			[CompilerGenerated]
			void Box(float x, float y, float w, float h, uint color)
			{
				CounterRect counterRect = R(x, y, w, h);
				p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, color));
			}
			[CompilerGenerated]
			void Button(int id, float x, float y, float w, string text, bool active = false)
			{
				CounterRect rect = R(x, y, w, 34f);
				p.Controls.Add(new CounterControl(id, rect));
				Box(x, y, w, 34f, active ? 592138239u : 355221503u);
				Box(x, y + 33f, w, 1f, 2464017407u);
				Text(x + 9f, y + 4f, w - 18f, 26f, text, 15);
			}
			[CompilerGenerated]
			CounterRect R(float x, float y, float w, float h)
			{
				return new CounterRect(b.X + x * s, b.Y + y * s, w * s, h * s);
			}
			[CompilerGenerated]
			void Text(float x, float y, float w, float h, string text, int size = 14, uint color = 3588878847u)
			{
				CounterRect counterRect = R(x, y, w, h);
				p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, color, text, Math.Max(8, (int)Math.Round((double)((float)size * s)))));
			}
		}
	}
	public sealed class CounterCapture
	{
		private const int MaximumRecords = 120000;

		[field: CompilerGenerated]
		public JudgementCounts Counts
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public bool Ready
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public void Reset()
		{
			Counts = default(JudgementCounts);
			Ready = false;
		}

		public void Observe(LogicalNotePlayer player, double now)
		{
			//IL_0074: 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)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			_T ve = player._ve;
			Memory<_cH> val = ((ve != null) ? ve._cd : null);
			Object val2 = val?._object;
			if (val2 == null)
			{
				Ready = false;
				return;
			}
			System.IntPtr pointer = ((Il2CppObjectBase)val2).Pointer;
			System.IntPtr intPtr = IL2CPP.il2cpp_object_get_class(pointer);
			if (IL2CPP.il2cpp_class_get_element_class(intPtr) != Il2CppClassPointerStore<_cH>.NativeClassPtr || IL2CPP.il2cpp_array_element_size(intPtr) != 40 || System.Runtime.CompilerServices.Unsafe.SizeOf<JudgementRecord>() != 40 || RuntimeHelpers.IsReferenceOrContainsReferences<_cH>())
			{
				throw new InvalidOperationException("Unsupported native judgement layout; counter disabled for this read.");
			}
			Il2CppStructArray<_cH> val3 = new Il2CppStructArray<_cH>(pointer);
			try
			{
				int index = val._index;
				int dd = ve._Dd;
				int num = val._length & 0x7FFFFFFF;
				if (index < 0 || dd < 0 || dd > 120000 || dd > num || index > ((Il2CppArrayBase<_cH>)(object)val3).Length - dd)
				{
					throw new InvalidOperationException("Invalid judgement buffer range.");
				}
				System.Span<_cH> span = Il2CppStructArray<_cH>.op_Implicit(val3);
				if (span.IsEmpty)
				{
					Counts = default(JudgementCounts);
					Ready = true;
				}
				else
				{
					Counts = JudgementCounts.Read(MemoryMarshal.CreateReadOnlySpan<JudgementRecord>(ref System.Runtime.CompilerServices.Unsafe.As<_cH, JudgementRecord>(ref MemoryMarshal.GetReference<_cH>(span)), span.Length).Slice(index, dd));
					Ready = true;
				}
			}
			finally
			{
				GC.KeepAlive((object)val3);
				GC.KeepAlive((object)val2);
				GC.KeepAlive((object)player);
			}
		}
	}
	public sealed class CounterInputGate
	{
		private bool _draining;

		private int _neutral = -1;

		private double _after;

		[field: CompilerGenerated]
		public bool Blocked
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public void Reset()
		{
			Blocked = (_draining = false);
			_neutral = -1;
			_after = 0.0;
		}

		public void Observe(bool open, bool focused, bool editable, bool held, double now, int frame)
		{
			if (!focused || !editable)
			{
				Reset();
				return;
			}
			if (open)
			{
				Blocked = (_draining = true);
				_neutral = -1;
				_after = now + 0.08;
				return;
			}
			if (!_draining)
			{
				Blocked = false;
				return;
			}
			Blocked = true;
			if (held)
			{
				_neutral = -1;
				_after = now + 0.08;
				return;
			}
			if (_neutral < 0)
			{
				_neutral = frame;
			}
			if (frame > _neutral && now >= _after)
			{
				Reset();
			}
		}
	}
	public readonly record struct CounterInk(float X, float Y, float W, float H, uint Color, string Text = "", int Size = 16, bool Right = false)
	{
		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterInk");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("X = ");
			builder.Append(((object)X/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Y = ");
			builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString());
			builder.Append(", W = ");
			builder.Append(((object)W/*cast due to .constrained prefix*/).ToString());
			builder.Append(", H = ");
			builder.Append(((object)H/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Color = ");
			builder.Append(((object)Color/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Text = ");
			builder.Append((object)Text);
			builder.Append(", Size = ");
			builder.Append(((object)Size/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Right = ");
			builder.Append(((object)Right/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	public static class CounterLayout
	{
		public const float Width = 216f;

		public const float Height = 296f;

		public const uint Perfect = 4088463359u;

		public const uint Small = 3130716927u;

		public const uint Near = 2531125247u;

		public const uint Miss = 4101801983u;

		public static CounterRect Bounds(int screenWidth, int screenHeight, CounterOptions options)
		{
			CounterOptions counterOptions = options.Normalize();
			float num = (counterOptions.Horizontal ? 568f : 216f);
			float num2 = (counterOptions.Horizontal ? 120f : 296f);
			num *= counterOptions.WidthScale;
			num2 *= counterOptions.HeightScale;
			float num3 = Math.Min(counterOptions.Scale * Math.Clamp((float)screenHeight / 1080f, 0.5f, 2f), Math.Min((float)screenWidth / num, (float)screenHeight / num2));
			return new CounterRect(((float)screenWidth - num * num3) * counterOptions.X, ((float)screenHeight - num2 * num3) * counterOptions.Y, num * num3, num2 * num3);
		}

		public static List<CounterInk> Create(JudgementCounts n, int screenWidth, int screenHeight, float scale, float anchorX, float anchorY, bool ready, bool horizontal = false, bool breakOnRight = false, float widthScale = 1f, float heightScale = 1f)
		{
			CounterOptions counterOptions = new CounterOptions(Enabled: true, horizontal, anchorX, anchorY, scale, HideWhenPaused: false, HideOnScreenshot: true);
			counterOptions.WidthScale = widthScale;
			counterOptions.HeightScale = heightScale;
			CounterOptions counterOptions2 = counterOptions.Normalize();
			CounterRect counterRect = Bounds(screenWidth, screenHeight, counterOptions2 with
			{
				WidthScale = 1f,
				HeightScale = 1f
			});
			CounterRect counterRect2 = Bounds(screenWidth, screenHeight, counterOptions2);
			List<CounterInk> val = CreateBase(n, screenWidth, screenHeight, counterOptions2.Scale, counterOptions2.X, counterOptions2.Y, ready, horizontal, breakOnRight);
			float num = counterRect2.W / counterRect.W;
			float num2 = counterRect2.H / counterRect.H;
			for (int i = 0; i < val.Count; i++)
			{
				CounterInk counterInk = val[i];
				val[i] = counterInk with
				{
					X = counterRect2.X + (counterInk.X - counterRect.X) * num,
					Y = counterRect2.Y + (counterInk.Y - counterRect.Y) * num2,
					W = counterInk.W * num,
					H = counterInk.H * num2,
					Size = Math.Max(1, (int)Math.Round((double)((float)counterInk.Size * Math.Min(num, num2))))
				};
			}
			return val;
		}

		private static List<CounterInk> CreateBase(JudgementCounts n, int screenWidth, int screenHeight, float scale, float anchorX, float anchorY, bool ready, bool horizontal = false, bool breakOnRight = false)
		{
			if (horizontal)
			{
				return Horizontal(n, screenWidth, screenHeight, new CounterOptions(Enabled: true, Horizontal: true, anchorX, anchorY, scale, HideWhenPaused: true, HideOnScreenshot: true), ready, breakOnRight);
			}
			scale = (float.IsFinite(scale) ? Math.Clamp(scale, 0.6f, 2f) : 1f);
			float num = Math.Min((float)screenWidth / 216f, (float)screenHeight / 296f);
			float s = Math.Min(scale * Math.Clamp((float)screenHeight / 1080f, 0.5f, 2f), num);
			float x = ((float)screenWidth - 216f * s) * (float.IsFinite(anchorX) ? Math.Clamp(anchorX, 0f, 1f) : 0.02f);
			float y = ((float)screenHeight - 296f * s) * (float.IsFinite(anchorY) ? Math.Clamp(anchorY, 0f, 1f) : 0.35f);
			List<CounterInk> p = new List<CounterInk>(38);
			Box(0f, 0f, 216f, 296f, 118562280u);
			Box(0f, 0f, 216f, 1f, 1147762892u);
			Box(0f, 295f, 216f, 1f, 1147762892u);
			Box(0f, 0f, 3f, 296f, 1147762824u);
			Box(0f, 0f, 62f, 2f, 2296244991u);
			Text(12f, 8f, 188f, 18f, "JUDGEMENT", 3588878847u, 13);
			Text(16f, 30f, 184f, 18f, "EARLY / FAST", 2293614847u, 11);
			Row(50f, "NEAR", n.EarlyNear, 2531125247u);
			Row(85f, "EXACT", n.EarlyExact, 3130716927u);
			Row(122f, "EXACT", n.Exact, 4088463359u, centre: true);
			Row(159f, "EXACT", n.LateExact, 3130716927u);
			Row(194f, "NEAR", n.LateNear, 2531125247u);
			Text(16f, 230f, 184f, 18f, "LATE / SLOW", 2293614847u, 11);
			Box(10f, 251f, 196f, 1f, 1147762858u);
			Row(257f, "BREAK", n.Break, 4101801983u);
			return p;
			[CompilerGenerated]
			void Box(float a, float b, float w, float h, uint c)
			{
				p.Add(new CounterInk(x + a * s, y + b * s, w * s, h * s, c));
			}
			[CompilerGenerated]
			void Row(float top, string name, int value, uint color, bool centre = false)
			{
				Box(10f, top, 196f, 32f, centre ? 942427865u : 287387306u);
				Box(10f, top, 2f, 32f, color);
				Text(20f, top + 4f, 86f, 24f, name, color, centre ? 20 : 17);
				Text(110f, top + 3f, 84f, 26f, ready ? value.ToString() : "--", color, centre ? 23 : 20, right: true);
			}
			[CompilerGenerated]
			void Text(float a, float b, float w, float h, string text, uint c, int size = 16, bool right = false)
			{
				p.Add(new CounterInk(x + a * s, y + b * s, w * s, h * s, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s))), right));
			}
		}

		private static List<CounterInk> Horizontal(JudgementCounts n, int width, int height, CounterOptions o, bool ready, bool breakOnRight)
		{
			CounterRect b = Bounds(width, height, o);
			float s = b.W / 568f;
			List<CounterInk> p = new List<CounterInk>(40);
			Box(0f, 0f, 568f, 120f, 118562280u);
			Box(0f, 0f, 568f, 1f, 1147762892u);
			Box(0f, 0f, 62f, 2f, 2296244991u);
			Box(0f, 119f, 568f, 1f, 1147762892u);
			Text(12f, 5f, 280f, 18f, "JUDGEMENT", 3588878847u, 12);
			uint[] array = new uint[6];
			RuntimeHelpers.InitializeArray((System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			uint[] array2 = array;
			string[] array3 = new string[6] { "BREAK", "NEAR", "EXACT", "EXACT", "EXACT", "NEAR" };
			int[] array4 = new int[6] { n.Break, n.EarlyNear, n.EarlyExact, n.Exact, n.LateExact, n.LateNear };
			for (int i = 0; i < 6; i++)
			{
				int num = (breakOnRight ? ((i + 1) % 6) : i);
				float num2 = 10 + i * 92;
				Box(num2, 28f, 86f, 82f, (num == 3) ? 942427865u : 287387306u);
				Box(num2, 28f, 2f, 82f, array2[num]);
				Text(num2 + 8f, 48f, 72f, 22f, array3[num], array2[num], (num == 3) ? 18 : 16);
				Text(num2 + 8f, 73f, 70f, 30f, Count(array4[num]), array2[num], (num == 3) ? 22 : 20, right: true);
			}
			Text(breakOnRight ? 18 : 110, 30f, 164f, 16f, "FAST", 2293614847u, 10);
			Text(breakOnRight ? 294 : 386, 30f, 164f, 16f, "LATE", 2293614847u, 10);
			return p;
			[CompilerGenerated]
			void Box(float x, float y, float w, float h, uint c)
			{
				p.Add(new CounterInk(b.X + x * s, b.Y + y * s, w * s, h * s, c));
			}
			[CompilerGenerated]
			string Count(int v)
			{
				if (!ready)
				{
					return "--";
				}
				return v.ToString();
			}
			[CompilerGenerated]
			void Text(float x, float y, float w, float h, string text, uint c, int size = 16, bool right = false)
			{
				p.Add(new CounterInk(b.X + x * s, b.Y + y * s, w * s, h * s, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s))), right));
			}
		}
	}
	public sealed class CounterLifetime
	{
		public enum Page
		{
			Hidden,
			Playing,
			AwaitingResults,
			Results
		}

		private int _state = -1;

		private long _closedGameOwner;

		[field: CompilerGenerated]
		public Page Current
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public long GameOwner
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public long ResultsOwner
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public bool Visible => Current != Page.Hidden;

		public bool InResults => Current == Page.Results;

		public void Begin(long owner)
		{
			Current = Page.Playing;
			GameOwner = owner;
			ResultsOwner = 0L;
			_state = -1;
		}

		public bool ObserveGame(long owner, int state)
		{
			if (Current == Page.Hidden && owner == _closedGameOwner && state >= 3)
			{
				return false;
			}
			int num;
			if (owner == GameOwner && Current != Page.Hidden)
			{
				if (state >= 0 && state < 3)
				{
					num = ((_state >= 3) ? 1 : 0);
					if (num != 0)
					{
						goto IL_0045;
					}
				}
				else
				{
					num = 0;
				}
				goto IL_004c;
			}
			num = 1;
			goto IL_0045;
			IL_0045:
			Begin(owner);
			goto IL_004c;
			IL_004c:
			_state = state;
			if (state >= 4 && Current == Page.Playing)
			{
				Current = Page.AwaitingResults;
			}
			return (byte)num != 0;
		}

		public void LeaveGame(long owner, bool completed)
		{
			if (owner == GameOwner && Current != Page.Results)
			{
				if (completed)
				{
					Current = Page.AwaitingResults;
				}
				else
				{
					Clear();
				}
			}
		}

		public void ObserveResults(long owner)
		{
			if ((Current == Page.AwaitingResults || Current == Page.Results) && (ResultsOwner == 0L || ResultsOwner == owner))
			{
				ResultsOwner = owner;
				Current = Page.Results;
			}
		}

		public bool CloseResults(long owner)
		{
			if (!InResults || owner != ResultsOwner)
			{
				return false;
			}
			Clear();
			return true;
		}

		public void Clear()
		{
			if (GameOwner != 0L)
			{
				_closedGameOwner = GameOwner;
			}
			Current = Page.Hidden;
			long gameOwner = (ResultsOwner = 0L);
			GameOwner = gameOwner;
			_state = -1;
		}
	}
	public readonly record struct CounterOptions
	{
		public bool Enabled
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public bool Horizontal
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public float X
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public float Y
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public float Scale
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public bool HideWhenPaused
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public bool HideOnScreenshot
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public bool BreakOnRight
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public float WidthScale
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public float HeightScale
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			init;
		}

		public static CounterOptions Default => new CounterOptions(Enabled: true, Horizontal: false, 0.02f, 0.35f, 1f, HideWhenPaused: false, HideOnScreenshot: true);

		public CounterOptions(bool Enabled, bool Horizontal, float X, float Y, float Scale, bool HideWhenPaused, bool HideOnScreenshot)
		{
			BreakOnRight = false;
			this.Enabled = Enabled;
			this.Horizontal = Horizontal;
			this.X = X;
			this.Y = Y;
			this.Scale = Scale;
			this.HideWhenPaused = HideWhenPaused;
			this.HideOnScreenshot = HideOnScreenshot;
			WidthScale = 1f;
			HeightScale = 1f;
		}

		public CounterOptions Normalize()
		{
			return this with
			{
				X = Finite(X, 0f, 1f, 0.02f),
				Y = Finite(Y, 0f, 1f, 0.35f),
				Scale = Finite(Scale, 0.6f, 2f, 1f),
				WidthScale = Finite(WidthScale, 0.4f, 2.5f, 1f),
				HeightScale = Finite(HeightScale, 0.4f, 2.5f, 1f)
			};
		}

		private static float Finite(float n, float min, float max, float fallback)
		{
			if (!float.IsFinite(n))
			{
				return fallback;
			}
			return Math.Clamp(n, min, max);
		}

		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterOptions");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Enabled = ");
			builder.Append(((object)Enabled/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Horizontal = ");
			builder.Append(((object)Horizontal/*cast due to .constrained prefix*/).ToString());
			builder.Append(", X = ");
			builder.Append(((object)X/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Y = ");
			builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Scale = ");
			builder.Append(((object)Scale/*cast due to .constrained prefix*/).ToString());
			builder.Append(", HideWhenPaused = ");
			builder.Append(((object)HideWhenPaused/*cast due to .constrained prefix*/).ToString());
			builder.Append(", HideOnScreenshot = ");
			builder.Append(((object)HideOnScreenshot/*cast due to .constrained prefix*/).ToString());
			builder.Append(", BreakOnRight = ");
			builder.Append(((object)BreakOnRight/*cast due to .constrained prefix*/).ToString());
			builder.Append(", WidthScale = ");
			builder.Append(((object)WidthScale/*cast due to .constrained prefix*/).ToString());
			builder.Append(", HeightScale = ");
			builder.Append(((object)HeightScale/*cast due to .constrained prefix*/).ToString());
			return true;
		}

		[CompilerGenerated]
		public void Deconstruct(out bool Enabled, out bool Horizontal, out float X, out float Y, out float Scale, out bool HideWhenPaused, out bool HideOnScreenshot)
		{
			Enabled = this.Enabled;
			Horizontal = this.Horizontal;
			X = this.X;
			Y = this.Y;
			Scale = this.Scale;
			HideWhenPaused = this.HideWhenPaused;
			HideOnScreenshot = this.HideOnScreenshot;
		}
	}
	public readonly record struct CounterRect(float X, float Y, float W, float H)
	{
		public bool Contains(float x, float y)
		{
			if (x >= X && x < X + W && y >= Y)
			{
				return y < Y + H;
			}
			return false;
		}

		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterRect");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("X = ");
			builder.Append(((object)X/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Y = ");
			builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString());
			builder.Append(", W = ");
			builder.Append(((object)W/*cast due to .constrained prefix*/).ToString());
			builder.Append(", H = ");
			builder.Append(((object)H/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	public readonly record struct CounterControl(int Id, CounterRect Rect, bool Slider = false)
	{
		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterControl");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Id = ");
			builder.Append(((object)Id/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Rect = ");
			builder.Append(((object)Rect/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Slider = ");
			builder.Append(((object)Slider/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	public sealed class CounterPanel
	{
		public readonly List<CounterInk> Ink = new List<CounterInk>();

		public readonly List<CounterControl> Controls = new List<CounterControl>();

		public CounterRect Bounds;

		public static CounterPanel Create(CounterOptions options, int width, int height)
		{
			CounterOptions counterOptions = options.Normalize();
			float s = Math.Min(Math.Clamp((float)height / 1080f, 0.55f, 1.6f), Math.Min((float)width / 408f, (float)height / 470f));
			float left = (float)width - 388f * s;
			float top = Math.Max(16f * s, Math.Min((float)height * 0.12f, (float)height - 446f * s));
			CounterPanel p = new CounterPanel
			{
				Bounds = new CounterRect(left, top, 368f * s, 430f * s)
			};
			Box(0f, 0f, 368f, 430f, 118562303u);
			Box(0f, 0f, 368f, 2f, 2464017407u);
			Text(16f, 12f, 224f, 30f, "判定统计设置", 3588878847u, 22);
			Button(17, 246f, 12f, 106f, "按键设置");
			Text(16f, 45f, 336f, 20f, "拖动定位 · 拖右下角改变长宽", 2293614847u, 13);
			Button(1, 16f, 76f, 104f, counterOptions.Enabled ? "显示:开" : "显示:关", counterOptions.Enabled);
			Button(2, 128f, 76f, 108f, "竖版", !counterOptions.Horizontal);
			Button(3, 244f, 76f, 108f, "横版", counterOptions.Horizontal);
			Slider(4, 16f, 118f, 160f, "水平", counterOptions.X, 0f, 1f, (counterOptions.X * 100f).ToString("0.0") + "%");
			Slider(5, 192f, 118f, 160f, "垂直", counterOptions.Y, 0f, 1f, (counterOptions.Y * 100f).ToString("0.0") + "%");
			Slider(14, 16f, 172f, 160f, "宽度", counterOptions.WidthScale, 0.4f, 2.5f, counterOptions.WidthScale.ToString("0.00") + "×");
			Slider(15, 192f, 172f, 160f, "高度", counterOptions.HeightScale, 0.4f, 2.5f, counterOptions.HeightScale.ToString("0.00") + "×");
			Slider(6, 16f, 226f, 336f, "整体缩放", counterOptions.Scale, 0.6f, 2f, counterOptions.Scale.ToString("0.00") + "×");
			Button(7, 16f, 286f, 160f, counterOptions.HideWhenPaused ? "暂停隐藏:开" : "暂停隐藏:关", counterOptions.HideWhenPaused);
			Button(8, 192f, 286f, 160f, counterOptions.HideOnScreenshot ? "截图隐藏:开" : "截图隐藏:关", counterOptions.HideOnScreenshot);
			Button(9, 16f, 324f, 160f, "恢复位置与尺寸");
			Button(10, 192f, 324f, 160f, "完成并关闭");
			Button(13, 16f, 362f, 160f, counterOptions.BreakOnRight ? "横版 Break:最右" : "横版 Break:最左", counterOptions.BreakOnRight);
			Button(12, 192f, 362f, 160f, "重新加载底图");
			Text(16f, 405f, 336f, 18f, "选歌 / 暂停 / 结算均可设置", 2293614847u, 12);
			return p;
			[CompilerGenerated]
			void Box(float x, float y, float w, float h, uint c)
			{
				CounterRect counterRect = R(x, y, w, h);
				p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, c));
			}
			[CompilerGenerated]
			void Button(int id, float x, float y, float w, string text, bool active = false)
			{
				CounterRect rect = R(x, y, w, 30f);
				p.Controls.Add(new CounterControl(id, rect));
				Box(x, y, w, 30f, active ? 592138239u : 355221503u);
				Box(x, y + 29f, w, 1f, active ? 1625932543u : 1400145151u);
				Text(x + 8f, y + 3f, w - 16f, 24f, text, active ? 1961740543u : 3588878847u, 14);
			}
			[CompilerGenerated]
			CounterRect R(float x, float y, float w, float h)
			{
				return new CounterRect(left + x * s, top + y * s, w * s, h * s);
			}
			[CompilerGenerated]
			void Slider(int id, float x, float y, float w, string label, float value, float min, float max, string display)
			{
				Text(x, y, w, 22f, label + "  " + display, 3084708607u, 14);
				CounterRect rect = R(x, y + 24f, w, 20f);
				p.Controls.Add(new CounterControl(id, rect, Slider: true));
				float num = Math.Clamp((value - min) / (max - min), 0f, 1f);
				Box(x, y + 32f, w, 3f, 742939135u);
				Box(x, y + 32f, w * num, 3f, 2464017407u);
				Box(x + w * num - 3f, y + 25f, 6f, 17f, 3824484351u);
			}
			[CompilerGenerated]
			void Text(float x, float y, float w, float h, string text, uint c = 3588878847u, int size = 16)
			{
				CounterRect counterRect = R(x, y, w, h);
				p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s)))));
			}
		}
	}
	public sealed class CounterEditor
	{
		public bool RefreshRequested;

		public bool ShortcutsRequested;

		private float _grabX;

		private float _grabY;

		private float _resizeX;

		private float _resizeY;

		private float _resizeW;

		private float _resizeH;

		private float _startWidth;

		private float _startHeight;

		private float _resizeLeft;

		private float _resizeTop;

		[field: CompilerGenerated]
		public int Captured
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		public void Cancel()
		{
			Captured = 0;
		}

		public CounterOptions Handle(CounterPanel panel, CounterRect overlay, CounterOptions options, int width, int height, float x, float y, bool down, bool drag, bool up, out bool close, CounterViewport? preview = null)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			close = false;
			CounterOptions counterOptions = options.Normalize();
			float num = preview?.OutputX(x) ?? x;
			float num2 = preview?.OutputY(y) ?? y;
			if (down && Captured == 0)
			{
				Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CounterControl current = enumerator.Current;
						if (current.Rect.Contains(x, y))
						{
							Captured = current.Id;
							break;
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				if (Captured == 0 && !panel.Bounds.Contains(x, y) && (!preview.HasValue || preview.GetValueOrDefault().Rect.Contains(x, y)) && overlay.Contains(num, num2))
				{
					float num3 = 16f / (preview?.Zoom ?? 1f);
					if (num >= overlay.X + overlay.W - num3 && num2 >= overlay.Y + overlay.H - num3)
					{
						Captured = 16;
						_resizeX = num;
						_resizeY = num2;
						_resizeW = overlay.W;
						_resizeH = overlay.H;
						_startWidth = counterOptions.WidthScale;
						_startHeight = counterOptions.HeightScale;
						_resizeLeft = overlay.X;
						_resizeTop = overlay.Y;
					}
					else
					{
						Captured = 11;
						_grabX = num - overlay.X;
						_grabY = num2 - overlay.Y;
					}
				}
			}
			if (((Captured >= 4 && Captured <= 6) || Captured == 14 || Captured == 15) && (down || drag || up))
			{
				Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CounterControl current2 = enumerator.Current;
						if (current2.Id == Captured)
						{
							float num4 = Math.Clamp((x - current2.Rect.X) / current2.Rect.W, 0f, 1f);
							counterOptions = ((Captured == 4) ? counterOptions with
							{
								X = num4
							} : ((Captured == 5) ? counterOptions with
							{
								Y = num4
							} : ((Captured == 14) ? counterOptions with
							{
								WidthScale = 0.4f + num4 * 2.1f
							} : ((Captured == 15) ? counterOptions with
							{
								HeightScale = 0.4f + num4 * 2.1f
							} : counterOptions with
							{
								Scale = 0.6f + num4 * 1.4f
							}))));
							break;
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			if (Captured == 11 && (down || drag || up))
			{
				counterOptions = counterOptions with
				{
					X = (((float)width > overlay.W) ? Math.Clamp((num - _grabX) / ((float)width - overlay.W), 0f, 1f) : 0f),
					Y = (((float)height > overlay.H) ? Math.Clamp((num2 - _grabY) / ((float)height - overlay.H), 0f, 1f) : 0f)
				};
			}
			if (Captured == 16 && (down || drag || up))
			{
				CounterOptions counterOptions2 = counterOptions with
				{
					WidthScale = _startWidth * (1f + (num - _resizeX) / _resizeW),
					HeightScale = _startHeight * (1f + (num2 - _resizeY) / _resizeH)
				};
				CounterOptions counterOptions3 = counterOptions2.Normalize();
				CounterRect counterRect = CounterLayout.Bounds(width, height, counterOptions3);
				counterOptions = counterOptions3 with
				{
					X = (((float)width > counterRect.W) ? Math.Clamp(_resizeLeft / ((float)width - counterRect.W), 0f, 1f) : 0f),
					Y = (((float)height > counterRect.H) ? Math.Clamp(_resizeTop / ((float)height - counterRect.H), 0f, 1f) : 0f)
				};
			}
			if (up)
			{
				Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						CounterControl current3 = enumerator.Current;
						if (current3.Id == Captured && current3.Rect.Contains(x, y))
						{
							switch (Captured)
							{
							case 1:
								counterOptions = counterOptions with
								{
									Enabled = !counterOptions.Enabled
								};
								break;
							case 2:
								counterOptions = counterOptions with
								{
									Horizontal = false
								};
								break;
							case 3:
								counterOptions = counterOptions with
								{
									Horizontal = true
								};
								break;
							case 7:
								counterOptions = counterOptions with
								{
									HideWhenPaused = !counterOptions.HideWhenPaused
								};
								break;
							case 8:
								counterOptions = counterOptions with
								{
									HideOnScreenshot = !counterOptions.HideOnScreenshot
								};
								break;
							case 9:
								counterOptions = counterOptions with
								{
									X = 0.02f,
									Y = 0.35f,
									Scale = 1f,
									WidthScale = 1f,
									HeightScale = 1f
								};
								break;
							case 10:
								close = true;
								break;
							case 12:
								RefreshRequested = true;
								break;
							case 13:
								counterOptions = counterOptions with
								{
									BreakOnRight = !counterOptions.BreakOnRight
								};
								break;
							case 17:
								ShortcutsRequested = true;
								break;
							case 4:
							case 5:
							case 6:
							case 11:
							case 14:
							case 15:
							case 16:
								break;
							}
							break;
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				Cancel();
			}
			return counterOptions;
		}
	}
	public sealed class CounterSettingsView
	{
		private readonly CounterView _painter = new CounterView
		{
			Depth = -31000
		};

		private readonly CounterView _previewPainter = new CounterView
		{
			Depth = -31000
		};

		private readonly CounterEditor _editor = new CounterEditor();

		private CounterPanel _panel;

		private CounterOptions _previous;

		private int _width;

		private int _height;

		private int _control;

		private int _bindingPressed;

		public CounterShortcuts Shortcuts;

		public bool Open;

		public void Close()
		{
			Open = false;
			_editor.Cancel();
			_bindingPressed = 0;
			Shortcuts?.CloseEditor();
			if (_control != 0 && GUIUtility.hotControl == _control)
			{
				GUIUtility.hotControl = 0;
			}
			_control = 0;
		}

		public CounterOptions Draw(CounterOptions o, JudgementCounts counts, ReferenceBackground background, out bool released)
		{
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Invalid comparison between Unknown and I4
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Invalid comparison between Unknown and I4
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Invalid comparison between Unknown and I4
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Invalid comparison between Unknown and I4
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Invalid comparison between Unknown and I4
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Invalid comparison between Unknown and I4
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Invalid comparison between Unknown and I4
			released = false;
			if (_panel == null || _previous != o || _width != Screen.width || _height != Screen.height)
			{
				_previous = o;
				_width = Screen.width;
				_height = Screen.height;
				_panel = CounterPanel.Create(o, _width, _height);
			}
			CounterViewport counterViewport = CounterViewport.Create(_width, _height, _panel.Bounds);
			_painter.DrawPlan(new CounterInk[1]
			{
				new CounterInk(0f, 0f, _width, _height, 101587199u)
			});
			background.Draw(counterViewport, -31000);
			_previewPainter.Draw(counts, ready: true, o.Scale, o.X, o.Y, o.Horizontal, counterViewport, o.BreakOnRight, o.WidthScale, o.HeightScale);
			CounterRect counterRect = CounterLayout.Bounds(_width, _height, o);
			_painter.DrawPlan(new CounterInk[2]
			{
				new CounterInk(counterRect.X + counterRect.W - 14f / counterViewport.Zoom, counterRect.Y + counterRect.H - 3f / counterViewport.Zoom, 14f / counterViewport.Zoom, 3f / counterViewport.Zoom, 2464017407u),
				new CounterInk(counterRect.X + counterRect.W - 3f / counterViewport.Zoom, counterRect.Y + counterRect.H - 14f / counterViewport.Zoom, 3f / counterViewport.Zoom, 14f / counterViewport.Zoom, 2464017407u)
			}, counterViewport);
			_painter.DrawPlan(new CounterInk[1]
			{
				new CounterInk(18f, 30f, _panel.Bounds.X - 30f, 24f, 3084708607u, "游戏截图定位预览 · 拖动统计框即可调整", Math.Max(10, (int)((float)_height / 1080f * 16f)))
			});
			CounterShortcuts shortcuts = Shortcuts;
			if (shortcuts != null && shortcuts.EditorOpen)
			{
				DrawBindings();
				return o;
			}
			Event current = Event.current;
			int controlID = GUIUtility.GetControlID(704118, (FocusType)2);
			if (current != null)
			{
				bool flag = (int)current.type == 0 && current.button == 0;
				bool flag2 = (int)current.type == 1 && current.button == 0;
				bool drag = (int)current.type == 3;
				bool flag3 = _editor.Captured != 0;
				o = _editor.Handle(_panel, CounterLayout.Bounds(_width, _height, o), o, _width, _height, current.mousePosition.x, current.mousePosition.y, flag, drag, flag2, out var close, counterViewport);
				if (flag && _editor.Captured != 0)
				{
					_control = controlID;
					GUIUtility.hotControl = controlID;
				}
				if (flag2 && flag3)
				{
					if (GUIUtility.hotControl == _control)
					{
						GUIUtility.hotControl = 0;
					}
					_control = 0;
					released = true;
				}
				if (((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6 || (int)current.type == 4 || (int)current.type == 5) && (flag3 || _editor.Captured != 0 || Open))
				{
					current.Use();
				}
				if (close)
				{
					released = true;
					Close();
				}
				if (_editor.RefreshRequested)
				{
					_editor.RefreshRequested = false;
					background.Reload();
				}
				if (_editor.ShortcutsRequested)
				{
					_editor.ShortcutsRequested = false;
					_editor.Cancel();
					Shortcuts?.OpenEditor();
				}
			}
			_painter.DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)_panel.Ink);
			return o;
		}

		private void DrawBindings()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Invalid comparison between Unknown and I4
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Invalid comparison between Unknown and I4
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Invalid comparison between Unknown and I4
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Invalid comparison between Unknown and I4
			CounterPanel counterPanel = CounterBindingPanel.Create(Shortcuts, _width, _height);
			Event current = Event.current;
			int controlID = GUIUtility.GetControlID(704119, (FocusType)2);
			if (current != null)
			{
				bool num = (int)current.type == 0 && current.button == 0;
				bool flag = (int)current.type == 1 && current.button == 0;
				if (num)
				{
					Enumerator<CounterControl> enumerator = counterPanel.Controls.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CounterControl current2 = enumerator.Current;
							if (current2.Rect.Contains(current.mousePosition.x, current.mousePosition.y))
							{
								_bindingPressed = current2.Id;
								_control = controlID;
								GUIUtility.hotControl = controlID;
								break;
							}
						}
					}
					finally
					{
						((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
					}
				}
				if (flag)
				{
					Enumerator<CounterControl> enumerator = counterPanel.Controls.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							CounterControl current3 = enumerator.Current;
							if (current3.Id != _bindingPressed || !current3.Rect.Contains(current.mousePosition.x, current.mousePosition.y))
							{
								continue;
							}
							if (current3.Id == 104)
							{
								Shortcuts.CloseEditor();
							}
							else if (current3.Id == 105)
							{
								Shortcuts.Cancel();
							}
							else if (Shortcuts.Capturing < 0)
							{
								if (current3.Id == 101 || current3.Id == 102)
								{
									Shortcuts.Begin(current3.Id - 101);
								}
								if (current3.Id == 103)
								{
									Shortcuts.Reset();
								}
							}
							break;
						}
					}
					finally
					{
						((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
					}
					_bindingPressed = 0;
					if (_control != 0 && GUIUtility.hotControl == _control)
					{
						GUIUtility.hotControl = 0;
					}
					_control = 0;
				}
				if ((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6 || (int)current.type == 4 || (int)current.type == 5)
				{
					current.Use();
				}
			}
			_painter.DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)counterPanel.Ink);
		}

		public void Dispose()
		{
			Close();
			_painter.Dispose();
			_previewPainter.Dispose();
			_panel = null;
		}
	}
	[Flags]
	public enum CounterModifiers : byte
	{
		None = 0,
		Ctrl = 1,
		Alt = 2,
		Shift = 4
	}
	public readonly record struct CounterChord(int Key, CounterModifiers Modifiers = CounterModifiers.None)
	{
		public string Text => (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Ctrl) ? "Ctrl+" : "") + (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Alt) ? "Alt+" : "") + (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Shift) ? "Shift+" : "") + Name(Key);

		public bool Allowed
		{
			get
			{
				if (Name(Key).Length > 0 && Key != 123 && ((uint)Modifiers & 0xFFFFFFF8u) == 0 && (!((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Alt) || (Key != 115 && Key != 9 && Key != 27 && Key != 32)) && (!((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Ctrl) || Key != 27))
				{
					if (Key == 46)
					{
						return (Modifiers & (CounterModifiers.Ctrl | CounterModifiers.Alt)) != (CounterModifiers.Ctrl | CounterModifiers.Alt);
					}
					return true;
				}
				return false;
			}
		}

		public static bool Modifier(int key)
		{
			switch (key)
			{
			case 16:
			case 17:
			case 18:
			case 91:
			case 92:
			case 160:
			case 161:
			case 162:
			case 163:
			case 164:
			case 165:
				return true;
			default:
				return false;
			}
		}

		public static string Name(int key)
		{
			switch (key)
			{
			case 65:
			case 66:
			case 67:
			case 68:
			case 69:
			case 70:
			case 71:
			case 72:
			case 73:
			case 74:
			case 75:
			case 76:
			case 77:
			case 78:
			case 79:
			case 80:
			case 81:
			case 82:
			case 83:
			case 84:
			case 85:
			case 86:
			case 87:
			case 88:
			case 89:
			case 90:
				return ((char)key).ToString();
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
				return ((char)key).ToString();
			case 112:
			case 113:
			case 114:
			case 115:
			case 116:
			case 117:
			case 118:
			case 119:
			case 120:
			case 121:
			case 122:
			case 123:
			case 124:
			case 125:
			case 126:
			case 127:
			case 128:
			case 129:
			case 130:
			case 131:
			case 132:
			case 133:
			case 134:
			case 135:
				return "F" + (key - 111).ToString((IFormatProvider)(object)CultureInfo.InvariantCulture);
			case 96:
			case 97:
			case 98:
			case 99:
			case 100:
			case 101:
			case 102:
			case 103:
			case 104:
			case 105:
				return "Num" + (key - 96).ToString((IFormatProvider)(object)CultureInfo.InvariantCulture);
			case 8:
				return "Backspace";
			case 9:
				return "Tab";
			case 13:
				return "Enter";
			case 32:
				return "Space";
			case 33:
				return "PageUp";
			case 34:
				return "PageDown";
			case 35:
				return "End";
			case 36:
				return "Home";
			case 37:
				return "Left";
			case 38:
				return "Up";
			case 39:
				return "Right";
			case 40:
				return "Down";
			case 45:
				return "Insert";
			case 46:
				return "Delete";
			case 106:
				return "NumMultiply";
			case 107:
				return "NumAdd";
			case 109:
				return "NumSubtract";
			case 110:
				return "NumDecimal";
			case 111:
				return "NumDivide";
			case 186:
				return "Semicolon";
			case 187:
				return "Equals";
			case 188:
				return "Comma";
			case 189:
				return "Minus";
			case 190:
				return "Period";
			case 191:
				return "Slash";
			case 192:
				return "Backquote";
			case 219:
				return "LeftBracket";
			case 220:
				return "Backslash";
			case 221:
				return "RightBracket";
			case 222:
				return "Quote";
			default:
				return "";
			}
		}

		public static bool TryParse(string text, out CounterChord result)
		{
			int num = 0;
			CounterModifiers counterModifiers = CounterModifiers.None;
			result = default(CounterChord);
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string[] array = text.Split('+', (StringSplitOptions)0);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				CounterModifiers counterModifiers2 = ((text2.Equals("Ctrl", (StringComparison)5) || text2.Equals("Control", (StringComparison)5)) ? CounterModifiers.Ctrl : (text2.Equals("Alt", (StringComparison)5) ? CounterModifiers.Alt : (text2.Equals("Shift", (StringComparison)5) ? CounterModifiers.Shift : CounterModifiers.None)));
				if (counterModifiers2 != CounterModifiers.None)
				{
					if ((counterModifiers & counterModifiers2) != CounterModifiers.None)
					{
						return false;
					}
					counterModifiers |= counterModifiers2;
					continue;
				}
				if (num != 0 || text2.Length == 0)
				{
					return false;
				}
				for (int j = 8; j < 256; j++)
				{
					if (text2.Equals(Name(j), (StringComparison)5))
					{
						num = j;
						break;
					}
				}
				if (num == 0)
				{
					return false;
				}
			}
			result = new CounterChord(num, counterModifiers);
			return result.Allowed;
		}

		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterChord");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Key = ");
			builder.Append(((object)Key/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Modifiers = ");
			builder.Append(((object)Modifiers/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Text = ");
			builder.Append((object)Text);
			builder.Append(", Allowed = ");
			builder.Append(((object)Allowed/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	public sealed class CounterShortcuts
	{
		private readonly Func<int, bool> _read;

		private readonly Func<CounterChord[], bool> _save;

		private readonly CounterChord[] _bindings = new CounterChord[2]
		{
			new CounterChord(115),
			new CounterChord(115, CounterModifiers.Shift)
		};

		private readonly bool[] _keys = new bool[256];

		private readonly bool[] _last = new bool[256];

		private bool _release = true;

		private bool _focused;

		private int _phase;

		private CounterChord _candidate;

		[field: CompilerGenerated]
		public bool EditorOpen
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public int Capturing
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		} = -1;

		[field: CompilerGenerated]
		public bool CloseRequested
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		public string Message
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		} = "支持 Ctrl / Alt / Shift + 一个主键。";

		private CounterModifiers Mods => (CounterModifiers)((_keys[17] ? 1 : 0) | (_keys[18] ? 2 : 0) | (_keys[16] ? 4 : 0));

		public static CounterChord Default(int i)
		{
			return new CounterChord(115, (i == 1) ? CounterModifiers.Shift : CounterModifiers.None);
		}

		public CounterChord Binding(int i)
		{
			return _bindings[i];
		}

		public string Label(int i)
		{
			if (i != Capturing)
			{
				return _bindings[i].Text;
			}
			if (_phase != 2)
			{
				return "等待按键…";
			}
			return _candidate.Text;
		}

		public CounterShortcuts(Func<int, bool> read = null, Func<CounterChord[], bool> save = null)
		{
			_read = read;
			_save = save;
		}

		public void Load(string panel, string visibility)
		{
			_bindings[0] = (CounterChord.TryParse(panel, out var result) ? result : Default(0));
			_bindings[1] = (CounterChord.TryParse(visibility, out var result2) ? result2 : Default(1));
			if (_bindings[0] == _bindings[1])
			{
				_bindings[0] = Default(0);
				_bindings[1] = Default(1);
			}
			_release = true;
		}

		public void OpenEditor()
		{
			EditorOpen = true;
			Cancel();
			Message = "点击对应按键修改;请避免与其他模组重合。";
		}

		public void CloseEditor()
		{
			EditorOpen = false;
			Cancel();
		}

		public void Cancel()
		{
			Capturing = -1;
			_phase = 0;
			_candidate = default(CounterChord);
			_release = true;
		}

		public void Begin(int i)
		{
			if (EditorOpen && i >= 0 && i <= 1)
			{
				Capturing = i;
				_phase = 0;
				_release = true;
				Message = "先松开旧按键,再按新组合,全部松开后保存。";
			}
		}

		private bool Save(CounterChord[] bindings)
		{
			try
			{
				return _save?.Invoke(bindings) ?? true;
			}
			catch
			{
				return false;
			}
		}

		public bool Reset()
		{
			if (Capturing >= 0)
			{
				return false;
			}
			CounterChord[] array = new CounterChord[2]
			{
				Default(0),
				Default(1)
			};
			if (!Save(array))
			{
				Message = "保存失败,原绑定保留。";
				return false;
			}
			System.Array.Copy((System.Array)array, (System.Array)_bindings, 2);
			Cancel();
			Message = "已恢复 F4 / Shift+F4。";
			return true;
		}

		public int Poll(bool focused, bool editable, bool panelOpen)
		{
			CloseRequested = false;
			if (!focused)
			{
				Cancel();
				_focused = false;
				return -1;
			}
			if (_read == null)
			{
				return -1;
			}
			bool flag = EditorOpen || _release;
			System.Array.Clear((System.Array)_keys, 0, 256);
			bool flag2 = false;
			for (int i = 8; i < 256; i++)
			{
				if (flag || i == 16 || i == 17 || i == 18 || i == 27 || i == 91 || i == 92 || i == _bindings[0].Key || i == _bindings[1].Key)
				{
					_keys[i] = _read.Invoke(i);
					flag2 |= _keys[i];
				}
			}
			try
			{
				if (!_focused)
				{
					_focused = true;
					_release = true;
				}
				if (EditorOpen && !editable)
				{
					CloseEditor();
					return -1;
				}
				if (_keys[27] && !_last[27])
				{
					if (Capturing >= 0)
					{
						Cancel();
						Message = "已取消,原绑定保留。";
					}
					else if (EditorOpen)
					{
						CloseEditor();
					}
					else if (panelOpen)
					{
						CloseRequested = true;
						_release = true;
					}
					return -1;
				}
				if (EditorOpen)
				{
					if (Capturing >= 0)
					{
						Capture(flag2);
					}
					else if (!flag2)
					{
						_release = false;
					}
					return -1;
				}
				if (_release)
				{
					if (!flag2)
					{
						_release = false;
					}
					return -1;
				}
				if (_keys[91] || _keys[92])
				{
					return -1;
				}
				for (int j = 0; j < 2; j++)
				{
					if (_keys[_bindings[j].Key] && !_last[_bindings[j].Key] && Mods == _bindings[j].Modifiers)
					{
						return j;
					}
				}
				return -1;
			}
			finally
			{
				System.Array.Copy((System.Array)_keys, (System.Array)_last, 256);
			}
		}

		private void Capture(bool any)
		{
			if (_phase == 0)
			{
				if (!any)
				{
					_phase = 1;
				}
				return;
			}
			int key = 0;
			int num = 0;
			for (int i = 8; i < 256; i++)
			{
				if (_keys[i] && !_last[i] && !CounterChord.Modifier(i))
				{
					key = i;
					num++;
				}
			}
			if (_phase == 2)
			{
				if (num > 0)
				{
					_phase = 0;
					Message = "一次只按一个主键,松键后重试。";
				}
				else if (!any)
				{
					CounterChord[] array = (CounterChord[])((System.Array)_bindings).Clone();
					array[Capturing] = _candidate;
					bool flag = Save(array);
					if (flag)
					{
						System.Array.Copy((System.Array)array, (System.Array)_bindings, 2);
					}
					Cancel();
					Message = (flag ? "绑定已保存。" : "保存失败,原绑定保留。");
				}
			}
			else if (num != 0)
			{
				CounterChord counterChord = new CounterChord(key, Mods);
				if (num != 1 || _keys[91] || _keys[92] || !counterChord.Allowed)
				{
					_phase = 0;
					Message = "该组合保留或不可用,松键后重试。";
				}
				else if (counterChord == _bindings[1 - Capturing])
				{
					_phase = 0;
					Message = "与另一功能重复,松键后重试。";
				}
				else
				{
					_candidate = counterChord;
					_phase = 2;
					Message = "已识别,松开全部按键后保存。";
				}
			}
		}
	}
	public sealed class CounterView
	{
		private GUIStyle _style;

		private readonly SafeGuiTexture _texturePainter = new SafeGuiTexture();

		private Font _font;

		private List<CounterInk> _plan;

		private JudgementCounts _previous;

		public int Depth = -9000;

		private int _width;

		private int _height;

		private float _scale;

		private float _x;

		private float _y;

		private float _widthScale;

		private float _heightScale;

		private bool _ready;

		private bool _horizontal;

		private bool _breakOnRight;

		public void Draw(JudgementCounts counts, bool ready, float scale, float x, float y, bool horizontal = false, CounterViewport? preview = null, bool breakOnRight = false, float widthScale = 1f, float heightScale = 1f)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			Event current = Event.current;
			if (current != null && (int)current.type == 7 && Screen.width >= 1 && Screen.height >= 1)
			{
				if (_plan == null || counts != _previous || ready != _ready || _width != Screen.width || _height != Screen.height || _scale != scale || _x != x || _y != y || _horizontal != horizontal || _breakOnRight != breakOnRight || _widthScale != widthScale || _heightScale != heightScale)
				{
					_previous = counts;
					_ready = ready;
					_width = Screen.width;
					_height = Screen.height;
					_scale = scale;
					_x = x;
					_y = y;
					_horizontal = horizontal;
					_breakOnRight = breakOnRight;
					_widthScale = widthScale;
					_heightScale = heightScale;
					_plan = CounterLayout.Create(counts, _width, _height, scale, x, y, ready, horizontal, breakOnRight, widthScale, heightScale);
				}
				DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)_plan, preview);
			}
		}

		public void DrawPlan(System.Collections.Generic.IReadOnlyList<CounterInk> plan, CounterViewport? preview = null)
		{
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_005e: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_022d: Unknown result type (might be due to invalid IL or missing references)
			Event current = Event.current;
			if (current == null || (int)current.type != 7)
			{
				return;
			}
			if (_style == null)
			{
				_font = new Font();
				Font.Internal_CreateDynamicFont(_font, new Il2CppStringArray(new string[3] { "Bahnschrift", "Microsoft YaHei UI", "Arial" }), 20);
				_style = new GUIStyle
				{
					font = _font,
					fontStyle = (FontStyle)0,
					wordWrap = false,
					clipping = (TextClipping)1
				};
				_style.normal.textColor = Color.white;
			}
			Color color = GUI.color;
			int depth = GUI.depth;
			try
			{
				GUI.depth = Depth;
				System.Collections.Generic.IEnumerator<CounterInk> enumerator = ((System.Collections.Generic.IEnumerable<CounterInk>)plan).GetEnumerator();
				try
				{
					Rect val = default(Rect);
					while (((System.Collections.IEnumerator)enumerator).MoveNext())
					{
						CounterInk current2 = enumerator.Current;
						GUI.color = new Color((float)(current2.Color >> 24) / 255f, (float)((current2.Color >> 16) & 0xFF) / 255f, (float)((current2.Color >> 8) & 0xFF) / 255f, (float)(current2.Color & 0xFF) / 255f);
						((Rect)(ref val))..ctor(current2.X, current2.Y, current2.W, current2.H);
						float num = preview?.Zoom ?? 1f;
						if (preview.HasValue)
						{
							CounterViewport value = preview.Value;
							((Rect)(ref val))..ctor(value.Rect.X + current2.X * num, value.Rect.Y + current2.Y * num, current2.W * num, current2.H * num);
						}
						if (current2.Text.Length == 0)
						{
							_texturePainter.Draw(val, Texture2D.whiteTexture);
							continue;
						}
						_style.fontSize = Math.Max(1, (int)Math.Round((double)((float)current2.Size * num)));
						_style.alignment = (TextAnchor)(current2.Right ? 5 : 3);
						GUI.Label(val, current2.Text, _style);
					}
				}
				finally
				{
					((System.IDisposable)enumerator)?.Dispose();
				}
			}
			finally
			{
				GUI.color = color;
				GUI.depth = depth;
			}
		}

		public void Dispose()
		{
			_texturePainter.Release();
			if ((Object)(object)_font != (Object)null)
			{
				Object.Destroy((Object)(object)_font);
			}
			_font = null;
			_style = null;
			_plan = null;
		}
	}
	public readonly record struct CounterViewport(CounterRect Rect, float Zoom)
	{
		public static CounterViewport Create(int width, int height, CounterRect panel)
		{
			float num = Math.Max(1f, panel.X - 36f);
			float num2 = Math.Max(1, height - 110);
			float num3 = Math.Min(num / (float)width, num2 / (float)height);
			return new CounterViewport(new CounterRect(18f + (num - (float)width * num3) * 0.5f, 66f + (num2 - (float)height * num3) * 0.5f, (float)width * num3, (float)height * num3), num3);
		}

		public float OutputX(float x)
		{
			return (x - Rect.X) / Zoom;
		}

		public float OutputY(float y)
		{
			return (y - Rect.Y) / Zoom;
		}

		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("CounterViewport");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Rect = ");
			builder.Append(((object)Rect/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Zoom = ");
			builder.Append(((object)Zoom/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	[StructLayout((LayoutKind)2, Size = 40)]
	public struct JudgementRecord
	{
		[FieldOffset(0)]
		public long Id;

		[FieldOffset(16)]
		public double AbsoluteMs;

		[FieldOffset(32)]
		public byte Result;

		[FieldOffset(33)]
		public byte Finalized;
	}
	public readonly record struct JudgementCounts(int Exact, int EarlyExact, int LateExact, int EarlyNear, int LateNear, int Break)
	{
		public int SmallExact => EarlyExact + LateExact;

		public int Near => EarlyNear + LateNear;

		public int Total => Exact + SmallExact + Near + Break;

		public static JudgementCounts Read(System.ReadOnlySpan<JudgementRecord> records)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			System.ReadOnlySpan<JudgementRecord> readOnlySpan = records;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				ref JudgementRecord reference = readOnlySpan[i];
				if (reference.Finalized != 0)
				{
					switch (reference.Result)
					{
					case 1:
						num6++;
						break;
					case 2:
						num4++;
						break;
					case 3:
						num5++;
						break;
					case 4:
						num2++;
						break;
					case 5:
						num3++;
						break;
					case 6:
						num++;
						break;
					}
				}
			}
			return new JudgementCounts(num, num2, num3, num4, num5, num6);
		}

		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("JudgementCounts");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Exact = ");
			builder.Append(((object)Exact/*cast due to .constrained prefix*/).ToString());
			builder.Append(", EarlyExact = ");
			builder.Append(((object)EarlyExact/*cast due to .constrained prefix*/).ToString());
			builder.Append(", LateExact = ");
			builder.Append(((object)LateExact/*cast due to .constrained prefix*/).ToString());
			builder.Append(", EarlyNear = ");
			builder.Append(((object)EarlyNear/*cast due to .constrained prefix*/).ToString());
			builder.Append(", LateNear = ");
			builder.Append(((object)LateNear/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Break = ");
			builder.Append(((object)Break/*cast due to .constrained prefix*/).ToString());
			builder.Append(", SmallExact = ");
			builder.Append(((object)SmallExact/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Near = ");
			builder.Append(((object)Near/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Total = ");
			builder.Append(((object)Total/*cast due to .constrained prefix*/).ToString());
			return true;
		}
	}
	public readonly record struct RgbaImage(int Width, int Height, byte[] Pixels)
	{
		[CompilerGenerated]
		public override string ToString()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringBuilder val = new StringBuilder();
			val.Append("RgbaImage");
			val.Append(" { ");
			if (PrintMembers(val))
			{
				val.Append(' ');
			}
			val.Append('}');
			return ((object)val).ToString();
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			builder.Append("Width = ");
			builder.Append(((object)Width/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Height = ");
			builder.Append(((object)Height/*cast due to .constrained prefix*/).ToString());
			builder.Append(", Pixels = ");
			builder.Append((object)Pixels);
			return true;
		}
	}
	public static class LocalImageCodec
	{
		private struct Startup
		{
			public uint Version;

			public System.IntPtr Callback;

			public int Thread;

			public int Codecs;
		}

		private struct Area
		{
			public int X;

			public int Y;

			public int Width;

			public int Height;
		}

		private struct BitmapData
		{
			public uint Width;

			public uint Height;

			public int Stride;

			public int Format;

			public System.IntPtr Pixels;

			public System.IntPtr Reserved;
		}

		private static System.IntPtr _token;

		private static readonly object Gate = new object();

		private const int Argb32 = 2498570;

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdiplusStartup(out System.IntPtr token, ref Startup input, System.IntPtr output);

		[DllImport("gdiplus.dll", CharSet = (CharSet)3, ExactSpelling = true)]
		private static extern int GdipCreateBitmapFromFile(string path, out System.IntPtr image);

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdipGetImageWidth(System.IntPtr image, out uint width);

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdipGetImageHeight(System.IntPtr image, out uint height);

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdipBitmapLockBits(System.IntPtr image, ref Area area, uint flags, int format, ref BitmapData data);

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdipBitmapUnlockBits(System.IntPtr image, ref BitmapData data);

		[DllImport("gdiplus.dll", ExactSpelling = true)]
		private static extern int GdipDisposeImage(System.IntPtr image);

		private static void Check(int status)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (status != 0)
			{
				throw new IOException("PNG codec status " + status);
			}
		}

		public static RgbaImage Load(string path)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			lock (Gate)
			{
				if (_token == System.IntPtr.Zero)
				{
					Startup input = new Startup
					{
						Version = 1u
					};
					Check(GdiplusStartup(out _token, ref input, System.IntPtr.Zero));
				}
				Check(GdipCreateBitmapFromFile(path, out var image));
				try
				{
					Check(GdipGetImageWidth(image, out var width));
					Check(GdipGetImageHeight(image, out var height));
					if (width == 0 || height == 0 || width > 8192 || height > 8192 || (long)width * (long)height > 16000000)
					{
						throw new IOException("Invalid reference screenshot dimensions");
					}
					int num = (int)width;
					int num2 = (int)height;
					Area area = new Area
					{
						Width = num,
						Height = num2
					};
					BitmapData data = default(BitmapData);
					Check(GdipBitmapLockBits(image, ref area, 1u, 2498570, ref data));
					try
					{
						byte[] array = new byte[checked(num * num2 * 4)];
						byte[] array2 = new byte[num * 4];
						for (int i = 0; i < num2; i++)
						{
							Marshal.Copy(System.IntPtr.Add(data.Pixels, i * data.Stride), array2, 0, array2.Length);
							int num3 = (num2 - 1 - i) * num * 4;
							for (int j = 0; j < array2.Length; j += 4)
							{
								array[num3 + j] = array2[j + 2];
								array[num3 + j + 1] = array2[j + 1];
								array[num3 + j + 2] = array2[j];
								array[num3 + j + 3] = array2[j + 3];
							}
						}
						return new RgbaImage(num, num2, array);
					}
					finally
					{
						GdipBitmapUnlockBits(image, ref data);
					}
				}
				finally
				{
					GdipDisposeImage(image);
				}
			}
		}

		public static RgbaImage Fit(RgbaImage image, int maxWidth)
		{
			if (image.Width <= maxWidth)
			{
				return image;
			}
			int num = Math.Max(1, (int)Math.Round((double)image.Height * (double)maxWidth / (double)image.Width));
			byte[] array = new byte[checked(maxWidth * num * 4)];
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < maxWidth; j++)
				{
					int num2 = ((int)((long)i * (long)image.Height / num) * image.Width + (int)((long)j * (long)image.Width / maxWidth)) * 4;
					int num3 = (i * maxWidth + j) * 4;
					array[num3] = image.Pixels[num2];
					array[num3 + 1] = image.Pixels[num2 + 1];
					array[num3 + 2] = image.Pixels[num2 + 2];
					array[num3 + 3] = image.Pixels[num2 + 3];
				}
			}
			return new RgbaImage(maxWidth, num, array);
		}

		public static byte[] Encode(RgbaImage image)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			if (image.Width <= 0 || image.Height <= 0 || image.Pixels.Length != checked(image.Width * image.Height * 4))
			{
				throw new ArgumentException("Invalid RGBA frame");
			}
			MemoryStream val = new MemoryStream();
			try
			{
				((Stream)val).Write((System.ReadOnlySpan<byte>)new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 });
				byte[] array = new byte[13];
				BinaryPrimitives.WriteInt32BigEndian(System.Span<byte>.op_Implicit(array), image.Width);
				BinaryPrimitives.WriteInt32BigEndian(MemoryExtensions.AsSpan<byte>(array, 4), image.Height);
				array[8] = 8;
				array[9] = 6;
				Chunk((Stream)(object)val, "IHDR", array);
				MemoryStream val2 = new MemoryStream();
				try
				{
					ZLibStream val3 = new ZLibStream((Stream)(object)val2, (CompressionLevel)1, true);
					try
					{
						for (int num = image.Height - 1; num >= 0; num--)
						{
							((Stream)val3).WriteByte((byte)0);
							((Stream)val3).Write(image.Pixels, num * image.Width * 4, image.Width * 4);
						}
					}
					finally
					{
						((System.IDisposable)val3)?.Dispose();
					}
					Chunk((Stream)(object)val, "IDAT", val2.ToArray());
					Chunk((Stream)(object)val, "IEND", System.Array.Empty<byte>());
					return val.ToArray();
				}
				finally
				{
					((System.IDisposable)val2)?.Dispose();
				}
			}
			finally
			{
				((System.IDisposable)val)?.Dispose();
			}
		}

		private static void Chunk(Stream stream, string name, byte[] data)
		{
			System.Span<byte> span = stackalloc byte[4];
			BinaryPrimitives.WriteInt32BigEndian(span, data.Length);
			stream.Write(System.Span<byte>.op_Implicit(span));
			byte[] bytes = Encoding.ASCII.GetBytes(name);
			stream.Write(System.ReadOnlySpan<byte>.op_Implicit(bytes));
			stream.Write(System.ReadOnlySpan<byte>.op_Implicit(data));
			uint num = 4294967295u;
			byte[] array = bytes;
			foreach (byte value in array)
			{
				num = ByteCrc(num, value);
			}
			array = data;
			foreach (byte value2 in array)
			{
				num = ByteCrc(num, value2);
			}
			BinaryPrimitives.WriteUInt32BigEndian(span, ~num);
			stream.Write(System.Span<byte>.op_Implicit(span));
		}

		private static uint ByteCrc(uint crc, byte value)
		{
			crc ^= value;
			for (int i = 0; i < 8; i++)
			{
				crc = (crc >> 1) ^ (uint)(((crc & 1) != 0) ? (-306674912) : 0);
			}
			return crc;
		}
	}
	internal static class NativeInputBarrier
	{
		private static IDetour _detour;

		private static NativeInputDispatch _dispatch;

		internal unsafe static void Install()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_00a6: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			if (_detour != null)
			{
				throw new InvalidOperationException("Input barrier already prepared");
			}
			if ((int)RuntimeInformation.ProcessArchitecture != 1)
			{
				throw new PlatformNotSupportedException("Requires Windows x64 input ABI");
			}
			MethodInfo method = typeof(InputManager).GetMethod("ProcessEventOnInputReceiver");
			if (method == (MethodInfo)null || ((MethodBase)method).IsStatic || ((MethodBase)method).GetParameters().Length != 6)
			{
				throw new MissingMethodException("Unexpected native input signature");
			}
			Patches patchInfo = Harmony.GetPatchInfo((MethodBase)(object)method);
			if (patchInfo != null && patchInfo.Owners.Count > 0)
			{
				throw new InvalidOperationException("Input dispatch already patched by another owner");
			}
			System.IntPtr intPtr = IL2CPP.il2cpp_class_get_method_from_name(Il2CppClassPointerStore<InputManager>.NativeClassPtr, "ProcessEventOnInputReceiver", 6);
			if (intPtr == System.IntPtr.Zero)
			{
				throw new MissingMethodException("Native input dispatch missing");
			}
			INativeMethodInfoStruct val = UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)intPtr);
			if (val.ParametersCount != 6 || val.MethodPointer == System.IntPtr.Zero)
			{
				throw new MissingMethodException("Unexpected native dispatch metadata");
			}
			_dispatch = new NativeInputDispatch(CounterBehaviour.AllowNativeDispatch, CounterBehaviour.InputBarrierFailed);
			try
			{
				_detour = Il2CppInteropRuntime.Instance.DetourProvider.Create<NativeDispatchCall>(val.MethodPointer, _dispatch.Callback);
				_dispatch.Attach(_detour.GenerateTrampoline<NativeDispatchCall>());
				_detour.Apply();
				_dispatch.Enable();
			}
			catch
			{
				_dispatch.Disable();
				throw;
			}
		}
	}
	[UnmanagedFunctionPointer(/*Could not decode attribute arguments.*/)]
	public delegate void NativeDispatchCall(System.IntPtr owner, System.IntPtr pair, System.IntPtr inputEvent, System.IntPtr consumed, System.IntPtr modifiers, System.IntPtr mouse, System.IntPtr delta, System.IntPtr method);
	public sealed class NativeInputDispatch
	{
		private readonly Func<bool> _allowed;

		private readonly Action<System.Exception> _fault;

		private NativeDispatchCall _original;

		private bool _enabled;

		private bool _failed;

		public readonly NativeDispatchCall Callback;

		public NativeInputDispatch(Func<bool> allowed, Action<System.Exception> fault = null)
		{
			_allowed = allowed;
			_fault = fault;
			Callback = Invoke;
		}

		public void Attach(NativeDispatchCall original)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			_original = original ?? throw new ArgumentNullException("original");
		}

		public void Enable()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (_original == null)
			{
				throw new InvalidOperationException("Original dispatch is not ready");
			}
			_enabled = true;
		}

		public void Disable()
		{
			_enabled = false;
		}

		private void Invoke(System.IntPtr owner, System.IntPtr pair, System.IntPtr inputEvent, System.IntPtr consumed, System.IntPtr modifiers, System.IntPtr mouse, System.IntPtr delta, System.IntPtr method)
		{
			NativeDispatchCall original = _original;
			if (original == null)
			{
				return;
			}
			bool flag = true;
			if (_enabled && !_failed)
			{
				try
				{
					flag = _allowed?.Invoke() ?? true;
				}
				catch (System.Exception ex)
				{
					_failed = true;
					try
					{
						_fault?.Invoke(ex);
					}
					catch
					{
					}
				}
			}
			if (!flag)
			{
				if (consumed != System.IntPtr.Zero)
				{
					Marshal.WriteByte(consumed, (byte)1);
				}
			}
			else
			{
				original(owner, pair, inputEvent, consumed, modifiers, mouse, delta, method);
			}
		}
	}
	[BepInPlugin("skyfrozen.infalsus.judgementcounter", "In Falsus Judgement Counter", "1.0.1")]
	public sealed class Plugin : BasePlugin
	{
		internal static ManualLogSource Logger;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> Horizontal;

		internal static ConfigEntry<bool> BreakOnRight;

		internal static ConfigEntry<bool> HideOnScreenshot;

		internal static ConfigEntry<bool> HideWhenPaused;

		internal static ConfigEntry<float> Scale;

		internal static ConfigEntry<float> PositionX;

		internal static ConfigEntry<float> PositionY;

		internal static ConfigEntry<float> WidthScale;

		internal static ConfigEntry<float> HeightScale;

		internal static ConfigEntry<string> PanelKey;

		internal static ConfigEntry<string> VisibilityKey;

		internal static bool InputBlockReady;

		private static ConfigFile _settings;

		internal static CounterOptions Options
		{
			get
			{
				CounterOptions result = new CounterOptions(Enabled.Value, Horizontal.Value, PositionX.Value, PositionY.Value, Scale.Value, HideWhenPaused.Value, HideOnScreenshot.Value);
				result.BreakOnRight = BreakOnRight.Value;
				result.WidthScale = WidthScale.Value;
				result.HeightScale = HeightScale.Value;
				return result;
			}
		}

		internal static void Apply(CounterOptions value)
		{
			CounterOptions counterOptions = value.Normalize();
			Enabled.Value = counterOptions.Enabled;
			Horizontal.Value = counterOptions.Horizontal;
			BreakOnRight.Value = counterOptions.BreakOnRight;
			PositionX.Value = counterOptions.X;
			PositionY.Value = counterOptions.Y;
			Scale.Value = counterOptions.Scale;
			WidthScale.Value = counterOptions.WidthScale;
			HeightScale.Value = counterOptions.HeightScale;
			HideWhenPaused.Value = counterOptions.HideWhenPaused;
			HideOnScreenshot.Value = counterOptions.HideOnScreenshot;
		}

		internal static void Save()
		{
			_settings.Save();
		}

		internal static bool SaveBindings(CounterChord[] bindings)
		{
			string value = PanelKey.Value;
			string value2 = VisibilityKey.Value;
			try
			{
				PanelKey.Value = bindings[0].Text;
				VisibilityKey.Value = bindings[1].Text;
				_settings.Save();
				return true;
			}
			catch (System.Exception ex)
			{
				PanelKey.Value = value;
				VisibilityKey.Value = value2;
				Logger.LogWarning((object)("Shortcut save failed: " + ex.Message));
				return false;
			}
		}

		public override void Load()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Expected O, but got Unknown
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Expected O, but got Unknown
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Expected O, but got Unknown
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Expected O, but got Unknown
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Expected O, but got Unknown
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missin