Decompiled source of SeamlessStorage v1.0.1

SeamlessStorage.dll

Decompiled 2 days 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.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using AzuEPI;
using AzuEPI.Core.Slots;
using AzuExtendedPlayerInventory;
using Backpacks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EpicLootAPI;
using GUIFramework;
using HarmonyLib;
using ItemDataManager;
using JetBrains.Annotations;
using Jewelcrafting;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SeamlessStorage.CraftFromChests;
using SeamlessStorage.CraftFromChests.APIs;
using SeamlessStorage.CraftFromChests.Compatibility;
using SeamlessStorage.CraftFromChests.Compatibility.WardIsLove;
using SeamlessStorage.CraftFromChests.IContainers;
using SeamlessStorage.CraftFromChests.Patches;
using SeamlessStorage.CraftFromChests.Util;
using SeamlessStorage.CraftFromChests.Util.Functions;
using SeamlessStorage.Deposit;
using SeamlessStorage.Deposit.APIs;
using SeamlessStorage.Deposit.APIs.Compatibility.WardIsLove;
using SeamlessStorage.Deposit.Interfaces;
using SeamlessStorage.Deposit.Patches.Combining;
using SeamlessStorage.Deposit.Patches.Favoriting;
using SeamlessStorage.Deposit.Patches.Rename;
using SeamlessStorage.Deposit.Patches.Search;
using SeamlessStorage.Deposit.Patches.Sorting;
using SeamlessStorage.Deposit.Patches.Trash;
using SeamlessStorage.Deposit.Util;
using SeamlessStorage.SharedChest;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Pool;
using UnityEngine.Rendering;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("gui_framework")]
[assembly: AssemblyCompany("SeamlessStorage")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("SeamlessStorage")]
[assembly: AssemblyTitle("SeamlessStorage")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 JetBrains.Annotations
{
	[AttributeUsage(AttributeTargets.All)]
	internal sealed class UsedImplicitlyAttribute : Attribute
	{
		public UsedImplicitlyAttribute()
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
		{
		}

		public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
		{
		}
	}
	[Flags]
	internal enum ImplicitUseKindFlags
	{
		Default = 7,
		Assign = 1,
		Accessors = 2,
		InstantiatedWithFixedConstructorSignature = 4,
		InstantiatedNoFixedConstructorSignature = 8
	}
	[Flags]
	internal enum ImplicitUseTargetFlags
	{
		Default = 1,
		Itself = 1,
		Members = 2,
		WithMembers = 3
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public static event Action? OnLocalizationComplete;

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			_ = plugin;
		}

		public static void LoadLocalizationLater(Localization __instance)
		{
			LoadLocalization(Localization.instance, __instance.GetSelectedLanguage());
		}

		public static void SafeCallLocalizeComplete()
		{
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string[] array = Path.GetFileNameWithoutExtension(item).Split('.');
				if (array.Length >= 2)
				{
					string text = array[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
			}
			byte[] array2 = LoadTranslationFromAssembly("English");
			if (array2 == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.TryGetValue(language, out var value))
				{
					text2 = File.ReadAllText(value);
				}
				else
				{
					byte[] array3 = LoadTranslationFromAssembly(language);
					if (array3 != null)
					{
						text2 = Encoding.UTF8.GetString(array3);
					}
				}
			}
			if (text2 == null && dictionary.TryGetValue("English", out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string>(2) { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	public static class LocalizationManagerVersion
	{
		public const string Version = "1.4.1";
	}
}
namespace SeamlessStorage
{
	public enum ChestAccessPolicy
	{
		AnyAccessible,
		OwnChestsOnly,
		OwnPrivateOnly
	}
	public static class ChestAccess
	{
		private class ConfigurationManagerAttributes
		{
			public int? Order;
		}

		private const string NotYourChest = "the server only allows your own chests.";

		public static ConfigEntry<ChestAccessPolicy> Policy { get; private set; }

		public static void Bind(BaseUnityPlugin host, ConfigSync configSync)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			if (Policy == null)
			{
				ConfigEntry<ChestAccessPolicy> val = host.Config.Bind<ChestAccessPolicy>("1 - General", "Chest Access Policy", ChestAccessPolicy.AnyAccessible, new ConfigDescription("Which chests the mod may deposit into or pull from. AnyAccessible = current behavior (ward + vanilla privacy). OwnChestsOnly = only chests you built. OwnPrivateOnly = only your Private chests. Under Own* policies, Item Drawers without a Piece are blocked (your backpack still works). [Synced with Server]", (AcceptableValueBase)null, new object[1]
				{
					new ConfigurationManagerAttributes
					{
						Order = 10
					}
				}));
				configSync.AddConfigEntry<ChestAccessPolicy>(val).SynchronizedConfig = true;
				Policy = val;
			}
		}

		public static bool MatchesPolicy(Container container, long playerId)
		{
			return PolicyDenyReason(container, playerId) == null;
		}

		private static string? PolicyDenyReason(Container container, long playerId)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null || Policy == null)
			{
				return null;
			}
			ChestAccessPolicy value = Policy.Value;
			if (value == ChestAccessPolicy.AnyAccessible)
			{
				return null;
			}
			if (IsOnLocalPlayer(((Component)container).gameObject))
			{
				return null;
			}
			Piece val = ResolvePiece(((Component)container).gameObject, container);
			if ((Object)(object)val == (Object)null)
			{
				return "the server only allows your own chests.";
			}
			long creator = val.GetCreator();
			if (creator == 0L || creator != playerId)
			{
				return "the server only allows your own chests.";
			}
			if (value == ChestAccessPolicy.OwnPrivateOnly && (int)container.m_privacy != 0)
			{
				return "the server only allows your own Private chests - set this chest to Private first.";
			}
			return null;
		}

		public static bool IsAllowed(Container container, long playerId)
		{
			return DenyReason(container, playerId) == null;
		}

		public static string? DenyReason(Container container, long playerId)
		{
			if ((Object)(object)container == (Object)null)
			{
				return "this chest is unavailable.";
			}
			if (!container.CheckAccess(playerId))
			{
				return "this is someone else's private chest.";
			}
			return PolicyDenyReason(container, playerId);
		}

		public static bool MatchesPolicyForObject(GameObject go, long playerId)
		{
			if ((Object)(object)go == (Object)null || Policy == null)
			{
				return true;
			}
			if (Policy.Value == ChestAccessPolicy.AnyAccessible)
			{
				return true;
			}
			Container val = go.GetComponent<Container>() ?? go.GetComponentInParent<Container>();
			if ((Object)(object)val != (Object)null)
			{
				return MatchesPolicy(val, playerId);
			}
			if (IsOnLocalPlayer(go))
			{
				return true;
			}
			Piece val2 = ResolvePiece(go, null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			long creator = val2.GetCreator();
			if (creator == 0L || creator != playerId)
			{
				return false;
			}
			return true;
		}

		private static Piece? ResolvePiece(GameObject go, Container? container)
		{
			if ((Object)(object)container?.m_piece != (Object)null)
			{
				return container.m_piece;
			}
			return go.GetComponent<Piece>() ?? go.GetComponentInParent<Piece>();
		}

		private static bool IsOnLocalPlayer(GameObject go)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)go == (Object)null)
			{
				return false;
			}
			Player componentInParent = go.GetComponentInParent<Player>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return (Object)(object)componentInParent == (Object)(object)localPlayer;
			}
			return false;
		}
	}
	[BepInPlugin("ModdedWolf.SeamlessStorage", "Seamless Storage", "1.0.1")]
	[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.*/)]
	[BepInIncompatibility("aedenthorn.CraftFromContainers")]
	[BepInIncompatibility("CFCMod")]
	public class SeamlessStoragePlugin : BaseUnityPlugin
	{
		public const string GUID = "ModdedWolf.SeamlessStorage";

		public const string NAME = "Seamless Storage";

		public const string VERSION = "1.0.1";

		private static readonly string[] IncompatiblePluginGuids = new string[2]
		{
			Decode("QXp1bWF0dC5BenVBdXRvU3RvcmU="),
			Decode("QXp1bWF0dC5BenVDcmFmdHlCb3hlcw==")
		};

		private static bool _modulesReady;

		private readonly Harmony _harmony = new Harmony("ModdedWolf.SeamlessStorage");

		internal static SeamlessStoragePlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private static string Decode(string value)
		{
			return Encoding.UTF8.GetString(Convert.FromBase64String(value));
		}

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			List<string> list = new List<string>();
			string[] incompatiblePluginGuids = IncompatiblePluginGuids;
			foreach (string text in incompatiblePluginGuids)
			{
				if (Chainloader.PluginInfos.TryGetValue(text, out var value))
				{
					BepInPlugin metadata = value.Metadata;
					string text2 = ((metadata != null) ? metadata.Name : null);
					text2 = ((!string.IsNullOrWhiteSpace(text2)) ? (text2 + " (" + text + ")") : text);
					list.Add(text2);
				}
			}
			if (list.Count > 0)
			{
				Log.LogError((object)("Seamless Storage found another mod that provides the same storage features. Disable conflicting chest-deposit / craft-from-container mods, then restart. Seamless Storage will not start. Conflicting: " + string.Join(", ", list)));
				return;
			}
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			CraftFromChestsModule.Initialize((BaseUnityPlugin)(object)this);
			DepositModule.Initialize((BaseUnityPlugin)(object)this);
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			_modulesReady = true;
			Log.LogInfo((object)"Seamless Storage v1.0.1 loaded.");
		}

		private void Start()
		{
			if (_modulesReady)
			{
				CraftFromChestsModule.OnStart();
				DepositModule.OnStart();
			}
		}

		private void Update()
		{
			if (_modulesReady)
			{
				CraftFromChestsModule.OnUpdate();
				DepositModule.OnUpdate();
			}
		}

		private void LateUpdate()
		{
			if (_modulesReady)
			{
				CraftFromChestsModule.OnLateUpdate();
			}
		}

		private void OnDestroy()
		{
			if (_modulesReady)
			{
				CraftFromChestsModule.OnDestroyed();
				DepositModule.OnDestroyed();
			}
		}
	}
	internal static class Sync
	{
		internal static readonly ConfigSync Instance = new ConfigSync("ModdedWolf.SeamlessStorage")
		{
			DisplayName = "Seamless Storage",
			CurrentVersion = "1.0.1",
			MinimumRequiredVersion = "1.0.1"
		};
	}
}
namespace SeamlessStorage.SharedChest
{
	internal static class ClientOps
	{
		internal static int TryAddFromPlayer(Container container, ItemData item, int amount)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (!SharedChest.IsEnabled && !SharedChest.ExternalMultiUserChestLoaded)
			{
				return 0;
			}
			if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner())
			{
				return 0;
			}
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return 0;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			if (inventory == null || !inventory.ContainsItem(item))
			{
				return 0;
			}
			amount = InvUtil.PossibleAmount(container.GetInventory(), item, new Vector2i(-1, -1), amount);
			if (amount <= 0)
			{
				return 0;
			}
			if (SharedChest.ExternalMultiUserChestLoaded)
			{
				int stack = item.m_stack;
				container.GetInventory().AddItem(item, amount, -1, -1, false);
				if (!inventory.ContainsItem(item))
				{
					return stack;
				}
				return stack - item.m_stack;
			}
			int stack2 = item.m_stack;
			if (BeginAdd(container, item, inventory, new Vector2i(-1, -1), amount) != null)
			{
				return amount;
			}
			if (!inventory.ContainsItem(item))
			{
				return stack2;
			}
			return Math.Max(0, stack2 - item.m_stack);
		}

		internal static AddRequest? BeginAdd(Container container, ItemData item, Inventory source, Vector2i to, int dragAmount)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner())
			{
				return null;
			}
			dragAmount = InvUtil.PossibleAmount(container.GetInventory(), item, to, dragAmount);
			ItemData itemAt = container.GetInventory().GetItemAt(to.x, to.y);
			bool flag = itemAt != null && dragAmount != item.m_stack && !ItemPack.CanStack(itemAt, item);
			if (dragAmount <= 0 || flag || !source.ContainsItem(item))
			{
				return null;
			}
			AddRequest addRequest = new AddRequest(to, dragAmount, item, source, container.GetInventory());
			RequestStore.Track(addRequest);
			SlotBlock.Of(source).Block(item.m_gridPos);
			source.RemoveItem(item, dragAmount);
			if (container.m_nview.IsOwner())
			{
				AddResponse response = OwnerOps.ApplyAdd(container.GetInventory(), addRequest);
				ApplyAddResponse(source, response);
				return null;
			}
			RpcHub.Invoke(container.m_nview, "SS_RequestItemAdd", addRequest);
			return addRequest;
		}

		internal static RemoveRequest? BeginRemove(Container container, ItemData item, Inventory destination, Vector2i to, int dragAmount, ItemData? switchItem)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner())
			{
				return null;
			}
			dragAmount = InvUtil.PossibleAmount(destination, item, to, dragAmount);
			if (dragAmount <= 0 || SlotBlock.Of(destination).IsBlocked(to))
			{
				return null;
			}
			RemoveRequest removeRequest = new RemoveRequest(item.m_gridPos, to, dragAmount, switchItem, container.GetInventory(), destination);
			if (switchItem != null && !ItemPack.CanStack(item, switchItem))
			{
				if (dragAmount != item.m_stack)
				{
					return null;
				}
				destination.RemoveItem(switchItem);
			}
			RequestStore.Track(removeRequest);
			SlotBlock.Of(destination).Block(removeRequest.ToPos);
			if (container.m_nview.IsOwner())
			{
				RemoveResponse response = OwnerOps.ApplyRemove(container.GetInventory(), removeRequest);
				ApplyRemoveResponse(destination, response);
				return null;
			}
			RpcHub.Invoke(container.m_nview, "SS_RequestItemRemove", removeRequest);
			return removeRequest;
		}

		internal static void BeginMove(Container container, ItemData item, Vector2i toPos, int dragAmount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			MoveRequest package = new MoveRequest(item, toPos, dragAmount, container.GetInventory());
			RequestStore.Track(package);
			RpcHub.Invoke(container.m_nview, "SS_RequestItemMove", package);
		}

		internal static void OnAddResponse(long sender, ZDOID containerId, ZPackage package)
		{
			AddResponse addResponse = new AddResponse(package);
			ApplyAddResponse(RequestStore.Get<AddRequest>(addResponse.SourceId)?.SourceInventory, addResponse);
		}

		internal static void ApplyAddResponse(Inventory? inventory, AddResponse response)
		{
			//IL_000b: 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)
			if (inventory != null)
			{
				SlotBlock.Of(inventory).Release(response.InventoryPos);
				RequestStore.Forget(response);
				if (response.SwitchItem != null && !InvUtil.AddAt(inventory, response.SwitchItem, response.SwitchItem.m_stack, response.InventoryPos))
				{
					DropAtPlayer(response.SwitchItem, response.SwitchItem.m_stack);
				}
				RefreshGui(inventory);
			}
		}

		internal static void OnRemoveResponse(long sender, ZDOID containerId, ZPackage package)
		{
			RemoveResponse removeResponse = new RemoveResponse(package);
			ApplyRemoveResponse(RequestStore.Get<RemoveRequest>(removeResponse.SourceId)?.TargetInventory, removeResponse);
		}

		internal static void ApplyRemoveResponse(Inventory? inventory, RemoveResponse response)
		{
			//IL_0017: 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)
			//IL_001c: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			RemoveRequest removeRequest = RequestStore.Get<RemoveRequest>(response.SourceId);
			Vector2i val = removeRequest?.ToPos ?? Vector2i.zero;
			if (inventory == null)
			{
				inventory = removeRequest?.TargetInventory;
			}
			if (inventory == null)
			{
				return;
			}
			SlotBlock.Of(inventory).Release(val);
			RequestStore.Forget(response);
			if (response.Success && val.x >= 0 && val.y >= 0 && response.ResponseItem != null)
			{
				if (!InvUtil.AddAt(inventory, response.ResponseItem, response.Amount, val))
				{
					ItemData itemAt = inventory.GetItemAt(val.x, val.y);
					int num = response.Amount;
					if (itemAt != null && ItemPack.CanStack(response.ResponseItem, itemAt))
					{
						int num2 = itemAt.m_shared.m_maxStackSize - itemAt.m_stack;
						itemAt.m_stack += num2;
						num -= num2;
					}
					DropAtPlayer(response.ResponseItem, num);
				}
			}
			else if (response.ResponseItem != null)
			{
				Inventory val2 = new Inventory("ss_tmp", (Sprite)null, 1, 1);
				val2.AddItem(response.ResponseItem);
				inventory.MoveItemToThis(val2, response.ResponseItem);
				ItemData itemAt2 = val2.GetItemAt(0, 0);
				if (itemAt2 != null)
				{
					DropAtPlayer(itemAt2, itemAt2.m_stack);
				}
			}
			RefreshGui(inventory);
		}

		internal static void OnMoveResponse(long sender, ZDOID containerId, ZPackage package)
		{
			RequestStore.Forget(new MoveResponse(package));
		}

		internal static void OnConsumeResponse(long sender, ZDOID containerId, ZPackage package)
		{
			ConsumeResponse consumeResponse = new ConsumeResponse(package);
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			SlotBlock.Of(((Humanoid)localPlayer).GetInventory()).BlockConsume = false;
			if (consumeResponse.Item != null && ((Humanoid)localPlayer).CanConsumeItem(consumeResponse.Item, false))
			{
				if (Object.op_Implicit((Object)(object)consumeResponse.Item.m_shared.m_consumeStatusEffect))
				{
					((Character)localPlayer).m_seman.AddStatusEffect(consumeResponse.Item.m_shared.m_consumeStatusEffect, true, 0, 0f, (short)(-1));
				}
				if ((double)consumeResponse.Item.m_shared.m_food > 0.0)
				{
					localPlayer.EatFood(consumeResponse.Item);
				}
			}
		}

		internal static void OnDropResponse(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			DropResponse dropResponse = new DropResponse(package);
			DropAtPlayer(dropResponse.Item, dropResponse.Item?.m_stack ?? 0);
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && dropResponse.Sender == ((Character)Player.m_localPlayer).GetZDOID())
			{
				InventoryGui.instance.UpdateCraftingPanel(false);
			}
		}

		internal static void OnSalvageResponse(long sender, ZDOID containerId, ZPackage package)
		{
			ItemSalvage.OnChestItemRemoved(new SalvageResponse(package).Item);
		}

		internal static void DropAtPlayer(ItemData? item, int amount)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && item != null && amount > 0)
			{
				Transform transform = ((Component)localPlayer).transform;
				ItemDrop val = ItemDrop.DropItem(item, amount, transform.position + transform.forward + transform.up, transform.rotation);
				val.OnPlayerDrop();
				((Component)val).GetComponent<Rigidbody>().velocity = (transform.forward + Vector3.up) * 5f;
				((Character)localPlayer).m_zanim.SetTrigger("interact");
				((Humanoid)localPlayer).m_dropEffects.Create(transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				((Character)localPlayer).Message((MessageType)1, "$msg_dropped " + val.m_itemData.m_shared.m_name, val.m_itemData.m_stack, val.m_itemData.GetIcon(), false);
			}
		}

		private static void RefreshGui(Inventory inventory)
		{
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(inventory))
			{
				InventoryGui.instance.UpdateCraftingPanel(false);
			}
		}
	}
	internal static class InventoryExtensions
	{
		internal static IEnumerable<Inventory> GetInventories(this Inventory inventory)
		{
			yield return inventory;
		}
	}
	internal abstract class InvOwner
	{
		internal abstract ZNetView View { get; }

		internal abstract Inventory Inventory { get; }

		internal virtual bool IsValid()
		{
			if (Object.op_Implicit((Object)(object)View) && View.HasOwner())
			{
				return Inventory != null;
			}
			return false;
		}

		internal static InvOwner? Of(Inventory? inventory)
		{
			if (inventory == null)
			{
				return null;
			}
			if (PlayerLink.TryGet(inventory, out PlayerInvOwner owner))
			{
				return owner;
			}
			if (ContainerLink.TryGet(inventory, out ContainerInvOwner owner2))
			{
				return owner2;
			}
			return null;
		}

		internal static InvOwner? Of(ItemData? item)
		{
			if (item == null)
			{
				return null;
			}
			if (InventoryInterceptPatch.ItemInventory.TryGetValue(item, out Inventory value))
			{
				return Of(value);
			}
			return null;
		}
	}
	internal sealed class ContainerInvOwner : InvOwner
	{
		internal Container Container { get; }

		internal override ZNetView View => Container.m_nview;

		internal override Inventory Inventory => Container.GetInventory();

		internal ContainerInvOwner(Container container)
		{
			Container = container;
		}
	}
	internal sealed class PlayerInvOwner : InvOwner
	{
		private readonly Inventory _inventory;

		internal Humanoid Humanoid { get; }

		internal override ZNetView View => ((Character)Humanoid).m_nview;

		internal override Inventory Inventory => _inventory;

		internal PlayerInvOwner(Humanoid humanoid, Inventory inventory)
		{
			Humanoid = humanoid;
			_inventory = inventory;
		}
	}
	internal sealed class ContainerLink : MonoBehaviour
	{
		private static readonly ConditionalWeakTable<Inventory, ContainerInvOwner> Map = new ConditionalWeakTable<Inventory, ContainerInvOwner>();

		private Inventory? _inventory;

		private void Awake()
		{
			Container container = default(Container);
			if (!((Component)this).TryGetComponent<Container>(ref container))
			{
				return;
			}
			_inventory = container.GetInventory();
			if (_inventory != null)
			{
				Map.GetValue(_inventory, (Inventory _) => new ContainerInvOwner(container));
			}
		}

		private void OnDestroy()
		{
			if (_inventory != null)
			{
				Map.Remove(_inventory);
			}
		}

		internal static bool TryGet(Inventory inventory, out ContainerInvOwner? owner)
		{
			return Map.TryGetValue(inventory, out owner);
		}
	}
	internal sealed class PlayerLink : MonoBehaviour
	{
		private static readonly ConditionalWeakTable<Inventory, PlayerInvOwner> Map = new ConditionalWeakTable<Inventory, PlayerInvOwner>();

		private Inventory? _inventory;

		private void Awake()
		{
			Link();
		}

		private void Start()
		{
			Link();
		}

		private void Link()
		{
			Humanoid humanoid = default(Humanoid);
			if (!((Component)this).TryGetComponent<Humanoid>(ref humanoid))
			{
				return;
			}
			_inventory = humanoid.GetInventory();
			if (_inventory == null)
			{
				return;
			}
			foreach (Inventory sub in _inventory.GetInventories())
			{
				Map.GetValue(sub, (Inventory _) => new PlayerInvOwner(humanoid, sub));
			}
		}

		private void OnDestroy()
		{
			if (_inventory == null)
			{
				return;
			}
			foreach (Inventory inventory in _inventory.GetInventories())
			{
				Map.Remove(inventory);
			}
		}

		internal static bool TryGet(Inventory inventory, out PlayerInvOwner? owner)
		{
			return Map.TryGetValue(inventory, out owner);
		}
	}
	internal static class InvUtil
	{
		internal static Inventory Copy(Inventory target)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			return new Inventory(target.m_name, target.m_bkg, target.m_width, target.m_height)
			{
				m_inventory = new List<ItemData>(from x in target.GetAllItems()
					select x.Clone())
			};
		}

		internal static bool AddAt(Inventory target, ItemData item, int amount, Vector2i pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (amount <= 0)
			{
				return false;
			}
			ItemData itemAt = target.GetItemAt(pos.x, pos.y);
			if (itemAt != null)
			{
				if (!ItemPack.CanStack(itemAt, item))
				{
					return false;
				}
				if (itemAt.m_stack + amount > itemAt.m_shared.m_maxStackSize)
				{
					return false;
				}
			}
			ItemData val = ItemPack.CloneDeep(item);
			val.m_stack = amount;
			return target.AddItem(val, amount, pos.x, pos.y, false);
		}

		internal static bool MoveItem(Inventory inventory, ItemData item, int amount, Vector2i toPos, out int movedAmount)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			movedAmount = 0;
			if (item == null)
			{
				return false;
			}
			ItemData itemAt = inventory.GetItemAt(toPos.x, toPos.y);
			if (itemAt == item)
			{
				movedAmount = amount;
				return true;
			}
			if (itemAt == null)
			{
				movedAmount = amount;
				return inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y);
			}
			if (ItemPack.CanStack(itemAt, item))
			{
				movedAmount = Mathf.Min(amount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack);
				return inventory.MoveItemToThis(inventory, item, movedAmount, toPos.x, toPos.y);
			}
			if (item.m_stack != amount)
			{
				return false;
			}
			inventory.RemoveItem(item);
			inventory.MoveItemToThis(inventory, itemAt, itemAt.m_stack, item.m_gridPos.x, item.m_gridPos.y);
			inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y);
			movedAmount = amount;
			return true;
		}

		internal static int PossibleAmount(Inventory inventoryTo, ItemData dragItem, Vector2i to, int dragAmount)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			dragAmount = ((dragAmount >= 0) ? Mathf.Min(dragAmount, dragItem.m_stack) : dragItem.m_stack);
			if (to.x >= 0 && to.y >= 0)
			{
				ItemData itemAt = inventoryTo.GetItemAt(to.x, to.y);
				if (itemAt != null && dragAmount < dragItem.m_stack)
				{
					if (ItemPack.CanStack(itemAt, dragItem))
					{
						return Mathf.Min(dragAmount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack);
					}
					return 0;
				}
			}
			else if (!inventoryTo.HaveEmptySlot())
			{
				int num = inventoryTo.FindFreeStackSpace(dragItem.m_shared.m_name, (float)dragItem.m_worldLevel);
				return Mathf.Min(dragAmount, num);
			}
			return dragAmount;
		}
	}
	internal static class ItemPack
	{
		private static readonly MethodInfo MemberwiseCloneMethod = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null);

		internal static void Write(ItemData? item, ZPackage pkg)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			pkg.Write(item != null);
			if (item == null)
			{
				return;
			}
			pkg.Write(PrefabName(item));
			pkg.Write(item.m_stack);
			pkg.Write(item.m_durability);
			pkg.Write(item.m_gridPos);
			pkg.Write(item.m_quality);
			pkg.Write(item.m_variant);
			pkg.Write(item.m_crafterID);
			pkg.Write(item.m_crafterName);
			pkg.Write(item.m_worldLevel);
			pkg.Write(item.m_pickedUp);
			pkg.Write(item.m_customData.Count);
			foreach (KeyValuePair<string, string> customDatum in item.m_customData)
			{
				pkg.Write(customDatum.Key);
				pkg.Write(customDatum.Value);
			}
		}

		internal static ItemData? Read(ZPackage pkg)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00ab: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (!pkg.ReadBool())
			{
				return null;
			}
			string text = pkg.ReadString();
			int num = pkg.ReadInt();
			float num2 = pkg.ReadSingle();
			Vector2i val = pkg.ReadVector2i();
			int num3 = pkg.ReadInt();
			int num4 = pkg.ReadInt();
			long num5 = pkg.ReadLong();
			string text2 = pkg.ReadString();
			int num6 = pkg.ReadInt();
			bool flag = pkg.ReadBool();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num7 = pkg.ReadInt();
			for (int i = 0; i < num7; i++)
			{
				dictionary[pkg.ReadString()] = pkg.ReadString();
			}
			Inventory val2 = new Inventory("ss_tmp", (Sprite)null, val.x + 1, val.y + 1);
			val2.AddItem(text, num, num2, val, false, num3, num4, num5, text2, dictionary, num6, flag, false, false);
			ItemData itemAt = val2.GetItemAt(val.x, val.y);
			if (itemAt != null)
			{
				val2.RemoveItem(itemAt);
			}
			return itemAt;
		}

		internal static string PrefabName(ItemData item)
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return ((Object)item.m_dropPrefab).name;
			}
			return item.m_shared.m_name;
		}

		internal static bool CanStack(ItemData a, ItemData b)
		{
			if (a.m_shared.m_name == b.m_shared.m_name && (a.m_shared.m_maxQuality <= 1 || b.m_quality == a.m_quality))
			{
				return a.m_shared.m_maxStackSize != 1;
			}
			return false;
		}

		internal static ItemData CloneDeep(ItemData item)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ItemData obj = item.Clone();
			obj.m_shared = (SharedData)MemberwiseCloneMethod.Invoke(item.m_shared, null);
			return obj;
		}

		internal static ItemData? ClampStack(ItemData? item)
		{
			if (item == null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return item;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(PrefabName(item));
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return item;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component != (Object)null)
			{
				item.m_shared.m_maxStackSize = component.m_itemData.m_shared.m_maxStackSize;
			}
			return item;
		}
	}
	internal static class OwnerOps
	{
		internal static void OnAdd(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemAddResponse", ApplyAdd, new AddRequest(package));
		}

		internal static void OnRemove(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemRemoveResponse", ApplyRemove, new RemoveRequest(package));
		}

		internal static void OnMove(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemMoveResponse", ApplyMove, new MoveRequest(package));
		}

		internal static void OnConsume(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemConsumeResponse", ApplyConsume, new ConsumeRequest(package));
		}

		internal static void OnDrop(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemDropResponse", ApplyDrop, new DropRequest(package));
		}

		internal static void OnSalvage(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Handle(containerId, sender, "SS_RequestItemSalvageResponse", ApplySalvage, new SalvageRequest(package));
		}

		internal static void OnSort(long sender, ZDOID containerId, int mode)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(containerId);
			ZNetView val = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsOwner())
			{
				Container componentInChildren = ((Component)val).GetComponentInChildren<Container>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					InventorySorter.Sort(componentInChildren.GetInventory(), (SortMode)mode, isPlayer: false, ignoreHotbar: false);
				}
			}
		}

		private static void Handle<TIn, TOut>(ZDOID containerId, long target, string responseRpc, Func<Inventory, TIn, TOut> apply, TIn input) where TIn : ISsPackage where TOut : ISsPackage, new()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(containerId);
			ZNetView val = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null);
			TOut val2;
			if (!Object.op_Implicit((Object)(object)val) || !val.IsOwner())
			{
				val2 = Fallback<TOut>(input);
			}
			else
			{
				Container componentInChildren = ((Component)val).GetComponentInChildren<Container>();
				val2 = (((Object)(object)componentInChildren != (Object)null) ? apply(componentInChildren.GetInventory(), input) : Fallback<TOut>(input));
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(target, responseRpc, new object[2]
			{
				containerId,
				val2.Write()
			});
		}

		private static TOut Fallback<TOut>(ISsPackage input) where TOut : ISsPackage, new()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			TOut val = new TOut();
			if (input is ISsRequest ssRequest && val is ISsResponse ssResponse)
			{
				ssResponse.SourceId = ssRequest.RequestId;
			}
			if (input is AddRequest addRequest && val is AddResponse addResponse)
			{
				addResponse.SwitchItem = addRequest.DragItem;
				addResponse.InventoryPos = addRequest.DragItem?.m_gridPos ?? Vector2i.zero;
			}
			else if (input is RemoveRequest removeRequest && val is RemoveResponse removeResponse)
			{
				removeResponse.ResponseItem = removeRequest.SwitchItem;
			}
			return val;
		}

		internal static AddResponse ApplyAdd(Inventory inventory, AddRequest request)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (request.DragItem == null)
			{
				return new AddResponse(request.RequestId, success: false, Vector2i.zero, 0, request.DragItem);
			}
			if (request.ToPos.x < 0 || request.ToPos.y < 0)
			{
				return AddAny(inventory, request);
			}
			return AddSlot(inventory, request);
		}

		private static AddResponse AddSlot(Inventory inventory, AddRequest request)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!CanStackSlot(inventory, request, out int stackSpace, out ItemData removed))
			{
				return new AddResponse(request.RequestId, success: false, request.DragItem.m_gridPos, 0, request.DragItem);
			}
			bool flag = InvUtil.AddAt(inventory, request.DragItem, stackSpace, request.ToPos);
			if (!flag)
			{
				stackSpace = 0;
			}
			if (!flag || stackSpace != request.DragItem.m_stack)
			{
				removed = request.DragItem;
				removed.m_stack = request.DragItem.m_stack - stackSpace;
				removed.m_gridPos = request.DragItem.m_gridPos;
			}
			return new AddResponse(request.RequestId, flag, request.DragItem.m_gridPos, stackSpace, removed);
		}

		private static bool CanStackSlot(Inventory inventory, AddRequest request, out int stackSpace, out ItemData? removed)
		{
			ItemData itemAt = inventory.GetItemAt(request.ToPos.x, request.ToPos.y);
			removed = null;
			if (itemAt == null)
			{
				stackSpace = request.DragItem.m_stack;
				return true;
			}
			if (ItemPack.CanStack(itemAt, request.DragItem))
			{
				stackSpace = Mathf.Min(itemAt.m_shared.m_maxStackSize - itemAt.m_stack, request.DragItem.m_stack);
				return true;
			}
			if (request.AllowSwitch)
			{
				inventory.RemoveItem(itemAt, itemAt.m_stack);
				removed = itemAt;
				stackSpace = request.DragItem.m_stack;
				return true;
			}
			stackSpace = 0;
			return false;
		}

		private static AddResponse AddAny(Inventory inventory, AddRequest request)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_00c0: 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)
			Inventory val = new Inventory("ss_tmp", (Sprite)null, 1, 1);
			val.AddItem(request.DragItem.Clone(), request.DragItem.m_stack, 0, 0, false);
			inventory.MoveItemToThis(val, val.GetItemAt(0, 0));
			ItemData itemAt = val.GetItemAt(0, 0);
			if (itemAt == null)
			{
				return new AddResponse(request.RequestId, success: true, request.DragItem.m_gridPos, request.DragItem.m_stack, null);
			}
			ItemData val2 = request.DragItem.Clone();
			int num = request.DragItem.m_stack - itemAt.m_stack;
			val2.m_stack -= num;
			bool success = itemAt.m_stack != request.DragItem.m_stack;
			return new AddResponse(request.RequestId, success, request.DragItem.m_gridPos, num, val2);
		}

		internal static RemoveResponse ApplyRemove(Inventory inventory, RemoveRequest request)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemAt = inventory.GetItemAt(request.FromPos.x, request.FromPos.y);
			if (itemAt == null)
			{
				return new RemoveResponse(request.RequestId, success: false, 0, null);
			}
			int num = 0;
			ItemData switchItem = request.SwitchItem;
			bool success;
			if (switchItem == null)
			{
				num = Mathf.Min(itemAt.m_stack, request.DragAmount);
				success = inventory.RemoveItem(itemAt, num);
			}
			else if (ItemPack.CanStack(itemAt, switchItem))
			{
				num = Mathf.Min(switchItem.m_shared.m_maxStackSize - switchItem.m_stack, request.DragAmount);
				success = inventory.RemoveItem(itemAt, num);
			}
			else
			{
				if (request.DragAmount < itemAt.m_stack)
				{
					return new RemoveResponse(request.RequestId, success: false, 0, request.SwitchItem);
				}
				num = Mathf.Min(itemAt.m_stack, request.DragAmount);
				success = inventory.RemoveItem(itemAt, request.DragAmount);
				if (!InvUtil.AddAt(inventory, switchItem, switchItem.m_stack, request.FromPos))
				{
					ClientOps.DropAtPlayer(switchItem, switchItem.m_stack);
				}
			}
			ItemData val = itemAt.Clone();
			val.m_stack = num;
			return new RemoveResponse(request.RequestId, success, num, val);
		}

		private static MoveResponse ApplyMove(Inventory inventory, MoveRequest request)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemAt = inventory.GetItemAt(request.FromPos.x, request.FromPos.y);
			if (itemAt == null)
			{
				return new MoveResponse(request.RequestId, success: false, 0);
			}
			if (StringExtensionMethods.GetStableHashCode(ItemPack.PrefabName(itemAt)) != request.ItemHash)
			{
				return new MoveResponse(request.RequestId, success: false, 0);
			}
			int movedAmount;
			bool success = InvUtil.MoveItem(inventory, itemAt, request.DragAmount, request.ToPos, out movedAmount);
			return new MoveResponse(request.RequestId, success, movedAmount);
		}

		private static ConsumeResponse ApplyConsume(Inventory inventory, ConsumeRequest request)
		{
			ItemData itemAt = inventory.GetItemAt(request.ItemPosX, request.ItemPosY);
			if (itemAt == null || itemAt.m_stack <= 0)
			{
				return ConsumeResponse.FromItem(null);
			}
			inventory.RemoveOneItem(itemAt);
			ItemData obj = itemAt.Clone();
			obj.m_stack = 1;
			return ConsumeResponse.FromItem(obj);
		}

		private static DropResponse ApplyDrop(Inventory inventory, DropRequest request)
		{
			//IL_0022: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemAt = inventory.GetItemAt(request.Slot.x, request.Slot.y);
			if (itemAt == null)
			{
				return new DropResponse(null, request.Sender);
			}
			int num = Mathf.Min(itemAt.m_stack, request.Amount);
			inventory.RemoveItem(itemAt, num);
			if (num == 0)
			{
				return new DropResponse(null, request.Sender);
			}
			ItemData obj = itemAt.Clone();
			obj.m_stack = num;
			return new DropResponse(obj, request.Sender);
		}

		private static SalvageResponse ApplySalvage(Inventory inventory, SalvageRequest request)
		{
			ItemData itemAt = inventory.GetItemAt(request.Slot.x, request.Slot.y);
			if (itemAt == null || request.Amount <= 0 || itemAt.m_stack < request.Amount || itemAt.m_quality != request.Quality || StringExtensionMethods.GetStableHashCode(ItemPack.PrefabName(itemAt)) != request.ItemHash)
			{
				return new SalvageResponse();
			}
			ItemData obj = itemAt.Clone();
			obj.m_stack = request.Amount;
			inventory.RemoveItem(itemAt, request.Amount);
			return new SalvageResponse(obj);
		}
	}
	internal sealed class AddRequest : ISsRequest, ISsPackage
	{
		internal readonly Vector2i ToPos;

		internal readonly ItemData? DragItem;

		internal readonly bool AllowSwitch;

		public int RequestId { get; set; }

		public Inventory? SourceInventory { get; }

		public Inventory? TargetInventory { get; }

		internal AddRequest(Vector2i toPos, int dragAmount, ItemData? dragItem, Inventory? source, Inventory? target)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ToPos = toPos;
			SourceInventory = source;
			TargetInventory = target;
			if (dragItem != null)
			{
				DragItem = dragItem.Clone();
				DragItem.m_stack = Mathf.Min(dragAmount, DragItem.m_stack);
				AllowSwitch = dragAmount == dragItem.m_stack;
			}
		}

		internal AddRequest(ZPackage pkg)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			RequestId = pkg.ReadInt();
			ToPos = pkg.ReadVector2i();
			DragItem = ItemPack.Read(pkg);
			AllowSwitch = pkg.ReadBool();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(RequestId);
			val.Write(ToPos);
			ItemPack.Write(DragItem, val);
			val.Write(AllowSwitch);
			return val;
		}
	}
	internal sealed class AddResponse : ISsResponse, ISsPackage
	{
		internal bool Success;

		internal int Amount;

		internal Vector2i InventoryPos;

		internal ItemData? SwitchItem;

		public int SourceId { get; set; }

		public AddResponse()
		{
		}

		internal AddResponse(int sourceId, bool success, Vector2i inventoryPos, int amount, ItemData? switchItem)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			SourceId = sourceId;
			Success = success;
			InventoryPos = inventoryPos;
			Amount = amount;
			SwitchItem = ItemPack.ClampStack(switchItem);
		}

		internal AddResponse(ZPackage pkg)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SourceId = pkg.ReadInt();
			InventoryPos = pkg.ReadVector2i();
			Success = pkg.ReadBool();
			Amount = pkg.ReadInt();
			SwitchItem = ItemPack.Read(pkg);
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(SourceId);
			val.Write(InventoryPos);
			val.Write(Success);
			val.Write(Amount);
			ItemPack.Write(SwitchItem, val);
			return val;
		}
	}
	internal sealed class RemoveRequest : ISsRequest, ISsPackage
	{
		internal readonly Vector2i FromPos;

		internal readonly Vector2i ToPos;

		internal readonly int DragAmount;

		internal readonly ItemData? SwitchItem;

		public int RequestId { get; set; }

		public Inventory? SourceInventory { get; }

		public Inventory? TargetInventory { get; }

		internal RemoveRequest(Vector2i fromPos, Vector2i toPos, int dragAmount, ItemData? switchItem, Inventory? source, Inventory? target)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//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)
			FromPos = fromPos;
			ToPos = toPos;
			DragAmount = dragAmount;
			SwitchItem = ((switchItem != null) ? switchItem.Clone() : null);
			SourceInventory = source;
			TargetInventory = target;
		}

		internal RemoveRequest(ZPackage pkg)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			RequestId = pkg.ReadInt();
			FromPos = pkg.ReadVector2i();
			ToPos = pkg.ReadVector2i();
			DragAmount = pkg.ReadInt();
			SwitchItem = ItemPack.Read(pkg);
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(RequestId);
			val.Write(FromPos);
			val.Write(ToPos);
			val.Write(DragAmount);
			ItemPack.Write(SwitchItem, val);
			return val;
		}
	}
	internal sealed class RemoveResponse : ISsResponse, ISsPackage
	{
		internal bool Success;

		internal int Amount;

		internal ItemData? ResponseItem;

		public int SourceId { get; set; }

		public RemoveResponse()
		{
		}

		internal RemoveResponse(int sourceId, bool success, int amount, ItemData? responseItem)
		{
			SourceId = sourceId;
			Success = success;
			Amount = amount;
			ResponseItem = ItemPack.ClampStack(responseItem);
		}

		internal RemoveResponse(ZPackage pkg)
		{
			SourceId = pkg.ReadInt();
			Success = pkg.ReadBool();
			Amount = pkg.ReadInt();
			ResponseItem = ItemPack.Read(pkg);
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(SourceId);
			val.Write(Success);
			val.Write(Amount);
			ItemPack.Write(ResponseItem, val);
			return val;
		}
	}
	internal sealed class MoveRequest : ISsRequest, ISsPackage
	{
		internal readonly Vector2i FromPos;

		internal readonly Vector2i ToPos;

		internal readonly int ItemHash;

		internal readonly int DragAmount;

		public int RequestId { get; set; }

		public Inventory? SourceInventory { get; }

		public Inventory? TargetInventory { get; }

		internal MoveRequest(ItemData? item, Vector2i toPos, int dragAmount, Inventory? inventory)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			SourceInventory = inventory;
			TargetInventory = inventory;
			if (item == null)
			{
				FromPos = new Vector2i(-1, -1);
				ToPos = new Vector2i(-1, -1);
				return;
			}
			FromPos = item.m_gridPos;
			ToPos = toPos;
			ItemHash = StringExtensionMethods.GetStableHashCode(ItemPack.PrefabName(item));
			DragAmount = dragAmount;
		}

		internal MoveRequest(ZPackage pkg)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			RequestId = pkg.ReadInt();
			FromPos = pkg.ReadVector2i();
			ToPos = pkg.ReadVector2i();
			ItemHash = pkg.ReadInt();
			DragAmount = pkg.ReadInt();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(RequestId);
			val.Write(FromPos);
			val.Write(ToPos);
			val.Write(ItemHash);
			val.Write(DragAmount);
			return val;
		}
	}
	internal sealed class MoveResponse : ISsResponse, ISsPackage
	{
		internal bool Success;

		internal int Amount;

		public int SourceId { get; set; }

		public MoveResponse()
		{
		}

		internal MoveResponse(int sourceId, bool success, int amount)
		{
			SourceId = sourceId;
			Success = success;
			Amount = amount;
		}

		internal MoveResponse(ZPackage pkg)
		{
			SourceId = pkg.ReadInt();
			Success = pkg.ReadBool();
			Amount = pkg.ReadInt();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(SourceId);
			val.Write(Success);
			val.Write(Amount);
			return val;
		}
	}
	internal sealed class ConsumeRequest : ISsPackage
	{
		internal readonly int ItemPosX;

		internal readonly int ItemPosY;

		internal ConsumeRequest(ItemData item)
		{
			ItemPosX = item.m_gridPos.x;
			ItemPosY = item.m_gridPos.y;
		}

		internal ConsumeRequest(ZPackage pkg)
		{
			ItemPosX = pkg.ReadInt();
			ItemPosY = pkg.ReadInt();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(ItemPosX);
			val.Write(ItemPosY);
			return val;
		}
	}
	internal sealed class ConsumeResponse : ISsPackage
	{
		internal ItemData? Item;

		public ConsumeResponse()
		{
		}

		internal static ConsumeResponse FromItem(ItemData? item)
		{
			return new ConsumeResponse
			{
				Item = item
			};
		}

		internal ConsumeResponse(ZPackage pkg)
		{
			Item = ItemPack.Read(pkg);
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			ItemPack.Write(Item, val);
			return val;
		}
	}
	internal sealed class DropRequest : ISsPackage
	{
		internal readonly Vector2i Slot;

		internal readonly int Amount;

		internal readonly ZDOID Sender;

		internal DropRequest(Vector2i slot, int amount, ZDOID sender)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Slot = slot;
			Amount = amount;
			Sender = sender;
		}

		internal DropRequest(ZPackage pkg)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Slot = pkg.ReadVector2i();
			Amount = pkg.ReadInt();
			Sender = pkg.ReadZDOID();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(Slot);
			val.Write(Amount);
			val.Write(Sender);
			return val;
		}
	}
	internal sealed class SalvageRequest : ISsPackage
	{
		internal readonly Vector2i Slot;

		internal readonly int Amount;

		internal readonly int ItemHash;

		internal readonly int Quality;

		internal SalvageRequest(ItemData item, int amount)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Slot = item.m_gridPos;
			Amount = amount;
			ItemHash = StringExtensionMethods.GetStableHashCode(ItemPack.PrefabName(item));
			Quality = item.m_quality;
		}

		internal SalvageRequest(ZPackage pkg)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Slot = pkg.ReadVector2i();
			Amount = pkg.ReadInt();
			ItemHash = pkg.ReadInt();
			Quality = pkg.ReadInt();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(Slot);
			val.Write(Amount);
			val.Write(ItemHash);
			val.Write(Quality);
			return val;
		}
	}
	internal sealed class SalvageResponse : ISsPackage
	{
		internal ItemData? Item;

		public SalvageResponse()
		{
		}

		internal SalvageResponse(ItemData? item)
		{
			Item = item;
		}

		internal SalvageResponse(ZPackage pkg)
		{
			Item = ItemPack.Read(pkg);
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			ItemPack.Write(Item, val);
			return val;
		}
	}
	internal sealed class DropResponse : ISsPackage
	{
		internal ItemData? Item;

		internal ZDOID Sender;

		public DropResponse()
		{
		}

		internal DropResponse(ItemData? item, ZDOID sender)
		{
			//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;
			Sender = sender;
		}

		internal DropResponse(ZPackage pkg)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Item = ItemPack.Read(pkg);
			Sender = pkg.ReadZDOID();
		}

		public ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			ItemPack.Write(Item, val);
			val.Write(Sender);
			return val;
		}
	}
	[HarmonyPatch]
	internal static class ContainerOpenPatch
	{
		[HarmonyPatch(typeof(Container), "Awake")]
		[HarmonyPostfix]
		private static void ContainerAwake(Container __instance)
		{
			if (!SharedChest.ExternalMultiUserChestLoaded)
			{
				((Component)__instance).gameObject.AddComponent<ContainerLink>();
				if (!Object.op_Implicit((Object)(object)__instance.m_nview))
				{
					__instance.m_nview = (Object.op_Implicit((Object)(object)__instance.m_rootObjectOverride) ? ((Component)__instance.m_rootObjectOverride).GetComponent<ZNetView>() : ((Component)__instance).GetComponent<ZNetView>());
				}
			}
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestOpen")]
		[HarmonyPrefix]
		private static bool RequestOpen(Container __instance, long uid, long playerID)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!SharedChest.IsEnabled)
			{
				return true;
			}
			if (!__instance.m_nview.IsOwner())
			{
				return true;
			}
			if (!__instance.CheckAccess(playerID))
			{
				__instance.m_nview.InvokeRPC(uid, "RPC_OpenResponse", new object[1] { false });
				return false;
			}
			if (IsInUseByOther(__instance, uid))
			{
				ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
				__instance.m_nview.InvokeRPC(uid, "RPC_OpenResponse", new object[1] { true });
				return false;
			}
			ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
			__instance.m_nview.GetZDO().SetOwner(uid);
			__instance.m_nview.InvokeRPC(uid, "RPC_OpenResponse", new object[1] { true });
			return false;
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestStack")]
		[HarmonyPrefix]
		private static bool RequestStack(Container __instance, long uid, long playerID)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!SharedChest.IsEnabled)
			{
				return true;
			}
			if (!__instance.m_nview.IsOwner())
			{
				return true;
			}
			if (!__instance.CheckAccess(playerID))
			{
				__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { false });
				return false;
			}
			if (IsInUseByOther(__instance, uid))
			{
				ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
				__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { true });
				return false;
			}
			ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
			__instance.m_nview.GetZDO().SetOwner(uid);
			__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { true });
			return false;
		}

		private static bool IsInUseByOther(Container container, long requesterUid)
		{
			if (container.IsInUse() || (Object.op_Implicit((Object)(object)container.m_wagon) && container.m_wagon.InUse()))
			{
				return requesterUid != ZNet.GetUID();
			}
			return false;
		}

		[HarmonyPatch(typeof(Container), "Load")]
		[HarmonyPrefix]
		private static void AllowNonOwnerLoad(Container __instance, ref bool __state)
		{
			__state = false;
			if (SharedChest.IsEnabled && Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsValid() && !__instance.m_nview.IsOwner() && __instance.IsInUse())
			{
				AccessTools.Field(typeof(Container), "m_inUse")?.SetValue(__instance, false);
				__state = true;
			}
		}

		[HarmonyPatch(typeof(Container), "Load")]
		[HarmonyPostfix]
		private static void RestoreInUseAfterLoad(Container __instance, bool __state)
		{
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class GameStartPatch
	{
		private static void Postfix()
		{
			if (!SharedChest.ExternalMultiUserChestLoaded)
			{
				RpcHub.Register();
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "Awake")]
	internal static class HumanoidAwakePatch
	{
		private static void Postfix(Humanoid __instance)
		{
			if (!SharedChest.ExternalMultiUserChestLoaded)
			{
				((Component)__instance).gameObject.AddComponent<PlayerLink>();
			}
		}
	}
	[HarmonyPatch]
	internal static class InventoryGuiSharedPatch
	{
		[HarmonyPatch(typeof(InventoryGui), "Update")]
		[HarmonyPostfix]
		private static void UpdateContainerChanges(InventoryGui __instance)
		{
			if (SharedChest.IsEnabled && Object.op_Implicit((Object)(object)__instance.m_currentContainer) && Object.op_Implicit((Object)(object)__instance.m_currentContainer.m_nview) && __instance.m_currentContainer.m_nview.IsValid())
			{
				__instance.m_currentContainer.CheckForChanges();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> AllowNonOwnerOpen(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			if (SharedChest.ExternalMultiUserChestLoaded)
			{
				return instructions;
			}
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "m_currentContainer"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "IsOwner"), (string)null)
			}).RemoveInstructions(1).Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InventoryGuiSharedPatch), "CanShowContainer", (Type[])null, (Type[])null))
			})
				.InstructionEnumeration();
		}

		private static bool CanShowContainer(Container container)
		{
			if (!SharedChest.IsEnabled)
			{
				return container.IsOwner();
			}
			return true;
		}

		[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
		[HarmonyPrefix]
		private static bool RightClickConsume(InventoryGui __instance, InventoryGrid grid, ItemData item)
		{
			if (!SharedChest.IsEnabled)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if (item == null || !Object.op_Implicit((Object)(object)localPlayer))
			{
				return true;
			}
			if (grid.GetInventory() == ((Humanoid)localPlayer).GetInventory())
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)__instance.m_currentContainer) || __instance.m_currentContainer.IsOwner())
			{
				return true;
			}
			if (SlotBlock.Of(((Humanoid)localPlayer).GetInventory()).BlockConsume)
			{
				return false;
			}
			if (((Humanoid)localPlayer).CanConsumeItem(item, false))
			{
				SlotBlock.Of(((Humanoid)localPlayer).GetInventory()).BlockConsume = true;
				RpcHub.Invoke(__instance.m_currentContainer.m_nview, "SS_RequestItemConsume", new ConsumeRequest(item));
			}
			return false;
		}

		[HarmonyPatch(typeof(InventoryGui), "OnDropOutside")]
		[HarmonyPrefix]
		private static void DropOutside(InventoryGui __instance, ref bool __runOriginal)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (SharedChest.IsEnabled && __runOriginal && Object.op_Implicit((Object)(object)__instance.m_dragGo) && !((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(__instance.m_dragInventory) && Object.op_Implicit((Object)(object)__instance.m_currentContainer) && !__instance.m_currentContainer.IsOwner())
			{
				RpcHub.Invoke(__instance.m_currentContainer.m_nview, "SS_RequestItemDrop", new DropRequest(__instance.m_dragItem.m_gridPos, __instance.m_dragAmount, ((Character)Player.m_localPlayer).GetZDOID()));
				__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
				__runOriginal = false;
			}
		}
	}
	[HarmonyPatch]
	internal static class InventoryInterceptPatch
	{
		internal static readonly ConditionalWeakTable<ItemData, Inventory> ItemInventory = new ConditionalWeakTable<ItemData, Inventory>();

		private static readonly WeakReference<ItemData> LastRemoved = new WeakReference<ItemData>(null);

		private static bool _allowSwap = true;

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		private static void AddItemPrefix(Inventory __instance, ref bool __runOriginal, ItemData item, int amount, int x, int y, ref bool __result)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (SharedChest.IsEnabled && __runOriginal && Intercept(__instance, item, amount, new Vector2i(x, y), out var success))
			{
				__result = success;
				__runOriginal = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		private static void AddItemPrefix2(Inventory __instance, ref bool __runOriginal, ItemData item, ref bool __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (SharedChest.IsEnabled && __runOriginal && Intercept(__instance, item, item.m_stack, new Vector2i(-1, -1), out var success))
			{
				__result = success;
				__runOriginal = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		private static void RemovePrefix(Inventory __instance, ref bool __runOriginal, ref bool __result)
		{
			if (SharedChest.IsEnabled && __runOriginal)
			{
				InvOwner invOwner = InvOwner.Of(__instance);
				if (invOwner != null && invOwner.IsValid() && !invOwner.View.IsOwner())
				{
					__result = false;
					__runOriginal = false;
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		[HarmonyPostfix]
		private static void RemovePostfix(Inventory __instance, ItemData item, ref bool __result)
		{
			if (SharedChest.IsEnabled)
			{
				LastRemoved.SetTarget(__result ? item : null);
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void MoveAllPrefix()
		{
			if (SharedChest.IsEnabled)
			{
				_allowSwap = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void MoveAllPostfix()
		{
			if (SharedChest.IsEnabled)
			{
				_allowSwap = true;
			}
		}

		[HarmonyPatch(typeof(Inventory), "Changed")]
		[HarmonyPostfix]
		private static void ChangedPostfix(Inventory __instance)
		{
			if (!SharedChest.IsEnabled)
			{
				return;
			}
			foreach (Inventory inventory in __instance.GetInventories())
			{
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					ItemInventory.Remove(allItem);
					ItemInventory.Add(allItem, inventory);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "Pickup")]
		[HarmonyPrefix]
		private static bool BlockPickupWhilePending(Humanoid __instance)
		{
			if (!SharedChest.IsEnabled)
			{
				return true;
			}
			Inventory inventory = __instance.GetInventory();
			if (inventory != null)
			{
				return !SlotBlock.Of(inventory).AnyBlocked;
			}
			return true;
		}

		private static bool Intercept(Inventory inventory, ItemData item, int amount, Vector2i pos, out bool success)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			InvOwner invOwner = InvOwner.Of(item);
			InvOwner invOwner2 = InvOwner.Of(inventory);
			if (invOwner == null || !invOwner.IsValid() || invOwner2 == null || !invOwner2.IsValid())
			{
				success = false;
				return false;
			}
			if (invOwner.View.IsOwner() && !invOwner2.View.IsOwner() && invOwner2 is ContainerInvOwner containerInvOwner)
			{
				AddRequest addRequest = ClientOps.BeginAdd(containerInvOwner.Container, item, invOwner.Inventory, pos, amount);
				success = addRequest != null && addRequest.DragItem?.m_stack == amount;
				return true;
			}
			if (!invOwner.View.IsOwner() && invOwner2.View.IsOwner() && invOwner is ContainerInvOwner containerInvOwner2)
			{
				ItemData val = invOwner2.Inventory.GetItemAt(pos.x, pos.y);
				if (val == null && LastRemoved.TryGetTarget(out ItemData target) && InvOwner.Of(target) == invOwner2 && target.m_gridPos == pos)
				{
					val = target;
				}
				if (!_allowSwap && val != null)
				{
					success = false;
					return true;
				}
				if (val != null && ItemPack.CanStack(item, val))
				{
					val = null;
				}
				RemoveRequest removeRequest = ClientOps.BeginRemove(containerInvOwner2.Container, item, invOwner2.Inventory, pos, amount, val);
				success = removeRequest == null || removeRequest.DragAmount == amount;
				if (removeRequest == null)
				{
					success = true;
				}
				return true;
			}
			if (!invOwner.View.IsOwner() && !invOwner2.View.IsOwner() && invOwner is ContainerInvOwner containerInvOwner3 && invOwner2 is ContainerInvOwner containerInvOwner4 && (Object)(object)containerInvOwner3.Container == (Object)(object)containerInvOwner4.Container)
			{
				ClientOps.BeginMove(containerInvOwner3.Container, item, pos, amount);
				success = true;
				return true;
			}
			success = false;
			return false;
		}
	}
	internal interface ISsPackage
	{
		ZPackage Write();
	}
	internal interface ISsRequest : ISsPackage
	{
		int RequestId { get; set; }

		Inventory? SourceInventory { get; }

		Inventory? TargetInventory { get; }
	}
	internal interface ISsResponse : ISsPackage
	{
		int SourceId { get; set; }
	}
	internal static class RequestStore
	{
		private static readonly Dictionary<int, ISsPackage> Packages = new Dictionary<int, ISsPackage>();

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

		private static readonly Random Rng = new Random();

		private const float TimeoutSeconds = 60f;

		internal static int Track(ISsPackage package)
		{
			Prune();
			int num = Rng.Next(int.MinValue, int.MaxValue);
			if (package is ISsRequest ssRequest)
			{
				ssRequest.RequestId = num;
			}
			Packages[num] = package;
			AddedAt[num] = Time.time;
			return num;
		}

		internal static void Forget(int id)
		{
			Packages.Remove(id);
			AddedAt.Remove(id);
		}

		internal static void Forget(ISsResponse response)
		{
			Forget(response.SourceId);
		}

		internal static T? Get<T>(int id) where T : class, ISsPackage
		{
			if (!Packages.TryGetValue(id, out ISsPackage value))
			{
				return null;
			}
			return value as T;
		}

		private static void Prune()
		{
			if (Packages.Count == 0)
			{
				return;
			}
			float time = Time.time;
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, float> item in AddedAt)
			{
				if (time - item.Value >= 60f)
				{
					list.Add(item.Key);
				}
			}
			foreach (int item2 in list)
			{
				Forget(item2);
			}
		}
	}
	internal sealed class SlotBlock
	{
		private static readonly ConditionalWeakTable<Inventory, SlotBlock> Table = new ConditionalWeakTable<Inventory, SlotBlock>();

		private readonly HashSet<Vector2i> _blocked = new HashSet<Vector2i>();

		internal bool BlockConsume;

		internal bool AnyBlocked
		{
			get
			{
				if (_blocked.Count <= 0)
				{
					return BlockConsume;
				}
				return true;
			}
		}

		internal static SlotBlock Of(Inventory inventory)
		{
			return Table.GetValue(inventory, (Inventory _) => new SlotBlock());
		}

		internal void Block(Vector2i slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			if (slot.x >= 0 && slot.y >= 0)
			{
				_blocked.Add(slot);
			}
		}

		internal void Release(Vector2i slot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_blocked.Remove(slot);
		}

		internal bool IsBlocked(Vector2i slot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _blocked.Contains(slot);
		}
	}
	internal static class RpcNames
	{
		internal const string Add = "SS_RequestItemAdd";

		internal const string AddResponse = "SS_RequestItemAddResponse";

		internal const string Remove = "SS_RequestItemRemove";

		internal const string RemoveResponse = "SS_RequestItemRemoveResponse";

		internal const string Move = "SS_RequestItemMove";

		internal const string MoveResponse = "SS_RequestItemMoveResponse";

		internal const string Consume = "SS_RequestItemConsume";

		internal const string ConsumeResponse = "SS_RequestItemConsumeResponse";

		internal const string Drop = "SS_RequestItemDrop";

		internal const string DropResponse = "SS_RequestItemDropResponse";

		internal const string Salvage = "SS_RequestItemSalvage";

		internal const string SalvageResponse = "SS_RequestItemSalvageResponse";

		internal const string Sort = "SS_RequestSort";
	}
	internal static class RpcHub
	{
		internal static void Register()
		{
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemAdd", (Action<long, ZDOID, ZPackage>)OwnerOps.OnAdd);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemRemove", (Action<long, ZDOID, ZPackage>)OwnerOps.OnRemove);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemMove", (Action<long, ZDOID, ZPackage>)OwnerOps.OnMove);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemConsume", (Action<long, ZDOID, ZPackage>)OwnerOps.OnConsume);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemDrop", (Action<long, ZDOID, ZPackage>)OwnerOps.OnDrop);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemSalvage", (Action<long, ZDOID, ZPackage>)OwnerOps.OnSalvage);
			ZRoutedRpc.instance.Register<ZDOID, int>("SS_RequestSort", (Action<long, ZDOID, int>)OwnerOps.OnSort);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemAddResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnAddResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemRemoveResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnRemoveResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemMoveResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnMoveResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemConsumeResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnConsumeResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemDropResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnDropResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("SS_RequestItemSalvageResponse", (Action<long, ZDOID, ZPackage>)ClientOps.OnSalvageResponse);
		}

		internal static void Invoke(ZNetView netView, string rpc, ISsPackage package)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ZRoutedRpc.instance.InvokeRoutedRPC(netView.m_zdo.GetOwner(), rpc, new object[2]
			{
				netView.m_zdo.m_uid,
				package.Write()
			});
		}
	}
	public static class SharedChest
	{
		public const string MultiUserChestGuid = "com.maxsch.valheim.MultiUserChest";

		internal static ConfigEntry<DepositModule.Toggle> EnableSharedChests;

		public static bool ExternalMultiUserChestLoaded => Chainloader.PluginInfos.ContainsKey("com.maxsch.valheim.MultiUserChest");

		public static bool IsEnabled
		{
			get
			{
				if (!ExternalMultiUserChestLoaded && EnableSharedChests != null)
				{
					return EnableSharedChests.Value == DepositModule.Toggle.On;
				}
				return false;
			}
		}

		public static bool CanUseWhileInUse
		{
			get
			{
				if (!ExternalMultiUserChestLoaded)
				{
					return IsEnabled;
				}
				return true;
			}
		}

		internal static void SetEnabledConfig(ConfigEntry<DepositModule.Toggle> entry)
		{
			EnableSharedChests = entry;
		}
	}
	public static class SharedChestApi
	{
		public static bool IsEnabled => SharedChest.IsEnabled;

		public static bool CanUseWhileInUse => SharedChest.CanUseWhileInUse;

		public static Inventory CopyInventory(Inventory target)
		{
			return InvUtil.Copy(target);
		}

		public static int TryAddFromPlayer(Container container, ItemData item, int amount)
		{
			return ClientOps.TryAddFromPlayer(container, item, amount);
		}

		public static int HowMuchFits(Inventory target, ItemData item)
		{
			return InventoryMove.HowMuchFits(target, item);
		}
	}
}
namespace SeamlessStorage.Deposit
{
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	internal static class TerminalInitTerminalPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleOptionsFetcher <>9__0_1;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				if (args.Length > 1 && Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					ChestSearch.SearchNearby(string.Join(" ", args.Args.Skip(1).ToArray()));
				}
			}

			internal List<string> <Postfix>b__0_1()
			{
				if (Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					return ZNetScene.instance.GetPrefabNames();
				}
				return new List<string>();
			}
		}

		private static void Postfix(Terminal __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					if (args.Length > 1 && Object.op_Implicit((Object)(object)ZNetScene.instance))
					{
						ChestSearch.SearchNearby(string.Join(" ", args.Args.Skip(1).ToArray()));
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleOptionsFetcher val2 = () => Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefabNames() : new List<string>();
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("seamlesssearch", "[prefab name/query text] - search for items in chests near the player. It uses the prefab name", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false);
		}
	}
	public class DepositModule
	{
		public enum Toggle
		{
			Off,
			On
		}

		public enum StoreHighlightPreset
		{
			BrightCyan,
			NeonBlue,
			Lime,
			Gold,
			Magenta,
			White,
			Custom
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string Category;

			[UsedImplicitly]
			public Action<ConfigEntryBase>? CustomDrawer;
		}

		private class AcceptableShortcuts : AcceptableValueBase
		{
			public AcceptableShortcuts()
				: base(typeof(KeyboardShortcut))
			{
			}

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

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

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

		internal const string ModName = "Seamless Storage";

		internal const string ModVersion = "1.0.1";

		internal const string Author = "ModdedWolf";

		internal const string ModGUID = "ModdedWolf.SeamlessStorage";

		internal const string KgGuid = "kg.ItemDrawers";

		internal const string BackpacksGuid = "org.bepinex.plugins.backpacks";

		private static string ConfigFileName = "ModdedWolf.SeamlessStorage.cfg";

		private static readonly string ConfigFileFullPath = Paths.ConfigPath + Path.DirectorySeparatorChar + ConfigFileName;

		internal static string ConnectionError = "";

		private static Harmony _harmony = null;

		public static ManualLogSource DepositLog = null;

		private static BaseUnityPlugin Host = null;

		internal static bool BackpacksIsLoaded = false;

		internal static readonly string yamlFileName = "ModdedWolf.SeamlessStorage.Deposit.yml";

		internal static readonly string yamlPath = Paths.ConfigPath + Path.DirectorySeparatorChar + yamlFileName;

		internal static readonly CustomSyncedValue<string> DepositContainerData = new CustomSyncedValue<string>(ConfigSync, "seamlessDepositData", "");

		internal static readonly CustomSyncedValue<string> PullContainerGroupsData = new CustomSyncedValue<string>(ConfigSync, "seamlessDepositGroupsData", "");

		internal static Dictionary<string, object>? yamlData;

		internal static Dictionary<string?, HashSet<string?>> groups = null;

		internal static DepositModule self = null;

		private const string RangeMigrationMarker = "# Seamless Storage: containers without a range use the Fallback Chest Range config.";

		private static readonly Regex PinnedDefaultRange = new Regex("^\\s+range:\\s*6(\\.0+)?\\s*(#.*)?$", RegexOptions.IgnoreCase);

		internal static ConfigEntry<Toggle> EnableAutoDeposit = null;

		internal static ConfigEntry<Toggle> EnableChestRename = null;

		internal static ConfigEntry<Toggle> EnableItemSearchButton = null;

		internal static ConfigEntry<Toggle> EnableSingleItemDeposit = null;

		internal static ConfigEntry<Toggle> EnableRightClickDragDeposit = null;

		internal static ConfigEntry<Toggle> ChestsPickupFromGround = null;

		internal static ConfigEntry<Toggle> MustHaveExistingItemToPull =