Decompiled source of CustomBoombox v1.0.1

BoomboxSounds.dll

Decompiled a month 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
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("BoomboxSounds")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BoomboxSounds")]
[assembly: AssemblyTitle("BoomboxSounds")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BoomboxSounds
{
	[BepInPlugin("BoomboxSounds", "BoomboxSounds", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginId = "mattcy.bg.boombox";

		public const string PluginName = "Boombox Sounds";

		public const string Version = "1.0.1";

		internal static ManualLogSource Logger;

		private Harmony harmony;

		public static List<AudioClip> ClipsLoaded = new List<AudioClip>();

		public static string ClipsFolder;

		public static AudioClip currentClip = null;

		public static AudioSource source = null;

		public static int index = 0;

		private static TMP_FontAsset _cachedFont;

		private Canvas hudCanvas;

		private TextMeshProUGUI hudText;

		private bool hudInitialized = false;

		public static Plugin Instance { get; private set; }

		public static ConfigEntry<KeyboardShortcut> ReloadSounds { get; set; }

		public static ConfigEntry<KeyboardShortcut> ChangeMusic { get; set; }

		public static ConfigEntry<bool> ChangeJonathanMusic { get; set; }

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			ClipsFolder = Path.Combine(Paths.PluginPath, "BoomboxCustomSounds");
			ReloadSounds = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Config", "Reload Songs", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), (ConfigDescription)null);
			ChangeMusic = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Config", "Change Music", new KeyboardShortcut((KeyCode)121, Array.Empty<KeyCode>()), (ConfigDescription)null);
			ChangeJonathanMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Change Jonathan Music", true, (ConfigDescription)null);
			if (!Directory.Exists(ClipsFolder))
			{
				Directory.CreateDirectory(ClipsFolder);
			}
			LoadAllCustomSounds();
			harmony = new Harmony("BoomboxSounds");
			harmony.PatchAll(typeof(Plugin).Assembly);
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = ReloadSounds.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				ReloadSongs();
			}
			value = ChangeMusic.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				SwicthCurrentMusic();
			}
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)hudCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)hudCanvas).gameObject);
			}
		}

		public void ShowText(string text, float duration)
		{
			if (!hudInitialized)
			{
				InitHUD();
			}
			if (!((Object)(object)hudText == (Object)null))
			{
				((MonoBehaviour)this).StopAllCoroutines();
				((MonoBehaviour)this).StartCoroutine(FadeTextRoutine(text, duration));
			}
		}

		private IEnumerator FadeTextRoutine(string text, float duration)
		{
			((TMP_Text)hudText).text = text;
			Color color = ((Graphic)hudText).color;
			color.a = 1f;
			((Graphic)hudText).color = color;
			yield return (object)new WaitForSeconds(duration);
			while (color.a > 0f)
			{
				float delta = Time.deltaTime * 2f;
				color.a -= delta;
				((Graphic)hudText).color = color;
				yield return null;
			}
			((TMP_Text)hudText).text = "";
		}

		private static TMP_FontAsset GetGameFont()
		{
			if ((Object)(object)_cachedFont != (Object)null)
			{
				return _cachedFont;
			}
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			TMP_FontAsset[] array2 = array;
			foreach (TMP_FontAsset val in array2)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == "Zyzol SDF")
				{
					_cachedFont = val;
					Logger.LogInfo((object)("[Boombox Sounds] Font found: " + ((Object)val).name));
					return _cachedFont;
				}
			}
			TMP_FontAsset[] array3 = array;
			foreach (TMP_FontAsset val2 in array3)
			{
				if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "LiberationSans SDF")
				{
					_cachedFont = val2;
					Logger.LogWarning((object)("[Boombox Sounds] Zyzol not found, fallback: " + ((Object)val2).name));
					return _cachedFont;
				}
			}
			_cachedFont = TMP_Settings.defaultFontAsset;
			return _cachedFont;
		}

		private void InitHUD()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BoomboxNotificationHUD");
			Object.DontDestroyOnLoad((Object)(object)val);
			hudCanvas = val.AddComponent<Canvas>();
			hudCanvas.renderMode = (RenderMode)0;
			hudCanvas.sortingOrder = 100;
			val.AddComponent<CanvasScaler>();
			CanvasGroup val2 = val.AddComponent<CanvasGroup>();
			val2.blocksRaycasts = false;
			val2.interactable = false;
			GameObject val3 = new GameObject("BoomboxNotificationText");
			val3.transform.SetParent(val.transform, false);
			hudText = val3.AddComponent<TextMeshProUGUI>();
			((TMP_Text)hudText).fontSize = 60f;
			((TMP_Text)hudText).fontStyle = (FontStyles)1;
			((TMP_Text)hudText).alignment = (TextAlignmentOptions)1028;
			((Graphic)hudText).color = new Color(1f, 1f, 1f, 0f);
			((TMP_Text)hudText).overflowMode = (TextOverflowModes)0;
			((Graphic)hudText).raycastTarget = false;
			TMP_FontAsset gameFont = GetGameFont();
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)hudText).font = gameFont;
				((TMP_Text)hudText).fontSharedMaterial = ((TMP_Asset)gameFont).material;
			}
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0f);
			component.anchorMax = new Vector2(0.5f, 0f);
			component.pivot = new Vector2(0.5f, 0f);
			component.sizeDelta = new Vector2((float)Screen.width * 0.9f, 200f);
			component.anchoredPosition = new Vector2(0f, 300f);
			((TMP_Text)hudText).text = "";
			hudInitialized = true;
		}

		private void ReloadSongs()
		{
			ClipsLoaded.Clear();
			LoadAllCustomSounds();
		}

		private void PlayNewSong()
		{
			if (!((Object)(object)source == (Object)null))
			{
				if ((Object)(object)source.clip != (Object)(object)currentClip)
				{
					source.clip = currentClip;
				}
				source.Stop();
				source.Play();
			}
		}

		private void SwicthCurrentMusic()
		{
			if (ClipsLoaded.Count != 0)
			{
				index = (index + 1) % ClipsLoaded.Count;
				currentClip = ClipsLoaded[index];
				ShowText("Now Playing - " + ((Object)currentClip).name, 2f);
				PlayNewSong();
			}
		}

		private void LoadAllCustomSounds()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			string[] array = (from f in Directory.GetFiles(ClipsFolder, "*.*")
				where f.EndsWith(".wav", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)
				select f).ToArray();
			Array.Sort(array);
			string[] array2 = array;
			foreach (string text in array2)
			{
				AudioType audioType = GetAudioType(text);
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file://" + text, audioType);
				try
				{
					audioClip.SendWebRequest();
					while (!audioClip.isDone)
					{
					}
					if ((int)audioClip.result == 1)
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
						((Object)content).name = Path.GetFileNameWithoutExtension(text);
						ClipsLoaded.Add(content);
						Logger.LogInfo((object)$"Loaded Clip: {((Object)content).name} ({audioType})");
					}
					else
					{
						Logger.LogError((object)("Failed to load clip " + Path.GetFileName(text) + ": " + audioClip.error));
					}
				}
				finally
				{
					((IDisposable)audioClip)?.Dispose();
				}
			}
			Logger.LogInfo((object)$"Total clips loaded: {ClipsLoaded.Count}");
		}

		private AudioType GetAudioType(string filePath)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(filePath).ToLower();
			string text2 = text;
			string text3 = text2;
			if (text3 == ".mp3")
			{
				return (AudioType)13;
			}
			return (AudioType)20;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "BoomboxSounds";

		public const string PLUGIN_NAME = "BoomboxSounds";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace BoomboxSounds.Patches
{
	[HarmonyPatch(typeof(PlayerController), "OnEquipped")]
	internal static class InventoryOnNetworkSpawnPatch
	{
		private static void Postfix(InventoryBase __instance, string name)
		{
			if (!(name == "music box") || Plugin.ClipsLoaded.Count <= 0)
			{
				return;
			}
			AudioSource componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<AudioSource>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Plugin.source = componentInChildren;
				if ((Object)(object)Plugin.currentClip == (Object)null)
				{
					Plugin.currentClip = Plugin.ClipsLoaded[Plugin.index];
				}
				if ((Object)(object)componentInChildren.clip != (Object)(object)Plugin.currentClip)
				{
					componentInChildren.clip = Plugin.currentClip;
				}
				Plugin.Instance.ShowText("Now Playing - " + ((Object)Plugin.currentClip).name, 2f);
				componentInChildren.Play();
			}
		}
	}
	[HarmonyPatch]
	internal static class OnSpawnedPrivatePatch
	{
		[HarmonyTargetMethod]
		private static MethodBase TargetMethod()
		{
			Type nestedType = typeof(AiDirector).GetNestedType("RuntimeEntityCollection", BindingFlags.Public | BindingFlags.NonPublic);
			if (nestedType == null)
			{
				return null;
			}
			return nestedType.GetMethod("OnSpawned", BindingFlags.Instance | BindingFlags.NonPublic);
		}

		[HarmonyPostfix]
		private static void Postfix(object __instance, object instance)
		{
			if (instance == null)
			{
				return;
			}
			PropertyInfo property = instance.GetType().GetProperty("gameObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(property != null))
			{
				return;
			}
			object? value = property.GetValue(instance);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			GameEntityAI component = val.GetComponent<GameEntityAI>();
			if (!((Object)(object)component != (Object)null) || !(((Object)((GameEntityBase)component).EntityData).name == "Jonathan") || !Plugin.ChangeJonathanMusic.Value || Plugin.ClipsLoaded.Count <= 0)
			{
				return;
			}
			Transform val2 = val.transform.Find("jonathan_unity/Armature/boombox/Boombox/GameObject");
			if ((Object)(object)val2 != (Object)null)
			{
				AudioSource component2 = ((Component)val2).GetComponent<AudioSource>();
				if ((Object)(object)component2 != (Object)null)
				{
					int index = Random.Range(0, Plugin.ClipsLoaded.Count);
					component2.Stop();
					component2.clip = Plugin.ClipsLoaded[index];
					component2.Play();
				}
			}
			else
			{
				Plugin.Logger.LogInfo((object)"Didn't find Boombox!");
			}
		}
	}
}