Decompiled source of CustomAudio LocationMusic v1.5.11

CustomAudio.dll

Decompiled 2 weeks ago
using System;
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 System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
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: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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]
	[Microsoft.CodeAnalysis.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]
	[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;
		}
	}
}
public static class SavWav
{
	private const int HEADER_SIZE = 44;

	public static bool Save(string filename, AudioClip clip)
	{
		if (!filename.ToLower().EndsWith(".wav"))
		{
			filename += ".wav";
		}
		string text = Path.Combine(Application.persistentDataPath, filename);
		Debug.Log((object)text);
		Directory.CreateDirectory(Path.GetDirectoryName(text));
		using (FileStream fileStream = CreateEmpty(text))
		{
			ConvertAndWrite(fileStream, clip);
			WriteHeader(fileStream, clip);
		}
		return true;
	}

	public static AudioClip TrimSilence(AudioClip clip, float min)
	{
		float[] array = new float[clip.samples];
		clip.GetData(array, 0);
		return TrimSilence(new List<float>(array), min, clip.channels, clip.frequency);
	}

	public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz)
	{
		return TrimSilence(samples, min, channels, hz, _3D: false, stream: false);
	}

	public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz, bool _3D, bool stream)
	{
		int i;
		for (i = 0; i < samples.Count && !(Mathf.Abs(samples[i]) > min); i++)
		{
		}
		samples.RemoveRange(0, i);
		i = samples.Count - 1;
		while (i > 0 && !(Mathf.Abs(samples[i]) > min))
		{
			i--;
		}
		samples.RemoveRange(i, samples.Count - i);
		AudioClip obj = AudioClip.Create("TempClip", samples.Count, channels, hz, stream);
		obj.SetData(samples.ToArray(), 0);
		return obj;
	}

	private static FileStream CreateEmpty(string filepath)
	{
		FileStream fileStream = new FileStream(filepath, FileMode.Create);
		byte value = 0;
		for (int i = 0; i < 44; i++)
		{
			fileStream.WriteByte(value);
		}
		return fileStream;
	}

	private static void ConvertAndWrite(FileStream fileStream, AudioClip clip)
	{
		float[] array = new float[clip.samples];
		clip.GetData(array, 0);
		short[] array2 = new short[array.Length];
		byte[] array3 = new byte[array.Length * 2];
		int num = 32767;
		for (int i = 0; i < array.Length; i++)
		{
			array2[i] = (short)(array[i] * (float)num);
			_ = new byte[2];
			BitConverter.GetBytes(array2[i]).CopyTo(array3, i * 2);
		}
		fileStream.Write(array3, 0, array3.Length);
	}

	private static void WriteHeader(FileStream fileStream, AudioClip clip)
	{
		int frequency = clip.frequency;
		int channels = clip.channels;
		int samples = clip.samples;
		fileStream.Seek(0L, SeekOrigin.Begin);
		byte[] bytes = Encoding.UTF8.GetBytes("RIFF");
		fileStream.Write(bytes, 0, 4);
		byte[] bytes2 = BitConverter.GetBytes(fileStream.Length - 8);
		fileStream.Write(bytes2, 0, 4);
		byte[] bytes3 = Encoding.UTF8.GetBytes("WAVE");
		fileStream.Write(bytes3, 0, 4);
		byte[] bytes4 = Encoding.UTF8.GetBytes("fmt ");
		fileStream.Write(bytes4, 0, 4);
		byte[] bytes5 = BitConverter.GetBytes(16);
		fileStream.Write(bytes5, 0, 4);
		byte[] bytes6 = BitConverter.GetBytes((ushort)1);
		fileStream.Write(bytes6, 0, 2);
		byte[] bytes7 = BitConverter.GetBytes(channels);
		fileStream.Write(bytes7, 0, 2);
		byte[] bytes8 = BitConverter.GetBytes(frequency);
		fileStream.Write(bytes8, 0, 4);
		byte[] bytes9 = BitConverter.GetBytes(frequency * channels * 2);
		fileStream.Write(bytes9, 0, 4);
		ushort value = (ushort)(channels * 2);
		fileStream.Write(BitConverter.GetBytes(value), 0, 2);
		byte[] bytes10 = BitConverter.GetBytes((ushort)16);
		fileStream.Write(bytes10, 0, 2);
		byte[] bytes11 = Encoding.UTF8.GetBytes("data");
		fileStream.Write(bytes11, 0, 4);
		byte[] bytes12 = BitConverter.GetBytes(samples * channels * 2);
		fileStream.Write(bytes12, 0, 4);
	}
}
namespace CustomAudio
{
	[BepInPlugin("aedenthorn.CustomAudio", "Custom Audio", "1.5.11")]
	public class BepInExPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZSFX), "Awake")]
		private static class ZSFX_Awake_Patch
		{
			private static void Postfix(ZSFX __instance)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				string zSFXName = GetZSFXName(__instance);
				if (dumpInfo.Value)
				{
					Dbgl("Checking SFX: " + zSFXName);
				}
				Dictionary<string, Dictionary<string, AudioClip>> customSFXList = BepInExPlugin.customSFXList;
				if (customSFXList != null && customSFXList.TryGetValue(zSFXName, out Dictionary<string, AudioClip> value))
				{
					if (dumpInfo.Value)
					{
						Dbgl("replacing SFX list by name: " + zSFXName);
					}
					__instance.m_audioClips = value.Values.ToArray();
				}
				else
				{
					if (customSFX == null || __instance.m_audioClips == null)
					{
						return;
					}
					for (int i = 0; i < __instance.m_audioClips.Length; i++)
					{
						if (__instance.m_audioClips[i] == null)
						{
							continue;
						}
						if (dumpInfo.Value)
						{
							Dbgl("checking SFX: " + zSFXName + ", clip: " + ((Object)__instance.m_audioClips[i]).name);
						}
						if (customSFX.TryGetValue(((Object)__instance.m_audioClips[i]).name, out AudioClip value2))
						{
							if (dumpInfo.Value)
							{
								Dbgl("replacing SFX: " + zSFXName + ", clip: " + ((Object)__instance.m_audioClips[i]).name);
							}
							__instance.m_audioClips[i] = value2;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(MusicMan), "Awake")]
		private static class MusicMan_Awake_Patch
		{
			private static void Postfix(MusicMan __instance)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				List<string> list = new List<string>();
				for (int i = 0; i < __instance.m_music.Count; i++)
				{
					list.Add("Music list name: " + __instance.m_music[i].m_name);
					for (int j = 0; j < __instance.m_music[i].m_clips.Length; j++)
					{
						if (!Object.op_Implicit((Object)(object)__instance.m_music[i].m_clips[j]))
						{
							continue;
						}
						list.Add("\ttrack name: " + ((Object)__instance.m_music[i].m_clips[j]).name);
						if (customMusic.ContainsKey(((Object)__instance.m_music[i].m_clips[j]).name))
						{
							if (dumpInfo.Value)
							{
								CustomAudioLogger.LogInfo((object)("replacing music: " + __instance.m_music[i].m_name + ", clip: " + ((Object)__instance.m_music[i].m_clips[j]).name));
							}
							__instance.m_music[i].m_clips[j] = customMusic[((Object)__instance.m_music[i].m_clips[j]).name];
						}
					}
					if (customMusicList.ContainsKey(__instance.m_music[i].m_name))
					{
						if (dumpInfo.Value)
						{
							CustomAudioLogger.LogInfo((object)("replacing music list by name: " + __instance.m_music[i].m_name));
						}
						__instance.m_music[i].m_clips = customMusicList[__instance.m_music[i].m_name].Values.ToArray();
					}
				}
				if (dumpInfo.Value)
				{
					CustomAudioLogger.LogInfo((object)string.Join("\n", list));
				}
			}
		}

		[HarmonyPatch(typeof(AudioMan), "Awake")]
		private static class AudioMan_Awake_Patch
		{
			private static void Postfix(AudioMan __instance, List<BiomeAmbients> ___m_randomAmbients, AudioSource ___m_oceanAmbientSource, AudioSource ___m_windLoopSource)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				List<string> list = new List<string>();
				for (int i = 0; i < ___m_randomAmbients.Count; i++)
				{
					list.Add("Ambient list name: " + ___m_randomAmbients[i].m_name);
					list.Add("\tAmbient tracks: (use " + ___m_randomAmbients[i].m_name + ")");
					for (int j = 0; j < ___m_randomAmbients[i].m_randomAmbientClips.Count; j++)
					{
						list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name);
						if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name))
						{
							CustomAudioLogger.LogInfo((object)("replacing ambient: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name));
							___m_randomAmbients[i].m_randomAmbientClips[j] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name];
						}
					}
					list.Add("\tAmbient day tracks: (use " + ___m_randomAmbients[i].m_name + "_day)");
					for (int k = 0; k < ___m_randomAmbients[i].m_randomAmbientClipsDay.Count; k++)
					{
						if (!((Object)(object)__instance.m_randomAmbients[i].m_randomAmbientClipsDay[k] == (Object)null))
						{
							list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name);
							if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name))
							{
								CustomAudioLogger.LogInfo((object)("replacing ambient day: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name));
								___m_randomAmbients[i].m_randomAmbientClipsDay[k] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name];
							}
						}
					}
					list.Add("\tAmbient night tracks: (use " + ___m_randomAmbients[i].m_name + "_night)");
					for (int l = 0; l < ___m_randomAmbients[i].m_randomAmbientClipsNight.Count; l++)
					{
						if (!((Object)(object)__instance.m_randomAmbients[i].m_randomAmbientClipsNight[l] == (Object)null))
						{
							list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name);
							if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name))
							{
								CustomAudioLogger.LogInfo((object)("replacing ambient night: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name));
								___m_randomAmbients[i].m_randomAmbientClipsNight[l] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name];
							}
						}
					}
					if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name + "_day"))
					{
						CustomAudioLogger.LogInfo((object)("replacing ambient day list by name: " + ___m_randomAmbients[i].m_name + "_day"));
						___m_randomAmbients[i].m_randomAmbientClipsDay = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name + "_day"].Values.ToList());
					}
					else if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name + "_night"))
					{
						CustomAudioLogger.LogInfo((object)("replacing ambient night list by name: " + ___m_randomAmbients[i].m_name + "_night"));
						___m_randomAmbients[i].m_randomAmbientClipsNight = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name + "_night"].Values.ToList());
					}
					else if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name))
					{
						CustomAudioLogger.LogInfo((object)("replacing ambient list by name: " + ___m_randomAmbients[i].m_name));
						___m_randomAmbients[i].m_randomAmbientClips = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name].Values.ToList());
					}
				}
				if (dumpInfo.Value)
				{
					CustomAudioLogger.LogInfo((object)string.Join("\n", list));
				}
				if (customAmbient.ContainsKey("ocean"))
				{
					___m_oceanAmbientSource.clip = customAmbient["ocean"];
				}
				if (customAmbient.ContainsKey("wind"))
				{
					___m_windLoopSource.clip = customAmbient["wind"];
				}
			}
		}

		[HarmonyPatch(typeof(MusicLocation), "Awake")]
		public static class MusicLocation_Awake_Patch
		{
			private static void Postfix(ref AudioSource ___m_audioSource, ref float ___m_baseVolume)
			{
				if (!((Object)(object)___m_audioSource != (Object)null))
				{
					return;
				}
				if (dumpInfo.Value)
				{
					CustomAudioLogger.LogInfo((object)("Loaded m_audioSource: " + ((Object)___m_audioSource).name));
					CustomAudioLogger.LogInfo((object)("       clip name    : " + ((Object)___m_audioSource.clip).name));
					CustomAudioLogger.LogInfo((object)$"       m_baseVolume : {___m_baseVolume}");
				}
				if (customMusic.ContainsKey(((Object)___m_audioSource.clip).name))
				{
					if (dumpInfo.Value)
					{
						CustomAudioLogger.LogInfo((object)("replacing music: " + ((Object)___m_audioSource.clip).name));
					}
					___m_audioSource.clip = customMusic[((Object)___m_audioSource.clip).name];
					___m_baseVolume *= locationVolmult.Value;
				}
			}
		}

		[HarmonyPatch(typeof(MusicMan), "UpdateMusic")]
		private static class UpdateMusic_Patch
		{
			private static NamedMusic lastMusic;

			private static void Prefix(ref NamedMusic ___m_currentMusic, ref NamedMusic ___m_queuedMusic, AudioSource ___m_musicSource)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				if (___m_queuedMusic != null)
				{
					___m_queuedMusic.m_volume = musicVol.Value;
				}
				if ((Object)(object)((___m_musicSource != null) ? ___m_musicSource.clip : null) != (Object)null && lastMusicName != ((Object)___m_musicSource.clip).name)
				{
					if (dumpInfo.Value)
					{
						Dbgl("Switching music from " + lastMusicName + " to " + ((Object)___m_musicSource.clip).name);
					}
					lastMusicName = ((Object)___m_musicSource.clip).name;
				}
				if (___m_queuedMusic == null && !___m_musicSource.isPlaying && PlayerPrefs.GetInt("ContinousMusic", 1) == 1)
				{
					if (lastMusic != null)
					{
						lastMusic.m_lastPlayedTime = 0f;
						___m_queuedMusic = lastMusic;
						lastMusic = null;
					}
					else if (___m_currentMusic != null)
					{
						lastMusic = ___m_currentMusic;
					}
					else
					{
						lastMusic = null;
					}
				}
				else
				{
					lastMusic = null;
				}
				if (___m_musicSource.isPlaying && ___m_queuedMusic != null && ___m_musicSource.loop)
				{
					Dbgl("queued " + ___m_queuedMusic?.m_name + ", setting " + ((Object)___m_musicSource).name + " loop to false");
					___m_musicSource.loop = false;
				}
			}
		}

		[HarmonyPatch(typeof(AudioMan), "QueueAmbientLoop")]
		private static class QueueAmbientLoop_Patch
		{
			private static void Prefix(ref float ___m_queuedAmbientVol, ref float ___m_ambientVol, ref float vol)
			{
				if (modEnabled.Value)
				{
					vol = ambientVol.Value;
					___m_ambientVol = ambientVol.Value;
					___m_queuedAmbientVol = ambientVol.Value;
				}
			}
		}

		[HarmonyPatch(typeof(EnvMan), "Awake")]
		private static class EnvMan_Awake_Patch
		{
			private static void Postfix(EnvMan __instance)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				for (int i = 0; i < __instance.m_environments.Count; i++)
				{
					if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Morning"))
					{
						AddMusicList(__instance, i, "Morning");
					}
					if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Day"))
					{
						AddMusicList(__instance, i, "Day");
					}
					if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Evening"))
					{
						AddMusicList(__instance, i, "Evening");
					}
					if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Night"))
					{
						AddMusicList(__instance, i, "Night");
					}
				}
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Awake")]
		private static class TeleportWorld_Awake_Patch
		{
			private static void Postfix(TeleportWorld __instance)
			{
				if (modEnabled.Value && customSFX.ContainsKey("portal"))
				{
					AudioSource componentInChildren = ((Component)__instance).GetComponentInChildren<AudioSource>();
					componentInChildren.clip = customSFX["portal"];
					((Component)componentInChildren).gameObject.SetActive(false);
					((Component)componentInChildren).gameObject.SetActive(true);
				}
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Start")]
		private static class Fireplace_Start_Patch
		{
			private static void Postfix(Fireplace __instance)
			{
				if (!modEnabled.Value)
				{
					return;
				}
				if (((Object)__instance).name.Contains("groundtorch") && customSFX.ContainsKey("groundtorch"))
				{
					Dbgl("Replacing ground torch audio");
					__instance.m_enabledObject.GetComponentInChildren<AudioSource>().clip = customSFX["groundtorch"];
				}
				else if (((Object)__instance).name.Contains("walltorch") && customSFX.ContainsKey("walltorch"))
				{
					Dbgl("Replacing walltorch audio");
					GameObject enabledObjectHigh = __instance.m_enabledObjectHigh;
					if (Object.op_Implicit((Object)(object)((enabledObjectHigh != null) ? enabledObjectHigh.GetComponentInChildren<AudioSource>() : null)))
					{
						__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["walltorch"];
						return;
					}
					GameObject enabledObject = __instance.m_enabledObject;
					if (Object.op_Implicit((Object)(object)((enabledObject != null) ? enabledObject.GetComponentInChildren<AudioSource>() : null)))
					{
						__instance.m_enabledObject.GetComponentInChildren<AudioSource>().clip = customSFX["walltorch"];
					}
				}
				else if (((Object)__instance).name.Contains("fire_pit") && customSFX.ContainsKey("fire_pit"))
				{
					Dbgl("Replacing fire_pit audio");
					__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["fire_pit"];
				}
				else if (((Object)__instance).name.Contains("bonfire") && customSFX.ContainsKey("bonfire"))
				{
					Dbgl("Replacing bonfire audio");
					__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["bonfire"];
				}
				else if (((Object)__instance).name.Contains("hearth") && customSFX.ContainsKey("hearth"))
				{
					Dbgl("Replacing hearth audio");
					__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["hearth"];
				}
			}
		}

		[HarmonyPatch(typeof(Terminal), "InputText")]
		private static class InputText_Patch
		{
			private static bool Prefix(Terminal __instance)
			{
				if (!modEnabled.Value)
				{
					return true;
				}
				string text = ((TMP_InputField)__instance.m_input).text;
				if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
				{
					((BaseUnityPlugin)context).Config.Reload();
					((BaseUnityPlugin)context).Config.Save();
					Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
					Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue();
					return false;
				}
				if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " music"))
				{
					Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
					if (Object.op_Implicit((Object)(object)EnvMan.instance))
					{
						string name;
						if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Player.m_localPlayer.IsSafeInHome())
						{
							name = "home";
						}
						else
						{
							name = EnvMan.instance.GetAmbientMusic();
						}
						Dbgl("Current environment: " + EnvMan.instance.GetCurrentEnvironment().m_name);
						Dbgl("Current music list: " + name + " " + ((IEnumerable<NamedMusic>)MusicMan.instance.m_music).FirstOrDefault((Func<NamedMusic, bool>)((NamedMusic m) => m.m_name == name))?.m_clips.Length);
					}
					Dbgl("Vanilla music list names:\n" + string.Join("\n", MusicMan.instance.m_music.Select((NamedMusic m) => m.m_name)));
					if (Object.op_Implicit((Object)(object)EnvMan.instance))
					{
						List<string> list = new List<string>();
						for (int i = 0; i < EnvMan.instance.m_environments.Count; i++)
						{
							list.Add(EnvMan.instance.m_environments[i].m_name + "Morning");
							list.Add(EnvMan.instance.m_environments[i].m_name + "Day");
							list.Add(EnvMan.instance.m_environments[i].m_name + "Evening");
							list.Add(EnvMan.instance.m_environments[i].m_name + "Night");
						}
						Dbgl("Possible music list names:\n" + string.Join("\n", list));
					}
					Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped music names" }).GetValue();
					return false;
				}
				if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " env"))
				{
					Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
					if (!Object.op_Implicit((Object)(object)EnvMan.instance))
					{
						Traverse.Create((object)__instance).Method("AddString", new object[1] { "Must be called in-game" }).GetValue();
					}
					Dbgl("Current environment: " + EnvMan.instance.GetCurrentEnvironment().m_name);
					return false;
				}
				return true;
			}
		}

		public static ConfigEntry<bool> isDebug;

		public static ConfigEntry<bool> modEnabled;

		public static ConfigEntry<bool> dumpInfo;

		public static ConfigEntry<float> musicVol;

		public static ConfigEntry<float> ambientVol;

		public static ConfigEntry<float> locationVolmult;

		internal const string ModName = "Custom Audio";

		public static Dictionary<string, AudioClip> customMusic = new Dictionary<string, AudioClip>();

		public static Dictionary<string, Dictionary<string, AudioClip>> customMusicList = new Dictionary<string, Dictionary<string, AudioClip>>();

		public static Dictionary<string, AudioClip> customAmbient = new Dictionary<string, AudioClip>();

		public static Dictionary<string, Dictionary<string, AudioClip>> customAmbientList = new Dictionary<string, Dictionary<string, AudioClip>>();

		public static Dictionary<string, AudioClip> customSFX = new Dictionary<string, AudioClip>();

		public static Dictionary<string, Dictionary<string, AudioClip>> customSFXList = new Dictionary<string, Dictionary<string, AudioClip>>();

		public static readonly ManualLogSource CustomAudioLogger = Logger.CreateLogSource("Custom Audio");

		private static string lastMusicName = "";

		private static BepInExPlugin context;

		public static void Dbgl(string str = "", bool pref = true)
		{
			if (isDebug.Value)
			{
				CustomAudioLogger.LogInfo((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
			}
		}

		private void Awake()
		{
			context = this;
			modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
			isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", false, "Show debug log messages in the console");
			dumpInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DumpInfo", false, "Dump audio info to the console");
			musicVol = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MusicVol", 0.6f, "Music volume, 0.0 - 1.0");
			locationVolmult = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LocationVol", 5f, "Location music volume multiplier");
			ambientVol = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AmbientVol", 0.3f, "Ambient volume");
			if (modEnabled.Value)
			{
				PreloadAudioClips();
				Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			}
		}

		public void PreloadAudioClips()
		{
			if (dumpInfo.Value)
			{
				CustomAudioLogger.LogInfo((object)"Preloading audio clips.");
			}
			string text = Path.Combine(Paths.PluginPath, "CustomAudio");
			if (Directory.Exists(text))
			{
				customMusic.Clear();
				customAmbient.Clear();
				customSFX.Clear();
				customMusicList.Clear();
				customAmbientList.Clear();
				customSFXList.Clear();
				if (Directory.Exists(Path.Combine(text, "Music")))
				{
					CollectAudioFiles(Path.Combine(text, "Music"), customMusic, customMusicList);
				}
				else
				{
					Directory.CreateDirectory(Path.Combine(text, "Music"));
				}
				if (Directory.Exists(Path.Combine(text, "SFX")))
				{
					CollectAudioFiles(Path.Combine(text, "SFX"), customSFX, customSFXList);
				}
				else
				{
					Directory.CreateDirectory(Path.Combine(text, "SFX"));
				}
				if (Directory.Exists(Path.Combine(text, "Ambient")))
				{
					CollectAudioFiles(Path.Combine(text, "Ambient"), customAmbient, customAmbientList);
				}
				else
				{
					Directory.CreateDirectory(Path.Combine(text, "Ambient"));
				}
			}
			else
			{
				CustomAudioLogger.LogInfo((object)("Directory " + text + " does not exist! Creating."));
				Directory.CreateDirectory(text);
				Directory.CreateDirectory(Path.Combine(text, "Ambient"));
				Directory.CreateDirectory(Path.Combine(text, "Music"));
				Directory.CreateDirectory(Path.Combine(text, "SFX"));
			}
			string[] directories = Directory.GetDirectories(Paths.PluginPath, "*", SearchOption.AllDirectories);
			for (int i = 0; i < directories.Length; i++)
			{
				string text2 = Path.Combine(directories[i], "CustomAudio");
				if (Directory.Exists(text2))
				{
					string path = Path.Combine(text2, "Music");
					if (Directory.Exists(path))
					{
						CollectAudioFiles(path, customMusic, customMusicList);
					}
					string path2 = Path.Combine(text2, "Ambient");
					if (Directory.Exists(path2))
					{
						CollectAudioFiles(path2, customAmbient, customAmbientList);
					}
					string path3 = Path.Combine(text2, "SFX");
					if (Directory.Exists(path3))
					{
						CollectAudioFiles(path3, customSFX, customSFXList);
					}
				}
			}
		}

		public void CollectAudioFiles(string path, Dictionary<string, AudioClip> customDict, Dictionary<string, Dictionary<string, AudioClip>> customDictDict)
		{
			Dbgl("checking folder " + Path.GetFileName(path));
			string[] files = Directory.GetFiles(path);
			foreach (string path2 in files)
			{
				PreloadClipCoroutine(path2, (AudioType)0, customDict);
			}
			files = Directory.GetDirectories(path);
			foreach (string path3 in files)
			{
				string fileName = Path.GetFileName(path3);
				string[] files2 = Directory.GetFiles(path3);
				customDictDict[fileName] = new Dictionary<string, AudioClip>();
				string[] array = files2;
				foreach (string path4 in array)
				{
					PreloadClipCoroutine(path4, (AudioType)0, customDictDict[fileName]);
				}
			}
			files = Directory.GetDirectories(path);
			foreach (string path5 in files)
			{
				string fileName2 = Path.GetFileName(path5);
				string[] files3 = Directory.GetFiles(path5);
				if (files3.Length == 1 && files3[0].ToLower().EndsWith(".txt") && customDictDict.ContainsKey(Path.GetFileNameWithoutExtension(files3[0])))
				{
					if (dumpInfo.Value)
					{
						CustomAudioLogger.LogInfo((object)("\tlinking music folder " + Path.GetFileName(path5) + " to folder " + Path.GetFileNameWithoutExtension(files3[0])));
					}
					customDictDict[fileName2] = customDictDict[Path.GetFileNameWithoutExtension(files3[0])];
				}
			}
		}

		private void PreloadClipCoroutine(string path, AudioType audioType, Dictionary<string, AudioClip> whichDict)
		{
			//IL_0049: 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_0071: Expected O, but got Unknown
			if (path.EndsWith(".txt") || !path.Contains("."))
			{
				return;
			}
			Dbgl("path: " + path);
			path = "file:///" + path.Replace("\\", "/");
			try
			{
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
				audioClip.SendWebRequest();
				while (!audioClip.isDone)
				{
				}
				if (audioClip != null)
				{
					DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)audioClip.downloadHandler;
					if (val != null)
					{
						AudioClip audioClip2 = val.audioClip;
						if ((Object)(object)audioClip2 != (Object)null)
						{
							string text = (((Object)audioClip2).name = Path.GetFileNameWithoutExtension(path));
							if (!whichDict.ContainsKey(text))
							{
								whichDict[text] = audioClip2;
							}
							Dbgl("Added audio clip " + text + " to dict");
						}
						else
						{
							Dbgl("audio clip is null. data: " + ((DownloadHandler)val).text);
						}
					}
					else
					{
						Dbgl("DownloadHandler is null. bytes downloaded: " + audioClip.downloadedBytes);
					}
				}
				else
				{
					Dbgl("www is null " + audioClip.url);
				}
			}
			catch
			{
			}
		}

		public static string GetZSFXName(ZSFX zfx)
		{
			string name = ((Object)zfx).name;
			char[] anyOf = new char[2] { '(', ' ' };
			int num = name.IndexOfAny(anyOf);
			if (num != -1)
			{
				return name.Remove(num);
			}
			return name;
		}

		private static void AddMusicList(EnvMan envMan, int index, string which)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			string text = envMan.m_environments[index].m_name + which;
			Dbgl($"Adding music list by name: {text} ({customMusicList[text].Count})");
			switch (which)
			{
			case "Morning":
				envMan.m_environments[index].m_musicMorning = text;
				break;
			case "Day":
				envMan.m_environments[index].m_musicDay = text;
				break;
			case "Evening":
				envMan.m_environments[index].m_musicEvening = text;
				break;
			case "Night":
				envMan.m_environments[index].m_musicNight = text;
				break;
			}
			MusicMan.instance.m_music.Add(new NamedMusic
			{
				m_name = text,
				m_clips = customMusicList[text].Values.ToArray(),
				m_loop = true,
				m_ambientMusic = true,
				m_resume = true
			});
		}
	}
	public class UnityWebRequestAwaiter : INotifyCompletion
	{
		private UnityWebRequestAsyncOperation asyncOp;

		private Action continuation;

		public bool IsCompleted
		{
			get
			{
				BepInExPlugin.Dbgl("Is completed get");
				return ((AsyncOperation)asyncOp).isDone;
			}
		}

		public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
		{
			this.asyncOp = asyncOp;
			((AsyncOperation)asyncOp).completed += OnRequestCompleted;
			BepInExPlugin.Dbgl("created asyncop");
		}

		public void GetResult()
		{
			BepInExPlugin.Dbgl("Get Result");
		}

		public void OnCompleted(Action continuation)
		{
			this.continuation = continuation;
			BepInExPlugin.Dbgl("on completed");
		}

		private void OnRequestCompleted(AsyncOperation obj)
		{
			continuation();
			BepInExPlugin.Dbgl("on request completed");
		}
	}
	public static class ExtensionMethods
	{
		public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
		{
			return new UnityWebRequestAwaiter(asyncOp);
		}
	}
}