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);
}
}
}
}