Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChestSearch v1.0.6
plugins/ChestSearch/ChestSearch.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ChestSearch")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+f9b163275ab4d47a7afb50ff89f586c3a2035d9b")] [assembly: AssemblyProduct("ChestSearch")] [assembly: AssemblyTitle("ChestSearch")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ChestSearch; [HarmonyPatch(typeof(Player), "SetSelectedPiece", new Type[] { typeof(Vector2Int) })] public static class BuildPullPatch { [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); private static bool IsOSKeyDown(int vKey) { return (GetAsyncKeyState(vKey) & 0x8000) != 0; } private static void Postfix(Player __instance, Vector2Int p) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) int value = Plugin.BuildPullVKey.Value; if (value == 0 || !IsOSKeyDown(value) || (Object)(object)__instance == (Object)null) { return; } Piece piece = __instance.GetPiece(p); if ((Object)(object)piece == (Object)null || piece.m_resources == null) { return; } Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory == null) { return; } float value2 = Plugin.TakeRange.Value; List<string> list = new List<string>(); List<string> list2 = new List<string>(); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if ((Object)(object)val.m_resItem == (Object)null || val.m_amount <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; string arg = Localization.instance.Localize(name); int num = inventory.CountItems(name, -1, true); int num2 = val.m_amount - num; if (num2 > 0) { int num3 = ContainerSearcher.TakeItems(name, num2, value2); if (num3 >= num2) { list.Add($"{num3}x {arg}"); } else if (num3 > 0) { list.Add($"{num3}x {arg}"); list2.Add($"{num2 - num3}x {arg}"); } else { list2.Add($"{num2}x {arg}"); } } } if (list.Count > 0) { string text = "Pulled " + string.Join(", ", list); if (list2.Count > 0) { text = text + " | Missing " + string.Join(", ", list2); } MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false); } } else if (list2.Count > 0) { MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)1, "Missing " + string.Join(", ", list2), 0, (Sprite)null, false); } } } } public class ContainerHighlight : MonoBehaviour { private float duration = 8f; private float elapsed; private readonly List<Light> lights = new List<Light>(); private readonly List<float> offsets = new List<float>(); private const int LightCount = 3; private const float OrbitRadius = 1.2f; private const float OrbitSpeed = 2f; private const float BobSpeed = 3f; private const float BobAmount = 0.3f; private float baseY; private ParticleSystem particles; private static readonly Color highlightColor = new Color(0.4f, 0.8f, 1f, 1f); private readonly List<Renderer> glowRenderers = new List<Renderer>(); private readonly List<Color> originalColors = new List<Color>(); private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor"); public static void Highlight(Container container, float seconds = 8f) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)container == (Object)null)) { ContainerHighlight componentInChildren = ((Component)container).GetComponentInChildren<ContainerHighlight>(); if ((Object)(object)componentInChildren != (Object)null) { Object.Destroy((Object)(object)((Component)componentInChildren).gameObject); } GameObject val = new GameObject("ChestSearchHighlight"); val.transform.SetParent(((Component)container).transform, false); val.transform.localPosition = Vector3.up * 1.2f; val.AddComponent<ContainerHighlight>().duration = seconds; } } private void Start() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0194: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Expected O, but got Unknown //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) baseY = ((Component)this).transform.localPosition.y; Container componentInParent = ((Component)this).GetComponentInParent<Container>(); if ((Object)(object)componentInParent != (Object)null) { Renderer[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { Material[] materials = val.materials; foreach (Material val2 in materials) { if (val2.HasProperty(EmissionColor)) { glowRenderers.Add(val); originalColors.Add(val2.GetColor(EmissionColor)); val2.EnableKeyword("_EMISSION"); break; } } } } for (int k = 0; k < 3; k++) { GameObject val3 = new GameObject($"OrbitLight_{k}"); val3.transform.SetParent(((Component)this).transform, false); Light val4 = val3.AddComponent<Light>(); val4.type = (LightType)2; val4.color = highlightColor; val4.intensity = 1.5f; val4.range = 3f; val4.shadows = (LightShadows)0; lights.Add(val4); offsets.Add((float)k * 120f); } GameObject val5 = new GameObject("Sparkles"); val5.transform.SetParent(((Component)this).transform, false); val5.transform.localPosition = Vector3.zero; particles = val5.AddComponent<ParticleSystem>(); MainModule main = particles.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.5f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.08f); ((MainModule)(ref main)).maxParticles = 30; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(highlightColor); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.1f); EmissionModule emission = particles.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(12f); ShapeModule shape = particles.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.6f; ColorOverLifetimeModule colorOverLifetime = particles.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val6 = new Gradient(); val6.SetKeys((GradientColorKey[])(object)new GradientColorKey[3] { new GradientColorKey(highlightColor, 0f), new GradientColorKey(highlightColor, 0.5f), new GradientColorKey(highlightColor, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(1f, 0.2f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val6); SizeOverLifetimeModule sizeOverLifetime = particles.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.Linear(0f, 1f, 1f, 0f)); ParticleSystemRenderer component = val5.GetComponent<ParticleSystemRenderer>(); Shader val7 = Shader.Find("Legacy Shaders/Particles/Additive") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default"); ((Renderer)component).material = new Material(val7); ((Renderer)component).material.color = highlightColor; } private void Update() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) elapsed += Time.deltaTime; float num = 1f; if (elapsed > duration - 2f) { num = Mathf.Clamp01((duration - elapsed) / 2f); } for (int i = 0; i < lights.Count; i++) { float num2 = (Time.time * 2f * 360f + offsets[i]) * ((float)Math.PI / 180f); float num3 = Mathf.Cos(num2) * 1.2f; float num4 = Mathf.Sin(num2) * 1.2f; float num5 = Mathf.Sin(Time.time * 3f + offsets[i] * ((float)Math.PI / 180f)) * 0.3f; ((Component)lights[i]).transform.localPosition = new Vector3(num3, num5, num4); lights[i].intensity = 1.5f * num; } if ((Object)(object)particles != (Object)null) { EmissionModule emission = particles.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(12f * num); } float num6 = (Mathf.Sin(Time.time * 3f) * 0.5f + 0.5f) * num; for (int j = 0; j < glowRenderers.Count; j++) { if (!((Object)(object)glowRenderers[j] != (Object)null)) { continue; } Material[] materials = glowRenderers[j].materials; foreach (Material val in materials) { if (val.HasProperty(EmissionColor)) { val.SetColor(EmissionColor, highlightColor * num6 * 2f); } } } if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < glowRenderers.Count; i++) { if (!((Object)(object)glowRenderers[i] != (Object)null)) { continue; } Material[] materials = glowRenderers[i].materials; foreach (Material val in materials) { if (val.HasProperty(EmissionColor)) { val.SetColor(EmissionColor, originalColors[i]); } } } foreach (Light light in lights) { if ((Object)(object)light != (Object)null) { Object.Destroy((Object)(object)((Component)light).gameObject); } } } } public struct SearchResult { public string ContainerName; public Vector3 Position; public float Distance; public List<ItemMatch> Items; public Container Container; } public struct ItemMatch { public string Name; public int Stack; public string QualityText; public string ItemKey; } public static class ContainerSearcher { public static List<SearchResult> Search(string query) { //IL_0027: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) List<SearchResult> list = new List<SearchResult>(); if (string.IsNullOrWhiteSpace(query) || (Object)(object)Player.m_localPlayer == (Object)null) { return list; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; string value = query.ToLowerInvariant(); Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); foreach (Container val in array) { if ((Object)(object)val == (Object)null || val.GetInventory() == null) { continue; } float distance = Vector3.Distance(position, ((Component)val).transform.position); List<ItemData> allItems = val.GetInventory().GetAllItems(); if (allItems == null || allItems.Count == 0) { continue; } List<ItemMatch> list2 = new List<ItemMatch>(); foreach (ItemData item in allItems) { string text = Localization.instance.Localize(item.m_shared.m_name); if (text.ToLowerInvariant().Contains(value)) { string qualityText = ((item.m_shared.m_maxQuality > 1) ? $" (Lv {item.m_quality})" : ""); list2.Add(new ItemMatch { Name = text, Stack = item.m_stack, QualityText = qualityText, ItemKey = item.m_shared.m_name }); } } if (list2.Count <= 0) { continue; } List<ItemMatch> items = (from m in (from m in list2 group m by m.Name + m.QualityText).Select(delegate(IGrouping<string, ItemMatch> g) { ItemMatch result = default(ItemMatch); result.Name = g.First().Name; result.Stack = g.Sum((ItemMatch m) => m.Stack); result.QualityText = g.First().QualityText; result.ItemKey = g.First().ItemKey; return result; }) orderby m.Name select m).ToList(); string containerName = GetContainerName(val); list.Add(new SearchResult { ContainerName = containerName, Position = ((Component)val).transform.position, Distance = distance, Items = items, Container = val }); } return list.OrderBy((SearchResult r) => r.Distance).ToList(); } private static string GetContainerName(Container container) { Piece componentInParent = ((Component)container).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent != (Object)null) { string text = Localization.instance.Localize(componentInParent.m_name); if (!string.IsNullOrEmpty(text)) { return text; } } if (!string.IsNullOrEmpty(container.m_name)) { return Localization.instance.Localize(container.m_name); } return ((Object)((Component)container).gameObject).name.Replace("(Clone)", "").Trim(); } public static void PingContainer(Container container) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)container == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { ContainerHighlight.Highlight(container); Vector3 val = ((Component)container).transform.position + Vector3.up; Chat instance = Chat.instance; if (instance != null) { instance.SendPing(val); } } } public static int TakeItems(Container container, string itemKey, float maxRange) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return 0; } if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)container).transform.position) > maxRange) { return 0; } ZNetView component = ((Component)container).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && !component.IsOwner()) { component.ClaimOwnership(); } Inventory inventory = container.GetInventory(); Inventory inventory2 = ((Humanoid)Player.m_localPlayer).GetInventory(); if (inventory == null || inventory2 == null) { return 0; } int num = 0; List<ItemData> allItems = inventory.GetAllItems(); for (int num2 = allItems.Count - 1; num2 >= 0; num2--) { ItemData val = allItems[num2]; if (!(val.m_shared.m_name != itemKey)) { if (!inventory2.CanAddItem(val, -1)) { break; } int stack = val.m_stack; if (inventory2.AddItem(val)) { inventory.RemoveItem(val); num += stack; } } } return num; } public static int TakeItems(string itemKey, int maxCount, float maxRange) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || maxCount <= 0) { return 0; } Vector3 position = ((Component)Player.m_localPlayer).transform.position; Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); int num = 0; Container[] array2 = array; foreach (Container val in array2) { if (num >= maxCount) { break; } if (!((Object)(object)val == (Object)null) && val.GetInventory() != null && !(Vector3.Distance(position, ((Component)val).transform.position) > maxRange)) { int maxCount2 = maxCount - num; int num2 = TakeItemsFromContainer(val, itemKey, maxCount2); num += num2; } } return num; } private static int TakeItemsFromContainer(Container container, string itemKey, int maxCount) { ZNetView component = ((Component)container).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && !component.IsOwner()) { component.ClaimOwnership(); } Inventory inventory = container.GetInventory(); Inventory inventory2 = ((Humanoid)Player.m_localPlayer).GetInventory(); if (inventory == null || inventory2 == null) { return 0; } int num = 0; List<ItemData> allItems = inventory.GetAllItems(); int num2 = allItems.Count - 1; while (num2 >= 0 && num < maxCount) { ItemData val = allItems[num2]; if (!(val.m_shared.m_name != itemKey)) { int num3 = maxCount - num; int num4 = Mathf.Min(val.m_stack, num3); if (num4 >= val.m_stack) { if (!inventory2.CanAddItem(val, -1)) { break; } if (inventory2.AddItem(val)) { inventory.RemoveItem(val); num += num4; } } else { ItemData val2 = val.Clone(); val2.m_stack = num4; if (!inventory2.CanAddItem(val2, -1)) { break; } if (inventory2.AddItem(val2)) { val.m_stack -= num4; num += num4; } } } num2--; } return num; } } public enum TidyCategory { Material, Consumable, OneHandedWeapon, TwoHandedWeapon, TwoHandedWeaponLeft, Bow, Shield, Helmet, Chest, Legs, Hands, Shoulder, Tool, Torch, Utility, Trinket, Ammo, AmmoNonEquipable, Trophy, Fish, Customization, Misc } public class PlannedSlot { public Container TargetContainer; public int TargetContainerIdx; public Vector2i TargetPos; public ItemData Item; public Container CurrentContainer; public bool Done; } public static class ContainerTidy { private static List<string> logLines; private static MethodInfo inventoryChangedMethod; private static void LogLine(string msg) { logLines?.Add(msg); } private static void FlushLog() { if (logLines == null || logLines.Count == 0) { return; } try { File.WriteAllLines(Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? ".", "tidy-debug.log"), logLines); } catch { } } private static void InvokeChanged(Inventory inv) { if (inventoryChangedMethod == null) { inventoryChangedMethod = typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic); } inventoryChangedMethod?.Invoke(inv, null); } public static TidyCategory GetCategory(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected I4, but got Unknown return (type - 1) switch { 0 => TidyCategory.Material, 1 => TidyCategory.Consumable, 2 => TidyCategory.OneHandedWeapon, 13 => TidyCategory.TwoHandedWeapon, 21 => TidyCategory.TwoHandedWeaponLeft, 3 => TidyCategory.Bow, 4 => TidyCategory.Shield, 5 => TidyCategory.Helmet, 6 => TidyCategory.Chest, 10 => TidyCategory.Legs, 11 => TidyCategory.Hands, 16 => TidyCategory.Shoulder, 18 => TidyCategory.Tool, 14 => TidyCategory.Torch, 17 => TidyCategory.Utility, 23 => TidyCategory.Trinket, 8 => TidyCategory.Ammo, 22 => TidyCategory.AmmoNonEquipable, 12 => TidyCategory.Trophy, 20 => TidyCategory.Fish, 9 => TidyCategory.Customization, _ => TidyCategory.Misc, }; } private static int CompareItems(ItemData a, ItemData b) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) TidyCategory category = GetCategory(a.m_shared.m_itemType); TidyCategory category2 = GetCategory(b.m_shared.m_itemType); if (category != category2) { return category.CompareTo(category2); } int num = string.Compare(a.m_shared.m_name, b.m_shared.m_name, StringComparison.Ordinal); if (num != 0) { return num; } return b.m_stack.CompareTo(a.m_stack); } private static int CompareItemsStable((Container c, ItemData item) a, (Container c, ItemData item) b, List<Container> containers) { int num = CompareItems(a.item, b.item); if (num != 0) { return num; } int num2 = containers.IndexOf(a.c); int num3 = containers.IndexOf(b.c); if (num2 != num3) { return num2.CompareTo(num3); } int num4 = a.item.m_gridPos.y * 100 + a.item.m_gridPos.x; int value = b.item.m_gridPos.y * 100 + b.item.m_gridPos.x; return num4.CompareTo(value); } private static string ItemKey(ItemData item) { return $"{item.m_shared.m_name}|{item.m_quality}|{item.m_worldLevel}"; } private static string DisplayName(ItemData item) { return Localization.instance.Localize(item.m_shared.m_name); } public static string Tidy(float range) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return "No player"; } List<Container> containers = GetNearbyContainers(range); if (containers.Count < 2) { return "Need at least 2 containers nearby"; } foreach (Container item4 in containers) { ZNetView component = ((Component)item4).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && !component.IsOwner()) { component.ClaimOwnership(); } } logLines = new List<string>(); LogLine($"=== TIDY START === {containers.Count} containers"); SortContainersByLayout(containers); LogLine("\n--- CONTAINERS (spatial order) ---"); int num = 0; for (int j = 0; j < containers.Count; j++) { Container val = containers[j]; Inventory inventory = val.GetInventory(); Vector3 position = ((Component)val).transform.position; int num2 = inventory.GetWidth() * inventory.GetHeight(); num += num2; LogLine($" [{j}] {((Object)((Component)val).gameObject).name} ({position.x:F1},{position.y:F1},{position.z:F1}) {inventory.GetWidth()}x{inventory.GetHeight()}={num2} items:{inventory.NrOfItems()}"); } LogLine("\n--- PHASE 1: In-place stack consolidation ---"); int num3 = 0; foreach (Container item5 in containers) { int num4 = ConsolidateWithinContainer(item5); num3 += num4; if (num4 > 0) { LogLine($" {((Object)((Component)item5).gameObject).name}: merged {num4} stacks"); } } LogLine("\n--- PHASE 2: Cross-container consolidation ---"); num3 += ConsolidateAcrossContainers(containers); LogLine("\n--- BUILDING TARGET PLAN ---"); List<(Container, ItemData)> list = new List<(Container, ItemData)>(); LogLine("\n--- CURRENT STATE (before plan) ---"); for (int k = 0; k < containers.Count; k++) { Container val2 = containers[k]; List<ItemData> allItems = val2.GetInventory().GetAllItems(); if (allItems.Count == 0) { continue; } LogLine($" Container[{k}] ({allItems.Count} items):"); foreach (ItemData item6 in allItems) { list.Add((val2, item6)); LogLine($" ({item6.m_gridPos.x},{item6.m_gridPos.y}) {DisplayName(item6)} x{item6.m_stack} hash:{((object)item6).GetHashCode()}"); } } list.Sort(((Container c, ItemData item) a, (Container c, ItemData item) b) => CompareItemsStable(a, b, containers)); HashSet<TidyCategory> hashSet = new HashSet<TidyCategory>(); foreach (var item7 in list) { ItemData item = item7.Item2; hashSet.Add(GetCategory(item.m_shared.m_itemType)); } int count = list.Count; if (count > num) { int num5 = count - num; LogLine($"ABORT: {count} slots needed but only {num} available"); FlushLog(); return $"Need {num5} more slots to tidy ({count} stacks, {num} slots available)"; } List<PlannedSlot> list2 = new List<PlannedSlot>(); int num6 = 0; int num7 = 0; int num8 = 0; TidyCategory? tidyCategory = null; for (int l = 0; l < list.Count; l++) { (Container, ItemData) tuple = list[l]; Container item2 = tuple.Item1; ItemData item3 = tuple.Item2; TidyCategory category = GetCategory(item3.m_shared.m_itemType); if (tidyCategory.HasValue && tidyCategory.Value != category && num7 + num8 > 0) { num6 = Mathf.Min(num6 + 1, containers.Count - 1); num7 = 0; num8 = 0; } tidyCategory = category; Inventory inventory2 = containers[num6].GetInventory(); int width = inventory2.GetWidth(); int height = inventory2.GetHeight(); if (num8 >= height) { num6 = Mathf.Min(num6 + 1, containers.Count - 1); num7 = 0; num8 = 0; Inventory inventory3 = containers[num6].GetInventory(); width = inventory3.GetWidth(); height = inventory3.GetHeight(); } list2.Add(new PlannedSlot { TargetContainer = containers[num6], TargetContainerIdx = num6, TargetPos = new Vector2i(num7, num8), Item = item3, CurrentContainer = item2, Done = ((Object)(object)item2 == (Object)(object)containers[num6]) }); num7++; if (num7 >= width) { num7 = 0; num8++; } } LogLine($"\nPlan: {list2.Count} items across {containers.Count} containers"); int num9 = list2.Count((PlannedSlot p) => p.Done && (Object)(object)p.CurrentContainer == (Object)(object)p.TargetContainer); int num10 = list2.Count - num9; LogLine($" Already in correct container: {num9}"); LogLine($" Need to move: {num10}"); LogLine("\n--- TARGET PLAN ---"); foreach (PlannedSlot item8 in list2) { int num11 = -1; for (int m = 0; m < containers.Count; m++) { if ((Object)(object)containers[m] == (Object)(object)item8.CurrentContainer) { num11 = m; break; } } string text = (((Object)(object)item8.CurrentContainer == (Object)(object)item8.TargetContainer) ? "OK" : "MOVE"); bool flag = (Object)(object)item8.CurrentContainer == (Object)(object)item8.TargetContainer; LogLine($" Container[{item8.TargetContainerIdx}] ({item8.TargetPos.x},{item8.TargetPos.y}): {DisplayName(item8.Item)} x{item8.Item.m_stack} [{text}] currentlyIn:Container[{num11}] gridPos:({item8.Item.m_gridPos.x},{item8.Item.m_gridPos.y}) refMatch:{flag} hash:{((object)item8.Item).GetHashCode()}"); } LogLine("\n--- PHASE 3: Executing moves ---"); int num12 = ExecutePlan(list2, containers); foreach (Container item9 in containers) { InvokeChanged(item9.GetInventory()); } LogLine("\n--- FINAL STATE (after all moves + gridPos) ---"); for (int n = 0; n < containers.Count; n++) { List<ItemData> allItems2 = containers[n].GetInventory().GetAllItems(); if (allItems2.Count == 0) { continue; } LogLine($" Container[{n}] ({allItems2.Count} items):"); foreach (ItemData item10 in allItems2) { LogLine($" ({item10.m_gridPos.x},{item10.m_gridPos.y}) {DisplayName(item10)} x{item10.m_stack} hash:{((object)item10).GetHashCode()}"); } } LogLine("\n--- VALIDATION ---"); string text2 = null; HashSet<string> hashSet2 = new HashSet<string>(); int num13 = 0; for (int num14 = 0; num14 < containers.Count; num14++) { foreach (ItemData item11 in (from i in containers[num14].GetInventory().GetAllItems() orderby i.m_gridPos.y, i.m_gridPos.x select i).ToList()) { string name = item11.m_shared.m_name; if (name != text2) { if (hashSet2.Contains(name)) { LogLine($" VIOLATION: {DisplayName(item11)} appears again in Container[{num14}] after gap! (last seen earlier)"); num13++; } if (text2 != null) { hashSet2.Add(text2); } text2 = name; } } } if (num13 == 0) { LogLine(" All items contiguous — PASS"); } else { LogLine($" {num13} contiguity violations found"); } List<string> list3 = new List<string>(); if (num3 > 0) { list3.Add($"consolidated {num3} stacks"); } if (num12 > 0) { list3.Add($"moved {num12} items"); } if (num3 == 0 && num12 == 0) { FlushLog(); return "Already tidy!"; } string text3 = "Tidied: " + string.Join(", ", list3); LogLine("\n=== RESULT: " + text3 + " ==="); FlushLog(); return text3; } private static int ExecutePlan(List<PlannedSlot> plan, List<Container> containers) { //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) int num = 0; Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); for (int i = 0; i < plan.Count; i++) { PlannedSlot p = plan[i]; if ((Object)(object)p.CurrentContainer == (Object)(object)p.TargetContainer) { p.Done = true; continue; } Inventory inventory2 = p.TargetContainer.GetInventory(); Inventory val = (((Object)(object)p.CurrentContainer != (Object)null) ? p.CurrentContainer.GetInventory() : inventory); if (!inventory2.CanAddItem(p.Item, -1)) { bool flag = false; foreach (ItemData candidate in new List<ItemData>(inventory2.GetAllItems())) { PlannedSlot plannedSlot = plan.FirstOrDefault((PlannedSlot cp) => cp.Item == candidate && (Object)(object)cp.TargetContainer != (Object)(object)p.TargetContainer); if (plannedSlot == null) { continue; } for (int num2 = containers.Count - 1; num2 >= 0; num2--) { Inventory inventory3 = containers[num2].GetInventory(); if (inventory3 != inventory2 && inventory3.CanAddItem(candidate, -1) && inventory3.AddItem(candidate)) { inventory2.RemoveItem(candidate); InvokeChanged(inventory2); InvokeChanged(inventory3); plannedSlot.CurrentContainer = containers[num2]; flag = true; num++; LogLine($" [{i}] evict {DisplayName(candidate)} x{candidate.m_stack} → Container[{num2}]"); break; } } if (!flag && inventory.CanAddItem(candidate, -1)) { inventory.AddItem(candidate); inventory2.RemoveItem(candidate); InvokeChanged(inventory2); InvokeChanged(inventory); plannedSlot.CurrentContainer = null; flag = true; num++; LogLine($" [{i}] evict {DisplayName(candidate)} x{candidate.m_stack} → player"); } if (flag) { break; } } if (!flag) { LogLine($" [{i}] STUCK: {DisplayName(p.Item)} — target full, can't evict"); continue; } } int num3 = inventory2.NrOfItems(); int num4 = val.NrOfItems(); bool flag2 = val.GetAllItems().Contains(p.Item); if (inventory2.AddItem(p.Item)) { bool flag3 = val.GetAllItems().Contains(p.Item); val.RemoveItem(p.Item); InvokeChanged(inventory2); InvokeChanged(val); int num5 = inventory2.NrOfItems(); int num6 = val.NrOfItems(); p.CurrentContainer = p.TargetContainer; p.Done = true; num++; LogLine($" [{i}] {DisplayName(p.Item)} x{p.Item.m_stack} → Container[{p.TargetContainerIdx}] (src:{num4}→{num6} had:{flag2} stillHas:{flag3} tgt:{num3}→{num5})"); } else { LogLine($" [{i}] FAILED: {DisplayName(p.Item)} — AddItem returned false"); } } LogLine("\n--- Set grid positions ---"); foreach (Container container in containers) { Inventory inventory4 = container.GetInventory(); List<ItemData> allItems = inventory4.GetAllItems(); if (allItems.Count == 0) { continue; } List<ItemData> list = new List<ItemData>(allItems); list.Sort((ItemData a, ItemData b) => CompareItems(a, b)); int width = inventory4.GetWidth(); for (int j = 0; j < list.Count; j++) { list[j].m_gridPos = new Vector2i(j % width, j / width); } allItems.Clear(); allItems.AddRange(list); InvokeChanged(inventory4); int num7 = containers.IndexOf(container); LogLine($" Container[{num7}]: {list.Count} items repositioned"); foreach (ItemData item in list) { LogLine($" ({item.m_gridPos.x},{item.m_gridPos.y}) {DisplayName(item)} x{item.m_stack}"); } } foreach (PlannedSlot item2 in plan.Where((PlannedSlot pp) => (Object)(object)pp.CurrentContainer == (Object)null).ToList()) { Inventory inventory5 = item2.TargetContainer.GetInventory(); if (inventory5.CanAddItem(item2.Item, -1) && inventory5.AddItem(item2.Item)) { inventory.RemoveItem(item2.Item); InvokeChanged(inventory5); InvokeChanged(inventory); item2.CurrentContainer = item2.TargetContainer; item2.Done = true; num++; LogLine($" Player → Container[{item2.TargetContainerIdx}]: {DisplayName(item2.Item)} x{item2.Item.m_stack}"); } else { LogLine(" WARNING: " + DisplayName(item2.Item) + " stuck in player inventory"); } } int num8 = plan.Count((PlannedSlot pp) => !pp.Done); if (num8 > 0) { LogLine($" WARNING: {num8} items not in target container"); } return num; } private static int ConsolidateWithinContainer(Container container) { Inventory inventory = container.GetInventory(); List<ItemData> allItems = inventory.GetAllItems(); Dictionary<string, List<ItemData>> dictionary = new Dictionary<string, List<ItemData>>(); foreach (ItemData item in allItems) { string key = ItemKey(item); if (!dictionary.ContainsKey(key)) { dictionary[key] = new List<ItemData>(); } dictionary[key].Add(item); } int num = 0; bool flag = false; foreach (KeyValuePair<string, List<ItemData>> item2 in dictionary) { List<ItemData> value = item2.Value; if (value.Count < 2) { continue; } int maxStackSize = value[0].m_shared.m_maxStackSize; if (maxStackSize <= 1) { continue; } for (int i = 0; i < value.Count; i++) { if (value[i].m_stack >= maxStackSize) { continue; } for (int num2 = value.Count - 1; num2 > i; num2--) { if (value[num2].m_stack > 0) { int num3 = Mathf.Min(maxStackSize - value[i].m_stack, value[num2].m_stack); if (num3 > 0) { ItemData obj = value[i]; obj.m_stack += num3; ItemData obj2 = value[num2]; obj2.m_stack -= num3; flag = true; if (value[num2].m_stack <= 0) { inventory.RemoveItem(value[num2]); num++; } if (value[i].m_stack >= maxStackSize) { break; } } } } } } if (flag) { InvokeChanged(inventory); } return num; } private static int ConsolidateAcrossContainers(List<Container> containers) { Dictionary<string, List<(Container, ItemData)>> dictionary = new Dictionary<string, List<(Container, ItemData)>>(); foreach (Container container in containers) { foreach (ItemData allItem in container.GetInventory().GetAllItems()) { string key = ItemKey(allItem); if (!dictionary.ContainsKey(key)) { dictionary[key] = new List<(Container, ItemData)>(); } dictionary[key].Add((container, allItem)); } } int num = 0; foreach (KeyValuePair<string, List<(Container, ItemData)>> item3 in dictionary) { List<(Container, ItemData)> value = item3.Value; if (value.Count < 2) { continue; } int maxStackSize = value[0].Item2.m_shared.m_maxStackSize; if (maxStackSize <= 1) { continue; } value.Sort(((Container c, ItemData item) a, (Container c, ItemData item) b) => b.item.m_stack.CompareTo(a.item.m_stack)); for (int i = 0; i < value.Count; i++) { (Container, ItemData) tuple = value[i]; if (tuple.Item2.m_stack >= maxStackSize) { continue; } for (int num2 = value.Count - 1; num2 > i; num2--) { (Container, ItemData) tuple2 = value[num2]; if (tuple2.Item2.m_stack > 0 && !((Object)(object)tuple2.Item1 == (Object)(object)tuple.Item1)) { int num3 = Mathf.Min(maxStackSize - tuple.Item2.m_stack, tuple2.Item2.m_stack); if (num3 > 0) { ItemData item = tuple.Item2; item.m_stack += num3; ItemData item2 = tuple2.Item2; item2.m_stack -= num3; if (tuple2.Item2.m_stack <= 0) { tuple2.Item1.GetInventory().RemoveItem(tuple2.Item2); num++; } InvokeChanged(tuple.Item1.GetInventory()); InvokeChanged(tuple2.Item1.GetInventory()); LogLine($" Merged {num3}x {DisplayName(tuple.Item2)}"); if (tuple.Item2.m_stack >= maxStackSize) { break; } } } } } } return num; } private static void SortContainersByLayout(List<Container> containers) { //IL_0010: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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) Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector3 val = Vector3.zero; foreach (Container container in containers) { val += ((Component)container).transform.position; } val /= (float)containers.Count; Vector3 val2 = val - position; val2.y = 0f; ((Vector3)(ref val2)).Normalize(); Vector3 val3 = Vector3.Cross(Vector3.up, val2); Vector3 right = ((Vector3)(ref val3)).normalized; LogLine("\n--- SPATIAL SORT ---"); LogLine($" Player: ({position.x:F1},{position.y:F1},{position.z:F1})"); LogLine($" Chest center: ({val.x:F1},{val.y:F1},{val.z:F1})"); LogLine($" Right vector: ({right.x:F2},{right.y:F2},{right.z:F2})"); containers.Sort(delegate(Container a, Container b) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = a.GetInventory(); Inventory inventory2 = b.GetInventory(); int num = inventory.GetWidth() * inventory.GetHeight(); int num2 = inventory2.GetWidth() * inventory2.GetHeight(); if (num != num2) { return num2.CompareTo(num); } Vector3 position2 = ((Component)a).transform.position; Vector3 position3 = ((Component)b).transform.position; float num3 = Mathf.Round(position2.y * 2f) / 2f; float num4 = Mathf.Round(position3.y * 2f) / 2f; if (num3 != num4) { return num4.CompareTo(num3); } float num5 = Vector3.Dot(position2, right); float value = Vector3.Dot(position3, right); return num5.CompareTo(value); }); } private static List<Container> GetNearbyContainers(float range) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Player.m_localPlayer).transform.position; Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); List<Container> list = new List<Container>(); Container[] array2 = array; foreach (Container val in array2) { if (!((Object)(object)val == (Object)null) && val.GetInventory() != null && !(Vector3.Distance(position, ((Component)val).transform.position) > range) && !val.IsInUse()) { list.Add(val); } } return list; } } public static class InputBlocker { internal static SearchUI SearchUI; public static bool IsBlocked() { if ((Object)(object)SearchUI != (Object)null) { return SearchUI.IsVisible; } return false; } } [HarmonyPatch(typeof(Player), "TakeInput")] public static class PlayerTakeInputPatch { private static void Postfix(ref bool __result) { if (InputBlocker.IsBlocked()) { __result = false; } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] public static class TextInputVisiblePatch { private static void Postfix(ref bool __result) { if (InputBlocker.IsBlocked()) { __result = true; } } } [HarmonyPatch(typeof(ZInput), "GetMouseDelta")] public static class MouseDeltaPatch { private static void Postfix(ref Vector2 __result) { //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) if (InputBlocker.IsBlocked()) { __result = Vector2.zero; } } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] public static class ZInputScrollPatch { private static void Postfix(ref float __result) { if (InputBlocker.IsBlocked()) { __result = 0f; } } } [BepInPlugin("com.channel2newsteam.chestsearch", "ChestSearch", "1.0.6")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.channel2newsteam.chestsearch"; public const string PluginName = "ChestSearch"; public const string PluginVersion = "1.0.6"; public static Plugin Instance; public static ConfigEntry<KeyboardShortcut> SearchHotkey; public static ConfigEntry<float> TakeRange; public static ConfigEntry<int> BuildPullVKey; public static ConfigEntry<float> TidyRange; public static ConfigEntry<float> WindowX; public static ConfigEntry<float> WindowY; private SearchUI searchUI; private Harmony harmony; private const int VK_ESCAPE = 27; private const int VK_F3 = 114; private bool wasHotkeyDown; private bool wasEscapeDown; public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); private static bool IsOSKeyDown(int vKey) { return (GetAsyncKeyState(vKey) & 0x8000) != 0; } private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown Instance = this; SearchHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SearchHotkey", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Hotkey to open the chest search window"); TakeRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TakeRange", 30f, "Maximum distance to remotely take items from containers (meters)"); BuildPullVKey = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BuildPullVKey", 90, "Windows virtual key code for auto-pull while building. Default: 0x5A (Z). Set to 0 to disable. Common: 0xA0=LShift, 0xA2=LCtrl, 0xA4=LAlt. See https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes"); TidyRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TidyRange", 15f, "Maximum distance for the Tidy feature to organize containers (meters)"); WindowX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowX", 20f, "Window X position"); WindowY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowY", 20f, "Window Y position"); harmony = new Harmony("com.channel2newsteam.chestsearch"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)"ChestSearch v1.0.6 loaded!"); } private void Update() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } bool flag = IsOSKeyDown(114); bool flag2 = IsOSKeyDown(27); bool num = flag && !wasHotkeyDown; bool flag3 = flag2 && !wasEscapeDown; wasHotkeyDown = flag; wasEscapeDown = flag2; bool flag4 = (Object)(object)searchUI != (Object)null && searchUI.IsVisible; if (num) { if ((Object)(object)searchUI == (Object)null) { GameObject val = new GameObject("ChestSearchUI"); Object.DontDestroyOnLoad((Object)(object)val); searchUI = val.AddComponent<SearchUI>(); } else { searchUI.Toggle(); } } else if (flag3 && flag4) { searchUI.Toggle(); } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } public class SearchUI : MonoBehaviour { private bool isVisible; private string searchText = ""; private string lastSearchText = ""; private List<SearchResult> results = new List<SearchResult>(); private Vector2 scrollPosition; private float searchCooldown; private int selectedIndex = -1; private string statusMessage = ""; private float statusTimer; private bool needsFocus; private float toggleCooldown; private Rect windowRect; private const int WindowID = 94317; private GUIStyle windowStyle; private GUIStyle headerStyle; private GUIStyle searchBoxStyle; private GUIStyle resultHeaderStyle; private GUIStyle resultHeaderInRangeStyle; private GUIStyle selectedHeaderStyle; private GUIStyle selectedHeaderInRangeStyle; private GUIStyle itemStyle; private GUIStyle pingButtonStyle; private GUIStyle takeButtonStyle; private GUIStyle closeButtonStyle; private GUIStyle hintStyle; private bool stylesInitialized; public bool IsVisible => isVisible; private void Start() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) InputBlocker.SearchUI = this; windowRect = new Rect(Plugin.WindowX.Value, Plugin.WindowY.Value, 420f, 500f); isVisible = true; Open(); } public void Toggle() { if (!(toggleCooldown > 0f)) { isVisible = !isVisible; toggleCooldown = 0.2f; if (isVisible) { Open(); } else { Close(); } } } private void Open() { searchText = ""; lastSearchText = ""; results.Clear(); selectedIndex = -1; GUIUtility.keyboardControl = 0; needsFocus = true; SetCursor(show: true); } private void Close() { isVisible = false; toggleCooldown = 0.2f; SetCursor(show: false); } private static void SetCursor(bool show) { Cursor.lockState = (CursorLockMode)((!show) ? 1 : 0); Cursor.visible = show; } private void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (toggleCooldown > 0f) { toggleCooldown -= Time.deltaTime; } if (!isVisible) { return; } if ((int)Cursor.lockState != 0) { SetCursor(show: true); } if (statusTimer > 0f) { statusTimer -= Time.deltaTime; } if (searchText != lastSearchText) { searchCooldown = 0.25f; lastSearchText = searchText; } if (searchCooldown > 0f) { searchCooldown -= Time.deltaTime; if (searchCooldown <= 0f) { PerformSearch(); } } } private void PerformSearch() { if (searchText.Length >= 2) { results = ContainerSearcher.Search(searchText); selectedIndex = ((results.Count <= 0) ? (-1) : 0); } else { results.Clear(); selectedIndex = -1; } } private void InitStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0031: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0076: 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) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00b7: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0204: Expected O, but got Unknown //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Expected O, but got Unknown //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Expected O, but got Unknown //IL_030d: Unknown result type (might be due to invalid IL or missing references) if (!stylesInitialized) { windowStyle = new GUIStyle(GUI.skin.window) { padding = new RectOffset(10, 10, 20, 10) }; headerStyle = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; headerStyle.normal.textColor = new Color(1f, 0.85f, 0.4f); searchBoxStyle = new GUIStyle(GUI.skin.textField) { fontSize = 16, fixedHeight = 30f, padding = new RectOffset(8, 8, 4, 4) }; resultHeaderStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; resultHeaderStyle.normal.textColor = new Color(0.6f, 0.9f, 1f); resultHeaderInRangeStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; resultHeaderInRangeStyle.normal.textColor = new Color(0.4f, 1f, 0.4f); selectedHeaderStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; selectedHeaderStyle.normal.textColor = new Color(1f, 0.95f, 0.5f); selectedHeaderInRangeStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; selectedHeaderInRangeStyle.normal.textColor = new Color(0.6f, 1f, 0.3f); itemStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, padding = new RectOffset(15, 0, 0, 0) }; itemStyle.normal.textColor = new Color(0.9f, 0.9f, 0.9f); pingButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 11, fixedWidth = 50f, fixedHeight = 20f }; takeButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 11, fixedWidth = 50f, fixedHeight = 18f }; closeButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 14, fontStyle = (FontStyle)1, fixedWidth = 24f, fixedHeight = 24f }; hintStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, fontStyle = (FontStyle)2, alignment = (TextAnchor)4 }; hintStyle.normal.textColor = new Color(0.85f, 0.85f, 0.7f); stylesInitialized = true; } } private void OnGUI() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Invalid comparison between Unknown and I4 //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Invalid comparison between Unknown and I4 if (!isVisible || (Object)(object)Player.m_localPlayer == (Object)null) { return; } InitStyles(); if ((int)Event.current.type == 4 && results.Count > 0) { if ((int)Event.current.keyCode == 274) { selectedIndex = Mathf.Min(selectedIndex + 1, results.Count - 1); ScrollToSelected(); Event.current.Use(); } else if ((int)Event.current.keyCode == 273) { selectedIndex = Mathf.Max(selectedIndex - 1, 0); ScrollToSelected(); Event.current.Use(); } else if ((int)Event.current.keyCode == 13 || (int)Event.current.keyCode == 271) { if (selectedIndex >= 0 && selectedIndex < results.Count) { ContainerSearcher.PingContainer(results[selectedIndex].Container); Event.current.Use(); } } else if ((int)Event.current.keyCode == 9 && selectedIndex >= 0 && selectedIndex < results.Count) { SearchResult searchResult = results[selectedIndex]; float value = Plugin.TakeRange.Value; if (searchResult.Distance <= value) { int num = 0; foreach (ItemMatch item in searchResult.Items) { num += ContainerSearcher.TakeItems(searchResult.Container, item.ItemKey, value); } if (num > 0) { SetStatus($"Took {num} items from {searchResult.ContainerName}"); PerformSearch(); } else { SetStatus("Inventory full"); } } else { SetStatus($"Too far ({searchResult.Distance:F0}m, need {value:F0}m)"); } Event.current.Use(); } } GUI.depth = 0; windowRect = GUI.Window(94317, windowRect, new WindowFunction(DrawWindow), "", windowStyle); ((Rect)(ref windowRect)).x = Mathf.Clamp(((Rect)(ref windowRect)).x, 0f, (float)Screen.width - ((Rect)(ref windowRect)).width); ((Rect)(ref windowRect)).y = Mathf.Clamp(((Rect)(ref windowRect)).y, 0f, (float)Screen.height - ((Rect)(ref windowRect)).height); if (!Input.GetMouseButton(0) && (((Rect)(ref windowRect)).x != Plugin.WindowX.Value || ((Rect)(ref windowRect)).y != Plugin.WindowY.Value)) { Plugin.WindowX.Value = ((Rect)(ref windowRect)).x; Plugin.WindowY.Value = ((Rect)(ref windowRect)).y; } } private void DrawWindow(int id) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: 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_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect(10f, 4f, ((Rect)(ref windowRect)).width - 50f, 30f), "Chest Search", headerStyle); if (GUI.Button(new Rect(((Rect)(ref windowRect)).width - 34f, 4f, 24f, 24f), "X", closeButtonStyle)) { Close(); return; } GUILayout.Space(35f); GUI.SetNextControlName("ChestSearchField"); searchText = GUILayout.TextField(searchText, searchBoxStyle, Array.Empty<GUILayoutOption>()); if (needsFocus) { GUI.FocusControl("ChestSearchField"); needsFocus = false; } GUILayout.Space(5f); if (searchText.Length < 2) { GUILayout.Label("Type at least 2 characters to search...", hintStyle, Array.Empty<GUILayoutOption>()); } else if (results.Count == 0) { GUILayout.Label("No containers found with \"" + searchText + "\"", hintStyle, Array.Empty<GUILayoutOption>()); } else { int num = 0; float value = Plugin.TakeRange.Value; int num2 = 0; foreach (SearchResult result in results) { foreach (ItemMatch item in result.Items) { num += item.Stack; } if (result.Distance <= value) { num2++; } } GUILayout.Label($"{num} items across {results.Count} containers ({num2} in take range)", hintStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(3f); scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>()); for (int i = 0; i < results.Count; i++) { SearchResult searchResult = results[i]; bool num3 = i == selectedIndex; if (num3) { Rect rect = GUILayoutUtility.GetRect(0f, 0f); ((Rect)(ref rect)).height = 20 + searchResult.Items.Count * 18 + 6; GUI.Box(rect, GUIContent.none); } float value2 = Plugin.TakeRange.Value; bool flag = searchResult.Distance <= value2; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUIStyle val = ((!num3) ? (flag ? resultHeaderInRangeStyle : resultHeaderStyle) : (flag ? selectedHeaderInRangeStyle : selectedHeaderStyle)); GUILayout.Label($"{searchResult.ContainerName} ({searchResult.Distance:F0}m)", val, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("Ping", pingButtonStyle, Array.Empty<GUILayoutOption>())) { ContainerSearcher.PingContainer(searchResult.Container); } GUILayout.EndHorizontal(); foreach (ItemMatch item2 in searchResult.Items) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label($" {item2.Name}{item2.QualityText} x{item2.Stack}", itemStyle, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (flag && GUILayout.Button("Take", takeButtonStyle, Array.Empty<GUILayoutOption>())) { int num4 = ContainerSearcher.TakeItems(searchResult.Container, item2.ItemKey, value2); if (num4 > 0) { SetStatus($"Took {num4}x {item2.Name}"); PerformSearch(); } else { SetStatus("Inventory full"); } } GUILayout.EndHorizontal(); } GUILayout.Space(6f); } GUILayout.EndScrollView(); } GUILayout.Space(5f); if (GUILayout.Button($"Tidy Nearby Containers ({Plugin.TidyRange.Value:F0}m)", Array.Empty<GUILayoutOption>())) { string status = ContainerTidy.Tidy(Plugin.TidyRange.Value); SetStatus(status); if (searchText.Length >= 2) { PerformSearch(); } } if (statusTimer > 0f) { GUILayout.Space(3f); GUILayout.Label(statusMessage, hintStyle, Array.Empty<GUILayoutOption>()); } GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width - 40f, 30f)); } private void ScrollToSelected() { if (selectedIndex < 0 || selectedIndex >= results.Count) { return; } float num = 0f; float num2 = 0f; for (int i = 0; i < results.Count; i++) { float num3 = 24 + results[i].Items.Count * 22 + 10; if (i < selectedIndex) { num2 += num3; } if (i == selectedIndex) { num = num3; } } float num4 = ((Rect)(ref windowRect)).height - 180f; float num5 = 30f; if (num2 < scrollPosition.y) { scrollPosition.y = num2; } else if (num2 + num + num5 > scrollPosition.y + num4) { scrollPosition.y = num2 + num + num5 - num4; } } private void SetStatus(string msg) { statusMessage = msg; statusTimer = 3f; } }