Decompiled source of TootTallyHitSounds v1.0.2

plugins/TootTallyHitSounds.dll

Decompiled 2 months 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.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("TootTallyHitSounds")]
[assembly: AssemblyTitle("TootTallyHitSounds")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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 _volumeSlider;

		private TootTallySettingDropdown _dropdown;

		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)
			_volumeSlider = ((TootTallySettingPage)this).AddSlider("Volume", 0f, 1f, Plugin.Instance.Volume, false);
			_dropdown = CreateDropdownFromFolder("HitSounds", Plugin.Instance.HitSoundName, "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).AddButton("Test Sound", (Action)TestSound);
		}

		public override void Initialize()
		{
			((TootTallySettingPage)this).Initialize();
			((UnityEvent<float>)(object)_volumeSlider.slider.onValueChanged).AddListener((UnityAction<float>)OnVolumeChange);
			((UnityEvent<int>)(object)_dropdown.dropdown.onValueChanged).AddListener((UnityAction<int>)OnHitSoundChange);
		}

		private void TestSound()
		{
			if (Plugin.HitSoundPatches.isClipLoaded)
			{
				Plugin.HitSoundPatches.testHitSound.Play();
			}
		}

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

		private void OnVolumeChange(float value)
		{
			Plugin.HitSoundPatches.testHitSound.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.2")]
	[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 float _volume;

			public static bool isClipLoaded;

			public static AudioSource testHitSound;

			private static bool _isSlider;

			private static int _lastIndex;

			private static double _time;

			private static float _nextTiming;

			private static bool _isStarted;

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

			[HarmonyPatch(typeof(GameController), "Start")]
			[HarmonyPostfix]
			public static void LoadHitSound(GameController __instance)
			{
				isClipLoaded = false;
				if (!(Instance.HitSoundName.Value == "None"))
				{
					_isStarted = false;
					_lastIsActive = false;
					_isSlider = false;
					_lastIndex = -1;
					_time = 0f - __instance.noteoffset;
					_nextTiming = ((__instance.leveldata.Count > 0) ? B2s(__instance.leveldata[0][0], __instance.tempo) : 0f);
					_hitsound = ((Component)__instance).gameObject.AddComponent<AudioSource>();
					_hitsound.volume = (_volume = Instance.Volume.Value * GlobalVariables.localsettings.maxvolume);
					((MonoBehaviour)Instance).StartCoroutine((IEnumerator)TryLoadingAudioClipLocal(Instance.HitSoundName.Value + ".wav", delegate(AudioClip clip)
					{
						_hitsound.clip = clip;
						isClipLoaded = true;
					}));
				}
			}

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

			[HarmonyPatch(typeof(GameController), "syncTrackPositions")]
			[HarmonyPostfix]
			public static void OnSyncTrack(GameController __instance)
			{
				_time = __instance.musictrack.time - __instance.noteoffset;
			}

			[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) && isClipLoaded && _isStarted)
				{
					if (ShouldPlayHitSound(__instance))
					{
						_lastIndex = __instance.currentnoteindex;
						PlayHitSound();
					}
					FadeOutVolume();
					_lastIsActive = __instance.noteactive;
				}
			}

			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;
				}
				if (!__instance.paused)
				{
					_time += Time.deltaTime * TootTallyGlobalVariables.gameSpeedMultiplier;
				}
				return _time > (double)_nextTiming && _lastIndex != __instance.currentnoteindex && !_isSlider;
			}

			public static void PlayHitSound()
			{
				_volume = Instance.Volume.Value * GlobalVariables.localsettings.maxvolume;
				_hitsound.Play();
			}

			public static void FadeOutVolume()
			{
				if (_volume < 0f)
				{
					_volume = 0f;
					_hitsound.Stop();
				}
				else if (_volume > 0f)
				{
					_volume -= Time.unscaledDeltaTime / 2f * Instance.Volume.Value * GlobalVariables.localsettings.maxvolume;
					_hitsound.volume = Mathf.Clamp(_volume, 0f, 1f);
				}
			}

			public static IEnumerator<UnityWebRequestAsyncOperation> TryLoadingAudioClipLocal(string fileName, Action<AudioClip> callback)
			{
				string assetDir = Path.Combine(Paths.BepInExRootPath, "HitSounds", 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";

		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> Volume { get; set; }

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

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

		public ConfigEntry<bool> SyncWithSong { 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
			};
			Volume = val.Bind<float>("General", "Volume", 1f, "Volume of the hitsounds.");
			HitSoundName = val.Bind<string>("General", "HitSoundName", "None", "Name of the hitsound 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.");
			string text2 = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Instance).Info.Location), "HitSounds");
			string text3 = Path.Combine(Paths.BepInExRootPath, "HitSounds");
			FileHelper.TryMigrateFolder(text2, text3, false);
			settingPage = TootTallySettingsManager.AddNewPage((TootTallySettingPage)(object)new CustomHitSoundSettingPage());
			Plugin.TryAddThunderstoreIconToPageButton(((BaseUnityPlugin)Instance).Info.Location, Name, settingPage);
			_harmony.PatchAll(typeof(HitSoundPatches));
			LogInfo("Module loaded!");
		}

		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.2";
	}
}