The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of ItemFinder v1.0.6
plugins/ItemFinder.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; using BepInEx; using HarmonyLib; using ItemSelector; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ItemFinder")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ItemFinder")] [assembly: AssemblyTitle("ItemFinder")] [assembly: AssemblyVersion("1.0.0.0")] public class ArrowLabelManager : MonoBehaviour { public class Billboard : MonoBehaviour { private void Update() { if (!((Object)(object)Camera.main == (Object)null)) { ((Component)this).transform.LookAt(((Component)Camera.main).transform); ((Component)this).transform.Rotate(0f, 180f, 0f); } } } public class DynamicBillboard : MonoBehaviour { public float scaleMultiplier = 1f; public float distanceScalingFactor = 0.02f; private Vector3 initialScale; private void Awake() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) initialScale = ((Component)this).transform.localScale; } private void Update() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Camera.main == (Object)null)) { ((Component)this).transform.LookAt(((Component)Camera.main).transform); ((Component)this).transform.Rotate(0f, 180f, 0f); float num = Vector3.Distance(((Component)this).transform.position, ((Component)Camera.main).transform.position); ((Component)this).transform.localScale = initialScale * (1f + num * distanceScalingFactor) * scaleMultiplier; } } } private Transform parentRoot; private readonly List<GameObject> spawnedObjects = new List<GameObject>(); private bool arrowsVisible = true; private bool labelsVisible = true; private void Awake() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown Debug.Log((object)$"[ArrowLabelManager] Awake on GameObject '{((Object)((Component)this).gameObject).name}', instanceID {((Object)this).GetInstanceID()}"); GameObject val = new GameObject("ArrowsAndLabelsRoot"); val.transform.SetParent(((Component)this).transform, false); parentRoot = val.transform; } public void ClearAll() { for (int num = spawnedObjects.Count - 1; num >= 0; num--) { GameObject val = spawnedObjects[num]; if ((Object)(object)val != (Object)null) { Object.DestroyImmediate((Object)(object)val); } } spawnedObjects.Clear(); } public void SpawnForItems(List<ItemFinder.ItemData> items) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0188: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //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_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: 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_0297: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0328: 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_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) ClearAll(); Debug.Log((object)("[ArrowLabelManager] SpawnForItems called. items.count=" + (items?.Count ?? 0))); if (items == null || items.Count == 0) { return; } if (ConfigManager._settingsConfig == null || ConfigManager._settingsConfig.automation == null) { Debug.LogWarning((object)"[ArrowLabelManager] Config or settings is null, using defaults"); return; } ArrowSettings arrows = ConfigManager._settingsConfig.automation.arrows; LabelSettings labels = ConfigManager._settingsConfig.automation.labels; List<ItemFinder.ItemData> list = items.Where((ItemFinder.ItemData i) => i.itemType != "Campfire").ToList(); foreach (ItemFinder.ItemData item2 in list) { ArrowConfigData topArrow = arrows.topArrow; float num = arrows.topArrowYScale / arrows.meshDefaultHeight; Vector3 scale = topArrow.GetScale(); scale.y = num; GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val.GetComponent<Collider>()); val.transform.SetParent(parentRoot, true); val.transform.localScale = scale; float num2 = num * arrows.meshDefaultHeight / 2f; val.transform.position = item2.position + Vector3.up * (topArrow.hoverHeight + num2); Material val2 = new Material(Shader.Find("Unlit/Color")); val2.color = topArrow.GetColor(); Renderer component = val.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null) { component.material = val2; } val.layer = LayerMask.NameToLayer("Default"); ((Object)val).name = "PeakArrow_Top"; spawnedObjects.Add(val); ArrowConfigData bottomArrow = arrows.bottomArrow; float num3 = arrows.bottomArrowYScale / arrows.meshDefaultHeight; Vector3 scale2 = bottomArrow.GetScale(); scale2.y = num3; GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val3.GetComponent<Collider>()); val3.transform.SetParent(parentRoot, true); val3.transform.localScale = scale2; float num4 = num3 * arrows.meshDefaultHeight / 2f; val3.transform.position = item2.position - Vector3.up * (bottomArrow.hoverHeight + num4); Material val4 = new Material(Shader.Find("Unlit/Color")); val4.color = bottomArrow.GetColor(); Renderer component2 = val3.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { component2.material = val4; } val3.layer = LayerMask.NameToLayer("Default"); ((Object)val3).name = "PeakArrow_Bottom"; spawnedObjects.Add(val3); } for (int j = 0; j < list.Count; j++) { ItemFinder.ItemData itemData = list[j]; Vector3 position = itemData.position + new Vector3(labels.xOffset, labels.YOffset, labels.zOffset); string text; if (ConfigManager._settingsConfig.automation.labels.useNiceNames) { text = ItemNameManager.Instance.GetNiceName(itemData.objectName); if (string.IsNullOrEmpty(text) || text == itemData.objectName) { text = ItemNameManager.Instance.GetNiceName(itemData.itemType); } if (string.IsNullOrEmpty(text) || text == itemData.itemType) { text = itemData.displayName; } } else { text = itemData.itemType ?? itemData.objectName ?? itemData.displayName ?? "Unknown"; } if (ConfigManager._settingsConfig.automation.labels.simplifyMushroomNames) { string text2 = (itemData.objectName ?? itemData.itemType ?? "").Replace("(Clone)", "").Trim(); if (text2.Contains("Mushroom")) { if (text2.Contains("Lace") && text2.Contains("Poison")) { text = "Bugle Shroom Poison"; } else if (text2.Contains("Lace")) { text = "Bugle Shroom"; } else if (text2.Contains("Normie") && text2.Contains("Poison")) { text = "Button Shroom Poison"; } else if (text2.Contains("Normie")) { text = "Button Shroom"; } else if (text2.Contains("Cluster") && text2.Contains("Poison")) { text = "Cluster Shroom Poison"; } else if (text2.Contains("Cluster")) { text = "Cluster Shroom"; } } GameObject item = CreateBoldTextLabel(text, position); spawnedObjects.Add(item); } ApplyVisibility(); Debug.Log((object)("[ArrowLabelManager] SpawnForItems completed. spawnedObjects=" + spawnedObjects.Count)); } } public void SpawnForAdditionalItems(List<ItemFinder.ItemData> newItems) { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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_0181: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)("[ArrowLabelManager] SpawnForAdditionalItems called. newItems.count=" + (newItems?.Count ?? 0))); if (newItems == null || newItems.Count == 0) { return; } if (ConfigManager._settingsConfig == null || ConfigManager._settingsConfig.automation == null) { Debug.LogWarning((object)"[ArrowLabelManager] Config or settings is null, using defaults"); return; } ArrowSettings arrows = ConfigManager._settingsConfig.automation.arrows; LabelSettings labels = ConfigManager._settingsConfig.automation.labels; List<ItemFinder.ItemData> list = newItems.Where((ItemFinder.ItemData i) => i.itemType != "Campfire").ToList(); foreach (ItemFinder.ItemData item2 in list) { ArrowConfigData topArrow = arrows.topArrow; float num = arrows.topArrowYScale / arrows.meshDefaultHeight; Vector3 scale = topArrow.GetScale(); scale.y = num; GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val.GetComponent<Collider>()); val.transform.SetParent(parentRoot, true); val.transform.localScale = scale; float num2 = num * arrows.meshDefaultHeight / 2f; val.transform.position = item2.position + Vector3.up * (topArrow.hoverHeight + num2); Material val2 = new Material(Shader.Find("Unlit/Color")); val2.color = topArrow.GetColor(); Renderer component = val.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null) { component.material = val2; } val.layer = LayerMask.NameToLayer("Default"); ((Object)val).name = "PeakArrow_Top"; spawnedObjects.Add(val); ArrowConfigData bottomArrow = arrows.bottomArrow; float num3 = arrows.bottomArrowYScale / arrows.meshDefaultHeight; Vector3 scale2 = bottomArrow.GetScale(); scale2.y = num3; GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)2); Object.DestroyImmediate((Object)(object)val3.GetComponent<Collider>()); val3.transform.SetParent(parentRoot, true); val3.transform.localScale = scale2; float num4 = num3 * arrows.meshDefaultHeight / 2f; val3.transform.position = item2.position - Vector3.up * (bottomArrow.hoverHeight + num4); Material val4 = new Material(Shader.Find("Unlit/Color")); val4.color = bottomArrow.GetColor(); Renderer component2 = val3.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { component2.material = val4; } val3.layer = LayerMask.NameToLayer("Default"); ((Object)val3).name = "PeakArrow_Bottom"; spawnedObjects.Add(val3); } for (int j = 0; j < list.Count; j++) { ItemFinder.ItemData itemData = list[j]; Vector3 position = itemData.position + new Vector3(labels.xOffset, labels.YOffset, labels.zOffset); string text; if (ConfigManager._settingsConfig.automation.labels.useNiceNames) { text = ItemNameManager.Instance.GetNiceName(itemData.objectName); if (string.IsNullOrEmpty(text) || text == itemData.objectName) { text = ItemNameManager.Instance.GetNiceName(itemData.itemType); } if (string.IsNullOrEmpty(text) || text == itemData.itemType) { text = itemData.displayName; } } else { text = itemData.itemType ?? itemData.objectName ?? itemData.displayName ?? "Unknown"; } if (ConfigManager._settingsConfig.automation.labels.simplifyMushroomNames) { string text2 = (itemData.objectName ?? itemData.itemType ?? "").Replace("(Clone)", "").Trim(); if (text2.Contains("Mushroom")) { if (text2.Contains("Lace") && text2.Contains("Poison")) { text = "Bugle Shroom Poison"; } else if (text2.Contains("Lace")) { text = "Bugle Shroom"; } else if (text2.Contains("Normie") && text2.Contains("Poison")) { text = "Button Shroom Poison"; } else if (text2.Contains("Normie")) { text = "Button Shroom"; } else if (text2.Contains("Cluster") && text2.Contains("Poison")) { text = "Cluster Shroom Poison"; } else if (text2.Contains("Cluster")) { text = "Cluster Shroom"; } } } GameObject item = CreateBoldTextLabel(text, position); spawnedObjects.Add(item); } ApplyVisibility(); Debug.Log((object)$"[ArrowLabelManager] SpawnForAdditionalItems completed. Total spawnedObjects: {spawnedObjects.Count}"); } private GameObject CreateBoldTextLabel(string text, Vector3 position) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0032: Expected O, but got Unknown //IL_004b: 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_00bb: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) Vector3 val = position; Debug.Log((object)("[ArrowLabelManager] Creating text label: " + text + " @ " + ((object)(Vector3)(ref val)).ToString())); GameObject val2 = new GameObject("ItemLabel"); val2.transform.SetParent(parentRoot, true); val2.transform.position = position; LabelSettings labelSettings = ConfigManager._settingsConfig?.automation?.labels; float num = labelSettings?.fontSize ?? 15f; float num2 = labelSettings?.faceDilate ?? 0.05f; float outlineWidth = labelSettings?.outlineWidth ?? 0.09f; Color color = (Color)(((??)labelSettings?.fontColor) ?? new Color(1f, 0.9f, 0.2f, 1f)); Color val3 = labelSettings?.outlineColor ?? Color.black; Color color2 = (Color)(((??)labelSettings?.fallbackFontColor) ?? new Color(1f, 0.8f, 0.1f, 1f)); TMP_FontAsset val4 = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name == "DarumaDropOne-Regular SDF")); if ((Object)(object)val4 != (Object)null) { TextMeshPro val5 = val2.AddComponent<TextMeshPro>(); ((TMP_Text)val5).text = text; ((TMP_Text)val5).font = val4; ((TMP_Text)val5).fontSize = num; if ((Object)(object)((TMP_Text)val5).fontMaterial != (Object)null) { ((TMP_Text)val5).fontMaterial.SetFloat("_FaceDilate", num2); } ((Graphic)val5).color = color; ((TMP_Text)val5).alignment = (TextAlignmentOptions)514; ((TMP_Text)val5).outlineColor = Color32.op_Implicit(val3); ((TMP_Text)val5).outlineWidth = outlineWidth; } else { TextMesh val6 = val2.AddComponent<TextMesh>(); val6.text = text; val6.fontSize = (int)num; val6.color = color2; val6.anchor = (TextAnchor)4; val6.alignment = (TextAlignment)1; } try { if (labelSettings != null && labelSettings.followCamera) { DynamicBillboard dynamicBillboard = val2.AddComponent<DynamicBillboard>(); dynamicBillboard.scaleMultiplier = labelSettings.scaleMultiplier; dynamicBillboard.distanceScalingFactor = labelSettings.distanceScalingFactor; } else { val2.AddComponent<Billboard>(); } } catch { val2.AddComponent<Billboard>(); } val2.layer = LayerMask.NameToLayer("Default"); return val2; } public void ToggleArrows() { arrowsVisible = !arrowsVisible; ApplyVisibility(); } public void ToggleLabels() { labelsVisible = !labelsVisible; ApplyVisibility(); } public void SetVisibility(bool arrowsActive, bool labelsActive) { arrowsVisible = arrowsActive; labelsVisible = labelsActive; ApplyVisibility(); } private void ApplyVisibility() { foreach (GameObject spawnedObject in spawnedObjects) { if (!((Object)(object)spawnedObject == (Object)null)) { if (((Object)spawnedObject).name == "ItemLabel") { spawnedObject.SetActive(labelsVisible); } else { spawnedObject.SetActive(arrowsVisible); } } } } public int GetSpawnedObjectCount() { return spawnedObjects.Count; } public void DebugSpawnedObjects() { Debug.Log((object)$"[ArrowLabelManager] Total spawned objects: {spawnedObjects.Count}"); Debug.Log((object)$"[ArrowLabelManager] Non-null objects: {spawnedObjects.Count((GameObject obj) => (Object)(object)obj != (Object)null)}"); Debug.Log((object)$"[ArrowLabelManager] Null objects: {spawnedObjects.Count((GameObject obj) => (Object)(object)obj == (Object)null)}"); List<GameObject> list = spawnedObjects.Where((GameObject obj) => (Object)(object)obj != (Object)null && obj.activeInHierarchy).ToList(); Debug.Log((object)$"[ArrowLabelManager] Active objects: {list.Count}"); List<GameObject> list2 = list.Where((GameObject obj) => ((Object)obj).name.Contains("Arrow")).ToList(); List<GameObject> list3 = list.Where((GameObject obj) => ((Object)obj).name == "ItemLabel").ToList(); Debug.Log((object)$"[ArrowLabelManager] Active arrows: {list2.Count}, Active labels: {list3.Count}"); } } public static class BiomeDetector { public static string CurrentBiome { get; private set; } static BiomeDetector() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown CurrentBiome = "Unknown"; Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; logs.Log("[BiomeDetector] Static constructor - Scene: " + name); Application.logMessageReceived += new LogCallback(OnLogMessageReceived); logs.Log("[BiomeDetector] Log listener registered - will detect biome changes automatically"); } public static void Initialize() { logs.Log("[BiomeDetector] Initialized. Current biome: " + CurrentBiome); } private static string GetFullPath(GameObject obj) { string text = ((Object)obj).name; Transform parent = obj.transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } public static void DetectInitialBiome() { GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0); GameObject[] array2 = array; foreach (GameObject val in array2) { if (((Object)val).name == "crashed plane") { string fullPath = GetFullPath(val); if (fullPath == "Map/Biome_1/Beach/Beach_Segment/crashed plane") { CurrentBiome = "SHORE"; logs.Log("[BiomeDetector] Initial biome detected: " + CurrentBiome + " (found crashed plane)"); return; } } } logs.Log("[BiomeDetector] Could not detect initial biome from scene objects"); } private static void OnLogMessageReceived(string logString, string stackTrace, LogType type) { if (logString.Contains("Set hero title: ")) { string text = logString.Replace("Set hero title: ", "").Trim(); if (ConfigManager._settingsConfig?.general?.validBiomes != null && ConfigManager._settingsConfig.general.validBiomes.Contains(text) && CurrentBiome != text) { string currentBiome = CurrentBiome; CurrentBiome = text; logs.Log("[BiomeDetector] Biome changed: " + currentBiome + " -> " + CurrentBiome); } } } } [Serializable] public class ItemsConfig { public CustomItemDetectionRule[] customItems = new CustomItemDetectionRule[0]; public CustomItemDetectionRule[] dbItems = new CustomItemDetectionRule[0]; public CampfireRule[] campfireRules = new CampfireRule[0]; [JsonIgnore] public ItemDetectionRule[] itemDetectionRules { get { List<ItemDetectionRule> list = new List<ItemDetectionRule>(); if (customItems != null) { list.AddRange(customItems); } if (dbItems != null) { list.AddRange(dbItems); } return list.ToArray(); } } } [Serializable] public class SettingsConfig { public AutomationSettings automation = new AutomationSettings(); public GeneralSettings general = new GeneralSettings(); public UISettings ui = new UISettings(); public CoordsGUISettings coordsGUI = new CoordsGUISettings(); } [Serializable] public class GeneralSettings { public string outputPath = ""; public string configPath = ""; public bool LogUnityDebug = false; public float levelReadyDelay = 2f; public float luggageOpenDelay = 1f; public float luggageTimeout = 10f; public float biomeChangeTimeout = 30f; public int stabilityThreshold = 20; public int maxStabilityChecks = 100; public float stabilityCheckInterval = 0.1f; public float positionToMetersMultiplier = 1.59f; public string timestampFormat = "yyyyMMdd_HHmmss"; public string automationContinueKey = "Alpha0"; public int? AscentToLoad = null; public int? LevelToLoad = null; public int? Levelindex = null; public string[] validBiomes = new string[12] { "SHORE", "TROPICS", "JUNGLE", "MESA", "DESERT", "ALPINE", "SNOW", "TUNDRA", "CALDERA", "VOLCANO", "KILN", "THE KILN" }; public KeyboardSettings keyboard = new KeyboardSettings(); public bool OpenLuggageAutomatically = true; public bool SkipAirportLobby = false; public bool fetchLevelIndexFromServer = false; public string levelServerUrl = "https://peaklogin.azurewebsites.net/api/VersionCheck"; public string _comment_AscentToLoad = "defaults to -1 (tenderfoot)"; public string _comment_LevelToLoad = "unused"; public string _comment_Levelindex = "unused"; public string _comment_SkipAirportLobby = "placeholder"; public string _comment_fetchLevelIndexFromServer = "unused"; public string _comment_levelServerUrl = "unused"; public string GetOutputDirectory() { if (string.IsNullOrEmpty(outputPath)) { return Path.Combine(Paths.PluginPath, "ItemFinder", "output"); } if (Path.IsPathRooted(outputPath)) { return outputPath; } return Path.Combine(Paths.PluginPath, "ItemFinder", outputPath); } public string GetConfigDirectory() { if (string.IsNullOrEmpty(configPath)) { return Path.Combine(Paths.ConfigPath, "ItemFinder"); } if (Path.IsPathRooted(configPath)) { return configPath; } return Path.Combine(Paths.ConfigPath, "ItemFinder", configPath); } } [Serializable] public class KeyboardSettings { public string _comment_hotkeys = "Case insensitive"; public string _comment_numpadkeys = "Hotkeys on the numpad require numpadX or keypadX like numpad0 numpad1 Keypad0 Keypad1 case insensitive"; public string _comment_supportedKeys = "Modifiers: ctrl, shift, alt, cmd, windows; Enter/Return, Esc, Space; Numbers: 0-9 (Alpha), Numpad: numpad0-9/keypad0-9; F1-F12; Arrows: up, down, left, right; Special: ., ,, /, \\, ;, ', [, ], -, =, `"; public bool requireShiftModifier = false; public string itemSelectorToggleKey = "I"; public string toggleArrowsKey = "F1"; public string toggleLabelsKey = "F2"; public string arrowModeKey = "F3"; public string fullAutomationKey = "F4"; public string hotReloadKey = "F5"; public string spawnItemsKey = "F6"; public string openLuggageKey = "F7"; public string unityCoordsKey = "F8"; public string arrowsNoLoadKey = "F9"; public string triggerCampfireKey = "F10"; public string _comment_requireShiftModifier = "placeholder"; public bool IsShiftRequirementMet() { if (!requireShiftModifier) { return true; } return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); } public KeyCode GetAutomationContinueKey(string keyString) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0016: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse<KeyCode>(keyString, out KeyCode result)) { return result; } return (KeyCode)48; } public KeyCode GetItemSelectorToggleKey() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(itemSelectorToggleKey, (KeyCode)105); } public KeyCode GetFullAutomationKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(fullAutomationKey, (KeyCode)285); } public KeyCode GetArrowModeKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(arrowModeKey, (KeyCode)284); } public KeyCode GetToggleArrowsKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(toggleArrowsKey, (KeyCode)282); } public KeyCode GetToggleLabelsKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(toggleLabelsKey, (KeyCode)283); } public KeyCode GetHotReloadKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(hotReloadKey, (KeyCode)286); } public KeyCode GetSpawnItemsKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(spawnItemsKey, (KeyCode)287); } public KeyCode GetOpenLuggageKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(openLuggageKey, (KeyCode)288); } public KeyCode GetUnityCoordsKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(unityCoordsKey, (KeyCode)289); } public KeyCode GetArrowsNoLoadKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(arrowsNoLoadKey, (KeyCode)290); } public KeyCode GetTriggerCampfireKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return ParseKeyCode(triggerCampfireKey, (KeyCode)291); } public KeyCode ParseKeyCode(string keyString, KeyCode fallback) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(keyString)) { return fallback; } keyString = keyString.Trim().ToLowerInvariant(); int result; if (keyString.Length == 1 && keyString[0] >= '0' && keyString[0] <= '9') { keyString = "Alpha" + keyString; } else if (keyString.StartsWith("numpad") && keyString.Length == 7 && char.IsDigit(keyString[6])) { keyString = "Keypad" + keyString[6]; } else if (keyString.StartsWith("f") && int.TryParse(keyString.Substring(1), out result) && result >= 1 && result <= 12) { keyString = "F" + result; } else { switch (keyString) { case "ctrl": case "control": keyString = "LeftControl"; break; case "shift": keyString = "LeftShift"; break; case "alt": keyString = "LeftAlt"; break; case "cmd": keyString = "LeftCommand"; break; case "windows": keyString = "LeftWindows"; break; case "enter": case "return": keyString = "Return"; break; case "esc": keyString = "Escape"; break; case "space": keyString = "Space"; break; case ".": keyString = "Period"; break; case ",": keyString = "Comma"; break; case "/": keyString = "Slash"; break; case "\\": keyString = "Backslash"; break; case ";": keyString = "Semicolon"; break; case "'": keyString = "Quote"; break; case "[": keyString = "LeftBracket"; break; case "]": keyString = "RightBracket"; break; case "-": keyString = "Minus"; break; case "=": keyString = "Equals"; break; case "`": keyString = "BackQuote"; break; case "up": keyString = "UpArrow"; break; case "down": keyString = "DownArrow"; break; case "left": keyString = "LeftArrow"; break; case "right": keyString = "RightArrow"; break; } } if (Enum.TryParse<KeyCode>(keyString, ignoreCase: true, out KeyCode result2)) { return result2; } return fallback; } } [Serializable] public class AutomationSettings { public ArrowSettings arrows = new ArrowSettings(); public ScreenshotSettings screenshot = new ScreenshotSettings(); public LabelSettings labels = new LabelSettings(); public bool skipLuggage = false; public bool skipCampfire = false; public bool skipScreenshots = false; public bool skipArrowSpawning = false; public string _comment_skipLuggage = "unused"; public string _comment_skipCampfire = "unused"; public string _comment_skipScreenshots = "unused"; public string _comment_skipArrowSpawning = "unused"; } [Serializable] public class ArrowSettings { public ArrowConfigData topArrow = new ArrowConfigData { color = new float[4] { 1f, 0f, 0f, 1f }, scale = new float[3] { 0.5f, 1000f, 0.5f }, hoverHeight = 5f }; public ArrowConfigData bottomArrow = new ArrowConfigData { color = new float[4] { 1f, 1f, 0f, 1f }, scale = new float[3] { 0.3f, 500f, 0.3f }, hoverHeight = 5f }; public float meshDefaultHeight = 2f; public float topArrowYScale = 1000f; public float bottomArrowYScale = 500f; } [Serializable] public class ArrowConfigData { public float[] color = new float[4]; public float[] scale = new float[3]; public float hoverHeight = 5f; public Color GetColor() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) return new Color(color[0], color[1], color[2], color[3]); } public Vector3 GetScale() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector3(scale[0], scale[1], scale[2]); } } [Serializable] public class ScreenshotSettings { public float teleportOffset = 3f; public float flySpeedX = 25f; public float flySpeedY = 25f; public float flySpeedZ = 25f; public float safePositionHeight = 2f; public float groundDetectionDistance = 10f; public Vector3 campfireTeleportOffset = new Vector3(0f, 50f, 5f); public string screenshotTriggerKey = "Alpha0"; public string flyUpKey = "Space"; public bool enableBiomeScreenshotTeleport = false; public Vector3 biomeScreenshotOffset = new Vector3(0f, 100f, 0f); public Vector3 biomeScreenshotFacing = Vector3.forward; public string _comment_enableBiomeScreenshotTeleport = "unused"; } [Serializable] public class LabelSettings { public bool useNiceNames = true; public bool followCamera = true; public bool simplifyMushroomNames = true; public float fontSize = 15f; public float faceDilate = 0.05f; public float outlineWidth = 0.09f; public float[] fontColorArray = new float[4] { 1f, 0.9f, 0.2f, 1f }; public float[] outlineColorArray = new float[4] { 0f, 0f, 0f, 1f }; public float scaleMultiplier = 1f; public float YOffset = 5f; public float stackSpacing = 0.5f; public float zOffset = -2f; public float xOffset = 0f; public float distanceScalingFactor = 0f; public float[] fallbackFontColorArray = new float[4] { 1f, 0.8f, 0.1f, 1f }; [JsonIgnore] public Color fontColor => new Color(fontColorArray[0], fontColorArray[1], fontColorArray[2], fontColorArray[3]); [JsonIgnore] public Color outlineColor => new Color(outlineColorArray[0], outlineColorArray[1], outlineColorArray[2], outlineColorArray[3]); [JsonIgnore] public Color fallbackFontColor => new Color(fallbackFontColorArray[0], fallbackFontColorArray[1], fallbackFontColorArray[2], fallbackFontColorArray[3]); } [Serializable] public class UISettings { public GridSettings grid = new GridSettings(); public ColorSettings colors = new ColorSettings(); public WindowSettings window = new WindowSettings(); public FontSettings fonts = new FontSettings(); public ScrollSettings scroll = new ScrollSettings(); } [Serializable] public class GridSettings { public int columns = 12; public float spacing = 8f; public float cellHeightMultiplier = 1.1f; } [Serializable] public class ColorSettings { public float[] selectedColor = new float[4] { 0.4f, 0.7f, 1f, 0.95f }; public float[] unselectedColor = new float[4] { 0.22f, 0.22f, 0.22f, 0.95f }; public float[] panelBackgroundColor = new float[4] { 0.2f, 0.2f, 0.2f, 0.95f }; [JsonIgnore] public Color SelectedColor => new Color(selectedColor[0], selectedColor[1], selectedColor[2], selectedColor[3]); [JsonIgnore] public Color UnselectedColor => new Color(unselectedColor[0], unselectedColor[1], unselectedColor[2], unselectedColor[3]); [JsonIgnore] public Color PanelBackgroundColor => new Color(panelBackgroundColor[0], panelBackgroundColor[1], panelBackgroundColor[2], panelBackgroundColor[3]); } [Serializable] public class WindowSettings { public float[] windowAnchorMin = new float[2] { 0.1f, 0.1f }; public float[] windowAnchorMax = new float[2] { 0.9f, 0.9f }; public int canvasSortingOrder = 100; public float[] referenceResolution = new float[2] { 1920f, 1080f }; } [Serializable] public class FontSettings { public float fontSizeHeightMultiplier = 0.18f; public int minFontSize = 10; public int maxFontSize = 22; public int dbItemFontSize = 16; public int customItemFontSize = 14; } [Serializable] public class ScrollSettings { public float scrollSensitivity = 25f; public float scrollbarWidth = 20f; } [Serializable] public class CoordsGUISettings { public string _comment_targetGameObjectName = "MUST BE AT ROOT LEVEL, NO RECURSIVE SEARCH YET (do we even need it?)"; public string targetGameObjectName = "MainCamera"; public float updateRate = 10f; public int fontSize = 18; public bool showRotation = true; public bool showVelocity = true; public bool showSpeed = true; public bool showMaxSpeed = true; public float positionToMetersMultiplier = 1.59f; } [Serializable] public class ItemDetectionRule { public string biome = ""; public string itemType = ""; public DetectionCondition detection = new DetectionCondition(); public NameModifier nameModifier = null; public bool normalizeName = true; } [Serializable] public class CustomItemDetectionRule : ItemDetectionRule { public bool selected = false; public string niceName = null; } [Serializable] public class CampfireRule { public string biome = ""; public DetectionCondition detection = new DetectionCondition(); public bool normalizeName = false; } [Serializable] public class DetectionCondition { public string type = ""; public string value = ""; public DetectionCondition[] conditions = new DetectionCondition[0]; } [Serializable] public class NameModifier { public string type = ""; public ModifierRule[] rules = new ModifierRule[0]; } [Serializable] public class ModifierRule { public string pathContains = ""; public string suffix = ""; } public static class ConfigManager { public static ItemsConfig _itemsConfig; public static SettingsConfig _settingsConfig; private static string ItemsConfigPath => Path.Combine(_settingsConfig?.general?.GetConfigDirectory() ?? Path.Combine(Paths.ConfigPath, "ItemFinder"), "ItemConfig.json"); private static string SettingsConfigPath => Path.Combine(_settingsConfig?.general?.GetConfigDirectory() ?? Path.Combine(Paths.ConfigPath, "ItemFinder"), "SettingsConfig.json"); private static void EnsureConfigDirectoryExists() { string path = _settingsConfig?.general?.GetConfigDirectory() ?? Path.Combine(Paths.ConfigPath, "ItemFinder"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } public static void LoadConfigs() { LoadItemsConfig(); LoadSettingsConfig(); } public static void LoadItemsConfig() { try { EnsureConfigDirectoryExists(); if (File.Exists(ItemsConfigPath)) { ConfigMigration.MigrateItemsConfig(ItemsConfigPath); string text = File.ReadAllText(ItemsConfigPath); logs.Log("[ConfigManager] Loading items config from " + ItemsConfigPath); _itemsConfig = JsonConvert.DeserializeObject<ItemsConfig>(text); if (_itemsConfig.customItems == null) { _itemsConfig.customItems = new CustomItemDetectionRule[0]; } if (_itemsConfig.dbItems == null) { _itemsConfig.dbItems = CreateDefaultCustomItemRules(); } if (_itemsConfig.campfireRules == null) { _itemsConfig.campfireRules = CreateDefaultCampfireRules(); } } else { logs.Log("[ConfigManager] ItemsConfig not found, creating default"); _itemsConfig = CreateDefaultItemsConfig(); SaveItemsConfig(); } } catch (Exception ex) { logs.Log("[ConfigManager] Error loading ItemsConfig: " + ex.Message); _itemsConfig = CreateDefaultItemsConfig(); } } public static void LoadSettingsConfig() { try { EnsureConfigDirectoryExists(); if (File.Exists(SettingsConfigPath)) { ConfigMigration.MigrateSettingsConfig(SettingsConfigPath); string text = File.ReadAllText(SettingsConfigPath); logs.Log("[ConfigManager] Loading settings config from " + SettingsConfigPath); _settingsConfig = JsonConvert.DeserializeObject<SettingsConfig>(text); if (_settingsConfig.automation == null) { _settingsConfig.automation = new AutomationSettings(); } if (_settingsConfig.general == null) { _settingsConfig.general = new GeneralSettings(); } if (_settingsConfig.ui == null) { _settingsConfig.ui = new UISettings(); } if (_settingsConfig.coordsGUI == null) { _settingsConfig.coordsGUI = new CoordsGUISettings(); } } else { logs.Log("[ConfigManager] SettingsConfig not found, creating default"); _settingsConfig = CreateDefaultSettingsConfig(); SaveSettingsConfig(); } } catch (Exception ex) { logs.Log("[ConfigManager] Error loading SettingsConfig: " + ex.Message); _settingsConfig = CreateDefaultSettingsConfig(); } } public static void SaveItemsConfig() { EnsureConfigDirectoryExists(); CustomItemDetectionRule[] array = _itemsConfig?.dbItems ?? new CustomItemDetectionRule[0]; ItemDetectionRule[] array2 = new ItemDetectionRule[array.Length]; for (int i = 0; i < array.Length; i++) { CustomItemDetectionRule customItemDetectionRule = array[i]; array2[i] = new ItemDetectionRule { biome = customItemDetectionRule.biome, itemType = customItemDetectionRule.itemType, detection = customItemDetectionRule.detection, nameModifier = customItemDetectionRule.nameModifier, normalizeName = customItemDetectionRule.normalizeName }; } var anon = new { customItems = (_itemsConfig?.customItems ?? new CustomItemDetectionRule[0]), dbItems = array2, campfireRules = (_itemsConfig?.campfireRules ?? new CampfireRule[0]) }; string contents = JsonConvert.SerializeObject((object)anon, (Formatting)1); File.WriteAllText(ItemsConfigPath, contents); } public static void SaveSettingsConfig() { EnsureConfigDirectoryExists(); string contents = JsonConvert.SerializeObject((object)_settingsConfig, (Formatting)1); File.WriteAllText(SettingsConfigPath, contents); } public static void SaveConfigs() { SaveItemsConfig(); SaveSettingsConfig(); } private static ItemsConfig CreateDefaultItemsConfig() { ItemsConfig itemsConfig = new ItemsConfig(); itemsConfig.customItems = CreateDefaultCustomItemRules(); itemsConfig.dbItems = new CustomItemDetectionRule[0]; itemsConfig.campfireRules = CreateDefaultCampfireRules(); return itemsConfig; } private static SettingsConfig CreateDefaultSettingsConfig() { return new SettingsConfig { automation = new AutomationSettings(), general = new GeneralSettings(), ui = new UISettings(), coordsGUI = new CoordsGUISettings() }; } public static CustomItemDetectionRule[] CreateDefaultCustomItemRules() { return new CustomItemDetectionRule[11] { new CustomItemDetectionRule { biome = "MESA", itemType = "MirageLuggageSmall", detection = new DetectionCondition { type = "pathContains", value = "LuggageSpawner_Mirrage/MirageLuggage" }, selected = false, niceName = "Mirage Small" }, new CustomItemDetectionRule { biome = "MESA", itemType = "MirageLuggageBig", detection = new DetectionCondition { type = "pathContains", value = "LuggageSpawner_Mirrage/MirageLuggageBig" }, selected = false, niceName = "Mirage Big" }, new CustomItemDetectionRule { biome = "MESA", itemType = "MirageLuggageEpic", detection = new DetectionCondition { type = "pathContains", value = "LuggageSpawner_Mirrage/MirageLuggageEpic" }, selected = false, niceName = "Mirage Epic" }, new CustomItemDetectionRule { biome = "MESA", itemType = "MirageLuggageAncient", detection = new DetectionCondition { type = "pathContains", value = "LuggageSpawner_Mirrage/MirageLuggageAncient" }, selected = false, niceName = "Mirage Ancient" }, new CustomItemDetectionRule { biome = "ANY", itemType = "LuggageSmall", detection = new DetectionCondition { type = "exactName", value = "LuggageSmall" }, selected = false, niceName = "Small Luggage" }, new CustomItemDetectionRule { biome = "ANY", itemType = "LuggageBig", detection = new DetectionCondition { type = "exactName", value = "LuggageBig" }, selected = false, niceName = "Big Luggage" }, new CustomItemDetectionRule { biome = "ANY", itemType = "LuggageEpic", detection = new DetectionCondition { type = "exactName", value = "LuggageEpic" }, selected = false, niceName = "Epic Luggage" }, new CustomItemDetectionRule { biome = "ANY", itemType = "LuggageAncient", detection = new DetectionCondition { type = "exactName", value = "LuggageAncient" }, selected = false, niceName = "Ancient Luggage" }, new CustomItemDetectionRule { biome = "MESA", itemType = "Antlion", detection = new DetectionCondition { type = "exactName", value = "AntLion" }, selected = false, niceName = "Antlion" }, new CustomItemDetectionRule { biome = "ANY", itemType = "CapybaraOnsen", detection = new DetectionCondition { type = "pathEndsWith", value = "Capybara/Onsen" }, selected = false, niceName = "Capybara Hot Spring" }, new CustomItemDetectionRule { biome = "CALDERA", itemType = "Eggs", detection = new DetectionCondition { type = "exactName", value = "EggNest" }, selected = false, niceName = "null" } }; } public static CampfireRule[] CreateDefaultCampfireRules() { return new CampfireRule[5] { new CampfireRule { biome = "SHORE", detection = new DetectionCondition { type = "exactPath", value = "Map/Biome_1/Beach/Beach_Campfire/Campfire/Campfire" } }, new CampfireRule { biome = "TROPICS", detection = new DetectionCondition { type = "exactPath", value = "Map/Biome_2/Jungle/Jungle_Campfire/Campfire/Campfire" } }, new CampfireRule { biome = "ALPINE", detection = new DetectionCondition { type = "exactPath", value = "Map/Biome_3/Snow/Snow_Campfire/Campfire/Campfire" } }, new CampfireRule { biome = "MESA", detection = new DetectionCondition { type = "pathContains", value = "Map/Biome_3/Desert" } }, new CampfireRule { biome = "CALDERA", detection = new DetectionCondition { type = "pathContains", value = "Map/Biome_4/Volcano/Volcano_Campfire" } } }; } public static bool MatchesDetection(GameObject obj, ItemDetectionRule rule) { if ((Object)(object)obj == (Object)null || rule == null || rule.detection == null) { return false; } string text = ((Object)obj).name; string text2 = rule.detection.value; if (rule.normalizeName) { text = NormalizeName(text); text2 = NormalizeName(text2); } string fullPath = GetFullPath(obj); switch (rule.detection.type) { case "exactName": return text == text2; case "pathEndsWith": return fullPath.EndsWith(text2); case "pathContains": return fullPath.Contains(text2); case "exactPath": return fullPath == text2; case "complex": { if (rule.detection.conditions == null || rule.detection.conditions.Length == 0) { return false; } DetectionCondition[] conditions = rule.detection.conditions; foreach (DetectionCondition detection in conditions) { ItemDetectionRule rule2 = new ItemDetectionRule { detection = detection, normalizeName = rule.normalizeName }; if (!MatchesDetection(obj, rule2)) { return false; } } return true; } default: return false; } } public static bool MatchesDetection(GameObject obj, CampfireRule rule) { if ((Object)(object)obj == (Object)null || rule == null || rule.detection == null) { return false; } string text = ((Object)obj).name; string text2 = rule.detection.value; if (rule.normalizeName) { text = NormalizeName(text); text2 = NormalizeName(text2); } string fullPath = GetFullPath(obj); return rule.detection.type switch { "exactName" => text == text2, "pathEndsWith" => fullPath.EndsWith(text2), "pathContains" => fullPath.Contains(text2), "exactPath" => fullPath == text2, _ => false, }; } public static string NormalizeName(string name) { if (string.IsNullOrEmpty(name)) { return ""; } name = name.Trim(); int num = name.IndexOf('('); if (num >= 0) { name = name.Substring(0, num); } return name.Trim(); } private static string GetFullPath(GameObject obj) { if ((Object)(object)obj == (Object)null) { return ""; } return ((Object)(object)obj.transform == (Object)null) ? ((Object)obj).name : obj.transform.GetHierarchyPath(); } } public static class TransformExtensions { public static string GetHierarchyPath(this Transform current) { if ((Object)(object)current.parent == (Object)null) { return ((Object)current).name; } return current.parent.GetHierarchyPath() + "/" + ((Object)current).name; } } public static class ConfigMigration { public static void MigrateSettingsConfig(string path) { if (!File.Exists(path)) { return; } try { string text = File.ReadAllText(path); JObject val = JObject.Parse(text); SettingsConfig settingsConfig = new SettingsConfig { automation = new AutomationSettings(), general = new GeneralSettings(), ui = new UISettings(), coordsGUI = new CoordsGUISettings() }; JObject defaults = JObject.FromObject((object)settingsConfig); if (DeepMerge(val, defaults)) { File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>())); logs.Log("[ConfigMigration] SettingsConfig updated with missing fields"); } else { logs.Log("[ConfigMigration] SettingsConfig is up to date"); } } catch (Exception ex) { logs.Log("[ConfigMigration] Error migrating SettingsConfig: " + ex.Message); } } public static void MigrateItemsConfig(string path) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (!File.Exists(path)) { return; } try { string text = File.ReadAllText(path); JObject val = JObject.Parse(text); bool flag = false; if (val["customItems"] == null) { val["customItems"] = (JToken)new JArray(); logs.Log("[ConfigMigration] Added customItems array"); flag = true; } if (val["dbItems"] == null) { val["dbItems"] = (JToken)new JArray(); logs.Log("[ConfigMigration] Added dbItems array"); flag = true; } if (val["campfireRules"] == null) { val["campfireRules"] = (JToken)new JArray(); logs.Log("[ConfigMigration] Added campfireRules array"); flag = true; } CustomItemDetectionRule[] array = ConfigManager.CreateDefaultCustomItemRules(); CampfireRule[] array2 = ConfigManager.CreateDefaultCampfireRules(); JToken obj = val["customItems"]; JArray val2 = (JArray)(object)((obj is JArray) ? obj : null); if (val2 != null) { HashSet<string> hashSet = new HashSet<string>(); foreach (JToken item in val2) { JToken obj2 = item[(object)"itemType"]; string text2 = ((obj2 != null) ? Extensions.Value<string>((IEnumerable<JToken>)obj2) : null); if (!string.IsNullOrEmpty(text2)) { hashSet.Add(text2); } } int num = 0; CustomItemDetectionRule[] array3 = array; foreach (CustomItemDetectionRule customItemDetectionRule in array3) { if (!hashSet.Contains(customItemDetectionRule.itemType)) { val2.Add((JToken)(object)JObject.FromObject((object)customItemDetectionRule)); logs.Log("[ConfigMigration] Added missing item: " + customItemDetectionRule.itemType); num++; flag = true; } } if (num > 0) { logs.Log($"[ConfigMigration] Added {num} missing custom items"); } } JToken obj3 = val["campfireRules"]; JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val3 != null) { HashSet<string> hashSet2 = new HashSet<string>(); foreach (JToken item2 in val3) { JToken obj4 = item2[(object)"biome"]; string text3 = ((obj4 != null) ? Extensions.Value<string>((IEnumerable<JToken>)obj4) : null); if (!string.IsNullOrEmpty(text3)) { hashSet2.Add(text3); } } int num2 = 0; CampfireRule[] array4 = array2; foreach (CampfireRule campfireRule in array4) { if (!hashSet2.Contains(campfireRule.biome)) { val3.Add((JToken)(object)JObject.FromObject((object)campfireRule)); logs.Log("[ConfigMigration] Added missing campfire rule for: " + campfireRule.biome); num2++; flag = true; } } if (num2 > 0) { logs.Log($"[ConfigMigration] Added {num2} missing campfire rules"); } } if (flag) { File.WriteAllText(path, ((JToken)val).ToString((Formatting)1, Array.Empty<JsonConverter>())); logs.Log("[ConfigMigration] ItemsConfig updated with missing fields"); } else { logs.Log("[ConfigMigration] ItemsConfig is up to date"); } } catch (Exception ex) { logs.Log("[ConfigMigration] Error migrating ItemsConfig: " + ex.Message); } } private static bool DeepMerge(JObject existing, JObject defaults) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00ad: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Invalid comparison between Unknown and I4 bool result = false; foreach (JProperty item in defaults.Properties()) { string name = item.Name; if (name.StartsWith("_comment")) { continue; } JToken val = existing[name]; JToken value = item.Value; if (val == null) { existing[name] = value.DeepClone(); logs.Log("[ConfigMigration] Added missing field: " + name); result = true; } else if ((int)val.Type == 1 && (int)value.Type == 1) { if (DeepMerge((JObject)val, (JObject)value)) { result = true; } } else if ((int)val.Type == 2 && (int)value.Type != 2) { } } return result; } } public static class IconLoader { private static readonly Dictionary<string, Texture2D> _cache = new Dictionary<string, Texture2D>(); private static bool _initialized = false; public static void Initialize() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (_initialized) { return; } string iconsFolder = GetIconsFolder(); if (!Directory.Exists(iconsFolder)) { Debug.LogWarning((object)("[IconLoader] Icons folder not found: " + iconsFolder)); _initialized = true; return; } string[] files = Directory.GetFiles(iconsFolder, "*.png"); foreach (string text in files) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); try { byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); if (ImageConversion.LoadImage(val, array)) { _cache[fileNameWithoutExtension] = val; } else { Debug.LogError((object)("[IconLoader] Failed to load image: " + text)); } } catch (Exception arg) { Debug.LogError((object)$"[IconLoader] Exception loading icon '{fileNameWithoutExtension}': {arg}"); } } _initialized = true; Debug.Log((object)$"[IconLoader] Loaded {_cache.Count} icons from {iconsFolder}"); } public static Texture2D GetIcon(string iconName) { if (!_initialized) { Initialize(); } if (string.IsNullOrEmpty(iconName)) { return null; } if (_cache.TryGetValue(iconName, out var value)) { return value; } _cache.TryGetValue("Missing", out value); return value; } private static string GetIconsFolder() { string path = Path.Combine(Paths.PluginPath, "ItemFinder"); return Path.Combine(path, "Icons"); } } public class ItemFinder : MonoBehaviour { public struct ItemData { public string itemType; public string biome; public Vector3 position; public string fullPath; public string objectName; public Campfire campfireRef; public string displayName; } [CompilerGenerated] private sealed class <>c__DisplayClass21_0 { public string originalBiome; internal bool <ArrowOnlyCoroutine>b__1() { return BiomeDetector.CurrentBiome != originalBiome; } } [CompilerGenerated] private sealed class <ArrowOnlyCoroutine>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder <>4__this; private <>c__DisplayClass21_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ArrowOnlyCoroutine>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; logs.ClearLog(); logs.Log("Arrow-only mode started. Waiting for level to be ready..."); <>2__current = <>4__this.WaitForLevelReady(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => BiomeDetector.CurrentBiome != "Unknown")); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.CurrentBiome = BiomeDetector.CurrentBiome; break; case 3: <>1__state = -1; <>4__this.CurrentBiome = BiomeDetector.CurrentBiome; logs.Log("Biome changed to: " + <>4__this.CurrentBiome); <>4__this.CurrentBiomeItems.Clear(); <>4__this.ArrowManager.ClearAll(); <>8__1 = null; break; } <>8__1 = new <>c__DisplayClass21_0(); logs.Log("Starting item detection cycle in biome: " + <>4__this.CurrentBiome); <>4__this.FindAllItemsForCurrentBiome(); <>4__this.EnsureArrowManager(); <>4__this.ArrowManager.SpawnForItems(<>4__this.CurrentBiomeItems); logs.Log($"Arrows spawned for {<>4__this.CurrentBiomeItems.Count} items. Waiting for biome change..."); <>8__1.originalBiome = <>4__this.CurrentBiome; <>2__current = (object)new WaitUntil((Func<bool>)(() => BiomeDetector.CurrentBiome != <>8__1.originalBiome)); <>1__state = 3; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <FullAutomationCoroutine>d__26 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder <>4__this; private SettingsConfig <config>5__1; private AutomationSettings <automation>5__2; private List<ItemData> <nonCampfireItems>5__3; private List<ItemData> <campfireItems>5__4; private ItemData <currentBiomeCampfire>5__5; private string <originalBiome>5__6; private float <timeout>5__7; private float <elapsed>5__8; private ScreenshotSettings <ssConfig>5__9; private Vector3 <offset>5__10; private Vector3 <facing>5__11; private Character <local>5__12; private Vector3 <teleportPos>5__13; private Vector3 <targetPos>5__14; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FullAutomationCoroutine>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <config>5__1 = null; <automation>5__2 = null; <nonCampfireItems>5__3 = null; <campfireItems>5__4 = null; <currentBiomeCampfire>5__5 = default(ItemData); <originalBiome>5__6 = null; <ssConfig>5__9 = null; <local>5__12 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) AutomationSettings automationSettings2; AutomationSettings automationSettings3; AutomationSettings automationSettings4; switch (<>1__state) { default: return false; case 0: <>1__state = -1; logs.ClearLog(); logs.Log("Full automation started. Waiting for level to be ready..."); <>2__current = <>4__this.WaitForLevelReady(); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => BiomeDetector.CurrentBiome != "Unknown")); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.CurrentBiome = BiomeDetector.CurrentBiome; <config>5__1 = ConfigManager._settingsConfig; <automation>5__2 = <config>5__1?.automation; goto IL_062a; case 3: <>1__state = -1; goto IL_0187; case 4: <>1__state = -1; goto IL_02c4; case 5: <>1__state = -1; logs.Log("Triggering campfire..."); <>2__current = Screenshotter.TriggerCampfireCoroutine(<>4__this, <currentBiomeCampfire>5__5); <>1__state = 6; return true; case 6: <>1__state = -1; if ((<automation>5__2?.screenshot?.enableBiomeScreenshotTeleport).GetValueOrDefault()) { <ssConfig>5__9 = <automation>5__2.screenshot; <offset>5__10 = <ssConfig>5__9.biomeScreenshotOffset; <facing>5__11 = <ssConfig>5__9.biomeScreenshotFacing; logs.Log($"Teleporting for biome screenshot with offset: {<offset>5__10} and facing: {<facing>5__11}"); <local>5__12 = Character.localCharacter; if ((Object)(object)<local>5__12 != (Object)null && !<local>5__12.data.dead) { <teleportPos>5__13 = <currentBiomeCampfire>5__5.position + <offset>5__10; ((MonoBehaviourPun)<local>5__12).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { <teleportPos>5__13, true }); <targetPos>5__14 = <currentBiomeCampfire>5__5.position + <facing>5__11; Screenshotter.FaceTarget(<local>5__12, <targetPos>5__14); } <ssConfig>5__9 = null; <local>5__12 = null; } <originalBiome>5__6 = <>4__this.CurrentBiome; <timeout>5__7 = <config>5__1.general.biomeChangeTimeout; <elapsed>5__8 = 0f; goto IL_054b; case 7: { <>1__state = -1; goto IL_054b; } IL_02c4: <currentBiomeCampfire>5__5 = <campfireItems>5__4.Find((ItemData c) => c.biome == <>4__this.CurrentBiome); if ((Object)(object)<currentBiomeCampfire>5__5.campfireRef != (Object)null) { AutomationSettings automationSettings = <automation>5__2; if (automationSettings == null || !automationSettings.skipCampfire) { logs.Log("Teleporting to campfire..."); <>2__current = Screenshotter.TeleportToCampfireCoroutine(<>4__this, <currentBiomeCampfire>5__5); <>1__state = 5; return true; } logs.Log("Skipping campfire handling due to skip flag."); goto IL_05dc; } logs.Log("No campfire found for current biome: " + <>4__this.CurrentBiome + ". Cannot progress to next biome."); logs.Log("Automation completed or stopped."); return false; IL_05dc: <>4__this.CurrentBiomeItems.Clear(); <>4__this.itemTypeCounter.Clear(); <>4__this.ArrowManager.ClearAll(); <nonCampfireItems>5__3 = null; <campfireItems>5__4 = null; <currentBiomeCampfire>5__5 = default(ItemData); goto IL_062a; IL_062a: logs.Log("Starting full automation cycle in biome: " + <>4__this.CurrentBiome); automationSettings2 = <automation>5__2; if (automationSettings2 == null || !automationSettings2.skipLuggage) { if (<config>5__1.general.OpenLuggageAutomatically) { <>2__current = <>4__this.OpenLuggageAndWaitForItems(); <>1__state = 3; return true; } logs.Log("Skipping luggage opening due to config."); } else { logs.Log("Skipping luggage opening due to skip flag."); } goto IL_0187; IL_0187: <>4__this.FindAllItemsForCurrentBiome(); <>4__this.EnsureArrowManager(); <>4__this.ArrowManager.SpawnForItems(<>4__this.CurrentBiomeItems); logs.Log($"Spawned arrows for {<>4__this.CurrentBiomeItems.Count} items."); <nonCampfireItems>5__3 = <>4__this.CurrentBiomeItems.FindAll((ItemData item) => item.itemType != "Campfire"); <campfireItems>5__4 = <>4__this.CurrentBiomeItems.FindAll((ItemData item) => item.itemType == "Campfire"); automationSettings3 = <automation>5__2; if ((automationSettings3 == null || !automationSettings3.skipScreenshots) && <nonCampfireItems>5__3.Count > 0) { <>2__current = Screenshotter.ScreenshotItemCoroutine(<>4__this, <>4__this.itemTypeCounter); <>1__state = 4; return true; } automationSettings4 = <automation>5__2; if (automationSettings4 != null && automationSettings4.skipScreenshots) { logs.Log("Skipping screenshots due to skip flag."); } goto IL_02c4; IL_054b: if (BiomeDetector.CurrentBiome == <originalBiome>5__6 && <elapsed>5__8 < <timeout>5__7) { <elapsed>5__8 += Time.deltaTime; <>2__current = null; <>1__state = 7; return true; } <>4__this.CurrentBiome = BiomeDetector.CurrentBiome; logs.Log("Biome changed to: " + <>4__this.CurrentBiome); <originalBiome>5__6 = null; goto IL_05dc; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OpenAllLuggageCoroutine>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder <>4__this; private List<Luggage> <luggageToOpen>5__1; private int <itemCountBefore>5__2; private float <timeout>5__3; private float <elapsed>5__4; private int <stableCount>5__5; private int <lastItemCount>5__6; private List<Luggage>.Enumerator <>s__7; private Luggage <lug>5__8; private Exception <ex>5__9; private int <stillClosed>5__10; private int <i>5__11; private int <currentItemCount>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OpenAllLuggageCoroutine>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <luggageToOpen>5__1 = null; <>s__7 = default(List<Luggage>.Enumerator); <lug>5__8 = null; <ex>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Expected O, but got Unknown //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; logs.Log("[ItemFinder] OpenAllLuggageCoroutine started"); <>4__this.CurrentBiome = BiomeDetector.CurrentBiome; logs.Log("[ItemFinder] Current biome: " + <>4__this.CurrentBiome); if (!ConfigManager._settingsConfig.general.OpenLuggageAutomatically) { logs.Log("[ItemFinder] OpenLuggageAutomatically is disabled in config"); return false; } <luggageToOpen>5__1 = (from l in Luggage.ALL_LUGGAGE.ToList() where (Object)(object)l != (Object)null && ((Component)l).gameObject.activeInHierarchy && l.IsInteractible((Character)null) select l).ToList(); if (<luggageToOpen>5__1.Count == 0) { logs.Log("[ItemFinder] No interactible luggage found to open"); return false; } logs.Log($"[ItemFinder] Found {<luggageToOpen>5__1.Count} luggage items to open"); <itemCountBefore>5__2 = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0).Length; logs.Log($"[ItemFinder] Object count before opening: {<itemCountBefore>5__2}"); <>s__7 = <luggageToOpen>5__1.GetEnumerator(); try { while (<>s__7.MoveNext()) { <lug>5__8 = <>s__7.Current; try { if ((Object)(object)<lug>5__8 != (Object)null && ((Component)<lug>5__8).gameObject.activeInHierarchy) { ((MonoBehaviourPun)<lug>5__8).photonView.RPC("OpenLuggageRPC", (RpcTarget)0, new object[1] { true }); logs.Log("[ItemFinder] Opened: " + ((Object)((Component)<lug>5__8).gameObject).name); } } catch (Exception ex) { <ex>5__9 = ex; Luggage obj = <lug>5__8; object obj2; if (obj == null) { obj2 = null; } else { GameObject gameObject = ((Component)obj).gameObject; obj2 = ((gameObject != null) ? ((Object)gameObject).name : null); } if (obj2 == null) { obj2 = "null"; } logs.Log("[ItemFinder] Failed to open " + (string?)obj2 + ": " + <ex>5__9.Message); } <lug>5__8 = null; } } finally { ((IDisposable)<>s__7).Dispose(); } <>s__7 = default(List<Luggage>.Enumerator); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; <timeout>5__3 = 5f; <elapsed>5__4 = 0f; goto IL_031b; case 2: <>1__state = -1; goto IL_031b; case 3: { <>1__state = -1; <currentItemCount>5__12 = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0).Length; if (<currentItemCount>5__12 == <lastItemCount>5__6) { <stableCount>5__5++; if (<stableCount>5__5 >= 20) { logs.Log($"[ItemFinder] Item spawning stabilized. Objects: {<itemCountBefore>5__2} -> {<currentItemCount>5__12}"); break; } } else { <stableCount>5__5 = 0; <lastItemCount>5__6 = <currentItemCount>5__12; } <i>5__11++; goto IL_041a; } IL_041a: if (<i>5__11 < 100) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } break; IL_031b: if (<elapsed>5__4 < <timeout>5__3) { <stillClosed>5__10 = (from l in Luggage.ALL_LUGGAGE.ToList() where (Object)(object)l != (Object)null && ((Component)l).gameObject.activeInHierarchy && l.IsInteractible((Character)null) select l).Count(); if (<stillClosed>5__10 != 0) { <elapsed>5__4 += Time.deltaTime; <>2__current = null; <>1__state = 2; return true; } logs.Log("[ItemFinder] All luggage opened successfully"); } logs.Log("[ItemFinder] Waiting for items to spawn..."); <stableCount>5__5 = 0; <lastItemCount>5__6 = <itemCountBefore>5__2; <i>5__11 = 0; goto IL_041a; } logs.Log("[ItemFinder] Luggage opening complete."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OpenLuggageAndWaitForItems>d__23 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder <>4__this; private int <initialItemCount>5__1; private List<Luggage> <luggageToOpen>5__2; private float <timeout>5__3; private float <elapsed>5__4; private int <stableCount>5__5; private int <lastItemCount>5__6; private List<Luggage>.Enumerator <>s__7; private Luggage <lug>5__8; private Exception <ex>5__9; private int <stillClosed>5__10; private int <i>5__11; private int <currentItemCount>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OpenLuggageAndWaitForItems>d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <luggageToOpen>5__2 = null; <>s__7 = default(List<Luggage>.Enumerator); <lug>5__8 = null; <ex>5__9 = null; <>1__state = -2; } private bool MoveNext() { //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!ConfigManager._settingsConfig.general.OpenLuggageAutomatically) { logs.Log("Skipping luggage opening due to config."); return false; } logs.Log("Opening all luggage and waiting for item spawn completion..."); <initialItemCount>5__1 = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0).Length; <luggageToOpen>5__2 = (from l in Luggage.ALL_LUGGAGE.ToList() where (Object)(object)l != (Object)null && ((Component)l).gameObject.activeInHierarchy && l.IsInteractible((Character)null) select l).ToList(); logs.Log($"Found {<luggageToOpen>5__2.Count} luggage items to open"); <>s__7 = <luggageToOpen>5__2.GetEnumerator(); try { while (<>s__7.MoveNext()) { <lug>5__8 = <>s__7.Current; try { if (((Component)<lug>5__8).gameObject.activeInHierarchy) { ((MonoBehaviourPun)<lug>5__8).photonView.RPC("OpenLuggageRPC", (RpcTarget)0, new object[1] { true }); logs.Log("Opened luggage: " + ((Object)((Component)<lug>5__8).gameObject).name); } else { logs.Log("Skipped inactive luggage: " + ((Object)((Component)<lug>5__8).gameObject).name); } } catch (Exception ex) { <ex>5__9 = ex; logs.Log("Failed to open luggage " + ((Object)((Component)<lug>5__8).gameObject).name + ": " + <ex>5__9.Message); } <lug>5__8 = null; } } finally { ((IDisposable)<>s__7).Dispose(); } <>s__7 = default(List<Luggage>.Enumerator); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; <timeout>5__3 = 10f; <elapsed>5__4 = 0f; goto IL_029e; case 2: <>1__state = -1; goto IL_029e; case 3: { <>1__state = -1; <currentItemCount>5__12 = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0).Length; if (<currentItemCount>5__12 == <lastItemCount>5__6) { <stableCount>5__5++; if (<stableCount>5__5 >= 20) { logs.Log($"Item spawning stabilized at {<currentItemCount>5__12} objects (was {<initialItemCount>5__1})"); break; } } else { <stableCount>5__5 = 0; <lastItemCount>5__6 = <currentItemCount>5__12; } <i>5__11++; goto IL_039d; } IL_039d: if (<i>5__11 < 100) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } break; IL_029e: if (<elapsed>5__4 < <timeout>5__3) { <stillClosed>5__10 = (from l in Luggage.ALL_LUGGAGE.ToList() where (Object)(object)l != (Object)null && ((Component)l).gameObject.activeInHierarchy && l.IsInteractible((Character)null) select l).Count(); if (<stillClosed>5__10 != 0) { <elapsed>5__4 += Time.deltaTime; <>2__current = null; <>1__state = 2; return true; } } logs.Log("All accessible luggage opened. Waiting for item spawning to complete..."); <stableCount>5__5 = 0; <lastItemCount>5__6 = <initialItemCount>5__1; <i>5__11 = 0; goto IL_039d; } logs.Log("Luggage opening and item spawning complete."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForLevelReady>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder <>4__this; private int <activeLuggage>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForLevelReady>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; logs.Log("Waiting for level to be fully ready..."); <>2__current = (object)new WaitUntil((Func<bool>)(() => logs.LevelReady)); <>1__state = 1; return true; case 1: <>1__state = -1; logs.Log("Basic level ready flag detected."); logs.Log("Waiting 2 seconds for GameObjects to settle..."); <>2__current = (object)new WaitForSeconds(2f); <>1__state = 2; return true; case 2: <>1__state = -1; logs.Log("2 second wait complete."); <>2__current = (object)new WaitUntil((Func<bool>)(() => Luggage.ALL_LUGGAGE.Count > 0)); <>1__state = 3; return true; case 3: <>1__state = -1; <activeLuggage>5__1 = Luggage.ALL_LUGGAGE.Where((Luggage l) => (Object)(object)l != (Object)null && ((Component)l).gameObject.activeInHierarchy).Count(); logs.Log($"Level ready - Found {<activeLuggage>5__1} active luggage out of {Luggage.ALL_LUGGAGE.Count} total."); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public string OutputDirectory; public string SessionTimestamp; public List<ItemData> CurrentBiomeItems = new List<ItemData>(); public string CurrentBiome = "Unknown"; private Dictionary<string, int> itemTypeCounter = new Dictionary<string, int>(); private HashSet<string> customItems = new HashSet<string>(); private HashSet<string> selectedCustomItems = new HashSet<string>(); private static GameObject[] _cachedObjects; private static string _lastScannedBiome; private static Dictionary<int, string> _pathCache = new Dictionary<int, string>(); public ArrowLabelManager ArrowManager { get; private set; } private void Awake() { Debug.Log((object)("[ItemFinder] Awake called on GameObject: " + ((Object)((Component)this).gameObject).name)); BiomeDetector.Initialize(); OutputDirectory = ConfigManager._settingsConfig?.general?.GetOutputDirectory(); SessionTimestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); ConfigManager.LoadConfigs(); RefreshCustomItemsFromConfig(); BiomeDetector.DetectInitialBiome(); CurrentBiome = BiomeDetector.CurrentBiome; logs.Log("[ItemFinder] Initialized with biome: " + CurrentBiome); ArrowLabelManager component = ((Component)this).gameObject.GetComponent<ArrowLabelManager>(); if ((Object)(object)component != (Object)null) { ArrowManager = component; } } public void EnsureArrowManager() { if ((Object)(object)ArrowManager == (Object)null) { ArrowLabelManager arrowLabelManager = ((Component)this).gameObject.GetComponent<ArrowLabelManager>(); if ((Object)(object)arrowLabelManager == (Object)null) { arrowLabelManager = ((Component)this).gameObject.AddComponent<ArrowLabelManager>(); Debug.Log((object)"[ItemFinder] Added ArrowLabelManager component at runtime."); } ArrowManager = arrowLabelManager; Debug.Log((object)$"[ItemFinder] EnsureArrowManager on ItemFinder '{((Object)((Component)this).gameObject).name}' (ItemFinder id {((Object)this).GetInstanceID()}) - existing ALM: {arrowLabelManager}"); } } private string GetFullPath(GameObject obj) { int instanceID = ((Object)obj).GetInstanceID(); if (_pathCache.TryGetValue(instanceID, out var value)) { return value; } string text = ((Object)obj).name; Transform val = obj.transform; while ((Object)(object)val.parent != (Object)null) { val = val.parent; text = ((Object)val).name + "/" + text; } _pathCache[instanceID] = text; return text; } private string NormalizeName(string name) { if (string.IsNullOrEmpty(name)) { return ""; } name = name.Trim(); int num = name.IndexOf('('); if (num >= 0) { name = name.Substring(0, num); } return name.Trim(); } private void SaveItemsToFile() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) try { if (string.IsNullOrEmpty(OutputDirectory) || string.IsNullOrEmpty(SessionTimestamp)) { logs.Log("Cannot save items - missing directory or timestamp"); return; } string text = "items_" + CurrentBiome + "_" + SessionTimestamp + ".txt"; string path = Path.Combine(OutputDirectory, text); using (StreamWriter streamWriter = new StreamWriter(path)) { streamWriter.WriteLine("Biome: " + CurrentBiome); streamWriter.WriteLine("Timestamp: " + SessionTimestamp); streamWriter.WriteLine($"Total Items Found: {CurrentBiomeItems.Count}"); streamWriter.WriteLine("----------------------------------------"); foreach (ItemData currentBiomeItem in CurrentBiomeItems) { streamWriter.WriteLine("Item: " + currentBiomeItem.itemType); streamWriter.WriteLine($"Position: {currentBiomeItem.position}"); streamWriter.WriteLine("Object Name: " + currentBiomeItem.objectName); streamWriter.WriteLine("Full Path: " + currentBiomeItem.fullPath); streamWriter.WriteLine("---"); } } logs.Log($"Saved {CurrentBiomeItems.Count} items to {text}"); } catch (Exception ex) { logs.Log("Error saving items to file: " + ex.Message); } } public void RunArrowOnlyMode() { ((MonoBehaviour)this).StartCoroutine(ArrowOnlyCoroutine()); } [IteratorStateMachine(typeof(<ArrowOnlyCoroutine>d__21))] private IEnumerator ArrowOnlyCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ArrowOnlyCoroutine>d__21(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<WaitForLevelReady>d__22))] private IEnumerator WaitForLevelReady() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForLevelReady>d__22(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<OpenLuggageAndWaitForItems>d__23))] private IEnumerator OpenLuggageAndWaitForItems() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OpenLuggageAndWaitForItems>d__23(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<OpenAllLuggageCoroutine>d__24))] public IEnumerator OpenAllLuggageCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OpenAllLuggageCoroutine>d__24(0) { <>4__this = this }; } public void RunFullAutomation() { ((MonoBehaviour)this).StartCoroutine(FullAutomationCoroutine()); } [IteratorStateMachine(typeof(<FullAutomationCoroutine>d__26))] private IEnumerator FullAutomationCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FullAutomationCoroutine>d__26(0) { <>4__this = this }; } private void RefreshCustomItemsFromConfig() { customItems.Clear(); selectedCustomItems.Clear(); CustomItemDetectionRule[] array = ConfigManager._itemsConfig?.customItems ?? Array.Empty<CustomItemDetectionRule>(); foreach (CustomItemDetectionRule customItemDetectionRule in array) { string item = ConfigManager.NormalizeName(customItemDetectionRule.itemType); customItems.Add(item); if (customItemDetectionRule.selected) { selectedCustomItems.Add(item); } } Debug.Log((object)$"[ItemFinder] Refreshed custom items: {customItems.Count} total, {selectedCustomItems.Count} selected"); } private GameObject GetItemObject(GameObject obj) { if ((Object)(object)obj == (Object)null) { return null; } if (obj.transform.childCount > 0) { for (int i = 0; i < obj.transform.childCount; i++) { GameObject gameObject = ((Component)obj.transform.GetChild(i)).gameObject; if (ConfigManager.NormalizeName(((Object)obj).name) == ConfigManager.NormalizeName(((Object)gameObject).name)) { return gameObject; } } } return obj; } public void FindAllItemsForCurrentBiome() { //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_077e: Unknown result type (might be due to invalid IL or missing references) //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_07ce: Unknown result type (might be due to invalid IL or missing references) //IL_08ae: Unknown result type (might be due to invalid IL or missing references) //IL_08b3: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: Unknown result type (might be due to invalid IL or missing references) logs.Log("=== DEBUG: Starting FindAllItemsForCurrentBiome ==="); logs.Log($"ConfigManager._itemsConfig is null: {ConfigManager._itemsConfig == null}"); if (ConfigManager._itemsConfig != null) { logs.Log($"dbItems is null: {ConfigManager._itemsConfig.dbItems == null}"); logs.Log($"customItems is null: {ConfigManager._itemsConfig.customItems == null}"); logs.Log($"campfireRules is null: {ConfigManager._itemsConfig.campfireRules == null}"); } logs.Log($"ItemNameManager.Instance is null: {ItemNameManager.Instance == null}"); logs.Log("OutputDirectory: " + OutputDirectory); logs.Log("CurrentBiome: " + CurrentBiome); if (!Directory.Exists(OutputDirectory)) { logs.Log("Creating output directory..."); Directory.CreateDirectory(OutputDirectory); } CurrentBiomeItems.Clear(); logs.Log("DEBUG: CurrentBiomeItems cleared"); bool flag = _cachedObjects != null && _cachedObjects.Any((GameObject obj) => (Object)(object)obj == (Object)null); if (_lastScannedBiome != CurrentBiome || _cachedObjects == null || flag) { if (flag) { logs.Log("DEBUG: Cache contains destroyed objects, rescanning..."); } else { logs.Log("DEBUG: About to scan for objects..."); } _cachedObjects = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0); GameObject[] cachedObjects = _cachedObjects; logs.Log($"DEBUG: Found {((cachedObjects != null) ? cachedObjects.Length : 0)} objects"); _pathCache.Clear(); _lastScannedBiome = CurrentBiome; logs.Log("DEBUG: About to filter luggage..."); try { List<GameObject> list = _cachedObjects.Where((GameObject obj) => (Object)(object)obj != (Object)null && ((Object)obj).name != null && ((Object)obj).name.Contains("Luggage")).ToList(); logs.Log($"Debug: Found {list.Count} active luggage objects in scene"); foreach (GameObject item in list.Take(10)) { logs.Log("Debug luggage name: '" + (((item != null) ? ((Object)item).name : null) ?? "NULL") + "'"); } } catch (Exception arg) { logs.Log($"DEBUG ERROR in luggage filtering: {arg}"); } } logs.Log("DEBUG: About to build campfire biome mapping..."); Dictionary<Campfire, string> dictionary = new Dictionary<Campfire, string>(); try { Campfire[] array = Object.FindObjectsByType<Campfire>((FindObjectsInactive)0, (FindObjectsSortMode)0); logs.Log($"DEBUG: Found {((array != null) ? array.Length : 0)} campfires"); Campfire[] array2 = array; foreach (Campfire val in array2) { if ((Object)(object)val == (Object)null) { logs.Log("DEBUG: Null campfire found, skipping"); continue; } string value = "UNKNOWN"; CampfireRule[] array3 = ConfigManager._itemsConfig?.campfireRules ?? Array.Empty<CampfireRule>(); foreach (CampfireRule campfireRule in array3) { if (ConfigManager.MatchesDetection(((Component)val).gameObject, campfireRule)) { value = campfireRule.biome; break; } } dictionary[val] = value; } logs.Log($"DEBUG: Built campfire mapping for {dictionary.Count} campfires"); } catch (Exception arg2) { logs.Log($"DEBUG ERROR in campfire mapping: {arg2}"); } logs.Log("DEBUG: About to start object processing..."); HashSet<Vector3> hashSet = new HashSet<Vector3>(); try { GameObject[] cachedObjects2 = _cachedObjects; logs.Log($"DEBUG: Processing {((cachedObjects2 != null) ? cachedObjects2.Length : 0)} cached objects"); GameObject[] array4 = _cachedObjects ?? Array.Empty<GameObject>(); foreach (GameObject val2 in array4) { if ((Object)(object)val2 == (Object)null) { continue; } GameObject itemObject = GetItemObject(val2); if ((Object)(object)itemObject == (Object)null) { continue; } Transform val3 = null; try { val3 = itemObject.transform.root; } catch { continue; } if ((Object)(object)val3 != (Object)null && ((Object)val3).name == "GAME") { continue; } Vector3 position; try { position = itemObject.transform.position; } catch { continue; } if (!((Object)itemObject).name.Contains("Luggage") && hashSet.Contains(position)) { continue; } bool flag2 = false; CustomItemDetectionRule[] array5 = ConfigManager._itemsConfig?.dbItems ?? Array.Empty<CustomItemDetectionRule>(); foreach (CustomItemDetectionRule customItemDetectionRule in array5) { if (customItemDetectionRule == null || (customItemDetectionRule.biome != CurrentBiome && customItemDetectionRule.biome != "ANY")) { continue; } bool flag3 = false; try { flag3 = ConfigManager.MatchesDetection(itemObject, customItemDetectionRule); } catch (Exception arg3) { logs.Log($"DEBUG ERROR in MatchesDetection (db): {arg3}"); } if (flag3) { string itemType = customItemDetectionRule.itemType; string displayName = ((ItemNameManager.Instance != null) ? ItemNameManager.Instance.GetNiceName(((Object)itemObject).name) : ((Object)itemObject).name); CurrentBiomeItems.Add(new ItemData { itemType = itemType, biome = CurrentBiome, position = position, fullPath = GetFullPath(itemObject), objectName = ((Object)itemObject).name, displayName = displayName }); if (!((Object)itemObject).name.Contains("Luggage")) { hashSet.Add(position); } flag2 = true; break; } } if (flag2) { continue; } CustomItemDetectionRule[] array6 = ConfigManager._itemsConfig?.customItems ?? Array.Empty<CustomItemDetectionRule>(); foreach (CustomItemDetectionRule customItemDetectionRule2 in array6) { if (customItemDetectionRule2 == null || (customItemDetectionRule2.biome != CurrentBiome && customItemDetectionRule2.biome != "ANY")) { continue; } bool flag4 = false; try { flag4 = ConfigManager.MatchesDetection(itemObject, customItemDetectionRule2); } catch (Exception arg4) { logs.Log($"DEBUG ERROR in MatchesDetection (custom): {arg4}"); } if (flag4 && IsCustomItemSelected(customItemDetectionRule2.itemType)) { string itemType2 = customItemDetectionRule2.itemType; string displayName2 = ((!string.IsNullOrEmpty(customItemDetectionRule2.niceName)) ? customItemDetectionRule2.niceName : customItemDetectionRule2.itemType); CurrentBiomeItems.Add(new ItemData { itemType = itemType2, biome = CurrentBiome, position = position, fullPath = GetFullPath(itemObject), objectName = ((Object)itemObject).name, displayName = displayName2 }); if (!((Object)itemObject).name.Contains("Luggage")) { hashSet.Add(position); } break; } } } logs.Log($"DEBUG: Finished processing objects, found {CurrentBiomeItems.Count} items so far"); } catch (Exception arg5) { logs.Log($"DEBUG ERROR in object processing: {arg5}"); } logs.Log("DEBUG: About to add campfires..."); try { foreach (KeyValuePair<Campfire, string> item2 in dictionary) { if (!(item2.Value != CurrentBiome)) { CurrentBiomeItems.Add(new ItemData { itemType = "Campfire", biome = item2.Value, position = ((Component)item2.Key).transform.position, fullPath = GetFullPath(((Component)item2.Key).gameObject), objectName = ((Object)item2.Key).name, campfireRef = item2.Key }); } } logs.Log($"DEBUG: Added campfires, total items now: {CurrentBiomeItems.Count}"); } catch (Exception arg6) { logs.Log($"DEBUG ERROR adding campfires: {arg6}"); } logs.Log("DEBUG: About to save items to file..."); try { SaveItemsToFile(); logs.Log("DEBUG: SaveItemsToFile completed successfully"); } catch (Exception arg7) { logs.Log($"DEBUG ERROR in SaveItemsToFile: {arg7}"); } logs.Log("=== DEBUG: FindAllItemsForCurrentBiome completed ==="); } public void ReloadAndSpawnItems() { //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Unknown result type (might be due to invalid IL or missing references) //IL_0770: Unknown result type (might be due to invalid IL or missing references) //IL_0850: Unknown result type (might be due to invalid IL or missing references) //IL_0855: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) logs.Log("[ItemFinder] ReloadAndSpawnItems() called - forcing complete refresh."); EnsureArrowManager(); if ((Object)(object)ArrowManager == (Object)null) { logs.Log("[ItemFinder] ArrowManager is null after EnsureArrowManager(). Aborting reload to avoid NRE."); return; } try { ArrowManager.ClearAll(); logs.Log("[ItemFinder] Cleared all existing arrows."); } catch (Exception ex) { logs.Log("[ItemFinder] Error clearing arrows: " + ex.Message); } logs.Log($"[ItemFinder] CurrentBiomeItems count before clear: {CurrentBiomeItems.Count}"); CurrentBiomeItems.Clear(); logs.Log($"[ItemFinder] CurrentBiomeItems count after clear: {CurrentBiomeItems.Count}"); logs.Log("=== DEBUG: Starting FindAllItemsForCurrentBiome ==="); if (!Directory.Exists(OutputDirectory)) { logs.Log("Creating output directory..."); Directory.CreateDirectory(OutputDirectory); } bool flag = _cachedObjects != null && _cachedObjects.Any((GameObject obj) => (Object)(object)obj == (Object)null); if (_cachedObjects == null || flag) { _cachedObjects = Object.FindObjectsByType<GameObject>((FindObjectsInactive)0, (FindObjectsSortMode)0); GameObject[] cachedObjects = _cachedObjects; logs.Lo