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 ClipsLoaded = new List(); 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 ReloadSounds { get; set; } public static ConfigEntry ChangeMusic { get; set; } public static ConfigEntry 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("Config", "Reload Songs", new KeyboardShortcut((KeyCode)114, Array.Empty()), (ConfigDescription)null); ChangeMusic = ((BaseUnityPlugin)this).Config.Bind("Config", "Change Music", new KeyboardShortcut((KeyCode)121, Array.Empty()), (ConfigDescription)null); ChangeJonathanMusic = ((BaseUnityPlugin)this).Config.Bind("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[] 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(); hudCanvas.renderMode = (RenderMode)0; hudCanvas.sortingOrder = 100; val.AddComponent(); CanvasGroup val2 = val.AddComponent(); val2.blocksRaycasts = false; val2.interactable = false; GameObject val3 = new GameObject("BoomboxNotificationText"); val3.transform.SetParent(val.transform, false); hudText = val3.AddComponent(); ((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(); 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(); 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(); 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(); 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!"); } } } }