Decompiled source of SortFromGround v1.0.0

plugins\TeflonTed.Common.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TeflonTed.Common")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Shared helpers for Teflon Ted's Valheim mods")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+aa3557958a7656958068f9c07e5ebb364e91eab7")]
[assembly: AssemblyProduct("TeflonTed.Common")]
[assembly: AssemblyTitle("TeflonTed.Common")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 TeflonTed.Common
{
	public static class NearbyContainers
	{
		public static List<Container> Find(Vector3 center, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Find(center, radius, includeAllIncinerators: false);
		}

		public static List<Container> FindNearAny(IEnumerable<Vector3> centers, float radius)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			if (centers == null)
			{
				return list;
			}
			foreach (Vector3 center in centers)
			{
				foreach (Container item in Find(center, radius))
				{
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static List<Container> Find(Vector3 center, float radius, bool includeAllIncinerators)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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)
			List<Container> result = new List<Container>();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return result;
			}
			long playerId = localPlayer.GetPlayerID();
			float radiusSq = radius * radius;
			Collider[] array = Physics.OverlapSphere(center, Mathf.Max(radius, 0f), LayerMask.GetMask(new string[1] { "piece" }));
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Container val2 = ((Component)val).GetComponentInParent<Container>();
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = ((Component)val).GetComponentInChildren<Container>();
					}
					TryAdd(val2);
					Incinerator componentInParent = ((Component)val).GetComponentInParent<Incinerator>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						TryAdd(componentInParent.m_container);
					}
				}
			}
			if (includeAllIncinerators)
			{
				Incinerator[] array2 = Object.FindObjectsByType<Incinerator>((FindObjectsSortMode)0);
				foreach (Incinerator val3 in array2)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						TryAdd(val3.m_container);
					}
				}
			}
			return result;
			void TryAdd(Container container)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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_004f: 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)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)container == (Object)null) && !result.Contains(container))
				{
					Vector3 val4 = ((Component)container).transform.position - center;
					if (((Vector3)(ref val4)).sqrMagnitude > radiusSq)
					{
						val4 = ((Component)container).transform.root.position - center;
						if (((Vector3)(ref val4)).sqrMagnitude > radiusSq)
						{
							return;
						}
					}
					ZNetView val5 = ((Component)container).GetComponent<ZNetView>() ?? ((Component)container).GetComponentInParent<ZNetView>();
					if (!((Object)(object)val5 == (Object)null) && val5.IsValid() && container.GetInventory() != null && container.CheckAccess(playerId) && (!container.m_checkGuardStone || PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)))
					{
						result.Add(container);
					}
				}
			}
		}

		public static int CountItem(IEnumerable<Container> containers, string sharedName, int quality = -1)
		{
			int num = 0;
			foreach (Container container in containers)
			{
				Inventory inventory = container.GetInventory();
				if (inventory != null)
				{
					num += inventory.CountItems(sharedName, quality, true);
				}
			}
			return num;
		}

		public static int TakeItem(IEnumerable<Container> containers, string sharedName, int amount, int quality = -1)
		{
			if (amount <= 0)
			{
				return 0;
			}
			int num = 0;
			int num2 = amount;
			foreach (Container container in containers)
			{
				if (num2 <= 0)
				{
					break;
				}
				Inventory inventory = container.GetInventory();
				if (inventory != null)
				{
					int num3 = inventory.CountItems(sharedName, quality, true);
					if (num3 > 0)
					{
						int num4 = Mathf.Min(num3, num2);
						inventory.RemoveItem(sharedName, num4, quality, true);
						container.Save();
						num += num4;
						num2 -= num4;
					}
				}
			}
			return num;
		}

		public static int DepositMatching(Container container, Inventory playerInv, ItemData item)
		{
			if ((Object)(object)container == (Object)null || playerInv == null || item?.m_shared == null || item.m_stack <= 0)
			{
				return 0;
			}
			int num = DepositMatching(container, item);
			if (num > 0 && item.m_stack <= 0)
			{
				playerInv.RemoveItem(item);
			}
			return num;
		}

		public static int DepositMatchingFromDrop(Container container, ItemDrop drop)
		{
			if ((Object)(object)container == (Object)null || drop?.m_itemData?.m_shared == null || drop.m_itemData.m_stack <= 0)
			{
				return 0;
			}
			int num = DepositMatching(container, drop.m_itemData);
			if (num <= 0)
			{
				return 0;
			}
			if (drop.m_itemData.m_stack <= 0)
			{
				NearbyItemDrops.Destroy(drop);
			}
			else
			{
				drop.Save();
			}
			return num;
		}

		public static int DepositMatching(Container container, ItemData item)
		{
			if ((Object)(object)container == (Object)null || item?.m_shared == null || item.m_stack <= 0)
			{
				return 0;
			}
			Inventory inventory = container.GetInventory();
			if (inventory == null)
			{
				return 0;
			}
			if (!inventory.HaveItem(item.m_shared.m_name, true))
			{
				return 0;
			}
			int num = 0;
			while (item.m_stack > 0)
			{
				ItemData val = item.Clone();
				val.m_stack = 1;
				if (!inventory.CanAddItem(val, -1) || !inventory.AddItem(val))
				{
					break;
				}
				item.m_stack--;
				num++;
			}
			if (num > 0)
			{
				container.Save();
			}
			return num;
		}
	}
	public static class NearbyItemDrops
	{
		public static List<ItemDrop> Find(Vector3 center, float radius)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			List<ItemDrop> list = new List<ItemDrop>();
			Collider[] array = Physics.OverlapSphere(center, Mathf.Max(radius, 0f), LayerMask.GetMask(new string[1] { "item" }));
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				ItemDrop val2 = null;
				if ((Object)(object)val.attachedRigidbody != (Object)null)
				{
					val2 = ((Component)val.attachedRigidbody).GetComponent<ItemDrop>();
				}
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)val).GetComponentInParent<ItemDrop>();
				}
				if (!((Object)(object)val2 == (Object)null))
				{
					ZNetView component = ((Component)val2).GetComponent<ZNetView>();
					if (!((Object)(object)component == (Object)null) && component.IsValid() && val2.m_itemData != null && val2.m_itemData.m_shared != null && !list.Contains(val2))
					{
						list.Add(val2);
					}
				}
			}
			return list;
		}

		public static List<ItemDrop> FindNearAny(IEnumerable<Vector3> centers, float radius)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			List<ItemDrop> list = new List<ItemDrop>();
			if (centers == null)
			{
				return list;
			}
			foreach (Vector3 center in centers)
			{
				foreach (ItemDrop item in Find(center, radius))
				{
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static string PrefabName(Component component)
		{
			return SmelterFuel.PrefabName(((Object)component.gameObject).name);
		}

		public static void Destroy(ItemDrop drop)
		{
			if (!((Object)(object)drop == (Object)null))
			{
				ZNetView component = ((Component)drop).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.Destroy();
				}
				else if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					ZNetScene.instance.Destroy(((Component)drop).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)drop).gameObject);
				}
			}
		}
	}
	public static class Radii
	{
		public const float Workstation = 20f;

		public const float FuelAdjacency = 4f;
	}
	public static class SmelterFuel
	{
		private static readonly FieldRef<Smelter, int> MaxFuel = AccessTools.FieldRefAccess<Smelter, int>("m_maxFuel");

		private static readonly FieldRef<Smelter, int> MaxOre = AccessTools.FieldRefAccess<Smelter, int>("m_maxOre");

		private static readonly MethodInfo GetFuelMethod = AccessTools.Method(typeof(Smelter), "GetFuel", (Type[])null, (Type[])null);

		private static readonly MethodInfo GetQueueSizeMethod = AccessTools.Method(typeof(Smelter), "GetQueueSize", (Type[])null, (Type[])null);

		private static readonly MethodInfo IsItemAllowedMethod = AccessTools.Method(typeof(Smelter), "IsItemAllowed", new Type[1] { typeof(string) }, (Type[])null);

		private static readonly HashSet<string> PremiumWoodPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "FineWood", "RoundLog", "ElderBark", "YggdrasilWood", "Blackwood", "AshWood" };

		private static readonly HashSet<string> PremiumWoodShared = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "$item_finewood", "$item_roundlog", "$item_elderbark", "$item_yggdrasilwood", "$item_blackwood", "$item_ashwood" };

		public static List<Vector3> IntakePositions(Smelter smelter)
		{
			List<Vector3> points = new List<Vector3>(4);
			if ((Object)(object)smelter == (Object)null)
			{
				return points;
			}
			Add(((Object)(object)smelter.m_addOreSwitch != (Object)null) ? ((Component)smelter.m_addOreSwitch).transform : null);
			Add(((Object)(object)smelter.m_addWoodSwitch != (Object)null) ? ((Component)smelter.m_addWoodSwitch).transform : null);
			if ((Object)(object)smelter.m_windmill != (Object)null)
			{
				Add(((Component)smelter.m_windmill).transform);
			}
			Add(((Component)smelter).transform);
			return points;
			void Add(Transform t)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: 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_0027: 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)
				if (!((Object)(object)t == (Object)null))
				{
					Vector3 position = t.position;
					for (int i = 0; i < points.Count; i++)
					{
						Vector3 val = points[i] - position;
						if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
						{
							return;
						}
					}
					points.Add(position);
				}
			}
		}

		public static Vector3 IntakePosition(Smelter smelter)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = IntakePositions(smelter);
			if (list.Count <= 0)
			{
				return Vector3.zero;
			}
			return list[0];
		}

		public static int FuelRoom(Smelter smelter)
		{
			if ((Object)(object)smelter == (Object)null || (Object)(object)smelter.m_nview == (Object)null || !smelter.m_nview.IsValid())
			{
				return 0;
			}
			if ((Object)(object)smelter.m_fuelItem == (Object)null)
			{
				return 0;
			}
			float num = ((GetFuelMethod != null) ? ((float)GetFuelMethod.Invoke(smelter, null)) : smelter.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f));
			return Mathf.Max(0, MaxFuel.Invoke(smelter) - Mathf.CeilToInt(num));
		}

		public static int OreRoom(Smelter smelter)
		{
			if ((Object)(object)smelter == (Object)null || (Object)(object)smelter.m_nview == (Object)null || !smelter.m_nview.IsValid())
			{
				return 0;
			}
			int num = ((GetQueueSizeMethod != null) ? ((int)GetQueueSizeMethod.Invoke(smelter, null)) : 0);
			return Mathf.Max(0, MaxOre.Invoke(smelter) - num);
		}

		public static void AddOneFuel(Smelter smelter)
		{
			if (!((Object)(object)smelter?.m_nview == (Object)null) && smelter.m_nview.IsValid())
			{
				smelter.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
			}
		}

		public static void AddOneOre(Smelter smelter, string prefabName, bool cheated = false)
		{
			if (!((Object)(object)smelter?.m_nview == (Object)null) && smelter.m_nview.IsValid() && !string.IsNullOrEmpty(prefabName))
			{
				smelter.m_nview.InvokeRPC("RPC_AddOre", new object[2] { prefabName, cheated });
			}
		}

		public static bool IsFuelItem(Smelter smelter, string sharedName)
		{
			if ((Object)(object)smelter?.m_fuelItem != (Object)null && smelter.m_fuelItem.m_itemData != null && smelter.m_fuelItem.m_itemData.m_shared != null)
			{
				return smelter.m_fuelItem.m_itemData.m_shared.m_name == sharedName;
			}
			return false;
		}

		public static bool IsFuelItem(Smelter smelter, ItemData item)
		{
			if (item?.m_shared != null)
			{
				return IsFuelItem(smelter, item.m_shared.m_name);
			}
			return false;
		}

		public static bool IsPremiumWood(string prefabName, string sharedName = null)
		{
			if (!string.IsNullOrEmpty(prefabName) && PremiumWoodPrefabs.Contains(PrefabName(prefabName) ?? prefabName))
			{
				return true;
			}
			if (!string.IsNullOrEmpty(sharedName))
			{
				return PremiumWoodShared.Contains(sharedName);
			}
			return false;
		}

		public static bool IsPremiumWood(ItemData item)
		{
			if (item?.m_shared == null)
			{
				return false;
			}
			return IsPremiumWood(PrefabName(item), item.m_shared.m_name);
		}

		public static bool IsOreItem(Smelter smelter, ItemData item)
		{
			if (IsPremiumWood(item))
			{
				return false;
			}
			string text = PrefabName(item);
			if ((Object)(object)smelter == (Object)null || string.IsNullOrEmpty(text) || IsItemAllowedMethod == null)
			{
				return false;
			}
			return (bool)IsItemAllowedMethod.Invoke(smelter, new object[1] { text });
		}

		public static string PrefabName(ItemData item)
		{
			if ((Object)(object)item?.m_dropPrefab == (Object)null)
			{
				return null;
			}
			return PrefabName(((Object)item.m_dropPrefab).name);
		}

		public static string PrefabName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			int num = name.IndexOfAny(new char[2] { '(', ' ' });
			if (num < 0)
			{
				return name;
			}
			return name.Substring(0, num);
		}

		public static bool TryAcceptItem(Smelter smelter, ItemData item)
		{
			if ((Object)(object)smelter == (Object)null || item?.m_shared == null)
			{
				return false;
			}
			if (IsPremiumWood(item))
			{
				return false;
			}
			if (IsFuelItem(smelter, item) && FuelRoom(smelter) > 0)
			{
				AddOneFuel(smelter);
				return true;
			}
			if (IsOreItem(smelter, item) && OreRoom(smelter) > 0)
			{
				string text = PrefabName(item);
				if (string.IsNullOrEmpty(text))
				{
					return false;
				}
				AddOneOre(smelter, text, item.m_cheated);
				return true;
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins\TeflonTed.SortFromGround.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TeflonTed.Common;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("TeflonTed.SortFromGround")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Teflon Ted's Sort From Ground — ground drops suck into nearby chests that already hold that item")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+aa3557958a7656958068f9c07e5ebb364e91eab7")]
[assembly: AssemblyProduct("TeflonTed.SortFromGround")]
[assembly: AssemblyTitle("TeflonTed.SortFromGround")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 TeflonTed.SortFromGround
{
	[BepInPlugin("com.teflonted.valheim.sortfromground", "Teflon Ted's Sort From Ground", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.teflonted.valheim.sortfromground";

		public const string PluginName = "Teflon Ted's Sort From Ground";

		public const string PluginVersion = "1.0.0";

		private void Awake()
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.teflonted.valheim.sortfromground");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Teflon Ted's Sort From Ground 1.0.0 loaded");
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "SlowUpdate")]
	internal static class ItemDrop_SlowUpdate_Patch
	{
		private const double SettleSeconds = 1.0;

		private static readonly Dictionary<int, float> LastTry = new Dictionary<int, float>();

		private static void Postfix(ItemDrop __instance, ZNetView ___m_nview)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || !___m_nview.IsOwner() || (Object)(object)Player.m_localPlayer == (Object)null || __instance.m_itemData?.m_shared == null || __instance.m_itemData.m_stack <= 0 || __instance.IsPiece() || __instance.GetTimeSinceSpawned() < 1.0)
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (LastTry.TryGetValue(instanceID, out var value) && Time.time - value < 0.5f)
			{
				return;
			}
			LastTry[instanceID] = Time.time;
			List<Container> list = NearbyContainers.Find(((Component)__instance).transform.position, 4f);
			if (list.Count == 0)
			{
				return;
			}
			foreach (Container item in list)
			{
				if ((Object)(object)__instance == (Object)null || __instance.m_itemData == null || __instance.m_itemData.m_stack <= 0)
				{
					break;
				}
				NearbyContainers.DepositMatchingFromDrop(item, __instance);
			}
			if (LastTry.Count > 64)
			{
				LastTry.Clear();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}