Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LoadoutManager v0.1.6
BepInEx/plugins/REPO.LoadoutManager.dll
Decompiled a month agousing System; using System.Collections; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("REPO.LoadoutManager")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("REPO mod: pick which purchased items to bring from the truck monitor screen")] [assembly: AssemblyFileVersion("0.1.6.0")] [assembly: AssemblyInformationalVersion("0.1.6")] [assembly: AssemblyProduct("REPO.LoadoutManager")] [assembly: AssemblyTitle("REPO.LoadoutManager")] [assembly: AssemblyVersion("0.1.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPO.ItemSpawner { [HarmonyPatch(typeof(TruckScreenText), "Awake")] internal static class TruckScreenText_Awake_Patch { private static void Postfix(TruckScreenText __instance) { try { MonitorUI.Build(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"[MonitorUI] Failed to build embedded UI: {arg}"); } } } internal static class MonitorUI { private static GameObject _rootGO; private static RectTransform _content; private static ScrollRect _scroll; private static int _selectedCategoryIndex; private static int _selectedRowIndex; private static TextMeshProUGUI _hintLabel; private static readonly List<Image> _tabImages = new List<Image>(); private static readonly List<Image> _rowImages = new List<Image>(); private static readonly Dictionary<string, Sprite> _iconCache = new Dictionary<string, Sprite>(); private static readonly Color TabColor = new Color(1f, 1f, 1f, 0.14f); private static readonly Color TabSelectedColor = new Color(1f, 0.85f, 0.2f, 0.5f); private static readonly Color RowColor = new Color(1f, 1f, 1f, 0.08f); private static readonly Color RowSelectedColor = new Color(1f, 0.85f, 0.2f, 0.35f); private static readonly Color FavoriteTabColor = new Color(0.85f, 0.75f, 0.1f, 0.35f); private static readonly Color FavoriteTabSelectedColor = new Color(1f, 0.9f, 0.15f, 0.65f); private static readonly Color HideTabColor = new Color(0.7f, 0.15f, 0.15f, 0.35f); private static readonly Color HideTabSelectedColor = new Color(1f, 0.2f, 0.2f, 0.65f); private static void GetTabColors(string category, out Color normal, out Color selected) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (category == "Favorite") { normal = FavoriteTabColor; selected = FavoriteTabSelectedColor; } else if (category == "Hide") { normal = HideTabColor; selected = HideTabSelectedColor; } else { normal = TabColor; selected = TabSelectedColor; } } public static void Build(TruckScreenText truckScreenText) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: 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) //IL_038c: Expected O, but got Unknown //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Expected O, but got Unknown //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Expected O, but got Unknown //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Expected O, but got Unknown //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)truckScreenText).transform.Find("Canvas"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[MonitorUI] Could not find 'Canvas' child under TruckScreenText."); return; } if ((Object)(object)((Component)val).GetComponent<Canvas>() == (Object)null) { Plugin.Log.LogWarning((object)"[MonitorUI] 'Canvas' child has no Canvas component."); return; } Transform obj = val.Find("Bg"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); GameObject val3 = new GameObject("REPO.ItemSpawner.Panel", new Type[2] { typeof(RectTransform), typeof(Canvas) }); _rootGO = val3; RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).SetParent(val, false); if ((Object)(object)val2 != (Object)null) { val4.anchorMin = val2.anchorMin; val4.anchorMax = val2.anchorMax; val4.anchoredPosition = val2.anchoredPosition + new Vector2(0f, 0.3f); val4.sizeDelta = val2.sizeDelta; } else { val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.anchoredPosition = Vector2.zero; val4.sizeDelta = Vector2.zero; } ((Transform)val4).localScale = new Vector3(0.95f, 0.75f, 1f); Canvas component = val3.GetComponent<Canvas>(); component.overrideSorting = true; component.sortingOrder = 100; ((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.9f); GameObject val5 = new GameObject("Padding", new Type[1] { typeof(RectTransform) }); RectTransform val6 = (RectTransform)val5.transform; ((Transform)val6).SetParent((Transform)(object)val4, false); val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = new Vector2(0.08f, 0.08f); val6.offsetMax = new Vector2(-0.08f, -0.08f); VerticalLayoutGroup obj2 = val5.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 0.04f; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; AddLabel((Transform)(object)val6, "Your Items", 0.2f, 0.26f); _hintLabel = AddLabel((Transform)(object)val6, BuildHintText(), 0.115f, 0.18f); ((TMP_Text)_hintLabel).enableAutoSizing = true; ((TMP_Text)_hintLabel).fontSizeMax = 0.115f; ((TMP_Text)_hintLabel).fontSizeMin = 0.05f; GameObject val7 = new GameObject("Tabs", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }); RectTransform val8 = (RectTransform)val7.transform; ((Transform)val8).SetParent((Transform)(object)val6, false); VerticalLayoutGroup component2 = val7.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 0.02f; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; LayoutElement component3 = val7.GetComponent<LayoutElement>(); string[] order = ItemCategories.Order; int num = (order.Length + 3) / 4; component3.preferredHeight = 0.26f * (float)num + ((HorizontalOrVerticalLayoutGroup)component2).spacing * (float)(num - 1); component3.minHeight = component3.preferredHeight; component3.flexibleHeight = 0f; _tabImages.Clear(); for (int i = 0; i < order.Length; i += 4) { GameObject val9 = new GameObject($"TabRow{i / 4}", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); RectTransform val10 = (RectTransform)val9.transform; ((Transform)val10).SetParent((Transform)(object)val8, false); HorizontalLayoutGroup component4 = val9.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component4).spacing = 0.02f; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true; LayoutElement component5 = val9.GetComponent<LayoutElement>(); component5.preferredHeight = 0.26f; component5.minHeight = 0.26f; component5.flexibleHeight = 0f; for (int j = i; j < Math.Min(i + 4, order.Length); j++) { Image item = CreateTab((Transform)(object)val10, order[j], 0.15f, 0.26f); _tabImages.Add(item); } } GameObject val11 = new GameObject("Scroll", new Type[5] { typeof(RectTransform), typeof(ScrollRect), typeof(Image), typeof(RectMask2D), typeof(LayoutElement) }); RectTransform val12 = (RectTransform)val11.transform; ((Transform)val12).SetParent((Transform)(object)val6, false); ((Graphic)val11.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.03f); LayoutElement component6 = val11.GetComponent<LayoutElement>(); component6.flexibleHeight = 1f; component6.minHeight = 0.5f; GameObject val13 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); _content = (RectTransform)val13.transform; ((Transform)_content).SetParent((Transform)(object)val12, false); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0.5f, 1f); _content.sizeDelta = Vector2.zero; VerticalLayoutGroup component7 = val13.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component7).spacing = 0.03f; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component7).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component7).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandWidth = true; ContentSizeFitter component8 = val13.GetComponent<ContentSizeFitter>(); component8.horizontalFit = (FitMode)0; component8.verticalFit = (FitMode)2; _scroll = val11.GetComponent<ScrollRect>(); _scroll.content = _content; _scroll.horizontal = false; _scroll.vertical = true; RefreshList(); Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(val4); Plugin.Log.LogInfo((object)"[MonitorUI] Embedded panel built (keyboard nav)."); } public static void SetVisible(bool visible) { if (!((Object)(object)_rootGO == (Object)null)) { bool activeSelf = _rootGO.activeSelf; _rootGO.SetActive(visible); if (visible && !activeSelf) { RefreshList(); } } } public static void MoveSelection(int delta) { int count = CurrentGrouped().Count; if (count != 0) { _selectedRowIndex = ((_selectedRowIndex + delta) % count + count) % count; UpdateHighlight(); ScrollToSelected(); } } public static void ChangeCategory(int delta) { string[] order = ItemCategories.Order; _selectedCategoryIndex = ((_selectedCategoryIndex + delta) % order.Length + order.Length) % order.Length; _selectedRowIndex = 0; RefreshList(); } public static void ConfirmSelection() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { ItemSpawner.RequestSpawn(list[_selectedRowIndex].Item1); RefreshList(); } } public static void CycleFavoriteSelected() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { Item item = list[_selectedRowIndex].Item1; int ownedTotal = GetOwnedTotal(item); ItemSpawner.RequestCycleFavorite(item, ownedTotal); } } public static void ToggleHiddenSelected() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { Hidden.Toggle(list[_selectedRowIndex].Item1.itemName); RefreshList(); } } private static int GetOwnedTotal(Item item) { if (!((Object)(object)StatsManager.instance != (Object)null)) { return 0; } return StatsManager.instance.GetItemPurchased(item); } private static List<(Item item, int count)> CurrentGrouped() { if ((Object)(object)StatsManager.instance == (Object)null || (Object)(object)ItemManager.instance == (Object)null) { return new List<(Item, int)>(); } string selectedCategory = ItemCategories.Order[_selectedCategoryIndex]; Dictionary<string, int> remainingByName = (from i in ItemManager.instance.purchasedItems group i by i.itemName).ToDictionary((IGrouping<string, Item> g) => g.Key, (IGrouping<string, Item> g) => g.Count()); IEnumerable<Item> source = StatsManager.instance.itemDictionary.Values.Where((Item it) => !it.disabled && GetOwnedTotal(it) > 0); if (selectedCategory == "Hide") { return (from it in source where Hidden.Set.Contains(it.itemName) select (it: it, Remaining(it))).ToList(); } source = source.Where((Item it) => !Hidden.Set.Contains(it.itemName)); if (selectedCategory == "Favorite") { return (from it in source where Favorites.Get(it.itemName) > 0 select (it: it, GetOwnedTotal(it))).ToList(); } return (from it in source where selectedCategory == "All" || ItemCategories.Of(it) == selectedCategory select (item: it, count: Remaining(it)) into g where g.count > 0 select g).ToList(); int Remaining(Item it) { if (!remainingByName.TryGetValue(it.itemName, out var value)) { return 0; } return value; } } private static TextMeshProUGUI AddLabel(Transform parent, string text, float fontSize, float height) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Label", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = text; ((TMP_Text)component).fontSize = fontSize; ((TMP_Text)component).alignment = (TextAlignmentOptions)513; ((Graphic)component).color = Color.white; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)0; LayoutElement component2 = val.GetComponent<LayoutElement>(); component2.preferredHeight = height; component2.minHeight = height; component2.flexibleHeight = 0f; return component; } private static Image CreateTab(Transform parent, string label, float fontSize, float height) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Tab_" + label, new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = TabColor; LayoutElement component2 = val.GetComponent<LayoutElement>(); component2.preferredHeight = height; component2.minHeight = height; component2.flexibleHeight = 0f; GameObject val2 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; TextMeshProUGUI component3 = val2.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component3).text = label; ((TMP_Text)component3).fontSize = fontSize; ((TMP_Text)component3).alignment = (TextAlignmentOptions)514; ((Graphic)component3).color = Color.white; ((TMP_Text)component3).enableAutoSizing = true; ((TMP_Text)component3).fontSizeMin = 0.06f; ((TMP_Text)component3).fontSizeMax = fontSize; ((TMP_Text)component3).enableWordWrapping = true; ((TMP_Text)component3).overflowMode = (TextOverflowModes)3; return component; } private static string BuildHintText() { List<string> list = new List<string>(); if (Keybinds.MoveUp.IsDefaultArrow((KeyCode)273) && Keybinds.MoveDown.IsDefaultArrow((KeyCode)274) && Keybinds.PrevCategory.IsDefaultArrow((KeyCode)276) && Keybinds.NextCategory.IsDefaultArrow((KeyCode)275)) { list.Add("Arrows: Move"); } else { AddPair(list, Keybinds.MoveUp, Keybinds.MoveDown, "Move"); AddPair(list, Keybinds.PrevCategory, Keybinds.NextCategory, "Tabs"); } AddSingle(list, Keybinds.Spawn, "Spawn"); AddSingle(list, Keybinds.Favorite, "Favorite"); AddSingle(list, Keybinds.Hide, "Hide"); return string.Join(" ", list); } private static void AddSingle(List<string> parts, KeyBinding binding, string action) { if (binding.IsBound) { parts.Add(binding.Label + ": " + action); } } private static void AddPair(List<string> parts, KeyBinding first, KeyBinding second, string action) { if (first.IsBound && second.IsBound) { parts.Add(first.Label + "/" + second.Label + ": " + action); } else if (first.IsBound) { parts.Add(first.Label + ": " + action); } else if (second.IsBound) { parts.Add(second.Label + ": " + action); } } public static void RefreshList() { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0218: 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) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_content == (Object)null || (Object)(object)ItemManager.instance == (Object)null) { return; } if ((Object)(object)_hintLabel != (Object)null) { ((TMP_Text)_hintLabel).text = BuildHintText(); } for (int num = ((Transform)_content).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_content).GetChild(num)).gameObject); } _rowImages.Clear(); List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= list.Count) { _selectedRowIndex = Math.Max(0, list.Count - 1); } if (list.Count == 0) { AddLabel((Transform)(object)_content, "No items in this category", 0.14f, 0.3f); } else { foreach (var item3 in list) { Item item = item3.Item1; int item2 = item3.Item2; GameObject val = new GameObject("Row_" + item.itemName, new Type[4] { typeof(RectTransform), typeof(Image), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); ((Transform)(RectTransform)val.transform).SetParent((Transform)(object)_content, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = RowColor; _rowImages.Add(component); LayoutElement component2 = val.GetComponent<LayoutElement>(); component2.preferredHeight = 0.32f; component2.minHeight = 0.32f; component2.flexibleHeight = 0f; HorizontalLayoutGroup component3 = val.GetComponent<HorizontalLayoutGroup>(); ((LayoutGroup)component3).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)component3).spacing = 0.04f; ((LayoutGroup)component3).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; GameObject val2 = new GameObject("Icon", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val2.transform.SetParent(val.transform, false); LayoutElement component4 = val2.GetComponent<LayoutElement>(); component4.preferredWidth = 0.26f; component4.preferredHeight = 0.26f; component4.minWidth = 0.26f; component4.minHeight = 0.26f; component4.flexibleWidth = 0f; component4.flexibleHeight = 0f; Image component5 = val2.GetComponent<Image>(); Sprite icon = GetIcon(item); if ((Object)(object)icon != (Object)null) { component5.sprite = icon; component5.preserveAspect = true; } else { ((Graphic)component5).color = new Color(1f, 1f, 1f, 0.15f); } GameObject val3 = new GameObject("Label", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); val3.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = new Vector2(0f, 0f); val4.anchorMax = new Vector2(1f, 1f); val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; LayoutElement component6 = val3.GetComponent<LayoutElement>(); component6.flexibleWidth = 1f; component6.minWidth = 0.5f; component6.minHeight = 0.3f; component6.preferredHeight = 0.3f; TextMeshProUGUI component7 = val3.GetComponent<TextMeshProUGUI>(); int num2 = Favorites.Get(item.itemName); string arg = ((num2 > 0) ? ((num2 == GetOwnedTotal(item)) ? "* " : $"*{num2} ") : ""); ((TMP_Text)component7).text = $"{arg}{item.itemName} x{item2}"; ((TMP_Text)component7).fontSize = 0.16f; ((Graphic)component7).color = Color.white; ((TMP_Text)component7).alignment = (TextAlignmentOptions)513; ((TMP_Text)component7).enableWordWrapping = false; ((TMP_Text)component7).overflowMode = (TextOverflowModes)0; } } UpdateHighlight(); } private static void UpdateHighlight() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) string[] order = ItemCategories.Order; for (int i = 0; i < _tabImages.Count; i++) { GetTabColors(order[i], out var normal, out var selected); ((Graphic)_tabImages[i]).color = ((i == _selectedCategoryIndex) ? selected : normal); } for (int j = 0; j < _rowImages.Count; j++) { ((Graphic)_rowImages[j]).color = ((j == _selectedRowIndex) ? RowSelectedColor : RowColor); } } private static void ScrollToSelected() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scroll == (Object)null || _rowImages.Count == 0) { return; } Rect rect = ((RectTransform)((Component)_scroll).transform).rect; float height = ((Rect)(ref rect)).height; rect = _content.rect; float height2 = ((Rect)(ref rect)).height; if (height2 <= height) { _scroll.verticalNormalizedPosition = 1f; return; } float num = height2 / (float)_rowImages.Count; float num2 = (float)_selectedRowIndex * num; float num3 = num2 + num; float num4 = height2 - height; float num5 = (1f - _scroll.verticalNormalizedPosition) * num4; float num6 = num5 + height; float num7 = num5; if (num2 < num5) { num7 = num2; } else if (num3 > num6) { num7 = num3 - height; } num7 = Mathf.Clamp(num7, 0f, num4); _scroll.verticalNormalizedPosition = 1f - num7 / num4; } private static Sprite GetIcon(Item item) { if (_iconCache.TryGetValue(((Object)item).name, out var value)) { return value; } Sprite val = SemiFunc.LoadSpriteFromFile(Path.Combine(Application.persistentDataPath, "Cache", "Icons", "Items", ((Object)item).name.ToLowerInvariant() + ".png")); _iconCache[((Object)item).name] = val; return val; } } [BepInPlugin("kohei.repo.loadoutmanager", "REPO Loadout Manager", "0.1.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string MenuLibGuid = "nickklmao.menulib"; internal const string RepoConfigGuid = "nickklmao.repoconfig"; internal static bool SettingsMenuAvailable; private static Harmony _harmony; private static bool _settingsRegistered; public const string PluginGuid = "kohei.repo.loadoutmanager"; public const string PluginName = "REPO Loadout Manager"; public const string PluginVersion = "0.1.6"; internal static ManualLogSource Log; internal static ConfigEntry<float> MonitorRange; internal static ConfigEntry<bool> DebugDumpsEnabled; internal static ConfigEntry<bool> DebugHotkeysEnabled; internal static ConfigEntry<bool> DisableFavoritesPatch; internal const string HideFromInGameMenu = "HideFromREPOConfig"; internal static void EnsureSettingsRegistered() { if (!_settingsRegistered) { _settingsRegistered = true; SettingsMenuAvailable = Chainloader.PluginInfos.ContainsKey("nickklmao.menulib"); if (SettingsMenuAvailable) { SettingsMenu.Register(_harmony); } else { Log.LogWarning((object)"MenuLib not installed - the in-game settings page is unavailable. Settings can still be edited in BepInEx/config/kohei.repo.loadoutmanager.cfg."); } } } private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; MonitorRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MonitorRange", 8f, new ConfigDescription("How close you have to stand to the truck's monitor for the item panel to appear. Raise this if the panel won't show up from where you normally stand.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); Keybinds.Bind(((BaseUnityPlugin)this).Config); DebugDumpsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugDumps", false, new ConfigDescription("Log the full item DB and the truck monitor's 3D hierarchy once, for development. Leave off unless debugging.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); DebugHotkeysEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugHotkeys", false, new ConfigDescription("Ctrl+F9 = jump straight to Prepare (via Shop), Ctrl+F10 = advance one step (Shop->Prepare->Run->Shop...), Ctrl+F11 = jump straight to a Run level, Ctrl+F12 = mark 3 of every item as purchased. Off by default - these are testing shortcuts, not meant for normal play. Enable only when debugging.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); DisableFavoritesPatch = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DisableFavoritesPatch", false, new ConfigDescription("Temporary isolation switch: when true, PunManager.TruckPopulateItemVolumes runs 100% vanilla (no purchasedItems truncation for favorites). Used to test whether that patch is the cause of the belt-slot item loss bug.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); Favorites.Load(); Hidden.Load(); _harmony = new Harmony("kohei.repo.loadoutmanager"); _harmony.PatchAll(); Log.LogInfo((object)"REPO Loadout Manager v0.1.6 loaded."); } } internal static class Keybinds { internal static KeyBinding MoveUp; internal static KeyBinding MoveDown; internal static KeyBinding PrevCategory; internal static KeyBinding NextCategory; internal static KeyBinding Spawn; internal static KeyBinding Favorite; internal static KeyBinding Hide; internal static IEnumerable<KeyBinding> All { get { yield return MoveUp; yield return MoveDown; yield return PrevCategory; yield return NextCategory; yield return Spawn; yield return Favorite; yield return Hide; } } internal static void Bind(ConfigFile config) { MoveUp = new KeyBinding(config, "MoveUp", "Move Up", "UpArrow", "Move the selection up one row."); MoveDown = new KeyBinding(config, "MoveDown", "Move Down", "DownArrow", "Move the selection down one row."); PrevCategory = new KeyBinding(config, "PreviousCategory", "Previous Category", "LeftArrow", "Switch to the previous category tab."); NextCategory = new KeyBinding(config, "NextCategory", "Next Category", "RightArrow", "Switch to the next category tab."); Spawn = new KeyBinding(config, "Spawn", "Spawn", "Return", "Spawn the selected item. Bound to Return also accepts the numpad's Enter."); Favorite = new KeyBinding(config, "CycleFavorite", "Cycle Favorite", "F", "Cycle how many of the selected item are favorited (0 -> 1 -> ... -> owned -> 0). Favorited items are spawned automatically at the start of every level."); Hide = new KeyBinding(config, "ToggleHide", "Toggle Hide", "H", "Hide/unhide the selected item. Hidden items are kept out of every tab except Hide."); } } internal sealed class KeyBinding { private readonly ConfigEntry<string> _entry; private KeyCode _code; internal string DisplayName { get; } internal ConfigEntryBase Entry => (ConfigEntryBase)(object)_entry; internal KeyCode Code => _code; internal string Label => LabelFor(_code); internal bool IsBound => (int)_code > 0; internal KeyBinding(ConfigFile config, string name, string displayName, string defaultKey, string description) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown DisplayName = displayName; _entry = config.Bind<string>("Keybinds", name, defaultKey, new ConfigDescription(description + " Only does anything while the truck monitor panel is on screen. Any UnityEngine KeyCode name works here (F, PageDown, Keypad5, ...); None disables it. Easiest to change in-game from the Mods menu.", (AcceptableValueBase)null, Array.Empty<object>())); Reparse(); _entry.SettingChanged += delegate { Reparse(); }; } internal unsafe static string LabelFor(KeyCode code) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown if ((int)code != 0) { if ((int)code != 13) { switch (code - 271) { case 2: return "Up"; case 3: return "Down"; case 5: return "Left"; case 4: return "Right"; case 0: return "Enter"; default: { string text = ((object)(*(KeyCode*)(&code))/*cast due to .constrained prefix*/).ToString(); if (!text.StartsWith("Alpha")) { return text; } return text.Substring(5); } } } return "Enter"; } return "-"; } internal bool IsDefaultArrow(KeyCode expected) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _code == expected; } internal bool Pressed() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if ((int)_code == 0) { return false; } if (Input.GetKeyDown(_code)) { return true; } if ((int)_code == 13) { return Input.GetKeyDown((KeyCode)271); } return false; } private void Reparse() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) _code = (KeyCode)(Enum.TryParse<KeyCode>(_entry.Value, out KeyCode result) ? ((int)result) : 0); } } [HarmonyPatch(typeof(ItemManager), "Awake")] internal static class ItemManager_Awake_Patch { private static void Postfix() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)ItemSpawnerRuntime.Instance != (Object)null)) { GameObject val = new GameObject("REPO.ItemSpawner.Runtime"); Object.DontDestroyOnLoad((Object)val); ItemSpawnerRuntime.Instance = val.AddComponent<ItemSpawnerRuntime>(); Plugin.Log.LogInfo((object)"[ItemSpawner] Runtime UI object created."); } } } internal class ItemSpawnerRuntime : MonoBehaviour { public static ItemSpawnerRuntime Instance; private static readonly FieldRef<RunManager, bool> RunManagerRestartingRef = AccessTools.FieldRefAccess<RunManager, bool>("restarting"); private const int DebugGrantPerItem = 3; private void OnDisable() { Plugin.Log.LogWarning((object)"[ItemSpawner] Runtime OnDisable - Update() will stop firing."); } private void OnDestroy() { Plugin.Log.LogWarning((object)"[ItemSpawner] Runtime OnDestroy."); } private void Update() { Plugin.EnsureSettingsRegistered(); if (Plugin.SettingsMenuAvailable) { SettingsMenu.PollRebind(); } if (ItemSpawnerState.MonitorActive) { if (Keybinds.MoveDown.Pressed()) { MonitorUI.MoveSelection(1); } else if (Keybinds.MoveUp.Pressed()) { MonitorUI.MoveSelection(-1); } else if (Keybinds.NextCategory.Pressed()) { MonitorUI.ChangeCategory(1); } else if (Keybinds.PrevCategory.Pressed()) { MonitorUI.ChangeCategory(-1); } else if (Keybinds.Spawn.Pressed()) { MonitorUI.ConfirmSelection(); } else if (Keybinds.Favorite.Pressed()) { MonitorUI.CycleFavoriteSelected(); } else if (Keybinds.Hide.Pressed()) { MonitorUI.ToggleHiddenSelected(); } } if (Plugin.DebugHotkeysEnabled.Value && !((Object)(object)RunManager.instance == (Object)null) && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))) { if (Input.GetKeyDown((KeyCode)290)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F9 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)5); ((MonoBehaviour)this).StartCoroutine(AdvanceToPrepareAfterShop()); } else if (Input.GetKeyDown((KeyCode)291)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F10 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)0); Plugin.Log.LogInfo((object)"[Debug] Advanced one step (Shop->Prepare / Prepare->Run / Run->Shop)."); } else if (Input.GetKeyDown((KeyCode)293)) { GrantEveryItem(); } else if (Input.GetKeyDown((KeyCode)292)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F11 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)1); Plugin.Log.LogInfo((object)"[Debug] Jumped straight to a Run level."); } } } private void GrantEveryItem() { StatsManager instance = StatsManager.instance; ItemManager instance2 = ItemManager.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { Plugin.Log.LogWarning((object)"[Debug] Ctrl+F12: no StatsManager/ItemManager yet."); return; } int num = 0; foreach (KeyValuePair<string, Item> item in instance.itemDictionary) { Item value = item.Value; if (!((Object)(object)value == (Object)null) && !value.disabled) { int num2 = Mathf.Min(3, value.maxAmount); instance.itemsPurchased.TryGetValue(item.Key, out var value2); for (int i = value2; i < num2; i++) { instance.ItemPurchase(item.Key); num++; } } } AccessTools.Method(typeof(ItemManager), "GetPurchasedItems", (Type[])null, (Type[])null)?.Invoke(instance2, null); MonitorUI.RefreshList(); Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F12: granted {num} purchase(s); stock is now {instance2.purchasedItems.Count} item(s)."); } private IEnumerator AdvanceToPrepareAfterShop() { float elapsed = 0f; while (!SemiFunc.RunIsShop() && elapsed < 10f) { yield return (object)new WaitForSeconds(0.2f); elapsed += 0.2f; } if (elapsed >= 10f) { Plugin.Log.LogWarning((object)"[Debug] Ctrl+F9: timed out waiting for Shop to load, not advancing to Prepare."); yield break; } yield return (object)new WaitForSeconds(0.5f); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)0); Plugin.Log.LogInfo((object)"[Debug] Ctrl+F9: Shop -> Prepare."); } } [HarmonyPatch(typeof(TruckScreenText), "Update")] internal static class TruckScreenText_HierarchyDump_Patch { private static bool _dumped; private static void Postfix(TruckScreenText __instance) { if (!_dumped && ItemSpawnerState.MonitorActive && Plugin.DebugDumpsEnabled.Value) { _dumped = true; Plugin.Log.LogInfo((object)"=== TruckScreenText hierarchy dump ==="); DumpRecursive(((Component)__instance).transform, 0); Plugin.Log.LogInfo((object)"=== end hierarchy dump ==="); } } private static void DumpRecursive(Transform t, int depth) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) string text = new string(' ', depth * 2); Renderer component = ((Component)t).GetComponent<Renderer>(); object obj; if (!((Object)(object)component != (Object)null)) { obj = ""; } else { Bounds bounds = component.bounds; obj = $" [Renderer bounds={((Bounds)(ref bounds)).size}]"; } string text2 = (string)obj; Plugin.Log.LogInfo((object)$"{text}{((Object)t).name} localPos={t.localPosition} localScale={t.localScale}{text2}"); for (int i = 0; i < t.childCount; i++) { DumpRecursive(t.GetChild(i), depth + 1); } } } internal static class ItemSpawnerState { public static bool MonitorActive; } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class RunManager_ChangeLevel_Diag_Patch { private static void Prefix() { DumpSpawnedItems("BEFORE ChangeLevel"); } private static void Postfix() { ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DumpAfterDelay()); } } private static IEnumerator DumpAfterDelay() { yield return (object)new WaitForSeconds(1.5f); DumpSpawnedItems("1.5s AFTER ChangeLevel"); } private static void DumpSpawnedItems(string label) { if ((Object)(object)ItemManager.instance == (Object)null) { Plugin.Log.LogInfo((object)("[Diag] " + label + ": ItemManager.instance is null.")); return; } List<ItemAttributes> spawnedItems = ItemManager.instance.spawnedItems; Plugin.Log.LogInfo((object)$"[Diag] {label}: spawnedItems.Count={spawnedItems.Count}"); foreach (ItemAttributes item in spawnedItems) { bool flag = (Object)(object)item != (Object)null; Plugin.Log.LogInfo((object)("[Diag] " + (flag ? "ALIVE" : "DESTROYED") + " - " + (flag ? ((Object)((Component)item).gameObject).name : "?"))); } } } [HarmonyPatch(typeof(RunManager), "GameDirectorStart")] internal static class RunManager_GameDirectorStart_Diag_Patch { private static void Postfix() { Plugin.Log.LogInfo((object)"[Diag] GameDirectorStart fired - run is now officially active (Prepare -> Run, no scene reload)."); DumpSlots("AT GameDirectorStart"); ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DumpSlotsAfterDelay()); } } private static IEnumerator DumpSlotsAfterDelay() { yield return (object)new WaitForSeconds(1.5f); DumpSlots("1.5s AFTER GameDirectorStart"); } private static void DumpSlots(string label) { if ((Object)(object)Inventory.instance == (Object)null) { Plugin.Log.LogInfo((object)("[Diag] " + label + ": Inventory.instance is null.")); return; } List<InventorySpot> allSpots = Inventory.instance.GetAllSpots(); for (int i = 0; i < allSpots.Count; i++) { InventorySpot obj = allSpots[i]; ItemEquippable val = ((obj != null) ? obj.CurrentItem : null); Plugin.Log.LogInfo((object)string.Format("[Diag] {0}: slot {1} = {2}", label, i, ((Object)(object)val != (Object)null) ? ((Object)val).name : "EMPTY")); } } } [HarmonyPatch(typeof(StatsManager), "PlayerInventoryUpdate")] internal static class StatsManager_PlayerInventoryUpdate_Diag_Patch { private static void Prefix(string _steamID, string itemName, int spot, bool sync) { Plugin.Log.LogInfo((object)$"[Diag] PlayerInventoryUpdate: steamID={_steamID} itemName='{itemName}' spot={spot} sync={sync}"); } } [HarmonyPatch(typeof(StatsManager), "LoadItemsFromFolder")] internal static class StatsManager_LoadItemsFromFolder_Patch { private static bool _dumped; private static void Postfix(StatsManager __instance) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (_dumped || !Plugin.DebugDumpsEnabled.Value) { return; } _dumped = true; Plugin.Log.LogInfo((object)$"=== Item DB dump ({__instance.itemDictionary.Count} items) ==="); foreach (KeyValuePair<string, Item> item in __instance.itemDictionary.OrderBy((KeyValuePair<string, Item> kv) => ((object)Unsafe.As<itemType, itemType>(ref kv.Value.itemType)/*cast due to .constrained prefix*/).ToString())) { Item value = item.Value; Plugin.Log.LogInfo((object)$"[{value.itemType}] key={item.Key} itemName=\"{value.itemName}\" category={ItemCategories.Of(value)} disabled={value.disabled}"); } Plugin.Log.LogInfo((object)"=== end item DB dump ==="); } } internal static class ItemCategories { public const string All = "All"; public const string Favorite = "Favorite"; public const string Hide = "Hide"; private static readonly Dictionary<itemType, string> Map = new Dictionary<itemType, string> { { (itemType)9, "Weapons" }, { (itemType)7, "Weapons" }, { (itemType)6, "Weapons" }, { (itemType)15, "Weapons" }, { (itemType)11, "Weapons" }, { (itemType)0, "Drones" }, { (itemType)1, "Drones" }, { (itemType)10, "Drones" }, { (itemType)8, "Healing" }, { (itemType)3, "Upgrades" }, { (itemType)4, "Upgrades" }, { (itemType)2, "Vehicles" }, { (itemType)12, "Vehicles" }, { (itemType)14, "Vehicles" }, { (itemType)13, "Tools" }, { (itemType)5, "Other" } }; public static readonly string[] Order = new string[10] { "All", "Favorite", "Hide", "Weapons", "Drones", "Healing", "Upgrades", "Vehicles", "Tools", "Other" }; public static string Of(Item item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!Map.TryGetValue(item.itemType, out var value)) { return "Other"; } return value; } } [HarmonyPatch(typeof(TruckScreenText), "Update")] internal static class TruckScreenText_Update_Patch { private static readonly FieldRef<TruckScreenText, bool> ScreenActiveRef = AccessTools.FieldRefAccess<TruckScreenText, bool>("screenActive"); private static void Postfix(TruckScreenText __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) bool flag = ScreenActiveRef.Invoke(__instance) && !SemiFunc.RunIsShop(); if (flag) { PlayerAvatar val = SemiFunc.PlayerGetLocal(); if ((Object)(object)val == (Object)null) { flag = false; } else if (Vector3.Distance(val.playerTransform.position, ((Component)__instance).transform.position) > Plugin.MonitorRange.Value) { flag = false; } } ItemSpawnerState.MonitorActive = flag; MonitorUI.SetVisible(flag); } } [HarmonyPatch(typeof(PunManager), "TruckPopulateItemVolumes")] internal static class PunManager_TruckPopulateItemVolumes_Patch { private static void Prefix() { if (!Plugin.DisableFavoritesPatch.Value && !SemiFunc.IsNotMasterClient() && SemiFunc.IsMultiplayer()) { ItemSpawnerNetwork instance = ItemSpawnerNetwork.Instance; if (instance != null) { ((MonoBehaviourPun)instance).photonView.RPC("SyncFavoritesRPC", (RpcTarget)1, new object[2] { Favorites.Counts.Keys.ToArray(), Favorites.Counts.Values.ToArray() }); } } } private static void Postfix() { if (!Plugin.DisableFavoritesPatch.Value && !SemiFunc.IsNotMasterClient()) { ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(CullNonFavoritedAfterSpawn()); } } } private static IEnumerator CullNonFavoritedAfterSpawn() { yield return (object)new WaitForSeconds(0.3f); ItemManager instance = ItemManager.instance; List<ItemAttributes> spawnedItems = instance.spawnedItems; Dictionary<string, int> dictionary = new Dictionary<string, int>(); int num = 0; int num2 = 0; for (int num3 = spawnedItems.Count - 1; num3 >= 0; num3--) { ItemAttributes val = spawnedItems[num3]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.item == (Object)null)) { string itemName = val.item.itemName; int num4 = Favorites.Get(itemName); int value; int num5 = (dictionary.TryGetValue(itemName, out value) ? value : 0); if (num5 < num4) { dictionary[itemName] = num5 + 1; } else { ItemEquippable component = ((Component)val).GetComponent<ItemEquippable>(); if ((Object)(object)component != (Object)null && (Object)(object)Inventory.instance != (Object)null && Inventory.instance.IsItemEquipped(component)) { dictionary[itemName] = num5 + 1; num2++; } else { PhotonView val2 = (SemiFunc.IsMultiplayer() ? ((Component)val).GetComponent<PhotonView>() : null); if ((Object)(object)val2 != (Object)null) { PhotonNetwork.Destroy(val2); } else { Object.Destroy((Object)(object)((Component)val).gameObject); } spawnedItems.RemoveAt(num3); num++; } } } } foreach (KeyValuePair<string, int> kv in dictionary) { for (int i = 0; i < kv.Value; i++) { int num6 = instance.purchasedItems.FindIndex((Item it) => it.itemName == kv.Key); if (num6 >= 0) { instance.purchasedItems.RemoveAt(num6); } } } if (SemiFunc.IsMultiplayer() && dictionary.Count > 0) { ItemSpawnerNetwork instance2 = ItemSpawnerNetwork.Instance; if (instance2 != null) { ((MonoBehaviourPun)instance2).photonView.RPC("ConsumeStockBatchRPC", (RpcTarget)1, new object[2] { dictionary.Keys.ToArray(), dictionary.Values.ToArray() }); } } Plugin.Log.LogInfo((object)$"[ItemSpawner] Truck auto-spawn: kept {dictionary.Values.Sum()} instance(s) across {dictionary.Count} type(s) ({num2} kept only because already equipped), removed {num} non-favorited vanilla-scattered instance(s)."); MonitorUI.RefreshList(); } } internal static class Favorites { public static readonly Dictionary<string, int> Counts = new Dictionary<string, int>(); private static readonly string SaveFilePath = Path.Combine(Paths.ConfigPath, "REPO.LoadoutManager.Favorites.txt"); public static int Get(string itemName) { if (!Counts.TryGetValue(itemName, out var value)) { return 0; } return value; } public static void Set(string itemName, int count) { if (count <= 0) { Counts.Remove(itemName); } else { Counts[itemName] = count; } Save(); } public static int Cycle(string itemName, int ownedCount) { int num = Get(itemName) + 1; if (num > ownedCount) { num = 0; } Set(itemName, num); return num; } public static void ReplaceAll(IEnumerable<string> names, IEnumerable<int> counts) { Counts.Clear(); using IEnumerator<string> enumerator = names.GetEnumerator(); using IEnumerator<int> enumerator2 = counts.GetEnumerator(); while (enumerator.MoveNext() && enumerator2.MoveNext()) { if (enumerator2.Current > 0) { Counts[enumerator.Current] = enumerator2.Current; } } Save(); } public static void Load() { try { if (!File.Exists(SaveFilePath)) { return; } Counts.Clear(); string[] array = File.ReadAllLines(SaveFilePath); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }); if (array2.Length == 2 && int.TryParse(array2[1], out var result) && result > 0) { Counts[array2[0]] = result; } } Plugin.Log.LogInfo((object)$"[Favorites] Loaded {Counts.Count} saved favorite(s) from disk."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Favorites] Failed to load saved favorites: " + ex.Message)); } } private static void Save() { try { File.WriteAllLines(SaveFilePath, Counts.Select((KeyValuePair<string, int> kv) => $"{kv.Key}={kv.Value}")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Favorites] Failed to save favorites: " + ex.Message)); } } } internal static class Hidden { public static readonly HashSet<string> Set = new HashSet<string>(); private static readonly string SaveFilePath = Path.Combine(Paths.ConfigPath, "REPO.LoadoutManager.Hidden.txt"); public static bool Toggle(string itemName) { bool result; if (Set.Contains(itemName)) { Set.Remove(itemName); result = false; } else { Set.Add(itemName); result = true; } Save(); return result; } public static void Load() { try { if (!File.Exists(SaveFilePath)) { return; } Set.Clear(); string[] array = File.ReadAllLines(SaveFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { Set.Add(text); } } Plugin.Log.LogInfo((object)$"[Hidden] Loaded {Set.Count} hidden item(s) from disk."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Hidden] Failed to load hidden items: " + ex.Message)); } } private static void Save() { try { File.WriteAllLines(SaveFilePath, Set); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Hidden] Failed to save hidden items: " + ex.Message)); } } } [HarmonyPatch(typeof(PunManager), "Awake")] internal static class PunManager_Awake_Patch { private static void Postfix(PunManager __instance) { if ((Object)(object)((Component)__instance).GetComponent<ItemSpawnerNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<ItemSpawnerNetwork>(); } } } internal class ItemSpawnerNetwork : MonoBehaviourPun { internal static ItemSpawnerNetwork Instance { get { PunManager instance = PunManager.instance; ItemSpawnerNetwork obj = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponent<ItemSpawnerNetwork>() : null); if ((Object)(object)obj == (Object)null) { Plugin.Log.LogWarning((object)"ItemSpawnerNetwork is missing from PunManager - networked action skipped."); } return obj; } } [PunRPC] public void RequestSpawnRPC(string itemName, Vector3 position, Quaternion rotation, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClient()) { Item val = ((IEnumerable<Item>)StatsManager.instance.itemDictionary.Values).FirstOrDefault((Func<Item, bool>)((Item it) => it.itemName == itemName)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Spawn request for unknown item: " + itemName)); } else if (!ItemManager.instance.purchasedItems.Any((Item i) => i.itemName == itemName)) { ManualLogSource log = Plugin.Log; string[] obj = new string[5] { "Rejected spawn request - no remaining stock of ", itemName, " (requested by ", null, null }; Player sender = info.Sender; obj[3] = ((sender != null) ? sender.NickName : null); obj[4] = ")"; log.LogWarning((object)string.Concat(obj)); } else { PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)val.prefab).ResourcePath, position, rotation, (byte)0, (object[])null); ((MonoBehaviourPun)this).photonView.RPC("ConsumeStockRPC", (RpcTarget)0, new object[1] { itemName }); } } } [PunRPC] public void ConsumeStockRPC(string itemName) { List<Item> purchasedItems = ItemManager.instance.purchasedItems; int num = purchasedItems.FindIndex((Item i) => i.itemName == itemName); if (num >= 0) { purchasedItems.RemoveAt(num); } else { Plugin.Log.LogWarning((object)("ConsumeStockRPC: no local stock entry found for " + itemName + ".")); } MonitorUI.RefreshList(); } [PunRPC] public void ConsumeStockBatchRPC(string[] itemNames, int[] counts) { List<Item> purchasedItems = ItemManager.instance.purchasedItems; int i; for (i = 0; i < itemNames.Length; i++) { for (int j = 0; j < counts[i]; j++) { int num = purchasedItems.FindIndex((Item it) => it.itemName == itemNames[i]); if (num >= 0) { purchasedItems.RemoveAt(num); } else { Plugin.Log.LogWarning((object)("ConsumeStockBatchRPC: no local stock entry found for " + itemNames[i] + ".")); } } } MonitorUI.RefreshList(); } [PunRPC] public void RequestCycleFavoriteRPC(string itemName, int ownedCount, PhotonMessageInfo info = default(PhotonMessageInfo)) { if (SemiFunc.IsMasterClient()) { int num = Favorites.Cycle(itemName, ownedCount); ((MonoBehaviourPun)this).photonView.RPC("SetFavoriteRPC", (RpcTarget)0, new object[2] { itemName, num }); } } [PunRPC] public void SetFavoriteRPC(string itemName, int count) { Favorites.Set(itemName, count); MonitorUI.RefreshList(); } [PunRPC] public void SyncFavoritesRPC(string[] itemNames, int[] counts) { Favorites.ReplaceAll(itemNames, counts); MonitorUI.RefreshList(); } } internal static class ItemSpawner { public static void RequestSpawn(Item item) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return; } PlayerAvatar val = SemiFunc.PlayerGetLocal(); if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = val.playerTransform.position + val.playerTransform.forward * 1.5f; Quaternion identity = Quaternion.identity; if (!SemiFunc.IsMultiplayer()) { List<Item> purchasedItems = ItemManager.instance.purchasedItems; int num = purchasedItems.FindIndex((Item i) => i.itemName == item.itemName); if (num < 0) { Plugin.Log.LogWarning((object)("Blocked spawn - no remaining stock of " + item.itemName)); return; } purchasedItems.RemoveAt(num); Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)item.prefab).Prefab, val2, identity); } else { ItemSpawnerNetwork instance = ItemSpawnerNetwork.Instance; if (instance != null) { ((MonoBehaviourPun)instance).photonView.RPC("RequestSpawnRPC", (RpcTarget)2, new object[3] { item.itemName, val2, identity }); } } } public static void RequestCycleFavorite(Item item, int ownedCount) { if ((Object)(object)item == (Object)null) { return; } if (!SemiFunc.IsMultiplayer()) { int num = Favorites.Cycle(item.itemName, ownedCount); Plugin.Log.LogInfo((object)$"[MonitorUI] {item.itemName} favorite count -> {num}/{ownedCount}"); MonitorUI.RefreshList(); return; } ItemSpawnerNetwork instance = ItemSpawnerNetwork.Instance; if (!((Object)(object)instance == (Object)null)) { if (SemiFunc.IsMasterClient()) { int num2 = Favorites.Cycle(item.itemName, ownedCount); ((MonoBehaviourPun)instance).photonView.RPC("SetFavoriteRPC", (RpcTarget)1, new object[2] { item.itemName, num2 }); Plugin.Log.LogInfo((object)$"[MonitorUI] {item.itemName} favorite count -> {num2}/{ownedCount}"); MonitorUI.RefreshList(); } else { ((MonoBehaviourPun)instance).photonView.RPC("RequestCycleFavoriteRPC", (RpcTarget)2, new object[2] { item.itemName, ownedCount }); } } } } internal static class SettingsMenu { private sealed class KeybindRow { private readonly string _title; private readonly MenuBigButton _native; private readonly REPOButton _fallback; internal bool IsAlive { get { if (!((Object)(object)_native != (Object)null)) { return (Object)(object)_fallback != (Object)null; } return true; } } internal KeybindRow(string title, MenuBigButton native, REPOButton fallback) { _title = title; _native = native; _fallback = fallback; } internal void ShowKey(string keyLabel) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_native != (Object)null) { _native.state = (State)0; _native.buttonName = keyLabel; TextMeshProUGUI val = ButtonTextRef(_native.menuButton); if ((Object)(object)val != (Object)null) { ((TMP_Text)val).text = keyLabel; } } else if ((Object)(object)_fallback != (Object)null && (Object)(object)_fallback.labelTMP != (Object)null) { ((TMP_Text)_fallback.labelTMP).text = _title + ": " + keyLabel; } } internal void ReapplyTitle() { if ((Object)(object)_native != (Object)null) { SetRowTitle(_native, _title); } } internal void ShowListening() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_native != (Object)null) { _native.state = (State)1; } else if ((Object)(object)_fallback != (Object)null && (Object)(object)_fallback.labelTMP != (Object)null) { ((TMP_Text)_fallback.labelTMP).text = _title + ": < press a key >"; } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static BuilderDelegate <>9__11_0; public static ShouldCloseMenuDelegate <>9__18_0; public static ScrollViewBuilderDelegate <>9__19_1; public static ScrollViewBuilderDelegate <>9__19_2; public static Func<Transform, Vector3> <>9__34_1; public static Func<Vector3, float> <>9__34_2; internal void <Register>b__11_0(Transform parent) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) REPOButton button = MenuAPI.CreateREPOButton("Loadout Manager", (Action)OpenStandalonePage, parent, Vector2.zero); PlaceBelowExistingButtons(parent, button); } internal bool <OpenStandalonePage>b__18_0() { if (_listening == null) { return true; } StopListening(); return false; } internal RectTransform <BuildRows>b__19_1(Transform scrollView) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return ((REPOElement)MenuAPI.CreateREPOLabel("Keybinds", scrollView, default(Vector2))).rectTransform; } internal RectTransform <BuildRows>b__19_2(Transform scrollView) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return ((REPOElement)MenuAPI.CreateREPOLabel("Esc cancel / Del unbind", scrollView, default(Vector2))).rectTransform; } internal Vector3 <PlaceBelowExistingButtons>b__34_1(Transform t) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return t.localPosition; } internal float <PlaceBelowExistingButtons>b__34_2(Vector3 p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return p.y; } internal bool <.cctor>b__39_0(KeyCode k) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return !Unbindable.Contains(k); } } private static KeyBinding _listening; private static readonly Dictionary<KeyBinding, KeybindRow> _bindRows = new Dictionary<KeyBinding, KeybindRow>(); private static readonly FieldRef<MenuButton, TextMeshProUGUI> _buttonTextRef = AccessTools.FieldRefAccess<MenuButton, TextMeshProUGUI>("buttonText"); private static readonly FieldRef<MenuKeybind, MenuBigButton> _keybindBigButtonRef = AccessTools.FieldRefAccess<MenuKeybind, MenuBigButton>("menuBigButton"); private static readonly Dictionary<KeyBinding, KeyCode> _displayed = new Dictionary<KeyBinding, KeyCode>(); private static FieldInfo _changedValuesField; private static FieldInfo _originalValuesField; private static readonly HashSet<KeyCode> Unbindable = new HashSet<KeyCode> { (KeyCode)0, (KeyCode)27, (KeyCode)127, (KeyCode)323, (KeyCode)324, (KeyCode)325, (KeyCode)326, (KeyCode)327, (KeyCode)328, (KeyCode)329 }; private static readonly KeyCode[] BindableKeys = (from KeyCode k in Enum.GetValues(typeof(KeyCode)) where !Unbindable.Contains(k) select k).Distinct().ToArray(); private static bool _listeningStaged; private static bool _titlesNeedReapply; private static int _reapplyFramesLeft; private static Dictionary<ConfigEntryBase, object> Changed => (Dictionary<ConfigEntryBase, object>)_changedValuesField.GetValue(null); private static Dictionary<ConfigEntryBase, object> Originals => (Dictionary<ConfigEntryBase, object>)_originalValuesField.GetValue(null); private static TextMeshProUGUI ButtonTextRef(MenuButton button) { if (!((Object)(object)button == (Object)null)) { return _buttonTextRef.Invoke(button); } return null; } internal static void Register(Harmony harmony) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if (Chainloader.PluginInfos.ContainsKey("nickklmao.repoconfig") && TryHookRepoConfig(harmony)) { Plugin.Log.LogInfo((object)"[Settings] Using our own rows on the REPOConfig Mods page."); return; } object obj = <>c.<>9__11_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) REPOButton button = MenuAPI.CreateREPOButton("Loadout Manager", (Action)OpenStandalonePage, parent, Vector2.zero); PlaceBelowExistingButtons(parent, button); }; <>c.<>9__11_0 = val; obj = (object)val; } MenuAPI.AddElementToSettingsMenu((BuilderDelegate)obj); Plugin.Log.LogInfo((object)"[Settings] REPOConfig not available - added a standalone page under Settings."); } private static bool TryHookRepoConfig(Harmony harmony) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("REPOConfig.ConfigMenu"); if (type == null) { return false; } MethodInfo methodInfo = AccessTools.Method(type, "CreateModEntries", (Type[])null, (Type[])null); _changedValuesField = AccessTools.Field(type, "changedEntryValues"); _originalValuesField = AccessTools.Field(type, "originalEntryValues"); if (methodInfo == null || _changedValuesField == null || _originalValuesField == null) { return false; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(SettingsMenu), "CreateModEntriesPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Settings] Could not hook REPOConfig (" + ex.Message + "). Falling back to a Settings page.")); return false; } } private static bool CreateModEntriesPrefix(REPOPopupPage modPage, ConfigEntryBase[] configEntryBases) { if (configEntryBases == null || !configEntryBases.Contains((ConfigEntryBase)(object)Plugin.MonitorRange)) { return true; } try { BuildRows(modPage, staged: true); return false; } catch (Exception arg) { Plugin.Log.LogError((object)$"[Settings] Failed to build our Mods page rows, falling back to REPOConfig's: {arg}"); return true; } } private static void OpenStandalonePage() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown REPOPopupPage obj = MenuAPI.CreateREPOPopupPage("Loadout Manager", (PresetSide)1, false, false, 0f); BuildRows(obj, staged: false); object obj2 = <>c.<>9__18_0; if (obj2 == null) { ShouldCloseMenuDelegate val = delegate { if (_listening == null) { return true; } StopListening(); return false; }; <>c.<>9__18_0 = val; obj2 = (object)val; } obj.onEscapePressed = (ShouldCloseMenuDelegate)obj2; obj.OpenPage(false); } private static void BuildRows(REPOPopupPage page, bool staged) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown StopListening(); _bindRows.Clear(); _displayed.Clear(); if (staged) { foreach (ConfigEntryBase item in OurEntries()) { RememberOriginal(item); } } page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOSlider("Monitor Range", "How close you must stand to the truck's monitor", (Action<float>)delegate(float value) { Apply((ConfigEntryBase)(object)Plugin.MonitorRange, value, staged); }, scrollView, default(Vector2), 1f, 20f, 0, CurrentRange(staged), string.Empty, string.Empty, (BarBehavior)0)).rectTransform), 10f, 10f); object obj = <>c.<>9__19_1; if (obj == null) { ScrollViewBuilderDelegate val = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOLabel("Keybinds", scrollView, default(Vector2))).rectTransform; <>c.<>9__19_1 = val; obj = (object)val; } page.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 25f, 20f); Transform template = FindKeybindTemplate(); _titlesNeedReapply = (Object)(object)template != (Object)null; foreach (KeyBinding item2 in Keybinds.All) { KeyBinding captured = item2; _displayed[captured] = CurrentKey(captured, staged); page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform scrollView) => BuildKeybindRow(scrollView, template, captured, staged)), 0f, 8f); } object obj2 = <>c.<>9__19_2; if (obj2 == null) { ScrollViewBuilderDelegate val2 = (Transform scrollView) => ((REPOElement)MenuAPI.CreateREPOLabel("Esc cancel / Del unbind", scrollView, default(Vector2))).rectTransform; <>c.<>9__19_2 = val2; obj2 = (object)val2; } page.AddElementToScrollView((ScrollViewBuilderDelegate)obj2, 20f, 20f); } private static Transform FindKeybindTemplate() { try { MenuManager instance = MenuManager.instance; if ((Object)(object)instance == (Object)null || instance.menuPages == null) { return null; } foreach (MenuPages menuPage in instance.menuPages) { if (menuPage != null && !((Object)(object)menuPage.menuPage == (Object)null)) { MenuKeybind componentInChildren = menuPage.menuPage.GetComponentInChildren<MenuKeybind>(true); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)((Component)componentInChildren).GetComponent<MenuBigButton>() == (Object)null)) { return ((Component)componentInChildren).transform; } } } Plugin.Log.LogWarning((object)"[Settings] No MenuKeybind row found in the game's menus - using plain buttons."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Settings] Could not fetch the game's keybind row (" + ex.Message + ") - using plain buttons.")); } return null; } private static RectTransform BuildKeybindRow(Transform scrollView, Transform template, KeyBinding binding, bool staged) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template != (Object)null) { try { RectTransform val = CloneNativeRow(scrollView, template, binding, staged); if ((Object)(object)val != (Object)null) { return val; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Settings] Falling back to a plain button for " + binding.DisplayName + ": " + ex.Message)); } } REPOButton val2 = MenuAPI.CreateREPOButton(binding.DisplayName + ": " + KeyBinding.LabelFor(_displayed[binding]), (Action)delegate { StartListening(binding, staged); }, scrollView, default(Vector2)); _bindRows[binding] = new KeybindRow(binding.DisplayName, null, val2); return ((REPOElement)val2).rectTransform; } private static RectTransform CloneNativeRow(Transform scrollView, Transform template, KeyBinding binding, bool staged) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, scrollView, false); ((Object)val).name = "Loadout Manager Keybind - " + binding.DisplayName; MenuBigButton component = val.GetComponent<MenuBigButton>(); if ((Object)(object)component == (Object)null || (Object)(object)component.menuButton == (Object)null) { Object.Destroy((Object)(object)val); return null; } MenuKeybind component2 = val.GetComponent<MenuKeybind>(); if ((Object)(object)component2 != (Object)null) { _keybindBigButtonRef.Invoke(component2) = component; Object.DestroyImmediate((Object)(object)component2); } component.buttonTitle = binding.DisplayName; SetRowTitle(component, binding.DisplayName); component.state = (State)0; Button component3 = ((Component)component.menuButton).GetComponent<Button>(); if ((Object)(object)component3 == (Object)null) { Object.Destroy((Object)(object)val); return null; } for (int i = 0; i < ((UnityEventBase)component3.onClick).GetPersistentEventCount(); i++) { ((UnityEventBase)component3.onClick).SetPersistentListenerState(i, (UnityEventCallState)0); } ((UnityEventBase)component3.onClick).RemoveAllListeners(); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { StartListening(binding, staged); }); KeybindRow keybindRow = new KeybindRow(binding.DisplayName, component, null); _bindRows[binding] = keybindRow; keybindRow.ShowKey(KeyBinding.LabelFor(_displayed[binding])); return (RectTransform)val.transform; } private static void SetRowTitle(MenuBigButton big, string title) { TextMeshProUGUI val = ButtonTextRef(big.menuButton); if ((Object)(object)big.buttonTitleTextMesh != (Object)null && (Object)(object)big.buttonTitleTextMesh != (Object)(object)val) { ((TMP_Text)big.buttonTitleTextMesh).text = title; return; } TextMeshProUGUI[] componentsInChildren = ((Component)big).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)(object)val)) { ((TMP_Text)val2).text = title; return; } } Plugin.Log.LogWarning((object)("[Settings] No title label found on the keybind row for " + title + ".")); } private static IEnumerable<ConfigEntryBase> OurEntries() { yield return (ConfigEntryBase)(object)Plugin.MonitorRange; foreach (KeyBinding item in Keybinds.All) { yield return item.Entry; } } private static void RememberOriginal(ConfigEntryBase entry) { Dictionary<ConfigEntryBase, object> originals = Originals; originals.Remove(entry); originals.Add(entry, entry.BoxedValue); } private static void Apply(ConfigEntryBase entry, object value, bool staged) { if (!staged) { entry.BoxedValue = value; return; } Dictionary<ConfigEntryBase, object> changed = Changed; if (Originals.TryGetValue(entry, out var value2) && object.Equals(value2, value)) { changed.Remove(entry); } else { changed[entry] = value; } } private static float CurrentRange(bool staged) { if (staged && Changed.TryGetValue((ConfigEntryBase)(object)Plugin.MonitorRange, out var value) && value is float) { return (float)value; } return Plugin.MonitorRange.Value; } private static KeyCode CurrentKey(KeyBinding binding, bool staged) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (staged && Changed.TryGetValue(binding.Entry, out var value) && value is string value2 && Enum.TryParse<KeyCode>(value2, out KeyCode result)) { return result; } return binding.Code; } private static void StartListening(KeyBinding binding, bool staged) { StopListening(); _listening = binding; _listeningStaged = staged; if (_bindRows.TryGetValue(binding, out var value)) { value.ShowListening(); } } private static void StopListening() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (_listening != null && _bindRows.TryGetValue(_listening, out var value)) { KeyCode value2; KeyCode code = (_displayed.TryGetValue(_listening, out value2) ? value2 : _listening.Code); value.ShowKey(KeyBinding.LabelFor(code)); } _listening = null; } private unsafe static void Bind(KeyCode code) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if ((int)code != 0) { UnbindConflicts(code); } _displayed[_listening] = code; Apply(_listening.Entry, ((object)(*(KeyCode*)(&code))/*cast due to .constrained prefix*/).ToString(), _listeningStaged); StopListening(); } private static void UnbindConflicts(KeyCode code) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) foreach (KeyBinding item in Keybinds.All) { if (item != _listening && (_displayed.TryGetValue(item, out var value) ? value : item.Code) == code) { _displayed[item] = (KeyCode)0; Apply(item.Entry, ((object)(KeyCode)0/*cast due to .constrained prefix*/).ToString(), _listeningStaged); if (_bindRows.TryGetValue(item, out var value2) && value2.IsAlive) { value2.ShowKey(KeyBinding.LabelFor((KeyCode)0)); } } } } private static void PlaceBelowExistingButtons(Transform parent, REPOButton button) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = (from Transform t in (IEnumerable)parent where (Object)(object)t != (Object)(object)((REPOElement)button).rectTransform select t.localPosition).ToList(); if (list.Count != 0) { List<Vector3> list2 = list.OrderByDescending((Vector3 p) => p.y).ToList(); float num = ((list2.Count >= 2) ? (list2[0].y - list2[1].y) : 34f); if (num <= 0f) { num = 34f; } Vector3 val = list2[list2.Count - 1]; ((Transform)((REPOElement)button).rectTransform).localPosition = new Vector3(val.x, val.y - num, val.z); } } private static void MaintainTitles() { if (_titlesNeedReapply) { _titlesNeedReapply = false; _reapplyFramesLeft = 5; } else { if (_reapplyFramesLeft <= 0) { return; } _reapplyFramesLeft--; foreach (KeybindRow value in _bindRows.Values) { value.ReapplyTitle(); } } } internal static void PollRebind() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) MaintainTitles(); if (_listening == null) { return; } if (!_bindRows.TryGetValue(_listening, out var value) || !value.IsAlive) { _listening = null; return; } if (Input.GetKeyDown((KeyCode)27)) { StopListening(); return; } if (Input.GetKeyDown((KeyCode)127)) { Bind((KeyCode)0); return; } KeyCode[] bindableKeys = BindableKeys; foreach (KeyCode val in bindableKeys) { if (Input.GetKeyDown(val)) { Bind(val); break; } } } } }