Decompiled source of USTManager v1.5.4

plugins/USTManager.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using GameConsole;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using USTManager;
using USTManager.Commands;
using USTManager.Data;
using USTManager.Misc;
using USTManager.Patches;
using USTManager.Preprocessor;
using USTManager.Resources;
using USTManager.Utility;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("USTManager")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod :D")]
[assembly: AssemblyFileVersion("1.5.4.0")]
[assembly: AssemblyInformationalVersion("1.5.4+5b5e7ad36193a57ec252595cb3a4e37c8da13ce7")]
[assembly: AssemblyProduct("USTManager")]
[assembly: AssemblyTitle("USTManager")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.4.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 class ConflictEntry : MonoBehaviour
{
	private TMP_Text Title;

	private TMP_Dropdown Dropdown;

	private ConflictResolutionScreen Parent;

	public void Setup(string title, string[] options)
	{
		Title = ((Component)((Component)this).transform.GetChild(0)).GetComponent<TMP_Text>();
		Dropdown = ((Component)((Component)this).transform.GetChild(1)).GetComponent<TMP_Dropdown>();
		Parent = ((Component)this).GetComponentInParent<ConflictResolutionScreen>();
		((UnityEvent<int>)(object)Dropdown.onValueChanged).AddListener((UnityAction<int>)delegate(int value)
		{
			Parent.UpdateResult(Title.text, value);
		});
		Title.text = title;
		Dropdown.ClearOptions();
		Dropdown.AddOptions(options.ToList());
		Dropdown.value = 0;
		Parent.UpdateResult(Title.text, 0);
	}
}
public class ConflictResolutionScreen : MonoBehaviour
{
	private ScrollRect ScrollRect;

	private Conflict result;

	private USTSelectionScreen Parent;

	private Button ConfirmButton;

	private Button ExitButton;

	private void OnDisable()
	{
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	public void Setup(Conflict conflict)
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		Parent = ((Component)((Component)this).transform.parent).GetComponent<USTSelectionScreen>();
		Debug.Log((object)(("Parent: " + (object)Parent == null) ? "null" : ((Object)Parent).name));
		ScrollRect = ((Component)this).GetComponentInChildren<ScrollRect>();
		ConfirmButton = ((Component)((Component)((Component)this).transform.GetChild(2)).transform.GetChild(1)).GetComponent<Button>();
		((UnityEvent)ConfirmButton.onClick).AddListener((UnityAction)delegate
		{
			Confirm();
		});
		ExitButton = ((Component)((Component)((Component)this).transform.GetChild(2)).transform.GetChild(0)).GetComponent<Button>();
		((UnityEvent)ExitButton.onClick).AddListener((UnityAction)delegate
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		});
		result = conflict;
		foreach (KeyValuePair<string, List<CustomUST>> conflict2 in conflict.Conflicts)
		{
			Object.Instantiate<GameObject>(Plugin.ConflictEntryPrefab, (Transform)(object)ScrollRect.content).AddComponent<ConflictEntry>().Setup(conflict2.Key, conflict2.Value.Select((CustomUST x) => x.Name).ToArray());
		}
	}

	public void UpdateResult(string key, int index)
	{
		result.Resolve(key, result.Conflicts[key][index]);
	}

	public void Confirm()
	{
		Parent.Confirm(result);
	}
}
public class USTEntry : MonoBehaviour
{
	public Image Image;

	public Button IconButton;

	public Button EntryButton;

	public Image EntryButtonImage;

	private Toggle Toggle;

	private Sprite Icon;

	public TMP_Text Name;

	public TMP_Text Author;

	public TMP_Text Status;

	private USTSelectionScreen SelectionScreen;

	public CustomUST UST;

	private static Color green = new Color(0f, 1f, 0f, 1f);

	private static Color white = new Color(1f, 1f, 1f, 1f);

	private void Awake()
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		SelectionScreen = ((Component)this).GetComponentInParent<USTSelectionScreen>();
		Toggle = ((Component)this).GetComponentInChildren<Toggle>();
		EntryButton = ((Component)this).GetComponent<Button>();
		EntryButtonImage = ((Component)EntryButton).GetComponent<Image>();
		((UnityEvent)IconButton.onClick).AddListener((UnityAction)delegate
		{
			if (Toggle.isOn)
			{
				Toggle.isOn = false;
			}
			else
			{
				Toggle.isOn = true;
			}
		});
		((UnityEvent)EntryButton.onClick).AddListener((UnityAction)delegate
		{
			if (Toggle.isOn)
			{
				Toggle.isOn = false;
			}
			else
			{
				Toggle.isOn = true;
			}
		});
		((UnityEvent<bool>)(object)Toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (value)
			{
				((Graphic)EntryButtonImage).color = green;
				SelectionScreen.SelectEntry(this);
			}
			else
			{
				((Graphic)EntryButtonImage).color = white;
				SelectionScreen.DeselectEntry(this);
			}
		});
	}

	public void Select()
	{
		Toggle.isOn = true;
	}

	private void OnDestroy()
	{
		((UnityEventBase)IconButton.onClick).RemoveAllListeners();
	}

	public void SetData(CustomUST ust)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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)
		UST = ust;
		if ((Object)(object)ust.Icon != (Object)null)
		{
			Icon = ust.Icon;
			Image.sprite = Icon;
		}
		else
		{
			_ = ust.UserColor;
			Color userColor = ust.UserColor;
			((Graphic)Image).color = userColor;
		}
		Name.text = ust.Name;
		Author.text = "by: " + ust.Author;
	}
}
public class USTSelectionScreen : MonoBehaviour
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__12_0;

		public static Action<USTEntry> <>9__12_4;

		public static Func<USTEntry, CustomUST> <>9__12_5;

		public static Action<USTEntry> <>9__12_6;

		public static Action<USTEntry> <>9__14_0;

		internal void <Awake>b__12_0()
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			RuntimePlatform platform = Application.platform;
			if ((int)platform != 1)
			{
				if ((int)platform != 2)
				{
					if ((int)platform == 13)
					{
						Process.Start("xdg-open", Plugin.USTDir);
					}
				}
				else
				{
					Process.Start("explorer.exe", Plugin.USTDir);
				}
			}
			else
			{
				Process.Start("open", Plugin.USTDir);
			}
		}

		internal void <Awake>b__12_4(USTEntry x)
		{
			PersistentEntries.Add(x.UST.Path);
		}

		internal CustomUST <Awake>b__12_5(USTEntry x)
		{
			return x.UST;
		}

		internal void <Awake>b__12_6(USTEntry x)
		{
			PersistentEntries.Add(x.UST.Path);
		}

		internal void <Confirm>b__14_0(USTEntry x)
		{
			PersistentEntries.Add(x.UST.Path);
		}
	}

	private static List<RectTransform> Entries = new List<RectTransform>();

	private ScrollRect? ScrollRect;

	private GameObject? EntryPrefab;

	private Button? CreateButton;

	private Button? OpenFolderButton;

	private Button? RefreshButton;

	private Button? ExitButton;

	private Button? ConfirmButton;

	public static Conflict? CurrentConflict;

	public List<USTEntry> SelectedEntries = new List<USTEntry>();

	public static List<string> PersistentEntries = new List<string>();

	public static USTSelectionScreen Instance { get; private set; }

	public static CustomUST? CurrentUST { get; private set; }

	private void Awake()
	{
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Expected O, but got Unknown
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Expected O, but got Unknown
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Expected O, but got Unknown
		Instance = this;
		if ((Object)(object)EntryPrefab == (Object)null)
		{
			EntryPrefab = Plugin.SelectionScreenEntryPrefab;
		}
		if ((Object)(object)CreateButton == (Object)null)
		{
			CreateButton = ((Component)((Component)this).transform.GetChild(4).GetChild(0)).GetComponent<Button>();
		}
		if ((Object)(object)OpenFolderButton == (Object)null)
		{
			OpenFolderButton = ((Component)((Component)this).transform.GetChild(4).GetChild(1)).GetComponent<Button>();
			ButtonClickedEvent onClick = OpenFolderButton.onClick;
			object obj = <>c.<>9__12_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					//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_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Invalid comparison between Unknown and I4
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_000c: Invalid comparison between Unknown and I4
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Invalid comparison between Unknown and I4
					RuntimePlatform platform = Application.platform;
					if ((int)platform != 1)
					{
						if ((int)platform != 2)
						{
							if ((int)platform == 13)
							{
								Process.Start("xdg-open", Plugin.USTDir);
							}
						}
						else
						{
							Process.Start("explorer.exe", Plugin.USTDir);
						}
					}
					else
					{
						Process.Start("open", Plugin.USTDir);
					}
				};
				<>c.<>9__12_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}
		if ((Object)(object)RefreshButton == (Object)null)
		{
			RefreshButton = ((Component)((Component)this).transform.GetChild(4).GetChild(2)).GetComponent<Button>();
			((UnityEvent)RefreshButton.onClick).AddListener((UnityAction)delegate
			{
				Refresh();
			});
		}
		if ((Object)(object)ExitButton == (Object)null)
		{
			ExitButton = ((Component)((Component)this).transform.GetChild(1)).GetComponent<Button>();
			((UnityEvent)ExitButton.onClick).AddListener((UnityAction)delegate
			{
				SelectedEntries.Clear();
				((Component)this).gameObject.SetActive(false);
			});
		}
		if ((Object)(object)ConfirmButton == (Object)null)
		{
			ConfirmButton = ((Component)((Component)this).transform.GetChild(2)).GetComponent<Button>();
			((UnityEvent)ConfirmButton.onClick).AddListener((UnityAction)delegate
			{
				if (SelectedEntries.Count != 0)
				{
					if (SelectedEntries.Count == 1)
					{
						Manager.LoadUST(SelectedEntries[0].UST);
						CurrentUST = SelectedEntries[0].UST;
						PersistentEntries.Clear();
						SelectedEntries.ForEach(delegate(USTEntry x)
						{
							PersistentEntries.Add(x.UST.Path);
						});
						if (File.Exists(Plugin.LastUSTs))
						{
							File.Delete(Plugin.LastUSTs);
						}
						Manager.SaveUST();
					}
					else if (SelectedEntries.Count > 1)
					{
						Conflict conflict = ConflictResolver.Merge(SelectedEntries.Select((USTEntry x) => x.UST).ToArray());
						if (!conflict.Validate(out CustomUST UST))
						{
							Object.Instantiate<GameObject>(Plugin.ConflictResolutionScreenPrefab, ((Component)this).transform).GetComponent<ConflictResolutionScreen>().Setup(conflict);
							return;
						}
						Manager.LoadUST(UST);
						CurrentUST = UST;
						PersistentEntries.Clear();
						SelectedEntries.ForEach(delegate(USTEntry x)
						{
							PersistentEntries.Add(x.UST.Path);
						});
						SelectedEntries.Clear();
						if (File.Exists(Plugin.LastUSTs))
						{
							File.Delete(Plugin.LastUSTs);
						}
						Manager.SaveUST();
					}
				}
				else
				{
					Manager.UnloadUST();
					PersistentEntries.Clear();
					SelectedEntries.Clear();
					if (File.Exists(Plugin.LastUSTs))
					{
						File.Delete(Plugin.LastUSTs);
					}
				}
				((Component)this).gameObject.SetActive(false);
			});
		}
		ScrollRect = ((Component)this).GetComponentInChildren<ScrollRect>();
	}

	public bool Confirm(Conflict conflict)
	{
		CurrentConflict = null;
		if (conflict.Validate(out CustomUST UST))
		{
			Manager.LoadUST(UST);
			CurrentConflict = conflict;
			CurrentUST = UST;
			PersistentEntries.Clear();
			SelectedEntries.ForEach(delegate(USTEntry x)
			{
				PersistentEntries.Add(x.UST.Path);
			});
			SelectedEntries.Clear();
			((Component)this).gameObject.SetActive(false);
			if (File.Exists(Plugin.LastUSTs))
			{
				File.Delete(Plugin.LastUSTs);
			}
			Manager.SaveUST();
			return true;
		}
		return false;
	}

	public static void InternalConfirm(List<string>? entries, CustomUST? ust)
	{
		if (entries != null && ust != null)
		{
			Manager.LoadUST(ust, fromSaved: true);
			CurrentUST = ust;
			PersistentEntries.Clear();
			PersistentEntries = entries;
		}
	}

	private void OnEnable()
	{
		Refresh();
	}

	private void OnDisable()
	{
		SelectedEntries.Clear();
		((Component)this).gameObject.SetActive(false);
	}

	public void SelectEntry(USTEntry entry)
	{
		if ((Object)(object)entry != (Object)null && !SelectedEntries.Contains(entry))
		{
			SelectedEntries.Add(entry);
		}
	}

	public void DeselectEntry(USTEntry entry)
	{
		if ((Object)(object)entry != (Object)null && SelectedEntries.Contains(entry))
		{
			SelectedEntries.Remove(entry);
		}
	}

	public void AddNew()
	{
	}

	public void Refresh()
	{
		Manager.CheckUSTs();
		RefreshUI(Manager.AllUSTs);
	}

	private void RefreshUI(List<CustomUST> data)
	{
		if (data == null)
		{
			return;
		}
		foreach (RectTransform entry in Entries)
		{
			if ((Object)(object)entry != (Object)null && (Object)(object)((Component)entry).gameObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)entry).gameObject);
			}
		}
		Entries.Clear();
		foreach (CustomUST datum in data)
		{
			GameObject val = Object.Instantiate<GameObject>(EntryPrefab, (Transform)(object)ScrollRect.content);
			USTEntry component = val.GetComponent<USTEntry>();
			component.SetData(datum);
			if (CurrentUST != null)
			{
				if (PersistentEntries.Contains(datum.Path))
				{
					Debug.Log((object)"Selected");
					component.Select();
				}
			}
			else
			{
				((Selectable)val.GetComponent<Button>()).interactable = true;
			}
			Entries.Add(val.GetComponent<RectTransform>());
		}
	}
}
namespace USTManager
{
	[BepInPlugin("dev.zeddevstuff.ustmanager", "USTManager", "1.5.4")]
	public class Plugin : BaseUnityPlugin
	{
		public static string UKPath;

		public static string USTDir;

		public static string LastUSTs;

		public ConfigEntry<bool> UpdateBasedSwappingEnabled;

		public static GameObject MenuEntryPrefab;

		public static GameObject SelectionScreenPrefab;

		public static GameObject SelectionScreenEntryPrefab;

		public static GameObject ConflictEntryPrefab;

		public static GameObject ConflictResolutionScreenPrefab;

		public static GameObject ToastPrefab;

		private Stopwatch sw = new Stopwatch();

		public static USTSelectionScreen Screen;

		private static Plugin instance;

		private void Awake()
		{
			UpdateBasedSwappingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "UpdateBasedSwappingEnabled", false, "Enable this to use Update based swapping on top of method patching. This should allow most sounds to be swapped. This method will probably hurt performance.");
			instance = this;
			Harmony.CreateAndPatchAll(typeof(AudioSourcePatches), (string)null);
			Harmony.CreateAndPatchAll(typeof(MainMenuPatches), (string)null);
			UKPath = new DirectoryInfo(Application.dataPath).Parent.FullName;
			LastUSTs = Path.Combine(UKPath, "USTs", "lastUSTs.json");
			if (File.Exists(LastUSTs))
			{
				try
				{
					Manager.USTSave uSTSave = JsonConvert.DeserializeObject<Manager.USTSave>(File.ReadAllText(LastUSTs));
					if (uSTSave != null)
					{
						USTSelectionScreen.InternalConfirm(uSTSave.Selected, uSTSave.UST);
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)ex);
				}
			}
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(UKPath, "USTs"));
			USTDir = directoryInfo.FullName;
			if (!directoryInfo.Exists)
			{
				directoryInfo.Create();
			}
			AssetBundle obj = AssetBundle.LoadFromMemory(Resource1.ust);
			MenuEntryPrefab = obj.LoadAsset<GameObject>("MenuEntry");
			MenuEntryPrefab.AddComponent<HudOpenEffect>();
			SelectionScreenEntryPrefab = obj.LoadAsset<GameObject>("USTEntry");
			USTEntry uSTEntry = SelectionScreenEntryPrefab.AddComponent<USTEntry>();
			uSTEntry.Image = ((Component)SelectionScreenEntryPrefab.transform.GetChild(0)).GetComponent<Image>();
			uSTEntry.Name = ((Component)SelectionScreenEntryPrefab.transform.GetChild(1)).GetComponent<TMP_Text>();
			uSTEntry.Author = ((Component)SelectionScreenEntryPrefab.transform.GetChild(2)).GetComponent<TMP_Text>();
			uSTEntry.IconButton = ((Component)SelectionScreenEntryPrefab.transform.GetChild(0)).GetComponent<Button>();
			uSTEntry.Status = ((Component)SelectionScreenEntryPrefab.transform.GetChild(0).GetChild(0)).GetComponent<TMP_Text>();
			SelectionScreenPrefab = obj.LoadAsset<GameObject>("OptionMenu");
			GameObject selectionScreenPrefab = SelectionScreenPrefab;
			if (selectionScreenPrefab != null)
			{
				selectionScreenPrefab.AddComponent<USTSelectionScreen>();
			}
			ConflictEntryPrefab = obj.LoadAsset<GameObject>("Conflict");
			ConflictResolutionScreenPrefab = obj.LoadAsset<GameObject>("ConflictResolutionScreen");
			GameObject conflictResolutionScreenPrefab = ConflictResolutionScreenPrefab;
			if (conflictResolutionScreenPrefab != null)
			{
				conflictResolutionScreenPrefab.AddComponent<ConflictResolutionScreen>();
			}
			CreateTemplate();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin USTManager is loaded!");
		}

		public void Update()
		{
			if (!UpdateBasedSwappingEnabled.Value)
			{
				return;
			}
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
			foreach (AudioSource val in array)
			{
				if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent<USTTarget>()))
				{
					((Component)val).gameObject.AddComponent<USTTarget>();
				}
			}
		}

		public static void OpenMenu(Transform transform)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Screen == (Object)null)
			{
				Screen = Object.Instantiate<GameObject>(SelectionScreenPrefab, transform).GetComponent<USTSelectionScreen>();
				((Component)Screen).GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0f);
			}
			else
			{
				((Component)Screen).gameObject.SetActive(true);
			}
		}

		public static void RunCoroutine(IEnumerator routine)
		{
			((MonoBehaviour)instance).StartCoroutine(routine);
		}

		public void CreateTemplate()
		{
			Directory.CreateDirectory(Path.Combine(UKPath, "USTs", "Template"));
			File.WriteAllText(Path.Combine(UKPath, "USTs", "Template", "template.ust"), CustomUST.GetTemplateJson());
			File.WriteAllText(Path.Combine(UKPath, "USTs", "Template", "readme.md"), StaticResources.Readme);
		}

		private void OnGUI()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (!Manager.IsDebug)
			{
				return;
			}
			AudioSource[] sources = (from s in Object.FindObjectsOfType<AudioSource>()
				where s.isPlaying
				where Manager.IsExtendedDebug || (double)s.spatialBlend < 1.0
				select s).ToArray();
			GUIStyle label = GUI.skin.label;
			label.fontSize = 24;
			HorizontalScope val = new HorizontalScope(Array.Empty<GUILayoutOption>());
			try
			{
				label.normal.textColor = Color.green;
				DrawColumn(delegate(AudioSource s)
				{
					GUILayout.Label(((Object)s).name ?? "null", Array.Empty<GUILayoutOption>());
				});
				GUILayout.Space(20f);
				label.normal.textColor = Color.white;
				DrawColumn(delegate(AudioSource s)
				{
					GUILayout.Label(Object.op_Implicit((Object)(object)s.clip) ? (((Object)s.clip).name ?? "null") : "null", Array.Empty<GUILayoutOption>());
				});
				GUILayout.Space(20f);
				label.normal.textColor = Color.red;
				DrawColumn(delegate(AudioSource s)
				{
					//IL_0005: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Expected O, but got Unknown
					HorizontalScope val4 = new HorizontalScope(Array.Empty<GUILayoutOption>());
					try
					{
						GUILayout.Label(s.volume * 100f + "%", Array.Empty<GUILayoutOption>());
						GUILayout.HorizontalSlider(s.time, 0f, Object.op_Implicit((Object)(object)s.clip) ? s.clip.length : 0f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
					}
					finally
					{
						((IDisposable)val4)?.Dispose();
					}
				});
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			void DrawColumn(Action<AudioSource> action)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Expected O, but got Unknown
				VerticalScope val2 = new VerticalScope(Array.Empty<GUILayoutOption>());
				try
				{
					AudioSource[] array = sources;
					foreach (AudioSource val3 in array)
					{
						if (val3 != null)
						{
							action(val3);
						}
					}
				}
				finally
				{
					((IDisposable)val2)?.Dispose();
				}
			}
		}
	}
	public static class Manager
	{
		public class USTSave
		{
			public List<string> Selected;

			public CustomUST UST;
		}

		public static bool IsEnabled = true;

		public static bool IsDebug = false;

		public static bool IsExtendedDebug = false;

		public static float DebugLifetime = 1f;

		private static Dictionary<string, AudioClip> CustomUST = new Dictionary<string, AudioClip>();

		public static List<CustomUST> AllUSTs = new List<CustomUST>();

		private static readonly HashSet<string> pitchedTracks = new HashSet<string> { "2-4:boss1", "2-4:boss2", "4-4:bassline", "7-1:boss2" };

		public static void CheckUSTs()
		{
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			IEnumerable<FileInfo> enumerable = (from x in Directory.GetFiles(Path.Combine(Plugin.UKPath, "USTs"), "*.ust", SearchOption.AllDirectories)
				select new FileInfo(x)).Concat(GetUstsInPlugins());
			AllUSTs.Clear();
			LegacyUSTConverter.legacyUSTs.Clear();
			foreach (FileInfo item in enumerable)
			{
				if (item.Name == "template.ust")
				{
					continue;
				}
				try
				{
					CustomUST customUST = JsonConvert.DeserializeObject<CustomUST>(File.ReadAllText(item.FullName));
					if (customUST == null)
					{
						continue;
					}
					customUST.Path = item.Directory.FullName;
					foreach (Dictionary<string, string> value in customUST.Levels.Values)
					{
						string[] array = value.Keys.ToArray();
						foreach (string key in array)
						{
							value[key] = Path.Combine(customUST.Path, value[key]);
						}
					}
					string path = Path.Combine(item.Directory.FullName, "icon.png");
					if (File.Exists(path))
					{
						Texture2D val = new Texture2D(100, 100);
						if (ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
						{
							customUST.Icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
						}
					}
					AllUSTs.Add(customUST);
				}
				catch (Exception message)
				{
					if (LegacyUSTConverter.IsLegacyUST(item.FullName))
					{
						Logging.Log("Legacy UST detected", Color.yellow);
						continue;
					}
					Logging.LogError("Failed to load UST " + item.Name + ": Invalid JSON");
					Logging.Log(message, Color.red);
				}
			}
			if (LegacyUSTConverter.legacyUSTs.Count > 0)
			{
				LegacyUSTConverter.ConvertLegacyUSTs();
				USTSelectionScreen.Instance.Refresh();
			}
		}

		public static void UnloadUST()
		{
			CustomUST.Clear();
		}

		public static void LoadUST(CustomUST ust, bool fromSaved = false)
		{
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			UnloadUST();
			if (ust == null)
			{
				return;
			}
			Dictionary<string, AudioClip> dictionary = new Dictionary<string, AudioClip>();
			string path = ust.Path;
			foreach (KeyValuePair<string, Dictionary<string, string>> level in ust.Levels)
			{
				foreach (KeyValuePair<string, string> item in level.Value)
				{
					string key = item.Key;
					string trackPath = item.Value;
					if ((fromSaved && !File.Exists(trackPath)) || (!fromSaved && !ust.IsMerged && !File.Exists(Path.Combine(path, trackPath))))
					{
						continue;
					}
					IEnumerable<KeyValuePair<string, AudioClip>> source = dictionary.Where((KeyValuePair<string, AudioClip> x) => ((Object)x.Value).name == "[UST] " + Path.GetFileNameWithoutExtension(trackPath));
					if (source.Count() > 0)
					{
						if (level.Key == "global")
						{
							if (!dictionary.ContainsKey(key))
							{
								dictionary.Add(key, source.First().Value);
								Logging.Log("Adding clip " + ((Object)source.First().Value).name, Color.green);
							}
						}
						else if (!dictionary.ContainsKey(level.Key + ":" + key))
						{
							dictionary.Add(level.Key + ":" + key, source.First().Value);
							Logging.Log("Adding clip " + level.Key + ":" + key, Color.green);
						}
						continue;
					}
					AudioClip val = Loader.LoadClipFromPath(trackPath);
					if ((Object)(object)val != (Object)null)
					{
						if (level.Key == "global")
						{
							if (!dictionary.ContainsKey(key))
							{
								dictionary.Add(key, val);
								Logging.Log("Adding clip " + ((Object)val).name, Color.green);
							}
						}
						else if (!dictionary.ContainsKey(level.Key + ":" + key))
						{
							dictionary.Add(level.Key + ":" + key, val);
							Logging.Log("Adding clip " + level.Key + ":" + key, Color.green);
						}
					}
					else
					{
						Logging.Log("Something went wrong with this clip", Color.red);
					}
				}
			}
			if (dictionary.Count > 0)
			{
				CustomUST.Clear();
				CustomUST = dictionary;
			}
		}

		public static void SaveUST()
		{
			if (USTSelectionScreen.PersistentEntries.Count > 0 && USTSelectionScreen.CurrentUST != null)
			{
				USTSave uSTSave = new USTSave
				{
					Selected = USTSelectionScreen.PersistentEntries,
					UST = USTSelectionScreen.CurrentUST
				};
				File.WriteAllText(Plugin.LastUSTs, JsonConvert.SerializeObject((object)uSTSave, (Formatting)1));
			}
		}

		public static IEnumerable<FileInfo> GetUstsInPlugins()
		{
			DirectoryInfo parent = new FileInfo(typeof(Plugin).Assembly.Location).Directory.Parent;
			if (parent.Exists)
			{
				return parent.GetFiles("*.ust", SearchOption.AllDirectories).Concat(parent.GetFiles("*.ust.json", SearchOption.AllDirectories));
			}
			return Enumerable.Empty<FileInfo>();
		}

		public static void HandleAudioSource(string level, AudioSource source)
		{
			if (!IsEnabled || (Object)(object)((source != null) ? source.clip : null) == (Object)null || ((Object)source.clip).name.Contains("[UST]"))
			{
				return;
			}
			if (CustomUST.ContainsKey(((Object)source.clip).name))
			{
				source.clip = CustomUST[((Object)source.clip).name];
				if (source.playOnAwake)
				{
					source.Play();
				}
				return;
			}
			level = level.Replace("Level ", "");
			string text2;
			switch (level)
			{
			case "0-5":
			{
				string name = ((Object)source.clip).name;
				string text = ((name == "Cerberus A") ? "boss1" : ((!(name == "Cerberus B")) ? null : "boss2"));
				text2 = text;
				break;
			}
			case "1-1":
				text2 = HeartOfTheSunrise(((Object)source.clip).name);
				break;
			case "1-2":
				text2 = TheBurningWorld(((Object)source.clip).name, ((Object)source).name == "CleanTheme");
				break;
			case "1-4":
				text2 = ((Object)source).name switch
				{
					"Music - Clair de Lune" => "piano", 
					"SlowMo" => "intro", 
					"Music - Versus" => "boss", 
					_ => null, 
				};
				break;
			case "2-4":
			{
				string name = ((Object)source.clip).name;
				string text = ((name == "Minos Corpse A") ? "boss1" : ((!(name == "Minos Corpse B")) ? null : "boss2"));
				text2 = text;
				break;
			}
			case "3-1":
				text2 = ((Object)source.clip).name switch
				{
					"3-1 Guts Clean" => "clean1", 
					"3-1 Glory Clean" => "clean2", 
					"3-1 Guts" => "battle1", 
					"3-1 Glory" => "battle2", 
					_ => null, 
				};
				break;
			case "3-2":
				text2 = ((Object)source).name switch
				{
					"Music 1" => "intro1", 
					"Music 2" => "intro2", 
					"Music 3" => "boss", 
					_ => null, 
				};
				break;
			case "4-3":
				text2 = AShotInTheDark(((Object)source.clip).name);
				break;
			case "4-4":
				text2 = ((Object)source.clip).name switch
				{
					"Tanpura Drone" => "drone", 
					"V2 Intro" => (source.pitch < 1f) ? "bassline" : "intro", 
					"V2 4-4" => "boss", 
					"Versus2Outro" => "outro", 
					_ => null, 
				};
				break;
			case "5-2":
				text2 = ((Object)source.clip).name switch
				{
					"Ferryman A" => "boss1", 
					"Ferryman B" => "boss2", 
					"Ferryman C" => "boss3", 
					_ => null, 
				};
				break;
			case "5-3":
			{
				string name;
				switch (((Object)source).name)
				{
				case "CleanTheme":
					name = (((Object)source.clip).name.Contains("Aftermath") ? "clean2" : "clean1");
					break;
				case "BattleTheme":
				case "BossTheme":
					name = (((Object)source.clip).name.Contains("Aftermath") ? "battle2" : "battle1");
					break;
				default:
					name = null;
					break;
				}
				text2 = name;
				break;
			}
			case "5-4":
			{
				string name = ((Object)source).name;
				string text = ((name == "Music 1") ? "boss1" : ((!(name == "Music 2")) ? null : "boss2"));
				text2 = text;
				break;
			}
			case "6-1":
			{
				string name;
				switch (((Object)source).name)
				{
				case "CleanTheme":
					name = (((Object)source.clip).name.Contains("6-1") ? "clean" : null);
					break;
				case "BattleTheme":
				case "BossTheme":
					name = (((Object)source.clip).name.Contains("6-1") ? "battle" : null);
					break;
				case "ClimaxMusic":
					name = "boss";
					break;
				default:
					name = null;
					break;
				}
				text2 = name;
				break;
			}
			case "6-2":
			{
				string text = ((!(((Object)source).name == "BossMusic")) ? null : "boss");
				text2 = text;
				break;
			}
			case "7-1":
				text2 = ((Object)source).name switch
				{
					"CleanTheme" => "clean", 
					"BattleTheme" => "battle", 
					"MinotaurPhase1Music" => "boss1", 
					"MinotaurPhase2Music" => "boss2", 
					_ => null, 
				};
				break;
			case "7-2":
			{
				string name;
				switch (((Object)source).name)
				{
				case "CleanTheme":
					name = (((Object)source.clip).name.Contains("Intro") ? "clean1" : "clean2");
					break;
				case "BattleTheme":
				case "BossTheme":
					name = (((Object)source.clip).name.Contains("Intro") ? "battle1" : "battle2");
					break;
				default:
					name = null;
					break;
				}
				text2 = name;
				break;
			}
			case "7-3":
			{
				string text;
				switch (((Object)source).name)
				{
				case "CleanTheme":
					text = (((Object)source.clip).name.Contains("Intro") ? "clean1" : "clean2");
					break;
				case "BattleTheme":
				case "BossTheme":
					text = (((Object)source.clip).name.Contains("Intro") ? "battle1" : "battle2");
					break;
				default:
					text = null;
					break;
				}
				text2 = text;
				break;
			}
			case "7-4":
				text2 = ((Object)source.clip).name switch
				{
					"Centaur A-1" => "outside1", 
					"Centaur A-2" => "outside2", 
					"Centaur A-3" => "outside3", 
					"Centaur A-4" => "outside4", 
					"Centaur A-5" => "outside5", 
					"Centaur A-6" => "outside6", 
					"Centaur B-1" => "inside1", 
					"Centaur B-2" => "inside2", 
					"Centaur B-3" => "inside3", 
					"Centaur B-4" => "escape1", 
					"Centaur B-5" => "escape2", 
					"Centaur B-6" => "escape3", 
					_ => null, 
				};
				break;
			case "P-1":
				text2 = ((Object)source).name switch
				{
					"Sourire" => "intro1", 
					"Sourire 2" => "intro2", 
					"Sourire 3" => "intro3", 
					"Sourire 4" => "intro4", 
					"Chaos" => "boss1", 
					"IntroMusic" => "speech", 
					"Music 3" => "boss2", 
					_ => null, 
				};
				break;
			case "P-2":
				text2 = ((Object)source.clip).name switch
				{
					"Weihnachten Am Klavier Subtler" => "intro", 
					"Deep Drone 5B" => "weezer", 
					"P-2 Clean" => "clean", 
					"P-2" => "battle", 
					"Flesh panopticon" => "boss1", 
					"Sisyphus Prime Intro" => "speech", 
					"Sisyphus Prime" => "boss2", 
					_ => null, 
				};
				break;
			default:
			{
				string text;
				switch (((Object)source).name)
				{
				case "CleanTheme":
					text = "clean";
					break;
				case "BossTheme":
					if (CustomUST.ContainsKey(level + ":boss"))
					{
						text = "boss";
						break;
					}
					goto case "BattleTheme";
				case "BattleTheme":
					text = "battle";
					break;
				default:
					text = null;
					break;
				}
				text2 = text;
				break;
			}
			}
			string text3 = text2;
			if (text3 != null)
			{
				text3 = level + ":" + text3;
			}
			if (text3 != null && CustomUST.ContainsKey(text3))
			{
				source.clip = CustomUST[text3];
				if (pitchedTracks.Contains(text3))
				{
					source.pitch = 1f;
				}
			}
		}

		public static bool HandleMusicChanger(string level, MusicChanger changer)
		{
			if (!IsEnabled)
			{
				return true;
			}
			AudioClip clean = changer.clean;
			string obj = ((clean != null) ? ((Object)clean).name : null) ?? "NULL";
			AudioClip battle = changer.battle;
			string text = ((battle != null) ? ((Object)battle).name : null) ?? "NULL";
			AudioClip boss = changer.boss;
			string text2 = ((boss != null) ? ((Object)boss).name : null) ?? "NULL";
			if (obj.Contains("[UST]") || text.Contains("[UST]") || text2.Contains("[UST]"))
			{
				return false;
			}
			level = level.Replace("Level ", "");
			HandleChangerClip(level, "clean", ref changer.clean);
			HandleChangerClip(level, "battle", ref changer.battle);
			HandleChangerClip(level, "boss", ref changer.boss);
			return true;
		}

		private static void HandleChangerClip(string level, string flavor, ref AudioClip clip)
		{
			if (!((Object)(object)clip == (Object)null))
			{
				string text = level switch
				{
					"1-1" => HeartOfTheSunrise(((Object)clip).name), 
					"1-2" => TheBurningWorld(((Object)clip).name, flavor == "clean"), 
					"4-3" => AShotInTheDark(((Object)clip).name), 
					_ => null, 
				};
				if (text != null)
				{
					text = level + ":" + text;
				}
				if (text != null && CustomUST.ContainsKey(text))
				{
					clip = CustomUST[text];
				}
				else if (level == "1-1" && flavor == "clean" && CustomUST.ContainsKey("1-1:clean"))
				{
					clip = CustomUST["1-1:clean"];
				}
			}
		}

		private static string HeartOfTheSunrise(string clipName)
		{
			return clipName switch
			{
				"A Thousand Greetings" => "clean1", 
				"1-1 Clean" => "clean2", 
				"1-1" => "battle", 
				_ => null, 
			};
		}

		private static string TheBurningWorld(string clipName, bool clean)
		{
			return clipName switch
			{
				"A Thousand Greetings" => clean ? "clean0" : "battle0", 
				"1-2 Dark Clean" => "clean1", 
				"1-2 Noise Clean" => "clean2", 
				"1-2 Dark Battle" => "battle1", 
				"1-2 Noise Battle" => "battle2", 
				_ => null, 
			};
		}

		private static string AShotInTheDark(string clipName)
		{
			return clipName switch
			{
				"4-3 Phase 1 Clean" => "clean1", 
				"4-3 Phase 2 Clean" => "clean2", 
				"4-3 Phase 3 Clean" => "clean3", 
				"4-3 Phase 1" => "battle1", 
				"4-3 Phase 2" => "battle2", 
				"4-3 Phase 3" => "battle3", 
				_ => null, 
			};
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "USTManager";

		public const string PLUGIN_NAME = "USTManager";

		public const string PLUGIN_VERSION = "1.5.4";
	}
}
namespace USTManager.Utility
{
	public static class ConflictResolver
	{
		public static Conflict Merge(IEnumerable<CustomUST> usts)
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, List<CustomUST>> dictionary = new Dictionary<string, List<CustomUST>>();
			string key;
			foreach (CustomUST ust in usts)
			{
				foreach (KeyValuePair<string, Dictionary<string, string>> level in ust.Levels)
				{
					level.Deconstruct(out key, out var value);
					string text = key;
					Dictionary<string, string> dictionary2 = value;
					if (text == "global")
					{
						foreach (string key4 in dictionary2.Keys)
						{
							string key2 = "global:" + key4;
							dictionary.GetOrAdd(key2, new List<CustomUST>()).Add(ust);
						}
					}
					else
					{
						dictionary.GetOrAdd(text, new List<CustomUST>()).Add(ust);
					}
				}
			}
			Dictionary<string, List<CustomUST>> dictionary3 = new Dictionary<string, List<CustomUST>>();
			CustomUST customUST = new CustomUST
			{
				IsMerged = true
			};
			foreach (KeyValuePair<string, List<CustomUST>> item in dictionary)
			{
				item.Deconstruct(out key, out var value2);
				string text2 = key;
				List<CustomUST> list = value2;
				if (list.Count != 1)
				{
					dictionary3.Add(text2, list);
					continue;
				}
				CustomUST customUST2 = list[0];
				if (text2.StartsWith("global:"))
				{
					string key3 = text2.Substring(7);
					string value3 = customUST2.Levels["global"][key3];
					customUST.Levels.GetOrAdd("global", new Dictionary<string, string>()).Add(key3, value3);
				}
				else
				{
					customUST.Levels.Add(text2, customUST2.Levels[text2]);
				}
				Logging.Log("Merged " + text2 + " from " + customUST2.Name);
			}
			return new Conflict(customUST, dictionary3);
		}
	}
	public sealed class Conflict
	{
		[JsonProperty("UST")]
		private readonly CustomUST mergedUST;

		[JsonProperty("Conflicts")]
		private readonly Dictionary<string, List<CustomUST>> conflicts;

		[JsonProperty("Resolutions")]
		private readonly Dictionary<string, CustomUST> resolutions;

		[JsonProperty("Validated")]
		public bool Validated;

		[JsonIgnore]
		public IReadOnlyDictionary<string, List<CustomUST>> Conflicts => conflicts;

		public int ConflictCount => conflicts.Count;

		public int SolvedCount => resolutions.Count;

		[JsonConstructor]
		private Conflict()
		{
		}

		public Conflict(CustomUST ust, Dictionary<string, List<CustomUST>> conflictingKeys)
		{
			mergedUST = ust;
			conflicts = conflictingKeys;
			resolutions = new Dictionary<string, CustomUST>();
		}

		public void Resolve(string key, CustomUST UST)
		{
			//IL_003a: 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)
			if (conflicts.ContainsKey(key) && conflicts[key].Contains(UST))
			{
				Logging.Log("Resolved conflict for " + key + " with " + UST.Name);
				resolutions[key] = UST;
			}
		}

		public bool Validate(out CustomUST UST)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (Validated)
			{
				UST = mergedUST;
				return true;
			}
			if (ConflictCount > SolvedCount)
			{
				Logging.Log("Conflicts not solved");
				UST = null;
				return false;
			}
			Logging.Log("No remaining conflicts");
			foreach (var (text2, customUST2) in resolutions)
			{
				if (text2.StartsWith("global:"))
				{
					string key = text2.Substring(7);
					string value = customUST2.Levels["global"][key];
					mergedUST.Levels.GetOrAdd("global", new Dictionary<string, string>()).Add(key, value);
				}
				else
				{
					mergedUST.Levels.Add(text2, customUST2.Levels[text2]);
				}
			}
			Validated = true;
			UST = mergedUST;
			return true;
		}

		public CustomUST? GetMerged()
		{
			if (Validated)
			{
				return mergedUST;
			}
			return null;
		}
	}
	public static class Extensions
	{
		public static V GetOrAdd<K, V>(this Dictionary<K, V> dict, K key, V toAdd)
		{
			if (dict.TryGetValue(key, out V value))
			{
				return value;
			}
			dict.Add(key, toAdd);
			return toAdd;
		}

		public static bool FastStartsWith(this string str, string target)
		{
			if (str.Length < target.Length)
			{
				return false;
			}
			for (int i = 0; i < target.Length; i++)
			{
				if (str[i] != target[i])
				{
					return false;
				}
			}
			return true;
		}

		public static void Deconstruct<K, V>(this KeyValuePair<K, V> pair, out K key, out V val)
		{
			key = pair.Key;
			val = pair.Value;
		}

		public static string GetPath(this Transform transform)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			do
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			while ((Object)(object)val != (Object)null);
			list.Reverse();
			return list.Aggregate((string a, string b) => a + "/" + b);
		}
	}
	public class LegacyUSTConverter
	{
		public struct LegacyUST
		{
			public string Name;

			public string Author;

			public string Description;

			[JsonIgnore]
			public string Path;

			public Dictionary<string, LegacyUSTDescriptor[]> levels;
		}

		public struct LegacyUSTDescriptor
		{
			public string Part;

			public string Path;
		}

		public static List<LegacyUST> legacyUSTs = new List<LegacyUST>();

		public static bool IsLegacyUST(string path)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			string text = File.ReadAllText(path);
			try
			{
				LegacyUST item = JsonConvert.DeserializeObject<LegacyUST>(text);
				item.Path = path;
				legacyUSTs.Add(item);
				return true;
			}
			catch (JsonException val)
			{
				Logging.LogError((object)val);
				return false;
			}
		}

		public static void ConvertLegacyUSTs()
		{
			foreach (LegacyUST legacyUST in legacyUSTs)
			{
				CustomUST customUST = new CustomUST(legacyUST.Name, legacyUST.Author, legacyUST.Description);
				foreach (KeyValuePair<string, LegacyUSTDescriptor[]> level in legacyUST.levels)
				{
					Dictionary<string, string> dictionary = new Dictionary<string, string>();
					LegacyUSTDescriptor[] value = level.Value;
					for (int i = 0; i < value.Length; i++)
					{
						LegacyUSTDescriptor legacyUSTDescriptor = value[i];
						dictionary.Add(legacyUSTDescriptor.Part, legacyUSTDescriptor.Path);
					}
					customUST.Levels.Add(level.Key, dictionary);
				}
				string contents = JsonConvert.SerializeObject((object)customUST, (Formatting)1);
				File.WriteAllText(legacyUST.Path, contents);
			}
			legacyUSTs.Clear();
		}
	}
	public class ListenableProperty<T>
	{
		private T _Value;

		public T Value
		{
			get
			{
				return _Value;
			}
			set
			{
				if (!value.Equals(_Value))
				{
					_Value = value;
					this.OnValueChanged?.Invoke(value);
				}
			}
		}

		public event Action<T> OnValueChanged;

		private ListenableProperty(T value)
		{
			_Value = value;
		}

		public static implicit operator ListenableProperty<T>(T value)
		{
			return new ListenableProperty<T>(value);
		}

		public static implicit operator T(ListenableProperty<T> value)
		{
			return value.Value;
		}
	}
	public class Loader
	{
		public static AudioClip LoadClipFromPath(string path)
		{
			if (File.Exists(path))
			{
				switch (Path.GetExtension(path))
				{
				case ".wav":
				case ".mp3":
				case ".ogg":
				{
					UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)0);
					audioClip.SendWebRequest();
					while (!audioClip.isDone)
					{
					}
					AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
					((Object)content).name = "[UST] " + Path.GetFileNameWithoutExtension(path);
					return content;
				}
				}
			}
			return null;
		}
	}
	public static class Logging
	{
		public static void Log(object message, Color color = default(Color))
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0011: 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)
			if (color == default(Color))
			{
				color = Color.white;
			}
			Debug.Log((object)$"<color=#{ColorUtility.ToHtmlStringRGB(color)}>[USTManager]</color> {message}");
		}

		public static void LogError(object message, Color color = default(Color))
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0011: 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)
			if (color == default(Color))
			{
				color = Color.red;
			}
			Debug.LogError((object)$"<color=#{ColorUtility.ToHtmlStringRGB(color)}>[USTManager]</color> {message}");
		}
	}
	public class Toast : MonoBehaviour
	{
		public string Message;

		private TMP_Text Text;

		public float Duration = 2f;

		private void Start()
		{
			Text = ((Component)this).GetComponentInChildren<TMP_Text>();
		}

		private IEnumerator Life()
		{
			yield return (object)new WaitForSeconds(Duration);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		public static void Show(string message, float duration = 2f)
		{
			GameObject obj = Object.Instantiate<GameObject>(Plugin.ToastPrefab);
			obj.GetComponent<Toast>().Duration = duration;
			obj.GetComponent<Toast>().Message = message;
		}
	}
}
namespace USTManager.Preprocessor
{
	public abstract class BasePreprocessor
	{
		public abstract string Name { get; }

		public abstract string Version { get; }

		public abstract string Format { get; }

		public abstract void Apply(IEnumerable<AudioSource> sources);
	}
	public static class Registry
	{
		internal static List<BasePreprocessor> Preprocessors = new List<BasePreprocessor>();

		public static bool Register(BasePreprocessor preprocessor)
		{
			if (!Preprocessors.Contains(preprocessor))
			{
				Preprocessors.Add(preprocessor);
				return true;
			}
			return false;
		}

		public static bool UnRegister(BasePreprocessor preprocessor)
		{
			if (Preprocessors.Contains(preprocessor))
			{
				Preprocessors.Remove(preprocessor);
				return true;
			}
			return false;
		}
	}
}
namespace USTManager.Patches
{
	public static class AudioSourcePatches
	{
		[HarmonyPatch(typeof(StatsManager), "Awake")]
		[HarmonyPostfix]
		public static void StatsManagerAwake(StatsManager __instance)
		{
			if (!Manager.IsEnabled)
			{
				return;
			}
			List<AudioSource> list = (from x in Resources.FindObjectsOfTypeAll(typeof(GameObject))
				where Object.op_Implicit((Object)(object)((GameObject)((x is GameObject) ? x : null)).GetComponentInChildren<AudioSource>())
				select x).SelectMany((Object x) => ((GameObject)((x is GameObject) ? x : null)).GetComponentsInChildren<AudioSource>()).ToList();
			foreach (BasePreprocessor preprocessor in Registry.Preprocessors)
			{
				preprocessor.Apply(list);
			}
			foreach (AudioSource item in list)
			{
				if ((Object)(object)item.clip != (Object)null && (Object)(object)((Component)item).gameObject.GetComponent<USTTarget>() != (Object)null)
				{
					((Component)item).gameObject.AddComponent<USTTarget>();
				}
			}
		}

		[HarmonyPatch(typeof(AudioSource), "clip")]
		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void SetClip(AudioSource __instance, AudioClip value)
		{
			if ((Object)(object)value != (Object)null && (Object)(object)((Component)__instance).gameObject.GetComponent<USTTarget>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<USTTarget>();
			}
		}

		[HarmonyPatch(typeof(AddressablesExtensions), "ToAsset")]
		[HarmonyPostfix]
		public static void AddressablesExtensionsToAsset(ref GameObject __result)
		{
			if (!Object.op_Implicit((Object)(object)__result.GetComponentInChildren<AudioSource>()))
			{
				return;
			}
			AudioSource[] componentsInChildren = __result.GetComponentsInChildren<AudioSource>();
			foreach (AudioSource val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent<USTTarget>()))
				{
					((Component)val).gameObject.AddComponent<USTTarget>();
				}
			}
		}

		[HarmonyPatch(typeof(AddressablesExtensions), "ToAssets")]
		[HarmonyPostfix]
		public static void AddressablesExtensionsToAssets(ref GameObject[] __result)
		{
			GameObject[] array = __result;
			foreach (GameObject val in array)
			{
				if (!Object.op_Implicit((Object)(object)val.GetComponentInChildren<AudioSource>()))
				{
					continue;
				}
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
				foreach (AudioSource val2 in componentsInChildren)
				{
					if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<USTTarget>()))
					{
						((Component)val2).gameObject.AddComponent<USTTarget>();
					}
				}
			}
		}

		public static void DumpSceneHierarchy(string path)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				Transform[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<Transform>();
				foreach (Transform transform in componentsInChildren)
				{
					text = text + transform.GetPath() + "\n";
				}
			}
			File.WriteAllText(path, text);
		}

		[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { typeof(double) })]
		[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { })]
		[HarmonyPrefix]
		public static void Play(AudioSource __instance)
		{
			Manager.HandleAudioSource(SceneHelper.CurrentScene, __instance);
		}

		[HarmonyPatch(typeof(GameObject), "SetActive")]
		[HarmonyPrefix]
		public static void SetActive(GameObject __instance, bool value)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (SceneHelper.CurrentScene == "Level 5-4" && ((Object)__instance).name == "Music")
			{
				foreach (Transform item in __instance.transform)
				{
					((Component)item).gameObject.SetActive(false);
					((Component)item).gameObject.SetActive(true);
				}
				return;
			}
			AudioSource source = default(AudioSource);
			if (__instance.TryGetComponent<AudioSource>(ref source))
			{
				Manager.HandleAudioSource(SceneHelper.CurrentScene, source);
			}
		}

		[HarmonyPatch(typeof(Crossfade), "Awake")]
		[HarmonyPrefix]
		public static void Awake(Crossfade __instance)
		{
			AudioSource val = default(AudioSource);
			if (((Component)__instance).TryGetComponent<AudioSource>(ref val))
			{
				Manager.HandleAudioSource(SceneHelper.CurrentScene, val);
				if (val.playOnAwake)
				{
					val.Play();
				}
			}
		}

		[HarmonyPatch(typeof(MusicChanger), "Change")]
		[HarmonyPrefix]
		public static bool Change(MusicChanger __instance)
		{
			return Manager.HandleMusicChanger(SceneHelper.CurrentScene, __instance);
		}

		public static IEnumerator DestroyAfter(GameObject obj, float time)
		{
			yield return (object)new WaitForSeconds(time);
			Object.Destroy((Object)(object)obj);
		}
	}
	public static class MainMenuPatches
	{
		[HarmonyPatch(typeof(HudOpenEffect), "Awake")]
		[HarmonyPostfix]
		public static void SetActive(HudOpenEffect __instance)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Object)__instance).name != "Audio Options") && (Object)(object)((Component)((Component)__instance).transform.GetChild(0)).transform.Find("MenuEntry(Clone)") == (Object)null)
			{
				RectTransform component = ((Component)((Component)__instance).transform.GetChild(0)).GetComponent<RectTransform>();
				RectTransform component2 = ((Component)Object.Instantiate<GameObject>(Plugin.MenuEntryPrefab, (Transform)(object)component).transform.Find("Button")).GetComponent<RectTransform>();
				component2.offsetMax = new Vector2(380f, 20f);
				component2.offsetMin = new Vector2(220f, -20f);
				Button btn = ((Component)component2).GetComponent<Button>();
				((UnityEvent)btn.onClick).AddListener((UnityAction)delegate
				{
					Plugin.OpenMenu(((Component)btn).transform.parent.parent.parent);
				});
				Logging.Log("Added USTManager button to main menu");
			}
		}

		[HarmonyPatch(typeof(Console), "Awake")]
		[HarmonyPostfix]
		public static void Awake(Console __instance)
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)__instance == (Object)(object)MonoSingleton<Console>.Instance && !__instance.registeredCommandTypes.Contains(typeof(USTDebug)))
			{
				__instance.RegisterCommand((ICommand)(object)new USTToggle());
				__instance.RegisterCommand((ICommand)(object)new USTDebug());
			}
		}
	}
	public class USTTarget : MonoBehaviour
	{
		private bool Preprocessed;

		public void Awake()
		{
			AudioSource val = default(AudioSource);
			if (((Component)this).TryGetComponent<AudioSource>(ref val))
			{
				if (val.playOnAwake)
				{
					val.playOnAwake = false;
					val.Stop();
					Manager.HandleAudioSource(SceneHelper.CurrentScene, val);
					val.playOnAwake = true;
					val.Play();
				}
				else
				{
					Manager.HandleAudioSource(SceneHelper.CurrentScene, val);
				}
			}
		}

		public void OnEnable()
		{
			AudioSource val = default(AudioSource);
			if (((Component)this).TryGetComponent<AudioSource>(ref val))
			{
				if (val.playOnAwake)
				{
					val.playOnAwake = false;
					val.Stop();
					Manager.HandleAudioSource(SceneHelper.CurrentScene, val);
					val.playOnAwake = true;
					val.Play();
				}
				else
				{
					Manager.HandleAudioSource(SceneHelper.CurrentScene, val);
				}
			}
		}

		public void Start()
		{
		}

		public void Preprocess()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (Preprocessed)
			{
				return;
			}
			Logging.Log("Preprocessing " + ((Object)this).name, Color.cyan);
			foreach (BasePreprocessor preprocessor in Registry.Preprocessors)
			{
				preprocessor.Apply(new <>z__ReadOnlySingleElementList<AudioSource>(((Component)this).GetComponent<AudioSource>()));
			}
		}
	}
}
namespace USTManager.Misc
{
	public static class StaticResources
	{
		public static readonly string Readme = "# An UST is made up of 3 parts:\r\n\r\n- soundtrack.ust : It can be named anything BUT template.ust, otherwise your UST won't show up in game. This is the main file that contains all the information about the UST. Please use the template.ust file as a base.\r\n\r\n- Any .mp3, .ogg and .wav files : These are the audio files that the UST uses. They can be named anything.\r\n\r\n- icon.png : This is the icon that will be displayed in the selection screen. It HAS to be .png.\r\n\r\n# Some extra notes:\r\n\r\nUSTManager can replace any audio in the game if you know the name of the clip.\r\nSimply add a \"global\" entry to your .ust file and set \"Part\" to the clip name and \"Path\" to the path of the replacement.\r\n\r\nThere are 2 commands in game. One just enables or disables USTManager (ust.toggle) and the other makes getting clip names a bit easier (ust.debug).";
	}
}
namespace USTManager.Data
{
	[Serializable]
	public class CustomUST
	{
		[JsonProperty("levels", Order = 4)]
		public Dictionary<string, Dictionary<string, string>> Levels = new Dictionary<string, Dictionary<string, string>>();

		[JsonIgnore]
		public string Path;

		[JsonIgnore]
		public bool IsMerged;

		[JsonIgnore]
		public Color UserColor = Color.white;

		[JsonIgnore]
		public Sprite? Icon;

		[JsonProperty(Order = 0)]
		public string Name { get; private set; }

		[JsonProperty(Order = 1)]
		public string Author { get; private set; }

		[JsonProperty(Order = 2)]
		public string Description { get; private set; }

		[JsonIgnore]
		public string Format { get; private set; }

		public CustomUST()
		{
		}//IL_000c: 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)


		public CustomUST(string name, string author, string description)
		{
			//IL_000c: 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)
			Name = name;
			Author = author;
			Description = description;
		}

		public CustomUST(string name, string author, string description, string format)
		{
			//IL_000c: 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)
			Name = name;
			Author = author;
			Description = description;
			Format = format;
		}

		public static string GetTemplateJson()
		{
			Dictionary<string, string> value = TemplateLevel("clean", "battle");
			Dictionary<string, string> value2 = TemplateLevel("clean1", "clean2", "battle1", "battle2");
			CustomUST customUST = new CustomUST("Name", "Author", "Description");
			customUST.Format = "USTManager";
			customUST.Levels.Add("comments", new Dictionary<string, string> { { "Comment", "This is an example UST file. It will get regenerated each time you launch the game with USTManager installed. Omit any unused parts." } });
			customUST.Levels.Add("global", new Dictionary<string, string> { { "audioClipName", "relative/path/to/audio" } });
			customUST.Levels.Add("0-0", value);
			customUST.Levels.Add("0-1", value);
			customUST.Levels.Add("0-2", value);
			customUST.Levels.Add("0-3", value);
			customUST.Levels.Add("0-4", value);
			customUST.Levels.Add("0-5", TemplateLevel("boss1", "boss2"));
			customUST.Levels.Add("1-1", TemplateLevel("clean1", "clean2", "battle"));
			customUST.Levels.Add("1-2", TemplateLevel("clean0", "clean1", "clean2", "battle0", "battle1", "battle2"));
			customUST.Levels.Add("1-3", TemplateLevel("clean", "battle", "boss"));
			customUST.Levels.Add("1-4", TemplateLevel("piano", "intro", "boss"));
			customUST.Levels.Add("2-1", value);
			customUST.Levels.Add("2-2", value);
			customUST.Levels.Add("2-3", value);
			customUST.Levels.Add("2-4", TemplateLevel("boss1", "boss2"));
			customUST.Levels.Add("3-1", value2);
			customUST.Levels.Add("3-2", TemplateLevel("intro1", "intro2", "boss"));
			customUST.Levels.Add("4-1", value);
			customUST.Levels.Add("4-2", value);
			customUST.Levels.Add("4-3", TemplateLevel("clean1", "clean2", "clean3", "battle1", "battle2", "battle3"));
			customUST.Levels.Add("4-4", TemplateLevel("drone", "bassline", "intro", "boss", "outro"));
			customUST.Levels.Add("5-1", value);
			customUST.Levels.Add("5-2", TemplateLevel("boss1", "boss2", "boss3"));
			customUST.Levels.Add("5-3", value2);
			customUST.Levels.Add("5-4", TemplateLevel("boss1", "boss2"));
			customUST.Levels.Add("6-1", TemplateLevel("clean", "battle", "boss"));
			customUST.Levels.Add("6-2", TemplateLevel("boss"));
			customUST.Levels.Add("7-1", TemplateLevel("clean", "battle", "boss1", "boss2"));
			customUST.Levels.Add("7-2", value2);
			customUST.Levels.Add("7-3", value2);
			customUST.Levels.Add("7-4", TemplateLevel("outside1", "outside2", "outside3", "outside4", "outside5", "outside6", "inside1", "inside2", "inside3", "escape1", "escape2", "escape3"));
			customUST.Levels.Add("P-1", TemplateLevel("intro1", "intro2", "intro3", "intro4", "boss1", "speech", "boss2"));
			customUST.Levels.Add("P-2", TemplateLevel("intro", "weezer", "clean", "battle", "boss1", "speech", "boss2"));
			return JsonConvert.SerializeObject((object)customUST, (Formatting)1);
		}

		private static Dictionary<string, string> TemplateLevel(params string[] tracks)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string key in tracks)
			{
				dictionary[key] = "relative/path/to/audio";
			}
			return dictionary;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is CustomUST customUST))
			{
				return false;
			}
			if (customUST.Name != Name)
			{
				return false;
			}
			if (customUST.Author != Author)
			{
				return false;
			}
			if (customUST.Description != Description)
			{
				return false;
			}
			if (customUST.Levels.Count != Levels.Count)
			{
				return false;
			}
			foreach (string key in customUST.Levels.Keys)
			{
				if (!Levels.ContainsKey(key))
				{
					return false;
				}
				Dictionary<string, string> dictionary = Levels[key];
				Dictionary<string, string> dictionary2 = customUST.Levels[key];
				if (dictionary2.Count != dictionary.Count)
				{
					return false;
				}
				foreach (string key2 in dictionary2.Keys)
				{
					if (!dictionary.ContainsKey(key2))
					{
						return false;
					}
					if (dictionary2[key2] != dictionary[key2])
					{
						return false;
					}
				}
			}
			return true;
		}

		public override int GetHashCode()
		{
			throw new NotImplementedException();
		}
	}
	internal class LevelsDict
	{
		public struct LevelAudioDescriptor
		{
			public string clean;

			public string battle;

			public string boss;

			public List<string> extras;

			public LevelAudioDescriptor(string clean, string battle, string boss)
			{
				extras = new List<string>();
				this.clean = clean;
				this.battle = battle;
				this.boss = boss;
			}

			public LevelAudioDescriptor(string clean, string battle, string boss, List<string> extras)
			{
				this.extras = new List<string>();
				this.clean = clean;
				this.battle = battle;
				this.boss = boss;
				this.extras = extras;
			}

			public LevelAudioDescriptor(string clean, string battle, string boss, params string[] extras)
			{
				this.extras = new List<string>();
				this.clean = clean;
				this.battle = battle;
				this.boss = boss;
				this.extras = new List<string>(extras);
			}
		}

		private static readonly Dictionary<string, LevelAudioDescriptor> AudioSources = new Dictionary<string, LevelAudioDescriptor>
		{
			{
				"default",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"0-1",
				new LevelAudioDescriptor("0-1 Clean", "0-1", "0-1", "EXTRA")
			},
			{
				"0-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"0-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"0-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"0-5",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"1-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"1-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"1-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"1-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"2-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"2-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"2-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"2-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"3-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"3-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"4-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"4-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"4-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"4-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"5-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"5-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"5-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"5-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"6-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"6-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"7-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"7-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"7-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"7-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"8-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"8-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"8-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"8-4",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"9-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"9-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"0-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"1-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"2-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"4-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"5-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"7-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"8-S",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"P-1",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"P-2",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			},
			{
				"P-3",
				new LevelAudioDescriptor("CleanTheme", "BattleTheme", "BossTheme", "EXTRA")
			}
		};
	}
}
namespace USTManager.Commands
{
	public class USTToggle : ICommand
	{
		public string Name => "ust.toggle";

		public string Description => "Toggle UST";

		public string Command => "ust.toggle";

		public void Execute(Console con, string[] args)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Manager.IsEnabled = !Manager.IsEnabled;
			Logging.Log("UST is now " + Manager.IsEnabled);
		}
	}
	public class USTDebug : ICommand
	{
		public string Name => "ust.debug";

		public string Description => "Toggle UST Debug";

		public string Command => "ust.debug";

		public void Execute(Console con, string[] args)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length != 0)
			{
				if (bool.TryParse(args[0].ToLower(), out var result))
				{
					if (args.Length > 1)
					{
						if (args[1].ToLower() == "extended")
						{
							Manager.IsDebug = result;
							Manager.IsExtendedDebug = result;
							Logging.Log("UST Debug is now " + (Manager.IsDebug ? "enabled" : "disabled") + (Manager.IsExtendedDebug ? " in extended mode" : ""));
						}
					}
					else
					{
						Manager.IsDebug = result;
						Manager.IsExtendedDebug = !result && Manager.IsExtendedDebug;
						Logging.Log("UST Debug is now " + (Manager.IsDebug ? "enabled" : "disabled"));
					}
				}
				else
				{
					Logging.Log("Incorrect argument \"" + args[0] + "\"");
				}
			}
			else
			{
				Logging.Log("Not enough arguments");
			}
		}
	}
}
namespace USTManager.Resources
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resource1
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("USTManager.Resources.Resource1", typeof(Resource1).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] ust => (byte[])ResourceManager.GetObject("ust", resourceCulture);

		internal Resource1()
		{
		}
	}
}
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}