Decompiled source of Auto Sort v1.0.1

Auto_Sort/Auto_Sort.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Auto_Sort")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b201f657ed69b6627a0439a9fc53032a31dde385")]
[assembly: AssemblyProduct("Auto_Sort")]
[assembly: AssemblyTitle("Auto_Sort")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Ocewen.AutoSort
{
	public enum SortMode
	{
		SlotThenLevel,
		LevelThenName,
		Name,
		Value
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<SortMode> SortMode { get; private set; }

		internal static ConfigEntry<bool> SortCosmeticSlots { get; private set; }

		internal static ConfigEntry<bool> ConsolidateStacks { get; private set; }

		internal static ConfigEntry<float> ButtonX { get; private set; }

		internal static ConfigEntry<float> ButtonY { get; private set; }

		internal static ConfigEntry<float> ButtonWidth { get; private set; }

		internal static ConfigEntry<float> ButtonHeight { get; private set; }

		internal static ConfigEntry<float> BorderSize { get; private set; }

		internal static ConfigEntry<string> BorderColor { get; private set; }

		internal static ConfigEntry<string> BgColor { get; private set; }

		internal static ConfigEntry<float> FontSize { get; private set; }

		internal static ConfigEntry<string> FontColor { get; private set; }

		internal static ConfigEntry<float> Padding { get; private set; }

		internal static ConfigEntry<string> ButtonLabel { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			SortMode = config.Bind<SortMode>("General", "SortMode", Ocewen.AutoSort.SortMode.SlotThenLevel, "SlotThenLevel, LevelThenName, Name, or Value");
			SortCosmeticSlots = config.Bind<bool>("General", "SortCosmeticSlots", false, "Include cosmetic slots (green-bordered) in the sort");
			ConsolidateStacks = config.Bind<bool>("General", "ConsolidateStacks", true, "Merge duplicate stacks of the same item before sorting");
			ButtonX = config.Bind<float>("Button", "ButtonX", -220f, "Horizontal offset from the right edge of the bag panel");
			ButtonY = config.Bind<float>("Button", "ButtonY", 26f, "Vertical offset from the top of the bag panel (negative = lower)");
			ButtonWidth = config.Bind<float>("Button", "ButtonWidth", 60f, "Button width in pixels");
			ButtonHeight = config.Bind<float>("Button", "ButtonHeight", 25f, "Button height in pixels");
			BorderSize = config.Bind<float>("Button", "BorderSize", 2.5f, "Border thickness in pixels (0 = no border)");
			BorderColor = config.Bind<string>("Button", "BorderColor", "#2B5867", "Border color (hex)");
			BgColor = config.Bind<string>("Button", "BgColor", "#141213", "Button background color (hex)");
			FontSize = config.Bind<float>("Button", "FontSize", 16f, "Label font size");
			FontColor = config.Bind<string>("Button", "FontColor", "#FFFFFF", "Label font color (hex)");
			Padding = config.Bind<float>("Button", "Padding", 0f, "Inner padding between text and button edge in pixels");
			ButtonLabel = config.Bind<string>("Button", "ButtonLabel", "Sort", "Text shown on the button (arrows are added automatically)");
			ButtonX.SettingChanged += delegate
			{
				UpdatePosition();
			};
			ButtonY.SettingChanged += delegate
			{
				UpdatePosition();
			};
			ButtonWidth.SettingChanged += delegate
			{
				UpdateSize();
			};
			ButtonHeight.SettingChanged += delegate
			{
				UpdateSize();
			};
			BorderSize.SettingChanged += delegate
			{
				UpdateBorderSize();
			};
			BorderColor.SettingChanged += delegate
			{
				UpdateBorderColor();
			};
			BgColor.SettingChanged += delegate
			{
				UpdateBgColor();
			};
			FontSize.SettingChanged += delegate
			{
				UpdateFont();
			};
			FontColor.SettingChanged += delegate
			{
				UpdateFont();
			};
			Padding.SettingChanged += delegate
			{
				UpdatePadding();
			};
			ButtonLabel.SettingChanged += delegate
			{
				UpdateLabel();
			};
		}

		internal static Color ParseColor(string hex, Color fallback)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			if (ColorUtility.TryParseHtmlString(hex, ref result))
			{
				return result;
			}
			return fallback;
		}

		private static void UpdatePosition()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SortButton.OuterRect != (Object)null)
			{
				SortButton.OuterRect.anchoredPosition = new Vector2(ButtonX.Value, ButtonY.Value);
			}
		}

		private static void UpdateSize()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SortButton.OuterRect != (Object)null)
			{
				SortButton.OuterRect.sizeDelta = new Vector2(ButtonWidth.Value, ButtonHeight.Value);
			}
		}

		private static void UpdateBorderSize()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SortButton.InnerRect == (Object)null))
			{
				float value = BorderSize.Value;
				SortButton.InnerRect.offsetMin = new Vector2(value, value);
				SortButton.InnerRect.offsetMax = new Vector2(0f - value, 0f - value);
			}
		}

		private static void UpdateBorderColor()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SortButton.BorderImage != (Object)null)
			{
				((Graphic)SortButton.BorderImage).color = ParseColor(BorderColor.Value, new Color(0.17f, 0.35f, 0.4f));
			}
		}

		private static void UpdateBgColor()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SortButton.BgImage != (Object)null)
			{
				((Graphic)SortButton.BgImage).color = ParseColor(BgColor.Value, new Color(0.08f, 0.07f, 0.07f));
			}
		}

		private static void UpdateFont()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SortButton.Label == (Object)null))
			{
				((TMP_Text)SortButton.Label).fontSize = FontSize.Value;
				((Graphic)SortButton.Label).color = ParseColor(FontColor.Value, Color.white);
			}
		}

		private static void UpdatePadding()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SortButton.LabelRect == (Object)null))
			{
				float value = Padding.Value;
				SortButton.LabelRect.offsetMin = new Vector2(value, value);
				SortButton.LabelRect.offsetMax = new Vector2(0f - value, 0f - value);
			}
		}

		private static void UpdateLabel()
		{
			if (!((Object)(object)SortButton.Label == (Object)null))
			{
				bool flag = ((TMP_Text)SortButton.Label).text.StartsWith("^");
				((TMP_Text)SortButton.Label).text = (flag ? "^ " : "v ") + ButtonLabel.Value;
			}
		}
	}
	[BepInPlugin("Ocewen.Auto_Sort", "Auto Sort", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("Ocewen.Auto_Sort");
			_harmony.PatchAll();
			Inventory playerInv = GameData.PlayerInv;
			if ((Object)(object)playerInv != (Object)null)
			{
				SortManager.ResetDirection();
				SortButton.Create(playerInv);
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Auto Sort 1.0.1 loaded.");
		}

		private void OnDestroy()
		{
			SortButton.Destroy();
			Inventory playerInv = GameData.PlayerInv;
			if ((Object)(object)playerInv != (Object)null)
			{
				List<ItemIcon> storedSlots = playerInv.StoredSlots;
				if (storedSlots != null && storedSlots.Count > 0)
				{
					Transform val = ((Component)playerInv.StoredSlots[0]).transform.parent.parent.Find("AutoSortButton");
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
				if ((Object)(object)playerInv.InvWindow != (Object)null)
				{
					Transform val2 = playerInv.InvWindow.transform.Find("AutoSortButton");
					if ((Object)(object)val2 != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val2).gameObject);
					}
				}
			}
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchAll("Ocewen.Auto_Sort");
			}
		}
	}
	internal static class SortButton
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__24_0;

			internal void <Create>b__24_0()
			{
				SortManager.Sort();
			}
		}

		internal static TextMeshProUGUI? Label { get; private set; }

		internal static Image? BorderImage { get; private set; }

		internal static Image? BgImage { get; private set; }

		internal static RectTransform? OuterRect { get; private set; }

		internal static RectTransform? InnerRect { get; private set; }

		internal static RectTransform? LabelRect { get; private set; }

		internal static void Create(Inventory inv)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			if (inv.StoredSlots.Count == 0)
			{
				return;
			}
			Transform parent = ((Component)inv.StoredSlots[0]).transform.parent.parent;
			if ((Object)(object)parent.Find("AutoSortButton") != (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("AutoSortButton");
			val.transform.SetParent(parent, false);
			BorderImage = val.AddComponent<Image>();
			((Graphic)BorderImage).color = ModConfig.ParseColor(ModConfig.BorderColor.Value, new Color(0.3f, 0.42f, 0.6f));
			Button obj = val.AddComponent<Button>();
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1.3f, 1.3f, 1.3f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.7f, 0.7f, 0.7f, 1f);
			((Selectable)obj).colors = colors;
			((Selectable)obj).targetGraphic = (Graphic)(object)BorderImage;
			ButtonClickedEvent onClick = obj.onClick;
			object obj2 = <>c.<>9__24_0;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					SortManager.Sort();
				};
				<>c.<>9__24_0 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			OuterRect = val.GetComponent<RectTransform>();
			OuterRect.anchorMin = new Vector2(1f, 1f);
			OuterRect.anchorMax = new Vector2(1f, 1f);
			OuterRect.pivot = new Vector2(0f, 1f);
			OuterRect.sizeDelta = new Vector2(ModConfig.ButtonWidth.Value, ModConfig.ButtonHeight.Value);
			OuterRect.anchoredPosition = new Vector2(ModConfig.ButtonX.Value, ModConfig.ButtonY.Value);
			GameObject val3 = new GameObject("BG");
			val3.transform.SetParent(val.transform, false);
			BgImage = val3.AddComponent<Image>();
			((Graphic)BgImage).color = ModConfig.ParseColor(ModConfig.BgColor.Value, new Color(0.05f, 0.09f, 0.16f));
			float value = ModConfig.BorderSize.Value;
			InnerRect = val3.GetComponent<RectTransform>();
			InnerRect.anchorMin = Vector2.zero;
			InnerRect.anchorMax = Vector2.one;
			InnerRect.offsetMin = new Vector2(value, value);
			InnerRect.offsetMax = new Vector2(0f - value, 0f - value);
			GameObject val4 = new GameObject("Label");
			val4.transform.SetParent(val.transform, false);
			Label = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)Label).text = "^ " + ModConfig.ButtonLabel.Value;
			((TMP_Text)Label).fontSize = ModConfig.FontSize.Value;
			((Graphic)Label).color = ModConfig.ParseColor(ModConfig.FontColor.Value, Color.white);
			((TMP_Text)Label).alignment = (TextAlignmentOptions)514;
			float value2 = ModConfig.Padding.Value;
			LabelRect = val4.GetComponent<RectTransform>();
			LabelRect.anchorMin = Vector2.zero;
			LabelRect.anchorMax = Vector2.one;
			LabelRect.offsetMin = new Vector2(value2, value2);
			LabelRect.offsetMax = new Vector2(0f - value2, 0f - value2);
		}

		internal static void Destroy()
		{
			Label = null;
			BorderImage = null;
			BgImage = null;
			OuterRect = null;
			InnerRect = null;
			LabelRect = null;
		}
	}
	internal static class SortManager
	{
		private static bool _ascending;

		internal static void ResetDirection()
		{
			_ascending = false;
		}

		internal static void Sort()
		{
			Inventory inv = GameData.PlayerInv;
			if ((Object)(object)inv == (Object)null || !inv.InvWindow.activeSelf || GameData.VendorWindowOpen || GameData.Trading || ((Object)(object)GameData.ItemOnCursor?.MyItem != (Object)null && (Object)(object)GameData.ItemOnCursor.MyItem != (Object)(object)inv.Empty))
			{
				return;
			}
			List<ItemIcon> cosmetic = inv.CosmeticSlots;
			List<ItemIcon> list = (ModConfig.SortCosmeticSlots.Value ? inv.StoredSlots : inv.StoredSlots.Where((ItemIcon s) => !cosmetic.Contains(s)).ToList());
			List<(Item, int)> list2 = (from s in list
				where (Object)(object)s.MyItem != (Object)null && (Object)(object)s.MyItem != (Object)(object)inv.Empty
				select (MyItem: s.MyItem, Quantity: s.Quantity)).ToList();
			if (ModConfig.ConsolidateStacks.Value)
			{
				list2 = (from x in list2
					group x by x.MyItem).SelectMany((IGrouping<Item, (Item MyItem, int Quantity)> g) => g.Key.Stackable ? ((IEnumerable<(Item, int)>)new(Item, int)[1] { (g.Key, g.Sum(((Item MyItem, int Quantity) x) => x.Quantity)) }) : ((IEnumerable<(Item, int)>)g.ToArray())).ToList();
			}
			list2.Sort(Compare);
			_ascending = !_ascending;
			if (!_ascending)
			{
				list2.Reverse();
			}
			for (int num = 0; num < list.Count; num++)
			{
				if (num < list2.Count)
				{
					list[num].MyItem = list2[num].Item1;
					list[num].Quantity = list2[num].Item2;
				}
				else
				{
					list[num].MyItem = inv.Empty;
					list[num].Quantity = 0;
				}
				list[num].UpdateSlotImage();
			}
			inv.UpdatePlayerInventory();
			if ((Object)(object)SortButton.Label != (Object)null)
			{
				((TMP_Text)SortButton.Label).text = (_ascending ? "^ " : "v ") + ModConfig.ButtonLabel.Value;
			}
		}

		private static int Compare((Item item, int qty) a, (Item item, int qty) b)
		{
			return ModConfig.SortMode.Value switch
			{
				SortMode.LevelThenName => (CompareLevel(a.item, b.item) != 0) ? CompareLevel(a.item, b.item) : string.Compare(a.item.ItemName, b.item.ItemName), 
				SortMode.Name => string.Compare(a.item.ItemName, b.item.ItemName), 
				SortMode.Value => b.item.ItemValue.CompareTo(a.item.ItemValue), 
				_ => CompareSlotThenLevel(a.item, b.item), 
			};
		}

		private static int CompareLevel(Item a, Item b)
		{
			return b.ItemLevel.CompareTo(a.ItemLevel);
		}

		private static int CompareSlotThenLevel(Item a, Item b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected I4, but got Unknown
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			int num = ((int)a.RequiredSlot).CompareTo((int)b.RequiredSlot);
			if (num != 0)
			{
				return num;
			}
			return CompareLevel(a, b);
		}
	}
}
namespace Ocewen.AutoSort.Patches
{
	[HarmonyPatch(typeof(Inventory), "Start")]
	internal static class Inventory_Start_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(Inventory __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)GameData.PlayerInv))
			{
				SortButton.Create(__instance);
			}
		}
	}
}