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.0
plugins/ItemFinder.dll
Decompiled 18 hours 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 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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown 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)); } } 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 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("Started BiomeDetector - Scene: " + name); Application.logMessageReceived += new LogCallback(OnLogMessageReceived); } 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>((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("Initial biome detected: " + CurrentBiome + " (found crashed plane)"); break; } } } } 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) { CurrentBiome = text; logs.Log("Biome detected: " + 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(); } [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 UnityCoordinatesFontSize = 18; public float coordinatesUpdateRate = 10f; public int? AscentToLoad = null; public int? LevelToLoad = null; public int? Levelindex = null; public string[] validBiomes = new string[7] { "SHORE", "TROPICS", "MESA", "ALPINE", "CALDERA", "KILN", "THE KILN" }; public KeyboardSettings keyboard = new KeyboardSettings(); public bool OpenLuggageAutomatically = false; 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 bool requireShiftModifier = false; public string itemSelectorToggleKey = "I"; public string fullAutomationKey = "F4"; public string arrowModeKey = "F3"; public string toggleArrowsKey = "F1"; public string toggleLabelsKey = "F2"; 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_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_0015: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse<KeyCode>(keyString, out KeyCode result)) { return result; } 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 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)) { string text = File.ReadAllText(ItemsConfigPath); logs.Log("[DEBUG] 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 = CreateDefaultItemRules(); } if (_itemsConfig.campfireRules == null) { _itemsConfig.campfireRules = CreateDefaultCampfireRules(); } } else { _itemsConfig = CreateDefaultItemsConfig(); SaveItemsConfig(); } } catch { _itemsConfig = CreateDefaultItemsConfig(); } } public static void LoadSettingsConfig() { try { EnsureConfigDirectoryExists(); if (File.Exists(SettingsConfigPath)) { string text = File.ReadAllText(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(); } } else { _settingsConfig = CreateDefaultSettingsConfig(); SaveSettingsConfig(); } } catch { _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 = CreateDefaultItemRules(); 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() }; } private static CustomItemDetectionRule[] CreateDefaultItemRules() { return new CustomItemDetectionRule[7] { 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 = "ALPINE", 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" } }; } private 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 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>.Enumerator <>s__1; private Luggage <lug>5__2; 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() { <>s__1 = default(List<Luggage>.Enumerator); <lug>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (ConfigManager._settingsConfig.general.OpenLuggageAutomatically) { <>s__1 = Luggage.ALL_LUGGAGE.ToList().GetEnumerator(); try { while (<>s__1.MoveNext()) { <lug>5__2 = <>s__1.Current; if (<lug>5__2.IsInteractible((Character)null)) { ((MonoBehaviourPun)<lug>5__2).photonView.RPC("OpenLuggageRPC", (RpcTarget)0, new object[1] { true }); } <lug>5__2 = null; } } finally { ((IDisposable)<>s__1).Dispose(); } <>s__1 = default(List<Luggage>.Enumerator); <>2__current = (object)new WaitUntil((Func<bool>)(() => Luggage.ALL_LUGGAGE.All((Luggage l) => !l.IsInteractible((Character)null)))); <>1__state = 1; return true; } logs.Log("Skipping OpenAllLuggageCoroutine due to config."); break; case 1: <>1__state = -1; break; } 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)); OutputDirectory = ConfigManager._settingsConfig?.general?.GetOutputDirectory(); SessionTimestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); ConfigManager.LoadConfigs(); RefreshCustomItemsFromConfig(); BiomeDetector.DetectInitialBiome(); 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; } } 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"); } public void FindAllItemsForCurrentBiome() { //IL_07b4: Unknown result type (might be due to invalid IL or missing references) //IL_07b9: Unknown result type (might be due to invalid IL or missing references) //IL_0460: 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_047b: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: 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) { logs.Log("DEBUG: Null object in cached objects, skipping"); continue; } Vector3 position = val2.transform.position; if (!((Object)val2).name.Contains("Luggage") && hashSet.Contains(position)) { continue; } if (!((Object)val2).name.Contains("Luggage")) { hashSet.Add(position); } bool flag2 = false; CustomItemDetectionRule[] array5 = ConfigManager._itemsConfig?.dbItems ?? Array.Empty<CustomItemDetectionRule>(); foreach (CustomItemDetectionRule customItemDetectionRule in array5) { if ((!(customItemDetectionRule.biome != CurrentBiome) || !(customItemDetectionRule.biome != "ANY")) && ConfigManager.MatchesDetection(val2, customItemDetectionRule)) { string itemType = customItemDetectionRule.itemType; string niceName = ItemNameManager.Instance.GetNiceName(((Object)val2).name); CurrentBiomeItems.Add(new ItemData { itemType = itemType, biome = CurrentBiome, position = position, fullPath = GetFullPath(val2), objectName = ((Object)val2).name, displayName = niceName }); flag2 = true; break; } } if (flag2) { continue; } CustomItemDetectionRule[] array6 = ConfigManager._itemsConfig?.customItems ?? Array.Empty<CustomItemDetectionRule>(); foreach (CustomItemDetectionRule customItemDetectionRule2 in array6) { if ((!(customItemDetectionRule2.biome != CurrentBiome) || !(customItemDetectionRule2.biome != "ANY")) && ConfigManager.MatchesDetection(val2, customItemDetectionRule2) && IsCustomItemSelected(customItemDetectionRule2.itemType)) { string itemType2 = customItemDetectionRule2.itemType; string displayName = ((!string.IsNullOrEmpty(customItemDetectionRule2.niceName)) ? customItemDetectionRule2.niceName : customItemDetectionRule2.itemType); CurrentBiomeItems.Add(new ItemData { itemType = itemType2, biome = CurrentBiome, position = position, fullPath = GetFullPath(val2), objectName = ((Object)val2).name, displayName = displayName }); break; } } } logs.Log($"DEBUG: Finished processing objects, found {CurrentBiomeItems.Count} items so far"); } catch (Exception arg3) { logs.Log($"DEBUG ERROR in object processing: {arg3}"); } 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 arg4) { logs.Log($"DEBUG ERROR adding campfires: {arg4}"); } logs.Log("DEBUG: About to save items to file..."); try { SaveItemsToFile(); logs.Log("DEBUG: SaveItemsToFile completed successfully"); } catch (Exception arg5) { logs.Log($"DEBUG ERROR in SaveItemsToFile: {arg5}"); } logs.Log("=== DEBUG: FindAllItemsForCurrentBiome completed ==="); } public void ReloadAndSpawnItems() { Debug.Log((object)"[ItemFinder] ReloadAndSpawnItems() called."); _lastScannedBiome = null; _cachedObjects = null; EnsureArrowManager(); FindAllItemsForCurrentBiome(); if ((Object)(object)ArrowManager != (Object)null) { ArrowManager.SpawnForItems(CurrentBiomeItems); } Debug.Log((object)"[ItemFinder] ReloadAndSpawnItems() completed."); } public bool IsCustomItem(string itemName) { return customItems.Contains(ConfigManager.NormalizeName(itemName)); } public bool IsCustomItemSelected(string itemName) { string item = ConfigManager.NormalizeName(itemName); return selectedCustomItems.Contains(item); } public void SetCustomItemSelected(string itemName, bool selected) { string text = ConfigManager.NormalizeName(itemName); if (!customItems.Contains(text)) { return; } if (selected) { selectedCustomItems.Add(text); } else { selectedCustomItems.Remove(text); } ItemDetectionRule[] array = ConfigManager._itemsConfig?.itemDetectionRules ?? Array.Empty<ItemDetectionRule>(); foreach (ItemDetectionRule itemDetectionRule in array) { if (itemDetectionRule is CustomItemDetectionRule customItemDetectionRule && ConfigManager.NormalizeName(customItemDetectionRule.itemType) == text) { customItemDetectionRule.selected = selected; break; } } } } public class ItemNameManager { [Serializable] private class SerializableDictionary { public List<string> RawName = new List<string>(); public List<string> DisplayName = new List<string>(); public Dictionary<string, string> ObjToNice { get { Dictionary<string, string> dictionary = new Dictionary<string, string>(); for (int i = 0; i < Math.Min(RawName.Count, DisplayName.Count); i++) { dictionary[RawName[i]] = DisplayName[i]; } return dictionary; } } public SerializableDictionary(Dictionary<string, string> objToNice) { foreach (KeyValuePair<string, string> item in objToNice) { RawName.Add(item.Key); DisplayName.Add(item.Value); } } public SerializableDictionary() { } } private static ItemNameManager _instance; private Dictionary<string, string> objToNice = new Dictionary<string, string>(); private string cachePath = Path.Combine(Paths.ConfigPath, "ItemFinder", "ItemNameCache.json"); public static ItemNameManager Instance { get { if (_instance == null) { _instance = new ItemNameManager(); } return _instance; } } private ItemNameManager() { EnsureCacheDirectoryExists(); PopulateFromDatabase(); } private void EnsureCacheDirectoryExists() { string directoryName = Path.GetDirectoryName(cachePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } } public string GetNiceName(string objName) { if (objToNice.TryGetValue(objName, out var value)) { return value; } return objName; } public void SetName(string objName, string niceName) { objToNice[objName] = niceName; } public void SaveToDisk() { try { SerializableDictionary serializableDictionary = new SerializableDictionary(objToNice); string contents = JsonUtility.ToJson((object)serializableDictionary, true); File.WriteAllText(cachePath, contents); Debug.Log((object)("[ItemNameManager] Cache saved to '" + cachePath + "'")); } catch { Debug.LogWarning((object)"[ItemNameManager] Failed to save cache."); } } public void PopulateFromDatabase() { if ((Object)(object)SingletonAsset<ItemDatabase>.Instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects == null) { return; } objToNice.Clear(); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects) { if (!((Object)(object)@object == (Object)null) && @object.UIData != null) { string name = ((Object)((Component)@object).gameObject).name; string key = @object.UIData.itemName ?? name; if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<string>()); } value.Add(name); } } foreach (KeyValuePair<string, List<string>> item in dictionary) { string key2 = item.Key; List<string> value2 = item.Value; if (value2.Count == 1) { SetName(value2[0], key2); continue; } foreach (string item2 in value2) { string niceName = key2 + " (" + item2 + ")"; SetName(item2, niceName); } } SaveToDisk(); Debug.Log((object)"[ItemNameManager] Cache overwritten from ItemDatabase with duplicate resolution."); } } [BepInPlugin("ItemFinder.plugin", "ItemFinder", "1.0.0")] public class Keyboard : BaseUnityPlugin { [CompilerGenerated] private sealed class <ManualTriggerCampfireCoroutine>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Keyboard <>4__this; private List<ItemFinder.ItemData> <campfireItems>5__1; private ItemFinder.ItemData <currentBiomeCampfire>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ManualTriggerCampfireCoroutine>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <campfireItems>5__1 = null; <currentBiomeCampfire>5__2 = default(ItemFinder.ItemData); <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.finder.FindAllItemsForCurrentBiome(); <campfireItems>5__1 = <>4__this.finder.CurrentBiomeItems.FindAll((ItemFinder.ItemData item) => item.itemType == "Campfire"); <currentBiomeCampfire>5__2 = <campfireItems>5__1.Find((ItemFinder.ItemData c) => c.biome == BiomeDetector.CurrentBiome); if ((Object)(object)<currentBiomeCampfire>5__2.campfireRef != (Object)null) { logs.Log("Triggering campfire in " + <currentBiomeCampfire>5__2.biome + "..."); <>2__current = Screenshotter.TriggerCampfireCoroutine(<>4__this.finder, <currentBiomeCampfire>5__2); <>1__state = 1; return true; } logs.Log("No campfire found for current biome: " + BiomeDetector.CurrentBiome); break; case 1: <>1__state = -1; break; } 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 <SetupUIDelayed>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Keyboard <>4__this; private GameObject <guiObj>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SetupUIDelayed>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <guiObj>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (ConfigManager._itemsConfig == null || ConfigManager._settingsConfig == null) { logs.Log("[Keyboard] Config is null, loading config..."); ConfigManager.LoadConfigs(); } goto IL_0070; case 1: <>1__state = -1; goto IL_0070; case 2: { <>1__state = -1; logs.Log($"[Keyboard] About to initialize window. ItemsConfig null: {ConfigManager._itemsConfig == null}, SettingsConfig null: {ConfigManager._settingsConfig == null}"); <>4__this.window.Initialize(); logs.Log("[Keyboard] Window initialization complete"); return false; } IL_0070: if ((Object)(object)SingletonAsset<ItemDatabase>.Instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } if ((Object)(object)<>4__this.window == (Object)null) { <>4__this.window = Object.FindObjectOfType<ItemSelectorWindow>(); if ((Object)(object)<>4__this.window == (Object)null) { <guiObj>5__1 = new GameObject("ItemSelectorWindow"); <>4__this.window = <guiObj>5__1.AddComponent<ItemSelectorWindow>(); <guiObj>5__1 = null; } } <>4__this.window.SetupUI(); <>2__current = null; <>1__state = 2; 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(); } } private ItemSelectorWindow window; private ItemFinder finder; private bool automationQueued = false; private bool arrowModeQueued = false; private void Awake() { logs.Log("[Keyboard] Loading config..."); ConfigManager.LoadConfigs(); logs.Log($"[Keyboard] Config loaded. Config is null: {ConfigManager._itemsConfig == null && ConfigManager._settingsConfig == null}"); SceneManager.sceneLoaded += OnSceneLoaded; logs.Log("[Keyboard] Peak Automation Plugin loaded!"); } private void EnsureFinderExists() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown if ((Object)(object)finder == (Object)null) { finder = Object.FindObjectOfType<ItemFinder>(); if ((Object)(object)finder == (Object)null) { logs.Log("[Keyboard] Creating new ItemFinder GameObject."); GameObject val = new GameObject("ItemFinder"); finder = val.AddComponent<ItemFinder>(); } else { logs.Log("[Keyboard] Found existing ItemFinder: " + ((Object)((Component)finder).gameObject).name); } } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ((MonoBehaviour)this).StartCoroutine(SetupUIDelayed()); if (automationQueued) { EnsureFinderExists(); finder?.RunFullAutomation(); automationQueued = false; } if (arrowModeQueued) { EnsureFinderExists(); finder?.RunArrowOnlyMode(); arrowModeQueued = false; } } [IteratorStateMachine(typeof(<SetupUIDelayed>d__7))] private IEnumerator SetupUIDelayed() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SetupUIDelayed>d__7(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<ManualTriggerCampfireCoroutine>d__8))] private IEnumerator ManualTriggerCampfireCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ManualTriggerCampfireCoroutine>d__8(0) { <>4__this = this }; } private void Update() { //IL_0029: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) KeyboardSettings keyboardSettings = ConfigManager._settingsConfig?.general?.keyboard ?? new KeyboardSettings(); if (Input.GetKeyDown(keyboardSettings.GetItemSelectorToggleKey())) { window?.Toggle(); } if (Input.GetKeyDown(keyboardSettings.GetFullAutomationKey()) && keyboardSettings.IsShiftRequirementMet()) { AirportCheckInKiosk val = Object.FindObjectOfType<AirportCheckInKiosk>(); if ((Object)(object)val != (Object)null) { try { int valueOrDefault = (ConfigManager._settingsConfig?.general?.AscentToLoad).GetValueOrDefault(-1); val.LoadIslandMaster(valueOrDefault); automationQueued = true; } catch (Exception arg) { logs.Log($"[Keyboard] Full automation key pressed - kiosk.LoadIslandMaster threw an exception: {arg}"); } } else { logs.Log("[Keyboard] Full automation key pressed - AirportCheckInKiosk not found"); } } if (Input.GetKeyDown(keyboardSettings.GetArrowModeKey()) && keyboardSettings.IsShiftRequirementMet()) { AirportCheckInKiosk val2 = Object.FindObjectOfType<AirportCheckInKiosk>(); if ((Object)(object)val2 != (Object)null) { try { int valueOrDefault2 = (ConfigManager._settingsConfig?.general?.AscentToLoad).GetValueOrDefault(-1); val2.LoadIslandMaster(valueOrDefault2); arrowModeQueued = true; } catch (Exception arg2) { logs.Log($"[Keyboard] Arrow mode key pressed - kiosk.LoadIslandMaster threw an exception: {arg2}"); } } else { logs.Log("[Keyboard] Arrow mode key pressed - AirportCheckInKiosk not found"); } } if (Input.GetKeyDown(keyboardSettings.GetArrowsNoLoadKey()) && keyboardSettings.IsShiftRequirementMet()) { AirportCheckInKiosk val3 = Object.FindObjectOfType<AirportCheckInKiosk>(); if ((Object)(object)val3 != (Object)null) { arrowModeQueued = true; logs.Log("[Keyboard] Arrow mode queued without game load - waiting for level ready"); } else { logs.Log("[Keyboard] Arrow mode queue attempted - AirportCheckInKiosk not found"); } } if (Input.GetKeyDown(keyboardSettings.GetToggleArrowsKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); finder?.EnsureArrowManager(); finder?.ArrowManager?.ToggleArrows(); } if (Input.GetKeyDown(keyboardSettings.GetToggleLabelsKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); finder?.EnsureArrowManager(); finder?.ArrowManager?.ToggleLabels(); } if (Input.GetKeyDown(keyboardSettings.GetHotReloadKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); if ((Object)(object)finder?.ArrowManager != (Object)null) { finder.ArrowManager.ClearAll(); finder.ReloadAndSpawnItems(); logs.Log("[Keyboard] Hot reload (F5) completed via ReloadAndSpawnItems()."); } } if (Input.GetKeyDown(keyboardSettings.GetSpawnItemsKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); finder?.EnsureArrowManager(); finder?.ReloadAndSpawnItems(); } if (Input.GetKeyDown(keyboardSettings.GetOpenLuggageKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); if ((Object)(object)finder != (Object)null) { logs.Log("F7 pressed - Opening all luggage..."); ((MonoBehaviour)finder).StartCoroutine(finder.OpenAllLuggageCoroutine()); } } if (Input.GetKeyDown(keyboardSettings.GetTriggerCampfireKey()) && keyboardSettings.IsShiftRequirementMet()) { EnsureFinderExists(); if ((Object)(object)finder != (Object)null) { logs.Log("Manual campfire trigger requested..."); ((MonoBehaviour)finder).StartCoroutine(ManualTriggerCampfireCoroutine()); } } } } public static class logs { private const float FADE_COMPLETE_THRESHOLD = 0.999f; private const int STABILITY_THRESHOLD = 20; private const int LOG_BATCH_SIZE = 50; private const int LOG_FLUSH_INTERVAL_MS = 1000; private static bool fadeOutComplete; private static int runStartedCount; private static float lastFadeValue; private static bool suppressCallbackOutput; private static readonly ConcurrentQueue<string> logQueue; private static CancellationTokenSource cancellationTokenSource; private static Task loggingTask; private static readonly object lockObject; private static bool isInitialized; private static string logFolder { get { string text = ConfigManager._settingsConfig?.general?.outputPath ?? ""; if (string.IsNullOrEmpty(text)) { return Path.Combine(Paths.ConfigPath, "Itemfinder"); } if (Path.IsPathRooted(text)) { return text; } return Path.Combine(Paths.ConfigPath, "ItemFinder", text); } } private static string logFilePath => Path.Combine(logFolder, "PeakAutomationLog.txt"); public static bool LevelReady { get; private set; } public static bool RunStarted { get; private set; } static logs() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown LevelReady = false; RunStarted = false; fadeOutComplete = false; runStartedCount = 0; lastFadeValue = 0f; suppressCallbackOutput = false; logQueue = new ConcurrentQueue<string>(); lockObject = new object(); isInitialized = false; EnsureLogDirectoryExists(); InitializeAsyncLogging(); Application.logMessageReceived += new LogCallback(OnLogMessageReceived); ResetLevelState(); } private static void InitializeAsyncLogging() { lock (lockObject) { if (!isInitialized) { cancellationTokenSource = new CancellationTokenSource(); loggingTask = Task.Run(() => ProcessLogQueueAsync(cancellationTokenSource.Token)); isInitialized = true; } } } private static void EnsureLogDirectoryExists() { try { if (!Directory.Exists(logFolder)) { Directory.CreateDirectory(logFolder); } } catch (Exception ex) { Debug.LogError((object)("[logs] Failed to create log directory: " + ex.Message)); } } public static void Log(string message) { Debug.Log((object)message); } public static void LogAsync(string message) { if (!isInitialized) { InitializeAsyncLogging(); } string item = $"[{DateTime.Now:HH:mm:ss}] {message}"; logQueue.Enqueue(item); } private static async Task ProcessLogQueueAsync(CancellationToken cancellationToken) { List<string> logBatch = new List<string>(50); while (!cancellationToken.IsCancellationRequested) { try { string logMessage; while (logQueue.TryDequeue(out logMessage) && logBatch.Count < 50) { logBatch.Add(logMessage); } if (logBatch.Count > 0) { await WriteBatchToFileAsync(logBatch); logBatch.Clear(); } await Task.Delay(1000, cancellationToken); } catch (OperationCanceledException) { break; } catch (Exception ex2) { Debug.LogError((object)("[logs] Error in async logging: " + ex2.Message)); await Task.Delay(5000, cancellationToken); } } if (logBatch.Count > 0) { try { await WriteBatchToFileAsync(logBatch); } catch (Exception ex) { Debug.LogError((object)("[logs] Error flushing final logs: " + ex.Message)); } } } private static async Task WriteBatchToFileAsync(List<string> messages) { EnsureLogDirectoryExists(); try { using StreamWriter writer = new StreamWriter(logFilePath, append: true); foreach (string message in messages) { await writer.WriteLineAsync(message); } await writer.FlushAsync(); } catch (Exception ex2) { Exception ex = ex2; Debug.LogError((object)("[logs] Failed to write batch to file: " + ex.Message)); } } private static void WriteToFileImmediate(string message) { try { EnsureLogDirectoryExists(); string text = $"[{DateTime.Now:HH:mm:ss}] {message}"; File.AppendAllText(logFilePath, text + Environment.NewLine); } catch (Exception ex) { if (!suppressCallbackOutput) { suppressCallbackOutput = true; Debug.Log((object)("[logs] failed to write to file: " + ex.Message)); suppressCallbackOutput = false; } } } public static void ClearLog() { try { EnsureLogDirectoryExists(); if (File.Exists(logFilePath)) { File.WriteAllText(logFilePath, ""); } } catch (Exception ex) { Debug.LogError((object)("[logs] Failed to clear log: " + ex.Message)); } ResetLevelState(); Debug.Log((object)"[logs] Cleared log and reset level state."); } public static void ResetLevelState() { LevelReady = false; RunStarted = false; fadeOutComplete = false; runStartedCount = 0; lastFadeValue = 0f; LogAsync("Level state reset for new detection cycle"); } public static void LogLevelState() { string text = $"Level State - Ready: {LevelReady}, RunStarted: {RunStarted}, " + $"FadeOut: {fadeOutComplete}, RunCount: {runStartedCount}, LastFade: {lastFadeValue}"; Debug.Log((object)text); } private static void OnLogMessageReceived(string logString, string stackTrace, LogType type) { if (string.IsNullOrEmpty(logString)) { return; } if (logString.StartsWith("[") || logString.Contains("BiomeDetector") || logString.Contains("ItemFinder") || logString.Contains("Keyboard") || logString.Contains("Set hero title:") || logString.Contains("SETTING FADE OUT:") || logString.Contains("RUN STARTED")) { LogAsync(logString); } else if ((ConfigManager._settingsConfig?.general?.LogUnityDebug).GetValueOrDefault()) { LogAsync("[Unity] " + logString); } if (logString.Contains("Set hero title: ")) { string text = logString.Replace("Set hero title: ", "").Trim(); LogAsync("[BiomeDetector] Raw hero title message: '" + text + "'"); if (IsValidBiomeTitle(text)) { LogAsync("[BiomeDetector] Detected hero title: '" + text + "'"); } else { LogAsync("[BiomeDetector] Hero title '" + text + "' not recognized as biome"); } } if (logString.Contains("SETTING FADE OUT:")) { string[] array = logString.Split(new string[1] { "SETTING FADE OUT:" }, StringSplitOptions.None); if (array.Length > 1 && float.TryParse(array[1].Trim(), out var result)) { lastFadeValue = result; LogAsync($"[Fade] parsed fade value = {result}"); if (!fadeOutComplete && result >= 0.999f) { fadeOutComplete = true; LogAsync("[Fade] fadeOutComplete = true (fade reached ~1)"); CheckLevelReady(); } } } if (logString.Contains("RUN STARTED")) { runStartedCount++; LogAsync($"[Run] RUN STARTED message received (count={runStartedCount})"); if (fadeOutComplete) { RunStarted = true; LogAsync("[Run] RunStarted = true (RUN STARTED happened after fade complete)"); CheckLevelReady(); } else { LogAsync("[Run] RUN STARTED seen before fade complete; waiting for fade completion to mark in-level run"); } } } private static void CheckLevelReady() { if (fadeOutComplete && RunStarted && !LevelReady) { LevelReady = true; WriteToFileImmediate("=== LEVEL READY: Both fade-out complete AND RUN STARTED (in-level) detected ==="); } } private static bool IsValidBiomeTitle(string s) { string[] array = new string[7] { "SHORE", "TROPICS", "MESA", "ALPINE", "CALDERA", "KILN", "THE KILN" }; string[] array2 = array; foreach (string text in array2) { if (text == s) { return true; } } return false; } public static async Task FlushAsync() { if (isInitialized) { int maxWaitMs = 5000; int waitedMs = 0; while (!logQueue.IsEmpty && waitedMs < maxWaitMs) { await Task.Delay(100); waitedMs += 100; } } } public static void Shutdown() { if (!isInitialized) { return; } try { cancellationTokenSource?.Cancel(); if (loggingTask != null && !loggingTask.IsCompleted) { loggingTask.Wait(TimeSpan.FromSeconds(5.0)); } string result; while (logQueue.TryDequeue(out result)) { try { File.AppendAllText(logFilePath, result + Environment.NewLine); } catch { break; } } } catch (Exception ex) { Debug.LogError((object)("[logs] Error during shutdown: " + ex.Message)); } finally { cancellationTokenSource?.Dispose(); isInitialized = false; } } } public static class Screenshotter { [CompilerGenerated] private sealed class <>c__DisplayClass1_0 { public KeyCode triggerKey; internal bool <ScreenshotItemCoroutine>b__0() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Input.GetKeyDown(triggerKey); } internal bool <ScreenshotItemCoroutine>b__1() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Input.GetKeyDown(triggerKey); } } [CompilerGenerated] private sealed class <ScreenshotItemCoroutine>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemFinder finder; public Dictionary<string, int> counters; private List<ItemFinder.ItemData> <items>5__1; private SettingsConfig <config>5__2; private ScreenshotSettings <screenshotSettings>5__3; private GeneralSettings <general>5__4; private int <i>5__5; private <>c__DisplayClass1_0 <>8__6; private ItemFinder.ItemData <item>5__7; private Character <local>5__8; private Vector3 <teleportPos>5__9; private int <count>5__10; private string <filename>5__11; private string <fullPath>5__12; private RaycastHit <hit>5__13; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ScreenshotItemCoroutine>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <items>5__1 = null; <config>5__2 = null; <screenshotSettings>5__3 = null; <general>5__4 = null; <>8__6 = null; <item>5__7 = default(ItemFinder.ItemData); <local>5__8 = null; <filename>5__11 = null; <fullPath>5__12 = null; <>1__state = -2; } private bool MoveNext() { //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <items>5__1 = finder.CurrentBiomeItems; <config>5__2 = ConfigManager._settingsConfig; if (<config>5__2 == null) { logs.Log("Config is null, cannot proceed with screenshot automation!"); return false; } <screenshotSettings>5__3 = <config>5__2.automation.screenshot; <general>5__4 = <config>5__2.general; <i>5__5 = 0; break; case 1: <>1__state