Decompiled source of Expand World Music v1.4.0

ExpandWorldMusic.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 BepInEx;
using ExpandWorldData;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ServerSync;
using Service;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExpandWorldMusic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+731222ea1219a36615ddb8ae50d210f6cab01a4a")]
[assembly: AssemblyProduct("ExpandWorldMusic")]
[assembly: AssemblyTitle("ExpandWorldMusic")]
[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;
		}
	}
}
namespace ExpandWorld.Music
{
	public class Configuration
	{
		public static CustomSyncedValue<string> valueMusicData;

		public static void Init(ConfigWrapper wrapper)
		{
			valueMusicData = wrapper.AddValue("music_data");
			((CustomSyncedValueBase)valueMusicData).ValueChanged += delegate
			{
				Manager.FromSetting(valueMusicData.Value);
			};
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public class SetCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<string, string> <>9__0_1;

			public static ConsoleEvent <>9__0_0;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				ZLog.Log((object)string.Join("\n", Loader.Clips.Keys.OrderBy((string k) => k)));
			}

			internal string <Postfix>b__0_1(string k)
			{
				return k;
			}
		}

		private static void Postfix()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate
				{
					ZLog.Log((object)string.Join("\n", Loader.Clips.Keys.OrderBy((string k) => k)));
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("ew_musics", "- Prints available music clips.", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[BepInPlugin("expand_world_music", "Expand World Music", "1.4")]
	[BepInDependency("expand_world_data", "1.27")]
	public class EWM : BaseUnityPlugin
	{
		public const string GUID = "expand_world_music";

		public const string NAME = "Expand World Music";

		public const string VERSION = "1.4";

		public static ConfigSync ConfigSync = new ConfigSync("expand_world_music")
		{
			DisplayName = "Expand World Music",
			CurrentVersion = "1.4",
			ModRequired = true,
			IsLocked = true
		};

		public void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Configuration.Init(new ConfigWrapper("expand_music_config", ((BaseUnityPlugin)this).Config, ConfigSync, (Action)delegate
			{
			}));
			new Harmony("expand_world_music").PatchAll();
			try
			{
				if (Configuration.DataReload)
				{
					Manager.SetupWatcher();
				}
			}
			catch (Exception ex)
			{
				Log.Error(ex.StackTrace);
			}
		}
	}
	public class Loader
	{
		public static Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>();

		public static NamedMusic FromData(Data data)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			return new NamedMusic
			{
				m_alwaysFadeout = data.alwaysFadeOut,
				m_ambientMusic = data.ambientMusic,
				m_clips = (from c in data.clips.Select(PreloadClipCoroutine)
					where (Object)(object)c != (Object)null
					select c).Cast<AudioClip>().ToArray(),
				m_enabled = true,
				m_fadeInTime = data.fadeInTime,
				m_loop = data.loop,
				m_name = data.name,
				m_resume = data.resume,
				m_volume = data.volume
			};
		}

		public static Data ToData(NamedMusic music)
		{
			return new Data
			{
				alwaysFadeOut = music.m_alwaysFadeout,
				ambientMusic = music.m_ambientMusic,
				clips = (from c in music.m_clips
					where ((c != null) ? ((Object)c).name : null) != null
					select ((Object)c).name).ToArray(),
				fadeInTime = music.m_fadeInTime,
				loop = music.m_loop,
				name = music.m_name,
				resume = music.m_resume,
				volume = music.m_volume
			};
		}

		public static void InitializeDefaultClips()
		{
			Clips = (from c in MusicMan.instance.m_music.SelectMany((NamedMusic m) => m.m_clips)
				where ((c != null) ? ((Object)c).name : null) != null
				select c).Distinct(new Comparer()).ToDictionary((AudioClip c) => ((Object)c).name, (AudioClip c) => c);
			Clips["empty"] = null;
			AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
			foreach (AudioClip val in array)
			{
				string key = ((Object)val).name;
				int num = 2;
				while (Clips.ContainsKey(key) && !((Object)(object)Clips[key] == (Object)(object)val))
				{
					key = ((Object)val).name + "_" + num++;
				}
				if (!Clips.ContainsKey(key))
				{
					Clips.Add(key, val);
				}
			}
		}

		private static AudioClip? PreloadClipCoroutine(string path)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (Clips.ContainsKey(path))
			{
				return Clips[path];
			}
			if (!File.Exists(path))
			{
				path = Path.Combine(Yaml.Directory, path);
			}
			if (Clips.ContainsKey(path))
			{
				return Clips[path];
			}
			if (!File.Exists(path))
			{
				Log.Warning("Can't find audio clip at " + path);
				return null;
			}
			string text = "file:///" + path.Replace("\\", "/");
			try
			{
				UnityWebRequest val = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)0) ?? throw new Exception();
				val.SendWebRequest();
				while (!val.isDone)
				{
				}
				AudioClip val2 = ((DownloadHandlerAudioClip)val.downloadHandler).audioClip ?? throw new Exception();
				((Object)val2).name = Path.GetFileNameWithoutExtension(path);
				Clips.Add(path, val2);
				return val2;
			}
			catch
			{
				Log.Warning("Failed to load audio clip at " + path);
			}
			return null;
		}
	}
	public class Comparer : IEqualityComparer<AudioClip>
	{
		public bool Equals(AudioClip x, AudioClip y)
		{
			return ((Object)x).name == ((Object)y).name;
		}

		public int GetHashCode(AudioClip obj)
		{
			return StringExtensionMethods.GetStableHashCode(((Object)obj).name);
		}
	}
	public class Manager
	{
		public static string FileName = "expand_music.yaml";

		public static string FilePath = Path.Combine(Yaml.Directory, FileName);

		public static string Pattern = "expand_music*.yaml";

		public static List<NamedMusic> Originals = new List<NamedMusic>();

		public static bool IsServer()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return ZNet.instance.IsServer();
			}
			return true;
		}

		public static void ToFile()
		{
			if (IsServer() && !File.Exists(FilePath))
			{
				string contents = Yaml.Serializer().Serialize((object)MusicMan.instance.m_music.Select(Loader.ToData).ToList());
				File.WriteAllText(FilePath, contents);
			}
		}

		public static void FromFile()
		{
			if (IsServer())
			{
				string text = DataManager.Read(Pattern);
				Set(text);
				Configuration.valueMusicData.Value = text;
			}
		}

		public static void FromSetting(string yaml)
		{
			if (!IsServer())
			{
				Set(yaml);
			}
		}

		private static void Set(string yaml)
		{
			if (IsServer() && Originals.Count == 0)
			{
				List<NamedMusic> music = MusicMan.instance.m_music;
				List<NamedMusic> list = new List<NamedMusic>(music.Count);
				list.AddRange(music);
				Originals = list;
			}
			if (yaml == "")
			{
				return;
			}
			try
			{
				List<NamedMusic> list2 = Yaml.Deserialize<Data>(yaml, FileName).Select(Loader.FromData).ToList();
				if (list2.Count == 0)
				{
					Log.Warning("Failed to load any music data.");
				}
				else if (!Configuration.DataMigration || !Helper.IsServer() || !AddMissingEntries(list2))
				{
					Log.Info($"Reloading music data ({list2.Count} entries).");
					MusicMan.instance.m_music = list2;
					UpdateHashes();
					string text = MusicMan.instance.m_currentMusic?.m_name ?? "";
					MusicMan.instance.Reset();
					MusicMan.instance.StartMusic(text);
				}
			}
			catch (Exception ex)
			{
				Log.Error(ex.Message);
				Log.Error(ex.StackTrace);
			}
		}

		private static bool AddMissingEntries(List<NamedMusic> entries)
		{
			HashSet<string> missingKeys = Originals.Select((NamedMusic e) => e.m_name).Distinct().ToHashSet();
			foreach (NamedMusic entry in entries)
			{
				missingKeys.Remove(entry.m_name);
			}
			if (missingKeys.Count == 0)
			{
				return false;
			}
			List<NamedMusic> list = Originals.Where((NamedMusic item) => missingKeys.Contains(item.m_name)).ToList();
			Log.Warning($"Adding {list.Count} missing music to the expand_music.yaml file.");
			foreach (NamedMusic item in list)
			{
				Log.Warning(item.m_name);
			}
			string text = File.ReadAllText(FilePath);
			string text2 = Yaml.Serializer().Serialize((object)list.Select(Loader.ToData));
			text = text + "\n" + text2;
			File.WriteAllText(FilePath, text);
			return true;
		}

		private static void UpdateHashes()
		{
			MusicMan instance = MusicMan.instance;
			instance.m_musicHashes.Clear();
			foreach (NamedMusic item in instance.m_music)
			{
				if (item.m_enabled && item.m_clips.Length != 0 && !((Object)(object)item.m_clips[0] == (Object)null))
				{
					instance.m_musicHashes.Add(StringExtensionMethods.GetStableHashCode(item.m_name), item);
				}
			}
		}

		public static void SetupWatcher()
		{
			Yaml.SetupWatcher(Pattern, (Action)FromFile);
		}
	}
	[HarmonyPatch(typeof(MusicMan), "Awake")]
	[HarmonyPriority(0)]
	public class InitializeContent
	{
		private static void Postfix()
		{
			Loader.InitializeDefaultClips();
			Manager.ToFile();
			Manager.FromFile();
		}
	}
	public class Data
	{
		public string name = "";

		public string[] clips = Array.Empty<string>();

		public float volume;

		public float fadeInTime;

		public bool alwaysFadeOut;

		public bool ambientMusic;

		public bool loop;

		public bool resume;
	}
}