Decompiled source of TootTallyPractice v1.0.3

plugins/TootTallyPractice.dll

Decompiled a day ago
using System;
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 BaboonAPI.Hooks.Tracks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.FSharp.Core;
using TMPro;
using TootTallyCore;
using TootTallyCore.Graphics;
using TootTallyCore.Graphics.Animations;
using TootTallyCore.Utils.TootTallyGlobals;
using TootTallyCore.Utils.TootTallyModules;
using TootTallyCore.Utils.TootTallyNotifs;
using TootTallySettings;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Localization.Components;
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("TootTallyPractice")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("TootTally Practice Module for Trombone Champ")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("TootTallyPractice")]
[assembly: AssemblyTitle("TootTallyPractice")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
namespace TootTallyPractice;

[BepInPlugin("TootTallyPractice", "TootTallyPractice", "1.0.3")]
[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 = "TootTallyPractice.cfg";

	private Harmony _harmony;

	public static TootTallySettingPage settingPage;

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

	public bool IsConfigInitialized { get; set; }

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

	private ConfigEntry<float> StartTime { get; set; }

	private ConfigEntry<int> SpeedIndex { 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", "Practice", true, "Start the song at any time at any speed to practice.");
		TootTallyModuleManager.AddModule((ITootTallyModule)(object)this);
		Plugin.Instance.AddModuleToSettingPage((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
		string text = Path.Combine(Paths.BepInExRootPath, "config/");
		ConfigFile val = new ConfigFile(text + "TootTallyPractice.cfg", true)
		{
			SaveOnConfigSet = true
		};
		val.Bind<float>("Default", "StartTime", 0f, "Time at which the song will start.");
		val.Bind<float>("Default", "SpeedIndex", 0f, "Time at which the song will start.");
		_harmony.PatchAll(typeof(PracticeManager));
		LogInfo("Module loaded!");
	}

	public void UnloadModule()
	{
		_harmony.UnpatchSelf();
		settingPage.Remove();
		LogInfo("Module unloaded!");
	}
}
public static class PracticeManager
{
	private static LevelSelectController _currentInstance;

	private static Button _practiceButton;

	private static AudioSource _btnClickSfx;

	private static PracticePanel _practicePanel;

	public static float StartTime;

	[HarmonyPatch(typeof(LevelSelectController), "Start")]
	[HarmonyPostfix]
	public static void OnLevelSelectControllerStartPostfixAddPracticeButton(LevelSelectController __instance)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Expected O, but got Unknown
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Expected O, but got Unknown
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		_currentInstance = __instance;
		TootTallyGlobalVariables.isPracticing = false;
		StartTime = 0f;
		_practicePanel = new PracticePanel();
		_btnClickSfx = __instance.hoversfx;
		_practiceButton = Object.Instantiate<Button>(__instance.playbtn, ((Component)__instance.fullpanel).transform);
		((Object)_practiceButton).name = "PRACTICE";
		RectTransform component = ((Component)_practiceButton).GetComponent<RectTransform>();
		component.anchoredPosition = new Vector2(461f, -58f);
		Text[] componentsInChildren = ((Component)_practiceButton).GetComponentsInChildren<Text>();
		Text[] array = componentsInChildren;
		LocalizeStringEvent val2 = default(LocalizeStringEvent);
		foreach (Text val in array)
		{
			if (((Component)val).TryGetComponent<LocalizeStringEvent>(ref val2))
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
			val.text = "<i>Practice</i>";
		}
		_practiceButton.onClick = new ButtonClickedEvent();
		((UnityEvent)_practiceButton.onClick).AddListener(new UnityAction(OnPracticeButtonClick));
		EventTrigger component2 = ((Component)_practiceButton).GetComponent<EventTrigger>();
		component2.triggers.Clear();
		Entry val3 = new Entry();
		val3.eventID = (EventTriggerType)0;
		((UnityEvent<BaseEventData>)(object)val3.callback).AddListener((UnityAction<BaseEventData>)OnPracticeButtonHover);
		component2.triggers.Add(val3);
		Entry val4 = new Entry();
		val4.eventID = (EventTriggerType)1;
		((UnityEvent<BaseEventData>)(object)val4.callback).AddListener((UnityAction<BaseEventData>)OnPracticeButtonUnhover);
		component2.triggers.Add(val4);
	}

	public static void OnPracticeButtonHover(BaseEventData _)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		_btnClickSfx.Play();
		if (!Theme.isDefault)
		{
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playBackground")).GetComponent<Image>()).color = Theme.colors.playButton.backgroundOver;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playOutline")).GetComponent<Image>()).color = Theme.colors.playButton.outlineOver;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("txt-play/txt-play-front")).GetComponent<Text>()).color = Theme.colors.playButton.textOver;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playShadow")).GetComponent<Image>()).color = Theme.colors.playButton.shadowOver;
		}
	}

	public static void OnPracticeButtonUnhover(BaseEventData _)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		if (!Theme.isDefault)
		{
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playBackground")).GetComponent<Image>()).color = Theme.colors.playButton.background;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playOutline")).GetComponent<Image>()).color = Theme.colors.playButton.outline;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("txt-play/txt-play-front")).GetComponent<Text>()).color = Theme.colors.playButton.text;
			((Graphic)((Component)((Component)_practiceButton).transform.Find("playShadow")).GetComponent<Image>()).color = Theme.colors.playButton.shadow;
		}
	}

	public static void OnPracticeButtonClick()
	{
		if (_practicePanel.IsVisible)
		{
			_practicePanel.Hide();
			_currentInstance.clipPlayer.cancelCrossfades();
			return;
		}
		_practicePanel.Show(_currentInstance.alltrackslist[_currentInstance.songindex].trackref);
		if (!GlobalVariables.menu_music)
		{
			_currentInstance.clipPlayer.current_track = _currentInstance.alltrackslist[_currentInstance.songindex];
			_currentInstance.clipPlayer.beginClipSearch();
		}
	}

	public static void SetAudioClipTime()
	{
		if ((Object)(object)_currentInstance.clipPlayer.clipPlayer.clip != (Object)null && StartTime < _currentInstance.clipPlayer.clipPlayer.clip.length)
		{
			_currentInstance.clipPlayer.clipPlayer.time = StartTime;
		}
	}

	public static void StopAudioClip()
	{
		_currentInstance.clipPlayer.clipPlayer.Stop();
	}

	public static void StartSongWithPractice()
	{
		TootTallyGlobalVariables.isPracticing = true;
		_currentInstance.clickPlay();
	}

	[HarmonyPatch(typeof(LevelSelectController), "clickPlay")]
	[HarmonyPostfix]
	public static void OnClickPlayAnimatePracticeButton()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		TootTallyAnimationManager.AddNewPositionAnimation(((Component)_practiceButton).gameObject, Vector2.op_Implicit(new Vector2(661f, -58f)), 0.35f, new SecondDegreeDynamicsAnimation(2.15f, 1f, 1f), (Action<GameObject>)null);
	}

	[HarmonyPatch(typeof(LevelSelectController), "advanceSongs")]
	[HarmonyPrefix]
	public static bool SkipAdvanceSongsIfPracticePanelVisible()
	{
		return !_practicePanel.IsVisible;
	}

	[HarmonyPatch(typeof(GameController), "playsong")]
	[HarmonyPrefix]
	public static void SkipToStartTimeOnSongStart(GameController __instance)
	{
		if (TootTallyGlobalVariables.isPracticing)
		{
			StartTime = Mathf.Clamp(StartTime, 0f, __instance.musictrack.clip.length - 1f);
			__instance.musictrack.time = StartTime;
			__instance.resync_timer = 5f;
		}
	}

	[HarmonyPatch(typeof(GameController), "buildNotes")]
	[HarmonyPrefix]
	public static void DeletePastNotesFromLevelData(GameController __instance)
	{
		if (TootTallyGlobalVariables.isPracticing && !(StartTime <= 2f))
		{
			int num = __instance.leveldata.FindIndex((float[] x) => BeatToSeconds2(x[0], __instance.tempo) >= StartTime + 2f);
			if (num > 0)
			{
				__instance.leveldata = __instance.leveldata.GetRange(num, __instance.leveldata.Count - num);
			}
		}
	}

	[HarmonyPatch(typeof(LevelSelectController), "clickRandomTrack")]
	[HarmonyPrefix]
	public static bool SkipRandomizingWhenPracticePanelVisible()
	{
		return !_practicePanel.IsVisible;
	}

	public static float BeatToSeconds2(float beat, float bpm)
	{
		return 60f / bpm * beat;
	}
}
public class PracticePanel
{
	private GameObject _practicePanel;

	private GameObject _fgPanel;

	private TootTallyAnimation _panelAnimation;

	private Text _title;

	private TMP_Text _startTimeLabel;

	private GameObject _panelContainer;

	private Slider _startTimeSlider;

	public bool IsVisible;

	private bool _isStarting;

	public PracticePanel()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Expected O, but got Unknown
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_032e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_036e: Expected O, but got Unknown
		_practicePanel = GameObjectFactory.CreateOverlayPanel((Transform)null, Vector2.zero, new Vector2(1000f, 350f), 12f, "PracticePanel");
		_practicePanel.SetActive(false);
		_fgPanel = ((Component)_practicePanel.transform.GetChild(0).GetChild(1)).gameObject;
		((Graphic)((Component)_fgPanel.transform.parent).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.01f);
		_fgPanel.transform.parent.localScale = Vector2.op_Implicit(Vector2.zero);
		Object.DestroyImmediate((Object)(object)((Component)_fgPanel.transform.GetChild(1)).gameObject);
		_title = ((Component)_fgPanel.transform.GetChild(0)).GetComponent<Text>();
		Object.DestroyImmediate((Object)(object)((Component)_title).GetComponent<LocalizeStringEvent>());
		_panelContainer = ((Component)_fgPanel.transform.GetChild(1)).gameObject;
		_startTimeLabel = GameObjectFactory.CreateSingleText(_panelContainer.transform, "StartTime", "Start Time: 0:00", (TextFont)0);
		_startTimeLabel.rectTransform.sizeDelta = new Vector2(600f, 40f);
		_startTimeSlider = GameObjectFactory.CreateSliderFromPrefab(_panelContainer.transform, "StartTimeSlider");
		((Component)_startTimeSlider).transform.localScale = Vector3.one;
		((Component)_startTimeSlider).GetComponent<RectTransform>().sizeDelta = new Vector2(700f, 40f);
		_startTimeSlider.handleRect.sizeDelta = new Vector2(40f, 0f);
		((Component)_startTimeSlider).gameObject.SetActive(true);
		((UnityEvent<float>)(object)_startTimeSlider.onValueChanged).AddListener((UnityAction<float>)OnStartTimeSliderValueChange);
		_startTimeSlider.minValue = 2f;
		Entry val = new Entry();
		val.eventID = (EventTriggerType)3;
		((UnityEvent<BaseEventData>)(object)val.callback).AddListener((UnityAction<BaseEventData>)delegate
		{
			PracticeManager.SetAudioClipTime();
		});
		((Component)_startTimeSlider).gameObject.AddComponent<EventTrigger>().triggers.Add(val);
		GameObjectFactory.CreateCustomButton(_panelContainer.transform, Vector2.zero, new Vector2(120f, 40f), "Back", "PracticeBackBtn", (Action)Hide);
		GameObjectFactory.CreateCustomButton(_panelContainer.transform, Vector2.zero, new Vector2(120f, 40f), "Start", "PracticeStartBtn", (Action)StartSong);
		_title.text = "Practice Mode";
		RectTransform component = _practicePanel.GetComponent<RectTransform>();
		component.anchorMin = (component.anchorMax = (component.pivot = Vector2.one / 2f));
		RectTransform component2 = _panelContainer.GetComponent<RectTransform>();
		component2.anchoredPosition = Vector2.zero;
		component2.sizeDelta = new Vector2(1000f, 150f);
		VerticalLayoutGroup component3 = _panelContainer.GetComponent<VerticalLayoutGroup>();
		((LayoutGroup)component3).childAlignment = (TextAnchor)4;
		((LayoutGroup)component3).padding = new RectOffset();
		IsVisible = false;
	}

	public void Show(string trackref)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected O, but got Unknown
		FSharpOption<TromboneTrack> val = TrackLookup.tryLookup(trackref);
		if (val == null)
		{
			TootTallyNotifManager.DisplayNotif("Track Incompatible with practice mode", 6f);
			return;
		}
		SetSliderMaxValue(val.Value.length - 1);
		_startTimeSlider.value = ((_startTimeSlider.value > (float)(val.Value.length - 1)) ? 0f : _startTimeSlider.value);
		IsVisible = true;
		_practicePanel.SetActive(true);
		TootTallyAnimation panelAnimation = _panelAnimation;
		if (panelAnimation != null)
		{
			panelAnimation.Dispose();
		}
		_panelAnimation = TootTallyAnimationManager.AddNewScaleAnimation(((Component)_fgPanel.transform.parent).gameObject, Vector3.one, 1f, new SecondDegreeDynamicsAnimation(2.75f, 1f, 0f), (Action<GameObject>)null);
	}

	public void Hide()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		IsVisible = false;
		TootTallyAnimation panelAnimation = _panelAnimation;
		if (panelAnimation != null)
		{
			panelAnimation.Dispose();
		}
		_panelAnimation = TootTallyAnimationManager.AddNewScaleAnimation(((Component)_fgPanel.transform.parent).gameObject, Vector2.zero, 0.45f, new SecondDegreeDynamicsAnimation(3.25f, 1f, 0.25f), (Action<GameObject>)delegate
		{
			_practicePanel.SetActive(false);
		});
		if (!GlobalVariables.menu_music)
		{
			PracticeManager.StopAudioClip();
		}
	}

	public void StartSong()
	{
		//IL_004a: 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_006e: Expected O, but got Unknown
		if (!_isStarting)
		{
			_isStarting = true;
			TootTallyAnimation panelAnimation = _panelAnimation;
			if (panelAnimation != null)
			{
				panelAnimation.Dispose();
			}
			TootTallyAnimationManager.AddNewPositionAnimation(((Component)_fgPanel.transform.parent).gameObject, new Vector3(2000f, 0f, 0f), 0.45f, new SecondDegreeDynamicsAnimation(3.25f, 1f, 0.15f), (Action<GameObject>)null);
			PracticeManager.StartSongWithPractice();
		}
	}

	public void OnStartTimeSliderValueChange(float value)
	{
		PracticeManager.StartTime = value - 2f;
		_startTimeLabel.text = $"Start Time: {TimeSpan.FromSeconds(value):mm\\:ss} / {TimeSpan.FromSeconds(_startTimeSlider.maxValue):mm\\:ss}";
	}

	public void SetSliderMaxValue(float maxValue)
	{
		_startTimeSlider.maxValue = maxValue;
	}
}
public static class PluginInfo
{
	public const string PLUGIN_GUID = "TootTallyPractice";

	public const string PLUGIN_NAME = "TootTallyPractice";

	public const string PLUGIN_VERSION = "1.0.3";
}