Decompiled source of SortStackHeavy v0.1.0

plugins/SortStackHeavy/SortStackHeavy.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Blackforge.Hot;
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: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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 Blackforge
{
	public static class Sort
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__ByWeight;

			public static UnityAction <1>__StackHeavy;
		}

		private const string Name = "bf_sort";

		private const string HeavyName = "bf_stack_heavy";

		private const float Light = 100f;

		private static HotHost host;

		private static GameObject button;

		private static GameObject heavy;

		public static void Load(HotHost from)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			host = from;
			host.Harmony.Patch((MethodBase)AccessTools.Method(typeof(InventoryGui), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Sort), "Tick", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void Unload()
		{
			if ((Object)(object)button != (Object)null)
			{
				Object.Destroy((Object)(object)button);
			}
			button = null;
			if ((Object)(object)heavy != (Object)null)
			{
				Object.Destroy((Object)(object)heavy);
			}
			heavy = null;
			host = null;
		}

		private static void Tick(InventoryGui __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0056: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			if (host == null || !InventoryGui.IsVisible() || (Object)(object)__instance.m_takeAllButton == (Object)null)
			{
				return;
			}
			if ((Object)(object)button == (Object)null)
			{
				RectTransform player = __instance.m_player;
				object obj = <>O.<0>__ByWeight;
				if (obj == null)
				{
					UnityAction val = ByWeight;
					<>O.<0>__ByWeight = val;
					obj = (object)val;
				}
				button = Make(__instance, player, "bf_sort", "Sort", (UnityAction)obj, new Vector2(32f, 5f));
			}
			if ((Object)(object)heavy == (Object)null && (Object)(object)__instance.m_container != (Object)null)
			{
				RectTransform container = __instance.m_container;
				object obj2 = <>O.<1>__StackHeavy;
				if (obj2 == null)
				{
					UnityAction val2 = StackHeavy;
					<>O.<1>__StackHeavy = val2;
					obj2 = (object)val2;
				}
				heavy = Make(__instance, container, "bf_stack_heavy", "Stack heavy", (UnityAction)obj2, new Vector2(32f, 138f));
			}
		}

		private static GameObject Make(InventoryGui gui, RectTransform panel, string name, string text, UnityAction pressed, Vector2 at)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00a5: 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
			GameObject obj = Object.Instantiate<GameObject>(((Component)gui.m_takeAllButton).gameObject, (Transform)(object)panel);
			((Object)obj).name = name;
			UIGamePad component = obj.GetComponent<UIGamePad>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Transform val = obj.transform.Find("gamepad_hint");
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
			RectTransform val2 = (RectTransform)obj.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(1f, 0f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = at;
			val2.sizeDelta = new Vector2(80f, 34f);
			TMP_Text componentInChildren = obj.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
				componentInChildren.enableAutoSizing = true;
				componentInChildren.fontSizeMin = 8f;
				componentInChildren.fontSizeMax = 18f;
			}
			Button component2 = obj.GetComponent<Button>();
			component2.onClick = new ButtonClickedEvent();
			((UnityEvent)component2.onClick).AddListener(pressed);
			obj.SetActive(true);
			return obj;
		}

		private static void ByWeight()
		{
			//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)
			Player localPlayer = Player.m_localPlayer;
			InventoryGui instance = InventoryGui.instance;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)instance == (Object)null) && instance.m_dragItem == null)
			{
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				int width = inventory.GetWidth();
				int rows = Math.Min(inventory.GetHeight(), BackpackRows(inventory.GetHeight()));
				int num = Join(inventory, rows);
				List<ItemData> list = (from item in inventory.GetAllItems()
					where item.m_gridPos.y >= 1 && item.m_gridPos.y < rows
					orderby item.GetWeight(-1) descending, item.m_shared.m_name, item.m_quality descending
					select item).ToList();
				for (int num2 = 0; num2 < list.Count; num2++)
				{
					list[num2].m_gridPos = new Vector2i(num2 % width, 1 + num2 / width);
				}
				inventory.Changed(false, false);
				host.Log.LogInfo((object)$"sort: {list.Count} stacks by weight in rows 1 to {rows - 1} of {inventory.GetHeight()}, {num} stacks went into others");
			}
		}

		private static int Join(Inventory inventory, int rows)
		{
			int num = 0;
			List<ItemData> list = (from item in inventory.GetAllItems()
				where item.m_gridPos.y >= 1 && item.m_gridPos.y < rows && item.m_shared.m_maxStackSize > 1
				orderby item.m_equipped descending, item.m_stack descending
				select item).ToList();
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				ItemData val = list[num2];
				int num3 = list.Count - 1;
				while (num3 > num2 && val.m_stack < val.m_shared.m_maxStackSize)
				{
					ItemData val2 = list[num3];
					if (!val2.m_equipped && Same(val, val2))
					{
						int num4 = Math.Min(val2.m_stack, val.m_shared.m_maxStackSize - val.m_stack);
						val.m_stack += num4;
						val2.m_stack -= num4;
						if (val2.m_stack == 0)
						{
							inventory.RemoveItem(val2);
							list.RemoveAt(num3);
							num++;
						}
					}
					num3--;
				}
			}
			return num;
		}

		private static bool Same(ItemData one, ItemData other)
		{
			string value;
			if (one.m_shared.m_name == other.m_shared.m_name && one.m_quality == other.m_quality && one.m_worldLevel == other.m_worldLevel && one.m_customData.Count == other.m_customData.Count)
			{
				return one.m_customData.All((KeyValuePair<string, string> pair) => other.m_customData.TryGetValue(pair.Key, out value) && value == pair.Value);
			}
			return false;
		}

		private static void StackHeavy()
		{
			Player localPlayer = Player.m_localPlayer;
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null || instance.m_dragItem != null || (Object)(object)instance.m_currentContainer == (Object)null || ((Character)localPlayer).IsTeleporting())
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			Inventory inventory2 = instance.m_currentContainer.GetInventory();
			int rows = Math.Min(inventory.GetHeight(), BackpackRows(inventory.GetHeight()));
			List<ItemData> list = (from item in inventory.GetAllItems()
				where item.m_gridPos.y >= 1 && item.m_gridPos.y < rows && !item.m_equipped
				orderby item.GetWeight(-1) descending
				select item).ToList();
			float totalWeight = inventory.GetTotalWeight();
			int num = 0;
			foreach (ItemData item in list)
			{
				if (inventory.GetTotalWeight() < 100f)
				{
					break;
				}
				float weight = item.GetWeight(-1);
				inventory2.MoveItemToThis(inventory, item);
				if (!inventory.ContainsItem(item) || item.GetWeight(-1) < weight)
				{
					num++;
				}
			}
			host.Log.LogInfo((object)$"sort: stack heavy put {num} of {list.Count} stacks into the chest, the player carries {inventory.GetTotalWeight():0.#} after {totalWeight:0.#}");
		}

		private static int BackpackRows(int all)
		{
			try
			{
				MethodInfo methodInfo = (from mod in AppDomain.CurrentDomain.GetAssemblies()
					select mod.GetType("ExtraSlots.API")).FirstOrDefault((Type found) => found != null)?.GetMethod("GetInventoryHeightPlayer", BindingFlags.Static | BindingFlags.Public);
				if (methodInfo != null && methodInfo.Invoke(null, null) is int num && num > 1)
				{
					return num;
				}
			}
			catch (Exception ex)
			{
				host.Log.LogWarning((object)("sort: Extra Slots did not say its rows, nothing is sorted: " + ex.Message));
				return 0;
			}
			return all;
		}
	}
	[BepInPlugin("vladasz.sortstackheavy", "Sort and Stack Heavy", "0.1.0")]
	public class SortStackHeavyPlugin : BaseUnityPlugin
	{
		public const string Id = "vladasz.sortstackheavy";

		public const string Number = "0.1.0";

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			HotHost hotHost = new HotHost(((BaseUnityPlugin)this).Logger, new Harmony("vladasz.sortstackheavy"), "0.1.0");
			if (!hotHost.IsDedicatedServer)
			{
				Sort.Load(hotHost);
			}
		}
	}
}
namespace Blackforge.Hot
{
	public sealed class HotHost
	{
		public ManualLogSource Log { get; }

		public Harmony Harmony { get; }

		public string Version { get; }

		public bool IsDedicatedServer => (int)SystemInfo.graphicsDeviceType == 4;

		internal HotHost(ManualLogSource log, Harmony harmony, string version)
		{
			Log = log;
			Harmony = harmony;
			Version = version;
		}

		public byte[] ReadAsset(string relative)
		{
			return File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(typeof(HotHost).Assembly.Location), relative));
		}

		public void UnregisterRpc(IEnumerable<string> names)
		{
			if (ZRoutedRpc.instance == null)
			{
				return;
			}
			foreach (string name in names)
			{
				ZRoutedRpc.instance.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name));
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}