Decompiled source of MenuCleaner v1.0.3

UltrakillLayerConfigurator.dll

Decompiled 19 hours 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.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PluginConfig.API;
using Steamworks;
using TMPro;
using UltrakillLayerConfigurator.Data;
using UltrakillLayerConfigurator.Data.Layers;
using UltrakillLayerConfigurator.Patches;
using UltrakillLayerConfigurator.Scripts;
using UltrakillModLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UltrakillLayerConfigurator")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+98ffb30681c4a473fb602eb6e0156488686dee0f")]
[assembly: AssemblyProduct("UltrakillLayerConfigurator")]
[assembly: AssemblyTitle("UltrakillLayerConfigurator")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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;
		}
	}
}
namespace UltrakillLayerConfigurator
{
	[BepInPlugin("net.zephyr.ultrakill.LayerConfigurator", "Menu Cleaner", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LayerPlugin : BaseUnityPlugin
	{
		internal static DebugLog Log;

		private PluginConfigurator config;

		public const string ModName = "Zephyr's Menu Cleaner";

		public const string ModPath = "net.zephyr.ultrakill.LayerConfigurator";

		private const string ConfigLocationButtonName = "Open CONFIG Folder";

		private const string FeedbackButtonName = "Send FEEDBACK / REPORT BUG (discord)";

		public static bool isBillionNemesisInstalled;

		public static LayerPlugin Instance { get; private set; }

		public LayerPlugin()
		{
			Instance = this;
			CreateConfig();
		}

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			Harmony val = new Harmony("net.zephyr.ultrakill.LayerConfigurator");
			val.CreateClassProcessor(typeof(ChapterSelectButtonPatch)).Patch();
			val.CreateClassProcessor(typeof(DifficultySelectButtonPatch)).Patch();
			val.CreateClassProcessor(typeof(GearCheckEnablerPatch)).Patch();
			val.CreateClassProcessor(typeof(GetMissionName)).Patch();
			if (Chainloader.PluginInfos.ContainsKey("billy.billionnemesis"))
			{
				val.CreateClassProcessor(typeof(BillionRankStuffPatch)).Patch();
			}
			Log = new DebugLog("Zephyr's Menu Cleaner", ConsoleColor.DarkCyan, false);
			Log.Log("The goop is in the bag.");
		}

		private void Start()
		{
			isBillionNemesisInstalled = Chainloader.PluginInfos.ContainsKey("billy.billionnemesis");
			if (isBillionNemesisInstalled)
			{
				Log.Log("BILLION NEMESIS is ACTIVE");
			}
			foreach (string key in Chainloader.PluginInfos.Keys)
			{
				PluginInfo val = Chainloader.PluginInfos[key];
				string location = val.Location;
				string fileName = Path.GetFileName(location);
				location = location.Replace(fileName, "");
				if (Directory.Exists(location))
				{
					Log.LogDebug("FILE PATH: " + location + " \n EXISTS");
					string[] files = Directory.GetFiles(location, "*.json", SearchOption.AllDirectories);
					string[] array = files;
					foreach (string path in array)
					{
						JsonReader.RegisterFullPath(key, path);
					}
				}
			}
		}

		private void Update()
		{
		}

		private void SetIcon()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_006a: 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)
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, "icon.png");
			if (!string.IsNullOrEmpty(text))
			{
				byte[] array = File.ReadAllBytes(text);
				if (array.Length != 0)
				{
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					ImageConversion.LoadImage(val, array);
					Sprite image = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					config.image = image;
				}
			}
		}

		private void CreateConfig()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			config = PluginConfigurator.Create("Zephyr's Menu Cleaner", "net.zephyr.ultrakill.LayerConfigurator");
			SetIcon();
			ConfigPanel configLocationButton = new ConfigPanel(config.rootPanel, "Open CONFIG Folder", "feedback_button", (PanelFieldType)3);
			configLocationButton.onPannelOpenEvent += (OpenPanelEventDelegate)delegate
			{
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				string text = Path.Combine(directoryName, "data/");
				Application.OpenURL(directoryName);
				configLocationButton.ClosePanel();
			};
			ConfigPanel feedbackButton = new ConfigPanel(config.rootPanel, "Send FEEDBACK / REPORT BUG (discord)", "feedback_button", (PanelFieldType)3);
			feedbackButton.onPannelOpenEvent += (OpenPanelEventDelegate)delegate
			{
				Process.Start("https://discord.gg/KcsjvKa6jw");
				feedbackButton.ClosePanel();
			};
		}

		private static Sprite SetUserIcon(Friend friend)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0040: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject();
			RawImage val2 = val.AddComponent<RawImage>();
			SteamController.FetchAvatar(val2, friend);
			Texture2D val3 = FlipTexture((Texture2D)val2.texture);
			Sprite result = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), Vector2.one * 0.5f);
			Object.Destroy((Object)(object)val);
			return result;
		}

		private static Texture2D FlipTexture(Texture2D original)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(((Texture)original).width, ((Texture)original).height);
			for (int i = 0; i < ((Texture)original).width; i++)
			{
				for (int j = 0; j < ((Texture)original).height; j++)
				{
					val.SetPixel(i, ((Texture)original).height - j - 1, original.GetPixel(i, j));
				}
			}
			val.Apply();
			return val;
		}
	}
}
namespace UltrakillLayerConfigurator.Scripts
{
	public class ChapterTitle : MonoBehaviour
	{
		public List<Button> buttons = new List<Button>();

		public ChapterTitle? previous;

		public string name;

		private ChapterTitle()
		{
			name = ((TMP_Text)((Component)((Component)this).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text;
		}

		private void OnEnable()
		{
			((TMP_Text)((Component)((Component)this).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = name;
			if (buttons.Count == 0 || !((Object)(object)previous != (Object)null))
			{
				return;
			}
			bool flag = true;
			foreach (Button button in previous.buttons)
			{
				if (((Component)button).gameObject.activeSelf)
				{
					flag = false;
				}
			}
			if (flag)
			{
				if (((TMP_Text)((Component)((Component)previous).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower().Contains("secondary"))
				{
					((TMP_Text)((Component)((Component)this).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = ((TMP_Text)((Component)((Component)previous).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text;
				}
				((Component)previous).gameObject.SetActive(false);
			}
		}
	}
	[DefaultExecutionOrder(5000)]
	public class CustomMainMenuManager : MonoBehaviour
	{
		private GameObject canvas;

		private GameObject gameController;

		private GameObject mainMenu;

		private GameObject difficultySelection;

		private GameObject chapterSelection;

		private GameObject chapters;

		private bool _updatedDifficulties = false;

		private bool _updatedChapters = false;

		private bool _updatedLayers = false;

		private bool _openedDifficulties = false;

		private bool _openedChapters = false;

		private ScrollRect _difficultyRect;

		private static readonly Type PluginType = AccessTools.TypeByName("BillionNemesis.Plugin");

		private static readonly Dictionary<int, Sprite> PanelIconCache = new Dictionary<int, Sprite>();

		public static readonly Dictionary<int, string> NameCache = new Dictionary<int, string>();

		public static readonly Dictionary<ChapterSelectButton, Color> ChapterPRankColorCache = new Dictionary<ChapterSelectButton, Color>();

		public static readonly Dictionary<LayerSelect, Color> LayerPRankColorCache = new Dictionary<LayerSelect, Color>();

		public static readonly Dictionary<LevelSelectPanel, Color> LevelPRankColorCache = new Dictionary<LevelSelectPanel, Color>();

		public static readonly Dictionary<ChapterSelectButton, Color> ChapterBaseColorCache = new Dictionary<ChapterSelectButton, Color>();

		public static readonly Dictionary<LayerSelect, Color> LayerBaseColorCache = new Dictionary<LayerSelect, Color>();

		public static readonly Dictionary<LevelSelectPanel, Color> LevelBaseColorCache = new Dictionary<LevelSelectPanel, Color>();

		public static CustomMainMenuManager Instance { get; private set; }

		public static void Create()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)Instance) || Object.FindObjectsOfType<CustomMainMenuManager>().Length == 0)
			{
				GameObject val = new GameObject("CustomMainMenuManager");
				CustomMainMenuManager instance = val.AddComponent<CustomMainMenuManager>();
				Instance = instance;
			}
		}

		private void Start()
		{
			LevelSelectPanel[] array = Object.FindObjectsByType<LevelSelectPanel>((FindObjectsInactive)1, (FindObjectsSortMode)1);
			foreach (LevelSelectPanel val in array)
			{
				int num = val.levelNumber;
				if (num == 100 || num == 666)
				{
					num += val.levelNumberInLayer - 1;
				}
				PanelIconCache.TryAdd(num, ((Component)((Component)val).transform.Find("Image")).GetComponent<Image>().sprite);
			}
			canvas = GameObject.Find("/Canvas");
			gameController = GameObject.Find("GameController");
			JsonReader.ChapterNumber = 999;
		}

		private void LateUpdate()
		{
			if ((Object)(object)canvas != (Object)null)
			{
				RedoDifficulties();
				RedoChapters();
			}
		}

		private async void RedoLayers()
		{
			if (_updatedLayers || !Object.op_Implicit((Object)(object)chapterSelection))
			{
				return;
			}
			Transform parent = chapterSelection.transform.parent;
			Transform ChapterBaseTransform = parent.Find("Level Select (Act I)");
			if (!Object.op_Implicit((Object)(object)ChapterBaseTransform))
			{
				return;
			}
			Stopwatch sw = Stopwatch.StartNew();
			GameObject ChapterTemplate = Object.Instantiate<GameObject>(((Component)ChapterBaseTransform).gameObject, parent);
			((Object)ChapterTemplate).name = "Chapter";
			ScrollRect scroll = ChapterTemplate.GetComponentInChildren<ScrollRect>();
			GameObject layerTemplate = Object.Instantiate<GameObject>(((Component)((Component)scroll.content).transform.Find("Layer 1 Limbo")).gameObject, ((Component)scroll.content).transform);
			((Object)layerTemplate).name = "Layer";
			foreach (Transform item in ((Component)scroll.content).transform)
			{
				Transform child = item;
				if ((Object)(object)((Component)child).gameObject != (Object)(object)layerTemplate)
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
			GameObject levelRow = ((Component)layerTemplate.transform.Find("Level Row")).gameObject;
			GameObject levelTemplate = Object.Instantiate<GameObject>(((Component)levelRow.transform.GetChild(0)).gameObject, levelRow.transform);
			((Object)levelTemplate).name = "Level";
			foreach (Transform item2 in levelRow.transform)
			{
				Transform child2 = item2;
				if ((Object)(object)((Component)child2).gameObject != (Object)(object)levelTemplate)
				{
					Object.Destroy((Object)(object)((Component)child2).gameObject);
				}
			}
			_updatedLayers = true;
			await JsonReader.PopulateCategories();
			foreach (string category in JsonReader.ChapterCategoriesWithButtons.Keys)
			{
				for (int i = 0; i < JsonReader.ChapterCategoriesWithButtons[category].Count; i++)
				{
					Button b = JsonReader.ChapterCategoriesWithButtons[category][i];
					ChapterSelectButton chapSelect = ((Component)b).GetComponent<ChapterSelectButton>();
					if ((Object)(object)chapSelect == (Object)null)
					{
						continue;
					}
					string buttonName = ((TMP_Text)((Component)((Component)b).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower();
					if (!JsonReader.ChapterDefinitions.ContainsKey(buttonName))
					{
						continue;
					}
					ChapterEntry entry = JsonReader.ChapterDefinitions[buttonName];
					ChapterBaseColorCache.Add(chapSelect, ChapterDatabase.ToColor(entry.DefaultColor));
					ChapterPRankColorCache.Add(chapSelect, ChapterDatabase.ToColor(entry.PrankColor));
					GameObject chapterBase = Object.Instantiate<GameObject>(((Component)ChapterBaseTransform).gameObject, parent);
					((Object)chapterBase).name = entry.Name;
					chapterBase.GetComponent<LevelSelectAct>();
					Button button = ((Component)chapSelect).GetComponent<Button>();
					button.onClick = new ButtonClickedEvent();
					((UnityEvent)button.onClick).AddListener((UnityAction)delegate
					{
						chapterSelection.SetActive(false);
						chapterBase.SetActive(true);
					});
					MenuActSelect menuActSelect = ((Component)chapSelect).GetComponent<MenuActSelect>();
					menuActSelect.nameWhenDisabled = entry.DisabledName;
					menuActSelect.requiredLevels = entry.RequiredLevels;
					menuActSelect.hideWhenOff = entry.HideWhenOff;
					menuActSelect.primeLevels = entry.PrimeLevels;
					menuActSelect.forceOff = entry.ForceOff;
					ScrollRect scrollRect = chapterBase.GetComponentInChildren<ScrollRect>();
					foreach (Transform item3 in ((Component)scrollRect.content).transform)
					{
						Transform child3 = item3;
						Object.Destroy((Object)(object)((Component)child3).gameObject);
					}
					List<LayerSelect> layers = new List<LayerSelect>();
					foreach (LayerEntry layer in entry.Layers)
					{
						GameObject layerObject = Object.Instantiate<GameObject>(layerTemplate, ((Component)scrollRect.content).transform);
						((Object)layerObject).name = layer.Name;
						LayerSelect l = layerObject.GetComponent<LayerSelect>();
						LayerBaseColorCache.Add(l, ChapterDatabase.ToColor(layer.DefaultColor));
						LayerPRankColorCache.Add(l, ChapterDatabase.ToColor(layer.PrankColor));
						layers.Add(l);
						l.layerNumber = layer.LayerNumber;
						l.levelAmount = layer.Missions.Count;
						LayerPlugin.Log.LogDebug(l.levelAmount + " levels in layer " + l.layerNumber);
						l.noSecretMission = layer.SecretMission.LevelNumber == -1;
						if (!l.noSecretMission)
						{
							l.secretMissionPanel.missionNumber = layer.SecretMission.LevelNumber;
						}
						Button secretLevelButton = ((Component)l.secretMissionPanel).GetComponent<Button>();
						secretLevelButton.onClick = new ButtonClickedEvent();
						((UnityEvent)secretLevelButton.onClick).AddListener((UnityAction)delegate
						{
							gameController.GetComponent<OptionsManager>().ChangeLevelAbrupt("Level " + layer.SecretMission.LeaderboardLevel);
						});
						GameObject Header = ((Component)layerObject.transform.GetChild(0)).gameObject;
						((TMP_Text)Header.GetComponentInChildren<TextMeshProUGUI>()).text = layer.Name;
						GameObject levels = ((Component)layerObject.transform.GetChild(1)).gameObject;
						foreach (Transform item4 in levels.transform)
						{
							Transform child4 = item4;
							Object.Destroy((Object)(object)((Component)child4).gameObject);
						}
						foreach (MissionEntry mission in layer.Missions)
						{
							GameObject levelObject = Object.Instantiate<GameObject>(levelTemplate, levels.transform);
							Button levelButton = levelObject.GetComponent<Button>();
							levelButton.onClick = new ButtonClickedEvent();
							((UnityEvent)levelButton.onClick).AddListener((UnityAction)delegate
							{
								gameController.GetComponent<OptionsManager>().ChangeLevelAbrupt("Level " + mission.LeaderboardLevel);
							});
							((Object)levelObject).name = mission.Name;
							LevelSelectPanel level = levelObject.GetComponent<LevelSelectPanel>();
							LevelBaseColorCache.Add(level, ChapterDatabase.ToColor(mission.DefaultColor));
							LevelPRankColorCache.Add(level, ChapterDatabase.ToColor(mission.PrankColor));
							level.levelNumberInLayer = layer.Missions.IndexOf(mission) + 1;
							level.levelNumber = mission.LevelNumber;
							if (mission.Name != "")
							{
								((TMP_Text)((Component)((Component)level).transform.Find("Name")).GetComponent<TextMeshProUGUI>()).text = mission.Name;
								NameCache[level.levelNumber] = mission.Name;
							}
							if (string.IsNullOrWhiteSpace(mission.UnlockedThumbnailPath))
							{
								int num = mission.LevelNumber;
								if (num == 100 || num == 666)
								{
									num += level.levelNumberInLayer - 1;
									((Component)level.challengeIcon).gameObject.SetActive(false);
									level.challengeIcon = null;
									RectTransform rank = ((Component)((Component)level).transform.Find("Stats").Find("Rank")).GetComponent<RectTransform>();
									rank.anchorMin = new Vector2(0.5f, 0f);
									rank.anchorMax = new Vector2(0.5f, 0f);
									rank.pivot = new Vector2(0.5f, 0.5f);
									rank.offsetMin = new Vector2(-30f, 10f);
									rank.offsetMax = new Vector2(30f, 70f);
								}
								((Component)((Component)level).transform.Find("Image")).GetComponent<Image>().sprite = PanelIconCache[num];
							}
							level.leaderboardPanel.GetComponent<LevelSelectLeaderboard>().layerLevelNumber = mission.LeaderboardLevel;
						}
					}
					chapSelect.layersInChapter = layers.ToArray();
					chapSelect.CheckScore();
					foreach (LayerSelect layer2 in layers)
					{
						LevelSelectPanel[] componentsInChildren = ((Component)layer2).GetComponentsInChildren<LevelSelectPanel>(true);
						LevelSelectPanel[] array = componentsInChildren;
						for (int num2 = 0; num2 < array.Length; num2++)
						{
							_ = array[num2];
						}
					}
				}
			}
			sw.Stop();
			LayerPlugin.Log.Log($"Loaded Layers in {sw.ElapsedMilliseconds} ms");
		}

		private async void RedoChapters()
		{
			await Task.Delay(50);
			if (!_updatedChapters)
			{
				Transform search = canvas.transform.Find("Chapter Select");
				if ((Object)(object)search == (Object)null)
				{
					return;
				}
				chapterSelection = ((Component)search).gameObject;
				if (!Object.op_Implicit((Object)(object)chapterSelection))
				{
					return;
				}
				Stopwatch sw = Stopwatch.StartNew();
				chapters = ((Component)chapterSelection.transform.Find("Chapters")).gameObject;
				Button[] allChapters = chapters.GetComponentsInChildren<Button>(true);
				List<Button> allButtons = new List<Button>(allChapters);
				if (allButtons.Count == 0)
				{
					return;
				}
				_updatedChapters = true;
				GameObject primary = ((Component)chapters.transform.Find("Primary")).gameObject;
				GameObject secondary = ((Component)chapters.transform.Find("Secondary")).gameObject;
				Object.Destroy((Object)(object)secondary);
				if (LayerPlugin.isBillionNemesisInstalled)
				{
					GameObject DifficultyTitle = ((Component)chapterSelection.transform.Find("Title (2)")).gameObject;
					string text = ((TMP_Text)DifficultyTitle.GetComponent<TextMeshProUGUI>()).text;
					text = text.Replace("\n<color=#ff00af>(NEMESIS)</color>", "");
					((TMP_Text)DifficultyTitle.GetComponent<TextMeshProUGUI>()).text = text;
					GameObject preludeButtonOriginal = ((Component)chapters.transform.Find("Prelude")).gameObject;
					ChapterSelectButton chapter0 = preludeButtonOriginal.GetComponent<ChapterSelectButton>();
					GameObject actIButtonOriginal = ((Component)chapters.transform.Find("Act I")).gameObject;
					ChapterSelectButton chapter1 = actIButtonOriginal.GetComponent<ChapterSelectButton>();
					GameObject actIiButtonOriginal = ((Component)chapters.transform.Find("Act II")).gameObject;
					ChapterSelectButton chapter2 = actIiButtonOriginal.GetComponent<ChapterSelectButton>();
					GameObject actIiiButtonOriginal = ((Component)chapters.transform.Find("Act III")).gameObject;
					ChapterSelectButton chapter3 = actIiiButtonOriginal.GetComponent<ChapterSelectButton>();
					Type changedInfoType = AccessTools.TypeByName("BillionNemesis.ChangedInfo");
					if (changedInfoType != null)
					{
						object value = AccessTools.Field(changedInfoType, "ChangedChapters")?.GetValue(null);
						IEnumerable<string> changedChapters = value as IEnumerable<string>;
						if (changedChapters != null)
						{
							if (changedChapters.Contains(((Object)chapter0).name))
							{
								GameObject preludeButton = Object.Instantiate<GameObject>(preludeButtonOriginal, chapterSelection.transform);
								((TMP_Text)((Component)preludeButton.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "<color=#ff00af>[NEMESIS]</color> PRELUDE";
								allButtons.Add(preludeButton.GetComponent<Button>());
							}
							if (changedChapters.Contains(((Object)chapter1).name))
							{
								GameObject actIButton = Object.Instantiate<GameObject>(actIButtonOriginal, chapterSelection.transform);
								((TMP_Text)((Component)actIButton.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "<color=#ff00af>[NEMESIS]</color> ACT I";
								allButtons.Add(actIButton.GetComponent<Button>());
							}
							if (changedChapters.Contains(((Object)chapter2).name))
							{
								GameObject actIiButton = Object.Instantiate<GameObject>(actIiButtonOriginal, chapterSelection.transform);
								((TMP_Text)((Component)actIiButton.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "<color=#ff00af>[NEMESIS]</color> ACT II";
								allButtons.Add(actIiButton.GetComponent<Button>());
							}
							if (changedChapters.Contains(((Object)chapter3).name))
							{
								GameObject actIiiButton = Object.Instantiate<GameObject>(actIiiButtonOriginal, chapterSelection.transform);
								((TMP_Text)((Component)actIiiButton.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "<color=#ff00af>[NEMESIS]</color> ACT III";
								allButtons.Add(actIiiButton.GetComponent<Button>());
							}
						}
					}
				}
				LayerPlugin.Log.LogDebug("LOAD ALL CHAPTERS");
				await JsonReader.LoadAllChapters(allButtons);
				LayerPlugin.Log.LogDebug($"CREATE TITLES [{JsonReader.ChapterCategoriesWithButtons.Keys.Count}]");
				ChapterTitle previousChapterTitle = null;
				foreach (string s in JsonReader.ChapterCategoriesWithButtons.Keys)
				{
					GameObject title = Object.Instantiate<GameObject>(primary, chapters.transform);
					title.transform.localScale = Vector3.one;
					((TMP_Text)((Component)title.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = s;
					ChapterTitle chapterTitle = title.AddComponent<ChapterTitle>();
					chapterTitle.buttons = JsonReader.ChapterCategoriesWithButtons[s];
					if (Object.op_Implicit((Object)(object)previousChapterTitle))
					{
						chapterTitle.previous = previousChapterTitle;
					}
					previousChapterTitle = chapterTitle;
				}
				Object.Destroy((Object)(object)primary);
				await SortChapters(chapters);
				ScrollRect rect = CreateChapterScrollView(chapters.GetComponent<RectTransform>(), chapterSelection.transform);
				rect.normalizedPosition = new Vector2(0f, 1f);
				sw.Stop();
				LayerPlugin.Log.Log($"Loaded Chapters in {sw.ElapsedMilliseconds} ms");
			}
			else if (Object.op_Implicit((Object)(object)chapterSelection) && Object.op_Implicit((Object)(object)chapters))
			{
				Button[] allChapters2 = chapters.GetComponentsInChildren<Button>(true);
				List<Button> allButtons2 = new List<Button>(allChapters2);
				if (JsonReader.ChapterNumber != allButtons2.Count && allButtons2.Count != 0)
				{
					LayerPlugin.Log.LogDebug($"{JsonReader.ChapterNumber} != {allButtons2.Count}");
					await JsonReader.SortAllChapters(allButtons2);
					await SortChapters(chapters);
				}
			}
		}

		private async Task SortChapters(GameObject parent)
		{
			Dictionary<string, Transform> titles = new Dictionary<string, Transform>();
			List<Transform> buttons = new List<Transform>();
			for (int i = 0; i < parent.transform.childCount; i++)
			{
				Transform t = parent.transform.GetChild(i);
				if ((Object)(object)((Component)t).GetComponent<Button>() != (Object)null)
				{
					buttons.Add(t);
					continue;
				}
				string s = ((TMP_Text)((Component)t.GetChild(0)).GetComponent<TextMeshProUGUI>()).text;
				titles[s] = t;
			}
			if (buttons.Count == 0)
			{
				return;
			}
			LayerPlugin.Log.LogDebug("DETACH FROM [" + ((Object)parent).name + " (" + ((Object)parent.transform.parent).name + ")]");
			parent.transform.DetachChildren();
			for (int j = 0; j < JsonReader.ChapterCategoriesWithButtons.Keys.Count; j++)
			{
				string category = JsonReader.ChapterCategoriesWithButtons.Keys.ToArray()[j];
				if (!titles.ContainsKey(category))
				{
					continue;
				}
				titles[category].SetParent(parent.transform);
				LayerPlugin.Log.LogDebug("[" + category + "]");
				foreach (Button b in JsonReader.ChapterCategoriesWithButtons[category])
				{
					((Component)b).transform.SetParent(parent.transform);
					LayerPlugin.Log.LogDebug("[" + ((Object)b).name + "] attached to [" + ((Object)parent).name + "]");
					if (!LayerPlugin.isBillionNemesisInstalled || !((TMP_Text)((Component)((Component)b).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower().Contains("nemesis"))
					{
						continue;
					}
					((UnityEvent)b.onClick).AddListener((UnityAction)delegate
					{
						if (PluginType != null)
						{
							object obj = AccessTools.Field(PluginType, "IsEnabled")?.GetValue(null);
							if (obj != null)
							{
								AccessTools.Method(obj.GetType(), "SetValue", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { true });
							}
						}
						((Component)b).GetComponent<ChapterSelectButton>().CheckScore();
					});
				}
			}
			List<GameObject> toActivate = new List<GameObject>();
			for (int i2 = 0; i2 < parent.transform.childCount; i2++)
			{
				toActivate.Add(((Component)parent.transform.GetChild(i2)).gameObject);
			}
			parent.GetComponent<ObjectActivateInSequence>().objectsToActivate = toActivate.ToArray();
		}

		private async void RedoDifficulties()
		{
			if (!_updatedDifficulties)
			{
				Transform search = canvas.transform.Find("Difficulty Select (1)");
				if ((Object)(object)search == (Object)null)
				{
					return;
				}
				difficultySelection = ((Component)search).gameObject;
				if (!Object.op_Implicit((Object)(object)difficultySelection))
				{
					return;
				}
				Stopwatch sw = Stopwatch.StartNew();
				GameObject interactables = ((Component)difficultySelection.transform.Find("Interactables")).gameObject;
				_updatedDifficulties = true;
				ObjectActivateInSequence seq = interactables.GetComponent<ObjectActivateInSequence>();
				DifficultySelectButton[] allDifficulties = (DifficultySelectButton[])(object)Object.FindObjectsOfType(typeof(DifficultySelectButton), true);
				await JsonReader.LoadAllDifficulties(allDifficulties);
				List<GameObject> objectsToActivate = new List<GameObject>();
				GameObject title = ((Component)interactables.transform.Find("Title")).gameObject;
				GameObject tip = ((Component)interactables.transform.Find("Assist Tip")).gameObject;
				objectsToActivate.Add(title);
				_difficultyRect = CreateDifficultyScrollView(interactables.transform);
				DifficultyMenuCategoryObject difObj = new DifficultyMenuCategoryObject(interactables);
				for (int i = 0; i < JsonReader.DifficultyCategoriesWithButtons.Keys.Count; i++)
				{
					string category = JsonReader.DifficultyCategoriesWithButtons.Keys.ToArray()[i];
					GameObject t = difObj.CreateNew(ref objectsToActivate, category, JsonReader.DifficultyCategoriesWithButtons[category]);
					t.transform.SetParent((Transform)(object)_difficultyRect.content);
					t.transform.localScale = new Vector3(1f, 1f, 1f);
					t.GetComponent<LayoutElement>().preferredHeight = 90 + JsonReader.DifficultyCategoriesWithButtons[category].Count * 55;
					RectTransform component = t.GetComponent<RectTransform>();
					component.offsetMax += new Vector2(0f, 100f);
				}
				difObj.Destroy();
				LayerPlugin.Log.Log(allDifficulties.Length + " DIFFICULTIES FOUND!");
				if (allDifficulties.Length <= 6)
				{
					((Component)_difficultyRect.verticalScrollbar).gameObject.SetActive(false);
					_difficultyRect.scrollSensitivity = 0f;
					_difficultyRect.vertical = false;
					_difficultyRect.verticalScrollbar = null;
				}
				objectsToActivate.Add(tip);
				GameObject[] objectsToActivate2 = seq.objectsToActivate;
				foreach (GameObject go in objectsToActivate2)
				{
					if (!objectsToActivate.Contains(go))
					{
						Object.Destroy((Object)(object)go);
					}
				}
				seq.objectsToActivate = objectsToActivate.ToArray();
				LayoutRebuilder.ForceRebuildLayoutImmediate(_difficultyRect.content);
				_difficultyRect.normalizedPosition = new Vector2(0f, 1f);
				sw.Stop();
				LayerPlugin.Log.Log($"Loaded Difficulties in {sw.ElapsedMilliseconds} ms");
			}
			else if (Object.op_Implicit((Object)(object)difficultySelection) && Object.op_Implicit((Object)(object)_difficultyRect) && _openedDifficulties != difficultySelection.activeSelf)
			{
				_openedDifficulties = difficultySelection.activeSelf;
				_difficultyRect.normalizedPosition = new Vector2(0f, 1f);
			}
		}

		public static ScrollRect CreateChapterScrollView(RectTransform content, Transform parent)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			ScrollRect val = CreateScrollView("Chapter", parent);
			val.content = content;
			((Component)val.content).transform.SetParent(((Component)val.viewport).transform, false);
			ContentSizeFitter val2 = ((Component)val.content).gameObject.AddComponent<ContentSizeFitter>();
			val2.verticalFit = (FitMode)2;
			for (int i = 0; i < ((Transform)val.content).childCount; i++)
			{
				GameObject gameObject = ((Component)((Component)val.content).transform.GetChild(i)).gameObject;
				LayoutElement val3 = gameObject.AddComponent<LayoutElement>();
				val3.preferredHeight = 54f;
			}
			val.scrollSensitivity = 5f;
			val.elasticity = 0.1f;
			val.viewport.anchorMax = new Vector2(1f, 1f);
			val.viewport.anchorMin = new Vector2(0f, 0f);
			val.viewport.offsetMin = new Vector2(0f, 0f);
			val.viewport.offsetMax = new Vector2(0f, 0f);
			val.content.anchorMax = new Vector2(1f, 1f);
			val.content.anchorMin = new Vector2(0f, 0f);
			val.content.offsetMin = new Vector2(0f, 0f);
			val.content.offsetMax = new Vector2(0f, 0f);
			val.content.pivot = new Vector2(0.5f, 1f);
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			component.anchorMax = new Vector2(1f, 1f);
			component.anchorMin = new Vector2(0f, 0f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.offsetMin = new Vector2(0f, 50f);
			component.offsetMax = new Vector2(0f, -150f);
			component.sizeDelta = new Vector2(0f, -200f);
			RectTransform component2 = ((Component)val.verticalScrollbar).GetComponent<RectTransform>();
			component2.pivot = new Vector2(0f, 0.5f);
			component2.anchorMin = new Vector2(0.5f, 0f);
			component2.anchorMax = new Vector2(0.5f, 1f);
			component2.offsetMax = new Vector2(240f, 0f);
			component2.offsetMin = new Vector2(220f, 0f);
			return val;
		}

		public static ScrollRect CreateDifficultyScrollView(Transform parent)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			ScrollRect val = CreateScrollView("Difficulty", parent);
			val.scrollSensitivity = 5f;
			val.elasticity = 0.1f;
			val.viewport.anchorMax = new Vector2(1f, 1f);
			val.viewport.anchorMin = new Vector2(0f, 0f);
			val.viewport.offsetMin = new Vector2(0f, 0f);
			val.viewport.offsetMax = new Vector2(0f, 0f);
			val.content.anchorMax = new Vector2(1f, 1f);
			val.content.anchorMin = new Vector2(0f, 0f);
			val.content.offsetMin = new Vector2(24.85f, 0f);
			val.content.offsetMax = new Vector2(0f, 0f);
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			component.anchorMax = new Vector2(0f, 1f);
			component.anchorMin = new Vector2(0f, 0f);
			component.pivot = new Vector2(0f, 0.5f);
			component.offsetMin = new Vector2(0f, 50f);
			component.offsetMax = new Vector2(842f, -100f);
			component.sizeDelta = new Vector2(842f, -150f);
			RectTransform component2 = ((Component)val.verticalScrollbar).GetComponent<RectTransform>();
			component2.offsetMin = new Vector2(-420f, 0f);
			component2.offsetMax = new Vector2(-400f, 0f);
			return val;
		}

		public static ScrollRect CreateScrollView(string name, Transform parent)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			GameObject val = new GameObject(name + " Scroll View", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Mask),
				typeof(ScrollRect)
			});
			val.transform.SetParent(parent, false);
			((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			ScrollRect component = val.GetComponent<ScrollRect>();
			GameObject val2 = new GameObject("Viewport", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Mask)
			});
			val2.transform.SetParent(val.transform, false);
			((Graphic)val2.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			Mask component2 = val2.GetComponent<Mask>();
			component2.showMaskGraphic = false;
			GameObject val3 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val2.transform, false);
			VerticalLayoutGroup val4 = val3.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val4).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val4).spacing = 0f;
			((LayoutGroup)val4).padding.top = 0;
			((LayoutGroup)val4).padding.bottom = 0;
			((LayoutGroup)val4).padding.left = 2;
			((LayoutGroup)val4).padding.right = 2;
			ContentSizeFitter val5 = val3.AddComponent<ContentSizeFitter>();
			val5.verticalFit = (FitMode)2;
			Object? obj = (from e in Object.FindObjectsOfType(typeof(Scrollbar), true)
				where e.name == "Scrollbar (1)"
				select e).FirstOrDefault();
			Scrollbar val6 = (Scrollbar)(object)((obj is Scrollbar) ? obj : null);
			if (!Object.op_Implicit((Object)(object)((Component)val6).gameObject))
			{
				LayerPlugin.Log.Error("NO SCROLLBAR FOUND");
			}
			GameObject val7 = Object.Instantiate<GameObject>(((Component)val6).gameObject);
			val7.transform.SetParent(val.transform, false);
			Scrollbar component3 = val7.GetComponent<Scrollbar>();
			component3.direction = (Direction)2;
			component.viewport = val2.GetComponent<RectTransform>();
			component.content = val3.GetComponent<RectTransform>();
			component.verticalScrollbar = component3;
			component.vertical = true;
			component.horizontal = false;
			return component;
		}
	}
	public class LayerCreator
	{
	}
}
namespace UltrakillLayerConfigurator.Data
{
	public class DifficultyMenuCategoryObject
	{
		private GameObject template;

		public GameObject Parent;

		public Transform Name;

		public Transform Line1;

		public Transform Line2;

		public DifficultyMenuCategoryObject(GameObject parent)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0075: 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_00b7: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			Parent = parent;
			template = new GameObject("Category Template", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			template.transform.parent = Parent.transform;
			template.transform.localScale = new Vector3(1f, 1f, 1f);
			template.GetComponent<RectTransform>().sizeDelta = Parent.GetComponent<RectTransform>().sizeDelta;
			template.GetComponent<RectTransform>().anchorMax = Parent.GetComponent<RectTransform>().anchorMax;
			template.GetComponent<RectTransform>().anchorMin = Parent.GetComponent<RectTransform>().anchorMin;
			template.GetComponent<RectTransform>().pivot = Parent.GetComponent<RectTransform>().pivot;
			Name = Object.Instantiate<Transform>(parent.transform.Find("Easy"), template.transform);
			((Object)Name).name = "Category Title";
			Line1 = Object.Instantiate<Transform>(parent.transform.Find("LineBreak (1)"), template.transform);
			((Object)Line1).name = "LineBreak 1";
			Line2 = Object.Instantiate<Transform>(parent.transform.Find("LineBreak (3)"), template.transform);
			((Object)Line2).name = "LineBreak 2";
			template.transform.localScale = new Vector3(1f, 1f, 1f);
		}

		public GameObject CreateNew(ref List<GameObject> toAppear, string category, List<DifficultySelectButton> buttons)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)template == (Object)null)
			{
				LayerPlugin.Log.Error("Missing Template");
				return null;
			}
			if (buttons.Count == 0)
			{
				return null;
			}
			int num = 0;
			template.transform.localScale = new Vector3(1f, 1f, 1f);
			GameObject val = Object.Instantiate<GameObject>(template);
			((Object)val).name = "Category (" + category.ToLower() + ")";
			val.transform.localScale = new Vector3(1f, 1f, 1f);
			float num2 = 55f * ((float)buttons.Count / 2f) - 25f;
			Transform val2 = val.transform.Find("Category Title");
			if ((Object)(object)val2 == (Object)null)
			{
				LayerPlugin.Log.Error("Missing Category Title");
				return val;
			}
			val2.localPosition = new Vector3(17f, num2 + 50f, 0f);
			val2.localScale = new Vector3(1f, 1f, 1f);
			TextMeshProUGUI component = ((Component)val2).GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = category;
			Transform val3 = val.transform.Find("LineBreak 1");
			if ((Object)(object)val3 == (Object)null)
			{
				LayerPlugin.Log.Error("Missing LineBreak 1");
				return val;
			}
			val3.localPosition = new Vector3(0f, num2 + 30f, 0f);
			val3.localScale = new Vector3(1f, 1f, 1f);
			Transform val4 = val.transform.Find("LineBreak 2");
			if ((Object)(object)val4 == (Object)null)
			{
				LayerPlugin.Log.Error("Missing LineBreak 2");
				return val;
			}
			val4.localPosition = new Vector3(0f, num2 + 25f, 0f);
			val4.localScale = new Vector3(1f, 1f, 1f);
			val4.localPosition -= new Vector3(0f, (float)buttons.Count * 55f, 0f);
			for (int i = 0; i < buttons.Count; i++)
			{
				DifficultySelectButton val5 = buttons[i];
				if (!((Object)(object)val5 == (Object)null))
				{
					((Component)val5).transform.SetParent(val.transform);
					((Component)val5).transform.localScale = new Vector3(1f, 1f, 1f);
					((Component)val5).transform.localPosition = new Vector3(-2.5f, num2 + -55f * (float)i, 0f);
				}
			}
			toAppear.Add(((Component)val2).gameObject);
			toAppear.Add(((Component)val3).gameObject);
			foreach (DifficultySelectButton button in buttons)
			{
				toAppear.Add(((Component)button).gameObject);
				((Component)button).gameObject.SetActive(false);
			}
			toAppear.Add(((Component)val4).gameObject);
			val.transform.localScale = new Vector3(1f, 1f, 1f);
			return val;
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)template);
		}
	}
	[Serializable]
	public class EntryCategory
	{
		public string name;

		public List<string> entries;
	}
	public class EntryDatabase
	{
		public List<EntryCategory> categories;
	}
	public static class JsonReader
	{
		public const string DifficultyTag = "difficulties";

		public const string ChapterTag = "chapters";

		public const string LayerTag = "layers";

		private static Dictionary<string, List<string>> ChapterCategories = new Dictionary<string, List<string>>();

		private static Dictionary<string, List<string>> DifficultyCategories = new Dictionary<string, List<string>>();

		public static Dictionary<string, List<Button>> ChapterCategoriesWithButtons = new Dictionary<string, List<Button>>();

		public static Dictionary<string, List<DifficultySelectButton>> DifficultyCategoriesWithButtons = new Dictionary<string, List<DifficultySelectButton>>();

		public static Dictionary<string, ChapterEntry> ChapterDefinitions = new Dictionary<string, ChapterEntry>();

		public static int ChapterNumber = 999;

		public static Dictionary<string, List<string>> FirstPaths = new Dictionary<string, List<string>>();

		public static Dictionary<string, List<string>> RegisteredPaths = new Dictionary<string, List<string>>();

		public static async Task LoadAllChapters(List<Button> buttons)
		{
			await ClearChapterCheck();
			if (ChapterCategories.Count == 0)
			{
				if (FirstPaths.ContainsKey("chapters"))
				{
					foreach (string path in FirstPaths["chapters"])
					{
						ChapterCategories = await Load(path, ChapterCategories);
					}
				}
				if (RegisteredPaths.ContainsKey("chapters"))
				{
					foreach (string path2 in RegisteredPaths["chapters"])
					{
						ChapterCategories = await Load(path2, ChapterCategories);
					}
				}
			}
			LayerPlugin.Log.LogDebug($"{ChapterCategories.Keys.Count} CATEGORIES and {ChapterCategories.Values.Count} CHAPTERS FOUND IN JSONS!");
			await SortAllChapters(buttons);
		}

		public static async Task SortAllChapters(List<Button> buttons)
		{
			List<Button> chapters = new List<Button>(buttons);
			LayerPlugin.Log.LogDebug($"SORTING {chapters.Count} BUTTONS");
			if (ChapterNumber == chapters.Count || chapters.Count == 0)
			{
				return;
			}
			ChapterNumber = chapters.Count;
			ChapterCategoriesWithButtons.Clear();
			LayerPlugin.Log.LogDebug($"SORTING {buttons.Count} BUTTONS into {ChapterCategories.Keys.Count} CHAPTERS");
			foreach (string category in ChapterCategories.Keys)
			{
				foreach (string entry in ChapterCategories[category])
				{
					foreach (Button button in buttons)
					{
						string name = ((TMP_Text)((Component)((Component)button).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower();
						if (name.Contains(entry.ToLower()))
						{
							chapters.Remove(button);
							LayerPlugin.Log.LogDebug("Placing Button " + name + " into " + category);
							DictionaryCollectionExtensions.Add<string, List<Button>, Button>(ChapterCategoriesWithButtons, category, button);
							break;
						}
					}
				}
			}
			if (chapters.Count > 0)
			{
				foreach (Button button2 in chapters)
				{
					DictionaryCollectionExtensions.Add<string, List<Button>, Button>(ChapterCategoriesWithButtons, "OTHER", button2);
				}
			}
			LayerPlugin.Log.LogDebug("SORTED ALL CHAPTERS");
		}

		public static async Task PopulateCategories()
		{
			if (ChapterDefinitions.Count != 0)
			{
				return;
			}
			if (FirstPaths.ContainsKey("layers"))
			{
				foreach (string path in FirstPaths["layers"])
				{
					ChapterDefinitions = await LoadLayers(path, ChapterDefinitions);
				}
			}
			if (!RegisteredPaths.ContainsKey("layers"))
			{
				return;
			}
			foreach (string path2 in RegisteredPaths["layers"])
			{
				ChapterDefinitions = await LoadLayers(path2, ChapterDefinitions);
			}
		}

		public static async Task ClearDifficultyCheck()
		{
			foreach (string category in DifficultyCategoriesWithButtons.Keys)
			{
				for (int i = 0; i < DifficultyCategoriesWithButtons[category].Count; i++)
				{
					if ((Object)(object)DifficultyCategoriesWithButtons[category][i] == (Object)null)
					{
						DifficultyCategoriesWithButtons.Clear();
						return;
					}
				}
			}
		}

		public static async Task ClearChapterCheck()
		{
			foreach (string category in ChapterCategoriesWithButtons.Keys)
			{
				for (int i = 0; i < ChapterCategoriesWithButtons[category].Count; i++)
				{
					if ((Object)(object)ChapterCategoriesWithButtons[category][i] == (Object)null)
					{
						ChapterCategoriesWithButtons.Clear();
						return;
					}
				}
			}
		}

		public static async Task LoadAllDifficulties(DifficultySelectButton[] allDifficulties)
		{
			List<DifficultySelectButton> difficulties = new List<DifficultySelectButton>(allDifficulties);
			await ClearDifficultyCheck();
			if (DifficultyCategories.Count == 0)
			{
				if (FirstPaths.ContainsKey("difficulties"))
				{
					foreach (string path in FirstPaths["difficulties"])
					{
						DifficultyCategories = await Load(path, DifficultyCategories);
					}
				}
				if (RegisteredPaths.ContainsKey("difficulties"))
				{
					foreach (string path2 in RegisteredPaths["difficulties"])
					{
						DifficultyCategories = await Load(path2, DifficultyCategories);
					}
				}
			}
			if (DifficultyCategoriesWithButtons.Count != 0)
			{
				return;
			}
			foreach (string category in DifficultyCategories.Keys)
			{
				foreach (string entry in DifficultyCategories[category])
				{
					foreach (DifficultySelectButton button in allDifficulties)
					{
						string name = ((TMP_Text)((Component)((Component)button).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower();
						if (name.Contains(entry.ToLower()))
						{
							difficulties.Remove(button);
							DictionaryCollectionExtensions.Add<string, List<DifficultySelectButton>, DifficultySelectButton>(DifficultyCategoriesWithButtons, category, button);
						}
					}
				}
			}
			if (difficulties.Count <= 0)
			{
				return;
			}
			foreach (DifficultySelectButton button2 in difficulties)
			{
				DictionaryCollectionExtensions.Add<string, List<DifficultySelectButton>, DifficultySelectButton>(DifficultyCategoriesWithButtons, "EXTRA", button2);
			}
		}

		public static async Task<Dictionary<string, List<string>>> Load(string path, Dictionary<string, List<string>> categories)
		{
			if (!File.Exists(path))
			{
				LayerPlugin.Log.Error("JSON file not found: " + path);
				return categories;
			}
			string json = File.ReadAllText(path);
			EntryDatabase db = JsonConvert.DeserializeObject<EntryDatabase>(json);
			if (db != null)
			{
				foreach (EntryCategory category in db.categories)
				{
					if (categories.ContainsKey(category.name))
					{
						categories[category.name].AddRange(category.entries);
					}
					else
					{
						categories.Add(category.name, category.entries);
					}
					LayerPlugin.Log.LogDebug($"Writing {category.entries.Count} ENTRIES into {category.name} [{categories[category.name].Count}]");
				}
			}
			return categories;
		}

		public static async Task<Dictionary<string, ChapterEntry>> LoadLayers(string path, Dictionary<string, ChapterEntry> chapters)
		{
			if (!File.Exists(path))
			{
				LayerPlugin.Log.Error("JSON file not found: " + path);
				return chapters;
			}
			string json = File.ReadAllText(path);
			ChapterDatabase db = JsonConvert.DeserializeObject<ChapterDatabase>(json);
			if (db != null)
			{
				foreach (ChapterEntry chapter in db.Chapters)
				{
					chapters.Add(chapter.Name.ToLower(), chapter);
				}
			}
			return chapters;
		}

		public static void RegisterDifficultyPath(string path)
		{
			RegisterPath("difficulties", path);
		}

		public static void RegisterChapterPath(string path)
		{
			RegisterPath("chapters", path);
		}

		public static void RegisterLayerPath(string path)
		{
			RegisterPath("layers", path);
		}

		public static void RegisterPath(string key, string path)
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, "data/" + path + "." + key + ".json");
			if (!File.Exists(text))
			{
				LayerPlugin.Log.Warn("JSON file not found: " + text);
				text = Path.Combine(directoryName, path + "." + key + ".json");
			}
			if (text.Contains("LayerConfigurator"))
			{
				if (FirstPaths == null)
				{
					FirstPaths = new Dictionary<string, List<string>>();
				}
				DictionaryCollectionExtensions.Add<string, List<string>, string>(FirstPaths, key, path);
			}
			else
			{
				if (RegisteredPaths == null)
				{
					RegisteredPaths = new Dictionary<string, List<string>>();
				}
				DictionaryCollectionExtensions.Add<string, List<string>, string>(RegisteredPaths, key, text);
			}
		}

		public static void RegisterFullPath(string mod, string path)
		{
			string text;
			if (path.Contains("difficulties.json"))
			{
				text = "difficulties";
			}
			else if (path.Contains("chapters.json"))
			{
				text = "chapters";
			}
			else
			{
				if (!path.Contains("layers.json"))
				{
					return;
				}
				text = "layers";
			}
			bool flag = false;
			if (mod == "net.zephyr.ultrakill.LayerConfigurator")
			{
				if (FirstPaths == null)
				{
					FirstPaths = new Dictionary<string, List<string>>();
				}
				DictionaryCollectionExtensions.Add<string, List<string>, string>(FirstPaths, text, path);
				flag = true;
			}
			else
			{
				if (RegisteredPaths == null)
				{
					RegisteredPaths = new Dictionary<string, List<string>>();
				}
				DictionaryCollectionExtensions.Add<string, List<string>, string>(RegisteredPaths, text, path);
			}
			string fileName = Path.GetFileName(path);
			if (flag)
			{
				LayerPlugin.Log.Log("Loaded [" + fileName + "]");
				return;
			}
			LayerPlugin.Log.Log("Loaded [" + fileName + "] (" + mod + ")");
		}
	}
}
namespace UltrakillLayerConfigurator.Data.Layers
{
	public class ChapterDatabase
	{
		[JsonProperty("chapters")]
		public List<ChapterEntry> Chapters { get; set; } = new List<ChapterEntry>();

		public static Color ToColor(float[] colors)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return new Color(colors[0], colors[1], colors[2], colors[3]);
		}
	}
	public class ChapterEntry
	{
		[JsonProperty("default_color")]
		public float[] DefaultColor = new float[4] { 1f, 1f, 1f, 1f };

		[JsonProperty("prank_color")]
		public float[] PrankColor = new float[4] { 1f, 0.686f, 0f, 1f };

		[JsonProperty("hide_when_off")]
		public bool HideWhenOff = false;

		[JsonProperty("prime_levels")]
		public bool PrimeLevels = false;

		[JsonProperty("force_off")]
		public bool ForceOff = false;

		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("name_when_disabled")]
		public string DisabledName { get; set; }

		[JsonProperty("required_levels")]
		public int RequiredLevels { get; set; }

		[JsonProperty("layers")]
		public List<LayerEntry> Layers { get; set; } = new List<LayerEntry>();
	}
	public class LayerEntry
	{
		[JsonProperty("default_color")]
		public float[] DefaultColor = new float[4] { 0f, 0f, 0f, 0.35f };

		[JsonProperty("prank_color")]
		public float[] PrankColor = new float[4] { 1f, 0.686f, 0f, 1f };

		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("layer_number")]
		public int LayerNumber { get; set; }

		[JsonProperty("missions")]
		public List<MissionEntry> Missions { get; set; } = new List<MissionEntry>();

		[JsonProperty("secret_mission")]
		public MissionEntry SecretMission { get; set; }
	}
	public class MissionEntry
	{
		[JsonProperty("name")]
		public string Name = "";

		[JsonProperty("name_when_disabled")]
		public string DisabledName = "";

		[JsonProperty("unlocked_thumbnail_path")]
		public string UnlockedThumbnailPath = "";

		[JsonProperty("locked_thumbnail_path")]
		public string LockedThumbnailPath = "";

		[JsonProperty("default_color")]
		public float[] DefaultColor = new float[4] { 0f, 0f, 0f, 0.35f };

		[JsonProperty("prank_color")]
		public float[] PrankColor = new float[4] { 1f, 0.686f, 0f, 1f };

		[JsonProperty("force_off")]
		public bool ForceOff = false;

		[JsonProperty("level_number")]
		public int LevelNumber { get; set; }

		[JsonProperty("leaderboard_level")]
		public string LeaderboardLevel { get; set; }
	}
}
namespace UltrakillLayerConfigurator.Patches
{
	[HarmonyPatch]
	public class BillionRankStuffPatch
	{
		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("BillionNemesis.RankStuff");
			if (type == null)
			{
				return null;
			}
			return AccessTools.Method(type, "UpdateRanksAndColors", (Type[])null, (Type[])null);
		}

		private static bool Prefix()
		{
			return false;
		}
	}
	[HarmonyPatch(typeof(ChapterSelectButton))]
	public class ChapterSelectButtonPatch
	{
		private static readonly Type PluginType = AccessTools.TypeByName("BillionNemesis.Plugin");

		private static bool switchedLast = false;

		[HarmonyPostfix]
		[HarmonyPatch("CheckScore")]
		public static void CheckScorePostfix(ChapterSelectButton __instance)
		{
		}

		[HarmonyPrefix]
		[HarmonyPatch("CheckScore")]
		public static void CheckScorePrefix(ChapterSelectButton __instance)
		{
			Sprite sprite = ((Component)__instance.rankText.transform.parent).GetComponent<Image>().sprite;
			if (!LayerPlugin.isBillionNemesisInstalled)
			{
				return;
			}
			Type type = AccessTools.TypeByName("BillionNemesis.Plugin");
			if (type != null)
			{
				AccessTools.Field(type, "IsEnabled");
			}
			if (!(PluginType != null))
			{
				return;
			}
			object obj = AccessTools.Field(PluginType, "IsEnabled")?.GetValue(null);
			if (obj != null)
			{
				bool flag = ((TMP_Text)((Component)((Component)__instance).transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text.ToLower().Contains("nemesis");
				if (switchedLast != flag)
				{
					switchedLast = flag;
					AccessTools.Method(obj.GetType(), "SetValue", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { flag });
				}
			}
		}
	}
	[HarmonyPatch(typeof(DifficultySelectButton))]
	public class DifficultySelectButtonPatch
	{
	}
	[HarmonyPatch(typeof(GearCheckEnabler))]
	public static class GearCheckEnablerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void StartPostfix()
		{
			CustomMainMenuManager.Create();
		}
	}
	[HarmonyPatch(typeof(GetMissionName))]
	public class GetMissionNamePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetMission")]
		public static bool GetMissionPrefix(int missionNum, ref string __result)
		{
			LayerPlugin.Log.LogDebug("HEELLLOOOOO");
			if (CustomMainMenuManager.NameCache.ContainsKey(missionNum))
			{
				LayerPlugin.Log.LogDebug(CustomMainMenuManager.NameCache[missionNum]);
				__result = CustomMainMenuManager.NameCache[missionNum];
				return false;
			}
			return true;
		}
	}
}