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 MoreMusicMod v1.0.2
plugins/MoreMusicMod.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.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using MoreMusicMod.Configuration; using MoreMusicMod.Helpers; using MoreMusicMod.Patches; using MoreMusicMod.Services; using UnityEngine; using UnityEngine.Networking; [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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("MoreMusicMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2+f861f30b8f892d1b09eb0702dc5bc81a0c4a9fa7")] [assembly: AssemblyProduct("MoreMusicMod")] [assembly: AssemblyTitle("MoreMusicMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 MoreMusicMod { [BepInPlugin("georgebjork.MoreMusicMod", "MoreMusicMod", "1.0.2")] public class Plugin : BaseUnityPlugin { private const string Guid = "georgebjork.MoreMusicMod"; private const string Name = "MoreMusicMod"; private const string Version = "1.0.2"; private static Plugin _instance; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown _instance = this; ResourceLoaderService.GenerateFolders(); Harmony val = new Harmony("georgebjork.MoreMusicMod"); val.PatchAll(typeof(BoomboxPatch)); val.PatchAll(typeof(StartUp)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin georgebjork.MoreMusicMod is loaded!"); } internal static void LogDebug(string message) { _instance.Log(message, (LogLevel)32); } internal static void LogInfo(string message) { _instance.Log(message, (LogLevel)16); } internal static void LogWarning(string message) { _instance.Log(message, (LogLevel)4); } internal static void LogError(string message) { _instance.Log(message, (LogLevel)2); } internal static void LogError(Exception ex) { _instance.Log(ex.Message + "\n" + ex.StackTrace, (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); } } public static class PluginInfo { public const string PLUGIN_GUID = "MoreMusicMod"; public const string PLUGIN_NAME = "MoreMusicMod"; public const string PLUGIN_VERSION = "1.0.2"; } } namespace MoreMusicMod.Services { public class AudioLoaderService : BaseService { private static readonly List<AudioClip> _clips = new List<AudioClip>(); private static string[] _songs_at_directory; public static bool IsLoaded = false; public static bool UseDefaultSongs => !IsLoaded && _songs_at_directory.Length == 0; public static int ClipsLength => _clips.Count; public static event Action AllSongsLoaded; public static void LoadAllSongs() { GetFilesAtDirectory(); Plugin.LogInfo("Attempting to load songs..."); try { List<IEnumerator> list = new List<IEnumerator>(); string[] songs_at_directory = _songs_at_directory; foreach (string filePath in songs_at_directory) { list.Add(LoadAudioClip(filePath)); } BaseService.HandleCoroutineList(list, OnAllSongsLoaded); } catch (Exception arg) { Plugin.LogError($"There was an error loading audio tracks. Exception: {arg}"); } } private static void GetFilesAtDirectory() { if (!IsLoaded) { _songs_at_directory = Directory.GetFiles(BaseService._music_directory); if (_songs_at_directory.Length == 0) { Plugin.LogWarning("No songs where found at " + BaseService._music_directory); } else { Plugin.LogInfo("Songs found!"); } } } private static IEnumerator LoadAudioClip(string filePath) { Plugin.LogInfo("Loading track: " + Path.GetFileName(filePath)); AudioType audioType = AudioHelper.GetAudioType(filePath); if ((int)audioType == 0) { Plugin.LogError("Failed to load AudioClip from " + filePath + ". Unsupported file extension. Supported types are: MPEG, WAV, and OGGVORBIS "); yield break; } AudioClip clip = StreamAudioClipFromDisk(filePath, audioType); if (clip != null) { ((Object)clip).name = Path.GetFileName(filePath); _clips.Add(clip); Plugin.LogInfo("Clip added."); } } private static AudioClip StreamAudioClipFromDisk(string filePath, AudioType audioType) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(filePath, audioType); try { ((DownloadHandlerAudioClip)audioClip.downloadHandler).streamAudio = true; audioClip.timeout = 10; audioClip.SendWebRequest(); while (!audioClip.isDone) { if (audioClip.error == null || audioClip.timeout <= 10) { continue; } Plugin.LogError("Error loading clip: " + Path.GetFileName(filePath) + ": " + audioClip.error); return null; } return DownloadHandlerAudioClip.GetContent(audioClip); } finally { ((IDisposable)audioClip)?.Dispose(); } } public static void AddClips(BoomboxItem __instance) { Plugin.LogInfo("Adding clips!"); __instance.musicAudios = (UseDefaultSongs ? __instance.musicAudios.Concat(_clips).ToArray() : _clips.ToArray()); Plugin.LogInfo($"{_clips.Count}/{_songs_at_directory.Length} where loaded!!"); } private static void OnAllSongsLoaded() { AudioLoaderService.AllSongsLoaded?.Invoke(); AudioLoaderService.AllSongsLoaded = null; IsLoaded = true; } } public class BaseService : MonoBehaviour { private static BaseService _instance; protected static readonly string _music_directory = Path.Combine(Paths.BepInExRootPath, Settings.PLUGINS_DIRECTORY, Settings.SONGS_FOLDER); protected static readonly string _plugins_directory = Path.Combine(Paths.BepInExRootPath, Settings.PLUGINS_DIRECTORY); private static readonly List<Coroutine> _active_coroutines = new List<Coroutine>(); protected static Coroutine StartCoroutine(IEnumerator routine) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_instance != (Object)null) { return ((MonoBehaviour)_instance).StartCoroutine(routine); } _instance = new GameObject("Shared Coroutine Starter").AddComponent<BaseService>(); Object.DontDestroyOnLoad((Object)(object)_instance); return ((MonoBehaviour)_instance).StartCoroutine(routine); } protected static void HandleCoroutineList(List<IEnumerator> coroutines, Action onComplete) { StartCoroutine(RunCoroutineList(coroutines, onComplete)); } private static IEnumerator RunCoroutineList(List<IEnumerator> coroutineList, Action onComplete) { foreach (IEnumerator routine in coroutineList) { Coroutine rv = StartCoroutine(routine); _active_coroutines.Add(rv); } foreach (Coroutine active_coroutine in _active_coroutines) { yield return active_coroutine; } _active_coroutines.Clear(); Plugin.LogInfo($"ALL DONE!! {_active_coroutines.Count}"); onComplete?.Invoke(); } } public class ResourceLoaderService : BaseService { public static void GenerateFolders() { try { if (Directory.Exists(BaseService._music_directory)) { Plugin.LogInfo("Directory already exists at: " + BaseService._music_directory); return; } Directory.CreateDirectory(BaseService._music_directory); Plugin.LogInfo("Directory created at: " + BaseService._music_directory); CheckFoldersForMusicDirectory(); } catch (Exception ex) { Plugin.LogError(ex); Plugin.LogError("Something went wrong. Unable to create directory at " + BaseService._music_directory); } } private static void CheckFoldersForMusicDirectory() { try { List<string> list = Directory.GetDirectories(BaseService._plugins_directory).ToList(); list.Remove(BaseService._music_directory); foreach (string item in list) { if (CheckFolder(item)) { MoveFilesFromFolderToMusicDirectory(Path.Combine(item, Settings.SONGS_FOLDER)); } } } catch (Exception ex) { Plugin.LogError("An error occurred: " + ex.Message); } } private static bool CheckFolder(string folder) { return Directory.Exists(Path.Combine(folder, Settings.SONGS_FOLDER)); } private static void MoveFilesFromFolderToMusicDirectory(string folder) { string[] files = Directory.GetFiles(folder); Plugin.LogInfo($"Moving from {folder}, {files.Length} files found."); string[] array = files; foreach (string text in array) { string fileName = Path.GetFileName(text); string text2 = Path.Combine(BaseService._music_directory, fileName); File.Copy(text, text2); Plugin.LogInfo("Moved " + text + " to " + text2); } } } } namespace MoreMusicMod.Patches { [HarmonyPatch(typeof(BoomboxItem))] internal static class BoomboxPatch { private static int CurrentIndex; [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start(BoomboxItem __instance) { Plugin.LogInfo($"Is our music loaded: ${AudioLoaderService.IsLoaded}"); if (AudioLoaderService.IsLoaded) { AudioLoaderService.AddClips(__instance); return; } AudioLoaderService.AllSongsLoaded += delegate { AudioLoaderService.AddClips(__instance); }; } [HarmonyPatch("StartMusic")] [HarmonyPrefix] private static bool StartMusicPrefix(BoomboxItem __instance, ref bool startMusic, bool pitchDown) { if (startMusic) { __instance.boomboxAudio.clip = __instance.musicAudios[CurrentIndex]; __instance.boomboxAudio.pitch = 1f; __instance.boomboxAudio.Play(); CurrentIndex = (CurrentIndex + 1) % __instance.musicAudios.Length; ((GrabbableObject)__instance).isBeingUsed = startMusic; __instance.isPlayingMusic = startMusic; return false; } return true; } } [HarmonyPatch(typeof(StartOfRound))] internal class StartUp { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Prefix() { AudioLoaderService.LoadAllSongs(); Plugin.LogInfo($"Is using default songs: {AudioLoaderService.UseDefaultSongs}"); } } } namespace MoreMusicMod.Helpers { public class AudioHelper { public static AudioType GetAudioType(string path) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) string text = Path.GetExtension(path).ToLower(); switch (text) { case ".wav": return (AudioType)20; case ".ogg": return (AudioType)14; case ".mp3": return (AudioType)13; default: Plugin.LogError("Unsupported extension type: " + text); return (AudioType)0; } } } } namespace MoreMusicMod.Configuration { public static class Settings { public static string PLUGINS_DIRECTORY = "plugins"; public static string SONGS_FOLDER = "MoreMusic/Music"; } }