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;
}
}
}