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 Valheim Music Plus v1.13.0
bin/BiomeMusic.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BiomeMusic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BiomeMusic")] [assembly: AssemblyTitle("BiomeMusic")] [assembly: AssemblyVersion("1.0.0.0")] namespace BiomeMusic; [BepInPlugin("kadabra.biomemusic", "BiomeMusic", "1.13.0")] public class BiomeMusicPlugin : BaseUnityPlugin { private static ManualLogSource Log; private ConfigEntry<float> cfgVolume; private ConfigEntry<float> cfgMinGap; private ConfigEntry<float> cfgMaxGap; private ConfigEntry<float> cfgFadeTime; private ConfigEntry<float> cfgBossRadius; private ConfigEntry<float> cfgBuildingRadius; private ConfigEntry<float> cfgHomeGrace; private ConfigEntry<float> cfgFireplaceRadius; private AudioSource source; private readonly Dictionary<string, List<AudioClip>> clips = new Dictionary<string, List<AudioClip>>(); private readonly List<AudioClip> globalClips = new List<AudioClip>(); private readonly Dictionary<string, (AudioClip clip, float pos)> _saved = new Dictionary<string, (AudioClip, float)>(); private readonly Dictionary<string, Queue<AudioClip>> _queues = new Dictionary<string, Queue<AudioClip>>(); private string _currentZone = ""; private bool _isFading; private bool _skipNextGap; private float _lastShelterTime = -999f; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; cfgVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.8f, "Volume of your tracks (0.0-1.0)"); cfgMinGap = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MinGap", 1f, "Min seconds gap between tracks (natural endings)"); cfgMaxGap = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MaxGap", 3f, "Max seconds gap between tracks (natural endings)"); cfgFadeTime = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "FadeTime", 2f, "Seconds to fade in/out on zone change"); cfgBossRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "BossRadius", 150f, "Meters to detect a nearby boss"); cfgBuildingRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "BuildingRadius", 1f, "Meters to detect nearby structural pieces"); cfgHomeGrace = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "HomeGrace", 3f, "Seconds home music lingers after leaving shelter"); cfgFireplaceRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "FireplaceRadius", 12f, "Meters to detect a burning fireplace outdoors"); ((MonoBehaviour)this).StartCoroutine(LoadAllClips(Path.Combine(Paths.PluginPath, "BiomeMusic", "music"))); } private void SilenceMusicMan() { MusicMan instance = MusicMan.instance; if ((Object)(object)instance == (Object)null) { return; } AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(); foreach (AudioSource val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.isPlaying) { val.Stop(); } } } private IEnumerator VanillaSilencer() { while (true) { if ((Object)(object)Player.m_localPlayer != (Object)null) { SilenceMusicMan(); } yield return (object)new WaitForSeconds(0.5f); } } private AudioClip NextClip(string zone) { if (!clips.ContainsKey(zone) || clips[zone].Count == 0) { return null; } if (!_queues.ContainsKey(zone) || _queues[zone].Count == 0) { List<AudioClip> list = new List<AudioClip>(clips[zone]); for (int num = list.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); AudioClip value = list[num]; list[num] = list[index]; list[index] = value; } _queues[zone] = new Queue<AudioClip>(list); Log.LogInfo((object)$"[BiomeMusic] [{zone}] reshuffled ({list.Count} tracks)"); } return _queues[zone].Dequeue(); } private IEnumerator FadeOutAndStop() { _isFading = true; float startVol = source.volume; float elapsed = 0f; float duration = cfgFadeTime.Value; while (elapsed < duration && source.isPlaying) { source.volume = Mathf.Lerp(startVol, 0f, elapsed / duration); elapsed += Time.deltaTime; yield return null; } source.Stop(); source.volume = cfgVolume.Value; _isFading = false; } private IEnumerator FadeIn() { float elapsed = 0f; float duration = cfgFadeTime.Value; while (elapsed < duration) { source.volume = Mathf.Lerp(0f, cfgVolume.Value, elapsed / duration); elapsed += Time.deltaTime; yield return null; } source.volume = cfgVolume.Value; } private bool IsBossNearby(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgBossRadius.Value); for (int i = 0; i < array.Length; i++) { Character componentInParent = ((Component)array[i]).GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)player && componentInParent.IsBoss() && !componentInParent.IsDead()) { return true; } } } catch { } return false; } private bool IsNearFireplace(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgFireplaceRadius.Value); for (int i = 0; i < array.Length; i++) { Fireplace componentInParent = ((Component)array[i]).GetComponentInParent<Fireplace>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.IsBurning()) { return true; } } } catch { } return false; } private bool IsNearBuilding(Player player) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) int num = 0; Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgBuildingRadius.Value); foreach (Collider val in array) { if ((Object)(object)((Component)val).GetComponentInParent<WearNTear>() != (Object)null) { float[] array2 = new float[3]; Bounds bounds = val.bounds; array2[0] = ((Bounds)(ref bounds)).size.x; bounds = val.bounds; array2[1] = ((Bounds)(ref bounds)).size.y; bounds = val.bounds; array2[2] = ((Bounds)(ref bounds)).size.z; if (Mathf.Max(array2) > 0.8f && ++num >= 5) { return true; } } } return false; } private string GetBiomeKey(Player player) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_006c: 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_0084: Expected I4, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Invalid comparison between Unknown and I4 if (IsBossNearby(player)) { return "boss"; } bool num = player.InShelter(); bool flag = IsNearFireplace(player); if (num && flag) { _lastShelterTime = Time.time; return "home"; } if (Time.time - _lastShelterTime < cfgHomeGrace.Value) { return "home"; } if (IsNearBuilding(player)) { return "approaching"; } Biome currentBiome = player.GetCurrentBiome(); if ((int)currentBiome <= 16) { switch (currentBiome - 1) { default: if ((int)currentBiome != 8) { if ((int)currentBiome != 16) { break; } return "plains"; } return "blackforest"; case 0: return "meadows"; case 1: return "swamp"; case 3: return "mountain"; case 2: break; } } else if ((int)currentBiome <= 64) { if ((int)currentBiome == 32) { return "ashlands"; } if ((int)currentBiome == 64) { return "deepnorth"; } } else { if ((int)currentBiome == 256) { return "ocean"; } if ((int)currentBiome == 512) { return "mistlands"; } } return "meadows"; } private IEnumerator LoadAllClips(string root) { string[] array = new string[12] { "meadows", "blackforest", "swamp", "mountain", "plains", "ocean", "mistlands", "ashlands", "deepnorth", "home", "boss", "approaching" }; string[] array2 = array; foreach (string biome in array2) { string dir = Path.Combine(root, biome); if (Directory.Exists(dir)) { clips[biome] = new List<AudioClip>(); string[] files = Directory.GetFiles(dir, "*.ogg"); foreach (string path in files) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path, clips[biome], (AudioType)14)); } files = Directory.GetFiles(dir, "*.wav"); foreach (string path2 in files) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path2, clips[biome], (AudioType)20)); } Log.LogInfo((object)$"[BiomeMusic] {biome}: {clips[biome].Count} track(s)"); } } string globalDir = Path.Combine(root, "global"); if (Directory.Exists(globalDir)) { array2 = Directory.GetFiles(globalDir, "*.ogg"); foreach (string path3 in array2) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path3, globalClips, (AudioType)14)); } array2 = Directory.GetFiles(globalDir, "*.wav"); foreach (string path4 in array2) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path4, globalClips, (AudioType)20)); } Log.LogInfo((object)$"[BiomeMusic] global: {globalClips.Count} track(s)"); string[] array3 = new string[11] { "meadows", "blackforest", "swamp", "mountain", "plains", "ocean", "mistlands", "ashlands", "deepnorth", "home", "approaching" }; foreach (string key in array3) { if (!clips.ContainsKey(key)) { clips[key] = new List<AudioClip>(); } clips[key].AddRange(globalClips); } } GameObject val = new GameObject("BiomeMusicPlayer"); Object.DontDestroyOnLoad((Object)(object)val); source = val.AddComponent<AudioSource>(); source.spatialBlend = 0f; source.loop = false; source.volume = cfgVolume.Value; int num = 0; foreach (List<AudioClip> value in clips.Values) { num += value.Count; } Log.LogInfo((object)$"[BiomeMusic] Ready — {num} total slots."); ((MonoBehaviour)this).StartCoroutine(VanillaSilencer()); ((MonoBehaviour)this).StartCoroutine(MusicLoop()); } private IEnumerator LoadClip(string path, List<AudioClip> target, AudioType type) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file://" + path, type); try { ((DownloadHandlerAudioClip)req.downloadHandler).streamAudio = false; yield return req.SendWebRequest(); if ((int)req.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(req); ((Object)content).name = Path.GetFileNameWithoutExtension(path); target.Add(content); } else { Log.LogWarning((object)("[BiomeMusic] Load failed: " + path + " — " + req.error)); } } finally { ((IDisposable)req)?.Dispose(); } } private IEnumerator MusicLoop() { yield return (object)new WaitForSeconds(20f); while (true) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { yield return (object)new WaitForSeconds(2f); continue; } string biomeKey = GetBiomeKey(localPlayer); if (_isFading) { yield return (object)new WaitForSeconds(0.1f); continue; } if (source.isPlaying) { if (biomeKey != _currentZone) { _saved[_currentZone] = (source.clip, source.time); _skipNextGap = true; Log.LogInfo((object)$"[BiomeMusic] [{_currentZone}→{biomeKey}] saved {source.time:F0}s — fading"); ((MonoBehaviour)this).StartCoroutine(FadeOutAndStop()); } yield return (object)new WaitForSeconds(1f); continue; } if (!_skipNextGap) { float num = Random.Range(cfgMinGap.Value, cfgMaxGap.Value); yield return (object)new WaitForSeconds(num); } _skipNextGap = false; localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { continue; } biomeKey = GetBiomeKey(localPlayer); if (!clips.ContainsKey(biomeKey) || clips[biomeKey].Count == 0) { yield return (object)new WaitForSeconds(2f); continue; } float num2 = 0f; AudioClip val; if (_saved.TryGetValue(biomeKey, out (AudioClip, float) value) && (Object)(object)value.Item1 != (Object)null && value.Item1.length - value.Item2 > 10f) { (val, num2) = value; _saved.Remove(biomeKey); Log.LogInfo((object)$"[BiomeMusic] ↩ Resume [{biomeKey}] {((Object)val).name} from {num2:F0}s"); } else { val = NextClip(biomeKey); if (_saved.ContainsKey(biomeKey)) { _saved.Remove(biomeKey); } Log.LogInfo((object)$"[BiomeMusic] ▶ [{biomeKey}] {((Object)val).name} ({val.length:F0}s)"); } _currentZone = biomeKey; source.clip = val; source.time = num2; source.volume = 0f; source.Play(); yield return ((MonoBehaviour)this).StartCoroutine(FadeIn()); } } }
obj/Release/BiomeMusic.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BiomeMusic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BiomeMusic")] [assembly: AssemblyTitle("BiomeMusic")] [assembly: AssemblyVersion("1.0.0.0")] namespace BiomeMusic; [BepInPlugin("kadabra.biomemusic", "BiomeMusic", "1.13.0")] public class BiomeMusicPlugin : BaseUnityPlugin { private static ManualLogSource Log; private ConfigEntry<float> cfgVolume; private ConfigEntry<float> cfgMinGap; private ConfigEntry<float> cfgMaxGap; private ConfigEntry<float> cfgFadeTime; private ConfigEntry<float> cfgBossRadius; private ConfigEntry<float> cfgBuildingRadius; private ConfigEntry<float> cfgHomeGrace; private ConfigEntry<float> cfgFireplaceRadius; private AudioSource source; private readonly Dictionary<string, List<AudioClip>> clips = new Dictionary<string, List<AudioClip>>(); private readonly List<AudioClip> globalClips = new List<AudioClip>(); private readonly Dictionary<string, (AudioClip clip, float pos)> _saved = new Dictionary<string, (AudioClip, float)>(); private readonly Dictionary<string, Queue<AudioClip>> _queues = new Dictionary<string, Queue<AudioClip>>(); private string _currentZone = ""; private bool _isFading; private bool _skipNextGap; private float _lastShelterTime = -999f; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; cfgVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.8f, "Volume of your tracks (0.0-1.0)"); cfgMinGap = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MinGap", 1f, "Min seconds gap between tracks (natural endings)"); cfgMaxGap = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MaxGap", 3f, "Max seconds gap between tracks (natural endings)"); cfgFadeTime = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "FadeTime", 2f, "Seconds to fade in/out on zone change"); cfgBossRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "BossRadius", 150f, "Meters to detect a nearby boss"); cfgBuildingRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "BuildingRadius", 1f, "Meters to detect nearby structural pieces"); cfgHomeGrace = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "HomeGrace", 3f, "Seconds home music lingers after leaving shelter"); cfgFireplaceRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Detection", "FireplaceRadius", 12f, "Meters to detect a burning fireplace outdoors"); ((MonoBehaviour)this).StartCoroutine(LoadAllClips(Path.Combine(Paths.PluginPath, "BiomeMusic", "music"))); } private void SilenceMusicMan() { MusicMan instance = MusicMan.instance; if ((Object)(object)instance == (Object)null) { return; } AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(); foreach (AudioSource val in componentsInChildren) { if ((Object)(object)val != (Object)null && val.isPlaying) { val.Stop(); } } } private IEnumerator VanillaSilencer() { while (true) { if ((Object)(object)Player.m_localPlayer != (Object)null) { SilenceMusicMan(); } yield return (object)new WaitForSeconds(0.5f); } } private AudioClip NextClip(string zone) { if (!clips.ContainsKey(zone) || clips[zone].Count == 0) { return null; } if (!_queues.ContainsKey(zone) || _queues[zone].Count == 0) { List<AudioClip> list = new List<AudioClip>(clips[zone]); for (int num = list.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); AudioClip value = list[num]; list[num] = list[index]; list[index] = value; } _queues[zone] = new Queue<AudioClip>(list); Log.LogInfo((object)$"[BiomeMusic] [{zone}] reshuffled ({list.Count} tracks)"); } return _queues[zone].Dequeue(); } private IEnumerator FadeOutAndStop() { _isFading = true; float startVol = source.volume; float elapsed = 0f; float duration = cfgFadeTime.Value; while (elapsed < duration && source.isPlaying) { source.volume = Mathf.Lerp(startVol, 0f, elapsed / duration); elapsed += Time.deltaTime; yield return null; } source.Stop(); source.volume = cfgVolume.Value; _isFading = false; } private IEnumerator FadeIn() { float elapsed = 0f; float duration = cfgFadeTime.Value; while (elapsed < duration) { source.volume = Mathf.Lerp(0f, cfgVolume.Value, elapsed / duration); elapsed += Time.deltaTime; yield return null; } source.volume = cfgVolume.Value; } private bool IsBossNearby(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgBossRadius.Value); for (int i = 0; i < array.Length; i++) { Character componentInParent = ((Component)array[i]).GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)player && componentInParent.IsBoss() && !componentInParent.IsDead()) { return true; } } } catch { } return false; } private bool IsNearFireplace(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgFireplaceRadius.Value); for (int i = 0; i < array.Length; i++) { Fireplace componentInParent = ((Component)array[i]).GetComponentInParent<Fireplace>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.IsBurning()) { return true; } } } catch { } return false; } private bool IsNearBuilding(Player player) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) int num = 0; Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, cfgBuildingRadius.Value); foreach (Collider val in array) { if ((Object)(object)((Component)val).GetComponentInParent<WearNTear>() != (Object)null) { float[] array2 = new float[3]; Bounds bounds = val.bounds; array2[0] = ((Bounds)(ref bounds)).size.x; bounds = val.bounds; array2[1] = ((Bounds)(ref bounds)).size.y; bounds = val.bounds; array2[2] = ((Bounds)(ref bounds)).size.z; if (Mathf.Max(array2) > 0.8f && ++num >= 5) { return true; } } } return false; } private string GetBiomeKey(Player player) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_006c: 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_0084: Expected I4, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Invalid comparison between Unknown and I4 if (IsBossNearby(player)) { return "boss"; } bool num = player.InShelter(); bool flag = IsNearFireplace(player); if (num && flag) { _lastShelterTime = Time.time; return "home"; } if (Time.time - _lastShelterTime < cfgHomeGrace.Value) { return "home"; } if (IsNearBuilding(player)) { return "approaching"; } Biome currentBiome = player.GetCurrentBiome(); if ((int)currentBiome <= 16) { switch (currentBiome - 1) { default: if ((int)currentBiome != 8) { if ((int)currentBiome != 16) { break; } return "plains"; } return "blackforest"; case 0: return "meadows"; case 1: return "swamp"; case 3: return "mountain"; case 2: break; } } else if ((int)currentBiome <= 64) { if ((int)currentBiome == 32) { return "ashlands"; } if ((int)currentBiome == 64) { return "deepnorth"; } } else { if ((int)currentBiome == 256) { return "ocean"; } if ((int)currentBiome == 512) { return "mistlands"; } } return "meadows"; } private IEnumerator LoadAllClips(string root) { string[] array = new string[12] { "meadows", "blackforest", "swamp", "mountain", "plains", "ocean", "mistlands", "ashlands", "deepnorth", "home", "boss", "approaching" }; string[] array2 = array; foreach (string biome in array2) { string dir = Path.Combine(root, biome); if (Directory.Exists(dir)) { clips[biome] = new List<AudioClip>(); string[] files = Directory.GetFiles(dir, "*.ogg"); foreach (string path in files) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path, clips[biome], (AudioType)14)); } files = Directory.GetFiles(dir, "*.wav"); foreach (string path2 in files) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path2, clips[biome], (AudioType)20)); } Log.LogInfo((object)$"[BiomeMusic] {biome}: {clips[biome].Count} track(s)"); } } string globalDir = Path.Combine(root, "global"); if (Directory.Exists(globalDir)) { array2 = Directory.GetFiles(globalDir, "*.ogg"); foreach (string path3 in array2) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path3, globalClips, (AudioType)14)); } array2 = Directory.GetFiles(globalDir, "*.wav"); foreach (string path4 in array2) { yield return ((MonoBehaviour)this).StartCoroutine(LoadClip(path4, globalClips, (AudioType)20)); } Log.LogInfo((object)$"[BiomeMusic] global: {globalClips.Count} track(s)"); string[] array3 = new string[11] { "meadows", "blackforest", "swamp", "mountain", "plains", "ocean", "mistlands", "ashlands", "deepnorth", "home", "approaching" }; foreach (string key in array3) { if (!clips.ContainsKey(key)) { clips[key] = new List<AudioClip>(); } clips[key].AddRange(globalClips); } } GameObject val = new GameObject("BiomeMusicPlayer"); Object.DontDestroyOnLoad((Object)(object)val); source = val.AddComponent<AudioSource>(); source.spatialBlend = 0f; source.loop = false; source.volume = cfgVolume.Value; int num = 0; foreach (List<AudioClip> value in clips.Values) { num += value.Count; } Log.LogInfo((object)$"[BiomeMusic] Ready — {num} total slots."); ((MonoBehaviour)this).StartCoroutine(VanillaSilencer()); ((MonoBehaviour)this).StartCoroutine(MusicLoop()); } private IEnumerator LoadClip(string path, List<AudioClip> target, AudioType type) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file://" + path, type); try { ((DownloadHandlerAudioClip)req.downloadHandler).streamAudio = false; yield return req.SendWebRequest(); if ((int)req.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(req); ((Object)content).name = Path.GetFileNameWithoutExtension(path); target.Add(content); } else { Log.LogWarning((object)("[BiomeMusic] Load failed: " + path + " — " + req.error)); } } finally { ((IDisposable)req)?.Dispose(); } } private IEnumerator MusicLoop() { yield return (object)new WaitForSeconds(20f); while (true) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { yield return (object)new WaitForSeconds(2f); continue; } string biomeKey = GetBiomeKey(localPlayer); if (_isFading) { yield return (object)new WaitForSeconds(0.1f); continue; } if (source.isPlaying) { if (biomeKey != _currentZone) { _saved[_currentZone] = (source.clip, source.time); _skipNextGap = true; Log.LogInfo((object)$"[BiomeMusic] [{_currentZone}→{biomeKey}] saved {source.time:F0}s — fading"); ((MonoBehaviour)this).StartCoroutine(FadeOutAndStop()); } yield return (object)new WaitForSeconds(1f); continue; } if (!_skipNextGap) { float num = Random.Range(cfgMinGap.Value, cfgMaxGap.Value); yield return (object)new WaitForSeconds(num); } _skipNextGap = false; localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { continue; } biomeKey = GetBiomeKey(localPlayer); if (!clips.ContainsKey(biomeKey) || clips[biomeKey].Count == 0) { yield return (object)new WaitForSeconds(2f); continue; } float num2 = 0f; AudioClip val; if (_saved.TryGetValue(biomeKey, out (AudioClip, float) value) && (Object)(object)value.Item1 != (Object)null && value.Item1.length - value.Item2 > 10f) { (val, num2) = value; _saved.Remove(biomeKey); Log.LogInfo((object)$"[BiomeMusic] ↩ Resume [{biomeKey}] {((Object)val).name} from {num2:F0}s"); } else { val = NextClip(biomeKey); if (_saved.ContainsKey(biomeKey)) { _saved.Remove(biomeKey); } Log.LogInfo((object)$"[BiomeMusic] ▶ [{biomeKey}] {((Object)val).name} ({val.length:F0}s)"); } _currentZone = biomeKey; source.clip = val; source.time = num2; source.volume = 0f; source.Play(); yield return ((MonoBehaviour)this).StartCoroutine(FadeIn()); } } }