Decompiled source of TootTallyHitSounds v1.0.4

plugins/TootTallyHitSounds.dll

Decompiled a day ago
using System;
using System.Collections;
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.Utils.Helpers;
using TootTallyCore.Utils.TootTallyGlobals;
using TootTallyCore.Utils.TootTallyModules;
using TootTallySettings;
using TootTallySettings.TootTallySettingsObjects;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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("TootTallyHitSounds")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Hitsounds module for TootTallyCore")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4")]
[assembly: AssemblyProduct("TootTallyHitSounds")]
[assembly: AssemblyTitle("TootTallyHitSounds")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.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 TootTallyHitSounds
{
	internal class CustomHitSoundSettingPage : TootTallySettingPage
	{
		private static ColorBlock _pageBtnColors;

		private TootTallySettingSlider _hitVolumeSlider;

		private TootTallySettingSlider _missVolumeSlider;

		private TootTallySettingDropdown _hitSoundsDropdown;

		private TootTallySettingDropdown _missSoundsDropdown;

		private TootTallySettingToggle _toggleSyncWithNotes;

		private TootTallySettingToggle _toggleSyncWithSong;

		public CustomHitSoundSettingPage()
			: base("HitSounds", "HitSounds", 40f, new Color(0f, 0f, 0f, 0f), _pageBtnColors)
		{
			//IL_0024: 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)
			_hitVolumeSlider = ((TootTallySettingPage)this).AddSlider("HitSound Volume", 0f, 1f, Plugin.Instance.HitSoundVolume, false);
			_hitSoundsDropdown = CreateDropdownFromFolder("HitSounds", Plugin.Instance.HitSoundName, "None");
			_missVolumeSlider = ((TootTallySettingPage)this).AddSlider("MissSound Volume", 0f, 1f, Plugin.Instance.MissSoundVolume, false);
			_missSoundsDropdown = CreateDropdownFromFolder("MissSounds", Plugin.Instance.MissSoundName, "None");
			_toggleSyncWithNotes = ((TootTallySettingPage)this).AddToggle("Sync With Notes", Plugin.Instance.SyncWithNotes, (UnityAction<bool>)delegate(bool v)
			{
				Plugin.Instance.SyncWithSong.Value = !v;
				_toggleSyncWithSong.toggle.SetIsOnWithoutNotify(!v);
			});
			_toggleSyncWithSong = ((TootTallySettingPage)this).AddToggle("Sync With Song", Plugin.Instance.SyncWithSong, (UnityAction<bool>)delegate(bool v)
			{
				Plugin.Instance.SyncWithNotes.Value = !v;
				_toggleSyncWithNotes.toggle.SetIsOnWithoutNotify(!v);
			});
			((TootTallySettingPage)this).AddToggle("Add Audio Latency To Sync", Plugin.Instance.AddAudioLatencyToSync, (UnityAction<bool>)null);
			((TootTallySettingPage)this).AddButton("Test HitSound", (Action)TestHitSound);
			((TootTallySettingPage)this).AddButton("Test MissSound", (Action)TestMissSound);
		}

		public override void Initialize()
		{
			((TootTallySettingPage)this).Initialize();
			((UnityEvent<float>)(object)_hitVolumeSlider.slider.onValueChanged).AddListener((UnityAction<float>)OnHitVolumeChange);
			((UnityEvent<float>)(object)_missVolumeSlider.slider.onValueChanged).AddListener((UnityAction<float>)OnMissVolumeChange);
			((UnityEvent<int>)(object)_hitSoundsDropdown.dropdown.onValueChanged).AddListener((UnityAction<int>)OnHitSoundChange);
			((UnityEvent<int>)(object)_missSoundsDropdown.dropdown.onValueChanged).AddListener((UnityAction<int>)OnMissSoundChange);
		}

		private void TestHitSound()
		{
			if (Plugin.HitSoundPatches.isHitClipLoaded)
			{
				Plugin.HitSoundPatches.testHitSound.Play();
			}
		}

		private void TestMissSound()
		{
			if (Plugin.HitSoundPatches.isMissClipLoaded)
			{
				Plugin.HitSoundPatches.testMissSound.Play();
			}
		}

		private void OnHitSoundChange(int _)
		{
			Plugin.HitSoundPatches.isHitClipLoaded = false;
			if (Plugin.Instance.HitSoundName.Value != "None")
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine((IEnumerator)Plugin.HitSoundPatches.TryLoadingAudioClipLocal("HitSounds", Plugin.Instance.HitSoundName.Value + ".wav", delegate(AudioClip clip)
				{
					Plugin.HitSoundPatches.testHitSound.clip = clip;
					Plugin.HitSoundPatches.isHitClipLoaded = true;
				}));
			}
		}

		private void OnMissSoundChange(int _)
		{
			Plugin.HitSoundPatches.isMissClipLoaded = false;
			if (Plugin.Instance.MissSoundName.Value != "None")
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine((IEnumerator)Plugin.HitSoundPatches.TryLoadingAudioClipLocal("MissSounds", Plugin.Instance.MissSoundName.Value + ".wav", delegate(AudioClip clip)
				{
					Plugin.HitSoundPatches.testMissSound.clip = clip;
					Plugin.HitSoundPatches.isMissClipLoaded = true;
				}));
			}
		}

		private void OnHitVolumeChange(float value)
		{
			Plugin.HitSoundPatches.testHitSound.volume = value;
		}

		private void OnMissVolumeChange(float value)
		{
			Plugin.HitSoundPatches.testMissSound.volume = value;
		}

		private TootTallySettingDropdown CreateDropdownFromFolder(string folderName, ConfigEntry<string> config, string defaultValue)
		{
			List<string> folderNames = new List<string> { defaultValue };
			string path = Path.Combine(Paths.BepInExRootPath, folderName);
			if (Directory.Exists(path))
			{
				List<string> list = Directory.GetFiles(path).ToList();
				list.ForEach(delegate(string d)
				{
					if (Path.GetExtension(d).ToLower().Contains("wav"))
					{
						folderNames.Add(Path.GetFileNameWithoutExtension(d));
					}
				});
			}
			((TootTallySettingPage)this).AddLabel(folderName, folderName, 24f, (FontStyles)0, (TextAlignmentOptions)1025);
			return ((TootTallySettingPage)this).AddDropdown(folderName + "Dropdown", config, folderNames.ToArray());
		}

		static CustomHitSoundSettingPage()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0094: 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)
			ColorBlock pageBtnColors = default(ColorBlock);
			((ColorBlock)(ref pageBtnColors)).colorMultiplier = 1f;
			((ColorBlock)(ref pageBtnColors)).fadeDuration = 0.2f;
			((ColorBlock)(ref pageBtnColors)).disabledColor = Color.gray;
			((ColorBlock)(ref pageBtnColors)).normalColor = new Color(0.6f, 0.6f, 0.6f);
			((ColorBlock)(ref pageBtnColors)).pressedColor = new Color(0.2f, 0.2f, 0.2f);
			((ColorBlock)(ref pageBtnColors)).highlightedColor = new Color(0.8f, 0.8f, 0.8f);
			((ColorBlock)(ref pageBtnColors)).selectedColor = new Color(0.6f, 0.6f, 0.6f);
			_pageBtnColors = pageBtnColors;
		}
	}
	[BepInPlugin("TootTallyHitSounds", "TootTallyHitSounds", "1.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin, ITootTallyModule
	{
		public static class HitSoundPatches
		{
			private static bool _lastIsActive;

			private static AudioSource _hitSound;

			private static AudioSource _missSound;

			private static float _hitVolume;

			private static float _missVolume;

			public static bool isHitClipLoaded;

			public static bool isMissClipLoaded;

			public static AudioSource testHitSound;

			public static AudioSource testMissSound;

			private static bool _isSlider;

			private static int _lastIndex;

			private static double _trackTime;

			private static int _lastSample;

			private static float _nextTiming;

			private static bool _isStarted;

			private static int _lastMult;

			private static bool _lastChamp;

			[HarmonyPatch(typeof(HomeController), "Start")]
			[HarmonyPostfix]
			public static void LoadTestSounds(HomeController __instance)
			{
				testHitSound = ((Component)__instance).gameObject.AddComponent<AudioSource>();
				testHitSound.volume = Instance.HitSoundVolume.Value;
				isHitClipLoaded = false;
				if (Instance.HitSoundName.Value != "None")
				{
					((MonoBehaviour)Instance).StartCoroutine((IEnumerator)TryLoadingAudioClipLocal("HitSounds", Instance.HitSoundName.Value + ".wav", delegate(AudioClip clip)
					{
						testHitSound.clip = clip;
						isHitClipLoaded = true;
					}));
				}
				testMissSound = ((Component)__instance).gameObject.AddComponent<AudioSource>();
				testMissSound.volume = Instance.HitSoundVolume.Value;
				isMissClipLoaded = false;
				if (Instance.MissSoundName.Value != "None")
				{
					((MonoBehaviour)Instance).StartCoroutine((IEnumerator)TryLoadingAudioClipLocal("MissSounds", Instance.MissSoundName.Value + ".wav", delegate(AudioClip clip)
					{
						testMissSound.clip = clip;
						isMissClipLoaded = true;
					}));
				}
			}

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void LoadHitSound(GameController __instance)
			{
				isHitClipLoaded = false;
				if (!(Instance.HitSoundName.Value == "None"))
				{
					_isStarted = false;
					_lastChamp = false;
					_lastMult = 0;
					_lastIsActive = false;
					_isSlider = false;
					_lastIndex = -1;
					_trackTime = 0.0;
					_nextTiming = ((__instance.leveldata.Count > 0) ? B2s(__instance.leveldata[0][0], __instance.tempo) : 0f);
					_hitSound = ((Component)__instance).gameObject.AddComponent<AudioSource>();
					_hitSound.volume = (_hitVolume = Instance.HitSoundVolume.Value * GlobalVariables.localsettings.maxvolume);
					((MonoBehaviour)Instance).StartCoroutine((IEnumerator)TryLoadingAudioClipLocal("HitSounds", Instance.HitSoundName.Value + ".wav", delegate(AudioClip clip)
					{
						LogInfo("Hit Sounds " + Instance.HitSoundName.Value + " Loaded.");
						_hitSound.clip = clip;
						isHitClipLoaded = true;
					}));
				}
			}

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void LoadMissSound(GameController __instance)
			{
				isMissClipLoaded = false;
				if (!(Instance.MissSoundName.Value == "None"))
				{
					_missSound = ((Component)__instance).gameObject.AddComponent<AudioSource>();
					_missSound.volume = (_hitVolume = Instance.MissSoundVolume.Value * GlobalVariables.localsettings.maxvolume);
					((MonoBehaviour)Instance).StartCoroutine((IEnumerator)TryLoadingAudioClipLocal("MissSounds", Instance.MissSoundName.Value + ".wav", delegate(AudioClip clip)
					{
						LogInfo("Miss Sounds " + Instance.MissSoundName.Value + " Loaded.");
						_missSound.clip = clip;
						isMissClipLoaded = true;
					}));
				}
			}

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

			[HarmonyPatch(typeof(GameController), "grabNoteRefs")]
			[HarmonyPrefix]
			public static void GetIsSlider(GameController __instance)
			{
				if (__instance.currentnoteindex + 1 < __instance.leveldata.Count)
				{
					_isSlider = Mathf.Abs(__instance.leveldata[__instance.currentnoteindex + 1][0] - (__instance.leveldata[__instance.currentnoteindex][0] + __instance.leveldata[__instance.currentnoteindex][1])) < 0.05f;
					_nextTiming = B2s(__instance.leveldata[__instance.currentnoteindex + 1][0], __instance.tempo);
				}
			}

			[HarmonyPatch(typeof(GameController), "Update")]
			[HarmonyPostfix]
			public static void PlaySoundOnNewNoteActive(GameController __instance)
			{
				if (!((Object)(object)_hitSound == (Object)null) && isHitClipLoaded && _isStarted && _isStarted && !__instance.paused && !__instance.quitting && !__instance.retrying)
				{
					_trackTime += Time.deltaTime * TootTallyGlobalVariables.gameSpeedMultiplier;
					if (_lastSample != __instance.musictrack.timeSamples)
					{
						_trackTime = __instance.musictrack.time - (Instance.AddAudioLatencyToSync.Value ? __instance.latency_offset : 0f);
						_lastSample = __instance.musictrack.timeSamples;
					}
					if (ShouldPlayHitSound(__instance))
					{
						_lastIndex = __instance.currentnoteindex;
						PlaySound(ref _hitVolume, ref _hitSound, Instance.HitSoundVolume.Value);
					}
					FadeOutVolume(ref _hitVolume, ref _hitSound, Instance.HitSoundVolume.Value);
					FadeOutVolume(ref _missVolume, ref _missSound, Instance.MissSoundVolume.Value);
					_lastIsActive = __instance.noteactive;
				}
			}

			[HarmonyPatch(typeof(GameController), "getScoreAverage")]
			[HarmonyPostfix]
			public static void OnNoteScoringPostfix(GameController __instance)
			{
				if (!((Object)(object)_missSound == (Object)null) && isMissClipLoaded && _isStarted)
				{
					if (ShouldPlayMissSount(__instance.multiplier, __instance.rainbowcontroller.champmode))
					{
						PlaySound(ref _missVolume, ref _missSound, Instance.MissSoundVolume.Value);
					}
					_lastMult = __instance.multiplier;
					_lastChamp = __instance.rainbowcontroller.champmode;
				}
			}

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

			public static bool ShouldPlayHitSound(GameController __instance)
			{
				if (Instance.SyncWithNotes.Value)
				{
					return __instance.noteactive && !_lastIsActive && !_isSlider;
				}
				return _trackTime > (double)_nextTiming && _lastIndex != __instance.currentnoteindex && !_isSlider;
			}

			public static bool ShouldPlayMissSount(int multiplier, bool champ)
			{
				return (_lastMult >= 10 && multiplier == 0) || (_lastChamp && !champ);
			}

			public static void PlaySound(ref float volume, ref AudioSource audioSource, float maxVolume)
			{
				volume = maxVolume * GlobalVariables.localsettings.maxvolume;
				audioSource.time = 0f;
				audioSource.Play();
			}

			public static void FadeOutVolume(ref float volume, ref AudioSource audioSource, float maxVolume)
			{
				if (volume < 0f)
				{
					volume = 0f;
					audioSource.Stop();
				}
				else if (volume > 0f)
				{
					volume -= Time.unscaledDeltaTime / 2f * maxVolume * GlobalVariables.localsettings.maxvolume;
					audioSource.volume = Mathf.Clamp(volume, 0f, 1f);
				}
			}

			public static IEnumerator<UnityWebRequestAsyncOperation> TryLoadingAudioClipLocal(string folderName, string fileName, Action<AudioClip> callback)
			{
				string assetDir = Path.Combine(Paths.BepInExRootPath, folderName, fileName);
				UnityWebRequest webRequest = UnityWebRequestMultimedia.GetAudioClip("file://" + assetDir, (AudioType)20);
				yield return webRequest.SendWebRequest();
				if (!webRequest.isHttpError && !webRequest.isNetworkError)
				{
					callback(DownloadHandlerAudioClip.GetContent(webRequest));
				}
			}
		}

		public static Plugin Instance;

		private const string CONFIG_NAME = "TootTallyHitSounds.cfg";

		public const string DEFAULT_HITSOUND = "None";

		public const string DEFAULT_MISSSOUND = "None";

		private Harmony _harmony;

		public static TootTallySettingPage settingPage;

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

		public bool IsConfigInitialized { get; set; }

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

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

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

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

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

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

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

		public ConfigEntry<bool> AddAudioLatencyToSync { 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", "HitSounds", true, "Add HitSounds when notes become active.");
			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 + "TootTallyHitSounds.cfg", true)
			{
				SaveOnConfigSet = true
			};
			HitSoundVolume = val.Bind<float>("General", "HitSoundVolume", 1f, "Volume of the hitsounds.");
			MissSoundVolume = val.Bind<float>("General", "MissSoundVolume", 1f, "Volume of the misssounds.");
			HitSoundName = val.Bind<string>("General", "HitSoundName", "None", "Name of the hitsound wav file.");
			MissSoundName = val.Bind<string>("General", "MissSoundName", "None", "Name of the misssound wav file.");
			SyncWithNotes = val.Bind<bool>("General", "SyncWithNotes", false, "Useful for charters to make sure your map is on time. Use with 0ms audio latency for best results.");
			SyncWithSong = val.Bind<bool>("General", "SyncWithSong", true, "Better for players since the clicking sound will (most of the time) match the music's timing.");
			AddAudioLatencyToSync = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddAudioLatencyToSync", false, "Adds the audio offset to tracktime for hitsound syncing.");
			TryMigrateSoundsFolder("HitSounds");
			TryMigrateSoundsFolder("MissSounds");
			settingPage = TootTallySettingsManager.AddNewPage((TootTallySettingPage)(object)new CustomHitSoundSettingPage());
			Plugin.TryAddThunderstoreIconToPageButton(((BaseUnityPlugin)Instance).Info.Location, Name, settingPage);
			_harmony.PatchAll(typeof(HitSoundPatches));
			LogInfo("Module loaded!");
		}

		private static void TryMigrateSoundsFolder(string folderName)
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), folderName);
			string text2 = Path.Combine(Paths.BepInExRootPath, folderName);
			FileHelper.TryMigrateFolder(text, text2, false);
		}

		public void UnloadModule()
		{
			_harmony.UnpatchSelf();
			settingPage.Remove();
			LogInfo("Module unloaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "TootTallyHitSounds";

		public const string PLUGIN_NAME = "TootTallyHitSounds";

		public const string PLUGIN_VERSION = "1.0.4";
	}
}