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 SimpleMusicReplacer v1.1.0
plugins\SimpleMusicReplacer.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace SimpleMusicReplacer; [BepInPlugin("sakelig.simplemusicreplacer", "SimpleMusicReplacer", "1.1.0")] public class SimpleMusicReplacerPlugin : BaseUnityPlugin { private class Playlist { public string Folder; public List<AudioClip> Clips = new List<AudioClip>(); public NamedMusic Music; public int Index; } public const string PluginGuid = "sakelig.simplemusicreplacer"; public const string PluginName = "SimpleMusicReplacer"; public const string PluginVersion = "1.1.0"; private const string CustomPrefix = "smr_"; private static readonly string[] AudioExtensions = new string[3] { ".ogg", ".wav", ".mp3" }; private static SimpleMusicReplacerPlugin _instance; private ConfigEntry<float> _volume; private ConfigEntry<bool> _shuffle; private ConfigEntry<bool> _oceanReplacesSailing; private string _musicDir; private int _pendingLoads; private readonly Dictionary<string, Playlist> _playlists = new Dictionary<string, Playlist>(); private MusicMan _appliedMusicMan; private EnvMan _appliedEnvMan; private AudioClip _lastClip; private void Awake() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) _instance = this; _volume = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Volume", 0.7f, new ConfigDescription("Volume of custom biome music (also scaled by the in-game music volume).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); _shuffle = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Shuffle", false, "Shuffle playlists instead of playing them in alphabetical order."); _oceanReplacesSailing = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OceanReplacesSailingMusic", true, "While on the Ocean biome, play the 'ocean' music instead of the vanilla sailing music."); _musicDir = Path.Combine(Paths.ConfigPath, "SimpleMusicReplacer"); Directory.CreateDirectory(Path.Combine(_musicDir, "ocean")); LoadAllMusic(); new Harmony("sakelig.simplemusicreplacer").PatchAll(typeof(SimpleMusicReplacerPlugin)); } private void LoadAllMusic() { string[] array = new string[2] { _musicDir, Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "music") }; string[] array2 = array; foreach (string path in array2) { if (!Directory.Exists(path)) { continue; } string[] directories = Directory.GetDirectories(path); foreach (string path2 in directories) { string[] array3 = (from f in Directory.GetFiles(path2) where AudioExtensions.Contains(Path.GetExtension(f).ToLowerInvariant()) select f).OrderBy<string, string>((string f) => f, StringComparer.OrdinalIgnoreCase).ToArray(); if (array3.Length != 0) { string text = Path.GetFileName(path2).ToLowerInvariant(); if (!_playlists.TryGetValue(text, out var value)) { Playlist playlist = new Playlist(); playlist.Folder = text; value = playlist; _playlists[text] = value; } string[] array4 = array3; foreach (string path3 in array4) { ((MonoBehaviour)this).StartCoroutine(LoadClip(path3, value)); } } } } if (_playlists.Count == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No music found. Put .ogg/.wav/.mp3 files in " + Path.Combine(_musicDir, "ocean"))); } } private IEnumerator LoadClip(string path, Playlist playlist) { _pendingLoads++; string url = "file:///" + path.Replace('\\', '/'); UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(url, GetAudioType(path)); try { ((DownloadHandlerAudioClip)req.downloadHandler).compressed = true; yield return req.SendWebRequest(); if ((int)req.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(req); ((Object)content).name = Path.GetFileNameWithoutExtension(path); playlist.Clips.Add(content); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded " + playlist.Folder + "/" + Path.GetFileName(path))); } else { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load " + path + ": " + req.error)); } } finally { ((IDisposable)req)?.Dispose(); } _pendingLoads--; if (_pendingLoads != 0) { yield break; } foreach (Playlist value in _playlists.Values) { value.Clips.Sort((AudioClip a, AudioClip b) => string.Compare(((Object)a).name, ((Object)b).name, StringComparison.OrdinalIgnoreCase)); if (_shuffle.Value) { Shuffle(value.Clips); } } } private void Update() { if (_pendingLoads <= 0 && _playlists.Count != 0) { if ((Object)(object)MusicMan.instance != (Object)null && (Object)(object)MusicMan.instance != (Object)(object)_appliedMusicMan) { _appliedMusicMan = MusicMan.instance; _appliedEnvMan = null; ApplyToMusicMan(_appliedMusicMan); } if ((Object)(object)EnvMan.instance != (Object)null && (Object)(object)EnvMan.instance != (Object)(object)_appliedEnvMan && (Object)(object)_appliedMusicMan != (Object)null) { _appliedEnvMan = EnvMan.instance; ApplyToEnvMan(_appliedEnvMan); } if ((Object)(object)_appliedMusicMan != (Object)null) { AdvancePlaylists(); } } } private void ApplyToMusicMan(MusicMan musicMan) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown WriteAvailableMusic(musicMan); Dictionary<int, NamedMusic> value = Traverse.Create((object)musicMan).Field("m_musicHashes").GetValue<Dictionary<int, NamedMusic>>(); foreach (Playlist p in _playlists.Values) { if (p.Clips.Count == 0) { continue; } NamedMusic val = ((IEnumerable<NamedMusic>)musicMan.m_music).FirstOrDefault((Func<NamedMusic, bool>)((NamedMusic m) => string.Equals(m.m_name, p.Folder, StringComparison.OrdinalIgnoreCase))); if (val == null) { if ((int)ParseBiome(p.Folder) == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("'" + p.Folder + "' is not a biome or music name. See available_music.txt")); continue; } NamedMusic val2 = new NamedMusic(); val2.m_name = "smr_" + p.Folder; val2.m_volume = _volume.Value; val2.m_fadeInTime = 3f; val2.m_alwaysFadeout = true; val2.m_loop = true; val2.m_ambientMusic = true; val = val2; musicMan.m_music.Add(val); value[StringExtensionMethods.GetStableHashCode(val.m_name)] = val; } val.m_enabled = true; val.m_resume = p.Clips.Count == 1; val.m_clips = (AudioClip[])(object)new AudioClip[1] { p.Clips[0] }; p.Music = val; value[StringExtensionMethods.GetStableHashCode(val.m_name)] = val; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Replaced music '" + val.m_name + "' with " + p.Clips.Count + " track(s)")); } } private void ApplyToEnvMan(EnvMan envMan) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) foreach (Playlist value in _playlists.Values) { Biome biome = ParseBiome(value.Folder); if ((int)biome == 0 || value.Music == null || !value.Music.m_name.StartsWith("smr_")) { continue; } foreach (BiomeEnvSetup item in envMan.m_biomes.Where((BiomeEnvSetup b) => b.m_biome == biome)) { item.m_musicMorning = value.Music.m_name; item.m_musicDay = value.Music.m_name; item.m_musicEvening = value.Music.m_name; item.m_musicNight = value.Music.m_name; } } } private void AdvancePlaylists() { AudioSource value = Traverse.Create((object)_appliedMusicMan).Field("m_musicSource").GetValue<AudioSource>(); if ((Object)(object)value == (Object)null || (Object)(object)value.clip == (Object)(object)_lastClip) { return; } _lastClip = value.clip; foreach (Playlist value2 in _playlists.Values) { if (value2.Music != null && value2.Clips.Count >= 2 && value2.Clips.Contains(value.clip)) { value.loop = false; value2.Index = (value2.Clips.IndexOf(value.clip) + 1) % value2.Clips.Count; if (value2.Index == 0 && _shuffle.Value) { Shuffle(value2.Clips); } value2.Music.m_clips = (AudioClip[])(object)new AudioClip[1] { value2.Clips[value2.Index] }; } } } [HarmonyPatch(typeof(MusicMan), "GetSailingMusic")] [HarmonyPostfix] private static void GetSailingMusicPostfix(ref string __result) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 if (_instance._oceanReplacesSailing.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && (int)Player.m_localPlayer.GetCurrentBiome() == 256 && _instance._playlists.TryGetValue("ocean", out var value) && value.Music != null) { __result = value.Music.m_name; } } private void WriteAvailableMusic(MusicMan musicMan) { List<string> list = new List<string>(); list.Add("Make a folder in BepInEx/config/SimpleMusicReplacer/ named after a biome or a music name"); list.Add("and put .ogg/.wav/.mp3 files in it. Several files = playlist."); list.Add(""); list.Add("Biomes (custom music plays everywhere in that biome):"); List<string> list2 = list; list2.AddRange(from n in Enum.GetNames(typeof(Biome)) where n != "None" && n != "All" && n != "Land" select " " + n.ToLowerInvariant()); list2.Add(""); list2.Add("Valheim music names (replaces that music):"); list2.AddRange(from n in (from m in musicMan.m_music where !m.m_name.StartsWith("smr_") select " " + m.m_name).Distinct() orderby n select n); File.WriteAllLines(Path.Combine(_musicDir, "available_music.txt"), list2.ToArray()); } private static Biome ParseBiome(string name) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) foreach (Biome value in Enum.GetValues(typeof(Biome))) { if ((int)value != 895 && string.Equals(((object)value).ToString(), name, StringComparison.OrdinalIgnoreCase)) { return value; } } return (Biome)0; } private static void Shuffle(List<AudioClip> clips) { for (int num = clips.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); AudioClip value = clips[num]; clips[num] = clips[index]; clips[index] = value; } } private static AudioType GetAudioType(string path) { return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch { ".wav" => 20, ".mp3" => 13, _ => 14, }); } }