Decompiled source of AzuCraftyBoxes v1.5.5

AzuCraftyBoxes.dll

Decompiled 16 hours 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.Reflection.Emit;
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 Backpacks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemDataManager;
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: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyProduct("AzuCraftyBoxes")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("AzuCraftyBoxes")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("1.5.5")]
[assembly: AssemblyConfiguration("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.5.0")]
[module: <8965a365-9603-4351-996f-9c8157e82e44>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<96e95b91-d4a2-4ea7-af4b-ea1fb51422e1>Embedded]
	internal sealed class <96e95b91-d4a2-4ea7-af4b-ea1fb51422e1>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<96e95b91-d4a2-4ea7-af4b-ea1fb51422e1>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <0ef51cff-a822-4172-8e41-361aea24de67>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <0ef51cff-a822-4172-8e41-361aea24de67>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <0ef51cff-a822-4172-8e41-361aea24de67>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<96e95b91-d4a2-4ea7-af4b-ea1fb51422e1>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <41143693-663e-4c48-ba60-4dda4336c369>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <41143693-663e-4c48-ba60-4dda4336c369>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<96e95b91-d4a2-4ea7-af4b-ea1fb51422e1>Embedded]
	[CompilerGenerated]
	internal sealed class <8965a365-9603-4351-996f-9c8157e82e44>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <8965a365-9603-4351-996f-9c8157e82e44>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AzuCraftyBoxes
{
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[PublicAPI]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	public class API
	{
		public static bool IsLoaded()
		{
			return true;
		}

		public static Type GetIContainerType()
		{
			return typeof(AzuCraftyBoxes.IContainers.IContainer);
		}

		public static Type GetVanillaContainerType()
		{
			return typeof(VanillaContainer);
		}

		public static Type GetKgDrawerType()
		{
			return typeof(kgDrawer);
		}

		public static Type GetItemDrawersAPIType()
		{
			return typeof(ItemDrawers_API);
		}

		public static Type GetBoxesUtilFunctionsType()
		{
			return typeof(Boxes);
		}

		public static AzuCraftyBoxes.IContainers.IContainer CreateContainer(string type, params object[] args)
		{
			if (!(type == "Vanilla"))
			{
				if (type == "kgDrawer")
				{
					return kgDrawer.Create(args[0] as ItemDrawers_API.Drawer);
				}
				throw new ArgumentException("Unknown container type: " + type);
			}
			object obj = args[0];
			return VanillaContainer.Create((Container)((obj is Container) ? obj : null));
		}

		public static void AddContainer(Container container)
		{
			Boxes.AddContainer(container);
		}

		public static void RemoveContainer(Container container)
		{
			Boxes.RemoveContainer(container);
		}

		public static List<AzuCraftyBoxes.IContainers.IContainer> GetNearbyContainers<[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)] T>(T gameObject, float rangeToUse) where T : Component
		{
			return Boxes.GetNearbyContainers(gameObject, rangeToUse);
		}

		public static Dictionary<string, List<string>> GetExcludedPrefabsForAllContainers()
		{
			return Boxes.GetExcludedPrefabsForAllContainers();
		}

		public static bool CanItemBePulled(string container, string prefab)
		{
			return Boxes.CanItemBePulled(container, prefab);
		}

		public static int CountItemInContainer(AzuCraftyBoxes.IContainers.IContainer container, string itemName)
		{
			if (container.ContainsItem(itemName, 1, out var result))
			{
				return result;
			}
			return 0;
		}

		public static bool ContainsItem(AzuCraftyBoxes.IContainers.IContainer container, string itemName, int amount)
		{
			int result;
			return container.ContainsItem(itemName, amount, out result);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[BepInPlugin("Azumatt.AzuCraftyBoxes", "AzuCraftyBoxes", "1.5.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("aedenthorn.CraftFromContainers")]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	[BepInIncompatibility("CFCMod")]
	public class AzuCraftyBoxesPlugin : BaseUnityPlugin
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(0)]
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(1)]
			[UsedImplicitly]
			public string Category;

			[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		[<0ef51cff-a822-4172-8e41-361aea24de67>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.5.5";

		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;

		internal static readonly Harmony harmony;

		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, Dictionary<string, List<string>>> yamlData;

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

		internal static Dictionary<string, bool> CanItemBePulledCache;

		internal static bool BackpacksIsLoaded;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		internal static ConfigEntry<Toggle> ModEnabled;

		internal static ConfigEntry<Toggle> debugLogsEnabled;

		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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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.");
			debugLogsEnabled = config("1 - General", "Output Debug Logs", Toggle.Off, "If on, the debug logs will be displayed in the BepInEx console window when BepInEx debugging is enabled.");
			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);
			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();
			Chainloader.PluginInfos.TryGetValue("Azumatt.AzuAntiArthriticCrafting", out var value);
			if (value != null)
			{
				AzuCraftyBoxesLogger.LogInfo((object)"AzuAntiArthriticCrafting found, enabling compatibility");
				MethodInfo method = ((object)value.Instance).GetType().Assembly.GetType("AzuAntiArthriticCrafting.Patches.HaveRequirementItemsTranspiler").GetMethod("GetCurrentCraftAmount");
				if (method != null)
				{
					MiscFunctions.GetCurrentCraftAmountMethod = method;
				}
			}
			if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks"))
			{
				BackpacksIsLoaded = true;
			}
		}

		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<[<0ef51cff-a822-4172-8e41-361aea24de67>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<[<0ef51cff-a822-4172-8e41-361aea24de67>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<[<0ef51cff-a822-4172-8e41-361aea24de67>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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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 = "";
			harmony = new Harmony("Azumatt.AzuCraftyBoxes");
			AzuCraftyBoxesLogger = Logger.CreateLogSource("AzuCraftyBoxes");
			ConfigSync = new ConfigSync("Azumatt.AzuCraftyBoxes")
			{
				DisplayName = "AzuCraftyBoxes",
				CurrentVersion = "1.5.5",
				MinimumRequiredVersion = "1.5.5"
			};
			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", "");
			yamlData = null;
			groups = new Dictionary<string, HashSet<string>>();
			CanItemBePulledCache = null;
			BackpacksIsLoaded = false;
			_serverConfigLocked = null;
			ModEnabled = null;
			debugLogsEnabled = 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;
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	public static class LoggerExtensions
	{
		public static void LogIfReleaseAndDebugEnable(this ManualLogSource logger, string message)
		{
			if (AzuCraftyBoxesPlugin.debugLogsEnabled.Value == AzuCraftyBoxesPlugin.Toggle.On)
			{
				logger.LogDebug((object)message);
			}
		}

		public static void LogIfDebugBuild(this ManualLogSource logger, string message)
		{
		}

		public static void LogIfDebuggingEpicLoot(this ManualLogSource logger, string message)
		{
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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.LogIfReleaseAndDebugEnable("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.5.5");
			peer.m_rpc.Invoke("AzuCraftyBoxes_VersionCheck", new object[1] { val });
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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);
			}
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	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.5.5,  remote: " + text));
			if (text != "1.5.5")
			{
				AzuCraftyBoxesPlugin.ConnectionError = "AzuCraftyBoxes Installed: 1.5.5\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.Functions
{
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>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>();

		private static ConcurrentDictionary<float, Stopwatch> stopwatches = new ConcurrentDictionary<float, Stopwatch>();

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

		internal static void RemoveContainer(Container container)
		{
			if (Containers.Contains(container))
			{
				ContainersToRemove.Add(container);
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("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<[<0ef51cff-a822-4172-8e41-361aea24de67>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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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);
			IEnumerable<AzuCraftyBoxes.IContainers.IContainer> second2 = new List<AzuCraftyBoxes.IContainers.IContainer>();
			List<AzuCraftyBoxes.IContainers.IContainer> list2 = new List<AzuCraftyBoxes.IContainers.IContainer>();
			if (AzuCraftyBoxesPlugin.BackpacksIsLoaded)
			{
				foreach (ItemData item2 in from x in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()
					where ((x == null) ? null : ItemExtensions.Data(x, "org.bepinex.plugins.backpacks")?.Get<ItemContainer>()) != null
					select x)
				{
					BackpackContainer item = BackpackContainer.Create((item2 == null) ? null : ItemExtensions.Data(item2, "org.bepinex.plugins.backpacks")?.Get<ItemContainer>());
					if (!list2.Contains(item))
					{
						list2.Add(item);
					}
				}
				second2 = list2;
			}
			if (Vector3.Distance(((Component)gameObject).transform.position, AzuCraftyBoxesPlugin.lastPosition) < 0.5f)
			{
				return AzuCraftyBoxesPlugin.cachedContainerList.Concat(second).Concat(second2).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).Concat(second2).ToList();
		}

		public static void AddContainerIfNotExists(string containerName)
		{
			if (!AzuCraftyBoxesPlugin.yamlData.ContainsKey(containerName))
			{
				AzuCraftyBoxesPlugin.yamlData[containerName] = new Dictionary<string, List<string>>
				{
					{
						"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([<41143693-663e-4c48-ba60-4dda4336c369>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.TryGetValue(container, out var value))
			{
				return true;
			}
			List<string> value2;
			List<string> list = (value.TryGetValue("exclude", out value2) ? value2 : new List<string>());
			if ((value.TryGetValue("includeOverride", out var value3) ? value3 : new List<string>()).Contains(prefab))
			{
				return true;
			}
			foreach (string item in list)
			{
				if (prefab.Equals((object?)item))
				{
					return false;
				}
				if (GroupUtils.IsGroupDefined(item) && GroupUtils.GetItemsInGroup(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.TryGetValue("exclude", out var value2))
			{
				List<string> list = new List<string>();
				{
					foreach (string item in value2)
					{
						if (AzuCraftyBoxesPlugin.groups.TryGetValue(item, out var value3))
						{
							list.AddRange(value3);
						}
						else
						{
							list.Add(item);
						}
					}
					return list;
				}
			}
			return new List<string>();
		}

		public static Stopwatch GetStopwatch(GameObject o)
		{
			float gameObjectPosHash = GetGameObjectPosHash(o);
			Stopwatch value = null;
			if (!stopwatches.TryGetValue(gameObjectPosHash, out value))
			{
				value = new Stopwatch();
				stopwatches.TryAdd(gameObjectPosHash, value);
			}
			return value;
		}

		private static float GetGameObjectPosHash(GameObject o)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			return 1000f * o.transform.position.x + o.transform.position.y + 0.001f * o.transform.position.z;
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	public static class YamlUtils
	{
		internal static void ReadYaml(string yamlInput)
		{
			AzuCraftyBoxesPlugin.yamlData = new DeserializerBuilder().Build().Deserialize<Dictionary<string, Dictionary<string, List<string>>>>(yamlInput);
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("yamlData:\n" + yamlInput);
		}

		internal static void ParseGroups()
		{
			if (!AzuCraftyBoxesPlugin.yamlData.TryGetValue("groups", out var value))
			{
				return;
			}
			foreach (KeyValuePair<string, List<string>> item in value)
			{
				AzuCraftyBoxesPlugin.groups[item.Key] = new HashSet<string>(item.Value);
			}
		}

		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);
		}
	}
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	public class GroupUtils
	{
		public static List<string> GetExcludedGroups(string container)
		{
			if (AzuCraftyBoxesPlugin.yamlData.TryGetValue(container, out var value) && value.TryGetValue("exclude", out var value2))
			{
				return value2.Where([<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(0)] (string excludeItem) => AzuCraftyBoxesPlugin.groups.ContainsKey(excludeItem)).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.TryGetValue("groups", out var value))
			{
				flag = value.ContainsKey(groupName);
			}
			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>();
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	public class MiscFunctions
	{
		[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(2)]
		public static MethodInfo GetCurrentCraftAmountMethod;

		internal static bool AllowByKey()
		{
			return true;
		}

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

		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.LogIfReleaseAndDebugEnable($"(ConsumeResourcesPatch) Have {totalAmount}/{totalRequirement} {reqName} in player inventory");
		}

		private static int ConsumeResourcesFromContainers(string reqName, int totalAmount, int totalRequirement, List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers)
		{
			int num = totalAmount;
			foreach (AzuCraftyBoxes.IContainers.IContainer nearbyContainer in nearbyContainers)
			{
				num = nearbyContainer.ProcessContainerInventory(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: <0ef51cff-a822-4172-8e41-361aea24de67>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([<41143693-663e-4c48-ba60-4dda4336c369>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>)([<41143693-663e-4c48-ba60-4dda4336c369>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([<41143693-663e-4c48-ba60-4dda4336c369>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([<41143693-663e-4c48-ba60-4dda4336c369>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([<41143693-663e-4c48-ba60-4dda4336c369>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([<41143693-663e-4c48-ba60-4dda4336c369>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([<41143693-663e-4c48-ba60-4dda4336c369>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.LogIfReleaseAndDebugEnable("(CreatePredefinedGroups) Added " + prefabName + " to " + groupName);
			}
		}
	}
}
namespace AzuCraftyBoxes.Patches
{
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (__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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (__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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Container __instance)
		{
			if (__instance.GetInventory() != null && __instance.m_nview.IsValid() && __instance.m_nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0L)
			{
				Boxes.RemoveContainer(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "OnDestroy")]
	internal static class WearNTearOnDestroyPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Prefix(WearNTear __instance)
		{
			Container[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Container>();
			Container[] componentsInParent = ((Component)__instance).GetComponentsInParent<Container>();
			if (componentsInChildren.Length != 0)
			{
				Container[] array = componentsInChildren;
				for (int i = 0; i < array.Length; i++)
				{
					Boxes.RemoveContainer(array[i]);
				}
			}
			if (componentsInParent.Length != 0)
			{
				Container[] array = componentsInParent;
				for (int i = 0; i < array.Length; i++)
				{
					Boxes.RemoveContainer(array[i]);
				}
			}
		}
	}
	[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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static bool Prefix(CookingStation __instance, ref bool __result, Humanoid user, ItemData item, ZNetView ___m_nview)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("(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) && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)__instance.m_fuelItem).name)))
			{
				return true;
			}
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("(CookingStationOnAddFuelSwitchPatch) Missing fuel in player inventory");
			string name = ((Object)__instance.m_fuelItem).name;
			if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("(CookingStationOnAddFuelSwitchPatch) CookingStation is forbidden to pull " + name + " by config");
				return true;
			}
			List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<CookingStation>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
			string name2 = __instance.m_fuelItem.m_itemData.m_shared.m_name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
			{
				if (item2.ContainsItem(name2, 1, out var result))
				{
					if (!Boxes.CanItemBePulled(item2.GetPrefabName(), name))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(CookingStationOnAddFuelSwitchPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
						return true;
					}
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(CookingStationOnAddFuelSwitchPatch) Container at {item2.GetPosition()} has {result} {name}, taking one");
					item2.RemoveItem(name2, 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("RPC_AddFuel", Array.Empty<object>());
					__result = true;
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CookingStation), "FindCookableItem")]
	internal static class CookingStationFindCookableItemPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(CookingStation __instance, ref ItemData __result)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("(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.LogIfReleaseAndDebugEnable("(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;
				string name2 = item.m_from.m_itemData.m_shared.m_name;
				if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable("(CookingStationOnAddFuelSwitchPatch) CookingStation is forbidden to pull " + name + " by config");
					continue;
				}
				foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
				{
					if (item2.ContainsItem(name2, 1, out var result))
					{
						if (Boxes.CanItemBePulled(item2.GetPrefabName(), name))
						{
							AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(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(name2, 1);
							item2.Save();
							return;
						}
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(CookingStationFindCookableItemPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Fireplace), "Interact")]
	internal static class FireplaceInteractPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: 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 (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)__instance.m_fuelItem).name))
			{
				return true;
			}
			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(ZDOVars.s_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("RPC_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(ZDOVars.s_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;
			string name2 = __instance.m_fuelItem.m_itemData.m_shared.m_name;
			foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
			{
				if (!item.ContainsItem(name2, 1, out var result) || !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f)) < __instance.m_maxFuel))
				{
					continue;
				}
				if (!Boxes.CanItemBePulled(item.GetPrefabName(), name))
				{
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(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(ZDOVars.s_fuel, 0f)), (float)result)));
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"Pull ALL is {key}");
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(FireplaceInteractPatch) Container at {item.GetPosition()} has {result} {name}, taking {num2}");
				item.RemoveItem(name2, 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("RPC_AddFuel", Array.Empty<object>());
				}
				__result = false;
				if (key && !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f)) >= __instance.m_maxFuel))
				{
					continue;
				}
				return false;
			}
			return __result;
		}
	}
	[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
	internal static class FireplaceGetHoverTextPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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_01c1: 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(ZDOVars.s_fuel, 0f));
			List<string> list = new List<string>();
			if (num <= 0.0)
			{
				return;
			}
			string name = ((Object)__instance.m_fuelItem).name;
			string name2 = __instance.m_fuelItem.m_itemData.m_shared.m_name;
			if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
			{
				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;
			foreach (AzuCraftyBoxes.IContainers.IContainer item in nearbyContainers)
			{
				if (item.ContainsItem(name2, 1, out var result))
				{
					Boxes.CanItemBePulled(item.GetPrefabName(), 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)));
			}
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
	[<0ef51cff-a822-4172-8e41-361aea24de67>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 itemName = resource.m_resItem.m_itemData.m_shared.m_name;
				int num = ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(itemName, -1, true);
				int result;
				int num2 = containers.Sum([<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(0)] (AzuCraftyBoxes.IContainers.IContainer c) => c.ContainsItem(itemName, 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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Hud __instance)
		{
			((TMP_Text)__instance.m_hoverName).autoSizeTextContainer = true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirementList")]
	internal static class InventoryGuiCollectRequirements
	{
		[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(1)]
		public static Dictionary<Requirement, int> actualAmounts = new Dictionary<Requirement, int>();

		private static void Prefix()
		{
			actualAmounts.Clear();
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
	internal static class InventoryGuiSetupRequirementPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(InventoryGui __instance, Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier = 1)
		{
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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);
			TextMeshProUGUI component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (!int.TryParse(((TMP_Text)component).text, out var result))
			{
				result = req.GetAmount(quality) * craftMultiplier;
			}
			if (result <= 0)
			{
				return;
			}
			if (num < result)
			{
				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;
							string name2 = req.m_resItem.m_itemData.m_shared.m_name;
							if (Boxes.CanItemBePulled(prefabName, name))
							{
								item.ContainsItem(name2, 1, out var result2);
								num += result2;
							}
						}
					}
					catch (Exception)
					{
					}
				}
				if (num >= result)
				{
					((Graphic)component).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? AzuCraftyBoxesPlugin.flashColor.Value : AzuCraftyBoxesPlugin.unFlashColor.Value);
					InventoryGuiCollectRequirements.actualAmounts[req] = result;
				}
			}
			((TMP_Text)component).text = ((AzuCraftyBoxesPlugin.resourceString.Value.Trim().Length > 0) ? string.Format(AzuCraftyBoxesPlugin.resourceString.Value, num, result) : result.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),
		typeof(int)
	})]
	internal static class PlayerHaveRequirementsPatch
	{
		[HarmonyPriority(700)]
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Player __instance, ref bool __result, Recipe piece, bool discover, int qualityLevel, HashSet<string> ___m_knownMaterial, int amount = 1)
		{
			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;
				}
				bool flag = false;
				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 num = val.GetAmount(qualityLevel) * amount;
					int num2 = 0;
					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;
					}
					for (int j = 1; j <= val.m_resItem.m_itemData.m_shared.m_maxQuality; j++)
					{
						int num3 = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, j, true);
						if (num3 > num2)
						{
							num2 = num3;
						}
						string prefabName = Utils.GetPrefabName(((Object)val.m_resItem).name);
						string name = val.m_resItem.m_itemData.m_shared.m_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(name, j, out var result);
								num2 = Math.Max(num2, result);
							}
						}
					}
					if (piece.m_requireOnlyOneIngredient)
					{
						if (num2 >= num && __instance.m_knownMaterial.Contains(val.m_resItem.m_itemData.m_shared.m_name))
						{
							flag = true;
						}
						continue;
					}
					if (num2 < num)
					{
						return;
					}
					flag = true;
				}
				if (flag)
				{
					__result = true;
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int),
		typeof(int)
	})]
	internal static class PlayerHaveRequirementsPatchRBoolInt
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Player __instance, Recipe recipe, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			if (discover)
			{
				if (Object.op_Implicit((Object)(object)recipe.m_craftingStation) && !__instance.KnowStationLevel(recipe.m_craftingStation.m_name, recipe.m_minStationLevel))
				{
					return;
				}
			}
			else if (!__instance.RequiredCraftingStation(recipe, qualityLevel, true))
			{
				return;
			}
			if ((recipe.m_item.m_itemData.m_shared.m_dlc.Length <= 0 || DLCMan.instance.IsDLCInstalled(recipe.m_item.m_itemData.m_shared.m_dlc)) && __instance.HaveRequirementItems(recipe, discover, qualityLevel, amount) && !__result)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	internal static class HaveRequirementsPatch2
	{
		[HarmonyPriority(700)]
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		[HarmonyWrapSafe]
		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 name3 = val.m_resItem.m_itemData.m_shared.m_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(name3, 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;
							string name2 = val.m_resItem.m_itemData.m_shared.m_name;
							if (!Boxes.CanItemBePulled(item2.GetPrefabName(), name))
							{
								continue;
							}
							try
							{
								item2.ContainsItem(name2, 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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality = -1, int multiplier = 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, multiplier);
			}
			catch (Exception ex)
			{
				AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogError((object)("Error in ConsumeResourcesPatch: " + ex.Message));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Game), "Logout")]
	internal static class GameLogoutPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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(ShieldGenerator), "OnHoverAddFuel")]
	internal static class ShieldGeneratorOnHoverAddFuelPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(ShieldGenerator __instance, ref string __result)
		{
			if (!OverrideHoverTextSg.ShouldReturn(__instance))
			{
				OverrideHoverTextSg.UpdateAddFuelSwitchHoverText(__instance, ref __result);
			}
		}
	}
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	public static class OverrideHoverTextSg
	{
		public static bool ShouldReturn(ShieldGenerator __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 ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer.m_hovering))
			{
				return (Object)(object)Player.m_localPlayer.m_hovering.GetComponentInParent<ShieldGenerator>() != (Object)(object)__instance;
			}
			return true;
		}

		internal static void UpdateAddFuelSwitchHoverText(ShieldGenerator __instance, ref string result)
		{
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			double num = (float)__instance.m_maxFuel - __instance.GetFuel();
			List<string> list = new List<string>();
			foreach (ItemDrop fuelItem in __instance.m_fuelItems)
			{
				string name = fuelItem.m_itemData.m_shared.m_name;
				Player localPlayer = Player.m_localPlayer;
				int num2 = ((localPlayer != null) ? ((Humanoid)localPlayer).m_inventory.CountItems(name, -1, true) : 0);
				int num3 = 0;
				foreach (AzuCraftyBoxes.IContainers.IContainer nearbyContainer in Boxes.GetNearbyContainers<ShieldGenerator>(__instance, AzuCraftyBoxesPlugin.mRange.Value))
				{
					if (Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)fuelItem).name))
					{
						nearbyContainer.ContainsItem(name, 1, out var result2);
						num3 += result2;
					}
				}
				if (num2 > 0)
				{
					list.Add($"{num2} {name} in inventory");
				}
				if (num3 > 0)
				{
					list.Add($"{num3} {name} 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>] Add {1}", AzuCraftyBoxesPlugin.fillAllModKey.Value, string.Join(" and ", list)));
			}
		}
	}
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	[HarmonyPatch(typeof(ShieldGenerator), "OnAddFuel")]
	internal static class ShieldGeneratorOnAddFuelPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static bool Prefix(ShieldGenerator __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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: 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)
			{
				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;
			}
			foreach (ItemDrop fuelItem in __instance.m_fuelItems)
			{
				string name = fuelItem.m_itemData.m_shared.m_name;
				if (flag && inventory.HaveItem(name, true) && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)fuelItem).name))
				{
					int num2 = (int)Mathf.Min((float)__instance.m_maxFuel - __instance.GetFuel(), (float)inventory.CountItems(name, -1, true));
					inventory.RemoveItem(name, num2, -1, true);
					for (int i = 0; i < num2; i++)
					{
						___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
					}
					num += num2;
					((Character)user).Message((MessageType)1, Localization.instance.Localize("$msg_fireadding", new string[1] { name }), 0, (Sprite)null);
					__result = false;
				}
				List<AzuCraftyBoxes.IContainers.IContainer> nearbyContainers = Boxes.GetNearbyContainers<ShieldGenerator>(__instance, AzuCraftyBoxesPlugin.mRange.Value);
				if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)fuelItem).name))
				{
					continue;
				}
				foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
				{
					if (!item2.ContainsItem(name, 1, out var result))
					{
						continue;
					}
					if (!Boxes.CanItemBePulled(item2.GetPrefabName(), ((Object)fuelItem).name))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(ShieldGeneratorOnAddFuelPatch) Container at {item2.GetPosition()} has {result} {name} but it's forbidden by config");
						continue;
					}
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"Pull ALL is {flag}");
					int num3 = ((!flag) ? 1 : ((int)Mathf.Min((float)__instance.m_maxFuel - __instance.GetFuel(), (float)result)));
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(ShieldGeneratorOnAddFuelPatch) 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("RPC_AddFuel", Array.Empty<object>());
					}
					num += num3;
					((Character)user).Message((MessageType)1, "$msg_added " + name, 0, (Sprite)null);
					__result = false;
					if (flag && Mathf.CeilToInt(___m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f)) < __instance.m_maxFuel)
					{
						continue;
					}
					return false;
				}
			}
			((Character)user).Message((MessageType)2, (num == 0) ? "$msg_noprocessableitems" : $"$msg_added {num} items", 0, (Sprite)null);
			return __result;
		}
	}
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	[HarmonyPatch(typeof(Smelter), "OnHoverAddOre")]
	internal static class SmelterOnHoverAddOrePatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
		private static void Postfix(Smelter __instance, ref string __result)
		{
			if (!OverrideHoverText.ShouldReturn(__instance))
			{
				OverrideHoverText.UpdateAddWoodSwitchHoverText(__instance, ref __result);
			}
		}
	}
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	[<0ef51cff-a822-4172-8e41-361aea24de67>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 prefabName, 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))
			{
				if (Boxes.CanItemBePulled(prefabName, nearbyContainer.GetPrefabName()))
				{
					nearbyContainer.ContainsItem(itemName, 1, out var result);
					num += result;
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnAddOre")]
	[<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(0)]
	[<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(1)]
	internal static class SmelterOnAddOrePatch
	{
		private static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ZNetView ___m_nview, [<0ef51cff-a822-4172-8e41-361aea24de67>Nullable(new byte[] { 0, 2 })] out KeyValuePair<ItemData, int> __state)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: 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([<41143693-663e-4c48-ba60-4dda4336c369>NullableContext(0)] (ItemConversion itemConversion) =>
			{
				string text = itemConversion?.m_from?.m_itemData?.m_shared?.m_name;
				return text != null && inventory.HaveItem(text, true) && !pullAll && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)itemConversion.m_from).name);
			}))
			{
				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.LogIfReleaseAndDebugEnable($"(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("RPC_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;
					}
				}
				if (!Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name2))
				{
					continue;
				}
				foreach (AzuCraftyBoxes.IContainers.IContainer item4 in nearbyContainers)
				{
					if (!item4.ContainsItem(name, 1, out var result))
					{
						continue;
					}
					if (!Boxes.CanItemBePulled(item4.GetPrefabName(), name2))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(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.LogIfReleaseAndDebugEnable($"Pull ALL is {pullAll}");
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(SmelterOnAddOrePatch) Container at {item4.GetPosition()} has {result} {name2}, taking {num2}");
					item4.RemoveItem(name, num2);
					item4.Save();
					for (int j = 0; j < num2; j++)
					{
						___m_nview.InvokeRPC("RPC_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([<41143693-663e-4c48-ba60-4dda4336c369>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, [<0ef51cff-a822-4172-8e41-361aea24de67>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;
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
	[HarmonyBefore(new string[] { "org.bepinex.plugins.conversionsizespeed" })]
	internal static class SmelterOnAddFuelPatch
	{
		[<41143693-663e-4c48-ba60-4dda4336c369>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_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: 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 && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)__instance.m_fuelItem).name)))
			{
				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) && Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), ((Object)__instance.m_fuelItem).name))
			{
				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("RPC_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;
			string name2 = __instance.m_fuelItem.m_itemData.m_shared.m_name;
			if (Boxes.CanItemBePulled(Utils.GetPrefabName(((Component)__instance).gameObject), name))
			{
				foreach (AzuCraftyBoxes.IContainers.IContainer item2 in nearbyContainers)
				{
					if (!item2.ContainsItem(name2, 1, out var result))
					{
						continue;
					}
					if (!Boxes.CanItemBePulled(item2.GetPrefabName(), name))
					{
						AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(SmelterOnAddFuelPatch) Container at {item2.GetPosition()} has {result} {name2} but it's forbidden by config");
						continue;
					}
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"Pull ALL is {flag}");
					int num3 = ((!flag) ? 1 : ((int)Mathf.Min((float)__instance.m_maxFuel - __instance.GetFuel(), (float)result)));
					AzuCraftyBoxesPlugin.AzuCraftyBoxesLogger.LogIfReleaseAndDebugEnable($"(SmelterOnAddFuelPatch) Container at {item2.GetPosition()} has {result} {name2}, taking {num3}");
					item2.RemoveItem(name2, num3);
					item2.Save();
					for (int j = 0; j < num3; j++)
					{
						___m_nview.InvokeRPC("RPC_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(ZDOVars.s_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;
		}
	}
	[Har