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.5
BepInEx/plugins/REPO.LoadoutManager.dll
Decompiled an hour 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.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; 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.5.0")] [assembly: AssemblyInformationalVersion("0.1.5")] [assembly: AssemblyProduct("REPO.LoadoutManager")] [assembly: AssemblyTitle("REPO.LoadoutManager")] [assembly: AssemblyVersion("0.1.5.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 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_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Expected O, but got Unknown //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Expected O, but got Unknown //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Expected O, but got Unknown //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0563: 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); AddLabel((Transform)(object)val6, "Arrows: Move Enter: Spawn F: Favorite H: Hide", 0.115f, 0.18f); 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) { _rootGO.SetActive(visible); } } 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 void AddLabel(Transform parent, string text, float fontSize, float height) { //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_0044: 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) 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; } 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; } public static void RefreshList() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: 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; } 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.5")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "kohei.repo.loadoutmanager"; public const string PluginName = "REPO Loadout Manager"; public const string PluginVersion = "0.1.5"; internal static ManualLogSource Log; internal static ConfigEntry<bool> DebugDumpsEnabled; internal static ConfigEntry<bool> DebugHotkeysEnabled; internal static ConfigEntry<bool> DisableFavoritesPatch; private void Awake() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; DebugDumpsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugDumps", false, "Log the full item DB and the truck monitor's 3D hierarchy once, for development. Leave off unless debugging."); DebugHotkeysEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugHotkeys", false, "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. Off by default - these are level-skip shortcuts for testing, not meant for normal play. Enable only when debugging."); DisableFavoritesPatch = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DisableFavoritesPatch", false, "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."); Favorites.Load(); new Harmony("kohei.repo.loadoutmanager").PatchAll(); Log.LogInfo((object)"REPO Loadout Manager v0.1.5 loaded."); } } [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 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() { if (ItemSpawnerState.MonitorActive) { if (Input.GetKeyDown((KeyCode)274)) { MonitorUI.MoveSelection(1); } else if (Input.GetKeyDown((KeyCode)273)) { MonitorUI.MoveSelection(-1); } else if (Input.GetKeyDown((KeyCode)275)) { MonitorUI.ChangeCategory(1); } else if (Input.GetKeyDown((KeyCode)276)) { MonitorUI.ChangeCategory(-1); } else if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)) { MonitorUI.ConfirmSelection(); } else if (Input.GetKeyDown((KeyCode)102)) { MonitorUI.CycleFavoriteSelected(); } else if (Input.GetKeyDown((KeyCode)104)) { 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)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 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 const float MaxInteractDistance = 8f; 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) > 8f) { 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()) { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent<ItemSpawnerNetwork>()).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) { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent<ItemSpawnerNetwork>()).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>(); public static bool Toggle(string itemName) { if (Set.Contains(itemName)) { Set.Remove(itemName); return false; } Set.Add(itemName); return true; } } [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 { [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 + ".")); } } [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 { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent<ItemSpawnerNetwork>()).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 component = ((Component)PunManager.instance).GetComponent<ItemSpawnerNetwork>(); if (SemiFunc.IsMasterClient()) { int num2 = Favorites.Cycle(item.itemName, ownedCount); ((MonoBehaviourPun)component).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)component).photonView.RPC("RequestCycleFavoriteRPC", (RpcTarget)2, new object[2] { item.itemName, ownedCount }); } } } }