Decompiled source of InventorySlots v1.6.25

InventorySlots.dll

Decompiled a week 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.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using AdventureBackpacks.API.Client;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GUIFramework;
using HarmonyLib;
using InventoryCompatibility;
using InventoryPersistence;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
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: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InventorySlots")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("sighsorry")]
[assembly: AssemblyProduct("InventorySlots")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("A57F2112-F59E-48EF-9D76-F2E4580F7401")]
[assembly: AssemblyFileVersion("1.6.25")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.25.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LocalizationManager
{
	internal static class Localizer
	{
		private static readonly string[] FileExtensions = new string[2] { ".yml", ".json" };

		private static readonly ManualLogSource Log = Logger.CreateLogSource("InventorySlots.Localization");

		private static BaseUnityPlugin? _plugin;

		private static bool _loaded;

		public static event Action? OnLocalizationComplete;

		public static void Load(BaseUnityPlugin plugin)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			_plugin = plugin;
			if (_loaded)
			{
				TryLoadCurrentLanguage();
				return;
			}
			_loaded = true;
			PatchLocalization(new Harmony(plugin.Info.Metadata.GUID + ".LocalizationManager"));
			TryLoadCurrentLanguage();
		}

		private static void PatchLocalization(Harmony harmony)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Localizer), "LocalizationSetupLanguagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Localizer), "FejdStartupSetupGuiPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void LocalizationSetupLanguagePostfix(Localization __instance, string language)
		{
			LoadLocalization(__instance, language);
		}

		private static void FejdStartupSetupGuiPostfix()
		{
			TryLoadCurrentLanguage();
		}

		private static void TryLoadCurrentLanguage()
		{
			if (PlatformInitializer.PlatformInitialized)
			{
				Localization instance = Localization.instance;
				if (instance != null)
				{
					LoadLocalization(instance, instance.GetSelectedLanguage());
				}
			}
		}

		private static void LoadLocalization(Localization localization, string language)
		{
			if ((Object)(object)_plugin == (Object)null || localization == null)
			{
				return;
			}
			Dictionary<string, string> dictionary = LoadLanguageDictionary("English");
			if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase))
			{
				Merge(dictionary, LoadLanguageDictionary(language));
			}
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				localization.AddWord(item.Key, item.Value);
			}
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static Dictionary<string, string> LoadLanguageDictionary(string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			Merge(dictionary, LoadEmbeddedLanguage(language));
			foreach (string item in FindExternalTranslationFiles(language))
			{
				try
				{
					Merge(dictionary, ParseTranslations(File.ReadAllText(item), item));
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Failed to load localization file " + item + ": " + ex.Message));
				}
			}
			return dictionary;
		}

		private static Dictionary<string, string> LoadEmbeddedLanguage(string language)
		{
			string[] fileExtensions = FileExtensions;
			foreach (string text in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + text);
				if (array != null)
				{
					return ParseTranslations(Encoding.UTF8.GetString(array), language + text);
				}
			}
			if (string.Equals(language, "English", StringComparison.OrdinalIgnoreCase))
			{
				Log.LogWarning((object)"Found no embedded English localization for InventorySlots.");
			}
			return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
		}

		private static IEnumerable<string> FindExternalTranslationFiles(string language)
		{
			if ((Object)(object)_plugin == (Object)null)
			{
				yield break;
			}
			string modName = _plugin.Info.Metadata.Name;
			foreach (string root in GetExternalTranslationRoots())
			{
				if (!Directory.Exists(root))
				{
					continue;
				}
				string[] fileExtensions = FileExtensions;
				foreach (string text in fileExtensions)
				{
					string searchPattern = modName + "." + language + text;
					string[] files = Directory.GetFiles(root, searchPattern, SearchOption.AllDirectories);
					for (int j = 0; j < files.Length; j++)
					{
						yield return files[j];
					}
				}
			}
		}

		private static IEnumerable<string> GetExternalTranslationRoots()
		{
			if (!string.IsNullOrWhiteSpace(Paths.PluginPath))
			{
				yield return Paths.PluginPath;
			}
			if ((Object)(object)_plugin != (Object)null)
			{
				yield return Path.Combine(Paths.ConfigPath, _plugin.Info.Metadata.GUID + "Translations");
			}
		}

		private static Dictionary<string, string> ParseTranslations(string text, string source)
		{
			try
			{
				return new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to parse localization source " + source + ": " + ex.Message));
				return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			}
		}

		private static void Merge(Dictionary<string, string> target, Dictionary<string, string> source)
		{
			foreach (KeyValuePair<string, string> item in source)
			{
				target[item.Key] = item.Value;
			}
		}

		private static byte[]? ReadEmbeddedFileBytes(string resourceFileName)
		{
			if ((Object)(object)_plugin == (Object)null)
			{
				return null;
			}
			Assembly assembly = ((object)_plugin).GetType().Assembly;
			string text = assembly.GetManifestResourceNames().FirstOrDefault((string name) => name.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				return null;
			}
			using Stream stream = assembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace InventoryPersistence
{
	internal static class LinkCompatibleFileWriter
	{
		private const int ErrorSymlinkNotSupported = 1464;

		internal static Exception? WriteAllText(string destinationPath, string contents)
		{
			string? directoryName = Path.GetDirectoryName(destinationPath);
			if (string.IsNullOrEmpty(directoryName))
			{
				throw new ArgumentException("The destination must include a directory.", "destinationPath");
			}
			Directory.CreateDirectory(directoryName);
			string text = destinationPath + "." + Guid.NewGuid().ToString("N") + ".tmp";
			try
			{
				File.WriteAllText(text, contents);
				if (!File.Exists(destinationPath))
				{
					File.Move(text, destinationPath);
					text = null;
					return null;
				}
				try
				{
					File.Replace(text, destinationPath, null);
					text = null;
					return null;
				}
				catch (Exception ex) when (IsLinkReplacementUnsupported(ex))
				{
					File.WriteAllText(destinationPath, contents);
					Exception ex2 = ex;
					return ex;
				}
			}
			finally
			{
				if (!string.IsNullOrEmpty(text) && File.Exists(text))
				{
					File.Delete(text);
				}
			}
		}

		internal static bool IsLinkReplacementUnsupported(Exception exception)
		{
			if (!(exception is NotSupportedException))
			{
				if (exception is IOException)
				{
					return (exception.HResult & 0xFFFF) == 1464;
				}
				return false;
			}
			return true;
		}
	}
}
namespace InventoryCompatibility
{
	internal static class PathOfValheimanActions
	{
		private const string PovOwner = "treextr.pathofvalheiman";

		private static Harmony? _patches;

		private static readonly List<(MethodBase Target, Patch Patch, HarmonyPatchType Kind)> Removed = new List<(MethodBase, Patch, HarmonyPatchType)>();

		private static Action<string>? _hostButtons;

		private static Func<string>? _buttonsHost;

		private static string? _previousHost;

		private static string? _owner;

		internal static void Install(Assembly assembly, string owner)
		{
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			if (_patches != null)
			{
				return;
			}
			Type type = assembly.GetType("PassiveTree.QuickStack", throwOnError: true);
			Type type2 = assembly.GetType("Valheiman.Api.QuickStack", throwOnError: true);
			MethodInfo methodInfo = Require(type2, "HostButtons", typeof(void), new Type[1] { typeof(string) });
			MethodInfo methodInfo2 = Require(type2, "get_ButtonsHostedBy", typeof(string), Array.Empty<Type>());
			if (!type2.IsVisible || !methodInfo.IsPublic || !methodInfo2.IsPublic)
			{
				throw new MissingMethodException(type2.FullName, "HostButtons");
			}
			MethodInfo methodInfo3 = Require(type, "Run", typeof(void), new Type[1] { typeof(Player) });
			MethodInfo methodInfo4 = Require(type, "Sort", typeof(void), new Type[1] { typeof(Player) });
			MethodInfo methodInfo5 = Require(type, "Make", typeof(void), new Type[1] { typeof(InventoryGui) });
			Type declaring = type.GetNestedType("Response", BindingFlags.NonPublic) ?? throw new TypeLoadException("PoV QuickStack.Response");
			Type declaring2 = type.GetNestedType("Keys", BindingFlags.NonPublic) ?? throw new TypeLoadException("PoV QuickStack.Keys");
			MethodInfo target = AccessTools.DeclaredMethod(typeof(Container), "RPC_StackResponse", new Type[2]
			{
				typeof(long),
				typeof(bool)
			}, (Type[])null);
			MethodInfo target2 = AccessTools.DeclaredMethod(typeof(Player), "Update", Type.EmptyTypes, (Type[])null);
			List<(MethodBase Target, Patch Patch, HarmonyPatchType Kind)> observers = new List<(MethodBase, Patch, HarmonyPatchType)>();
			Find(target, declaring, (HarmonyPatchType)1);
			Find(target, declaring, (HarmonyPatchType)4);
			Find(target2, declaring2, (HarmonyPatchType)2);
			_hostButtons = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), methodInfo);
			_buttonsHost = (Func<string>)Delegate.CreateDelegate(typeof(Func<string>), methodInfo2);
			_previousHost = _buttonsHost();
			_owner = owner;
			_patches = new Harmony(owner + ".pov.actions");
			try
			{
				HarmonyMethod val = new HarmonyMethod(typeof(PathOfValheimanActions), "Suppress", (Type[])null);
				_patches.Patch((MethodBase)methodInfo3, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patches.Patch((MethodBase)methodInfo4, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patches.Patch((MethodBase)methodInfo5, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_hostButtons(owner);
				foreach (var item in observers)
				{
					Removed.Add(item);
					_patches.Unpatch(item.Target, item.Patch.PatchMethod);
				}
			}
			catch
			{
				Dispose();
				throw;
			}
			unsafe void Find(MethodBase methodBase, Type type3, HarmonyPatchType kind)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Invalid comparison between Unknown and I4
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Invalid comparison between Unknown and I4
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				Patches patchInfo = Harmony.GetPatchInfo(methodBase);
				Patch[] array = (((int)kind != 1) ? (((int)kind != 2) ? patchInfo?.Finalizers : patchInfo?.Postfixes) : patchInfo?.Prefixes)?.Where((Patch p) => p.owner == "treextr.pathofvalheiman" && p.PatchMethod.DeclaringType == type3).ToArray() ?? Array.Empty<Patch>();
				if (array.Length != 1)
				{
					throw new NotSupportedException("PoV action observer changed: " + type3.FullName + "/" + ((object)(*(HarmonyPatchType*)(&kind))/*cast due to .constrained prefix*/).ToString());
				}
				observers.Add((methodBase, array[0], kind));
			}
			static MethodInfo Require(Type type3, string name, Type result, params Type[] args)
			{
				MethodInfo methodInfo6 = AccessTools.DeclaredMethod(type3, name, args, (Type[])null);
				if (methodInfo6 == null || !methodInfo6.IsStatic || methodInfo6.ReturnType != result)
				{
					throw new MissingMethodException(type3.FullName, name);
				}
				return methodInfo6;
			}
		}

		private static bool Suppress()
		{
			return false;
		}

		internal static void Dispose()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0118: 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_0134: Invalid comparison between Unknown and I4
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Invalid comparison between Unknown and I4
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Invalid comparison between Unknown and I4
			foreach (var observer in Removed)
			{
				Patches patchInfo = Harmony.GetPatchInfo(observer.Target);
				ReadOnlyCollection<Patch> obj = (((int)observer.Kind != 1) ? (((int)observer.Kind != 2) ? patchInfo?.Finalizers : patchInfo?.Postfixes) : patchInfo?.Prefixes);
				if (obj == null || !obj.Any((Patch p) => p.owner == observer.Patch.owner && p.PatchMethod == observer.Patch.PatchMethod))
				{
					HarmonyMethod val = new HarmonyMethod(observer.Patch.PatchMethod)
					{
						priority = observer.Patch.priority,
						before = observer.Patch.before,
						after = observer.Patch.after,
						debug = observer.Patch.debug
					};
					new Harmony(observer.Patch.owner).Patch(observer.Target, ((int)observer.Kind == 1) ? val : null, ((int)observer.Kind == 2) ? val : null, (HarmonyMethod)null, ((int)observer.Kind == 4) ? val : null, (HarmonyMethod)null);
				}
			}
			Removed.Clear();
			if (_buttonsHost != null && _buttonsHost() == _owner)
			{
				_hostButtons(_previousHost);
			}
			Harmony? patches = _patches;
			if (patches != null)
			{
				patches.UnpatchSelf();
			}
			_patches = null;
			_hostButtons = null;
			_buttonsHost = null;
			_previousHost = (_owner = null);
		}
	}
	internal static class PathOfValheimanTrashMode
	{
		private static Harmony? _patches;

		private static Func<bool>? _active;

		private static Func<bool>? _popup;

		private static Func<int>? _count;

		private static Action? _exit;

		private static Func<RectTransform>? _plate;

		private static RectTransform? _hiddenPlate;

		internal static void Install(Assembly assembly, string owner)
		{
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			if (_patches != null)
			{
				return;
			}
			Type type = assembly.GetType("PassiveTree.UI.TrashMode", throwOnError: true);
			MethodInfo methodInfo = Require("Build", typeof(void), new Type[1] { typeof(InventoryGui) });
			MethodInfo methodInfo2 = Require("Enter", typeof(void), Array.Empty<Type>());
			MethodInfo methodInfo3 = Require("Press", typeof(void), Array.Empty<Type>());
			_active = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), Require("get_Active", typeof(bool), Array.Empty<Type>()));
			_popup = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), Require("get_PopupOpen", typeof(bool), Array.Empty<Type>()));
			_count = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), Require("get_Count", typeof(int), Array.Empty<Type>()));
			_exit = (Action)Delegate.CreateDelegate(typeof(Action), Require("Exit", typeof(void), Array.Empty<Type>()));
			FieldInfo fieldInfo = AccessTools.DeclaredField(type, "plate");
			if (fieldInfo == null || !fieldInfo.IsStatic || fieldInfo.FieldType != typeof(RectTransform))
			{
				throw new MissingFieldException(type.FullName, "plate");
			}
			_plate = Expression.Lambda<Func<RectTransform>>(Expression.Field(null, fieldInfo), Array.Empty<ParameterExpression>()).Compile();
			_patches = new Harmony(owner + ".pov.delete-ui");
			try
			{
				HarmonyMethod val = new HarmonyMethod(typeof(PathOfValheimanTrashMode), "Suppress", (Type[])null);
				_patches.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patches.Patch((MethodBase)methodInfo2, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patches.Patch((MethodBase)methodInfo3, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Suppress();
			}
			catch
			{
				Dispose();
				throw;
			}
			MethodInfo Require(string name, Type result, params Type[] args)
			{
				MethodInfo methodInfo4 = AccessTools.DeclaredMethod(type, name, args, (Type[])null);
				if (methodInfo4 == null || !methodInfo4.IsStatic || methodInfo4.ReturnType != result)
				{
					throw new MissingMethodException(type.FullName, name);
				}
				return methodInfo4;
			}
		}

		private static bool Suppress()
		{
			if (_active() || _popup() || _count() != 0)
			{
				_exit();
			}
			RectTransform val = _plate();
			if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
			{
				_hiddenPlate = val;
				((Component)val).gameObject.SetActive(false);
			}
			return false;
		}

		internal static void Dispose()
		{
			Harmony? patches = _patches;
			if (patches != null)
			{
				patches.UnpatchSelf();
			}
			_patches = null;
			if ((Object)(object)_hiddenPlate != (Object)null)
			{
				((Component)_hiddenPlate).gameObject.SetActive(true);
			}
			_hiddenPlate = null;
			_active = (_popup = null);
			_count = null;
			_exit = null;
			_plate = null;
		}
	}
}
namespace InventorySlots
{
	[HarmonyPatch(typeof(Player), "AutoPickup", new Type[] { typeof(float) })]
	internal static class AutoPickupCapacityPatch
	{
		private static bool Prepare()
		{
			return !InventorySlotsPlugin.IsDedicatedServer;
		}

		[HarmonyBefore(new string[] { "sighsorry.AdminQoL", "mod.valheim_plus" })]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.Select((Func<CodeInstruction, CodeInstruction>)((CodeInstruction i) => new CodeInstruction(i))).ToList();
			if (!TryMoveWeightCheck(list))
			{
				InventorySlotsPlugin.Log.LogWarning((object)"Auto pickup capacity optimization could not locate one unchanged capacity/weight check pair; leaving pickup checks unchanged.");
			}
			return list;
		}

		private static bool TryMoveWeightCheck(List<CodeInstruction> code)
		{
			MethodInfo load = Method(typeof(ItemDrop), "Load", Array.Empty<Type>());
			MethodInfo capacity = Method(typeof(Inventory), "CanAddItem", new Type[2]
			{
				typeof(ItemData),
				typeof(int)
			});
			MethodInfo weight = Method(typeof(ItemData), "GetWeight", new Type[1] { typeof(int) });
			MethodInfo totalWeight = Method(typeof(Inventory), "GetTotalWeight", Array.Empty<Type>());
			MethodInfo maxWeight = Method(typeof(Player), "GetMaxCarryWeight", Array.Empty<Type>());
			FieldInfo inventory = typeof(Humanoid).GetField("m_inventory", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo item = typeof(ItemDrop).GetField("m_itemData", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			int num = -1;
			int num2 = 0;
			if (load != null && capacity != null && weight != null && totalWeight != null && maxWeight != null && inventory != null && item != null)
			{
				for (int i = 2; i <= code.Count - 18; i++)
				{
					if (Matches(i))
					{
						num = i;
						num2++;
					}
				}
			}
			if (num2 != 1)
			{
				return false;
			}
			List<CodeInstruction> range = code.GetRange(num, 7);
			List<CodeInstruction> range2 = code.GetRange(num + 7, 11);
			range2[0].labels.AddRange(range[0].labels);
			range[0].labels.Clear();
			code.RemoveRange(num, 18);
			code.InsertRange(num, range2);
			code.InsertRange(num + 11, range);
			return true;
			int BranchTarget(Label label)
			{
				int num3 = -1;
				for (int j = 0; j < code.Count; j++)
				{
					if (code[j].labels.Contains(label))
					{
						if (num3 >= 0)
						{
							return -1;
						}
						num3 = j;
					}
				}
				return num3;
			}
			bool LoadsField(int index, FieldInfo field)
			{
				if (code[index].opcode == OpCodes.Ldfld)
				{
					return object.Equals(code[index].operand, field);
				}
				return false;
			}
			bool Matches(int start)
			{
				CodeInstruction drop = code[start + 2];
				if (!CodeInstructionExtensions.IsLdloc(drop, (LocalBuilder)null) || !SameDrop(start - 2) || !CodeInstructionExtensions.Calls(code[start - 1], load) || code[start].opcode != OpCodes.Ldarg_0 || !LoadsField(start + 1, inventory) || !LoadsField(start + 3, item) || code[start + 4].opcode != OpCodes.Ldc_I4_M1 || !CodeInstructionExtensions.Calls(code[start + 5], capacity) || code[start + 6].opcode != OpCodes.Brfalse || !SameDrop(start + 7) || !LoadsField(start + 8, item) || code[start + 9].opcode != OpCodes.Ldc_I4_M1 || !CodeInstructionExtensions.Calls(code[start + 10], weight) || code[start + 11].opcode != OpCodes.Ldarg_0 || !LoadsField(start + 12, inventory) || !CodeInstructionExtensions.Calls(code[start + 13], totalWeight) || code[start + 14].opcode != OpCodes.Add || code[start + 15].opcode != OpCodes.Ldarg_0 || !CodeInstructionExtensions.Calls(code[start + 16], maxWeight) || code[start + 17].opcode != OpCodes.Bgt || !(code[start + 6].operand is Label label) || !(code[start + 17].operand is Label label2))
				{
					return false;
				}
				int num3 = BranchTarget(label);
				if (num3 < start + 18 || BranchTarget(label2) != num3)
				{
					return false;
				}
				for (int j = start; j < start + 18; j++)
				{
					if (code[j].blocks.Count != 0 || (j != start && code[j].labels.Count != 0))
					{
						return false;
					}
				}
				return true;
				bool SameDrop(int index)
				{
					if (code[index].opcode == drop.opcode)
					{
						return object.Equals(code[index].operand, drop.operand);
					}
					return false;
				}
			}
			static MethodInfo Method(Type type, string name, params Type[] parameters)
			{
				return type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null);
			}
		}
	}
	[BepInPlugin("sighsorry.InventorySlots", "InventorySlots", "1.6.25")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("Azumatt.AzuExtendedPlayerInventory")]
	[BepInIncompatibility("shudnal.ExtraSlots")]
	[BepInIncompatibility("shudnal.ExtraSlotsCustomSlots")]
	[BepInIncompatibility("randyknapp.mods.equipmentandquickslots")]
	[BepInIncompatibility("com.bruce.valheim.comfyquickslots")]
	[BepInIncompatibility("goldenrevolver.quick_stack_store")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class InventorySlotsPlugin : BaseUnityPlugin
	{
		private sealed class AzuCraftyBoxesApi
		{
			private readonly MethodInfo _getNearbyContainersMethod;

			private readonly MethodInfo _canItemBePulledMethod;

			private readonly MethodInfo? _shouldPreventMethod;

			private readonly FieldInfo? _rangeField;

			private readonly FieldInfo? _leaveOneField;

			private readonly FieldInfo? _resourceStringField;

			private readonly FieldInfo? _flashColorField;

			private readonly FieldInfo? _unFlashColorField;

			private readonly Dictionary<Type, MethodInfo?> _getPrefabNameMethods = new Dictionary<Type, MethodInfo>();

			private readonly Dictionary<Type, MethodInfo?> _itemCountMethods = new Dictionary<Type, MethodInfo>();

			private ConfigEntryBase? _rangeConfig;

			private ConfigEntryBase? _leaveOneConfig;

			private ConfigEntryBase? _resourceStringConfig;

			private ConfigEntryBase? _flashColorConfig;

			private ConfigEntryBase? _unFlashColorConfig;

			private AzuCraftyBoxesApi(MethodInfo getNearbyContainersMethod, MethodInfo canItemBePulledMethod, MethodInfo? shouldPreventMethod, FieldInfo? rangeField, FieldInfo? leaveOneField, FieldInfo? resourceStringField, FieldInfo? flashColorField, FieldInfo? unFlashColorField)
			{
				_getNearbyContainersMethod = getNearbyContainersMethod;
				_canItemBePulledMethod = canItemBePulledMethod;
				_shouldPreventMethod = shouldPreventMethod;
				_rangeField = rangeField;
				_leaveOneField = leaveOneField;
				_resourceStringField = resourceStringField;
				_flashColorField = flashColorField;
				_unFlashColorField = unFlashColorField;
			}

			public static bool TryCreate(Assembly assembly, out AzuCraftyBoxesApi? api, out string detail)
			{
				api = null;
				Type type = assembly.GetType("AzuCraftyBoxes.API");
				Type type2 = assembly.GetType("AzuCraftyBoxes.AzuCraftyBoxesPlugin");
				Type type3 = assembly.GetType("AzuCraftyBoxes.Util.Functions.MiscFunctions");
				MethodInfo methodInfo = (type?.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo method) => method.Name == "GetNearbyContainers" && method.IsGenericMethodDefinition && method.GetParameters().Length == 2))?.MakeGenericMethod(typeof(Player));
				MethodInfo methodInfo2 = type?.GetMethod("CanItemBePulled", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
				{
					typeof(string),
					typeof(string)
				}, null);
				if (methodInfo == null || methodInfo2 == null)
				{
					detail = "required API methods were not found";
					return false;
				}
				api = new AzuCraftyBoxesApi(methodInfo, methodInfo2, type3?.GetMethod("ShouldPrevent", BindingFlags.Static | BindingFlags.NonPublic), type2?.GetField("mRange", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), type2?.GetField("leaveOne", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), type2?.GetField("resourceString", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), type2?.GetField("flashColor", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), type2?.GetField("unFlashColor", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
				detail = "";
				return true;
			}

			public IEnumerable? GetNearbyContainers(Player player, float range)
			{
				return _getNearbyContainersMethod.Invoke(null, new object[2] { player, range }) as IEnumerable;
			}

			public bool CanItemBePulled(string containerPrefab, string itemPrefab)
			{
				try
				{
					object obj = _canItemBePulledMethod.Invoke(null, new object[2] { containerPrefab, itemPrefab });
					return obj is bool && (bool)obj;
				}
				catch
				{
					return false;
				}
			}

			public bool ShouldPrevent()
			{
				if (_shouldPreventMethod == null)
				{
					return false;
				}
				try
				{
					object obj = _shouldPreventMethod.Invoke(null, null);
					return obj is bool && (bool)obj;
				}
				catch
				{
					return false;
				}
			}

			public float GetRange()
			{
				object cachedConfigEntryValue = GetCachedConfigEntryValue(_rangeField, ref _rangeConfig);
				if (cachedConfigEntryValue == null)
				{
					return 20f;
				}
				try
				{
					return Convert.ToSingle(cachedConfigEntryValue);
				}
				catch
				{
					return 20f;
				}
			}

			public bool GetLeaveOne()
			{
				string a = GetCachedConfigEntryValue(_leaveOneField, ref _leaveOneConfig)?.ToString() ?? "";
				if (!string.Equals(a, "On", StringComparison.OrdinalIgnoreCase))
				{
					return string.Equals(a, "True", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}

			public string InvokeString(object instance, string methodName)
			{
				Type type = instance.GetType();
				if (!_getPrefabNameMethods.TryGetValue(type, out MethodInfo value))
				{
					value = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
					_getPrefabNameMethods[type] = value;
				}
				try
				{
					return (value?.Invoke(instance, null) as string) ?? "";
				}
				catch
				{
					return "";
				}
			}

			public int InvokeInt(object instance, string methodName, string argument)
			{
				Type type = instance.GetType();
				if (!_itemCountMethods.TryGetValue(type, out MethodInfo value))
				{
					value = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
					_itemCountMethods[type] = value;
				}
				try
				{
					return (value?.Invoke(instance, new object[1] { argument }) is int num) ? num : 0;
				}
				catch
				{
					return 0;
				}
			}

			public bool TryFormatRequirementAmount(int available, int required, out string text)
			{
				text = "";
				string text2 = (GetCachedConfigEntryValue(_resourceStringField, ref _resourceStringConfig) as string) ?? "";
				if (string.IsNullOrWhiteSpace(text2))
				{
					text = required.ToString();
					return true;
				}
				try
				{
					text = string.Format(text2, FormatThousands(available), required);
					return true;
				}
				catch
				{
					text = $"{FormatThousands(available)}/{required}";
					return true;
				}
			}

			public bool TryGetRequirementFlashColor(out Color color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				color = default(Color);
				FieldInfo fieldInfo = ((Mathf.Sin(Time.time * 10f) > 0f) ? _flashColorField : _unFlashColorField);
				if (((fieldInfo == _flashColorField) ? GetCachedConfigEntryValue(fieldInfo, ref _flashColorConfig) : GetCachedConfigEntryValue(fieldInfo, ref _unFlashColorConfig)) is Color val)
				{
					color = val;
					return true;
				}
				return false;
			}

			private object? GetCachedConfigEntryValue(FieldInfo? field, ref ConfigEntryBase? config)
			{
				if (field == null)
				{
					return null;
				}
				try
				{
					if (config == null)
					{
						object? value = field.GetValue(null);
						config = (ConfigEntryBase?)((value is ConfigEntryBase) ? value : null);
					}
					ConfigEntryBase? obj = config;
					return (obj != null) ? obj.BoxedValue : null;
				}
				catch
				{
					config = null;
					return null;
				}
			}

			private static string FormatThousands(int number)
			{
				if (number >= 1000000)
				{
					return ((double)number / 1000000.0).ToString("0.#") + "M";
				}
				if (number < 1000)
				{
					return number.ToString();
				}
				return ((double)number / 1000.0).ToString("0.#") + "K";
			}
		}

		private sealed class AdventureBackpacksApi
		{
			private readonly FieldInfo _backpackIsOpenField;

			private readonly FieldInfo _backpackEquippedField;

			private readonly MethodInfo _destroyBackpackContainerProxyMethod;

			private AdventureBackpacksApi(FieldInfo backpackIsOpenField, FieldInfo backpackEquippedField, MethodInfo destroyBackpackContainerProxyMethod)
			{
				_backpackIsOpenField = backpackIsOpenField;
				_backpackEquippedField = backpackEquippedField;
				_destroyBackpackContainerProxyMethod = destroyBackpackContainerProxyMethod;
			}

			public static bool TryCreate(Assembly assembly, out AdventureBackpacksApi? api, out string detail)
			{
				api = null;
				if (!ABAPIClient.IsLoaded())
				{
					detail = "AdventureBackpacks not loaded";
					return false;
				}
				Type? type = assembly.GetType("AdventureBackpacks.Patches.InventoryGuiPatches");
				FieldInfo fieldInfo = type?.GetField("BackpackIsOpen", BindingFlags.Static | BindingFlags.Public);
				FieldInfo fieldInfo2 = type?.GetField("BackpackEquipped", BindingFlags.Static | BindingFlags.Public);
				MethodInfo methodInfo = assembly.GetType("AdventureBackpacks.Extensions.PlayerExtensions")?.GetMethod("DestroyBackpackContainerProxy", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Player) }, null);
				if (fieldInfo?.FieldType != typeof(bool) || fieldInfo.IsInitOnly || fieldInfo.IsLiteral || fieldInfo2?.FieldType != typeof(bool) || fieldInfo2.IsInitOnly || fieldInfo2.IsLiteral || methodInfo == null || methodInfo.ReturnType != typeof(void) || methodInfo.ContainsGenericParameters)
				{
					detail = "AdventureBackpacks custom-slot unequip cleanup contract was not found";
					return false;
				}
				api = new AdventureBackpacksApi(fieldInfo, fieldInfo2, methodInfo);
				detail = string.Empty;
				return true;
			}

			public bool IsBackpack(ItemData? item)
			{
				if (item == null)
				{
					return false;
				}
				return ABAPIClient.IsBackpack(item);
			}

			public bool IsBackpackEquipped(Player player)
			{
				if ((Object)(object)player == (Object)null)
				{
					return false;
				}
				return ABAPIClient.IsBackpackEquipped(player);
			}

			public void OnCustomBackpackUnequipping(Player player, ItemData item)
			{
				if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || item == null || !IsBackpack(item))
				{
					return;
				}
				try
				{
					InventoryGui instance = InventoryGui.instance;
					if ((Object)(object)instance != (Object)null && instance.IsContainerOpen())
					{
						instance.CloseContainer();
					}
					_backpackIsOpenField.SetValue(null, false);
					_backpackEquippedField.SetValue(null, false);
					_destroyBackpackContainerProxyMethod.Invoke(null, new object[1] { player });
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("AdventureBackpacks custom-slot unequip cleanup failed: " + ex.GetBaseException().Message));
				}
			}
		}

		private sealed class SmoothbrainBackpacksApi
		{
			private readonly MethodInfo _validateBackpackMethod;

			private readonly FieldInfo _visualsField;

			private readonly FieldInfo _equippedBackpackItemField;

			private readonly FieldInfo? _currentBackpackItemHashField;

			private readonly MethodInfo? _setBackpackItemMethod;

			private readonly MethodInfo? _forceSetBackpackEquippedMethod;

			private SmoothbrainBackpacksApi(MethodInfo validateBackpackMethod, FieldInfo visualsField, FieldInfo equippedBackpackItemField, FieldInfo? currentBackpackItemHashField, MethodInfo? setBackpackItemMethod, MethodInfo? forceSetBackpackEquippedMethod)
			{
				_validateBackpackMethod = validateBackpackMethod;
				_visualsField = visualsField;
				_equippedBackpackItemField = equippedBackpackItemField;
				_currentBackpackItemHashField = currentBackpackItemHashField;
				_setBackpackItemMethod = setBackpackItemMethod;
				_forceSetBackpackEquippedMethod = forceSetBackpackEquippedMethod;
			}

			public static bool TryCreate(Assembly assembly, out SmoothbrainBackpacksApi? api, out string detail)
			{
				api = null;
				Type? type = assembly.GetType("Backpacks.Backpacks");
				Type type2 = assembly.GetType("Backpacks.Visual");
				MethodInfo methodInfo = type?.GetMethod("validateBackpack", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[1] { typeof(ItemData) }, null);
				FieldInfo fieldInfo = type2?.GetField("visuals", BindingFlags.Static | BindingFlags.Public);
				FieldInfo fieldInfo2 = type2?.GetField("equippedBackpackItem", BindingFlags.Instance | BindingFlags.Public);
				if (methodInfo == null || fieldInfo == null || fieldInfo2 == null)
				{
					detail = "validateBackpack or Visual fields were not found";
					return false;
				}
				api = new SmoothbrainBackpacksApi(methodInfo, fieldInfo, fieldInfo2, type2?.GetField("currentBackpackItemHash", BindingFlags.Instance | BindingFlags.Public), type2?.GetMethod("setBackpackItem", BindingFlags.Instance | BindingFlags.NonPublic), type2?.GetMethod("forceSetBackpackEquipped", BindingFlags.Instance | BindingFlags.Public));
				detail = "";
				return true;
			}

			public bool IsBackpack(ItemData? item)
			{
				if (item == null)
				{
					return false;
				}
				try
				{
					object obj = _validateBackpackMethod.Invoke(null, new object[1] { item });
					return obj is bool && (bool)obj;
				}
				catch
				{
					return false;
				}
			}

			public void SyncEquippedBackpack(Player player, ItemData? item)
			{
				if ((Object)(object)player == (Object)null || IsUnityNull((Object?)(object)((Humanoid)player).m_visEquipment) || !TryGetVisual(((Humanoid)player).m_visEquipment, out object visual) || visual == null)
				{
					return;
				}
				try
				{
					string text = (((Object)(object)item?.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : "");
					int num = ((!string.IsNullOrWhiteSpace(text)) ? StringExtensionMethods.GetStableHashCode(text) : 0);
					if (_equippedBackpackItemField.GetValue(visual) != item)
					{
						_equippedBackpackItemField.SetValue(visual, item);
					}
					_setBackpackItemMethod?.Invoke(visual, new object[1] { text });
					if (_forceSetBackpackEquippedMethod != null && GetCurrentHash(visual) != num)
					{
						_forceSetBackpackEquippedMethod.Invoke(visual, new object[1] { num });
					}
				}
				catch (Exception)
				{
				}
			}

			private bool TryGetVisual(VisEquipment visEquipment, out object? visual)
			{
				visual = null;
				if (!(_visualsField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(visEquipment))
				{
					return false;
				}
				visual = dictionary[visEquipment];
				return visual != null;
			}

			private int GetCurrentHash(object visual)
			{
				try
				{
					return (_currentBackpackItemHashField?.GetValue(visual) is int num) ? num : 0;
				}
				catch
				{
					return 0;
				}
			}
		}

		private sealed class RustyBagsApi
		{
			private readonly MethodInfo _isBagMethod;

			private readonly MethodInfo _isQuiverMethod;

			private readonly Type _bagEquipmentType;

			private readonly Type _bagType;

			private readonly Type _quiverType;

			private readonly MethodInfo _getBagMethod;

			private readonly MethodInfo _getQuiverMethod;

			private readonly MethodInfo _setBagMethod;

			private readonly MethodInfo _setQuiverMethod;

			private RustyBagsApi(MethodInfo isBagMethod, MethodInfo isQuiverMethod, Type bagEquipmentType, Type bagType, Type quiverType, MethodInfo getBagMethod, MethodInfo getQuiverMethod, MethodInfo setBagMethod, MethodInfo setQuiverMethod)
			{
				_isBagMethod = isBagMethod;
				_isQuiverMethod = isQuiverMethod;
				_bagEquipmentType = bagEquipmentType;
				_bagType = bagType;
				_quiverType = quiverType;
				_getBagMethod = getBagMethod;
				_getQuiverMethod = getQuiverMethod;
				_setBagMethod = setBagMethod;
				_setQuiverMethod = setQuiverMethod;
			}

			public static bool TryCreate(Assembly assembly, out RustyBagsApi? api, out string detail)
			{
				api = null;
				Type type = assembly.GetType("RustyBags.API");
				Type type2 = assembly.GetType("RustyBags.BagEquipment");
				Type type3 = assembly.GetType("RustyBags.Bag");
				Type type4 = assembly.GetType("RustyBags.Quiver");
				MethodInfo methodInfo = type?.GetMethod("IsBag", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
				MethodInfo methodInfo2 = type?.GetMethod("IsQuiver", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
				MethodInfo methodInfo3 = type2?.GetMethod("GetBag", BindingFlags.Instance | BindingFlags.Public);
				MethodInfo methodInfo4 = type2?.GetMethod("GetQuiver", BindingFlags.Instance | BindingFlags.Public);
				MethodInfo methodInfo5 = type2?.GetMethod("SetBag", BindingFlags.Instance | BindingFlags.NonPublic);
				MethodInfo methodInfo6 = type2?.GetMethod("SetQuiver", BindingFlags.Instance | BindingFlags.Public);
				if (methodInfo == null || methodInfo2 == null || type2 == null || type3 == null || type4 == null || methodInfo3 == null || methodInfo4 == null || methodInfo5 == null || methodInfo6 == null)
				{
					detail = "RustyBags API or BagEquipment methods were not found";
					return false;
				}
				api = new RustyBagsApi(methodInfo, methodInfo2, type2, type3, type4, methodInfo3, methodInfo4, methodInfo5, methodInfo6);
				detail = "";
				return true;
			}

			public bool IsBag(ItemData? item)
			{
				if (item?.m_shared == null)
				{
					return false;
				}
				try
				{
					object obj = _isBagMethod.Invoke(null, new object[1] { item.m_shared.m_name });
					return obj is bool && (bool)obj;
				}
				catch
				{
					return false;
				}
			}

			public bool IsQuiver(ItemData? item)
			{
				if (item?.m_shared == null)
				{
					return false;
				}
				try
				{
					object obj = _isQuiverMethod.Invoke(null, new object[1] { item.m_shared.m_name });
					return obj is bool && (bool)obj;
				}
				catch
				{
					return false;
				}
			}

			public void SyncBag(Player player, ItemData? item)
			{
				if (item == null || _bagType.IsInstanceOfType(item))
				{
					InvokeEquipmentSetter(player, _setBagMethod, item);
				}
			}

			public void SyncQuiver(Player player, ItemData? item)
			{
				if (item == null || _quiverType.IsInstanceOfType(item))
				{
					InvokeEquipmentSetter(player, _setQuiverMethod, item);
				}
			}

			public void ClearBagIfCurrent(Player player, ItemData item)
			{
				object bagEquipment = GetBagEquipment(player);
				if (bagEquipment != null && _getBagMethod.Invoke(bagEquipment, Array.Empty<object>()) == item)
				{
					_setBagMethod.Invoke(bagEquipment, new object[1]);
				}
			}

			public void ClearQuiverIfCurrent(Player player, ItemData item)
			{
				object bagEquipment = GetBagEquipment(player);
				if (bagEquipment != null && _getQuiverMethod.Invoke(bagEquipment, Array.Empty<object>()) == item)
				{
					_setQuiverMethod.Invoke(bagEquipment, new object[1]);
				}
			}

			private void InvokeEquipmentSetter(Player player, MethodInfo setter, ItemData? item)
			{
				object bagEquipment = GetBagEquipment(player);
				if (bagEquipment == null)
				{
					return;
				}
				try
				{
					setter.Invoke(bagEquipment, new object[1] { item });
				}
				catch (Exception)
				{
				}
			}

			private object? GetBagEquipment(Player player)
			{
				if ((Object)(object)player == (Object)null)
				{
					return null;
				}
				try
				{
					return ((Component)player).GetComponent(_bagEquipmentType);
				}
				catch
				{
					return null;
				}
			}
		}

		private sealed class BetterArcheryQuiverApi
		{
			private readonly FieldInfo _quiverEnabledField;

			private readonly FieldInfo _quiverRowIndexField;

			private ConfigEntry<bool>? _quiverEnabledConfig;

			private bool _quiverRowIndexResolved;

			private int _quiverRowIndex;

			private BetterArcheryQuiverApi(FieldInfo quiverEnabledField, FieldInfo quiverRowIndexField)
			{
				_quiverEnabledField = quiverEnabledField;
				_quiverRowIndexField = quiverRowIndexField;
			}

			public static bool TryCreate(Assembly assembly, out BetterArcheryQuiverApi? api, out string detail)
			{
				api = null;
				Type type = assembly.GetTypes().FirstOrDefault((Type candidate) => candidate.IsClass && candidate.Name == "BetterArchery");
				if (type == null)
				{
					detail = "BetterArchery type was not found";
					return false;
				}
				FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
				FieldInfo fieldInfo = fields.FirstOrDefault((FieldInfo field) => string.Equals(field.Name, "ConfigQuiverEnabled", StringComparison.OrdinalIgnoreCase));
				FieldInfo fieldInfo2 = fields.FirstOrDefault((FieldInfo field) => string.Equals(field.Name, "QuiverRowIndex", StringComparison.OrdinalIgnoreCase));
				if (fieldInfo == null || fieldInfo2 == null)
				{
					detail = "quiver config fields were not found";
					return false;
				}
				api = new BetterArcheryQuiverApi(fieldInfo, fieldInfo2);
				detail = "";
				return true;
			}

			public bool IsQuiverCell(Vector2i pos, bool includeRestockableSlots)
			{
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (_quiverEnabledConfig == null)
					{
						_quiverEnabledConfig = _quiverEnabledField.GetValue(null) as ConfigEntry<bool>;
					}
				}
				catch
				{
					_quiverEnabledConfig = null;
				}
				if (_quiverEnabledConfig == null || !_quiverEnabledConfig.Value)
				{
					return false;
				}
				if (!_quiverRowIndexResolved || _quiverRowIndex == 0)
				{
					try
					{
						_quiverRowIndex = ((_quiverRowIndexField.GetValue(null) is int num) ? num : 0);
					}
					catch
					{
						_quiverRowIndex = 0;
					}
					_quiverRowIndexResolved = _quiverRowIndex != 0;
				}
				if (_quiverRowIndex == 0)
				{
					return false;
				}
				if (pos.y == _quiverRowIndex - 1)
				{
					return true;
				}
				if (pos.y == _quiverRowIndex)
				{
					if (!includeRestockableSlots)
					{
						return pos.x > 2;
					}
					return true;
				}
				return false;
			}
		}

		private sealed class CircletExtendedApi
		{
			private delegate ItemData? GetCircletDelegate(Humanoid humanoid);

			private delegate ItemData? SetCircletDelegate(Humanoid humanoid, ItemData? item);

			private delegate bool IsCircletDelegate(ItemData item);

			private delegate bool CanEquipWithHelmetDelegate(ItemData? helmet);

			private readonly GetCircletDelegate _getCirclet;

			private readonly SetCircletDelegate _setCirclet;

			private readonly IsCircletDelegate _isCirclet;

			private readonly CanEquipWithHelmetDelegate _canEquipWithHelmet;

			private readonly ConfigEntry<bool> _enablePutOnTop;

			private bool _failed;

			private CircletExtendedApi(GetCircletDelegate getCirclet, SetCircletDelegate setCirclet, IsCircletDelegate isCirclet, CanEquipWithHelmetDelegate canEquipWithHelmet, ConfigEntry<bool> enablePutOnTop)
			{
				_getCirclet = getCirclet;
				_setCirclet = setCirclet;
				_isCirclet = isCirclet;
				_canEquipWithHelmet = canEquipWithHelmet;
				_enablePutOnTop = enablePutOnTop;
			}

			public static bool TryCreate(Assembly assembly, out CircletExtendedApi? api, out string detail)
			{
				api = null;
				Type type = assembly.GetType("CircletExtended.HumanoidExtension");
				Type type2 = assembly.GetType("CircletExtended.CircletItem");
				Type type3 = assembly.GetType("CircletExtended.CircletExtended");
				MethodInfo methodInfo = type?.GetMethod("GetCirclet", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Humanoid) }, null);
				MethodInfo methodInfo2 = type?.GetMethod("SetCirclet", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
				{
					typeof(Humanoid),
					typeof(ItemData)
				}, null);
				MethodInfo methodInfo3 = type2?.GetMethod("IsCircletItem", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ItemData) }, null);
				MethodInfo methodInfo4 = type2?.GetMethod("CanCircletBeEquippedWithHelmet", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ItemData) }, null);
				FieldInfo fieldInfo = type3?.GetField("enablePutOnTop", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (methodInfo?.ReturnType != typeof(ItemData) || methodInfo2?.ReturnType != typeof(ItemData) || methodInfo3?.ReturnType != typeof(bool) || methodInfo4?.ReturnType != typeof(bool) || fieldInfo == null || !typeof(ConfigEntryBase).IsAssignableFrom(fieldInfo.FieldType))
				{
					detail = "expected HumanoidExtension, CircletItem, or enablePutOnTop members were not found";
					return false;
				}
				try
				{
					if (!(fieldInfo.GetValue(null) is ConfigEntry<bool> enablePutOnTop))
					{
						detail = "enablePutOnTop was not initialized";
						return false;
					}
					api = new CircletExtendedApi((GetCircletDelegate)Delegate.CreateDelegate(typeof(GetCircletDelegate), methodInfo), (SetCircletDelegate)Delegate.CreateDelegate(typeof(SetCircletDelegate), methodInfo2), (IsCircletDelegate)Delegate.CreateDelegate(typeof(IsCircletDelegate), methodInfo3), (CanEquipWithHelmetDelegate)Delegate.CreateDelegate(typeof(CanEquipWithHelmetDelegate), methodInfo4), enablePutOnTop);
					detail = "";
					return true;
				}
				catch (Exception ex)
				{
					detail = "failed to bind CircletExtended delegates: " + ex.Message;
					return false;
				}
			}

			public bool TryGetPutOnTopEnabled(out bool enabled)
			{
				enabled = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					enabled = _enablePutOnTop.Value;
					return true;
				}
				catch (Exception exception)
				{
					return Fail("reading enablePutOnTop", exception);
				}
			}

			public bool TryIsCircletCustomType(ItemData item, out bool isCirclet)
			{
				isCirclet = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					isCirclet = _isCirclet(item);
					return true;
				}
				catch (Exception exception)
				{
					return Fail("checking the Circlet item type", exception);
				}
			}

			public bool TryCanEquipWithHelmet(ItemData? helmet, out bool compatible)
			{
				compatible = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					compatible = _canEquipWithHelmet(helmet);
					return true;
				}
				catch (Exception exception)
				{
					return Fail("checking helmet compatibility", exception);
				}
			}

			public bool TrySetCirclet(Humanoid humanoid, ItemData item, out bool changed)
			{
				changed = false;
				if (!TryGetCirclet(humanoid, out ItemData item2))
				{
					return false;
				}
				if (item2 == item)
				{
					return true;
				}
				return TrySetCircletValue(humanoid, item, out changed);
			}

			public bool TryIsCurrentCirclet(Humanoid humanoid, ItemData item, out bool isCurrent)
			{
				isCurrent = false;
				if (!TryGetCirclet(humanoid, out ItemData item2))
				{
					return false;
				}
				isCurrent = item2 == item;
				return true;
			}

			public bool TryClearCirclet(Humanoid humanoid, ItemData item, out bool changed)
			{
				changed = false;
				if (!TryGetCirclet(humanoid, out ItemData item2))
				{
					return false;
				}
				if (item2 != item)
				{
					return true;
				}
				return TrySetCircletValue(humanoid, null, out changed);
			}

			private bool TryGetCirclet(Humanoid humanoid, out ItemData? item)
			{
				item = null;
				if (_failed)
				{
					return false;
				}
				try
				{
					item = _getCirclet(humanoid);
					return true;
				}
				catch (Exception exception)
				{
					return Fail("reading the equipped Circlet", exception);
				}
			}

			private bool TrySetCircletValue(Humanoid humanoid, ItemData? item, out bool changed)
			{
				changed = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					if (_setCirclet(humanoid, item) != item)
					{
						return Fail("SetCirclet returned an unexpected item");
					}
					changed = true;
					return true;
				}
				catch (Exception exception)
				{
					return Fail("updating the equipped Circlet", exception);
				}
			}

			private bool Fail(string operation, Exception? exception = null)
			{
				if (!_failed)
				{
					string text = exception?.InnerException?.Message ?? exception?.Message ?? "unknown result";
					Log.LogWarning((object)("CircletExtended compatibility disabled while " + operation + ": " + text));
				}
				_failed = true;
				return false;
			}
		}

		private sealed class CompatApiRuntimeState<TApi> where TApi : class
		{
			public TApi? Api;

			public bool ReflectionFailed;
		}

		private sealed class CompatRuntimeState
		{
			public readonly CompatApiRuntimeState<AzuCraftyBoxesApi> AzuCraftyBoxes = new CompatApiRuntimeState<AzuCraftyBoxesApi>();

			public readonly CompatApiRuntimeState<JewelcraftingTooltipApi> JewelcraftingTooltip = new CompatApiRuntimeState<JewelcraftingTooltipApi>();

			public readonly CompatApiRuntimeState<JewelcraftingGemApi> JewelcraftingGem = new CompatApiRuntimeState<JewelcraftingGemApi>();

			public readonly CompatApiRuntimeState<JewelcraftingEffectApi> JewelcraftingEffect = new CompatApiRuntimeState<JewelcraftingEffectApi>();

			public readonly CompatApiRuntimeState<JewelcraftingSlotApi> JewelcraftingSlot = new CompatApiRuntimeState<JewelcraftingSlotApi>();

			public readonly CompatApiRuntimeState<JewelcraftingCraftingSocketUiApi> JewelcraftingCraftingSocketUi = new CompatApiRuntimeState<JewelcraftingCraftingSocketUiApi>();

			public readonly CompatApiRuntimeState<JewelcraftingGemCuttingApi> JewelcraftingGemCutting = new CompatApiRuntimeState<JewelcraftingGemCuttingApi>();

			public readonly CompatApiRuntimeState<JewelcraftingVisualApi> JewelcraftingVisual = new CompatApiRuntimeState<JewelcraftingVisualApi>();

			public readonly CompatApiRuntimeState<ItemRequiresSkillLevelApi> ItemRequiresSkillLevel = new CompatApiRuntimeState<ItemRequiresSkillLevelApi>();

			public readonly CompatApiRuntimeState<RecycleNReclaimApi> RecycleNReclaim = new CompatApiRuntimeState<RecycleNReclaimApi>();

			public readonly CompatApiRuntimeState<AdventureBackpacksApi> AdventureBackpacks = new CompatApiRuntimeState<AdventureBackpacksApi>();

			public readonly CompatApiRuntimeState<SmoothbrainBackpacksApi> SmoothbrainBackpacks = new CompatApiRuntimeState<SmoothbrainBackpacksApi>();

			public readonly CompatApiRuntimeState<RustyBagsApi> RustyBags = new CompatApiRuntimeState<RustyBagsApi>();

			public readonly CompatApiRuntimeState<MagicSupremacyApi> MagicSupremacy = new CompatApiRuntimeState<MagicSupremacyApi>();

			public readonly CompatApiRuntimeState<BetterArcheryQuiverApi> BetterArcheryQuiver = new CompatApiRuntimeState<BetterArcheryQuiverApi>();

			public readonly CompatApiRuntimeState<VeiledRecipesApi> VeiledRecipes = new CompatApiRuntimeState<VeiledRecipesApi>();

			public readonly CompatApiRuntimeState<CircletExtendedApi> CircletExtended = new CompatApiRuntimeState<CircletExtendedApi>();

			public readonly CompatApiRuntimeState<HipLanternApi> HipLantern = new CompatApiRuntimeState<HipLanternApi>();
		}

		private delegate bool CompatApiFactory<TApi>(Assembly assembly, out TApi? api, out string detail) where TApi : class;

		private enum ContainerAccessMode
		{
			Unavailable,
			DirectOwner,
			ExternalMultiUserChestRemote
		}

		private delegate bool TryGetContainerHoldContext(Player player, out Container container);

		private enum ContainerAreaFailure : byte
		{
			None,
			InvalidRequest,
			NotOwner,
			InUse,
			NoAccess,
			OutOfRange,
			Unavailable,
			Unsupported,
			Busy
		}

		private sealed class ContainerAreaSession
		{
			public Player Player;

			public Inventory Inventory;

			public Container Anchor;

			public ZDOID AnchorId;

			public bool QuickStack;

			public bool OpenAnchor;

			public Func<bool>? Interaction;

			public bool InteractionRunning;

			public bool InteractionSucceeded;

			public bool Completed;

			public List<Container> Targets;

			public int Next;

			public int Moved;

			public int Effects;

			public Container? Pending;

			public bool PendingNative;

			public ContainerAreaRequestIdentity PendingIdentity;

			public long Token;

			public uint DataRevision;

			public ushort OwnerRevision;

			public long Expires;

			public ContainerAreaHandoffDecision Decision;

			public ContainerAreaActionKind Action
			{
				get
				{
					if (Interaction == null)
					{
						if (!QuickStack)
						{
							return ContainerAreaActionKind.Restock;
						}
						return ContainerAreaActionKind.QuickStack;
					}
					return ContainerAreaActionKind.Interaction;
				}
			}
		}

		private enum ContainerPreviewPhase
		{
			Hidden,
			PreviewVisible,
			RestorePending,
			RealInventoryVisible
		}

		private enum ContainerTakeStacksMode
		{
			CurrentContainerMatchingStacks,
			AreaFavoriteRestock
		}

		private sealed class ControllerActionOption
		{
			public ControllerHotkeyAction Action { get; }

			public string Label { get; }

			public ControllerActionOption(ControllerHotkeyAction action, string label)
			{
				Action = action;
				Label = label;
			}
		}

		private sealed class CraftingListDetailState
		{
			public RectTransform? Root;

			public Image? Icon;

			public TMP_Text? Title;

			public TMP_Text? Body;

			public RectTransform? GemRow;

			public readonly List<JewelcraftingGemIconData> GemIcons = new List<JewelcraftingGemIconData>();

			public string GemSignature = "";

			public RectTransform? Style;

			public TMP_Text? StyleLabel;

			public CraftingRecipeStyleButtonMarker? StyleMarker;

			public readonly ScrollableTooltipBodyState Scroll = new ScrollableTooltipBodyState();

			public CraftingTabAdapterKind Tab;

			public Recipe? Recipe;

			public ItemData? Item;

			public int Variant = -1;

			public bool CanCraft;

			public int LocalizationVersion = -1;

			public float NextRefresh;

			public string BodyText = "";

			public string TitleText = "";

			public string StatusText = "";
		}

		private readonly struct CraftingRequirementAvailabilityCacheEntry
		{
			public int Amount { get; }

			public float ExpiresAt { get; }

			public CraftingRequirementAvailabilityCacheEntry(int amount, float expiresAt)
			{
				Amount = amount;
				ExpiresAt = expiresAt;
			}
		}

		private sealed class CraftingRequirementRuntimeState
		{
			public readonly Dictionary<string, CraftingRequirementAvailabilityCacheEntry> AvailabilityCache = new Dictionary<string, CraftingRequirementAvailabilityCacheEntry>(StringComparer.OrdinalIgnoreCase);

			public readonly List<Requirement> VisibleRequirements = new List<Requirement>();

			public readonly List<Requirement> VisibleRequirementCandidates = new List<Requirement>();

			public readonly List<RectTransform?> OwnedSlots = new List<RectTransform>();

			public int AvailabilityVersion;
		}

		private sealed class CraftingRecipeRuntimeState
		{
			public readonly List<CraftingRecipeGridCell> GridCells = new List<CraftingRecipeGridCell>();

			public readonly List<CraftingRecipeViewEntry> View = new List<CraftingRecipeViewEntry>();

			public readonly Dictionary<int, int> ViewIndexByOriginal = new Dictionary<int, int>();

			public readonly List<CraftingRecipeGroupPanel> GroupPanels = new List<CraftingRecipeGroupPanel>();

			public readonly List<CraftingRecipeGroupButton> GroupButtons = new List<CraftingRecipeGroupButton>();

			public readonly Dictionary<Recipe, int> Variants = new Dictionary<Recipe, int>();

			public readonly Dictionary<CraftingRecipePairCacheKey, string> SearchTextCache = new Dictionary<CraftingRecipePairCacheKey, string>();

			public readonly Dictionary<string, CraftingHoverTooltipContent> HoverTooltipContentCache = new Dictionary<string, CraftingHoverTooltipContent>(StringComparer.Ordinal);

			public readonly List<JewelcraftingGemIconData> HoverGemIconCache = new List<JewelcraftingGemIconData>();

			public readonly Dictionary<string, string> EnglishLocalizationCache = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

			public readonly Dictionary<string, string> EnglishLocalizationIndex = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

			public readonly Dictionary<CraftingRecipePairCacheKey, SortKey> SortKeyCache = new Dictionary<CraftingRecipePairCacheKey, SortKey>();

			public readonly Dictionary<CraftingRecipePairCacheKey, Dictionary<string, bool>> GroupMatchCache = new Dictionary<CraftingRecipePairCacheKey, Dictionary<string, bool>>();

			public readonly List<CraftingRecipeGroupFilter> SelectableGroupFilterCache = new List<CraftingRecipeGroupFilter>();

			public readonly Dictionary<string, bool> GroupHasRecipesCache = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
		}

		private sealed class CraftingGridRuntimeState
		{
			public RectTransform? RecipeGrid;

			public bool RecipeGridDirty = true;

			public int RecipePage;

			public CraftingRecipeGridStamp RecipeGridStamp;

			public string RecipeGridLayoutSignature = "";

			public int RecipeGridCellCapacity = -1;
		}

		private sealed class CraftingScrollbarRuntimeState
		{
			public RectTransform? RecipeScrollbar;

			public Scrollbar? RecipeScrollbarComponent;

			public bool UpdatingRecipeScrollbar;

			public bool RecipeScrollbarDirty = true;

			public CraftingRecipeScrollbarStamp RecipeScrollbarStamp;
		}

		private sealed class CraftingQueueRuntimeState
		{
			public bool ContinuingQueue;

			public int QueueTotal;

			public int QueueRemaining;

			public int QueueVariant;

			public int ProgressLabelCount;

			public int ProgressLabelVariant;

			public Recipe? QueueRecipe;

			public Recipe? ProgressLabelRecipe;

			public int InventoryLimitNoticeDepth;

			public ItemData? PendingInventoryLimitItem;

			public int PendingInventoryLimitMax = -1;
		}

		private sealed class CraftingUiRuntimeState
		{
			public GameObject? HoverTooltip;

			public RectTransform? HoverTooltipPanel;

			public TMP_Text? HoverTooltipTopic;

			public TMP_Text? HoverTooltipText;

			public readonly ScrollableTooltipBodyState HoverTooltipTextScroll = new ScrollableTooltipBodyState();

			public RectTransform? TooltipRecipeOverlay;

			public RectTransform? TooltipGemIconRow;

			public TMP_InputField? SearchInput;

			public RectTransform? SearchInputRect;

			public RectTransform? RecipeGridZoomHint;

			public RectTransform? GroupRail;

			public TMP_InputField? CountInput;

			public RectTransform? CountInputRect;

			public RectTransform? CountInputViewport;

			public RectTransform? UpgradeProgressionRect;

			public TMP_Text? UpgradeProgressionText;

			public RectTransform? SortModeButtonGroup;

			public RectTransform? ControlsBackground;

			public RectTransform? SocketWarningRect;

			public TMP_Text? SocketWarningText;

			public Transform? RequiredStationLevelOriginalRoot;

			public RectTransform? RequiredStationLevelHitbox;

			public RectTransformSnapshot? PanelRootSnapshot;

			public Vector2 PanelOriginalSizeDelta;

			public bool SearchInputDirty = true;

			public int HoveredRecipeIndex = -1;

			public CraftingSearchInputStamp SearchInputStamp;

			public string HoverTooltipSignature = "";

			public string HoverTooltipLayoutSignature = "";

			public string HoverTooltipVisualSignature = "";

			public string HoverGemIconSignature = "";

			public float HoverTooltipScrollOffset;

			public float HoverTooltipMaxScroll;

			public bool RecipeHoverMouseSyncPending;
		}

		private sealed class CraftingRefreshRuntimeState
		{
			public bool RecipeViewDirty = true;

			public string RecipeViewSignature = "";

			public bool GroupRailDirty = true;

			public CraftingGroupRailStamp GroupRailStamp;

			public bool BottomControlsDirty = true;

			public string BottomControlsSignature = "";

			public CraftingStatusHudStamp SocketWarningStamp;

			public CraftingSortModeButtonsStamp SortModeButtonsStamp;

			public CraftingFrameFastPathStamp FrameFastPathStamp;

			public string RecipeListChangeSignature = "";
		}

		private static class CraftingController
		{
			public static int HoveredRecipeIndex => CraftingUi.HoveredRecipeIndex;

			public static bool IsSearchInputDirty => CraftingUi.SearchInputDirty;

			public static bool NeedsModelRefresh(CraftingPanelUpdateReason reason, bool firstApply)
			{
				if (!firstApply && reason == CraftingPanelUpdateReason.FrameTick)
				{
					return HasModelRefreshWork();
				}
				return true;
			}

			public static bool HasModelRefreshWork()
			{
				if (!CraftingRefresh.RecipeViewDirty && !CraftingGrid.RecipeGridDirty && !CraftingScrollbar.RecipeScrollbarDirty)
				{
					return CraftingRefresh.GroupRailDirty;
				}
				return true;
			}

			public static bool HasFrameRebuildWork()
			{
				if (!HasModelRefreshWork())
				{
					return CraftingRefresh.BottomControlsDirty;
				}
				return true;
			}

			public static void MarkRecipeViewDirty()
			{
				CraftingRefresh.RecipeViewDirty = true;
				CraftingRefresh.RecipeViewSignature = "";
			}

			public static void MarkRecipeGridDirty()
			{
				CraftingGrid.RecipeGridDirty = true;
				CraftingGrid.RecipeGridStamp = default(CraftingRecipeGridStamp);
			}

			public static void MarkRecipeScrollbarDirty()
			{
				CraftingScrollbar.RecipeScrollbarDirty = true;
				CraftingScrollbar.RecipeScrollbarStamp = default(CraftingRecipeScrollbarStamp);
			}

			public static void MarkGroupRailDirty()
			{
				CraftingRefresh.GroupRailDirty = true;
				CraftingRefresh.GroupRailStamp = default(CraftingGroupRailStamp);
			}

			public static void MarkBottomControlsDirty()
			{
				CraftingRefresh.BottomControlsDirty = true;
				CraftingRefresh.BottomControlsSignature = "";
			}

			public static void MarkSearchInputDirty()
			{
				CraftingUi.SearchInputDirty = true;
				CraftingUi.SearchInputStamp = default(CraftingSearchInputStamp);
			}

			public static bool CanReuseRecipeView(string signature)
			{
				if (!CraftingRefresh.RecipeViewDirty)
				{
					return string.Equals(CraftingRefresh.RecipeViewSignature, signature, StringComparison.Ordinal);
				}
				return false;
			}

			public static void StoreRecipeViewSignature(string signature)
			{
				CraftingRefresh.RecipeViewSignature = signature;
				CraftingRefresh.RecipeViewDirty = false;
			}

			public static bool CanReuseRecipeGrid(CraftingRecipeGridStamp stamp)
			{
				if (!CraftingGrid.RecipeGridDirty)
				{
					return CraftingGrid.RecipeGridStamp.Equals(stamp);
				}
				return false;
			}

			public static void StoreRecipeGridStamp(CraftingRecipeGridStamp stamp)
			{
				CraftingGrid.RecipeGridStamp = stamp;
				CraftingGrid.RecipeGridDirty = false;
			}

			public static bool CanReuseRecipeScrollbar(CraftingRecipeScrollbarStamp stamp)
			{
				if (!CraftingScrollbar.RecipeScrollbarDirty)
				{
					return CraftingScrollbar.RecipeScrollbarStamp.Equals(stamp);
				}
				return false;
			}

			public static void StoreRecipeScrollbarStamp(CraftingRecipeScrollbarStamp stamp)
			{
				CraftingScrollbar.RecipeScrollbarStamp = stamp;
				CraftingScrollbar.RecipeScrollbarDirty = false;
			}

			public static bool CanReuseGroupRail(CraftingGroupRailStamp stamp)
			{
				if (!CraftingRefresh.GroupRailDirty)
				{
					return CraftingRefresh.GroupRailStamp.Equals(stamp);
				}
				return false;
			}

			public static void StoreGroupRailStamp(CraftingGroupRailStamp stamp)
			{
				CraftingRefresh.GroupRailStamp = stamp;
				CraftingRefresh.GroupRailDirty = false;
			}

			public static bool CanReuseSearchInput(CraftingSearchInputStamp stamp)
			{
				if (!CraftingUi.SearchInputDirty)
				{
					return CraftingUi.SearchInputStamp.Equals(stamp);
				}
				return false;
			}

			public static void StoreSearchInputStamp(CraftingSearchInputStamp stamp)
			{
				CraftingUi.SearchInputStamp = stamp;
				CraftingUi.SearchInputDirty = false;
			}

			public static bool NeedsBottomControlsLayout(string signature)
			{
				if (!CraftingRefresh.BottomControlsDirty)
				{
					return !string.Equals(CraftingRefresh.BottomControlsSignature, signature, StringComparison.Ordinal);
				}
				return true;
			}

			public static void StoreBottomControlsSignature(string signature)
			{
				CraftingRefresh.BottomControlsSignature = signature;
				CraftingRefresh.BottomControlsDirty = false;
			}

			public static bool CanReuseFrameFastPath(CraftingFrameFastPathStamp stamp)
			{
				return CraftingRefresh.FrameFastPathStamp.Equals(stamp);
			}

			public static void StoreFrameFastPathStamp(CraftingFrameFastPathStamp stamp)
			{
				CraftingRefresh.FrameFastPathStamp = stamp;
			}

			public static void ResetFrameFastPathStamp()
			{
				CraftingRefresh.FrameFastPathStamp = default(CraftingFrameFastPathStamp);
			}

			public static bool CanReuseSortModeButtons(CraftingSortModeButtonsStamp stamp)
			{
				return CraftingRefresh.SortModeButtonsStamp.Equals(stamp);
			}

			public static void StoreSortModeButtonsStamp(CraftingSortModeButtonsStamp stamp)
			{
				CraftingRefresh.SortModeButtonsStamp = stamp;
			}

			public static void ResetSortModeButtonsStamp()
			{
				CraftingRefresh.SortModeButtonsStamp = default(CraftingSortModeButtonsStamp);
			}

			public static bool CanReuseSocketWarning(CraftingStatusHudStamp stamp)
			{
				return CraftingRefresh.SocketWarningStamp.Equals(stamp);
			}

			public static void StoreSocketWarningStamp(CraftingStatusHudStamp stamp)
			{
				CraftingRefresh.SocketWarningStamp = stamp;
			}

			public static void ResetSocketWarningStamp()
			{
				CraftingRefresh.SocketWarningStamp = default(CraftingStatusHudStamp);
			}

			public static bool TryStoreRecipeListChangeSignature(string signature)
			{
				if (string.Equals(CraftingRefresh.RecipeListChangeSignature, signature, StringComparison.Ordinal))
				{
					return false;
				}
				CraftingRefresh.RecipeListChangeSignature = signature;
				return true;
			}

			public static void ResetRecipeListChangeSignature()
			{
				CraftingRefresh.RecipeListChangeSignature = "";
			}

			public static void MarkRecipeGridLayoutDirty()
			{
				MarkRecipeGridDirty();
				MarkRecipeScrollbarDirty();
				MarkBottomControlsDirty();
			}

			public static void SetHoveredRecipe(int index)
			{
				CraftingUi.HoveredRecipeIndex = index;
			}

			public static void ClearHoveredRecipe()
			{
				CraftingUi.HoveredRecipeIndex = -1;
			}

			public static bool IsHoveredRecipe(int index)
			{
				return CraftingUi.HoveredRecipeIndex == index;
			}

			public static void ClearHoveredRecipeAndRequestMouseSync()
			{
				ClearHoveredRecipe();
				CraftingUi.RecipeHoverMouseSyncPending = true;
			}

			public static bool ConsumeRecipeHoverMouseSync()
			{
				if (!CraftingUi.RecipeHoverMouseSyncPending)
				{
					return false;
				}
				CraftingUi.RecipeHoverMouseSyncPending = false;
				return true;
			}
		}

		private sealed class CustomEquipmentVisualState
		{
			public string SlotId { get; }

			public int ItemHash { get; }

			public int Variant { get; }

			public int Quality { get; }

			public string PrefabName { get; }

			public ItemType ItemType { get; }

			public CustomEquipmentVisualState(string slotId, int itemHash, int variant, int quality, string prefabName, ItemType itemType)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				SlotId = slotId;
				ItemHash = itemHash;
				Variant = variant;
				Quality = quality;
				PrefabName = prefabName;
				ItemType = itemType;
			}
		}

		private sealed class CustomEquipmentVisual
		{
			private readonly List<GameObject> _instances = new List<GameObject>();

			public string Key { get; }

			public VisEquipment Owner { get; }

			public string PrefabName { get; }

			public int Variant { get; }

			public int Quality { get; }

			public CustomEquipmentVisual(string key, VisEquipment owner, string prefabName, int variant, int quality)
			{
				Key = key;
				Owner = owner;
				PrefabName = prefabName;
				Variant = variant;
				Quality = quality;
			}

			public bool Matches(VisEquipment owner, string prefabName, int variant, int quality)
			{
				if (!IsUnityNull((Object?)(object)Owner) && (Object)(object)Owner == (Object)(object)owner && string.Equals(PrefabName, prefabName, StringComparison.Ordinal) && Variant == variant)
				{
					return Quality == quality;
				}
				return false;
			}

			public bool IsOwnedBy(VisEquipment owner)
			{
				if (!IsUnityNull((Object?)(object)Owner))
				{
					return (Object)(object)Owner == (Object)(object)owner;
				}
				return false;
			}

			public void Add(GameObject? instance)
			{
				if (!IsUnityNull((Object?)(object)instance))
				{
					_instances.Add(instance);
				}
			}

			public void AddRange(IEnumerable<GameObject>? instances)
			{
				if (instances == null)
				{
					return;
				}
				foreach (GameObject instance in instances)
				{
					Add(instance);
				}
			}

			public void AddActiveInstancesTo(List<GameObject> roots)
			{
				foreach (GameObject instance in _instances)
				{
					if (!IsUnityNull((Object?)(object)instance))
					{
						roots.Add(instance);
					}
				}
			}

			public void Destroy()
			{
				foreach (GameObject instance in _instances)
				{
					if (!IsUnityNull((Object?)(object)instance))
					{
						if (!IsUnityNull((Object?)(object)Owner) && !IsUnityNull((Object?)(object)Owner.m_lodGroup))
						{
							Utils.RemoveFromLodgroup(Owner.m_lodGroup, instance);
						}
						Object.Destroy((Object)(object)instance);
					}
				}
				_instances.Clear();
			}
		}

		internal sealed class KeepOnDeathItemState
		{
			public ItemData Item { get; }

			public Vector2i OriginalGridPos { get; }

			public string OriginalSlotId { get; }

			public SlotKind? OriginalSlotKind { get; }

			public bool OriginalEquipped { get; }

			public Dictionary<string, string> OriginalCustomData { get; }

			public bool WasQuickSlot => OriginalSlotKind == SlotKind.Quick;

			public bool WasSpecialSlot => OriginalSlotKind.HasValue;

			public KeepOnDeathItemState(ItemData item, Vector2i originalGridPos, string originalSlotId, SlotKind? originalSlotKind)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				Item = item;
				OriginalGridPos = originalGridPos;
				OriginalSlotId = originalSlotId;
				OriginalSlotKind = originalSlotKind;
				OriginalEquipped = item.m_equipped;
				OriginalCustomData = ((item.m_customData == null) ? new Dictionary<string, string>() : new Dictionary<string, string>(item.m_customData));
			}
		}

		internal sealed class TombStonePreparationState
		{
			public Inventory? SourceInventory { get; }

			public List<KeepOnDeathItemState> KeptItems { get; }

			public bool DeathDropUnequipPrepared { get; }

			public bool DeathDropUnequipCompleted { get; set; }

			public bool Completed { get; set; }

			public TombStonePreparationState(Inventory? sourceInventory, List<KeepOnDeathItemState> keptItems, bool deathDropUnequipPrepared)
			{
				SourceInventory = sourceInventory;
				KeptItems = keptItems;
				DeathDropUnequipPrepared = deathDropUnequipPrepared;
				DeathDropUnequipCompleted = !deathDropUnequipPrepared;
			}
		}

		private sealed class EpicLootPublicApi
		{
			public readonly Func<string, Func<ItemData, bool>, bool>? RegisterSacrificeFilter;

			public readonly Func<string, bool>? UnregisterSacrificeFilter;

			public readonly Action<Player>? InvalidatePlayerEffectCache;

			public readonly Func<GameObject, GameObject, ItemData?, bool, bool>? ApplyMagicItemBackground;

			public EpicLootPublicApi(Type apiType)
			{
				RegisterSacrificeFilter = (Func<string, Func<ItemData, bool>, bool>)CreateDelegate(apiType, "RegisterSacrificeFilter", typeof(bool), typeof(Func<string, Func<ItemData, bool>, bool>), typeof(string), typeof(Func<ItemData, bool>));
				UnregisterSacrificeFilter = (Func<string, bool>)CreateDelegate(apiType, "UnregisterSacrificeFilter", typeof(bool), typeof(Func<string, bool>), typeof(string));
				InvalidatePlayerEffectCache = (Action<Player>)CreateDelegate(apiType, "InvalidatePlayerEffectCache", typeof(void), typeof(Action<Player>), typeof(Player));
				ApplyMagicItemBackground = (Func<GameObject, GameObject, ItemData, bool, bool>)CreateDelegate(apiType, "ApplyMagicItemBackground", typeof(bool), typeof(Func<GameObject, GameObject, ItemData, bool, bool>), typeof(GameObject), typeof(GameObject), typeof(ItemData), typeof(bool));
			}

			private static Delegate? CreateDelegate(Type apiType, string methodName, Type returnType, Type delegateType, params Type[] parameterTypes)
			{
				MethodInfo method = apiType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null);
				if (!(method?.ReturnType == returnType))
				{
					return null;
				}
				return Delegate.CreateDelegate(delegateType, method);
			}
		}

		private sealed class HipLanternApi
		{
			private delegate ItemData? GetLanternDelegate(Humanoid humanoid);

			private delegate ItemData? SetLanternDelegate(Humanoid humanoid, ItemData? item);

			private delegate bool IsLanternDelegate(ItemData item);

			private readonly GetLanternDelegate _getLantern;

			private readonly SetLanternDelegate _setLantern;

			private readonly IsLanternDelegate _isLantern;

			private readonly ConfigEntry<bool> _useUtilitySlot;

			private bool _failed;

			private HipLanternApi(GetLanternDelegate getLantern, SetLanternDelegate setLantern, IsLanternDelegate isLantern, ConfigEntry<bool> useUtilitySlot)
			{
				_getLantern = getLantern;
				_setLantern = setLantern;
				_isLantern = isLantern;
				_useUtilitySlot = useUtilitySlot;
			}

			public static bool TryCreate(Assembly assembly, out HipLanternApi? api, out string detail)
			{
				api = null;
				Type type = assembly.GetType("HipLantern.HumanoidExtension");
				Type type2 = assembly.GetType("HipLantern.LanternItem");
				Type type3 = assembly.GetType("HipLantern.HipLantern");
				MethodInfo methodInfo = type?.GetMethod("GetHipLantern", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Humanoid) }, null);
				MethodInfo methodInfo2 = type?.GetMethod("SetHipLantern", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
				{
					typeof(Humanoid),
					typeof(ItemData)
				}, null);
				MethodInfo methodInfo3 = type2?.GetMethod("IsLanternItem", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ItemData) }, null);
				FieldInfo fieldInfo = type3?.GetField("itemSlotUtility", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (methodInfo?.ReturnType != typeof(ItemData) || methodInfo2?.ReturnType != typeof(ItemData) || methodInfo3?.ReturnType != typeof(bool) || fieldInfo == null || !typeof(ConfigEntryBase).IsAssignableFrom(fieldInfo.FieldType))
				{
					detail = "expected HumanoidExtension, LanternItem, or itemSlotUtility members were not found";
					return false;
				}
				try
				{
					if (!(fieldInfo.GetValue(null) is ConfigEntry<bool> useUtilitySlot))
					{
						detail = "itemSlotUtility was not initialized";
						return false;
					}
					api = new HipLanternApi((GetLanternDelegate)Delegate.CreateDelegate(typeof(GetLanternDelegate), methodInfo), (SetLanternDelegate)Delegate.CreateDelegate(typeof(SetLanternDelegate), methodInfo2), (IsLanternDelegate)Delegate.CreateDelegate(typeof(IsLanternDelegate), methodInfo3), useUtilitySlot);
					detail = "";
					return true;
				}
				catch (Exception ex)
				{
					detail = "failed to bind HipLantern delegates: " + ex.Message;
					return false;
				}
			}

			public bool TryGetUseUtilitySlot(out bool useUtilitySlot)
			{
				useUtilitySlot = true;
				if (_failed)
				{
					return false;
				}
				try
				{
					useUtilitySlot = _useUtilitySlot.Value;
					return true;
				}
				catch (Exception exception)
				{
					return Fail("reading itemSlotUtility", exception);
				}
			}

			public bool TryIsLanternItem(ItemData item, out bool isLantern)
			{
				isLantern = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					isLantern = _isLantern(item);
					return true;
				}
				catch (Exception exception)
				{
					return Fail("checking the HipLantern item type", exception);
				}
			}

			public bool TrySetLantern(Humanoid humanoid, ItemData item, out bool changed)
			{
				changed = false;
				if (!TryGetLantern(humanoid, out ItemData item2))
				{
					return false;
				}
				if (item2 == item)
				{
					return true;
				}
				return TrySetLanternValue(humanoid, item, out changed);
			}

			public bool TryIsCurrentLantern(Humanoid humanoid, ItemData item, out bool isCurrent)
			{
				isCurrent = false;
				if (!TryGetLantern(humanoid, out ItemData item2))
				{
					return false;
				}
				isCurrent = item2 == item;
				return true;
			}

			public bool TryClearLantern(Humanoid humanoid, ItemData item, out bool changed)
			{
				changed = false;
				if (!TryGetLantern(humanoid, out ItemData item2))
				{
					return false;
				}
				if (item2 != item)
				{
					return true;
				}
				return TrySetLanternValue(humanoid, null, out changed);
			}

			public bool TryGetLantern(Humanoid humanoid, out ItemData? item)
			{
				item = null;
				if (_failed)
				{
					return false;
				}
				try
				{
					item = _getLantern(humanoid);
					return true;
				}
				catch (Exception exception)
				{
					return Fail("reading the equipped HipLantern", exception);
				}
			}

			private bool TrySetLanternValue(Humanoid humanoid, ItemData? item, out bool changed)
			{
				changed = false;
				if (_failed)
				{
					return false;
				}
				try
				{
					if (_setLantern(humanoid, item) != item)
					{
						return Fail("SetHipLantern returned an unexpected item");
					}
					changed = true;
					return true;
				}
				catch (Exception exception)
				{
					return Fail("updating the equipped HipLantern", exception);
				}
			}

			private bool Fail(string operation, Exception? exception = null)
			{
				if (!_failed)
				{
					string text = exception?.InnerException?.Message ?? exception?.Message ?? "unknown result";
					Log.LogWarning((object)("HipLantern compatibility disabled while " + operation + ": " + text));
				}
				_failed = true;
				return false;
			}
		}

		private sealed class InventoryOverlayHost
		{
			internal RectTransform? Rect;

			internal RectTransform? Source;

			internal Transform? SourceParent;

			internal CanvasGroup? Group;

			internal CanvasGroup[] SourceGroups = Array.Empty<CanvasGroup>();

			internal void Follow(bool keepOnTop = false)
			{
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_017e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bd: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0200: Unknown result type (might be due to invalid IL or missing references)
				//IL_020e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Rect == (Object)null)
				{
					return;
				}
				if (keepOnTop && (Object)(object)((Transform)Rect).parent != (Object)null && ((Transform)Rect).GetSiblingIndex() != ((Transform)Rect).parent.childCount - 1)
				{
					((Transform)Rect).SetAsLastSibling();
				}
				bool flag = (Object)(object)Source != (Object)null && ((Component)Source).gameObject.activeInHierarchy;
				SetActionPanelActive(Rect, flag);
				if (!flag)
				{
					return;
				}
				if (Rect.pivot != Source.pivot)
				{
					Rect.pivot = Source.pivot;
				}
				Vector2 sizeDelta = Rect.sizeDelta;
				Rect rect = Source.rect;
				if (sizeDelta != ((Rect)(ref rect)).size)
				{
					RectTransform? rect2 = Rect;
					rect = Source.rect;
					rect2.sizeDelta = ((Rect)(ref rect)).size;
				}
				if (((Transform)Rect).position != ((Transform)Source).position)
				{
					((Transform)Rect).position = ((Transform)Source).position;
				}
				if (((Transform)Rect).rotation != ((Transform)Source).rotation)
				{
					((Transform)Rect).rotation = ((Transform)Source).rotation;
				}
				Vector3 lossyScale = ((Transform)Source).lossyScale;
				Vector3 lossyScale2 = ((Transform)Rect).parent.lossyScale;
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor((Mathf.Abs(lossyScale2.x) > 0.0001f) ? (lossyScale.x / lossyScale2.x) : 1f, (Mathf.Abs(lossyScale2.y) > 0.0001f) ? (lossyScale.y / lossyScale2.y) : 1f, (Mathf.Abs(lossyScale2.z) > 0.0001f) ? (lossyScale.z / lossyScale2.z) : 1f);
				if (((Transform)Rect).localScale != val)
				{
					((Transform)Rect).localScale = val;
				}
				float num = 1f;
				bool flag2 = true;
				bool flag3 = true;
				bool flag4 = false;
				CanvasGroup[] sourceGroups = SourceGroups;
				foreach (CanvasGroup val2 in sourceGroups)
				{
					if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).isActiveAndEnabled)
					{
						num *= val2.alpha;
						flag2 &= val2.interactable;
						flag3 &= val2.blocksRaycasts;
						if (val2.ignoreParentGroups)
						{
							flag4 = true;
							break;
						}
					}
				}
				if (Group.alpha != num)
				{
					Group.alpha = num;
				}
				if (Group.interactable != flag2)
				{
					Group.interactable = flag2;
				}
				if (Group.blocksRaycasts != flag3)
				{
					Group.blocksRaycasts = flag3;
				}
				if (Group.ignoreParentGroups != flag4)
				{
					Group.ignoreParentGroups = flag4;
				}
			}

			internal void Clear()
			{
				Rect = (Source = null);
				SourceParent = null;
				Group = null;
				SourceGroups = Array.Empty<CanvasGroup>();
			}
		}

		private sealed class InventoryHoverTooltipRuntimeState
		{
			public GameObject? HoverTooltip;

			public RectTransform? HoverTooltipPanel;

			public TMP_Text? HoverTooltipTopic;

			public TMP_Text? HoverTooltipText;

			public readonly ScrollableTooltipBodyState HoverTooltipTextScroll = new ScrollableTooltipBodyState();

			public readonly TooltipSourceCacheCore<UITooltip, InventoryHoverTooltipItemSource> HoverTooltipItems = new TooltipSourceCacheCore<UITooltip, InventoryHoverTooltipItemSource>(64);

			public string HoverTooltipSignature = "";

			public string HoverTooltipLayoutSignature = "";

			public float HoverTooltipScrollOffset;

			public float HoverTooltipMaxScroll;

			public bool HoverTooltipNeedsScroll;

			public RectTransform? HoverJewelcraftingTooltipRoot;

			public string HoverJewelcraftingTooltipSignature = "";

			public int HoverJewelcraftingTooltipLayoutRefreshFrames;

			public GameObject? SimpleNameTooltip;

			public RectTransform? SimpleNameTooltipRect;

			public TMP_Text? SimpleNameTooltipText;

			public string SimpleNameTooltipValue = "";

			public SimpleNameTooltipPlacement SimpleNameTooltipPlacement;

			public readonly SimpleTooltipOwnershipCore SimpleNameTooltipOwner = new SimpleTooltipOwnershipCore();

			public readonly object SimpleNameTooltipFallbackOwner = new object();

			public object? PinnedGemNameTooltipOwner;

			public float PinnedGemNameTooltipHoldUntil = -1000f;

			public UITooltip? ContainerHoverTooltipSource;

			public UITooltip? OwnedHoverTooltipSource;

			public bool LateUpdateExceptionLogged;
		}

		private enum SimpleNameTooltipPlacement
		{
			RightOfCursor,
			LeftOfCursor
		}

		private readonly struct InventoryHoverTooltipItemSource
		{
			public InventoryGrid? Grid { get; }

			public ItemData Item { get; }

			public InventoryHoverTooltipItemSource(InventoryGrid? grid, ItemData item)
			{
				Grid = grid;
				Item = item;
			}
		}

		private sealed class InventoryKeyHintGroupState
		{
			public GameObject? Group;

			public Transform? Parent;

			public GameObject? Favorite;

			public GameObject? Tooltip;

			public string FavoriteLabel = "";

			public string FavoriteKeys = "";

			public string TooltipLabel = "";

			public string TooltipKeys = "";

			public TMP_FontAsset? Font;

			public Material? Material;

			public int LocalizationVersion = -1;

			public int GroupChildCount;

			public int ParentChildCount;

			public bool WasVisible;

			public bool HasContent;

			public bool FavoriteVisible;

			public bool TooltipVisible;

			public void Clear()
			{
				if (!IsUnityNull((Object?)(object)Favorite))
				{
					Object.Destroy((Object)(object)Favorite);
				}
				if (!IsUnityNull((Object?)(object)Tooltip))
				{
					Object.Destroy((Object)(object)Tooltip);
				}
				Group = null;
				Parent = null;
				Favorite = null;
				Tooltip = null;
				Font = null;
				Material = null;
				HasContent = false;
				WasVisible = false;
			}
		}

		private sealed class NativeInventoryRows
		{
			public int Rows = 4;

			public bool Loaded;
		}

		private readonly struct PlayerInventoryPanelBackgroundSnapshot
		{
			public bool ActiveSelf { get; }

			public bool ImageEnabled { get; }

			public Sprite? Sprite { get; }

			public Type Type { get; }

			public float PixelsPerUnitMultiplier { get; }

			public Material? Material { get; }

			public Color Color { get; }

			public Vector2 AnchorMax { get; }

			public Vector2 Pivot { get; }

			public Vector2 OffsetMin { get; }

			public Vector2 OffsetMax { get; }

			public Vector2 AnchoredPosition { get; }

			public Vector2 SizeDelta { get; }

			public Vector3 LocalScale { get; }

			public Quaternion LocalRotation { get; }

			public PlayerInventoryPanelBackgroundSnapshot(bool activeSelf, bool imageEnabled, Sprite? sprite, Type type, float pixelsPerUnitMultiplier, Material? material, Color color, Vector2 anchorMax, Vector2 pivot, Vector2 offsetMin, Vector2 offsetMax, Vector2 anchoredPosition, Vector2 sizeDelta, Vector3 localScale, Quaternion localRotation)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				ActiveSelf = activeSelf;
				ImageEnabled = imageEnabled;
				Sprite = sprite;
				Type = type;
				PixelsPerUnitMultiplier = pixelsPerUnitMultiplier;
				Material = material;
				Color = color;
				AnchorMax = anchorMax;
				Pivot = pivot;
				OffsetMin = offsetMin;
				OffsetMax = offsetMax;
				AnchoredPosition = anchoredPosition;
				SizeDelta = sizeDelta;
				LocalScale = localScale;
				LocalRotation = localRotation;
			}
		}

		internal enum InventoryStateEnsureReason
		{
			Unknown,
			PeriodicAudit,
			PlayerAwake,
			PlayerSpawned,
			PlayerLoad,
			PlayerSave,
			InventoryChanged,
			EquipmentChanged,
			InventoryLoad,
			InventoryMove,
			Tombstone,
			GuiShow,
			SlotAction,
			BackupRestore,
			YamlReload,
			JewelcraftingSlotRefresh,
			ProgressionReset,
			ConfigChanged,
			ReentrantFollowUp
		}

		internal enum InventoryStateAuditLevel
		{
			None,
			HeightOnly,
			SlotLight,
			FullIntegrity
		}

		private sealed class InventoryPanelRuntimeState
		{
			public readonly Dictionary<int, RectTransform> CustomSlotPanels = new Dictionary<int, RectTransform>();

			public readonly Dictionary<int, RectTransform> QuickSlotPanels = new Dictionary<int, RectTransform>();

			public readonly List<MovedPlayerStatPanel> MovedPlayerStatPanels = new List<MovedPlayerStatPanel>();

			public readonly Dictionary<int, Vector3> QuickSlotPanelOutroStartPositions = new Dictionary<int, Vector3>();

			public readonly InventoryKeyHintGroupState InventoryKeyHints = new InventoryKeyHintGroupState();

			public readonly InventoryKeyHintGroupState ContainerKeyHints = new InventoryKeyHintGroupState();

			public RectTransform? QuickSlotsHotkeyBarRect;

			public HotkeyBar? QuickSlotsHotkeyBar;

			public RectTransform? PlayerStatPanelHost;

			public RectTransform? InventorySortPanel;

			public RectTransform? SortButtonLayer;

			public readonly InventoryOverlayHost PlayerSortHost = new InventoryOverlayHost();

			public readonly InventoryOverlayHost ContainerSortHost = new InventoryOverlayHost();

			public RectTransform? CurrencyPocketPanel;

			public Button? ContainerRestockButton;

			public Button? ContainerStoreAllButton;

			public Button? ContainerSortButton;

			public RectTransformSnapshot? TakeAllButtonOriginal;

			public RectTransformSnapshot? StackAllButtonOriginal;

			public RectTransform? TrackedContainerPanel;

			public RectTransform? TrackedContainerWeightPanel;

			public Vector3 ContainerPanelBasePosition;

			public Vector3 ContainerPanelAppliedOffset;

			public Vector3 ContainerWeightPanelBasePosition;

			public float ContainerWeightPanelAppliedYOffset;

			public RectTransform? DraggedInventoryPanel;

			public Vector2 InventoryPanelDragStartLocalMouse;

			public Vector2 InventoryPanelDragStartOffset;

			public Vector2 InventoryPanelDragOriginalO