using System; using System.Collections; 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.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("ShopMusicMPFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ShopMusicMPFix")] [assembly: AssemblyTitle("ShopMusicMPFix")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ShopMusicMPFix { [BepInPlugin("themorningstar.shopmusicmpfix", "Shop Music MP Fix", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "themorningstar.shopmusicmpfix"; internal static ManualLogSource Log; internal static string? SoundsPath; private void Awake() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; SoundsPath = FindRandomMusicShopSoundsPath(); if (SoundsPath != null) { Log.LogInfo((object)("[ShopMusicMPFix] Found RandomMusicShop sounds folder: " + SoundsPath)); int num = Directory.GetFiles(SoundsPath, "*_Shop.ogg").Length; Log.LogInfo((object)$"[ShopMusicMPFix] {num} *_Shop.ogg tracks available."); } else { Log.LogWarning((object)"[ShopMusicMPFix] RandomMusicShop sounds/ folder not found. Mod will load but won't replace any music. Make sure bazou-RandomMusicShop is installed."); } try { new Harmony("themorningstar.shopmusicmpfix").PatchAll(); Log.LogInfo((object)"[ShopMusicMPFix] Harmony patches applied."); } catch (Exception ex) { Log.LogError((object)("[ShopMusicMPFix] Failed to apply Harmony patches: " + ex)); } } private static string? FindRandomMusicShopSoundsPath() { string text = SearchForSoundsDir(Paths.PluginPath); if (text != null) { return text; } string text2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "com.kesomannen.gale", "cache", "bazou-RandomMusicShop"); if (Directory.Exists(text2)) { text = SearchForSoundsDir(text2, 8); if (text != null) { return text; } } return null; } private static string? SearchForSoundsDir(string root, int maxDepth = 4) { if (!Directory.Exists(root)) { return null; } try { return Directory.EnumerateDirectories(root, "sounds", SearchOption.AllDirectories).FirstOrDefault((string dir) => dir.Substring(root.Length).Count((char c) => c == Path.DirectorySeparatorChar || c == '/') <= maxDepth && Directory.GetFiles(dir, "*_Shop.ogg").Length != 0); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[ShopMusicMPFix] Error searching for sounds dir: " + ex.Message)); } return null; } } } [HarmonyPatch(typeof(ShopRadio), "Start")] internal static class ShopRadio_Start_Patch { private static void Postfix(ShopRadio __instance) { if (Plugin.SoundsPath != null) { ((MonoBehaviour)__instance).StartCoroutine(ReplaceShopMusicClip(__instance)); } } internal static IEnumerator ReplaceShopMusicClip(ShopRadio radio) { yield return null; yield return null; string[] files; try { files = Directory.GetFiles(Plugin.SoundsPath, "*_Shop.ogg"); } catch (Exception ex) { Plugin.Log.LogError((object)("[ShopMusicMPFix] Error listing ogg files: " + ex.Message)); yield break; } if (files.Length == 0) { Plugin.Log.LogWarning((object)("[ShopMusicMPFix] No *_Shop.ogg files found in: " + Plugin.SoundsPath)); yield break; } string chosenFile = files[Random.Range(0, files.Length)]; string text = "file:///" + chosenFile.Replace('\\', '/'); Plugin.Log.LogInfo((object)("[ShopMusicMPFix] Loading: " + Path.GetFileNameWithoutExtension(chosenFile))); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14); try { yield return www.SendWebRequest(); if ((int)www.result != 1) { Plugin.Log.LogError((object)("[ShopMusicMPFix] Failed to load " + chosenFile + ": " + www.error)); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(www); if ((Object)(object)content == (Object)null) { Plugin.Log.LogError((object)"[ShopMusicMPFix] DownloadHandlerAudioClip returned null."); yield break; } ((Object)content).name = Path.GetFileNameWithoutExtension(chosenFile); if ((Object)(object)radio == (Object)null || radio.shopMusic == null || (Object)(object)radio.shopMusic.Source == (Object)null) { Plugin.Log.LogWarning((object)"[ShopMusicMPFix] ShopRadio or shopMusic.Source was destroyed before clip load finished."); yield break; } radio.shopMusic.Sounds = (AudioClip[])(object)new AudioClip[1] { content }; radio.shopMusic.AudioInfoFetched = false; radio.shopMusic.Source.Stop(); Plugin.Log.LogInfo((object)("[ShopMusicMPFix] Now playing: " + ((Object)content).name)); } finally { ((IDisposable)www)?.Dispose(); } } } [HarmonyPatch(typeof(ShopRadio), "PlayNewClipRPC")] internal static class ShopRadio_PlayNewClipRPC_Patch { private static void Postfix(ShopRadio __instance) { if (Plugin.SoundsPath != null) { ((MonoBehaviour)__instance).StartCoroutine(ReplaceAfterHit(__instance)); } } private static IEnumerator ReplaceAfterHit(ShopRadio radio) { yield return null; if (Plugin.SoundsPath == null) { yield break; } string[] files; try { files = Directory.GetFiles(Plugin.SoundsPath, "*_Shop.ogg"); } catch { yield break; } if (files.Length == 0) { yield break; } string chosenFile = files[Random.Range(0, files.Length)]; string text = "file:///" + chosenFile.Replace('\\', '/'); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14); try { yield return www.SendWebRequest(); if ((int)www.result != 1) { yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(www); if (!((Object)(object)content == (Object)null)) { ((Object)content).name = Path.GetFileNameWithoutExtension(chosenFile); if (!((Object)(object)radio == (Object)null) && radio.shopMusic != null && !((Object)(object)radio.shopMusic.Source == (Object)null)) { radio.shopMusic.Sounds = (AudioClip[])(object)new AudioClip[1] { content }; radio.shopMusic.AudioInfoFetched = false; radio.shopMusic.Source.Stop(); Plugin.Log.LogInfo((object)("[ShopMusicMPFix] (hit) Now playing: " + ((Object)content).name)); } } } finally { ((IDisposable)www)?.Dispose(); } } } [HarmonyPatch(typeof(ShopRadio), "RandomClipOnAwakeRPC")] internal static class ShopRadio_RandomClipOnAwakeRPC_Patch { private static void Postfix(ShopRadio __instance) { if (Plugin.SoundsPath != null) { ((MonoBehaviour)__instance).StartCoroutine(ShopRadio_Start_Patch.ReplaceShopMusicClip(__instance)); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }