Decompiled source of AutoToot v1.2.5

AutoToot.dll

Decompiled a year ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using AutoToot.Helpers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TrombLoader.Data;
using UnityEngine;
using UnityEngine.SceneManagement;
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 = "")]
[assembly: AssemblyCompany("Tom.")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Auto play for Trombone Champ.")]
[assembly: AssemblyFileVersion("1.2.4.0")]
[assembly: AssemblyInformationalVersion("1.2.4")]
[assembly: AssemblyProduct("AutoToot")]
[assembly: AssemblyTitle("AutoToot")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.4.0")]
[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 AutoToot
{
	public class AutoIndicator : MonoBehaviour
	{
		private const string GameObjectName = "AutoToot Indicator";

		private const string IndicatorText = "AutoToot Enabled";

		private const float YPosition = -4.7322f;

		private const string ForegroundObjectName = "maxcombo_text";

		private Text _foregroundText;

		private Text _shadowText;

		private void Start()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			((Object)((Component)this).gameObject).name = "AutoToot Indicator";
			Vector3 position = ((Component)this).transform.position;
			position.y = -4.7322f;
			((Component)this).transform.position = position;
			_foregroundText = ((Component)((Component)this).transform.Find("maxcombo_text")).GetComponent<Text>();
			_shadowText = ((Component)this).GetComponent<Text>();
			_foregroundText.text = "AutoToot Enabled";
			_shadowText.text = "AutoToot Enabled";
		}

		private void Update()
		{
			bool isActive = Plugin.IsActive;
			if (((Behaviour)_foregroundText).enabled != isActive)
			{
				((Behaviour)_foregroundText).enabled = isActive;
				((Behaviour)_shadowText).enabled = isActive;
			}
		}
	}
	public class Bot
	{
		private float _lastNoteEndTime;

		private float _lastNoteEndY;

		private float _currentNoteStartTime;

		private float _currentNoteEndTime;

		private readonly GameController _gameController;

		private readonly HumanPuppetController _humanPuppetController;

		private readonly GameObject _bg;

		private readonly BackgroundPuppetController _backgroundPuppetController;

		private readonly RectTransform _noteHolderPosition;

		private readonly RectTransform _pointer;

		private readonly int _earlyStart;

		private readonly int _lateFinish;

		private readonly MethodInfo _easeFunction;

		private const float GameCanvasSize = 450f;

		private const float NotesHolderZeroOffset = 60f;

		private const string NotesHolderPath = "GameplayCanvas/GameSpace/NotesHolder";

		private const string CursorPath = "GameplayCanvas/GameSpace/TargetNote";

		public bool IsTooting { get; private set; }

		public bool IsPerfectPlay { get; }

		private ManualLogSource Logger => Plugin.Logger;

		public Bot(GameController gameController)
		{
			_gameController = gameController;
			_humanPuppetController = gameController.puppet_humanc;
			_backgroundPuppetController = null;
			_bg = GameObject.Find("_Background(Clone)");
			if (Object.op_Implicit((Object)(object)_bg))
			{
				_backgroundPuppetController = _bg.GetComponent<BackgroundPuppetController>();
			}
			GameObject obj = GameObject.Find("GameplayCanvas/GameSpace/NotesHolder");
			_noteHolderPosition = ((obj != null) ? obj.GetComponent<RectTransform>() : null);
			GameObject obj2 = GameObject.Find("GameplayCanvas/GameSpace/TargetNote");
			_pointer = ((obj2 != null) ? obj2.GetComponent<RectTransform>() : null);
			if ((Object)(object)_noteHolderPosition == (Object)null || (Object)(object)_pointer == (Object)null)
			{
				Logger.LogError((object)"Unable to locate the NotesHolder and Pointer, Auto-Toot cannot function.");
				Plugin.IsActive = false;
			}
			else
			{
				Logger.LogDebug((object)"Located NotesHolder and Pointer.");
			}
			_earlyStart = Plugin.Configuration.EarlyStart.Value;
			_lateFinish = Plugin.Configuration.LateFinish.Value;
			_easeFunction = typeof(Easing).GetMethod(Plugin.Configuration.EaseFunction.Value);
			IsPerfectPlay = Plugin.Configuration.PerfectScore.Value;
		}

		public void Update()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (_gameController.currentnoteindex > -1)
			{
				float time = GetTime();
				if (_currentNoteEndTime >= _gameController.currentnotestart)
				{
					_gameController.released_button_between_notes = true;
				}
				_currentNoteStartTime = _gameController.currentnotestart - (float)_earlyStart;
				_currentNoteEndTime = _gameController.currentnoteend + (float)_lateFinish;
				IsTooting = ShouldToot(time, _currentNoteStartTime, _currentNoteEndTime);
				if (IsTooting)
				{
					_lastNoteEndTime = time + (float)_lateFinish;
					_lastNoteEndY = _pointer.anchoredPosition.y;
				}
				float pointerY = GetPointerY(time, _currentNoteStartTime, _currentNoteEndTime);
				Vector2 anchoredPosition = _pointer.anchoredPosition;
				anchoredPosition.y = pointerY;
				_pointer.anchoredPosition = anchoredPosition;
				_humanPuppetController.doPuppetControl((0f - pointerY) / 450f * 2f);
				if (Object.op_Implicit((Object)(object)_backgroundPuppetController))
				{
					_backgroundPuppetController.DoPuppetControl((0f - pointerY) / 450f * 2f, _gameController.vibratoamt);
				}
			}
		}

		private float GetTime()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			float num = _noteHolderPosition.anchoredPosition3D.x - 60f;
			return (num <= 0f) ? Mathf.Abs(num) : (-1f);
		}

		private float Ease(float e)
		{
			return (float)_easeFunction.Invoke(typeof(Easing), new object[1] { e });
		}

		private float GetPointerY(float currentTime, float noteStartTime, float noteEndTime)
		{
			if (ShouldToot(currentTime, noteStartTime, noteEndTime))
			{
				return _gameController.currentnotestarty + _gameController.easeInOutVal(Mathf.Abs(1f - (noteEndTime - (float)_lateFinish - currentTime) / (noteEndTime - (float)_lateFinish - (noteStartTime + (float)_earlyStart))), 0f, _gameController.currentnotepshift, 1f);
			}
			return Mathf.Lerp(_lastNoteEndY, _gameController.currentnotestarty, Ease(1f - (noteStartTime - currentTime) / (noteStartTime - _lastNoteEndTime)));
		}

		private bool ShouldToot(float currentTime, float noteStartTime, float noteEndTime)
		{
			return !_gameController.outofbreath && currentTime >= noteStartTime && currentTime <= noteEndTime;
		}
	}
	public class Configuration
	{
		private const KeyCode DefaultToggleKey = 289;

		private const string DefaultEasingFunction = "Linear";

		private const int DefaultEarlyStart = 8;

		private const int DefaultLateFinish = 8;

		public ConfigEntry<KeyCode> ToggleKey { get; }

		public ConfigEntry<string> EaseFunction { get; }

		public ConfigEntry<int> EarlyStart { get; }

		public ConfigEntry<int> LateFinish { get; }

		public ConfigEntry<bool> PerfectScore { get; }

		internal Configuration(ConfigFile configFile)
		{
			Plugin.Logger.LogInfo((object)"Loading config...");
			ToggleKey = configFile.Bind<KeyCode>("Keybinds", "ToggleKey", (KeyCode)289, "The key used to toggle AutoToot on and off.");
			EaseFunction = configFile.Bind<string>("Interpolation", "EaseFunction", "Linear", "The easing function to use for animating pointer position between notes.\nValid easing functions are: " + string.Join(", ", GetValidEasingTypes()) + ".\nPreview easing functions at: https://easings.net/");
			EarlyStart = configFile.Bind<int>("Timing", "EarlyStart", 8, "Starts playing notes earlier by the given duration.");
			LateFinish = configFile.Bind<int>("Timing", "LateFinish", 8, "Finishes notes later by the given duration.");
			PerfectScore = configFile.Bind<bool>("Score", "PerfectScore", false, "Cheat the score returned by notes to achieve a perfect score.");
		}

		public void Validate()
		{
			if (typeof(Easing).GetMethod(EaseFunction.Value) == null)
			{
				Plugin.Logger.LogWarning((object)("Easing function '" + EaseFunction.Value + "' does not exist, falling back to 'Linear'.\nValid easing functions are: " + string.Join(", ", GetValidEasingTypes()) + "."));
				EaseFunction.Value = "Linear";
			}
			if (EarlyStart.Value < 0)
			{
				Plugin.Logger.LogWarning((object)$"Early start time is less than zero, falling back to {8}.");
				EarlyStart.Value = 8;
			}
			if (LateFinish.Value < 0)
			{
				Plugin.Logger.LogWarning((object)$"Late finish time is less than zero, falling back to {8}.");
				EarlyStart.Value = 8;
			}
		}

		private string[] GetValidEasingTypes()
		{
			MethodInfo[] methods = typeof(Easing).GetMethods();
			int num = methods.Length - 4;
			string[] array = new string[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = methods[i].Name;
			}
			return array;
		}
	}
	[BepInPlugin("AutoToot", "AutoToot", "1.2.4")]
	public class Plugin : BaseUnityPlugin
	{
		private static bool _isActive;

		private static bool _isInGameplay;

		private const string GameplaySceneName = "gameplay";

		private const string GameControllerPath = "GameController";

		public static bool IsActive
		{
			get
			{
				return _isActive;
			}
			set
			{
				if (_isActive != value)
				{
					if (value)
					{
						SetupBot();
						WasAutoUsed = true;
					}
					_isActive = value;
					Logger.LogInfo((object)((_isActive ? "Enabled" : "Disabled") + " Auto-Toot."));
				}
			}
		}

		public static bool WasAutoUsed { get; private set; }

		public static Bot Bot { get; private set; }

		public static Configuration Configuration { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Loaded AutoToot v1.2.4.");
			Configuration = new Configuration(((BaseUnityPlugin)this).Config);
			Configuration.Validate();
			Harmony val = new Harmony("AutoToot");
			val.PatchAll();
			SceneManager.sceneLoaded += OnSceneLoaded;
			Logger.LogDebug((object)"Added sceneLoaded delegate.");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)mode != 1)
			{
				Logger.LogDebug((object)$"Level {((Scene)(ref scene)).buildIndex} ({((Scene)(ref scene)).name}) was loaded.");
				if (((Scene)(ref scene)).name == "gameplay")
				{
					Logger.LogInfo((object)"Gameplay scene loaded.");
					_isInGameplay = true;
					WasAutoUsed = false;
				}
				else if (_isInGameplay)
				{
					Logger.LogInfo((object)"Gameplay scene unloaded.");
					_isInGameplay = false;
					IsActive = false;
					Bot = null;
				}
			}
		}

		private static void SetupBot()
		{
			GameObject val = GameObject.Find("GameController");
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError((object)"Unable to find the GameController object, Auto-Toot cannot function.");
				return;
			}
			GameController component = val.GetComponent<GameController>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.LogError((object)"Unable to retrieve the GameController component, Auto-Toot cannot function.");
			}
			else
			{
				Bot = new Bot(component);
			}
		}

		public static void ToggleActive()
		{
			IsActive = !_isActive;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "AutoToot";

		public const string PLUGIN_NAME = "AutoToot";

		public const string PLUGIN_VERSION = "1.2.4";
	}
}
namespace AutoToot.Patches
{
	[HarmonyPatch(typeof(GameController), "Start")]
	internal class GameControllerStartPatch
	{
		private const string ComboPath = "GameplayCanvas/UIHolder/maxcombo/maxcombo_shadow";

		private const string ParentPath = "GameplayCanvas/UIHolder";

		private static void Postfix()
		{
			GameObject val = GameObject.Find("GameplayCanvas/UIHolder/maxcombo/maxcombo_shadow");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogError((object)"Unable to find combo text, the auto toot indicator will not be present.");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, val.transform);
			val2.AddComponent<AutoIndicator>();
			GameObject val3 = GameObject.Find("GameplayCanvas/UIHolder");
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Logger.LogError((object)"Unable to find the UIHolder to re-parent the indicator, placement may be wrong.");
			}
			else
			{
				val2.transform.parent = val3.transform;
			}
		}
	}
	[HarmonyPatch(typeof(GameController), "Update")]
	internal class GameControllerUpdatePatch
	{
		private static void Postfix(GameController __instance)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.freeplay || __instance.paused)
			{
				return;
			}
			if (Input.GetKeyDown(Plugin.Configuration.ToggleKey.Value))
			{
				Plugin.ToggleActive();
			}
			__instance.controllermode = Plugin.IsActive;
			if (Plugin.IsActive)
			{
				Plugin.Bot.Update();
				if (Plugin.Bot.IsPerfectPlay)
				{
					__instance.released_button_between_notes = true;
					__instance.breathcounter = 0f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameController), "isNoteButtonPressed")]
	internal class GameControllerIsNoteButtonPressedPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (Plugin.IsActive)
			{
				__result = Plugin.Bot.IsTooting;
			}
		}
	}
	[HarmonyPatch(typeof(GameController), "getScoreAverage")]
	internal class GameControllerGetScoreAveragePatch
	{
		private static void Prefix(GameController __instance)
		{
			if (Plugin.IsActive && Plugin.Bot.IsPerfectPlay)
			{
				__instance.notescoreaverage = 100f;
			}
		}
	}
	[HarmonyPatch(typeof(GameController), "doScoreText")]
	internal class GameControllerDoScoreTextPatch
	{
		private static void Prefix(object[] __args)
		{
			if (Plugin.IsActive && Plugin.Bot.IsPerfectPlay)
			{
				__args[0] = 4;
				__args[1] = 100f;
			}
		}
	}
	[HarmonyPatch(typeof(GameController), "pauseRetryLevel")]
	internal class GameControllerRetryPatch
	{
		private static void Postfix(GameController __instance)
		{
			if (Plugin.IsActive)
			{
				Plugin.IsActive = false;
			}
		}
	}
	[HarmonyPatch(typeof(PointSceneController), "Start")]
	internal class PointSceneControllerStartPatch
	{
		private static void Prefix()
		{
			if (Plugin.WasAutoUsed)
			{
				SavedCardCollection localsave = GlobalVariables.localsave;
				localsave.tracks_played--;
			}
		}
	}
	[HarmonyPatch(typeof(PointSceneController), "updateSave")]
	internal class PointSceneControllerUpdateSavePatch
	{
		private static bool Prefix()
		{
			return !Plugin.WasAutoUsed;
		}
	}
	[HarmonyPatch(typeof(PointSceneController), "checkScoreCheevos")]
	internal class PointSceneControllerAchievementsCheckPatch
	{
		private static bool Prefix()
		{
			return !Plugin.WasAutoUsed;
		}
	}
	[HarmonyPatch(typeof(PointSceneController), "doCoins")]
	internal class PointSceneControllerDoCoinsPatch
	{
		private const string CoinPath = "Canvas/buttons/coingroup/coin";

		private const string TootsTextPath = "Canvas/buttons/coingroup/Text";

		private const float TootsTextXPosition = -0.246f;

		private static void Postfix(PointSceneController __instance)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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)
			if (Plugin.WasAutoUsed)
			{
				GameObject val = GameObject.Find("Canvas/buttons/coingroup/coin");
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Logger.LogError((object)"Unable to find toots coin, it may be visible still.");
				}
				else
				{
					val.SetActive(false);
				}
				GameObject val2 = GameObject.Find("Canvas/buttons/coingroup/Text");
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.Logger.LogError((object)"Unable to find toots text, AutoToot indicator will not be present.");
				}
				else
				{
					__instance.tootstext.text = "AutoTooted Play";
					Vector3 position = val2.transform.position;
					position.x = -0.246f;
					val2.transform.position = position;
				}
				((MonoBehaviour)__instance).Invoke("showContinue", 0.75f);
			}
		}
	}
}
namespace AutoToot.Helpers
{
	internal static class Easing
	{
		public static float Linear(float t)
		{
			return t;
		}

		public static float InQuad(float t)
		{
			return t * t;
		}

		public static float OutQuad(float t)
		{
			return 1f - InQuad(1f - t);
		}

		public static float InOutQuad(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuad(t * 2f) / 2f;
			}
			return 1f - InQuad((1f - t) * 2f) / 2f;
		}

		public static float InCubic(float t)
		{
			return t * t * t;
		}

		public static float OutCubic(float t)
		{
			return 1f - InCubic(1f - t);
		}

		public static float InOutCubic(float t)
		{
			if ((double)t < 0.5)
			{
				return InCubic(t * 2f) / 2f;
			}
			return 1f - InCubic((1f - t) * 2f) / 2f;
		}

		public static float InQuart(float t)
		{
			return t * t * t * t;
		}

		public static float OutQuart(float t)
		{
			return 1f - InQuart(1f - t);
		}

		public static float InOutQuart(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuart(t * 2f) / 2f;
			}
			return 1f - InQuart((1f - t) * 2f) / 2f;
		}

		public static float InQuint(float t)
		{
			return t * t * t * t * t;
		}

		public static float OutQuint(float t)
		{
			return 1f - InQuint(1f - t);
		}

		public static float InOutQuint(float t)
		{
			if ((double)t < 0.5)
			{
				return InQuint(t * 2f) / 2f;
			}
			return 1f - InQuint((1f - t) * 2f) / 2f;
		}

		public static float InSine(float t)
		{
			return (float)(0.0 - Math.Cos((double)t * Math.PI / 2.0));
		}

		public static float OutSine(float t)
		{
			return (float)Math.Sin((double)t * Math.PI / 2.0);
		}

		public static float InOutSine(float t)
		{
			return (float)(Math.Cos((double)t * Math.PI) - 1.0) / -2f;
		}

		public static float InExpo(float t)
		{
			return (float)Math.Pow(2.0, 10f * (t - 1f));
		}

		public static float OutExpo(float t)
		{
			return 1f - InExpo(1f - t);
		}

		public static float InOutExpo(float t)
		{
			if ((double)t < 0.5)
			{
				return InExpo(t * 2f) / 2f;
			}
			return 1f - InExpo((1f - t) * 2f) / 2f;
		}

		public static float InCirc(float t)
		{
			return 0f - ((float)Math.Sqrt(1f - t * t) - 1f);
		}

		public static float OutCirc(float t)
		{
			return 1f - InCirc(1f - t);
		}

		public static float InOutCirc(float t)
		{
			if ((double)t < 0.5)
			{
				return InCirc(t * 2f) / 2f;
			}
			return 1f - InCirc((1f - t) * 2f) / 2f;
		}

		public static float InElastic(float t)
		{
			return 1f - OutElastic(1f - t);
		}

		public static float OutElastic(float t)
		{
			float num = 0.3f;
			return (float)Math.Pow(2.0, -10f * t) * (float)Math.Sin((double)(t - num / 4f) * (Math.PI * 2.0) / (double)num) + 1f;
		}

		public static float InOutElastic(float t)
		{
			if ((double)t < 0.5)
			{
				return InElastic(t * 2f) / 2f;
			}
			return 1f - InElastic((1f - t) * 2f) / 2f;
		}

		public static float InBack(float t)
		{
			float num = 1.70158f;
			return t * t * ((num + 1f) * t - num);
		}

		public static float OutBack(float t)
		{
			return 1f - InBack(1f - t);
		}

		public static float InOutBack(float t)
		{
			if ((double)t < 0.5)
			{
				return InBack(t * 2f) / 2f;
			}
			return 1f - InBack((1f - t) * 2f) / 2f;
		}

		public static float InBounce(float t)
		{
			return 1f - OutBounce(1f - t);
		}

		public static float OutBounce(float t)
		{
			float num = 2.75f;
			float num2 = 7.5625f;
			if (t < 1f / num)
			{
				return num2 * t * t;
			}
			if (t < 2f / num)
			{
				t -= 1.5f / num;
				return num2 * t * t + 0.75f;
			}
			if ((double)t < 2.5 / (double)num)
			{
				t -= 2.25f / num;
				return num2 * t * t + 0.9375f;
			}
			t -= 2.625f / num;
			return num2 * t * t + 63f / 64f;
		}

		public static float InOutBounce(float t)
		{
			if ((double)t < 0.5)
			{
				return InBounce(t * 2f) / 2f;
			}
			return 1f - InBounce((1f - t) * 2f) / 2f;
		}
	}
}