Decompiled source of AutoFillFires v1.3.0

AutoFillFires.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("AutoFillFires")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AutoFillFires")]
[assembly: AssemblyTitle("AutoFillFires")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CartQuickStack
{
	[BepInPlugin("yourname.cartquickstack", "CartQuickStack", "1.0.0")]
	public class CartQuickStackPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "yourname.cartquickstack";

		public const string PluginName = "CartQuickStack";

		public const string PluginVersion = "1.0.0";

		private static readonly MethodInfo ContainerSave = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private ConfigEntry<KeyboardShortcut> _hotkey;

		private ConfigEntry<float> _cartRange;

		private ConfigEntry<float> _chestRange;

		private ConfigEntry<bool> _onlyMatchingChests;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Hotkey", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Key combo to empty the nearest cart into nearby chests.");
			_cartRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CartRange", 8f, "How far (meters) to look for a cart to empty.");
			_chestRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChestRange", 20f, "How far (meters) to look for chests to deposit into.");
			_onlyMatchingChests = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyMatchingChests", true, "If true, only deposit an item into chests that already contain that item (like your period-key sort). If false, leftovers spill into any chest with room.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CartQuickStack v1.0.0 loaded.");
		}

		private void Update()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()))
			{
				KeyboardShortcut value = _hotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					DumpCart(localPlayer);
				}
			}
		}

		private void DumpCart(Player player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			Vagon val = null;
			float num = float.MaxValue;
			Vagon[] array = Object.FindObjectsOfType<Vagon>();
			foreach (Vagon val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					float num2 = Vector3.Distance(position, ((Component)val2).transform.position);
					if (!(num2 > _cartRange.Value) && num2 < num)
					{
						num = num2;
						val = val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				((Character)player).Message((MessageType)2, $"No cart found within {_cartRange.Value:0}m", 0, (Sprite)null);
				return;
			}
			Container componentInChildren = ((Component)val).GetComponentInChildren<Container>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				((Character)player).Message((MessageType)2, "Couldn't read that cart's inventory", 0, (Sprite)null);
				return;
			}
			Inventory inventory = componentInChildren.GetInventory();
			if (inventory == null)
			{
				return;
			}
			ZNetView component = ((Component)componentInChildren).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			component.ClaimOwnership();
			List<Container> list = new List<Container>();
			Container[] array2 = Object.FindObjectsOfType<Container>();
			foreach (Container val3 in array2)
			{
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)componentInChildren) && !((Object)(object)((Component)val3).GetComponentInParent<Vagon>() != (Object)null) && !(Vector3.Distance(position, ((Component)val3).transform.position) > _chestRange.Value))
				{
					ZNetView component2 = ((Component)val3).GetComponent<ZNetView>();
					if (!((Object)(object)component2 == (Object)null) && component2.IsValid() && val3.GetInventory() != null)
					{
						list.Add(val3);
					}
				}
			}
			int num3 = 0;
			HashSet<Container> hashSet = new HashSet<Container>();
			List<ItemData> list2 = new List<ItemData>(inventory.GetAllItems());
			foreach (ItemData item in list2)
			{
				if (item == null || item.m_stack <= 0)
				{
					continue;
				}
				string name = item.m_shared.m_name;
				foreach (Container item2 in list)
				{
					if (item.m_stack <= 0)
					{
						break;
					}
					Inventory inventory2 = item2.GetInventory();
					if (inventory2 != null && ChestHasItem(inventory2, name))
					{
						int num4 = MoveInto(inventory, item, item2, inventory2);
						if (num4 > 0)
						{
							num3 += num4;
							hashSet.Add(item2);
						}
					}
				}
				if (_onlyMatchingChests.Value || item.m_stack <= 0)
				{
					continue;
				}
				foreach (Container item3 in list)
				{
					if (item.m_stack <= 0)
					{
						break;
					}
					Inventory inventory3 = item3.GetInventory();
					if (inventory3 != null)
					{
						int num5 = MoveInto(inventory, item, item3, inventory3);
						if (num5 > 0)
						{
							num3 += num5;
							hashSet.Add(item3);
						}
					}
				}
			}
			if (num3 > 0)
			{
				ContainerSave?.Invoke(componentInChildren, null);
				foreach (Container item4 in hashSet)
				{
					ContainerSave?.Invoke(item4, null);
				}
			}
			string text = ((num3 > 0) ? $"Emptied cart: moved {num3} item(s) into {hashSet.Count} chest(s)" : "Nothing moved (cart empty, or no matching chests with room nearby)");
			((Character)player).Message((MessageType)2, text, 0, (Sprite)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)text);
		}

		private static int ChestCapacityFor(Inventory inv, ItemData like)
		{
			int num = Mathf.Max(1, like.m_shared.m_maxStackSize);
			int num2 = 0;
			List<ItemData> allItems = inv.GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item != null && item.m_shared.m_name == like.m_shared.m_name)
				{
					num2 += Mathf.Max(0, num - item.m_stack);
				}
			}
			int num3 = inv.GetWidth() * inv.GetHeight() - allItems.Count;
			if (num3 > 0)
			{
				num2 += num3 * num;
			}
			return num2;
		}

		private static bool ChestHasItem(Inventory inv, string name)
		{
			foreach (ItemData allItem in inv.GetAllItems())
			{
				if (allItem != null && allItem.m_shared.m_name == name)
				{
					return true;
				}
			}
			return false;
		}

		private int MoveInto(Inventory cartInv, ItemData item, Container chest, Inventory chestInv)
		{
			int num = ChestCapacityFor(chestInv, item);
			int num2 = Mathf.Min(item.m_stack, num);
			if (num2 <= 0)
			{
				return 0;
			}
			ZNetView component = ((Component)chest).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return 0;
			}
			component.ClaimOwnership();
			ItemData val = item.Clone();
			val.m_stack = num2;
			if (!chestInv.AddItem(val))
			{
				return 0;
			}
			cartInv.RemoveItem(item, num2);
			return num2;
		}
	}
}
namespace AutoFillFires
{
	[BepInPlugin("yourname.autofillfires", "AutoFillFires", "1.3.0")]
	public class AutoFillFiresPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "yourname.autofillfires";

		public const string PluginName = "AutoFillFires";

		public const string PluginVersion = "1.3.0";

		private static readonly MethodInfo ContainerSave = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private ConfigEntry<KeyboardShortcut> _hotkey;

		private ConfigEntry<float> _range;

		private ConfigEntry<bool> _pullFromChests;

		private ConfigEntry<float> _chestRange;

		private ConfigEntry<bool> _autoFill;

		private ConfigEntry<float> _autoInterval;

		private ConfigEntry<bool> _autoUsesInventory;

		private ConfigEntry<bool> _autoNotify;

		private float _autoTimer;

		private void Awake()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			_hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Hotkey", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "Key for an instant manual fill (uses your inventory AND nearby chests). Set to None if you only want automatic filling.");
			_range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range", 30f, "Radius in meters around you to search for fires and torches.");
			_pullFromChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Chests", "PullFromChests", true, "Allow pulling fuel from nearby chests (applies to manual and automatic).");
			_chestRange = ((BaseUnityPlugin)this).Config.Bind<float>("Chests", "ChestRange", 20f, "How far (meters) to look for chests to pull fuel from.");
			_autoFill = ((BaseUnityPlugin)this).Config.Bind<bool>("Automatic", "AutoFill", true, "Automatically top up nearby fires on a timer, pulling from nearby chests.");
			_autoInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Automatic", "IntervalSeconds", 10f, "How often (seconds) the automatic fill runs.");
			_autoUsesInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("Automatic", "AutoAlsoUsesInventory", false, "If true, automatic filling also drains fuel you're carrying. Left false so auto-fill only uses chests and never touches your pockets.");
			_autoNotify = ((BaseUnityPlugin)this).Config.Bind<bool>("Automatic", "ShowNotifications", false, "If true, show an on-screen message when automatic filling tops up fires.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"AutoFillFires v1.3.0 loaded.");
		}

		private void Update()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (!Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()))
			{
				KeyboardShortcut value = _hotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					FillNearbyFires(localPlayer, useInventory: true, announceFilled: true, announceIdle: true);
				}
			}
			if (_autoFill.Value)
			{
				_autoTimer += Time.deltaTime;
				if (_autoTimer >= _autoInterval.Value)
				{
					_autoTimer = 0f;
					FillNearbyFires(localPlayer, _autoUsesInventory.Value, _autoNotify.Value, announceIdle: false);
				}
			}
		}

		private void FillNearbyFires(Player player, bool useInventory, bool announceFilled, bool announceIdle)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)player).transform.position;
			Inventory inventory = ((Humanoid)player).GetInventory();
			float value = _range.Value;
			List<Container> list = new List<Container>();
			if (_pullFromChests.Value)
			{
				Container[] array = Object.FindObjectsOfType<Container>();
				foreach (Container val in array)
				{
					if (!((Object)(object)val == (Object)null) && !(Vector3.Distance(position, ((Component)val).transform.position) > _chestRange.Value))
					{
						ZNetView component = ((Component)val).GetComponent<ZNetView>();
						if (!((Object)(object)component == (Object)null) && component.IsValid() && val.GetInventory() != null)
						{
							list.Add(val);
						}
					}
				}
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Fireplace[] array2 = Object.FindObjectsOfType<Fireplace>();
			foreach (Fireplace val2 in array2)
			{
				if ((Object)(object)val2 == (Object)null || Vector3.Distance(position, ((Component)val2).transform.position) > value)
				{
					continue;
				}
				num++;
				if (val2.m_infiniteFuel)
				{
					continue;
				}
				ItemDrop fuelItem = val2.m_fuelItem;
				if ((Object)(object)fuelItem == (Object)null)
				{
					continue;
				}
				ZNetView component2 = ((Component)val2).GetComponent<ZNetView>();
				if ((Object)(object)component2 == (Object)null || !component2.IsValid())
				{
					continue;
				}
				string name = fuelItem.m_itemData.m_shared.m_name;
				component2.ClaimOwnership();
				ZDO zDO = component2.GetZDO();
				float num4 = zDO.GetFloat("fuel", 0f);
				int num5 = (int)(val2.m_maxFuel - Mathf.Ceil(num4));
				if (num5 <= 0)
				{
					continue;
				}
				int num6 = 0;
				if (useInventory)
				{
					int num7 = Mathf.Min(num5, inventory.CountItems(name, -1, true));
					if (num7 > 0)
					{
						inventory.RemoveItem(name, num7, -1, true);
						num6 += num7;
					}
				}
				if (_pullFromChests.Value)
				{
					foreach (Container item in list)
					{
						if (num6 >= num5)
						{
							break;
						}
						try
						{
							Inventory inventory2 = item.GetInventory();
							if (inventory2 == null)
							{
								continue;
							}
							int num8 = inventory2.CountItems(name, -1, true);
							if (num8 > 0)
							{
								int num9 = Mathf.Min(num5 - num6, num8);
								ZNetView component3 = ((Component)item).GetComponent<ZNetView>();
								if (!((Object)(object)component3 == (Object)null) && component3.IsValid())
								{
									component3.ClaimOwnership();
									inventory2.RemoveItem(name, num9, -1, true);
									ContainerSave?.Invoke(item, null);
									num6 += num9;
								}
							}
						}
						catch
						{
						}
					}
				}
				if (num6 > 0)
				{
					zDO.Set("fuel", num4 + (float)num6);
					num2++;
					num3 += num6;
				}
			}
			if (num2 > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Filled {num2} fire(s) with {num3} fuel");
				if (announceFilled)
				{
					((Character)player).Message((MessageType)2, $"Filled {num2} fire(s) with {num3} fuel", 0, (Sprite)null);
				}
			}
			else if (announceIdle)
			{
				string text = ((num > 0) ? ($"Found {num} fire(s) nearby, but none needed fuel " + "(already full, or no matching materials on hand)") : $"No fires found within {value:0}m");
				((Character)player).Message((MessageType)2, text, 0, (Sprite)null);
			}
		}
	}
}