Decompiled source of AutoSortChests v1.0.1

AutoSortChests.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.Logging;
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: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 AutoSortChests
{
	[BepInPlugin("com.michal.valheim.autosortchests", "Auto Sort Chests", "1.0.1")]
	public class AutoSortChestsPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		private static class InventoryGui_Awake_Patch
		{
			private static void Postfix(InventoryGui __instance)
			{
				try
				{
					AddSortButton(__instance);
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Failed to add sort button: {arg}");
				}
			}
		}

		public const string PluginGUID = "com.michal.valheim.autosortchests";

		public const string PluginName = "Auto Sort Chests";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		private static readonly FieldInfo CurrentContainerField = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Game.isModded = true;
			new Harmony("com.michal.valheim.autosortchests").PatchAll(typeof(AutoSortChestsPlugin).Assembly);
		}

		private static void AddSortButton(InventoryGui gui)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			Button stackAllButton = gui.m_stackAllButton;
			GameObject obj = Object.Instantiate<GameObject>(((Component)stackAllButton).gameObject, ((Component)stackAllButton).transform.parent);
			((Object)obj).name = "SortAll";
			obj.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 150.5f);
			Button component = obj.GetComponent<Button>();
			((UnityEventBase)component.onClick).RemoveAllListeners();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				SortCurrentContainer(gui);
			});
			TextMeshProUGUI componentInChildren = obj.GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)componentInChildren).text = "Sort";
			}
			foreach (Transform item in obj.transform)
			{
				Transform val = item;
				if (((Object)val).name.StartsWith("gamepad_hint"))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private static void SortCurrentContainer(InventoryGui gui)
		{
			object? value = CurrentContainerField.GetValue(gui);
			Container val = (Container)((value is Container) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"No open container, nothing to sort.");
				return;
			}
			Inventory inventory = val.GetInventory();
			if (inventory != null)
			{
				MergeStacks(inventory);
				ReorderByTypeAndName(inventory);
				inventory.m_onChanged?.Invoke();
				Log.LogInfo((object)("Sorted container '" + ((Object)val).name + "'."));
			}
		}

		private static void MergeStacks(Inventory inventory)
		{
			List<ItemData> allItems = inventory.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (val.m_stack >= val.m_shared.m_maxStackSize)
				{
					continue;
				}
				for (int num = allItems.Count - 1; num > i; num--)
				{
					ItemData val2 = allItems[num];
					if (val.IsSameType(val2))
					{
						int num2 = val.m_shared.m_maxStackSize - val.m_stack;
						if (num2 <= 0)
						{
							break;
						}
						int num3 = Mathf.Min(num2, val2.m_stack);
						val.m_stack += num3;
						val2.m_stack -= num3;
						if (val2.m_stack <= 0)
						{
							allItems.RemoveAt(num);
						}
					}
				}
			}
		}

		private static void ReorderByTypeAndName(Inventory inventory)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			List<ItemData> list = (from i in inventory.GetAllItems()
				orderby i.m_shared.m_itemType, i.m_shared.m_name
				select i).ToList();
			int width = inventory.GetWidth();
			for (int num = 0; num < list.Count; num++)
			{
				list[num].m_gridPos = new Vector2i(num % width, num / width);
			}
		}
	}
}