Please disclose if your mod was created primarily 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 Boombox Playlists v1.0.1
BoomboxPlaylists.dll
Decompiled 2 years 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.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BoomboxPlaylists.Managers; using HarmonyLib; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BoomboxPlaylists")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BoomboxPlaylists")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("020a0457-0d96-492e-ad0f-548bc97b9557")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace BoomboxPlaylists { [BepInPlugin("Batres3.BoomboxPlaylists", "Boombox Playlists", "1.0.0")] public class BoomboxPlaylistsBase : BaseUnityPlugin { private const string modGUID = "Batres3.BoomboxPlaylists"; private const string modName = "Boombox Playlists"; private const string modVersion = "1.0.0"; private readonly Harmony harmony = new Harmony("Batres3.BoomboxPlaylists"); private static BoomboxPlaylistsBase Instance; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } if (!Directory.Exists(Path.Combine(Paths.BepInExRootPath, "Custom Playlists"))) { Directory.CreateDirectory(Path.Combine(Paths.BepInExRootPath, "Custom Playlists")); LogError("No custom playlists detected, they must be in the 'Custom Playlists' folder"); } else { harmony.PatchAll(); AudioManager.Load(); LogInfo("Boombox Playlists Loaded!"); } } internal static void LogInfo(string message) { Instance.Log(message, (LogLevel)16); } internal static void LogError(string message) { Instance.Log(message, (LogLevel)2); } private void Log(string message, LogLevel logLevel) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.Log(logLevel, (object)message); } } } namespace BoomboxPlaylists.Utils { internal class SharedCoroutineStarter : MonoBehaviour { private static SharedCoroutineStarter _instance; public static Coroutine StartCoroutine(IEnumerator routine) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_instance == (Object)null) { _instance = new GameObject("Shared Coroutine Starter").AddComponent<SharedCoroutineStarter>(); Object.DontDestroyOnLoad((Object)(object)_instance); } return ((MonoBehaviour)_instance).StartCoroutine(routine); } } } namespace BoomboxPlaylists.Patches { [HarmonyPatch(typeof(BoomboxItem))] internal class BoomboxItemPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start_Postfix(BoomboxItem __instance) { if (AudioManager.finishedLoading) { AudioManager.ApplyClips(ref __instance); return; } AudioManager.OnAllSongsLoaded += delegate { AudioManager.ApplyClips(ref __instance); }; AudioManager.SetTooltip(ref __instance); } [HarmonyPatch("StartMusic")] [HarmonyPostfix] private static void StartMusic_Postfix(BoomboxItem __instance, bool startMusic) { AudioManager.SetVolume(ref __instance); AudioManager.NextSong(ref __instance, ref startMusic); } [HarmonyPatch("PocketItem")] [HarmonyPostfix] private static void PocketItem_Postfix(BoomboxItem __instance) { AudioManager.ApplyClips(ref __instance); AudioManager.SetTooltip(ref __instance); } [HarmonyPatch("Update")] [HarmonyPostfix] private static void Update_Postfix(BoomboxItem __instance) { if (((GrabbableObject)__instance).isHeld) { if (((KeyboardShortcut)(ref AudioManager.lowerVolume)).IsPressed()) { AudioManager.ModifyVolume(increase: false, ref __instance); } else if (((KeyboardShortcut)(ref AudioManager.increaseVolume)).IsPressed()) { AudioManager.ModifyVolume(increase: true, ref __instance); } } } } } namespace BoomboxPlaylists.Managers { internal static class AudioManager { public static List<PlaylistManager> playlistManagers = new List<PlaylistManager>(); public static int currentPlaylistID; public static bool finishedLoading = false; public static int currentSongID = 0; private static readonly string directory = Path.Combine(Paths.BepInExRootPath, "Custom Playlists"); private static readonly string[] defaultTooltip = new string[3] { "Toggle Music : [LMB]", "Playlist : ", "Change Volume : [Ctrl]+[Shift]+[K]/[J]" }; private static KeyCode[] conditionKeys = (KeyCode[])(object)new KeyCode[2] { (KeyCode)304, (KeyCode)306 }; public static KeyboardShortcut lowerVolume = new KeyboardShortcut((KeyCode)106, conditionKeys); public static KeyboardShortcut increaseVolume = new KeyboardShortcut((KeyCode)107, conditionKeys); public static float volume = 1f; public static event Action OnAllSongsLoaded; public static void Load() { if (playlistManagers.Count != 0) { return; } string[] array = Directory.GetDirectories(directory).Select(Path.GetFileName).ToArray(); if (array.Length == 0) { BoomboxPlaylistsBase.LogError("No playlists detected"); return; } string[] array2 = array; foreach (string playlistname in array2) { playlistManagers.Add(new PlaylistManager(playlistname)); } int num = 0; foreach (PlaylistManager playlistManager in playlistManagers) { array2 = playlistManager.playlistSongsPaths; for (int i = 0; i < array2.Length; i++) { LoadAudioClip(array2[i], num); } BoomboxPlaylistsBase.LogInfo("Loaded playlist " + playlistManager.playlistName); num++; } } private static void LoadAudioClip(string filePath, int playlistID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 if ((int)GetAudioType(filePath) == 0) { BoomboxPlaylistsBase.LogError("Failed to load AudioClip from " + filePath + "!"); return; } UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(filePath, GetAudioType(filePath)); audioClip.SendWebRequest(); while (!audioClip.isDone) { } if (audioClip.error != null) { BoomboxPlaylistsBase.LogError("Error loading clip from path: " + filePath); BoomboxPlaylistsBase.LogError(audioClip.error); return; } AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip); if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2) { ((Object)content).name = Path.GetFileName(filePath); BoomboxPlaylistsBase.LogInfo("Loaded song " + ((Object)content).name); playlistManagers[playlistID].clips.Add(content); } else { BoomboxPlaylistsBase.LogError("Failed to load clip at: " + filePath + "\nThis might be due to an mismatch between the audio codec and the file extension!"); } } private static IEnumerator WaitForAllClips(List<Coroutine> coroutines, int playlistID) { foreach (Coroutine coroutine in coroutines) { yield return coroutine; } playlistManagers[playlistID].clips.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name)); finishedLoading = true; AudioManager.OnAllSongsLoaded?.Invoke(); AudioManager.OnAllSongsLoaded = null; } private static AudioType GetAudioType(string filePath) { string extension = Path.GetExtension(filePath); switch (extension) { case ".wav": return (AudioType)20; case ".ogg": return (AudioType)14; case ".mp3": return (AudioType)13; default: BoomboxPlaylistsBase.LogError("Unsupported extesion type: " + extension); return (AudioType)0; } } public static void ApplyClips(ref BoomboxItem __istance) { currentPlaylistID++; if (currentPlaylistID >= playlistManagers.Count) { currentPlaylistID = 0; } currentSongID = 0; __istance.musicAudios = playlistManagers[currentPlaylistID].clips.ToArray(); } public static void SetTooltip(ref BoomboxItem __instance) { string[] array = new string[3]; Array.Copy(defaultTooltip, array, defaultTooltip.Length); array[1] += playlistManagers[currentPlaylistID].playlistName; ((GrabbableObject)__instance).itemProperties.toolTips = array; } public static void ModifyVolume(bool increase, ref BoomboxItem __instance) { if (increase) { volume = Mathf.Clamp(volume + 0.01f, 0f, 1f); SetVolume(ref __instance); } else { volume = Mathf.Clamp(volume - 0.01f, 0f, 1f); SetVolume(ref __instance); } } public static void SetVolume(ref BoomboxItem __instance) { __instance.boomboxAudio.volume = volume; } public static void NextSong(ref BoomboxItem __instance, ref bool startMusic) { if (startMusic) { currentSongID++; if (currentSongID >= playlistManagers[currentPlaylistID].clips.Count) { currentSongID = 0; } __instance.boomboxAudio.clip = __instance.musicAudios[currentSongID]; __instance.boomboxAudio.pitch = 1f; __instance.boomboxAudio.Play(); startMusic = false; } } } internal class PlaylistManager { public string[] playlistSongsPaths; public List<AudioClip> clips = new List<AudioClip>(); private readonly string playlistPath; public string playlistName; public bool hasNoSongs => playlistSongsPaths.Length == 0; internal PlaylistManager(string playlistname) { playlistName = playlistname; playlistPath = Path.Combine(Paths.BepInExRootPath, "Custom Playlists", playlistName); playlistSongsPaths = Directory.GetFiles(playlistPath); if (hasNoSongs) { BoomboxPlaylistsBase.LogError("No songs found for playlist " + playlistName); } } } }