Decompiled source of GameTweaks v2.1.0

plugins/TootTally.GameTweaks.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TootTally.Graphics;
using TootTally.Replays;
using TootTally.Spectating;
using TootTally.Utils;
using TootTally.Utils.TootTallySettings;
using TrombLoader;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TootTally.GameTweaks
{
	public class NoteStructure
	{
		public GameObject root;

		public GameObject noteStart;

		public GameObject noteEnd;

		public NoteDesigner noteDesigner;

		public RectTransform noteRect;

		public RectTransform noteEndRect;

		public LineRenderer[] lineRenderers;

		public NoteStructure(GameObject root)
		{
			root.SetActive(true);
			this.root = root;
			noteDesigner = root.GetComponent<NoteDesigner>();
			noteRect = root.GetComponent<RectTransform>();
			noteStart = ((Component)root.transform.GetChild(0)).gameObject;
			noteEnd = ((Component)root.transform.GetChild(1)).gameObject;
			noteEndRect = noteEnd.GetComponent<RectTransform>();
			lineRenderers = (LineRenderer[])(object)new LineRenderer[2]
			{
				((Component)root.transform.GetChild(2)).GetComponent<LineRenderer>(),
				((Component)root.transform.GetChild(3)).GetComponent<LineRenderer>()
			};
		}

		public void CancelLeanTweens()
		{
			LeanTween.cancel(root);
		}

		public void SetColorScheme(float[] start, float[] end, bool flipScheme)
		{
			if (flipScheme)
			{
				float[] array = start;
				start = end;
				end = array;
			}
			noteDesigner.setColorScheme(start[0], start[1], start[2], end[0], end[1], end[2]);
		}
	}
	[BepInPlugin("TootTally.GameTweaks", "TootTally.GameTweaks", "2.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin, ITootTallyModule
	{
		public static class GameTweaks
		{
			public static bool _hasSyncedOnce;

			private static NoteStructure[] _noteArray;

			private static Queue<Coroutine> _currentCoroutines;

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void FixChampMeterSize(GameController __instance)
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: 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)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				if (Instance.option.ChampMeterSize.Value != 1f)
				{
					__instance.champcontroller.letters[0].transform.parent.localScale = Vector2.op_Implicit(Vector2.one * 0.29f * Instance.option.ChampMeterSize.Value);
					__instance.healthmask.transform.parent.SetParent(__instance.champcontroller.letters[0].transform.parent, true);
					__instance.healthmask.transform.parent.localScale = Vector2.op_Implicit(Vector2.one * Instance.option.ChampMeterSize.Value);
				}
			}

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void TouchScreenPatch(GameController __instance)
			{
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: 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_00be: Unknown result type (might be due to invalid IL or missing references)
				if (Instance.option.TouchScreenMode.Value)
				{
					GameObject gameObject = GameObject.Find("GameplayCanvas").gameObject;
					((Behaviour)gameObject.GetComponent<GraphicRaycaster>()).enabled = true;
					((Component)gameObject.transform.Find("GameSpace")).transform.localScale = Vector2.op_Implicit(new Vector2(1f, -1f));
					CustomButton val = GameObjectFactory.CreateCustomButton(gameObject.transform, Vector2.zero, new Vector2(32f, 32f), AssetManager.GetSprite("Block64.png"), "PauseButton", (Action)delegate
					{
						OnPauseButtonPress(__instance);
					});
					((Component)val).transform.position = new Vector3(-7.95f, 4.75f, 1f);
				}
			}

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void HideTromboner(GameController __instance)
			{
				if (Instance.option.HideTromboner.Value)
				{
					__instance.puppet_human.SetActive(false);
				}
			}

			[HarmonyPatch(typeof(GameController), "buildNotes")]
			[HarmonyPrefix]
			public static void OverwriteNoteSpacing(GameController __instance)
			{
				if (Instance.option.OverwriteNoteSpacing.Value && int.TryParse(Instance.option.NoteSpacing.Value, out var result) && result > 0)
				{
					__instance.defaultnotelength = (int)(100f / (__instance.tempo * ReplaySystemManager.gameSpeedMultiplier) * (float)result * GlobalVariables.gamescrollspeed);
				}
			}

			[HarmonyPatch(typeof(MuteBtn), "Start")]
			[HarmonyPostfix]
			public static void SetMuteButtonAlphaOnStart(MuteBtn __instance)
			{
				__instance.cg.alpha = Instance.option.MuteButtonTransparency.Value;
			}

			[HarmonyPatch(typeof(MuteBtn), "hoverOut")]
			[HarmonyPostfix]
			public static void UnMuteButtonHoverOut(MuteBtn __instance)
			{
				__instance.cg.alpha = Instance.option.MuteButtonTransparency.Value;
			}

			private static void OnPauseButtonPress(GameController __instance)
			{
				if (!__instance.quitting && __instance.musictrack.time > 0.5f && !__instance.level_finished && __instance.pausecontroller.done_animating && !__instance.freeplay)
				{
					__instance.notebuttonpressed = false;
					__instance.musictrack.Pause();
					__instance.sfxrefs.backfromfreeplay.Play();
					__instance.puppet_humanc.shaking = false;
					__instance.puppet_humanc.stopParticleEffects();
					__instance.puppet_humanc.playCameraRotationTween(false);
					__instance.paused = true;
					__instance.quitting = true;
					__instance.pausecanvas.SetActive(true);
					__instance.pausecontroller.showPausePanel();
					Cursor.visible = true;
				}
			}

			[HarmonyPatch(typeof(GameController), "startSong")]
			[HarmonyPostfix]
			public static void ResetSyncFlag()
			{
				_hasSyncedOnce = false;
			}

			[HarmonyPatch(typeof(GameController), "syncTrackPositions")]
			[HarmonyPrefix]
			public static bool SyncOnlyOnce()
			{
				if (Input.GetKey((KeyCode)32))
				{
					return true;
				}
				if (Instance.option.SyncDuringSong.Value)
				{
					return true;
				}
				if (ReplaySystemManager.wasPlayingReplay)
				{
					return true;
				}
				if (SpectatingManager.IsSpectating)
				{
					return true;
				}
				bool hasSyncedOnce = _hasSyncedOnce;
				_hasSyncedOnce = true;
				return !hasSyncedOnce;
			}

			[HarmonyPatch(typeof(LevelSelectController), "Update")]
			[HarmonyPostfix]
			public static void DetectKeyPressInLevelSelectController(LevelSelectController __instance)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (Input.GetKeyDown(Instance.option.RandomizeKey.Value) && !__instance.randomizing)
				{
					__instance.clickRandomTrack();
				}
			}

			[HarmonyPatch(typeof(CardSceneController), "showMultiPurchaseCanvas")]
			[HarmonyPostfix]
			public static void OverwriteMaximumOpeningCard(CardSceneController __instance)
			{
				if (Instance.option.SkipCardAnimation.Value)
				{
					__instance.multipurchase_maxpacks = (int)Mathf.Clamp((float)__instance.currency_toots / 499f, 1f, 999f);
				}
			}

			[HarmonyPatch(typeof(CardSceneController), "clickedContinue")]
			[HarmonyPrefix]
			public static bool OverwriteOpeningCardAnimation(CardSceneController __instance)
			{
				if (!Instance.option.SkipCardAnimation.Value)
				{
					return true;
				}
				__instance.moveAwayOpenedCards();
				return __instance.multipurchase_opened_sacks >= __instance.multipurchase_chosenpacks;
			}

			[HarmonyPatch(typeof(GameController), "buildAllLyrics")]
			[HarmonyPrefix]
			public static bool OverwriteBuildAllLyrics()
			{
				return !Instance.option.RemoveLyrics.Value;
			}

			[HarmonyPatch(typeof(GameController), "buildNotes")]
			[HarmonyPrefix]
			public static bool OverwriteBuildNotes(GameController __instance)
			{
				if (!Instance.option.OptimizeGame.Value || ReplaySystemManager.wasPlayingReplay)
				{
					return true;
				}
				BuildNoteArray(__instance, Plugin.Instance.beatsToShow.Value);
				BuildNotes(__instance);
				return false;
			}

			[HarmonyPatch(typeof(GameController), "animateOutNote")]
			[HarmonyPostfix]
			public static void OnGrabNoteRefsInstantiateNote(GameController __instance)
			{
				if (Instance.option.OptimizeGame.Value && !ReplaySystemManager.wasPlayingReplay && __instance.beatstoshow < __instance.leveldata.Count)
				{
					_currentCoroutines.Enqueue(((MonoBehaviour)Instance).StartCoroutine((IEnumerator)WaitForSecondsCallback(0.1f, delegate
					{
						_currentCoroutines.Dequeue();
						BuildSingleNote(__instance, __instance.beatstoshow);
					})));
				}
			}

			public static IEnumerator<WaitForSeconds> WaitForSecondsCallback(float seconds, Action callback)
			{
				yield return new WaitForSeconds(seconds);
				callback();
			}

			[HarmonyPatch(typeof(PointSceneController), "Start")]
			[HarmonyPostfix]
			public static void StopAllNoteCoroutine()
			{
				Coroutine result;
				while (_currentCoroutines.TryDequeue(out result))
				{
					((MonoBehaviour)Instance).StopCoroutine(result);
				}
			}

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void OnGameControllerStartInitRoutineQueue()
			{
				_currentCoroutines = new Queue<Coroutine>();
			}

			[HarmonyPatch(typeof(GameController), "activateNextNote")]
			[HarmonyPrefix]
			public static bool RemoveActivateNextNote()
			{
				if (Instance.option.OptimizeGame.Value)
				{
					return ReplaySystemManager.wasPlayingReplay;
				}
				return true;
			}

			private static void BuildNotes(GameController __instance)
			{
				__instance.beatstoshow = 0;
				for (int i = 0; i < _noteArray.Length; i++)
				{
					if (__instance.beatstoshow >= __instance.leveldata.Count)
					{
						break;
					}
					BuildSingleNote(__instance, i);
				}
			}

			private static void BuildNoteArray(GameController __instance, int size)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				_noteArray = new NoteStructure[size];
				for (int i = 0; i < size; i++)
				{
					_noteArray[i] = new NoteStructure(Object.Instantiate<GameObject>(__instance.singlenote, new Vector3(0f, 0f, 0f), Quaternion.identity, __instance.noteholder.transform));
				}
			}

			private static void BuildSingleNote(GameController __instance, int index)
			{
				//IL_00d0: 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_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_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0231: Unknown result type (might be due to invalid IL or missing references)
				//IL_0238: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_0366: Unknown result type (might be due to invalid IL or missing references)
				//IL_030c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0325: Unknown result type (might be due to invalid IL or missing references)
				//IL_039f: Unknown result type (might be due to invalid IL or missing references)
				if (index > __instance.leveldata.Count - 1)
				{
					return;
				}
				float[] array = new float[5] { 9999f, 9999f, 9999f, 0f, 9999f };
				if (index > 0)
				{
					array = __instance.leveldata[index - 1];
				}
				float[] array2 = __instance.leveldata[index];
				bool flag = Mathf.Abs(array[0] + array[1] - array2[0]) <= 0.02f;
				bool flag2 = array2[1] <= 0.0625f && __instance.tempo > 50f && array2[3] == 0f && !flag;
				if (array2[1] <= 0f)
				{
					array2[1] = 0.015f;
					__instance.leveldata[index][1] = 0.015f;
				}
				NoteStructure noteStructure = _noteArray[index % _noteArray.Length];
				noteStructure.CancelLeanTweens();
				noteStructure.root.transform.localScale = Vector3.one;
				__instance.allnotes.Add(noteStructure.root);
				__instance.flipscheme = flag && !__instance.flipscheme;
				noteStructure.SetColorScheme(__instance.note_c_start, __instance.note_c_end, __instance.flipscheme);
				((Behaviour)noteStructure.noteDesigner).enabled = false;
				if (index > 0)
				{
					((Component)__instance.allnotes[index - 1].transform.GetChild(1)).gameObject.SetActive(!flag || index - 1 >= __instance.leveldata.Count);
				}
				noteStructure.noteEnd.SetActive(!flag2);
				noteStructure.noteStart.SetActive(!flag);
				noteStructure.noteRect.anchoredPosition3D = new Vector3(array2[0] * (float)__instance.defaultnotelength, array2[2], 0f);
				((Transform)noteStructure.noteEndRect).localScale = (flag2 ? Vector2.op_Implicit(Vector2.zero) : Vector3.one);
				noteStructure.noteEndRect.anchoredPosition3D = new Vector3((float)__instance.defaultnotelength * array2[1] - (float)__instance.levelnotesize + 11.5f, array2[3], 0f);
				if (!flag2 && index >= Plugin.Instance.beatsToShow.Value)
				{
					RectTransform noteEndRect = noteStructure.noteEndRect;
					RectTransform noteEndRect2 = noteStructure.noteEndRect;
					Vector2 val = default(Vector2);
					((Vector2)(ref val))..ctor(1f, 0.5f);
					noteEndRect2.anchorMax = val;
					noteEndRect.anchorMin = val;
					noteStructure.noteEndRect.pivot = new Vector2(0.34f, 0.5f);
				}
				float[] item = new float[5]
				{
					array2[0] * (float)__instance.defaultnotelength,
					array2[0] * (float)__instance.defaultnotelength + (float)__instance.defaultnotelength * array2[1],
					array2[2],
					array2[3],
					array2[4]
				};
				__instance.allnotevals.Add(item);
				float num = (float)__instance.defaultnotelength * array2[1];
				float num2 = array2[3];
				LineRenderer[] lineRenderers = noteStructure.lineRenderers;
				foreach (LineRenderer val2 in lineRenderers)
				{
					((Component)val2).gameObject.SetActive(!flag2);
					if (flag2)
					{
						continue;
					}
					if (num2 == 0f)
					{
						val2.positionCount = 2;
						val2.SetPosition(0, new Vector3(-3f, 0f, 0f));
						val2.SetPosition(1, new Vector3(num, 0f, 0f));
						continue;
					}
					int num4 = (val2.positionCount = (int)Instance.option.SliderSamplePoints.Value);
					val2.SetPosition(0, new Vector3(-3f, 0f, 0f));
					for (int j = 1; j < num4; j++)
					{
						val2.SetPosition(j, new Vector3(num / (float)(num4 - 1) * (float)j, __instance.easeInOutVal((float)j, 0f, num2, (float)(num4 - 1)), 0f));
					}
				}
				__instance.beatstoshow++;
			}

			[HarmonyPatch(typeof(CharSelectController_new), "Start")]
			[HarmonyPrefix]
			public static void OnCharSelectStart()
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					GlobalVariables.chosen_character = Instance.option.CharacterID.Value;
					GlobalVariables.chosen_trombone = Instance.option.TromboneID.Value;
					GlobalVariables.chosen_soundset = Math.Min(Instance.option.SoundID.Value, 5);
					GlobalVariables.chosen_vibe = Instance.option.VibeID.Value;
					GlobalVariables.show_toot_rainbow = Instance.option.TootRainbow.Value;
					GlobalVariables.show_long_trombone = Instance.option.LongTrombone.Value;
				}
			}

			[HarmonyPatch(typeof(CharSelectController_new), "chooseChar")]
			[HarmonyPostfix]
			public static void OnCharSelect(int puppet_choice)
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					Instance.option.CharacterID.Value = puppet_choice;
				}
			}

			[HarmonyPatch(typeof(CharSelectController_new), "chooseTromb")]
			[HarmonyPostfix]
			public static void OnColorSelect(int tromb_choice)
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					Instance.option.TromboneID.Value = tromb_choice;
				}
			}

			[HarmonyPatch(typeof(CharSelectController_new), "chooseSoundPack")]
			[HarmonyPostfix]
			public static void OnSoundSelect(int sfx_choice)
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					Instance.option.SoundID.Value = sfx_choice;
				}
			}

			[HarmonyPatch(typeof(CharSelectController_new), "clickVibeButton")]
			[HarmonyPostfix]
			public static void OnTromboneSelect(int vibe_index)
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					Instance.option.VibeID.Value = vibe_index;
				}
			}

			[HarmonyPatch(typeof(CharSelectController_new), "clickExtraButton")]
			[HarmonyPostfix]
			public static void OnTogRainbowSelect()
			{
				if (Instance.option.RememberMyBoner.Value)
				{
					Instance.option.TootRainbow.Value = GlobalVariables.show_toot_rainbow;
					Instance.option.LongTrombone.Value = GlobalVariables.show_long_trombone;
				}
			}

			[HarmonyPatch(typeof(GameController), "buildNotes")]
			[HarmonyPrefix]
			public static void FixAudioLatency(GameController __instance)
			{
				if (Instance.option.AudioLatencyFix.Value)
				{
					if (GlobalVariables.practicemode != 1f)
					{
						__instance.latency_offset = (float)GlobalVariables.localsettings.latencyadjust * 0.001f * GlobalVariables.practicemode;
					}
					else if (GlobalVariables.turbomode)
					{
						__instance.latency_offset = (float)GlobalVariables.localsettings.latencyadjust * 0.002f;
					}
					else
					{
						__instance.latency_offset = (float)GlobalVariables.localsettings.latencyadjust * 0.001f * ReplaySystemManager.gameSpeedMultiplier;
					}
				}
			}

			[HarmonyPatch(typeof(ConfettiMaker), "startConfetti")]
			[HarmonyPrefix]
			public static bool RemoveAllConfetti()
			{
				return !Instance.option.RemoveConfetti.Value;
			}
		}

		public class Options
		{
			public ConfigEntry<float> ChampMeterSize { get; set; }

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

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

			public ConfigEntry<KeyCode> RandomizeKey { get; set; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static Plugin Instance;

		private const string CONFIG_NAME = "GameTweaks.cfg";

		public Options option;

		public static TootTallySettingPage settingPage;

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

		public bool IsConfigInitialized { get; set; }

		public string Name
		{
			get
			{
				return "TootTally.GameTweaks";
			}
			set
			{
				Name = value;
			}
		}

		public ManualLogSource GetLogger => ((BaseUnityPlugin)this).Logger;

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

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

		private void Awake()
		{
			if (!((Object)(object)Instance != (Object)null))
			{
				Instance = this;
				GameInitializationEvent.Register(((BaseUnityPlugin)this).Info, (Action)TryInitialize);
			}
		}

		private void TryInitialize()
		{
			ModuleConfigEnabled = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<bool>("Modules", "GameTweaks", true, "Game Tweaks with some quality of life changes.");
			Plugin.AddModule((ITootTallyModule)(object)this);
		}

		public void LoadModule()
		{
			//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_0029: Expected O, but got Unknown
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Paths.BepInExRootPath, "config/");
			ConfigFile val = new ConfigFile(text + "GameTweaks.cfg", true)
			{
				SaveOnConfigSet = true
			};
			option = new Options
			{
				ChampMeterSize = val.Bind<float>("General", "ChampMeterSize", 1f, "Resize the champ meter to make it less intrusive."),
				SyncDuringSong = val.Bind<bool>("General", "Sync During Song", false, "Allow the game to sync during a song, may cause lags but prevent desyncs."),
				HideTromboner = val.Bind<bool>("General", "Hide Tromboner", false, "Hide the Tromboner during gameplay."),
				RandomizeKey = val.Bind<KeyCode>("General", "RandomizeKey", (KeyCode)286, "Press that key to randomize."),
				MuteButtonTransparency = val.Bind<float>("General", "MuteBtnAlpha", 0.25f, "Change the transparency of the mute button."),
				TouchScreenMode = val.Bind<bool>("Misc", "TouchScreenMode", false, "Tweaks for touchscreen users."),
				OverwriteNoteSpacing = val.Bind<bool>("NoteSpacing", "OverwriteNoteSpacing", false, "Make the note spacing always the same."),
				NoteSpacing = val.Bind<string>("NoteSpacing", "NoteSpacing", 280.ToString(), "Note Spacing Value"),
				SkipCardAnimation = val.Bind<bool>("Misc", "SkipCardAnimation", true, "Skip the animation when opening cards."),
				RemoveLyrics = val.Bind<bool>("Misc", "RemoveLyrics", false, "Remove Lyrics from songs."),
				OptimizeGame = val.Bind<bool>("Misc", "OptimizeGame", false, "Instantiate and destroy notes as they enter and leave the screen."),
				SliderSamplePoints = val.Bind<float>("Misc", "SliderSamplePoints", 8f, "Increase or decrease the quality of slides."),
				RememberMyBoner = val.Bind<bool>("RMB", "RememberMyBoner", true, "Remembers the things you selected in the character selection screen."),
				TootRainbow = val.Bind<bool>("RMB", "TootRainbow", false, "Remembers the tootrainbow you selected."),
				LongTrombone = val.Bind<bool>("RMB", "LongTrombone", false, "Remembers the longtrombone you selected."),
				CharacterID = val.Bind<int>("RMB", "CharacterID", 0, "Remembers the character you selected."),
				TromboneID = val.Bind<int>("RMB", "TromboneID", 0, "Remembers the trombone you selected."),
				VibeID = val.Bind<int>("RMB", "VibeID", 0, "Remembers the vibe you selected."),
				SoundID = val.Bind<int>("RMB", "SoundID", 0, "Remembers the sound you selected."),
				AudioLatencyFix = val.Bind<bool>("Misc", "AudioLatencyFix", true, "Fix audio latency bug related when playing at different game speeds."),
				RemoveConfetti = val.Bind<bool>("Misc", "Remove Confetti", false, "Removes the confetti in the score screen.")
			};
			settingPage = TootTallySettingsManager.AddNewPage("GameTweaks", "Game Tweaks", 40f, new Color(0f, 0f, 0f, 0f));
			TootTallySettingPage obj = settingPage;
			if (obj != null)
			{
				obj.AddSlider("Champ Meter Size", 0f, 1f, option.ChampMeterSize, false);
			}
			TootTallySettingPage obj2 = settingPage;
			if (obj2 != null)
			{
				obj2.AddSlider("Mute Btn Alpha", 0f, 1f, option.MuteButtonTransparency, false);
			}
			TootTallySettingPage obj3 = settingPage;
			if (obj3 != null)
			{
				obj3.AddToggle("Hide Tromboner", option.HideTromboner, (UnityAction<bool>)null);
			}
			TootTallySettingPage obj4 = settingPage;
			if (obj4 != null)
			{
				obj4.AddToggle("Sync During Song", option.SyncDuringSong, (UnityAction<bool>)null);
			}
			TootTallySettingPage obj5 = settingPage;
			if (obj5 != null)
			{
				obj5.AddToggle("Touchscreen Mode", option.TouchScreenMode, (UnityAction<bool>)delegate(bool value)
				{
					GlobalVariables.localsettings.mousecontrolmode = ((!value) ? 1 : 0);
				});
			}
			TootTallySettingPage obj6 = settingPage;
			if (obj6 != null)
			{
				obj6.AddToggle("Skip Card Animation", option.SkipCardAnimation, (UnityAction<bool>)null);
			}
			TootTallySettingPage obj7 = settingPage;
			if (obj7 != null)
			{
				obj7.AddToggle("Overwrite Note Spacing", option.OverwriteNoteSpacing, (UnityAction<bool>)OnOverwriteNoteSpacingToggle);
			}
			TootTallySettingPage obj8 = settingPage;
			if (obj8 != null)
			{
				obj8.AddToggle("Remove Lyrics", option.RemoveLyrics, (UnityAction<bool>)null);
			}
			TootTallySettingPage obj9 = settingPage;
			if (obj9 != null)
			{
				obj9.AddToggle("Optimize Game", option.OptimizeGame, (UnityAction<bool>)OnOptimizeGameToggle);
			}
			OnOptimizeGameToggle(option.OptimizeGame.Value);
			TootTallySettingPage obj10 = settingPage;
			if (obj10 != null)
			{
				obj10.AddToggle("Remember My Boner", option.RememberMyBoner, (UnityAction<bool>)null);
			}
			OnOverwriteNoteSpacingToggle(option.OverwriteNoteSpacing.Value);
			TootTallySettingPage obj11 = settingPage;
			if (obj11 != null)
			{
				obj11.AddToggle("Fix Audio Latency", option.AudioLatencyFix, (UnityAction<bool>)null);
			}
			TootTallySettingPage obj12 = settingPage;
			if (obj12 != null)
			{
				obj12.AddToggle("Remove Confetti", option.RemoveConfetti, (UnityAction<bool>)null);
			}
			Harmony.CreateAndPatchAll(typeof(GameTweaks), "TootTally.GameTweaks");
			LogInfo("Module loaded!");
		}

		public void OnOptimizeGameToggle(bool value)
		{
			if (value)
			{
				TootTallySettingPage obj = settingPage;
				if (obj != null)
				{
					obj.AddSlider("SliderSamplePoints", 2f, 50f, option.SliderSamplePoints, true);
				}
			}
			else
			{
				TootTallySettingPage obj2 = settingPage;
				if (obj2 != null)
				{
					obj2.RemoveSettingObjectFromList("SliderSamplePoints");
				}
			}
		}

		public void OnOverwriteNoteSpacingToggle(bool value)
		{
			if (value)
			{
				TootTallySettingPage obj = settingPage;
				if (obj != null)
				{
					obj.AddTextField("NoteSpacing", option.NoteSpacing.Value, false, (Action<string>)OnNoteSpacingSubmit);
				}
			}
			else
			{
				TootTallySettingPage obj2 = settingPage;
				if (obj2 != null)
				{
					obj2.RemoveSettingObjectFromList("NoteSpacing");
				}
			}
		}

		public void OnNoteSpacingSubmit(string value)
		{
			if (int.TryParse(value, out var result) && result > 0)
			{
				option.NoteSpacing.Value = result.ToString();
			}
			else
			{
				PopUpNotifManager.DisplayNotif("Value has to be a positive integer.");
			}
		}

		public void UnloadModule()
		{
			Harmony.UnpatchID("TootTally.GameTweaks");
			settingPage.Remove();
			LogInfo("Module unloaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TootTally.GameTweaks";

		public const string PLUGIN_NAME = "TootTally.GameTweaks";

		public const string PLUGIN_VERSION = "2.1.0";
	}
}