Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MusicCenterMusicReplacer v0.1.0
BepInEx\plugins\MusicCenterMusicReplacer\MusicCenterMusicReplacer.dll
Decompiled 13 hours agousing 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 BepInEx; using BepInEx.Configuration; 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: AssemblyCompany("MusicCenterMusicReplacer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("MusicCenterMusicReplacer")] [assembly: AssemblyTitle("MusicCenterMusicReplacer")] [assembly: AssemblyVersion("0.1.0.0")] [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 MusicCenterMusicReplacer { internal static class AudioFileLoader { internal static IEnumerator LoadFromPluginFolder(string fileName, Action<AudioClip?> onLoaded) { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrWhiteSpace(directoryName)) { Plugin.Log.LogError((object)"Could not determine the plugin directory."); onLoaded(null); yield break; } string fullPath = Path.Combine(directoryName, fileName); if (!File.Exists(fullPath)) { Plugin.Log.LogWarning((object)("Music file not found: " + fullPath)); Plugin.Log.LogWarning((object)"Place boombox.ogg, boombox.wav or boombox.mp3 next to the DLL."); onLoaded(null); yield break; } AudioType audioType = GetAudioType(Path.GetExtension(fullPath)); if ((int)audioType == 0) { Plugin.Log.LogError((object)("Unsupported audio extension: " + Path.GetExtension(fullPath))); onLoaded(null); yield break; } string absoluteUri = new Uri(fullPath).AbsoluteUri; UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, audioType); try { yield return request.SendWebRequest(); if ((int)request.result != 1) { Plugin.Log.LogError((object)("Could not load music: " + request.error)); onLoaded(null); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)content == (Object)null) { Plugin.Log.LogError((object)"Unity returned an empty AudioClip."); onLoaded(null); } else { ((Object)content).name = "MusicCenter_" + Path.GetFileNameWithoutExtension(fullPath); Plugin.Log.LogInfo((object)$"Music loaded: {Path.GetFileName(fullPath)} ({content.length:0.00}s)."); onLoaded(content); } } finally { ((IDisposable)request)?.Dispose(); } } private static AudioType GetAudioType(string extension) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) return (AudioType)(extension.ToLowerInvariant() switch { ".ogg" => 14, ".wav" => 20, ".mp3" => 13, _ => 0, }); } } [BepInPlugin("com.artem.musiccentermusicreplacer", "Music Center Music Replacer", "0.1.0")] [BepInProcess("REPO.exe")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.artem.musiccentermusicreplacer"; public const string PluginName = "Music Center Music Replacer"; public const string PluginVersion = "0.1.0"; private static readonly HashSet<Sound> BoomboxSounds = new HashSet<Sound>(); private ConfigEntry<bool> _enabled; private ConfigEntry<string> _audioFileName; private ConfigEntry<bool> _forceLoop; private AudioClip? _replacementClip; private Harmony? _harmony; internal static Plugin? Instance { get; private set; } internal static ManualLogSource Log { get; private set; } = null; private void Awake() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enables replacement of the Museum Boombox / music center track."); _audioFileName = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "AudioFileName", "boombox.ogg", "Audio file placed next to the DLL. Supported: .ogg, .wav and .mp3."); _forceLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Playback", "ForceLoop", true, "Loops the custom track while the boombox is being held."); _harmony = new Harmony("com.artem.musiccentermusicreplacer"); _harmony.PatchAll(); ((MonoBehaviour)this).StartCoroutine(AudioFileLoader.LoadFromPluginFolder(_audioFileName.Value, OnReplacementLoaded)); Log.LogInfo((object)"Music Center Music Replacer v0.1.0 loaded."); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } BoomboxSounds.Clear(); Instance = null; } private void OnReplacementLoaded(AudioClip? clip) { _replacementClip = clip; if (!((Object)(object)clip == (Object)null)) { ValuableBoombox[] array = Resources.FindObjectsOfTypeAll<ValuableBoombox>(); for (int i = 0; i < array.Length; i++) { RegisterBoombox(array[i]); } } } internal static void RegisterBoombox(ValuableBoombox? boombox) { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)boombox == (Object)null) && boombox.soundBoomboxMusic != null) { Sound soundBoomboxMusic = boombox.soundBoomboxMusic; BoomboxSounds.Add(soundBoomboxMusic); instance.ApplyReplacement(soundBoomboxMusic, restartIfPlaying: true); } } private void ApplyReplacement(Sound sound, bool restartIfPlaying) { AudioClip replacementClip = _replacementClip; if (!_enabled.Value || (Object)(object)replacementClip == (Object)null) { return; } AudioSource source = sound.Source; bool flag = (Object)(object)source != (Object)null && source.isPlaying; sound.Sounds = (AudioClip[])(object)new AudioClip[1] { replacementClip }; if ((Object)(object)source != (Object)null) { source.loop = _forceLoop.Value; if (restartIfPlaying && flag) { source.Stop(); source.clip = replacementClip; source.time = 0f; source.Play(); Log.LogInfo((object)"[MUSIC START] Music center restarted from 0:00."); } } } internal static void BeforeSoundPlay(Sound? sound) { Plugin instance = Instance; if ((Object)(object)instance == (Object)null || sound == null || !BoomboxSounds.Contains(sound)) { return; } AudioClip replacementClip = instance._replacementClip; if (instance._enabled.Value && !((Object)(object)replacementClip == (Object)null)) { sound.Sounds = (AudioClip[])(object)new AudioClip[1] { replacementClip }; AudioSource source = sound.Source; if ((Object)(object)source != (Object)null) { source.Stop(); source.clip = replacementClip; source.time = 0f; source.loop = instance._forceLoop.Value; } } } internal static void AfterSoundPlay(Sound? sound) { Plugin instance = Instance; if ((Object)(object)instance == (Object)null || sound == null || !BoomboxSounds.Contains(sound)) { return; } AudioClip replacementClip = instance._replacementClip; if (!instance._enabled.Value || (Object)(object)replacementClip == (Object)null) { return; } AudioSource source = sound.Source; if (!((Object)(object)source == (Object)null)) { source.clip = replacementClip; source.loop = instance._forceLoop.Value; source.time = 0f; if (!source.isPlaying) { source.Play(); } Log.LogInfo((object)"[MUSIC START] Music center started from 0:00."); } } } [HarmonyPatch(typeof(ValuableBoombox), "Start")] internal static class ValuableBoomboxStartPatch { private static void Postfix(ValuableBoombox __instance) { Plugin.RegisterBoombox(__instance); } } [HarmonyPatch] internal static class BoomboxSoundPlayPatch { private static IEnumerable<MethodBase> TargetMethods() { return from method in AccessTools.GetDeclaredMethods(typeof(Sound)) where method.Name == "Play" select method; } private static void Prefix(Sound __instance) { Plugin.BeforeSoundPlay(__instance); } private static void Postfix(Sound __instance) { Plugin.AfterSoundPlay(__instance); } } }