Decompiled source of AzuCraftyBoxes v1.2.9

AzuCraftyBoxes.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using AzuCraftyBoxes.APIs;
using AzuCraftyBoxes.Compatibility.WardIsLove;
using AzuCraftyBoxes.IContainers;
using AzuCraftyBoxes.Util.Functions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: AssemblyFileVersion("1.2.9")]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyProduct("AzuCraftyBoxes")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("AzuCraftyBoxes")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.9.0")]
[module: <00207709-c48a-41ac-b259-40ceef2e3b38>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<ae5abaf0-fdd0-41ce-a1a1-3b3ded62809c>Embedded]
	internal sealed class <ae5abaf0-fdd0-41ce-a1a1-3b3ded62809c>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<ae5abaf0-fdd0-41ce-a1a1-3b3ded62809c>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <a16f4ee7-5397-4398-af26-e6172c6d14b4>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <a16f4ee7-5397-4398-af26-e6172c6d14b4>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <a16f4ee7-5397-4398-af26-e6172c6d14b4>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<ae5abaf0-fdd0-41ce-a1a1-3b3ded62809c>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<ae5abaf0-fdd0-41ce-a1a1-3b3ded62809c>Embedded]
	[CompilerGenerated]
	internal sealed class <00207709-c48a-41ac-b259-40ceef2e3b38>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <00207709-c48a-41ac-b259-40ceef2e3b38>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AzuCraftyBoxes
{
	[BepInIncompatibility("CFCMod")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Azumatt.AzuCraftyBoxes", "AzuCraftyBoxes", "1.2.9")]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[BepInIncompatibility("aedenthorn.CraftFromContainers")]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public class AzuCraftyBoxesPlugin : BaseUnityPlugin
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)]
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)]
			[UsedImplicitly]
			public string Category;

			[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
		private class AcceptableShortcuts : AcceptableValueBase
		{
			public AcceptableShortcuts()
				: base(typeof(KeyboardShortcut))
			{
			}

			public override object Clamp(object value)
			{
				return value;
			}

			public override bool IsValid(object value)
			{
				return true;
			}

			public override string ToDescriptionString()
			{
				return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes);
			}
		}

		internal const string ModName = "AzuCraftyBoxes";

		internal const string ModVersion = "1.2.9";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.AzuCraftyBoxes";

		private static string ConfigFileName = "Azumatt.AzuCraftyBoxes.cfg";

		private static string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("Azumatt.AzuCraftyBoxes");

		public static readonly ManualLogSource AzuCraftyBoxesLogger;

		private static readonly ConfigSync ConfigSync;

		internal static bool skip;

		public static Vector3 lastPosition;

		public static List<AzuCraftyBoxes.IContainers.IContainer> cachedContainerList;

		internal static readonly string yamlFileName;

		internal static readonly string yamlPath;

		internal static readonly CustomSyncedValue<string> CraftyContainerData;

		internal static readonly CustomSyncedValue<string> CraftyContainerGroupsData;

		internal static Dictionary<string, object> yamlData;

		internal static Dictionary<string, HashSet<string>> groups;

		internal static Dictionary<string, bool> CanItemBePulledCache;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		internal static ConfigEntry<Toggle> ModEnabled;

		public static ConfigEntry<Color> flashColor;

		public static ConfigEntry<Color> unFlashColor;

		public static ConfigEntry<Color> canbuildDisplayColor;

		public static ConfigEntry<Color> cannotbuildDisplayColor;

		public static ConfigEntry<string> resourceString;

		public static ConfigEntry<string> pulledMessage;

		public static ConfigEntry<KeyboardShortcut> pullItemsKey;

		public static ConfigEntry<KeyboardShortcut> fillAllModKey;

		public static ConfigEntry<float> mRange;

		public void Awake()
		{
			//IL_0093: 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)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only.");
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			ModEnabled = config("1 - General", "Mod Enabled", Toggle.On, "If off, everything in the mod will not run. This is useful if you want to disable the mod without uninstalling it.");
			mRange = config("2 - CraftyBoxes", "Container Range", 20f, "The maximum range from which to pull items from.");
			resourceString = TextEntryConfig("2 - CraftyBoxes", "ResourceCostString", "{0}/{1}", "String used to show required and available resources. {0} is replaced by how much is available, and {1} is replaced by how much is required. Set to nothing to leave it as default.", synchronizedSetting: false);
			flashColor = config<Color>("2 - CraftyBoxes", "FlashColor", Color.yellow, "Resource amounts will flash to this colour when coming from containers", synchronizedSetting: false);
			unFlashColor = config<Color>("2 - CraftyBoxes", "UnFlashColor", Color.white, "Resource amounts will flash from this colour when coming from containers (set both colors to the same color for no flashing)", synchronizedSetting: false);
			canbuildDisplayColor = config<Color>("2 - CraftyBoxes", "Can Build Color", Color.green, "The color of the build panel's count of pieces you can build", synchronizedSetting: false);
			cannotbuildDisplayColor = config<Color>("2 - CraftyBoxes", "Cannot Build Color", Color.red, "The color of the build panel's count if you cannot build something", synchronizedSetting: false);
			pulledMessage = TextEntryConfig("2 - CraftyBoxes", "PulledMessage", "Pulled items to inventory", "Message to show after pulling items to player inventory", synchronizedSetting: false);
			fillAllModKey = config<KeyboardShortcut>("3 - Keys", "FillAllModKey", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), new ConfigDescription("Modifier key to pull all available fuel or ore when down. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html", (AcceptableValueBase)(object)new AcceptableShortcuts(), Array.Empty<object>()), synchronizedSetting: false);
			if (!File.Exists(yamlPath))
			{
				WriteConfigFileFromResource(yamlPath);
			}
			CraftyContainerData.ValueChanged += OnValChangedUpdate;
			CraftyContainerData.AssignLocalValue(File.ReadAllText(yamlPath));
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private static void WriteConfigFileFromResource(string configFilePath)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "AzuCraftyBoxes.Example.yml";
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				throw new FileNotFoundException("Resource '" + text + "' not found in the assembly.");
			}
			using StreamReader streamReader = new StreamReader(stream);
			string contents = streamReader.ReadToEnd();
			File.WriteAllText(configFilePath, contents);
		}

		private void Start()
		{
			AutoDoc();
		}

		private void LateUpdate()
		{
			skip = false;
		}

		private void AutoDoc()
		{
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
			FileSystemWatcher fileSystemWatcher2 = new FileSystemWatcher(Paths.ConfigPath, yamlFileName);
			fileSystemWatcher2.Changed += ReadYamlFiles;
			fileSystemWatcher2.Created += ReadYamlFiles;
			fileSystemWatcher2.Renamed += ReadYamlFiles;
			fileSystemWatcher2.IncludeSubdirectories = true;
			fileSystemWatcher2.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher2.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				AzuCraftyBoxesLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				AzuCraftyBoxesLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				AzuCraftyBoxesLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private void ReadYamlFiles(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(yamlPath))
			{
				return;
			}
			try
			{
				AzuCraftyBoxesLogger.LogDebug((object)"ReadConfigValues called");
				CraftyContainerData.AssignLocalValue(File.ReadAllText(yamlPath));
			}
			catch
			{
				AzuCraftyBoxesLogger.LogError((object)("There was an issue loading your " + yamlFileName));
				AzuCraftyBoxesLogger.LogError((object)"Please check your entries for spelling and format!");
			}
		}

		private static void OnValChangedUpdate()
		{
			AzuCraftyBoxesLogger.LogDebug((object)"OnValChanged called");
			try
			{
				YamlUtils.ReadYaml(CraftyContainerData.Value);
				YamlUtils.ParseGroups();
			}
			catch (Exception arg)
			{
				AzuCraftyBoxesLogger.LogError((object)$"Failed to deserialize {yamlFileName}: {arg}");
			}
		}

		private ConfigEntry<T> config<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		private ConfigEntry<T> config<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		internal ConfigEntry<T> TextEntryConfig<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)] T>(string group, string name, T value, string desc, bool synchronizedSetting = true)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
			{
				CustomDrawer = TextAreaDrawer
			};
			return config(group, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }), synchronizedSetting);
		}

		internal static void TextAreaDrawer(ConfigEntryBase entry)
		{
			GUILayout.ExpandHeight(true);
			GUILayout.ExpandWidth(true);
			entry.BoxedValue = GUILayout.TextArea((string)entry.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
		}

		static AzuCraftyBoxesPlugin()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			AzuCraftyBoxesLogger = Logger.CreateLogSource("AzuCraftyBoxes");
			ConfigSync = new ConfigSync("Azumatt.AzuCraftyBoxes")
			{
				DisplayName = "AzuCraftyBoxes",
				CurrentVersion = "1.2.9",
				MinimumRequiredVersion = "1.2.9"
			};
			lastPosition = Vector3.positiveInfinity;
			cachedContainerList = new List<AzuCraftyBoxes.IContainers.IContainer>();
			yamlFileName = "Azumatt.AzuCraftyBoxes.yml";
			string configPath2 = Paths.ConfigPath;
			directorySeparatorChar = Path.DirectorySeparatorChar;
			yamlPath = configPath2 + directorySeparatorChar + yamlFileName;
			CraftyContainerData = new CustomSyncedValue<string>(ConfigSync, "craftyboxesData", "");
			CraftyContainerGroupsData = new CustomSyncedValue<string>(ConfigSync, "craftyboxesGroupsData", "");
			CanItemBePulledCache = null;
			_serverConfigLocked = null;
			ModEnabled = null;
			flashColor = null;
			unFlashColor = null;
			canbuildDisplayColor = null;
			cannotbuildDisplayColor = null;
			resourceString = null;
			pulledMessage = null;
			pullItemsKey = null;
			fillAllModKey = null;
			mRange = null;
		}
	}
	public static class KeyboardExtensions
	{
		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("AzuCraftyBoxes_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_AzuCraftyBoxes_Version);
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogInfo((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("1.2.9");
			peer.m_rpc.Invoke("AzuCraftyBoxes_VersionCheck", new object[1] { val });
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "AzuCraftyBoxesRequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMin = 15f;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + AzuCraftyBoxesPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_AzuCraftyBoxes_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogInfo((object)("Version check, local: 1.2.9,  remote: " + text));
			if (text != "1.2.9")
			{
				AzuCraftyBoxesPlugin.ConnectionError = "AzuCraftyBoxes Installed: 1.2.9\n Needed: " + text;
				if (ZNet.instance.IsServer())
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}
	}
}
namespace AzuCraftyBoxes.Util
{
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public class Group
	{
		public static Dictionary<string, Group> PredefinedGroups = new Dictionary<string, Group>
		{
			{
				"Swords",
				new Group("Swords", new List<string> { "SwordBlackmetal", "SwordBronze" })
			},
			{
				"Armor",
				new Group("Armor", new List<string> { "ArmorBronzeChest", "ArmorBronzeLegs" })
			}
		};

		public string Name { get; set; }

		public List<string> Items { get; set; }

		public Group(string name, List<string> items)
		{
			Name = name;
			Items = items;
		}
	}
}
namespace AzuCraftyBoxes.Util.Functions
{
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public class Boxes
	{
		internal static readonly List<Container> Containers = new List<Container>();

		private static readonly List<Container> ContainersToAdd = new List<Container>();

		private static readonly List<Container> ContainersToRemove = new List<Container>();

		internal static void AddContainer(Container container)
		{
			if (!Containers.Contains(container))
			{
				ContainersToAdd.Add(container);
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("Added container " + ((Object)container).name + " to list"));
			}
			UpdateContainers();
		}

		internal static void RemoveContainer(Container container)
		{
			if (Containers.Contains(container))
			{
				ContainersToRemove.Add(container);
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("Removed container " + ((Object)container).name + " from list"));
			}
			UpdateContainers();
		}

		internal static void UpdateContainers()
		{
			foreach (Container item in ContainersToAdd)
			{
				Containers.Add(item);
			}
			ContainersToAdd.Clear();
			foreach (Container item2 in ContainersToRemove)
			{
				Containers.Remove(item2);
			}
			ContainersToRemove.Clear();
		}

		internal static List<AzuCraftyBoxes.IContainers.IContainer> GetNearbyContainers<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)] T>(T gameObject, float rangeToUse) where T : Component
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			List<AzuCraftyBoxes.IContainers.IContainer> list = new List<AzuCraftyBoxes.IContainers.IContainer>();
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return list;
			}
			IEnumerable<AzuCraftyBoxes.IContainers.IContainer> second = ItemDrawers_API.AllDrawersInRange(((Component)gameObject).transform.position, rangeToUse).Select(kgDrawer.Create);
			if (Vector3.Distance(((Component)gameObject).transform.position, AzuCraftyBoxesPlugin.lastPosition) < 0.5f)
			{
				return AzuCraftyBoxesPlugin.cachedContainerList.Concat(second).ToList();
			}
			foreach (Container container in Containers)
			{
				if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)container == (Object)null) && Vector3.Distance(((Component)container).transform.position, ((Component)gameObject).transform.position) <= rangeToUse && !container.IsInUse())
				{
					list.Add(VanillaContainer.Create(container));
				}
			}
			AzuCraftyBoxesPlugin.lastPosition = ((Component)gameObject).transform.position;
			AzuCraftyBoxesPlugin.cachedContainerList = list;
			return list.Concat(second).ToList();
		}

		public static void AddContainerIfNotExists(string containerName)
		{
			if (!AzuCraftyBoxesPlugin.yamlData.ContainsKey(containerName))
			{
				AzuCraftyBoxesPlugin.yamlData[containerName] = new Dictionary<string, object>
				{
					{
						"exclude",
						new List<string>()
					},
					{
						"includeOverride",
						new List<string>()
					}
				};
				YamlUtils.WriteYaml(AzuCraftyBoxesPlugin.yamlPath);
			}
		}

		public static Dictionary<string, List<string>> GetExcludedPrefabsForAllContainers()
		{
			Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
			foreach (string allContainer in GetAllContainers())
			{
				dictionary[allContainer] = GetExcludedPrefabs(allContainer);
			}
			return dictionary;
		}

		public static List<string> GetAllContainers()
		{
			return AzuCraftyBoxesPlugin.yamlData.Keys.Where([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (string key) => key != "groups").ToList();
		}

		public static bool CanItemBePulled(string container, string prefab)
		{
			if (AzuCraftyBoxesPlugin.yamlData == null)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)"yamlData is null. Make sure to call DeserializeYamlFile() before using CanItemBePulled.");
				return false;
			}
			if (!AzuCraftyBoxesPlugin.yamlData.ContainsKey(container))
			{
				return true;
			}
			if (!(AzuCraftyBoxesPlugin.yamlData[container] is Dictionary<object, object> dictionary))
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)("Unable to cast containerData for container '" + container + "' to Dictionary<object, object>."));
				return false;
			}
			object value;
			List<object> list = (dictionary.TryGetValue("exclude", out value) ? (value as List<object>) : new List<object>());
			object value2;
			List<object> list2 = (dictionary.TryGetValue("includeOverride", out value2) ? (value2 as List<object>) : new List<object>());
			if (list == null)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)("Unable to cast excludeList for container '" + container + "' to List<object>."));
				return false;
			}
			if (list2 == null)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)("Unable to cast includeOverrideList for container '" + container + "' to List<object>."));
				return false;
			}
			if (list2.Contains(prefab))
			{
				return true;
			}
			foreach (object item in list)
			{
				if (prefab.Equals(item))
				{
					return false;
				}
				if (GroupUtils.IsGroupDefined((string)item) && GroupUtils.GetItemsInGroup((string)item).Contains(prefab))
				{
					return false;
				}
			}
			return true;
		}

		internal static bool IsPrefabExcluded(string prefab, List<object> exclusionList)
		{
			if (exclusionList != null)
			{
				foreach (object exclusion in exclusionList)
				{
					string text = exclusion.ToString();
					if (AzuCraftyBoxesPlugin.groups.TryGetValue(text, out var value))
					{
						if (value.Contains(prefab))
						{
							return true;
						}
					}
					else if (text == prefab)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static List<string> GetExcludedPrefabs(string container)
		{
			if (AzuCraftyBoxesPlugin.yamlData.TryGetValue(container, out var value) && value is Dictionary<object, object> dictionary && dictionary.TryGetValue("exclude", out var value2) && value2 is List<object> list)
			{
				List<string> list2 = new List<string>();
				{
					foreach (object item in list)
					{
						string text = item.ToString();
						if (AzuCraftyBoxesPlugin.groups.TryGetValue(text, out var value3))
						{
							list2.AddRange(value3);
						}
						else
						{
							list2.Add(text);
						}
					}
					return list2;
				}
			}
			return new List<string>();
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public static class YamlUtils
	{
		internal static void ReadYaml(string yamlInput)
		{
			AzuCraftyBoxesPlugin.yamlData = new DeserializerBuilder().Build().Deserialize<Dictionary<string, object>>(yamlInput);
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("yamlData:\n" + yamlInput));
		}

		internal static void ParseGroups()
		{
			if (AzuCraftyBoxesPlugin.groups == null)
			{
				AzuCraftyBoxesPlugin.groups = new Dictionary<string, HashSet<string>>();
			}
			if (!AzuCraftyBoxesPlugin.yamlData.TryGetValue("groups", out var value) || !(value is Dictionary<object, object> dictionary))
			{
				return;
			}
			foreach (KeyValuePair<object, object> item in dictionary)
			{
				string key = item.Key.ToString();
				if (!(item.Value is List<object> list))
				{
					continue;
				}
				HashSet<string> hashSet = new HashSet<string>();
				foreach (object item2 in list)
				{
					hashSet.Add(item2.ToString());
				}
				AzuCraftyBoxesPlugin.groups[key] = hashSet;
			}
		}

		public static void WriteYaml(string filePath)
		{
			ISerializer serializer = new SerializerBuilder().Build();
			using StreamWriter writer = new StreamWriter(filePath);
			serializer.Serialize(writer, AzuCraftyBoxesPlugin.yamlData);
			string contents = serializer.Serialize(AzuCraftyBoxesPlugin.yamlData);
			File.AppendAllText(filePath, contents);
		}
	}
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public class GroupUtils
	{
		public static List<string> GetExcludedGroups(string container)
		{
			if (AzuCraftyBoxesPlugin.yamlData.TryGetValue(container, out var value) && value is Dictionary<object, object> dictionary && dictionary.TryGetValue("exclude", out var value2) && value2 is List<object> source)
			{
				return (from excludeItem in source
					where AzuCraftyBoxesPlugin.groups.ContainsKey(excludeItem.ToString())
					select excludeItem.ToString()).ToList();
			}
			return new List<string>();
		}

		public static bool IsGroupDefined(string groupName)
		{
			if (AzuCraftyBoxesPlugin.yamlData == null)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)"yamlData is null. Make sure to call DeserializeYamlFile() before using IsGroupDefined.");
				return false;
			}
			bool flag = false;
			if (AzuCraftyBoxesPlugin.yamlData.ContainsKey("groups"))
			{
				if (AzuCraftyBoxesPlugin.yamlData["groups"] is Dictionary<object, object> dictionary)
				{
					flag = dictionary.ContainsKey(groupName);
				}
				else
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)"Unable to cast groupsData to Dictionary<object, object>.");
				}
			}
			if (!flag)
			{
				return AzuCraftyBoxesPlugin.groups.ContainsKey(groupName);
			}
			return true;
		}

		public static bool GroupExists(string groupName)
		{
			return AzuCraftyBoxesPlugin.groups.ContainsKey(groupName);
		}

		public static List<string> GetAllGroups()
		{
			return AzuCraftyBoxesPlugin.groups.Keys.ToList();
		}

		public static List<string> GetItemsInGroup(string groupName)
		{
			if (AzuCraftyBoxesPlugin.groups.TryGetValue(groupName, out var value))
			{
				return value.ToList();
			}
			return new List<string>();
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public class MiscFunctions
	{
		internal static bool AllowByKey()
		{
			return true;
		}

		internal static void ProcessRequirements(Requirement[] requirements, int qualityLevel, Inventory pInventory, List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers, int itemQuality)
		{
			foreach (Requirement val in requirements)
			{
				if (!IsValidRequirement(val))
				{
					continue;
				}
				int amount = val.GetAmount(qualityLevel);
				if (amount > 0)
				{
					string name = ((Object)val.m_resItem).name;
					string name2 = val.m_resItem.m_itemData.m_shared.m_name;
					int num = pInventory.CountItems(name2, -1, true);
					LogResourceInfo(num, amount, name2);
					pInventory.RemoveItem(name2, Math.Min(num, amount), itemQuality, true);
					if (num < amount && ConsumeResourcesFromContainers(name, name2, num, amount, nearbyContainers) >= amount)
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("(ConsumeResourcesPatch) Consumed enough " + name2));
					}
				}
			}
		}

		private static bool IsValidRequirement(Requirement requirement)
		{
			if (Object.op_Implicit((Object)(object)requirement.m_resItem))
			{
				ItemData itemData = requirement.m_resItem.m_itemData;
				if (itemData != null)
				{
					return itemData.m_shared != null;
				}
				return false;
			}
			return false;
		}

		private static void LogResourceInfo(int totalAmount, int totalRequirement, string reqName)
		{
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(ConsumeResourcesPatch) Have {totalAmount}/{totalRequirement} {reqName} in player inventory");
		}

		private static int ConsumeResourcesFromContainers(string reqPrefab, string reqName, int totalAmount, int totalRequirement, List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers)
		{
			int num = totalAmount;
			foreach (AzuCraftyBoxes.IContainers.IContainer nearbyContainer in nearbyContainers)
			{
				num = nearbyContainer.ProcessContainerInventory(reqPrefab, reqName, num, totalRequirement);
				if (num >= totalRequirement)
				{
					break;
				}
			}
			return num;
		}

		public static string GetPrefabName(string name)
		{
			char[] anyOf = new char[2] { '(', ' ' };
			int num = name.IndexOfAny(anyOf);
			if (num >= 0)
			{
				return name.Substring(0, num);
			}
			return name;
		}

		[return: <a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)]
		internal static GameObject GetItemPrefabFromGameObject(ItemDrop itemDropComponent, GameObject inputGameObject)
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(GetPrefabName(((Object)inputGameObject).name));
			itemDropComponent.m_itemData.m_dropPrefab = itemPrefab;
			if (!((Object)(object)itemPrefab != (Object)null))
			{
				return null;
			}
			return itemPrefab;
		}

		internal static bool CheckItemDropIntegrity(ItemDrop itemDropComp)
		{
			if (itemDropComp.m_itemData == null)
			{
				return false;
			}
			return itemDropComp.m_itemData.m_shared != null;
		}

		internal static void CreatePredefinedGroups(ObjectDB __instance)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Invalid comparison between Unknown and I4
			//IL_0117: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Invalid comparison between Unknown and I4
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected I4, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Invalid comparison between Unknown and I4
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected I4, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Invalid comparison between Unknown and I4
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Invalid comparison between Unknown and I4
			foreach (GameObject item in __instance.m_items.Where([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (GameObject x) => (Object)(object)x.GetComponentInChildren<ItemDrop>() != (Object)null))
			{
				ItemDrop componentInChildren = item.GetComponentInChildren<ItemDrop>();
				if (!CheckItemDropIntegrity(componentInChildren))
				{
					continue;
				}
				GameObject itemPrefabFromGameObject = GetItemPrefabFromGameObject(componentInChildren, item);
				componentInChildren.m_itemData.m_dropPrefab = ((Component)componentInChildren).gameObject;
				if (!((Object)(object)itemPrefabFromGameObject != (Object)null))
				{
					continue;
				}
				SharedData sharedData = componentInChildren.m_itemData.m_shared;
				string text = "";
				if ((double)sharedData.m_food > 0.0 && (double)sharedData.m_foodStamina > 0.0)
				{
					text = "Food";
				}
				if ((double)sharedData.m_food > 0.0 && (double)sharedData.m_foodStamina == 0.0)
				{
					text = "Potion";
				}
				else if ((int)sharedData.m_itemType == 21)
				{
					text = "Fish";
				}
				ItemType itemType = sharedData.m_itemType;
				if ((int)itemType <= 4)
				{
					if ((int)itemType != 1)
					{
						if (itemType - 3 <= 1)
						{
							goto IL_0156;
						}
					}
					else
					{
						GameObject val = ((IEnumerable<GameObject>)ObjectDB.instance.GetItemPrefab("Cultivator").GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces.m_pieces).FirstOrDefault((Func<GameObject, bool>)([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (GameObject p) =>
						{
							Requirement[] resources = p.GetComponent<Piece>().m_resources;
							return resources.Length == 1 && resources[0].m_resItem.m_itemData.m_shared.m_name == sharedData.m_name;
						}));
						if (val != null)
						{
							Plant component = val.GetComponent<Plant>();
							text = ((component != null && component.m_grownPrefabs[0].GetComponent<Pickable>()?.m_amount > 1) ? "Crops" : "Seeds");
						}
						if (ZNetScene.instance.GetPrefab("smelter").GetComponent<Smelter>().m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name))
						{
							text = "Ores";
						}
						if (ZNetScene.instance.GetPrefab("smelter").GetComponent<Smelter>().m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion c) => c.m_to.m_itemData.m_shared.m_name == sharedData.m_name))
						{
							text = "Metals";
						}
						if (ZNetScene.instance.GetPrefab("blastfurnace").GetComponent<Smelter>().m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name))
						{
							text = "Ores";
						}
						if (ZNetScene.instance.GetPrefab("blastfurnace").GetComponent<Smelter>().m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion c) => c.m_to.m_itemData.m_shared.m_name == sharedData.m_name))
						{
							text = "Metals";
						}
						if (ZNetScene.instance.GetPrefab("charcoal_kiln").GetComponent<Smelter>().m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion c) => c.m_from.m_itemData.m_shared.m_name == sharedData.m_name))
						{
							text = "Woods";
						}
						if (sharedData.m_name == "$item_elderbark")
						{
							text = "Woods";
						}
					}
				}
				else
				{
					switch (itemType - 13)
					{
					case 1:
						goto IL_0156;
					case 2:
						goto IL_0215;
					case 0:
						goto IL_0221;
					}
					if ((int)itemType == 22)
					{
						goto IL_0156;
					}
				}
				goto IL_043f;
				IL_0215:
				text = "Equipment";
				goto IL_043f;
				IL_0156:
				SkillType skillType = sharedData.m_skillType;
				switch (skillType - 1)
				{
				case 0:
					text = "Swords";
					break;
				case 7:
					text = "Bows";
					break;
				case 13:
					text = "Crossbows";
					break;
				case 6:
					text = "Axes";
					break;
				case 2:
					text = "Clubs";
					break;
				case 1:
					text = "Knives";
					break;
				case 11:
					text = "Pickaxes";
					break;
				case 3:
					text = "Polearms";
					break;
				case 4:
					text = "Spears";
					break;
				}
				goto IL_043f;
				IL_043f:
				if (!string.IsNullOrEmpty(text))
				{
					AddItemToGroup(text, componentInChildren);
				}
				if (sharedData != null)
				{
					text = "All";
					AddItemToGroup(text, componentInChildren);
				}
				continue;
				IL_0221:
				text = (new string[6] { "eikthyr", "elder", "bonemass", "dragonqueen", "goblinking", "SeekerQueen" }.Any(sharedData.m_name.EndsWith) ? "Boss Trophy" : "Trophy");
				goto IL_043f;
			}
		}

		private static void AddItemToGroup(string groupName, ItemDrop itemDrop)
		{
			if (!GroupUtils.GroupExists(groupName))
			{
				AzuCraftyBoxesPlugin.groups[groupName] = new HashSet<string>();
			}
			string prefabName = Utils.GetPrefabName(itemDrop.m_itemData.m_dropPrefab);
			if (!AzuCraftyBoxesPlugin.groups[groupName].Contains(prefabName))
			{
				AzuCraftyBoxesPlugin.groups[groupName].Add(prefabName);
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("(CreatePredefinedGroups) Added " + prefabName + " to " + groupName));
			}
		}
	}
}
namespace AzuCraftyBoxes.Patches
{
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)__instance).name.StartsWith("Treasure") || __instance.GetInventory() == null || !__instance.m_nview.IsValid() || __instance.m_nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) == 0L)
			{
				return;
			}
			try
			{
				if ((Object)(object)((Component)__instance).GetComponentInParent<Player>() != (Object)null && (Object)(object)((Component)__instance).GetComponentInParent<Player>() != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				if (WardIsLovePlugin.IsLoaded() && WardIsLovePlugin.WardEnabled().Value && WardMonoscript.CheckAccess(((Component)__instance).transform.position, 0f, flash: false, wardCheck: true))
				{
					long playerID = Game.instance.GetPlayerProfile().GetPlayerID();
					if (__instance.CheckAccess(playerID))
					{
						Boxes.AddContainer(__instance);
					}
				}
				else
				{
					long playerID2 = Game.instance.GetPlayerProfile().GetPlayerID();
					if (__instance.CheckAccess(playerID2) && PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, true))
					{
						Boxes.AddContainer(__instance);
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Load")]
	internal static class ContainerLoadPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)__instance).name.StartsWith("Treasure") || __instance.GetInventory() == null || !__instance.m_nview.IsValid() || __instance.m_nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) == 0L || (Object)(object)Player.m_localPlayer == (Object)null || ((Object)(object)((Component)__instance).GetComponentInParent<Player>() != (Object)null && (Object)(object)((Component)__instance).GetComponentInParent<Player>() != (Object)(object)Player.m_localPlayer) || Player.m_localPlayer.m_isLoading || Player.m_localPlayer.m_teleporting)
			{
				return;
			}
			if (WardIsLovePlugin.IsLoaded() && WardIsLovePlugin.WardEnabled().Value && WardMonoscript.CheckAccess(((Component)__instance).transform.position, 0f, flash: false, wardCheck: true))
			{
				long playerID = Game.instance.GetPlayerProfile().GetPlayerID();
				if (__instance.CheckAccess(playerID))
				{
					Boxes.AddContainer(__instance);
				}
			}
			else
			{
				long playerID2 = Game.instance.GetPlayerProfile().GetPlayerID();
				if (__instance.CheckAccess(playerID2) && PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, true))
				{
					Boxes.AddContainer(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "OnDestroyed")]
	internal static class ContainerOnDestroyedPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			if (!((Object)__instance).name.StartsWith("Treasure") && __instance.GetInventory() != null && __instance.m_nview.IsValid() && __instance.m_nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0L)
			{
				Boxes.RemoveContainer(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateTeleport")]
	public static class PlayerUpdateTeleportPatchCleanupContainers
	{
		public static void Prefix(float dt)
		{
			if (!((Object)(object)Player.m_localPlayer != (Object)null) || !Player.m_localPlayer.m_teleporting)
			{
				return;
			}
			foreach (Container item in from container in Boxes.Containers.ToList()
				where !((Object)(object)container != (Object)null) || !((Object)(object)((Component)container).transform != (Object)null) || container.GetInventory() == null
				where (Object)(object)container != (Object)null
				select container)
			{
				Boxes.RemoveContainer(item);
			}
		}
	}
	[HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")]
	internal static class CookingStationOnAddFuelSwitchPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static bool Prefix(CookingStation __instance, ref bool __result, Humanoid user, ItemData item, ZNetView ___m_nview)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"(CookingStationOnAddFuelSwitchPatch) Looking for fuel");
			if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || !MiscFunctions.AllowByKey() || item != null || __instance.GetFuel() > (float)(__instance.m_maxFuel - 1) || user.GetInventory().HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true))
			{
				return true;
			}
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"(CookingStationOnAddFuelSwitchPatch) Missing fuel in player inventory");
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<CookingStation>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			string name = ((Object)__instance.m_fuelItem).name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
			{
				if (item2.ContainsItem(name, 1, out var result))
				{
					if (Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(CookingStationOnAddFuelSwitchPatch) Container at {item2.GetPosition()} has {result} {name}, taking one");
						item2.RemoveItem(name, 1);
						item2.Save();
						((Character)user).Message((MessageType)2, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null);
						___m_nview.InvokeRPC("AddFuel", Array.Empty<object>());
						__result = true;
						return false;
					}
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(CookingStationOnAddFuelSwitchPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CookingStation), "FindCookableItem")]
	internal static class CookingStationFindCookableItemPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(CookingStation __instance, ref ItemData __result)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"(CookingStationFindCookableItemPatch) Looking for cookable");
			if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || !MiscFunctions.AllowByKey() || __result != null || (__instance.m_requireFire && !__instance.IsFireLit()) || __instance.GetFreeSlot() == -1)
			{
				return;
			}
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"(CookingStationFindCookableItemPatch) Missing cookable in player inventory");
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<CookingStation>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			foreach (ItemConversion item in __instance.m_conversion)
			{
				string name = ((Object)item.m_from).name;
				foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
				{
					if (item2.ContainsItem(name, 1, out var result))
					{
						if (Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
						{
							AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(CookingStationFindCookableItemPatch) Container at {item2.GetPosition()} has {result} {name}, taking one");
							GameObject val = ObjectDB.instance.m_itemByHash[StringExtensionMethods.GetStableHashCode(name)];
							ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone();
							val2.m_dropPrefab = val;
							__result = val2;
							item2.RemoveItem(name, 1);
							item2.Save();
							return;
						}
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(CookingStationFindCookableItemPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Fireplace), "Interact")]
	internal static class FireplaceInteractPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static bool Prefix(Fireplace __instance, Humanoid user, bool hold, ref bool __result, ZNetView ___m_nview)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			__result = true;
			KeyboardShortcut value = AzuCraftyBoxesPlugin.fillAllModKey.Value;
			bool key = Input.GetKey(((KeyboardShortcut)(ref value)).MainKey);
			Inventory inventory = user.GetInventory();
			if (!MiscFunctions.AllowByKey() || hold || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !key))
			{
				return true;
			}
			if (!___m_nview.HasOwner())
			{
				___m_nview.ClaimOwnership();
			}
			if (key && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true))
			{
				int num = (int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true));
				inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num, -1, true);
				inventory.Changed();
				for (int i = 0; i < num; i++)
				{
					___m_nview.InvokeRPC("AddFuel", Array.Empty<object>());
				}
				((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null);
				__result = false;
			}
			if (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) || !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel))
			{
				return __result;
			}
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Fireplace>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			string name = ((Object)__instance.m_fuelItem).name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
			{
				if (!item.ContainsItem(name, 1, out var result) || !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel))
				{
					continue;
				}
				if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(FireplaceInteractPatch) Container at {item.GetPosition()} has {result} {name} but it's forbidden by config");
					continue;
				}
				int num2 = ((!key) ? 1 : ((int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)result)));
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Pull ALL is {key}");
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(FireplaceInteractPatch) Container at {item.GetPosition()} has {result} {name}, taking {num2}");
				item.RemoveItem(name, num2);
				item.Save();
				if (__result)
				{
					((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null);
				}
				for (int j = 0; j < num2; j++)
				{
					___m_nview.InvokeRPC("AddFuel", Array.Empty<object>());
				}
				__result = false;
				if (key && !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) >= __instance.m_maxFuel))
				{
					continue;
				}
				return false;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
	internal static class FireplaceGetHoverTextPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Fireplace __instance, ref string __result)
		{
			//IL_0005: 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)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = AzuCraftyBoxesPlugin.fillAllModKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return;
			}
			double num = (double)__instance.m_maxFuel - (double)Mathf.CeilToInt(__instance.m_nview.GetZDO().GetFloat("fuel", 0f));
			List<string> list = new List<string>();
			if (num <= 0.0)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			int num2 = ((localPlayer != null) ? ((Humanoid)localPlayer).m_inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true) : 0);
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Fireplace>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			int num3 = 0;
			__instance.m_fuelItem.m_itemData.m_dropPrefab = ((Component)__instance.m_fuelItem).gameObject;
			string name = ((Object)__instance.m_fuelItem).name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
			{
				if (item.ContainsItem(name, 1, out var result))
				{
					Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name);
					num3 += result;
				}
			}
			if (num2 > 0)
			{
				list.Add($"{num2} in inventory");
			}
			if (num3 > 0)
			{
				list.Add($"{num3} in nearby containers");
			}
			if (num - (double)num2 - (double)num3 > 0.0 && num < (double)__instance.m_maxFuel)
			{
				list.Add($"{num - (double)num2 - (double)num3} needed to fill");
			}
			if (list.Count > 0)
			{
				__result += Localization.instance.Localize(string.Format("\n[<b><color=yellow>{0}</color> + <color=yellow>$KEY_Use</color></b>] {1}", AzuCraftyBoxesPlugin.fillAllModKey.Value, string.Join(" and ", list)));
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public class HUDPatches
	{
		private const float UpdateInterval = 0.5f;

		private static float _lastUpdate;

		private static int _cachedItemCount = int.MaxValue;

		[HarmonyPriority(0)]
		private static void Postfix(Hud __instance, Piece piece, TMP_Text ___m_buildSelection)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (AzuCraftyBoxesPlugin.ModEnabled.Value != 0 && !((Object)(object)piece == (Object)null) && !(piece.m_name == "$piece_repair"))
			{
				float time = Time.time;
				if (time - _lastUpdate >= 0.5f)
				{
					_lastUpdate = time;
					UpdateItemCount(piece);
				}
				string text = ((_cachedItemCount > 0) ? ColorUtility.ToHtmlStringRGBA(AzuCraftyBoxesPlugin.canbuildDisplayColor.Value) : ColorUtility.ToHtmlStringRGBA(AzuCraftyBoxesPlugin.cannotbuildDisplayColor.Value));
				___m_buildSelection.text = Localization.instance.Localize(piece.m_name) + " (<color=#" + text + ">" + ((_cachedItemCount == int.MaxValue) ? "∞" : _cachedItemCount.ToString()) + "</color>)";
			}
		}

		internal static void UpdateItemCount(Piece piece)
		{
			List<AzuCraftyBoxes.IContainers.IContainer> containers = Boxes.GetNearbyContainers<Player>(Player.m_localPlayer, AzuCraftyBoxesPlugin.mRange.Value);
			_cachedItemCount = piece.m_resources.Select(delegate(Requirement resource)
			{
				string name = resource.m_resItem.m_itemData.m_shared.m_name;
				string itemPrefabName = ((Object)resource.m_resItem).name;
				int num = ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(name, -1, true);
				int result;
				int num2 = containers.Sum([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (AzuCraftyBoxes.IContainers.IContainer c) => c.ContainsItem(itemPrefabName, 1, out result) ? result : 0);
				return (num + num2) / resource.m_amount;
			}).Concat(new int[1] { 2147483647 }).Min();
		}
	}
	[HarmonyPatch(typeof(Hud), "Awake")]
	internal static class HudAwakePatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Hud __instance)
		{
			((TMP_Text)__instance.m_hoverName).autoSizeTextContainer = true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
	internal static class InventoryGuiSetupRequirementPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(InventoryGui __instance, Transform elementRoot, Requirement req, Player player, bool craft, int quality)
		{
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || !MiscFunctions.AllowByKey() || req == null || (Object)(object)req.m_resItem == (Object)null || req.m_resItem.m_itemData == null || req.m_resItem.m_itemData.m_shared == null)
			{
				return;
			}
			req.m_resItem.m_itemData.m_dropPrefab = ((Component)req.m_resItem).gameObject;
			if ((Object)(object)req.m_resItem.m_itemData.m_dropPrefab == (Object)null)
			{
				return;
			}
			int num = ((Humanoid)player).GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true);
			int amount = req.GetAmount(quality);
			if (amount <= 0)
			{
				return;
			}
			TextMeshProUGUI component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (num < amount)
			{
				List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Player>(Player.m_localPlayer, AzuCraftyBoxesPlugin.mRange.Value);
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(req.m_resItem.GetPrefabName(((Object)((Component)req.m_resItem).gameObject).name));
				if ((Object)(object)itemPrefab == (Object)null)
				{
					return;
				}
				req.m_resItem.m_itemData.m_dropPrefab = itemPrefab;
				foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
				{
					try
					{
						string prefabName = item.GetPrefabName();
						if (!((Object)(object)req.m_resItem.m_itemData.m_dropPrefab == (Object)null))
						{
							string name = ((Object)req.m_resItem).name;
							if (Boxes.CanItemBePulled(prefabName, name))
							{
								item.ContainsItem(name, 1, out var result);
								num += result;
							}
						}
					}
					catch (Exception)
					{
					}
				}
				if (num >= amount)
				{
					((Graphic)component).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? AzuCraftyBoxesPlugin.flashColor.Value : AzuCraftyBoxesPlugin.unFlashColor.Value);
				}
			}
			((TMP_Text)component).text = ((AzuCraftyBoxesPlugin.resourceString.Value.Trim().Length > 0) ? string.Format(AzuCraftyBoxesPlugin.resourceString.Value, num, amount) : amount.ToString());
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")]
	internal static class UpdateKnownRecipesListPatch
	{
		private static void Prefix()
		{
			AzuCraftyBoxesPlugin.skip = true;
		}

		private static void Postfix()
		{
			AzuCraftyBoxesPlugin.skip = false;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirementItems", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int)
	})]
	internal static class PlayerHaveRequirementsPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Player __instance, ref bool __result, Recipe piece, bool discover, int qualityLevel, HashSet<string> ___m_knownMaterial)
		{
			try
			{
				if (((AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off) | __result) || discover || !MiscFunctions.AllowByKey())
				{
					return;
				}
				List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Player>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
				if (nearbyContainers.Count == 0)
				{
					return;
				}
				Requirement[] resources = piece.m_resources;
				foreach (Requirement val in resources)
				{
					if (!Object.op_Implicit((Object)(object)val.m_resItem) || !MiscFunctions.CheckItemDropIntegrity(val.m_resItem))
					{
						continue;
					}
					int amount = val.GetAmount(qualityLevel);
					int num = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true);
					if (num >= amount)
					{
						continue;
					}
					GameObject itemPrefabFromGameObject = MiscFunctions.GetItemPrefabFromGameObject(val.m_resItem, ((Component)val.m_resItem).gameObject);
					val.m_resItem.m_itemData.m_dropPrefab = ((Component)val.m_resItem).gameObject;
					if ((Object)(object)itemPrefabFromGameObject == (Object)null)
					{
						continue;
					}
					if ((Object)(object)val.m_resItem.m_itemData.m_dropPrefab == (Object)null)
					{
						ManualLogSource azuCraftyBoxesLogger = AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger;
						string[] obj = new string[5] { "Skipping ", null, null, null, null };
						ItemDrop resItem = val.m_resItem;
						obj[1] = ((resItem != null) ? ((Object)((Component)resItem).gameObject).name : null);
						obj[2] = " also known as ";
						obj[3] = Localization.instance.Localize(val.m_resItem?.m_itemData?.m_shared?.m_name);
						obj[4] = " is listed as a requirement but cannot be found in the ObjectDB in order to populate the m_dropPrefab like the ItemDrop script expects. Value was null. This will cause issues when attempting to drop the item on the ground, or any mod that patches recipes expecting this value to be populated.";
						azuCraftyBoxesLogger.LogWarning((object)string.Concat(obj));
						continue;
					}
					string prefabName = Utils.GetPrefabName(((Object)val.m_resItem).name);
					foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
					{
						if (!((Object)(object)val.m_resItem?.m_itemData?.m_dropPrefab == (Object)null) && Boxes.CanItemBePulled(item.GetPrefabName(), prefabName))
						{
							item.ContainsItem(prefabName, 1, out var result);
							num += result;
						}
					}
					if (num < amount)
					{
						return;
					}
				}
				__result = true;
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	internal static class HaveRequirementsPatch2
	{
		[HarmonyWrapSafe]
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Player __instance, ref bool __result, Piece piece, RequirementMode mode, HashSet<string> ___m_knownMaterial, Dictionary<string, int> ___m_knownStations)
		{
			//IL_0034: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected I4, but got Unknown
			try
			{
				if (((AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off) | __result) || AzuCraftyBoxesPlugin.skip || __instance == null)
				{
					return;
				}
				Transform transform = ((Component)__instance).transform;
				if (!((transform != null) ? new Vector3?(transform.position) : null).HasValue || !MiscFunctions.AllowByKey() || (Object)(object)piece == (Object)null)
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)piece.m_craftingStation))
				{
					if (mode - 1 <= 1)
					{
						if (!___m_knownStations.ContainsKey(piece.m_craftingStation.m_name))
						{
							return;
						}
					}
					else if (!Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position)))
					{
						return;
					}
				}
				if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc))
				{
					return;
				}
				List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Player>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
				Requirement[] resources = piece.m_resources;
				foreach (Requirement val in resources)
				{
					if ((Object)(object)val.m_resItem == (Object)null || !Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0 || !MiscFunctions.CheckItemDropIntegrity(val.m_resItem))
					{
						continue;
					}
					val.m_resItem.m_itemData.m_dropPrefab = ((Component)val.m_resItem).gameObject;
					if ((Object)(object)val.m_resItem.m_itemData.m_dropPrefab == (Object)null)
					{
						continue;
					}
					switch ((int)mode)
					{
					case 1:
						if (!___m_knownMaterial.Contains(val.m_resItem.m_itemData.m_shared.m_name))
						{
							return;
						}
						break;
					case 2:
					{
						if (((Humanoid)__instance).GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true))
						{
							break;
						}
						bool flag = false;
						string name2 = ((Object)val.m_resItem).name;
						foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
						{
							val.m_resItem.m_itemData.m_dropPrefab = ((Component)val.m_resItem).gameObject;
							if (!((Object)(object)val.m_resItem.m_itemData.m_dropPrefab == (Object)null))
							{
								string prefabName = Utils.GetPrefabName(val.m_resItem.m_itemData.m_dropPrefab);
								if (Boxes.CanItemBePulled(item.GetPrefabName(), prefabName) && item.ContainsItem(name2, 1, out var _))
								{
									flag = true;
									break;
								}
							}
						}
						if (!flag)
						{
							return;
						}
						break;
					}
					case 0:
					{
						if (((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) >= val.m_amount)
						{
							break;
						}
						int num = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true);
						foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
						{
							val.m_resItem.m_itemData.m_dropPrefab = ((Component)val.m_resItem).gameObject;
							if ((Object)(object)val.m_resItem.m_itemData.m_dropPrefab == (Object)null)
							{
								continue;
							}
							string name = ((Object)val.m_resItem).name;
							if (!Boxes.CanItemBePulled(item2.GetPrefabName(), name))
							{
								continue;
							}
							try
							{
								item2.ContainsItem(name, 1, out var result);
								num += result;
								if (num >= val.m_amount)
								{
									break;
								}
							}
							catch
							{
							}
						}
						if (num < val.m_amount)
						{
							return;
						}
						break;
					}
					}
				}
				__result = true;
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeResources")]
	internal static class ConsumeResourcesPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality = -1)
		{
			try
			{
				if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || !MiscFunctions.AllowByKey())
				{
					return true;
				}
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Player>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
				MiscFunctions.ProcessRequirements(requirements, qualityLevel, inventory, nearbyContainers, itemQuality);
			}
			catch (Exception ex)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)("Error in ConsumeResourcesPatch: " + ex.Message));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Game), "Logout")]
	internal static class GameLogoutPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Prefix(Game __instance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			AzuCraftyBoxesPlugin.lastPosition = Vector3.zero;
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class PredefinedGroupGrab
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(ObjectDB __instance)
		{
			if (Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				MiscFunctions.CreatePredefinedGroups(__instance);
			}
		}
	}
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	[HarmonyPatch(typeof(Smelter), "OnHoverAddOre")]
	internal static class SmelterOnHoverAddOrePatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Smelter __instance, ref string __result)
		{
			if (!OverrideHoverText.ShouldReturn(__instance))
			{
				OverrideHoverText.UpdateAddOreSwitchHoverText(__instance, ref __result);
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")]
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	internal static class SmelterOnHoverAddFuelPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static void Postfix(Smelter __instance, ref string __result)
		{
			if (!OverrideHoverText.ShouldReturn(__instance))
			{
				OverrideHoverText.UpdateAddWoodSwitchHoverText(__instance, ref __result);
			}
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public static class OverrideHoverText
	{
		public static bool ShouldReturn(Smelter __instance)
		{
			//IL_0005: 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)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = AzuCraftyBoxesPlugin.fillAllModKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return true;
			}
			if (Player.m_localPlayer == null)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer.m_hovering) || (Object)(object)Player.m_localPlayer.m_hovering.GetComponentInParent<Smelter>() != (Object)(object)__instance)
			{
				return true;
			}
			return false;
		}

		internal static void UpdateAddWoodSwitchHoverText(Smelter __instance, ref string result)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			int itemCountInInventoryAndContainers = GetItemCountInInventoryAndContainers(((Object)__instance.m_fuelItem).name, __instance.m_fuelItem.m_itemData.m_shared.m_name, __instance);
			int num = Math.Min(__instance.m_maxFuel - Mathf.CeilToInt(__instance.GetFuel()), itemCountInInventoryAndContainers);
			__instance.m_fuelItem.m_itemData.m_dropPrefab = ((Component)__instance.m_fuelItem).gameObject;
			if (num > 0 && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), Utils.GetPrefabName(__instance.m_fuelItem.m_itemData.m_dropPrefab)))
			{
				result += Localization.instance.Localize($"\n[<b><color=yellow>{AzuCraftyBoxesPlugin.fillAllModKey.Value}</color> + <color=yellow>$KEY_Use</color></b>] $piece_smelter_add {__instance.m_fuelItem.m_itemData.m_shared.m_name} {num} from Inventory & Nearby Containers");
			}
		}

		internal static void UpdateAddOreSwitchHoverText(Smelter __instance, ref string result)
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			int num = __instance.m_maxOre - __instance.GetQueueSize();
			List<string> list = new List<string>();
			foreach (ItemConversion item in __instance.m_conversion)
			{
				if (num <= 0)
				{
					break;
				}
				int itemCountInInventoryAndContainers = GetItemCountInInventoryAndContainers(((Object)item.m_from).name, item.m_from.m_itemData.m_shared.m_name, __instance);
				int num2 = Math.Min(num, itemCountInInventoryAndContainers);
				num -= num2;
				if (MiscFunctions.CheckItemDropIntegrity(item.m_from))
				{
					item.m_from.m_itemData.m_dropPrefab = ((Component)item.m_from).gameObject;
					if (!((Object)(object)MiscFunctions.GetItemPrefabFromGameObject(item.m_from, ((Component)item.m_from).gameObject) == (Object)null) && num2 > 0 && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), Utils.GetPrefabName(item.m_from.m_itemData.m_dropPrefab)))
					{
						list.Add($"{num2} {item.m_from.m_itemData.m_shared.m_name}");
					}
				}
			}
			if (list.Count > 0)
			{
				result += Localization.instance.Localize(string.Format("\n[<b><color=yellow>{0}</color> + <color=yellow>$KEY_Use</color></b>] {1} {2} from Inventory & Nearby Containers", AzuCraftyBoxesPlugin.fillAllModKey.Value, __instance.m_addOreTooltip, string.Join(", ", list)));
			}
		}

		private static int GetItemCountInInventoryAndContainers(string itemPrefab, string itemName, Smelter smelterInstance)
		{
			Player localPlayer = Player.m_localPlayer;
			int num = ((localPlayer != null) ? ((Humanoid)localPlayer).m_inventory.CountItems(itemName, -1, true) : 0);
			foreach (AzuCraftyBoxes.IContainers.IContainer nearbyContainer in Boxes.GetNearbyContainers<Smelter>(smelterInstance, AzuCraftyBoxesPlugin.mRange.Value))
			{
				nearbyContainer.ContainsItem(itemPrefab, 1, out var result);
				num += result;
			}
			return num;
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[HarmonyPatch(typeof(Smelter), "OnAddOre")]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	internal static class SmelterOnAddOrePatch
	{
		private static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ZNetView ___m_nview, [<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(new byte[] { 0, 2 })] out KeyValuePair<ItemData, int> __state)
		{
			//IL_0021: 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_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			int queueSize = __instance.GetQueueSize();
			__state = new KeyValuePair<ItemData, int>(item, queueSize);
			bool pullAll = AzuCraftyBoxesPlugin.fillAllModKey.Value.IsKeyHeld();
			if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || (!MiscFunctions.AllowByKey() && !pullAll) || item != null || __instance.GetQueueSize() >= __instance.m_maxOre)
			{
				return true;
			}
			Inventory inventory = user.GetInventory();
			if (__instance.m_conversion.Any([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ItemConversion itemConversion) =>
			{
				string text = itemConversion?.m_from?.m_itemData?.m_shared?.m_name;
				return text != null && inventory.HaveItem(text, true) && !pullAll;
			}))
			{
				return true;
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Humanoid>(user, AzuCraftyBoxesPlugin.mRange.Value);
			foreach (ItemConversion item3 in __instance.m_conversion)
			{
				if (__instance.GetQueueSize() >= __instance.m_maxOre || (dictionary.Any() && !pullAll))
				{
					break;
				}
				string name = item3.m_from.m_itemData.m_shared.m_name;
				string name2 = ((Object)item3.m_from).name;
				if (pullAll && inventory.HaveItem(name, true))
				{
					ItemData item2 = inventory.GetItem(name, -1, false);
					if (item2 == null)
					{
						continue;
					}
					try
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(__instance.m_fuelItem.GetPrefabName(((Object)((Component)item3.m_from).gameObject).name));
						item2.m_dropPrefab = itemPrefab;
					}
					catch (Exception)
					{
					}
					if ((Object)(object)item2.m_dropPrefab == (Object)null)
					{
						continue;
					}
					string prefabName = Utils.GetPrefabName(item2.m_dropPrefab);
					if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), prefabName))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(SmelterOnAddOrePatch) debug log 1:  Container at {((Component)user).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config");
						continue;
					}
					int num = ((!pullAll) ? 1 : Mathf.Min(__instance.m_maxOre - __instance.GetQueueSize(), inventory.CountItems(name, -1, true)));
					if (!dictionary.ContainsKey(name))
					{
						dictionary[name] = 0;
					}
					dictionary[name] += num;
					inventory.RemoveItem(item3.m_from.m_itemData.m_shared.m_name, num, -1, true);
					for (int i = 0; i < num; i++)
					{
						___m_nview.InvokeRPC("AddOre", new object[1] { ((Object)item2.m_dropPrefab).name });
					}
					((Character)user).Message((MessageType)1, $"$msg_added {num} {name}", 0, (Sprite)null);
					if (__instance.GetQueueSize() >= __instance.m_maxOre)
					{
						break;
					}
				}
				foreach (AzuCraftyBoxes.IContainers.IContainer item4 in nearbyContainers)
				{
					if (!item4.ContainsItem(name2, 1, out var result))
					{
						continue;
					}
					if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name2))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(SmelterOnAddOrePatch) Container at {item4.GetPosition()} has {result} {name2} but it's forbidden by config");
						continue;
					}
					int num2 = ((!pullAll) ? 1 : Mathf.Min(__instance.m_maxOre - __instance.GetQueueSize(), result));
					if (!dictionary.ContainsKey(name))
					{
						dictionary[name] = 0;
					}
					dictionary[name] += num2;
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Pull ALL is {pullAll}");
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(SmelterOnAddOrePatch) Container at {item4.GetPosition()} has {result} {name2}, taking {num2}");
					item4.RemoveItem(name2, num2);
					item4.Save();
					for (int j = 0; j < num2; j++)
					{
						___m_nview.InvokeRPC("AddOre", new object[1] { name2 });
					}
					((Character)user).Message((MessageType)1, $"$msg_added {num2} {name}", 0, (Sprite)null);
					if (__instance.GetQueueSize() < __instance.m_maxOre && pullAll)
					{
						continue;
					}
					break;
				}
			}
			if (!dictionary.Any())
			{
				((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null);
			}
			else
			{
				List<string> values = dictionary.Select([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (KeyValuePair<string, int> kvp) => $"$msg_added {kvp.Value} {kvp.Key}").ToList();
				((Character)user).Message((MessageType)2, string.Join("\n", values), 0, (Sprite)null);
			}
			return false;
		}

		public static void Postfix(Smelter __instance, Switch sw, Humanoid user, [<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(new byte[] { 0, 2 })] KeyValuePair<ItemData, int> __state, bool __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!(AzuCraftyBoxesPlugin.fillAllModKey.Value.IsKeyHeld() && __result) || __state.Key != null)
			{
				return;
			}
			if (!__instance.m_nview.IsOwner() && __instance.m_nview.GetZDO() != null)
			{
				int queueSize = __instance.GetQueueSize();
				if (queueSize == __state.Value)
				{
					__instance.m_nview.GetZDO().Set(ZDOVars.s_queued, queueSize + 1, false);
				}
			}
			MessageHud instance = MessageHud.m_instance;
			MessageHud.m_instance = null;
			try
			{
				__instance.OnAddOre(sw, user, (ItemData)null);
			}
			finally
			{
				MessageHud.m_instance = instance;
			}
		}
	}
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
	internal static class SmelterOnAddFuelPatch
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		private static bool Prefix(Smelter __instance, ref bool __result, ZNetView ___m_nview, Humanoid user, ItemData item)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			bool flag = AzuCraftyBoxesPlugin.fillAllModKey.Value.IsKeyHeld();
			Inventory inventory = user.GetInventory();
			if (AzuCraftyBoxesPlugin.ModEnabled.Value == AzuCraftyBoxesPlugin.Toggle.Off || (!MiscFunctions.AllowByKey() && !flag) || item != null || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !flag))
			{
				return true;
			}
			__result = true;
			int num = 0;
			if (__instance.GetFuel() > (float)(__instance.m_maxFuel - 1))
			{
				((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null);
				__result = false;
				return false;
			}
			if (flag && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true))
			{
				int num2 = (int)Mathf.Min((float)__instance.m_maxFuel - __instance.GetFuel(), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true));
				inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true);
				for (int i = 0; i < num2; i++)
				{
					___m_nview.InvokeRPC("AddFuel", Array.Empty<object>());
				}
				num += num2;
				((Character)user).Message((MessageType)1, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null);
				__result = false;
			}
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<Smelter>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			string name = ((Object)__instance.m_fuelItem).name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
			{
				if (!item2.ContainsItem(name, 1, out var result))
				{
					continue;
				}
				if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(SmelterOnAddFuelPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
					continue;
				}
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Pull ALL is {flag}");
				int num3 = ((!flag) ? 1 : ((int)Mathf.Min((float)__instance.m_maxFuel - __instance.GetFuel(), (float)result)));
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(SmelterOnAddFuelPatch) Container at {item2.GetPosition()} has {result} {name}, taking {num3}");
				item2.RemoveItem(name, num3);
				item2.Save();
				for (int j = 0; j < num3; j++)
				{
					___m_nview.InvokeRPC("AddFuel", Array.Empty<object>());
				}
				num += num3;
				((Character)user).Message((MessageType)1, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null);
				__result = false;
				if (flag && Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel)
				{
					continue;
				}
				return false;
			}
			((Character)user).Message((MessageType)2, (num == 0) ? "$msg_noprocessableitems" : $"$msg_added {num} {__instance.m_fuelItem.m_itemData.m_shared.m_name}", 0, (Sprite)null);
			return __result;
		}
	}
}
namespace AzuCraftyBoxes.IContainers
{
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public interface IContainer
	{
		int ProcessContainerInventory(string reqPrefab, string reqName, int totalAmount, int totalRequirement);

		bool ContainsItem(string prefab, int amount, out int result);

		void RemoveItem(string prefab, int amount);

		Vector3 GetPosition();

		void Save();

		string GetPrefabName();
	}
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public class kgDrawer : IContainer
	{
		[CompilerGenerated]
		private ItemDrawers_API.Drawer <_drawer>P;

		public kgDrawer(ItemDrawers_API.Drawer _drawer)
		{
			<_drawer>P = _drawer;
			base..ctor();
		}

		public int ProcessContainerInventory(string reqPrefab, string reqName, int totalAmount, int totalRequirement)
		{
			if (<_drawer>P.Prefab != reqPrefab)
			{
				return totalAmount;
			}
			int num = Mathf.Min(<_drawer>P.Amount, totalRequirement - totalAmount);
			<_drawer>P.Remove(num);
			return totalAmount + num;
		}

		public bool ContainsItem(string prefab, int amount, out int result)
		{
			result = 0;
			if (<_drawer>P.Prefab != prefab)
			{
				return false;
			}
			result = <_drawer>P.Amount;
			return result >= amount;
		}

		public void RemoveItem(string prefab, int amount)
		{
			amount = Mathf.Min(amount, <_drawer>P.Amount);
			<_drawer>P.Remove(amount);
		}

		public void Save()
		{
		}

		public Vector3 GetPosition()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return <_drawer>P.Position;
		}

		public string GetPrefabName()
		{
			return <_drawer>P.ZNVName;
		}

		public static kgDrawer Create(ItemDrawers_API.Drawer drawer)
		{
			return new kgDrawer(drawer);
		}
	}
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public class VanillaContainer : IContainer
	{
		[CompilerGenerated]
		private Container <_container>P;

		public VanillaContainer(Container _container)
		{
			<_container>P = _container;
			base..ctor();
		}

		public int ProcessContainerInventory(string reqPrefab, string reqName, int totalAmount, int totalRequirement)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = <_container>P.GetInventory();
			if (inventory == null)
			{
				return totalAmount;
			}
			int num = Mathf.Min(inventory.CountItems(reqName, -1, true), totalRequirement - totalAmount);
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(ConsumeResourcesPatch) Container at {((Component)<_container>P).transform.position} has {inventory.CountItems(reqName, -1, true)}");
			if (num == 0)
			{
				return totalAmount;
			}
			for (int i = 0; i < inventory.GetAllItems().Count; i++)
			{
				ItemData item = inventory.GetItem(i);
				if (!(item?.m_shared?.m_name != reqName))
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Container Total Items Count is {inventory.GetAllItems().Count}");
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(ConsumeResourcesPatch) Got stack of {item.m_stack} {reqName}");
					int num2 = Mathf.Min(item.m_stack, totalRequirement - totalAmount);
					if (num2 == item.m_stack)
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("(ConsumeResourcesPatch) Removing item " + reqName + " from container"));
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Container inventory before removal: {inventory.GetAllItems().Count}, Item at index {i}: {inventory.GetItem(i)?.m_shared?.m_name}");
						bool flag = inventory.RemoveItem(i);
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("Removed was " + flag));
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"Container inventory after attempted removal: {inventory.GetAllItems().Count}");
						i--;
					}
					else
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(ConsumeResourcesPatch) Removing {num2} {reqName} from container");
						item.m_stack -= num2;
					}
					totalAmount += num2;
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)$"(ConsumeResourcesPatch) Total amount is now {totalAmount}/{totalRequirement} {reqName}");
					if (totalAmount >= totalRequirement)
					{
						break;
					}
				}
			}
			<_container>P.Save();
			inventory.Changed();
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)"Saved container");
			if (totalAmount >= totalRequirement)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogDebug((object)("(ConsumeResourcesPatch) Consumed enough " + reqName));
			}
			return totalAmount;
		}

		public bool ContainsItem(string prefab, int amount, out int result)
		{
			result = 0;
			Inventory inventory = <_container>P.GetInventory();
			if (inventory == null)
			{
				return false;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (((Object)allItem.m_dropPrefab).name == prefab)
				{
					result += allItem.m_stack;
				}
			}
			return result >= amount;
		}

		public void RemoveItem(string prefab, int amount)
		{
			Inventory inventory = <_container>P.GetInventory();
			if (inventory == null)
			{
				return;
			}
			for (int i = 0; i < inventory.GetAllItems().Count; i++)
			{
				ItemData item = inventory.GetItem(i);
				object obj;
				if (item == null)
				{
					obj = null;
				}
				else
				{
					GameObject dropPrefab = item.m_dropPrefab;
					obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
				}
				if (!((string?)obj != prefab))
				{
					int num = Mathf.Min(item.m_stack, amount);
					if (num == item.m_stack)
					{
						inventory.RemoveItem(i);
						i--;
					}
					else
					{
						item.m_stack -= num;
					}
					amount -= num;
					if (amount <= 0)
					{
						break;
					}
				}
			}
			<_container>P.Save();
			inventory.Changed();
		}

		public void Save()
		{
			<_container>P.Save();
			Inventory inventory = <_container>P.m_inventory;
			if (inventory != null)
			{
				inventory.Changed();
			}
		}

		public Vector3 GetPosition()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)<_container>P).transform.position;
		}

		public string GetPrefabName()
		{
			return Utils.GetPrefabName(((Component)<_container>P).gameObject);
		}

		public static VanillaContainer Create(Container container)
		{
			return new VanillaContainer(container);
		}
	}
}
namespace AzuCraftyBoxes.Compatibility
{
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public class ModCompat
	{
		protected static T InvokeMethod<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)] T>(Type type, object instance, string methodName, object[] parameter)
		{
			return (T)(type.GetMethod(methodName)?.Invoke(instance, parameter));
		}

		[return: <a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)]
		protected static T GetField<[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(2)] T>(Type type, object instance, string fieldName)
		{
			return (T)(type.GetField(fieldName)?.GetValue(instance));
		}
	}
}
namespace AzuCraftyBoxes.Compatibility.WardIsLove
{
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	public class WardIsLovePlugin : ModCompat
	{
		private const string GUID = "Azumatt.WardIsLove";

		private static readonly System.Version MinVersion = new System.Version(2, 3, 3);

		private static Type ClassType()
		{
			return Type.GetType("WardIsLove.WardIsLovePlugin, WardIsLove");
		}

		public static bool IsLoaded()
		{
			if (Chainloader.PluginInfos.ContainsKey("Azumatt.WardIsLove"))
			{
				return Chainloader.PluginInfos["Azumatt.WardIsLove"].Metadata.Version >= MinVersion;
			}
			return false;
		}

		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(2)]
		public static ConfigEntry<bool> WardEnabled()
		{
			return ModCompat.GetField<ConfigEntry<bool>>(ClassType(), null, "WardEnabled");
		}
	}
	public class WardMonoscript : ModCompat
	{
		[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
		public static Type ClassType()
		{
			return Type.GetType("WardIsLove.Util.WardMonoscript, WardIsLove");
		}

		public static bool CheckInWardMonoscript(Vector3 point, bool flash = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ModCompat.InvokeMethod<bool>(ClassType(), null, "CheckInWardMonoscript", new object[2] { point, flash });
		}

		public static bool InsideWard(Vector3 pos)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (WardIsLovePlugin.WardEnabled().Value)
			{
				return CheckInWardMonoscript(pos);
			}
			return false;
		}

		public static bool CheckAccess(Vector3 point, float radius = 0f, bool flash = true, bool wardCheck = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ModCompat.InvokeMethod<bool>(ClassType(), null, "CheckAccess", new object[4] { point, radius, flash, wardCheck });
		}
	}
}
namespace AzuCraftyBoxes.APIs
{
	[<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(1)]
	[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
	public static class ItemDrawers_API
	{
		[<a16f4ee7-5397-4398-af26-e6172c6d14b4>Nullable(0)]
		public class Drawer
		{
			[CompilerGenerated]
			private ZNetView <znv>P;

			public string Prefab;

			public int Amount;

			public Vector3 Position => ((Component)<znv>P).transform.position;

			public string ZNVName => ((Object)((Component)<znv>P).gameObject).name;

			public Drawer(ZNetView znv)
			{
				<znv>P = znv;
				Prefab = <znv>P.m_zdo.GetString("Prefab", "");
				Amount = <znv>P.m_zdo.GetInt("Amount", 0);
				base..ctor();
			}

			public void Remove(int amount)
			{
				<znv>P.ClaimOwnership();
				<znv>P.InvokeRPC("ForceRemove", new object[1] { amount });
			}

			public void Withdraw(int amount)
			{
				<znv>P.InvokeRPC("WithdrawItem_Request", new object[1] { amount });
			}

			public void Add(int amount)
			{
				<znv>P.InvokeRPC("AddItem_Request", new object[2] { Prefab, amount });
			}
		}

		private static readonly bool _IsInstalled;

		private static readonly MethodInfo MI_GetAllDrawers;

		public static List<Drawer> AllDrawers
		{
			get
			{
				if (!_IsInstalled)
				{
					return new List<Drawer>();
				}
				return ((List<ZNetView>)MI_GetAllDrawers.Invoke(null, null)).Select([<56b5fe3c-0bbe-452e-a68e-59f9d91c02f4>NullableContext(0)] (ZNetView znv) => new Drawer(znv)).ToList();
			}
		}

		public static List<Drawer> AllDrawersInRange(Vector3 pos, float range)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!_IsInstalled)
			{
				return new List<Drawer>();
			}
			return (from znv in (List<ZNetView>)MI_GetAllDrawers.Invoke(null, null)
				where Vector3.Distance(((Component)znv).transform.position, pos) <= range
				select new Drawer(znv)).ToList();
		}

		static ItemDrawers_API()
		{
			Type type = Type.GetType("API.ClientSide, kg_ItemDrawers");
			if ((object)type == null)
			{
				_IsInstalled = false;
				return;
			}
			_IsInstalled = true;
			MI_GetAllDrawers = type.GetMethod("AllDrawers", BindingFlags.Static | BindingFlags.Public);
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[<52ebc6df-22fa-431f-88e1-b9692cdd6f17>Embedded]
	[CompilerGenerated]
	internal sealed class <52ebc6df-22fa-431f-88e1-b9692cdd6f17>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<52ebc6df-22fa-431f-88e1-b9692cdd6f17>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <a9205bc4-3574-433c-a1f7-88539c76ecf8>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <a9205bc4-3574-433c-a1f7-88539c76ecf8>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <a9205bc4-3574-433c-a1f7-88539c76ecf8>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<52ebc6df-22fa-431f-88e1-b9692cdd6f17>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <337c449d-f0db-4566-ada8-f1a4f24783c5>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <337c449d-f0db-4566-ada8-f1a4f24783c5>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[<52ebc6df-22fa-431f-88e1-b9692cdd6f17>Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServerSync
{
	[<337c449d-f0db-4566-ada8-f1a4f24783c5>NullableContext(1)]
	[<a9205bc4-3574-433c-a1f7-88539c76ecf8>Nullable(0)]
	[PublicAPI]
	internal abstract class OwnConfigEntryBase
	{
		[<a9205bc4-3574-433c-a1f7-88539c76ecf8>Nullable(2)]
		public object LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	[<337c449d-f0db-4566-ada8-f1a4f24783c5>NullableContext(1)]
	[<a9205bc4-3574-433c-a1f7-88539c76ecf8>Nullable(0)]
	internal class SyncedConfigEntry<[<a9205bc4-3574-433c-a1f7-88539c76ecf8>Nullable(2)] T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
		}

		public voi