Decompiled source of TootTallyURCounter v1.0.1

plugins/TootTallyURCounter.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BaboonAPI.Hooks.Initializer;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using TootTallyCore;
using TootTallyCore.Graphics;
using TootTallyCore.Utils.TootTallyGlobals;
using TootTallyCore.Utils.TootTallyModules;
using TootTallySettings;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TootTallyURCounter")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("UR Counter for TootTally")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("TootTallyURCounter")]
[assembly: AssemblyTitle("TootTallyURCounter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TootTallyURCounter
{
	[BepInPlugin("TootTallyURCounter", "TootTallyURCounter", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin, ITootTallyModule
	{
		public static Plugin Instance;

		private const string CONFIG_NAME = "TootTallyURCounter.cfg";

		private Harmony _harmony;

		public static TootTallySettingPage settingPage;

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

		public bool IsConfigInitialized { get; set; }

		public string Name
		{
			get
			{
				return "TootTallyURCounter";
			}
			set
			{
				Name = value;
			}
		}

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

		public static void LogInfo(string msg)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)msg);
		}

		public static void LogError(string msg)
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)msg);
		}

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				Instance = this;
				_harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				GameInitializationEvent.Register(((BaseUnityPlugin)this).Info, (Action)TryInitialize);
			}
		}

		private void TryInitialize()
		{
			ModuleConfigEnabled = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Modules", "URCounter", true, "Add URCounter to help with tap timing.");
			TootTallyModuleManager.AddModule((ITootTallyModule)(object)this);
		}

		public void LoadModule()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Paths.BepInExRootPath, "config/");
			ConfigFile val = new ConfigFile(text + "TootTallyURCounter.cfg", true)
			{
				SaveOnConfigSet = true
			};
			TimingWindow = val.Bind<float>("General", "TimingWindow", 200f, (ConfigDescription)null);
			settingPage = TootTallySettingsManager.AddNewPage("URCounter", "URCounter", 40f, new Color(0f, 0f, 0f, 0f));
			settingPage.AddSlider("Timing Window (ms)", 20f, 1000f, TimingWindow, true);
			Plugin.TryAddThunderstoreIconToPageButton(((BaseUnityPlugin)Instance).Info.Location, Name, settingPage);
			_harmony.PatchAll(typeof(URCounterManager));
			LogInfo("Module loaded!");
		}

		public void UnloadModule()
		{
			_harmony.UnpatchSelf();
			settingPage.Remove();
			LogInfo("Module unloaded!");
		}
	}
	public class URCounterGraphicController
	{
		private GameObject _urBar;

		private GameObject _urBarDataPrefab;

		private LineRenderer[] _urBarDataArray;

		private double[] _urBarAlphaMultArray;

		private LineRenderer _urAveragePointerLineRenderer;

		private int _currentIndex;

		private readonly Color _colorToFadeout;

		private readonly Color _startColor;

		private const int TIMING_LINE_COUNT = 25;

		public URCounterGraphicController(Transform canvas, Material material)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			_urBarDataArray = (LineRenderer[])(object)new LineRenderer[25];
			_urBarAlphaMultArray = new double[25];
			_urBarDataPrefab = new GameObject("DataBarPrefab", new Type[2]
			{
				typeof(RectTransform),
				typeof(LineRenderer)
			});
			LineRenderer component = _urBarDataPrefab.GetComponent<LineRenderer>();
			((Renderer)component).material = material;
			component.numCapVertices = 5;
			component.useWorldSpace = false;
			RectTransform component2 = _urBarDataPrefab.GetComponent<RectTransform>();
			component2.anchoredPosition = Vector2.zero;
			component2.anchorMin = (component2.anchorMax = Vector2.one / 2f);
			_colorToFadeout = new Color(0f, 0f, 0f, 0.005f);
			_startColor = new Color(1f, 1f, 1f, 0.5f);
			_currentIndex = 0;
			CreateURBar(canvas);
			SetTimingBarPrefab();
			CreateTimingBars();
		}

		public void UpdateTimingBarAlpha()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (_urBarDataArray == null || _urBarAlphaMultArray == null)
			{
				return;
			}
			for (int i = 0; i < _urBarDataArray.Length; i++)
			{
				if (!((Object)(object)_urBarDataArray[i] == (Object)null))
				{
					_urBarAlphaMultArray[i] += Time.deltaTime / 10f;
					LineRenderer obj = _urBarDataArray[i];
					LineRenderer obj2 = _urBarDataArray[i];
					Color startColor = (obj2.endColor -= (float)_urBarAlphaMultArray[i] * _colorToFadeout);
					obj.startColor = startColor;
				}
			}
		}

		private void CreateURBar(Transform canvas)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: 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_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			_urBar = Object.Instantiate<GameObject>(_urBarDataPrefab, canvas);
			RectTransform component = _urBar.GetComponent<RectTransform>();
			component.anchoredPosition = Vector2.zero;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, -0.155f);
			component.anchorMax = val;
			component.anchorMin = val;
			LineRenderer component2 = _urBar.GetComponent<LineRenderer>();
			component2.widthMultiplier = 0.12f;
			component2.positionCount = 7;
			Gradient val2 = new Gradient();
			val2.colorKeys = (GradientColorKey[])(object)new GradientColorKey[6]
			{
				new GradientColorKey(new Color(1f, 1f, 0f), 0f),
				new GradientColorKey(new Color(0f, 1f, 0f), 0.2f),
				new GradientColorKey(new Color(0f, 0.25f, 1f), 0.45f),
				new GradientColorKey(new Color(0f, 0.25f, 1f), 0.55f),
				new GradientColorKey(new Color(0f, 1f, 0f), 0.8f),
				new GradientColorKey(new Color(1f, 1f, 0f), 1f)
			};
			val2.mode = (GradientMode)0;
			component2.colorGradient = val2;
			component2.SetPositions((Vector3[])(object)new Vector3[7]
			{
				Vector2.op_Implicit(new Vector2(-125f, 0f)),
				Vector2.op_Implicit(new Vector2(-100f, 0f)),
				Vector2.op_Implicit(new Vector2(-56f, 0f)),
				Vector2.op_Implicit(new Vector2(0f, 0f)),
				Vector2.op_Implicit(new Vector2(56f, 0f)),
				Vector2.op_Implicit(new Vector2(100f, 0f)),
				Vector2.op_Implicit(new Vector2(125f, 0f))
			});
			GameObject val3 = Object.Instantiate<GameObject>(_urBarDataPrefab, _urBar.transform);
			LineRenderer component3 = val3.GetComponent<LineRenderer>();
			component3.widthMultiplier = 0.05f;
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(1f, 1f, 1f, 0.8f);
			component3.endColor = val4;
			component3.startColor = val4;
			component3.SetPositions((Vector3[])(object)new Vector3[2]
			{
				Vector2.op_Implicit(new Vector2(0f, -7f)),
				Vector2.op_Implicit(new Vector2(0f, 7f))
			});
			_urAveragePointerLineRenderer = Object.Instantiate<GameObject>(_urBarDataPrefab, _urBar.transform).GetComponent<LineRenderer>();
			_urAveragePointerLineRenderer.numCapVertices = 2;
			_urAveragePointerLineRenderer.numCornerVertices = 2;
			_urAveragePointerLineRenderer.widthMultiplier = 0.12f;
			LineRenderer urAveragePointerLineRenderer = _urAveragePointerLineRenderer;
			LineRenderer urAveragePointerLineRenderer2 = _urAveragePointerLineRenderer;
			((Color)(ref val4))..ctor(1f, 1f, 1f, 1f);
			urAveragePointerLineRenderer2.endColor = val4;
			urAveragePointerLineRenderer.startColor = val4;
			_urAveragePointerLineRenderer.endWidth = 0f;
			_urAveragePointerLineRenderer.SetPositions((Vector3[])(object)new Vector3[2]
			{
				Vector2.op_Implicit(new Vector2(0f, 10f)),
				Vector2.op_Implicit(new Vector2(0f, 7f))
			});
		}

		private void SetTimingBarPrefab()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			LineRenderer component = _urBarDataPrefab.GetComponent<LineRenderer>();
			component.widthMultiplier = 0.05f;
			Color startColor2 = (component.endColor = _startColor);
			component.startColor = startColor2;
			((Renderer)_urBarDataPrefab.GetComponent<LineRenderer>()).enabled = false;
		}

		public void AddTiming(float tapTiming)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_urBarDataPrefab == (Object)null) && _urBarDataArray != null && !((Object)(object)_urBar == (Object)null))
			{
				_urBarAlphaMultArray[_currentIndex] = 0.0;
				LineRenderer val = _urBarDataArray[_currentIndex++];
				((Renderer)val).enabled = true;
				Color startColor2 = (val.endColor = _startColor);
				val.startColor = startColor2;
				float num = TimingToPosX(tapTiming);
				val.SetPositions((Vector3[])(object)new Vector3[2]
				{
					Vector2.op_Implicit(new Vector2(num, -5f)),
					Vector2.op_Implicit(new Vector2(num, 5f))
				});
				if (_currentIndex >= _urBarDataArray.Length)
				{
					_currentIndex = 0;
				}
			}
		}

		public void SetAveragePosition(float averageTiming)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_urAveragePointerLineRenderer == (Object)null))
			{
				float num = TimingToPosX(averageTiming);
				_urAveragePointerLineRenderer.SetPositions((Vector3[])(object)new Vector3[2]
				{
					Vector2.op_Implicit(new Vector2(num, 10f)),
					Vector2.op_Implicit(new Vector2(num, 7f))
				});
			}
		}

		public void CreateTimingBars()
		{
			for (int i = 0; i < _urBarDataArray.Length; i++)
			{
				_urBarDataArray[i] = Object.Instantiate<GameObject>(_urBarDataPrefab, _urBar.transform).GetComponent<LineRenderer>();
				_urBarAlphaMultArray[i] = 0.0;
			}
		}

		public float TimingToPosX(float timing)
		{
			return timing / URCounterManager.AdjustedTimingWindow * 120f;
		}
	}
	public static class URCounterManager
	{
		private static bool _lastIsTooting;

		private static bool _isSlider;

		private static bool _isStarted;

		private static float _trackTime;

		private static float _lastTiming;

		private static float _nextTiming;

		private static int _lastIndex;

		private static float _savedLatency;

		private static bool _lastReleasedToot;

		private static bool _releasedToot;

		private static int _timingCount;

		private static float _timingSum;

		private static float _averageTiming;

		private static List<float> _noteTimingList;

		private static List<float> _tapTimingList;

		private static URCounterGraphicController _graphicController;

		public static float AdjustedTimingWindow { get; private set; }

		[HarmonyPatch(typeof(GameController), "Start")]
		[HarmonyPostfix]
		public static void OnGameControllerStart(GameController __instance)
		{
			AdjustedTimingWindow = Plugin.Instance.TimingWindow.Value / 1000f / TootTallyGlobalVariables.gameSpeedMultiplier;
			_isSlider = false;
			_isStarted = false;
			_lastIsTooting = false;
			_lastIndex = -1;
			_savedLatency = __instance.latency_offset;
			_trackTime = 0f - __instance.noteoffset - __instance.latency_offset;
			_nextTiming = ((__instance.leveldata.Count > 0) ? B2s(__instance.leveldata[0][0], __instance.tempo) : 0f);
			_noteTimingList = new List<float>();
			_tapTimingList = new List<float>();
			_noteTimingList.Add(_nextTiming);
			_graphicController = new URCounterGraphicController(__instance.pointer.transform.parent, ((Renderer)((Component)__instance.singlenote.transform.GetChild(3)).GetComponent<LineRenderer>()).material);
		}

		[HarmonyPatch(typeof(GameController), "Update")]
		[HarmonyPostfix]
		public static void UpdateTrackTimer(GameController __instance)
		{
			if (_isStarted && !__instance.paused && !__instance.quitting && !__instance.retrying && _graphicController != null)
			{
				_trackTime += Time.deltaTime * TootTallyGlobalVariables.gameSpeedMultiplier;
				_graphicController.UpdateTimingBarAlpha();
			}
		}

		[HarmonyPatch(typeof(GameController), "isNoteButtonPressed")]
		[HarmonyPostfix]
		public static void OnButtonPressedRegisterTapTiming(GameController __instance, bool __result)
		{
			if (!_lastIsTooting && __result && ShouldRecordTap())
			{
				RecordTapTiming(__instance);
			}
			_lastIsTooting = __result;
		}

		[HarmonyPatch(typeof(GameController), "playsong")]
		[HarmonyPostfix]
		public static void OnPlaySong()
		{
			_isStarted = true;
		}

		public static bool ShouldRecordTap()
		{
			return _noteTimingList.Count > _tapTimingList.Count;
		}

		public static void RecordTapTiming(GameController __instance)
		{
			float num;
			if (_noteTimingList.Count - 2 == _tapTimingList.Count)
			{
				num = Mathf.Clamp(0f - (_lastTiming - _trackTime), 0f - AdjustedTimingWindow, AdjustedTimingWindow);
				OnTapRecord(num / TootTallyGlobalVariables.gameSpeedMultiplier);
			}
			num = 0f - (_nextTiming - _trackTime);
			if (num == 0f)
			{
				OnTapRecord(0f);
			}
			else if (Mathf.Abs(num) <= AdjustedTimingWindow)
			{
				OnTapRecord(num / TootTallyGlobalVariables.gameSpeedMultiplier);
			}
		}

		public static void OnTapRecord(float tapTiming)
		{
			_tapTimingList.Add(tapTiming);
			_timingSum += tapTiming;
			_timingCount++;
			_averageTiming = _timingSum / (float)_timingCount;
			if (_graphicController != null)
			{
				_graphicController.AddTiming(tapTiming);
				_graphicController.SetAveragePosition(_averageTiming);
			}
		}

		[HarmonyPatch(typeof(GameController), "syncTrackPositions")]
		[HarmonyPostfix]
		public static void OnSyncTrack(GameController __instance)
		{
			_trackTime = (float)__instance.musictrack.timeSamples / (float)__instance.musictrack.clip.frequency - __instance.noteoffset - __instance.latency_offset;
		}

		public static float B2s(float time, float bpm)
		{
			return time / bpm * 60f;
		}

		[HarmonyPatch(typeof(GameController), "getScoreAverage")]
		[HarmonyPrefix]
		public static void GetNoteScore(GameController __instance)
		{
			_lastReleasedToot = _releasedToot;
			_releasedToot = __instance.released_button_between_notes && !__instance.force_no_gap_gameobject_to_appear;
		}

		[HarmonyPatch(typeof(GameController), "grabNoteRefs")]
		[HarmonyPrefix]
		public static void GetIsSlider(GameController __instance)
		{
			if (__instance.currentnoteindex + 1 >= __instance.leveldata.Count)
			{
				return;
			}
			if (!_isStarted)
			{
				_noteTimingList = new List<float>();
				_tapTimingList = new List<float>();
			}
			_isSlider = Mathf.Abs(__instance.leveldata[__instance.currentnoteindex + 1][0] - (__instance.leveldata[__instance.currentnoteindex][0] + __instance.leveldata[__instance.currentnoteindex][1])) < 0.05f;
			if (_isSlider)
			{
				return;
			}
			if (_noteTimingList.Count - 2 >= _tapTimingList.Count)
			{
				if (!_lastReleasedToot)
				{
					OnTapRecord(0f - AdjustedTimingWindow);
				}
				else
				{
					OnTapRecord(AdjustedTimingWindow);
				}
			}
			_lastTiming = _nextTiming;
			_nextTiming = B2s(__instance.leveldata[__instance.currentnoteindex + 1][0], __instance.tempo);
			_noteTimingList.Add(_nextTiming);
		}

		[HarmonyPatch(typeof(PointSceneController), "Start")]
		[HarmonyPostfix]
		public static void GetNoteScore(PointSceneController __instance)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (_tapTimingList.Count > 1)
			{
				double standardDeviation = GetStandardDeviation(_tapTimingList);
				TMP_Text val = GameObjectFactory.CreateSingleText(__instance.fullpanel.transform, "URLabel", GetURStringText(standardDeviation), (TextFont)0);
				val.rectTransform.anchoredPosition = new Vector2(0f, 417f);
				val.fontSize = 8f;
				val.fontStyle = (FontStyles)1;
				((Graphic)val).color = new Color(0.1294f, 0.2549f, 0.2549f, 1f);
				val.outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0f));
			}
		}

		private static string GetURStringText(double sd)
		{
			return $"UR: {sd * 1000.0:0.0}ms - MN: {_averageTiming * 1000f:0.0}ms - Timing Deviation: {((double)_averageTiming - sd) * 1000.0:0.0}ms ~ {((double)_averageTiming + sd) * 1000.0:0.0}ms";
		}

		private static string GetString()
		{
			return $"Average: {_averageTiming * 1000f:0.0}ms";
		}

		private static string GetString2()
		{
			return "Average:" + (_averageTiming * 1000f).ToString("0.0") + "ms";
		}

		public static double GetStandardDeviation(List<float> values)
		{
			return Mathf.Sqrt(values.Average((float value) => FastPow(value - _averageTiming, 2)));
		}

		public static float FastPow(double num, int exp)
		{
			double num2 = 1.0;
			while (exp > 0)
			{
				if (exp % 2 == 1)
				{
					num2 *= num;
				}
				exp >>= 1;
				num *= num;
			}
			return (float)num2;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TootTallyURCounter";

		public const string PLUGIN_NAME = "TootTallyURCounter";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}