Decompiled source of AutoStorage v1.0.1

BepInEx/plugins/OldMarket.AutoStorage/OldMarket.AutoStorage.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OldMarket.AutoStash")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OldMarket.AutoStash")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("885f682c-1afd-44bf-b472-80edfe0a5225")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OldMarket.AutoStorage;

[BepInPlugin("oldmarket.autostorage", "Old Market Auto Storage", "1.0.1")]
public class AutoStoragePlugin : BaseUnityPlugin
{
	public const string PluginGuid = "oldmarket.autostorage";

	public const string PluginName = "Old Market Auto Storage";

	public const string PluginVersion = "1.0.1";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> PreferOneDayLeftOverNormal;

	internal static ConfigEntry<string> KeyRegisterStorage;

	internal static ConfigEntry<string> KeyStoreAll;

	internal static ConfigEntry<string> KeyStoreCurrent;

	internal static ConfigEntry<string> KeyAutoStack;

	internal static ConfigEntry<string> KeyDropAll;

	private void Awake()
	{
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Expected O, but got Unknown
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		PreferOneDayLeftOverNormal = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "PreferOneDayLeftOverNormal", true, "If true, products with 1 day left are sent to the special '1-day-left cellar' position even when a normal storage position is registered. If false, the special position is only used when there is no normal storage position.");
		KeyRegisterStorage = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "RegisterStorageKey", "L", "Key used for registering a storage location for the current slot item (UnityEngine.InputSystem.Key name).");
		KeyStoreAll = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "StoreAllKey", "Y", "Key used for auto-storing all inventory slots (UnityEngine.InputSystem.Key name).");
		KeyStoreCurrent = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "StoreCurrentKey", "U", "Key used for auto-storing only the current slot (UnityEngine.InputSystem.Key name).");
		KeyAutoStack = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "AutoStackKey", "Home", "Key used for auto-stacking items placed on registered storage locations (UnityEngine.InputSystem.Key name).");
		KeyDropAll = ((BaseUnityPlugin)this).Config.Bind<string>("Keybinds", "DropAllKey", "B", "Key used for dropping all non-bag, non-tool inventory items at the player's feet (UnityEngine.InputSystem.Key name).");
		string text = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		if (string.IsNullOrEmpty(text))
		{
			text = Paths.PluginPath;
		}
		AutoStorageConfigManager.Initialize(text);
		Log.LogInfo((object)"[Old Market Auto Storage] 1.0.1 loaded.");
		GameObject val = new GameObject("AutoStorageController");
		Object.DontDestroyOnLoad((Object)val);
		((Object)val).hideFlags = (HideFlags)61;
		val.AddComponent<AutoStorageController>();
		GameObject val2 = new GameObject("AutoStorageWorldDebug");
		Object.DontDestroyOnLoad((Object)val2);
		((Object)val2).hideFlags = (HideFlags)61;
		val2.AddComponent<AutoStorageWorldDebug>();
		GameObject val3 = new GameObject("AutoStorageInventoryDebug");
		Object.DontDestroyOnLoad((Object)val3);
		((Object)val3).hideFlags = (HideFlags)61;
		val3.AddComponent<AutoStorageInventoryDebug>();
	}

	internal static void ShowNotification(string msg)
	{
		try
		{
			if ((Object)(object)UIManager.Instance != (Object)null)
			{
				UIManager.Instance.ShowNotification(msg, false, 2f, false);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] ShowNotification failed: " + ex));
			}
		}
	}
}
public class AutoStorageWorldDebug : MonoBehaviour
{
	private const Key DebugKey = 99;

	private GameObject _cellarMarker;

	private GameObject _junkmanMarker;

	private GameObject _workshopMarker;

	private GameObject _oneDayCellarMarker;

	private long _markersMapId = long.MinValue;

	private bool _markersVisible;

	private const float MarkerHeightOffset = 1f;

	private static Material _markerBaseMaterial;

	private void Awake()
	{
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		SceneManager.sceneLoaded += OnSceneLoaded;
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)"[AutoStorage] WorldDebug Awake (press F6 to dump world info and toggle markers).");
		}
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		ClearMarkers();
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		ClearMarkers();
		_markersVisible = false;
		_markersMapId = long.MinValue;
	}

	private void Update()
	{
		try
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				KeyControl val = current[(Key)99];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					DumpWorldInfo();
					ToggleMarkers();
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] WorldDebug exception in Update: " + ex));
			}
		}
	}

	private void DumpWorldInfo()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			GameManager instance = GameManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[AutoStorage DEBUG] GameManager.Instance is null.");
				}
				return;
			}
			string text;
			try
			{
				text = instance.GetMarketTitle();
			}
			catch
			{
				text = string.Empty;
			}
			long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
			string currentWorldKey = AutoStorageConfigManager.GetCurrentWorldKey();
			Vector3 val = Vector3.zero;
			try
			{
				PlayerInventory val2 = ((IEnumerable<PlayerInventory>)Object.FindObjectsOfType<PlayerInventory>()).FirstOrDefault((Func<PlayerInventory, bool>)((PlayerInventory i) => (Object)(object)i != (Object)null && ((NetworkBehaviour)i).IsOwner));
				if ((Object)(object)val2 != (Object)null)
				{
					val = ((Component)val2).transform.position;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = AutoStoragePlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[AutoStorage DEBUG] Failed to get player position: " + ex));
				}
			}
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)"========== [AutoStorage WORLD DEBUG] ==========");
			}
			ManualLogSource log4 = AutoStoragePlugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("[AutoStorage DEBUG] MarketTitle = '" + text + "'"));
			}
			ManualLogSource log5 = AutoStoragePlugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[AutoStorage DEBUG] mapId      = {mapId}");
			}
			ManualLogSource log6 = AutoStoragePlugin.Log;
			if (log6 != null)
			{
				log6.LogInfo((object)("[AutoStorage DEBUG] worldKey   = '" + currentWorldKey + "'"));
			}
			ManualLogSource log7 = AutoStoragePlugin.Log;
			if (log7 != null)
			{
				log7.LogInfo((object)$"[AutoStorage DEBUG] playerPos  = {val}");
			}
			if (AutoStorageConfigManager.DefaultConfig == null || AutoStorageConfigManager.DefaultConfig.Worlds == null)
			{
				ManualLogSource log8 = AutoStoragePlugin.Log;
				if (log8 != null)
				{
					log8.LogInfo((object)"[AutoStorage DEBUG] DefaultConfig or Worlds is null.");
				}
			}
			else
			{
				AutoStorageConfigManager.DefaultWorldConfig defaultWorldConfig = AutoStorageConfigManager.DefaultConfig.Worlds.FirstOrDefault((AutoStorageConfigManager.DefaultWorldConfig w) => w.mapId == mapId);
				if (defaultWorldConfig == null)
				{
					ManualLogSource log9 = AutoStoragePlugin.Log;
					if (log9 != null)
					{
						log9.LogInfo((object)"[AutoStorage DEBUG] No DefaultWorldConfig found for this mapId.");
					}
				}
				else
				{
					LogLocation("Cellar", defaultWorldConfig.cellar);
					LogLocation("Junkman", defaultWorldConfig.junkman);
					LogLocation("Workshop", defaultWorldConfig.workshop);
					LogLocation("OneDayLeftCellar", defaultWorldConfig.oneDayLeftCellar);
				}
			}
			ManualLogSource log10 = AutoStoragePlugin.Log;
			if (log10 != null)
			{
				log10.LogInfo((object)"==============================================");
			}
			AutoStoragePlugin.ShowNotification("AutoStorage: dumped world info (see LogOutput.log)");
		}
		catch (Exception ex2)
		{
			ManualLogSource log11 = AutoStoragePlugin.Log;
			if (log11 != null)
			{
				log11.LogError((object)("[AutoStorage DEBUG] DumpWorldInfo exception: " + ex2));
			}
		}
	}

	private void LogLocation(string label, AutoStorageConfigManager.DefaultLocation loc)
	{
		if (loc == null)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[AutoStorage DEBUG] " + label + ": (null)"));
			}
			return;
		}
		ManualLogSource log2 = AutoStoragePlugin.Log;
		if (log2 != null)
		{
			log2.LogInfo((object)$"[AutoStorage DEBUG] {label}: ({loc.x:F2}, {loc.y:F2}, {loc.z:F2})");
		}
	}

	private void ToggleMarkers()
	{
		try
		{
			GameManager instance = GameManager.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				long num = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
				if (!_markersVisible || _markersMapId != num)
				{
					CreateMarkersForCurrentMap(num);
					_markersVisible = true;
					_markersMapId = num;
				}
				else
				{
					ClearMarkers();
					_markersVisible = false;
					_markersMapId = long.MinValue;
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage DEBUG] ToggleMarkers exception: " + ex));
			}
		}
	}

	private void CreateMarkersForCurrentMap(long mapId)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		ClearMarkers();
		AutoStorageConfigManager.AutoStorageDefaultsConfig defaultConfig = AutoStorageConfigManager.DefaultConfig;
		if (defaultConfig == null || defaultConfig.Worlds == null)
		{
			return;
		}
		AutoStorageConfigManager.DefaultWorldConfig defaultWorldConfig = defaultConfig.Worlds.FirstOrDefault((AutoStorageConfigManager.DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[AutoStorage DEBUG] No DefaultWorldConfig found, cannot create markers.");
			}
			return;
		}
		EnsureMarkerBaseMaterial();
		if (defaultWorldConfig.cellar != null)
		{
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(defaultWorldConfig.cellar.x, defaultWorldConfig.cellar.y, defaultWorldConfig.cellar.z);
			_cellarMarker = CreateMarker("CellarMarker", position, Color.green);
		}
		if (defaultWorldConfig.junkman != null)
		{
			Vector3 position2 = default(Vector3);
			((Vector3)(ref position2))..ctor(defaultWorldConfig.junkman.x, defaultWorldConfig.junkman.y, defaultWorldConfig.junkman.z);
			_junkmanMarker = CreateMarker("JunkmanMarker", position2, Color.red);
		}
		if (defaultWorldConfig.workshop != null)
		{
			Vector3 position3 = default(Vector3);
			((Vector3)(ref position3))..ctor(defaultWorldConfig.workshop.x, defaultWorldConfig.workshop.y, defaultWorldConfig.workshop.z);
			_workshopMarker = CreateMarker("WorkshopMarker", position3, Color.blue);
		}
		if (defaultWorldConfig.oneDayLeftCellar != null)
		{
			Vector3 position4 = default(Vector3);
			((Vector3)(ref position4))..ctor(defaultWorldConfig.oneDayLeftCellar.x, defaultWorldConfig.oneDayLeftCellar.y, defaultWorldConfig.oneDayLeftCellar.z);
			_oneDayCellarMarker = CreateMarker("OneDayCellarMarker", position4, Color.yellow);
		}
	}

	private void EnsureMarkerBaseMaterial()
	{
		if ((Object)(object)_markerBaseMaterial != (Object)null)
		{
			return;
		}
		try
		{
			Renderer val = ((IEnumerable<Renderer>)Object.FindObjectsOfType<Renderer>()).FirstOrDefault((Func<Renderer, bool>)((Renderer r) => (Object)(object)r != (Object)null && (Object)(object)r.sharedMaterial != (Object)null));
			if ((Object)(object)val != (Object)null)
			{
				_markerBaseMaterial = val.sharedMaterial;
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("[AutoStorage DEBUG] Marker base material acquired from renderer '" + ((Object)((Component)val).gameObject).name + "'."));
				}
			}
			else
			{
				ManualLogSource log2 = AutoStoragePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[AutoStorage DEBUG] No renderer with sharedMaterial found. Markers will use sphere's default material.");
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogError((object)("[AutoStorage DEBUG] EnsureMarkerBaseMaterial failed: " + ex));
			}
		}
	}

	private GameObject CreateMarker(string name, Vector3 position, Color color)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
		((Object)val).name = name;
		val.transform.position = position + new Vector3(0f, 1f, 0f);
		val.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
		val.layer = LayerMask.NameToLayer("Default");
		Collider component = val.GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			component.enabled = false;
		}
		Renderer renderer = val.GetComponent<Renderer>();
		if ((Object)(object)renderer != (Object)null)
		{
			try
			{
				Material val2 = null;
				Renderer val3 = ((IEnumerable<Renderer>)Object.FindObjectsOfType<Renderer>()).FirstOrDefault((Func<Renderer, bool>)((Renderer r) => (Object)(object)r != (Object)(object)renderer && (Object)(object)r.sharedMaterial != (Object)null));
				if ((Object)(object)val3 != (Object)null)
				{
					val2 = val3.sharedMaterial;
				}
				else if ((Object)(object)renderer.sharedMaterial != (Object)null)
				{
					val2 = renderer.sharedMaterial;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					Material val4 = new Material(val2);
					if (val4.HasProperty("_MainTex"))
					{
						val4.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
					}
					if (val4.HasProperty("_BaseMap"))
					{
						val4.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture);
					}
					Color val5 = color;
					val5.a = 1f;
					if (val4.HasProperty("_BaseColor"))
					{
						val4.SetColor("_BaseColor", val5);
					}
					else if (val4.HasProperty("_Color"))
					{
						val4.SetColor("_Color", val5);
					}
					Color val6 = color * 3f;
					val6.a = 1f;
					bool flag = false;
					if (val4.HasProperty("_EmissionColor"))
					{
						val4.EnableKeyword("_EMISSION");
						val4.SetColor("_EmissionColor", val6);
						flag = true;
					}
					if (!flag && val4.HasProperty("_EmissionColorLDR"))
					{
						val4.EnableKeyword("_EMISSION");
						val4.SetColor("_EmissionColorLDR", val6);
					}
					renderer.shadowCastingMode = (ShadowCastingMode)0;
					renderer.receiveShadows = false;
					if (val4.HasProperty("_Surface"))
					{
						val4.SetFloat("_Surface", 0f);
					}
					if (val4.HasProperty("_SrcBlend"))
					{
						val4.SetInt("_SrcBlend", 1);
					}
					if (val4.HasProperty("_DstBlend"))
					{
						val4.SetInt("_DstBlend", 0);
					}
					if (val4.HasProperty("_ZWrite"))
					{
						val4.SetInt("_ZWrite", 1);
					}
					val4.DisableKeyword("_ALPHATEST_ON");
					val4.DisableKeyword("_ALPHABLEND_ON");
					val4.DisableKeyword("_ALPHAPREMULTIPLY_ON");
					val4.renderQueue = 2000;
					renderer.material = val4;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogError((object)("[AutoStorage DEBUG] Failed to setup marker material: " + ex));
				}
			}
		}
		Object.DontDestroyOnLoad((Object)(object)val);
		return val;
	}

	private void ClearMarkers()
	{
		DestroySafe(ref _cellarMarker);
		DestroySafe(ref _junkmanMarker);
		DestroySafe(ref _workshopMarker);
		DestroySafe(ref _oneDayCellarMarker);
	}

	private void DestroySafe(ref GameObject go)
	{
		if ((Object)(object)go != (Object)null)
		{
			Object.Destroy((Object)(object)go);
			go = null;
		}
	}
}
public class AutoStorageInventoryDebug : MonoBehaviour
{
	private const Key DebugKey = 100;

	private void Awake()
	{
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)"[AutoStorage] InventoryDebug Awake (press F7 to dump inventory info).");
		}
	}

	private void Update()
	{
		try
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				KeyControl val = current[(Key)100];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					DumpCurrentSlotAndInventory();
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] InventoryDebug exception in Update: " + ex));
			}
		}
	}

	private void DumpCurrentSlotAndInventory()
	{
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_033e: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			GameManager instance = GameManager.Instance;
			if ((Object)(object)instance == (Object)null || !instance.IsWorldLoaded())
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[AutoStorage DEBUG] GameManager not ready or world not loaded.");
				}
				return;
			}
			PlayerInventory val = null;
			try
			{
				val = ((IEnumerable<PlayerInventory>)Object.FindObjectsOfType<PlayerInventory>()).FirstOrDefault((Func<PlayerInventory, bool>)((PlayerInventory pi) => (Object)(object)pi != (Object)null && ((NetworkBehaviour)pi).IsOwner));
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = AutoStoragePlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[AutoStorage DEBUG] Failed to find PlayerInventory: " + ex));
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log3 = AutoStoragePlugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)"[AutoStorage DEBUG] Local PlayerInventory not found.");
				}
				return;
			}
			ManualLogSource log4 = AutoStoragePlugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)"========== [AutoStorage INVENTORY DEBUG] ==========");
			}
			int value = val.currentSlot.Value;
			InventorySlot currentInventorySlot = val.GetCurrentInventorySlot();
			ItemSO val2 = ((currentInventorySlot.itemId != -1) ? instance.GetItemById(currentInventorySlot.itemId) : null);
			ManualLogSource log5 = AutoStoragePlugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[AutoStorage DEBUG] CurrentSlotIndex = {value}");
			}
			ManualLogSource log6 = AutoStoragePlugin.Log;
			if (log6 != null)
			{
				log6.LogInfo((object)$"[AutoStorage DEBUG] CurrentSlot: itemId={currentInventorySlot.itemId}, amount={currentInventorySlot.amount}, cost={currentInventorySlot.cost}, dayCounter={currentInventorySlot.dayCounter}");
			}
			if ((Object)(object)val2 != (Object)null)
			{
				string name = ((object)val2).GetType().Name;
				bool flag = val2 is BagSO;
				bool flag2 = val2 is ToolSO;
				ManualLogSource log7 = AutoStoragePlugin.Log;
				if (log7 != null)
				{
					log7.LogInfo((object)($"[AutoStorage DEBUG] Current ItemSO: type={name}, isBag={flag}, isTool={flag2}, " + $"name='{val2.itemName}', basePrice={val2.basePrice}, stackSize={val2.stackSize}, id={val2.id}"));
				}
			}
			else
			{
				ManualLogSource log8 = AutoStoragePlugin.Log;
				if (log8 != null)
				{
					log8.LogInfo((object)"[AutoStorage DEBUG] Current ItemSO: null");
				}
			}
			ManualLogSource log9 = AutoStoragePlugin.Log;
			if (log9 != null)
			{
				log9.LogInfo((object)"---------- ALL SLOTS ----------");
			}
			NetworkList<InventorySlot> slots = val.slots;
			for (int i = 0; i < slots.Count; i++)
			{
				InventorySlot val3 = slots[i];
				if (val3.itemId != -1 || val3.amount > 0)
				{
					ItemSO itemById = instance.GetItemById(val3.itemId);
					string text = (((Object)(object)itemById != (Object)null && !string.IsNullOrEmpty(itemById.itemName)) ? itemById.itemName : val3.itemId.ToString());
					string text2 = (((Object)(object)itemById != (Object)null) ? ((object)itemById).GetType().Name : "null");
					bool flag3 = itemById is BagSO;
					bool flag4 = itemById is ToolSO;
					ManualLogSource log10 = AutoStoragePlugin.Log;
					if (log10 != null)
					{
						log10.LogInfo((object)($"[AutoStorage DEBUG] Slot[{i}]: itemId={val3.itemId}, amount={val3.amount}, cost={val3.cost}, dayCounter={val3.dayCounter}, " + $"ItemType={text2}, isBag={flag3}, isTool={flag4}, ItemName='{text}'"));
					}
				}
			}
			ManualLogSource log11 = AutoStoragePlugin.Log;
			if (log11 != null)
			{
				log11.LogInfo((object)"==============================================");
			}
		}
		catch (Exception ex2)
		{
			ManualLogSource log12 = AutoStoragePlugin.Log;
			if (log12 != null)
			{
				log12.LogError((object)("[AutoStorage DEBUG] DumpCurrentSlotAndInventory exception: " + ex2));
			}
		}
	}
}
internal static class AutoStorageConfigManager
{
	[Serializable]
	public class DepositPoint
	{
		public long ItemId;

		public float X;

		public float Y;

		public float Z;
	}

	[Serializable]
	public class WorldStorageConfig
	{
		public string WorldKey;

		public List<DepositPoint> Deposits;
	}

	[Serializable]
	public class DefaultLocation
	{
		public float x;

		public float y;

		public float z;
	}

	[Serializable]
	public class DefaultWorldConfig
	{
		public long mapId;

		public string worldTitle;

		public DefaultLocation cellar;

		public DefaultLocation junkman;

		public DefaultLocation workshop;

		public DefaultLocation oneDayLeftCellar;
	}

	[Serializable]
	public class AutoStorageDefaultsConfig
	{
		public List<DefaultWorldConfig> Worlds;
	}

	[Serializable]
	public class JunkmanLimitEntry
	{
		public long ItemId;

		public int MaxAmount;
	}

	[Serializable]
	private class JunkmanLimitsConfig
	{
		public List<JunkmanLimitEntry> Limits;
	}

	internal static string ConfigDirectory;

	private static bool _initialized;

	private static string _cachedWorldKey;

	private static WorldStorageConfig _cachedWorldConfig;

	internal static string DefaultConfigPath;

	internal static AutoStorageDefaultsConfig DefaultConfig;

	private static readonly HashSet<long> FishingTrashAndTrophyIds = new HashSet<long> { 1724272114666L, 1724272399327L, 1724272458460L, 1724272506042L, 1724272351457L, 1724253294653L };

	private static readonly HashSet<long> GatheringIds = new HashSet<long> { 1743946053037L, 1743945470505L, 1744379440551L, 1744379478330L, 1734622697722L, 1744379615565L, 1744379648133L, 1744379574797L, 1744379523651L, 1760107774195L };

	private static readonly HashSet<long> OreIds = new HashSet<long> { 1734622792143L, 1734622959366L, 1734623109544L, 1760106644678L, 1760108909804L };

	private static readonly HashSet<long> IngotIds = new HashSet<long> { 1734623060980L, 1734622864907L, 1734623167027L, 1734623245362L };

	private static readonly HashSet<long> LivestockMaterialIds = new HashSet<long> { 1734622103209L, 1734468509159L };

	internal static string LimitsConfigPath;

	internal static Dictionary<long, int> JunkmanLimits = new Dictionary<long, int>();

	internal static Dictionary<long, int> JunkmanLimitTable => JunkmanLimits;

	internal static string MaterialCategoriesPath => Path.Combine(ConfigDirectory, "OldMarket.AutoStorage.materialCategories.json");

	public static void Initialize(string pluginDirectory)
	{
		if (!_initialized)
		{
			ConfigDirectory = Path.Combine(Paths.ConfigPath, "OldMarket.AutoStorage");
			if (!Directory.Exists(ConfigDirectory))
			{
				Directory.CreateDirectory(ConfigDirectory);
			}
			DefaultConfigPath = Path.Combine(ConfigDirectory, "OldMarket.AutoStorage.defaults.json");
			LimitsConfigPath = Path.Combine(ConfigDirectory, "OldMarket.AutoStorage.limits.json");
			LoadDefaultConfig();
			ExportMaterialCategories();
			LoadJunkmanLimitsConfig();
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[AutoStorage] Config directory: " + ConfigDirectory));
			}
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[AutoStorage] Defaults config : " + DefaultConfigPath));
			}
			_initialized = true;
		}
	}

	public static string GetCurrentWorldKey()
	{
		try
		{
			GameManager instance = GameManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "UNKNOWN";
			}
			return ((long)(((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1))).ToString();
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] GetCurrentWorldKey failed: " + ex));
			}
			return "UNKNOWN";
		}
	}

	private static string GetWorldConfigPath(string worldKey)
	{
		string text = (string.IsNullOrEmpty(worldKey) ? "UNKNOWN" : worldKey);
		return Path.Combine(ConfigDirectory, "OldMarket.AutoStorage." + text + ".json");
	}

	private static WorldStorageConfig GetWorldConfig(string worldKey, bool createIfMissing)
	{
		if (_cachedWorldConfig != null && string.Equals(_cachedWorldKey, worldKey, StringComparison.Ordinal))
		{
			return _cachedWorldConfig;
		}
		WorldStorageConfig worldStorageConfig = LoadWorldConfig(worldKey);
		if (worldStorageConfig != null)
		{
			_cachedWorldKey = worldKey;
			_cachedWorldConfig = worldStorageConfig;
			return worldStorageConfig;
		}
		if (!createIfMissing)
		{
			return null;
		}
		worldStorageConfig = new WorldStorageConfig
		{
			WorldKey = worldKey,
			Deposits = new List<DepositPoint>()
		};
		_cachedWorldKey = worldKey;
		_cachedWorldConfig = worldStorageConfig;
		SaveWorldConfig(worldStorageConfig);
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)("[AutoStorage] Created new world config for key=" + worldKey));
		}
		return worldStorageConfig;
	}

	private static WorldStorageConfig LoadWorldConfig(string worldKey)
	{
		try
		{
			string worldConfigPath = GetWorldConfigPath(worldKey);
			if (!File.Exists(worldConfigPath))
			{
				return null;
			}
			string text = File.ReadAllText(worldConfigPath, Encoding.UTF8);
			if (string.IsNullOrWhiteSpace(text))
			{
				return new WorldStorageConfig
				{
					WorldKey = worldKey,
					Deposits = new List<DepositPoint>()
				};
			}
			WorldStorageConfig worldStorageConfig = ParseWorldConfigJson(text);
			if (worldStorageConfig == null)
			{
				return null;
			}
			if (worldStorageConfig.Deposits == null)
			{
				worldStorageConfig.Deposits = new List<DepositPoint>();
			}
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[AutoStorage] World config loaded for key={worldKey}, deposits={worldStorageConfig.Deposits.Count}");
			}
			return worldStorageConfig;
		}
		catch (Exception arg)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)$"[AutoStorage] LoadWorldConfig failed for key={worldKey}: {arg}");
			}
			return null;
		}
	}

	private static void SaveWorldConfig(WorldStorageConfig cfg)
	{
		try
		{
			string worldConfigPath = GetWorldConfigPath(cfg.WorldKey);
			string contents = BuildWorldConfigJson(cfg);
			File.WriteAllText(worldConfigPath, contents, Encoding.UTF8);
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[AutoStorage] World config saved: {worldConfigPath} (deposits={cfg.Deposits?.Count ?? 0})");
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)$"[AutoStorage] SaveWorldConfig failed for key={cfg.WorldKey}: {arg}");
			}
		}
	}

	public static void SetDepositForItem(string worldKey, long itemId, Vector3 position)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		WorldStorageConfig worldConfig = GetWorldConfig(worldKey, createIfMissing: true);
		if (worldConfig.Deposits == null)
		{
			worldConfig.Deposits = new List<DepositPoint>();
		}
		DepositPoint depositPoint = worldConfig.Deposits.FirstOrDefault((DepositPoint d) => d.ItemId == itemId);
		if (depositPoint == null)
		{
			depositPoint = new DepositPoint
			{
				ItemId = itemId
			};
			worldConfig.Deposits.Add(depositPoint);
		}
		depositPoint.X = position.x;
		depositPoint.Y = position.y;
		depositPoint.Z = position.z;
		SaveWorldConfig(worldConfig);
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)$"[AutoStorage] SetDepositForItem: worldKey={worldKey}, itemId={itemId}, pos={position}");
		}
	}

	public static bool TryGetDepositForItem(string worldKey, long itemId, out Vector3 position)
	{
		//IL_000e: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		WorldStorageConfig worldConfig = GetWorldConfig(worldKey, createIfMissing: false);
		if (worldConfig == null || worldConfig.Deposits == null)
		{
			return false;
		}
		DepositPoint depositPoint = worldConfig.Deposits.FirstOrDefault((DepositPoint d) => d.ItemId == itemId);
		if (depositPoint == null)
		{
			return false;
		}
		position = new Vector3(depositPoint.X, depositPoint.Y, depositPoint.Z);
		return true;
	}

	public static List<Vector3> GetAllDepositPositionsForWorld(string worldKey)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		WorldStorageConfig worldConfig = GetWorldConfig(worldKey, createIfMissing: false);
		if (worldConfig == null || worldConfig.Deposits == null)
		{
			return list;
		}
		foreach (DepositPoint deposit in worldConfig.Deposits)
		{
			list.Add(new Vector3(deposit.X, deposit.Y, deposit.Z));
		}
		return list;
	}

	private static WorldStorageConfig ParseWorldConfigJson(string json)
	{
		WorldStorageConfig worldStorageConfig = new WorldStorageConfig
		{
			WorldKey = string.Empty,
			Deposits = new List<DepositPoint>()
		};
		try
		{
			Match match = Regex.Match(json, "\"WorldKey\"\\s*:\\s*\"(?<key>[^\"]*)\"", RegexOptions.Singleline);
			if (match.Success)
			{
				worldStorageConfig.WorldKey = match.Groups["key"].Value;
			}
			foreach (Match item in new Regex("\"ItemId\"\\s*:\\s*(?<id>-?\\d+)\\s*,\\s*\"X\"\\s*:\\s*(?<x>-?\\d+(?:\\.\\d+)?)\\s*,\\s*\"Y\"\\s*:\\s*(?<y>-?\\d+(?:\\.\\d+)?)\\s*,\\s*\"Z\"\\s*:\\s*(?<z>-?\\d+(?:\\.\\d+)?)", RegexOptions.Singleline).Matches(json))
			{
				if (item.Success)
				{
					string value = item.Groups["id"].Value;
					string value2 = item.Groups["x"].Value;
					string value3 = item.Groups["y"].Value;
					string value4 = item.Groups["z"].Value;
					if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
					{
						float result2 = 0f;
						float result3 = 0f;
						float result4 = 0f;
						float.TryParse(value2, NumberStyles.Float, CultureInfo.InvariantCulture, out result2);
						float.TryParse(value3, NumberStyles.Float, CultureInfo.InvariantCulture, out result3);
						float.TryParse(value4, NumberStyles.Float, CultureInfo.InvariantCulture, out result4);
						worldStorageConfig.Deposits.Add(new DepositPoint
						{
							ItemId = result,
							X = result2,
							Y = result3,
							Z = result4
						});
					}
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] ParseWorldConfigJson failed: " + ex));
			}
		}
		return worldStorageConfig;
	}

	private static string BuildWorldConfigJson(WorldStorageConfig cfg)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("{\n");
		stringBuilder.Append("  \"WorldKey\": \"").Append(EscapeJsonString(cfg.WorldKey ?? string.Empty)).Append("\",\n");
		stringBuilder.Append("  \"Deposits\": [");
		if (cfg.Deposits != null && cfg.Deposits.Count > 0)
		{
			for (int i = 0; i < cfg.Deposits.Count; i++)
			{
				DepositPoint depositPoint = cfg.Deposits[i];
				if (i > 0)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.Append("\n    {\n");
				stringBuilder.Append("      \"ItemId\": ").Append(depositPoint.ItemId).Append(",\n");
				stringBuilder.Append("      \"X\": ").Append(depositPoint.X.ToString(CultureInfo.InvariantCulture)).Append(",\n");
				stringBuilder.Append("      \"Y\": ").Append(depositPoint.Y.ToString(CultureInfo.InvariantCulture)).Append(",\n");
				stringBuilder.Append("      \"Z\": ").Append(depositPoint.Z.ToString(CultureInfo.InvariantCulture)).Append("\n");
				stringBuilder.Append("    }");
			}
			stringBuilder.Append("\n  ]\n");
		}
		else
		{
			stringBuilder.Append("]\n");
		}
		stringBuilder.Append("}\n");
		return stringBuilder.ToString();
	}

	private static string EscapeJsonString(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return string.Empty;
		}
		return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
	}

	private static void LoadDefaultConfig()
	{
		try
		{
			if (!File.Exists(DefaultConfigPath))
			{
				RecreateDefaultsWithBuiltInEntries();
				return;
			}
			string text = File.ReadAllText(DefaultConfigPath, Encoding.UTF8);
			if (string.IsNullOrWhiteSpace(text))
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[AutoStorage] Defaults config is empty. Recreating with built-in entries.");
				}
				RecreateDefaultsWithBuiltInEntries();
				return;
			}
			AutoStorageDefaultsConfig autoStorageDefaultsConfig = ParseDefaultsConfigJson(text);
			if (autoStorageDefaultsConfig != null && autoStorageDefaultsConfig.Worlds != null && autoStorageDefaultsConfig.Worlds.Count > 0)
			{
				DefaultConfig = autoStorageDefaultsConfig;
				return;
			}
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)"[AutoStorage] Defaults config JSON had no valid Worlds. Recreating with built-in entries.");
			}
			RecreateDefaultsWithBuiltInEntries();
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogError((object)("[AutoStorage] Failed to load defaults config, recreating with built-in entries: " + ex));
			}
			RecreateDefaultsWithBuiltInEntries();
		}
	}

	private static void SaveDefaultConfig()
	{
		try
		{
			if (DefaultConfig == null)
			{
				DefaultConfig = new AutoStorageDefaultsConfig
				{
					Worlds = new List<DefaultWorldConfig>()
				};
			}
			if (DefaultConfig.Worlds == null)
			{
				DefaultConfig.Worlds = new List<DefaultWorldConfig>();
			}
			string contents = BuildDefaultsConfigJson(DefaultConfig);
			File.WriteAllText(DefaultConfigPath, contents, Encoding.UTF8);
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[AutoStorage] Defaults config saved.");
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("[AutoStorage] Failed to save defaults config: " + ex));
			}
		}
	}

	private static string BuildDefaultsConfigJson(AutoStorageDefaultsConfig data)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("{\n  \"Worlds\": [");
		if (data.Worlds != null)
		{
			for (int i = 0; i < data.Worlds.Count; i++)
			{
				DefaultWorldConfig defaultWorldConfig = data.Worlds[i];
				if (i > 0)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.Append("\n    {\n");
				stringBuilder.Append("      \"mapId\": ").Append(defaultWorldConfig.mapId);
				bool num = defaultWorldConfig.cellar != null;
				bool flag = defaultWorldConfig.junkman != null;
				bool flag2 = defaultWorldConfig.workshop != null;
				bool flag3 = defaultWorldConfig.oneDayLeftCellar != null;
				if (num)
				{
					stringBuilder.Append(",\n      \"cellar\": ");
					AppendLocationObject(stringBuilder, defaultWorldConfig.cellar, 6);
				}
				if (flag)
				{
					stringBuilder.Append(",\n      \"junkman\": ");
					AppendLocationObject(stringBuilder, defaultWorldConfig.junkman, 6);
				}
				if (flag2)
				{
					stringBuilder.Append(",\n      \"workshop\": ");
					AppendLocationObject(stringBuilder, defaultWorldConfig.workshop, 6);
				}
				if (flag3)
				{
					stringBuilder.Append(",\n      \"oneDayLeftCellar\": ");
					AppendLocationObject(stringBuilder, defaultWorldConfig.oneDayLeftCellar, 6);
				}
				stringBuilder.Append("\n    }");
			}
		}
		stringBuilder.Append("\n  ]\n}\n");
		return stringBuilder.ToString();
	}

	private static void AppendLocationObject(StringBuilder sb, DefaultLocation loc, int indent)
	{
		string value = new string(' ', indent);
		sb.Append("{\n");
		sb.Append(value).Append("  \"x\": ").Append(loc.x.ToString(CultureInfo.InvariantCulture))
			.Append(",\n");
		sb.Append(value).Append("  \"y\": ").Append(loc.y.ToString(CultureInfo.InvariantCulture))
			.Append(",\n");
		sb.Append(value).Append("  \"z\": ").Append(loc.z.ToString(CultureInfo.InvariantCulture))
			.Append("\n");
		sb.Append(value).Append("}");
	}

	public static void EnsureWorldDefaultsEntry(long mapId, string worldTitle)
	{
		if (DefaultConfig == null)
		{
			DefaultConfig = new AutoStorageDefaultsConfig
			{
				Worlds = new List<DefaultWorldConfig>()
			};
		}
		if (DefaultConfig.Worlds == null)
		{
			DefaultConfig.Worlds = new List<DefaultWorldConfig>();
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		bool flag = false;
		if (defaultWorldConfig == null)
		{
			defaultWorldConfig = new DefaultWorldConfig
			{
				mapId = mapId,
				worldTitle = (worldTitle ?? string.Empty)
			};
			DefaultConfig.Worlds.Add(defaultWorldConfig);
			flag = true;
		}
		if (!flag)
		{
			return;
		}
		if (mapId == 0L)
		{
			defaultWorldConfig.cellar = new DefaultLocation
			{
				x = -18.3f,
				y = 0.6f,
				z = -27.64f
			};
			defaultWorldConfig.junkman = new DefaultLocation
			{
				x = 39.99f,
				y = 6.17f,
				z = -23.19f
			};
			defaultWorldConfig.workshop = new DefaultLocation
			{
				x = 3.71f,
				y = 10.02f,
				z = -23.95f
			};
			defaultWorldConfig.oneDayLeftCellar = new DefaultLocation
			{
				x = -17.52f,
				y = 0.6f,
				z = -27.2f
			};
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[AutoStorage] Created Tropical defaults for mapId=0.");
			}
		}
		else if (mapId == 1)
		{
			defaultWorldConfig.cellar = new DefaultLocation
			{
				x = 100.49f,
				y = 0.88f,
				z = 164.69f
			};
			defaultWorldConfig.junkman = new DefaultLocation
			{
				x = 65.66f,
				y = 1.73f,
				z = 121.99f
			};
			defaultWorldConfig.workshop = new DefaultLocation
			{
				x = 75.99f,
				y = 4.63f,
				z = 179.01f
			};
			defaultWorldConfig.oneDayLeftCellar = new DefaultLocation
			{
				x = 98.89f,
				y = 0.88f,
				z = 164.67f
			};
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"[AutoStorage] Created EastTown defaults for mapId=1.");
			}
		}
		else if (mapId == 2)
		{
			if (defaultWorldConfig.cellar == null)
			{
				defaultWorldConfig.cellar = new DefaultLocation
				{
					x = -2.49f,
					y = 28.27f,
					z = -26.84f
				};
			}
			if (defaultWorldConfig.junkman == null)
			{
				defaultWorldConfig.junkman = new DefaultLocation
				{
					x = 24.69f,
					y = 26.55f,
					z = 1.45f
				};
			}
			if (defaultWorldConfig.workshop == null)
			{
				defaultWorldConfig.workshop = new DefaultLocation
				{
					x = -39.53f,
					y = 27.73f,
					z = 9.02f
				};
			}
			if (defaultWorldConfig.oneDayLeftCellar == null)
			{
				defaultWorldConfig.oneDayLeftCellar = new DefaultLocation
				{
					x = -2.49f,
					y = 28.27f,
					z = -25.98f
				};
			}
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)"[AutoStorage] Created RomanTown defaults for mapId=2.");
			}
		}
		else
		{
			ManualLogSource log4 = AutoStoragePlugin.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("[AutoStorage] Created empty defaults entry for mapId=" + mapId + "."));
			}
		}
		SaveDefaultConfig();
	}

	private static string GetCanonicalWorldTitle(long mapId, string worldTitleFromGame)
	{
		if ((ulong)mapId <= 2uL)
		{
			switch (mapId)
			{
			case 0L:
				return "Tropical Island";
			case 1L:
				return "EastTown";
			case 2L:
				return "RomanTown";
			}
		}
		return worldTitleFromGame ?? string.Empty;
	}

	public static bool TryGetDefaultPositionForItem(long itemId, string worldTitle, out Vector3 position, out string locationLabel)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		locationLabel = null;
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
		EnsureWorldDefaultsEntry(mapId, worldTitle);
		if (DefaultConfig == null || DefaultConfig.Worlds == null)
		{
			return false;
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null)
		{
			return false;
		}
		DefaultLocation defaultLocation;
		if (FishingTrashAndTrophyIds.Contains(itemId))
		{
			defaultLocation = defaultWorldConfig.junkman;
			locationLabel = "Junkman";
		}
		else if (GatheringIds.Contains(itemId) || OreIds.Contains(itemId) || IngotIds.Contains(itemId) || LivestockMaterialIds.Contains(itemId))
		{
			defaultLocation = defaultWorldConfig.workshop;
			locationLabel = "Workshop";
		}
		else
		{
			defaultLocation = defaultWorldConfig.cellar;
			locationLabel = "Cellar";
		}
		if (defaultLocation == null)
		{
			locationLabel = null;
			return false;
		}
		position = new Vector3(defaultLocation.x, defaultLocation.y, defaultLocation.z);
		return true;
	}

	public static bool TryGetJunkmanPositionForCurrentMap(out Vector3 position)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
		if (DefaultConfig == null || DefaultConfig.Worlds == null)
		{
			return false;
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null || defaultWorldConfig.junkman == null)
		{
			return false;
		}
		position = new Vector3(defaultWorldConfig.junkman.x, defaultWorldConfig.junkman.y, defaultWorldConfig.junkman.z);
		return true;
	}

	public static bool TryGetCellarPositionForCurrentMap(out Vector3 position)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
		if (DefaultConfig == null || DefaultConfig.Worlds == null)
		{
			return false;
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null || defaultWorldConfig.cellar == null)
		{
			return false;
		}
		position = new Vector3(defaultWorldConfig.cellar.x, defaultWorldConfig.cellar.y, defaultWorldConfig.cellar.z);
		return true;
	}

	public static bool TryGetWorkshopPositionForCurrentMap(out Vector3 position)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
		if (DefaultConfig == null || DefaultConfig.Worlds == null)
		{
			return false;
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null || defaultWorldConfig.workshop == null)
		{
			return false;
		}
		position = new Vector3(defaultWorldConfig.workshop.x, defaultWorldConfig.workshop.y, defaultWorldConfig.workshop.z);
		return true;
	}

	public static bool TryGetOneDayLeftCellarPositionForCurrentMap(out Vector3 position)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		long mapId = (((Object)(object)instance.mapSO != (Object)null) ? instance.mapSO.id : (-1));
		if (DefaultConfig == null || DefaultConfig.Worlds == null)
		{
			return false;
		}
		DefaultWorldConfig defaultWorldConfig = DefaultConfig.Worlds.FirstOrDefault((DefaultWorldConfig w) => w.mapId == mapId);
		if (defaultWorldConfig == null || defaultWorldConfig.oneDayLeftCellar == null)
		{
			return false;
		}
		position = new Vector3(defaultWorldConfig.oneDayLeftCellar.x, defaultWorldConfig.oneDayLeftCellar.y, defaultWorldConfig.oneDayLeftCellar.z);
		return true;
	}

	private static AutoStorageDefaultsConfig ParseDefaultsConfigJson(string json)
	{
		AutoStorageDefaultsConfig autoStorageDefaultsConfig = new AutoStorageDefaultsConfig
		{
			Worlds = new List<DefaultWorldConfig>()
		};
		if (string.IsNullOrWhiteSpace(json))
		{
			return autoStorageDefaultsConfig;
		}
		try
		{
			int num = json.IndexOf("\"Worlds\"", StringComparison.Ordinal);
			if (num < 0)
			{
				num = json.IndexOf("\"worlds\"", StringComparison.Ordinal);
			}
			if (num < 0)
			{
				return autoStorageDefaultsConfig;
			}
			int num2 = json.IndexOf('[', num);
			if (num2 < 0)
			{
				return autoStorageDefaultsConfig;
			}
			int num3 = json.IndexOf(']', num2 + 1);
			if (num3 < 0)
			{
				num3 = json.Length - 1;
			}
			string text = json.Substring(num2 + 1, num3 - num2 - 1);
			int num4 = 0;
			int num5 = -1;
			for (int i = 0; i < text.Length; i++)
			{
				switch (text[i])
				{
				case '{':
					if (num4 == 0)
					{
						num5 = i;
					}
					num4++;
					break;
				case '}':
					num4--;
					if (num4 == 0 && num5 >= 0)
					{
						DefaultWorldConfig defaultWorldConfig = ParseWorldConfig(text.Substring(num5, i - num5 + 1));
						if (defaultWorldConfig != null)
						{
							autoStorageDefaultsConfig.Worlds.Add(defaultWorldConfig);
						}
						num5 = -1;
					}
					break;
				}
			}
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[AutoStorage] Parsed defaults config JSON: Worlds={autoStorageDefaultsConfig.Worlds.Count}");
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("[AutoStorage] ParseDefaultsConfigJson failed: " + ex));
			}
		}
		return autoStorageDefaultsConfig;
	}

	private static DefaultWorldConfig ParseWorldConfig(string worldJson)
	{
		try
		{
			DefaultWorldConfig defaultWorldConfig = new DefaultWorldConfig();
			Match match = Regex.Match(worldJson, "\"mapId\"\\s*:\\s*(?<id>-?\\d+)", RegexOptions.Singleline);
			if (match.Success && long.TryParse(match.Groups["id"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				defaultWorldConfig.mapId = result;
			}
			Match match2 = Regex.Match(worldJson, "\"worldTitle\"\\s*:\\s*\"(?<title>[^\"]*)\"", RegexOptions.Singleline);
			if (match2.Success)
			{
				defaultWorldConfig.worldTitle = match2.Groups["title"].Value;
			}
			defaultWorldConfig.cellar = ParseLocation(worldJson, "cellar");
			defaultWorldConfig.junkman = ParseLocation(worldJson, "junkman");
			defaultWorldConfig.workshop = ParseLocation(worldJson, "workshop");
			defaultWorldConfig.oneDayLeftCellar = ParseLocation(worldJson, "oneDayLeftCellar");
			return defaultWorldConfig;
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] ParseWorldConfig failed: " + ex));
			}
			return null;
		}
	}

	private static DefaultLocation ParseLocation(string worldJson, string propName)
	{
		string pattern = "\"" + propName + "\"\\s*:\\s*{(?<body>[^}]*)}";
		Match match = Regex.Match(worldJson, pattern, RegexOptions.Singleline);
		if (!match.Success)
		{
			return null;
		}
		string value = match.Groups["body"].Value;
		float result = 0f;
		float result2 = 0f;
		float result3 = 0f;
		Match match2 = Regex.Match(value, "\"x\"\\s*:\\s*(?<v>-?\\d+(?:\\.\\d+)?)");
		Match match3 = Regex.Match(value, "\"y\"\\s*:\\s*(?<v>-?\\d+(?:\\.\\d+)?)");
		Match match4 = Regex.Match(value, "\"z\"\\s*:\\s*(?<v>-?\\d+(?:\\.\\d+)?)");
		if (match2.Success)
		{
			float.TryParse(match2.Groups["v"].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
		}
		if (match3.Success)
		{
			float.TryParse(match3.Groups["v"].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result2);
		}
		if (match4.Success)
		{
			float.TryParse(match4.Groups["v"].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result3);
		}
		return new DefaultLocation
		{
			x = result,
			y = result2,
			z = result3
		};
	}

	private static void RecreateDefaultsWithBuiltInEntries()
	{
		DefaultConfig = new AutoStorageDefaultsConfig
		{
			Worlds = new List<DefaultWorldConfig>()
		};
		EnsureWorldDefaultsEntry(0L, string.Empty);
		EnsureWorldDefaultsEntry(1L, string.Empty);
		EnsureWorldDefaultsEntry(2L, string.Empty);
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)"[AutoStorage] Created defaults with built-in entries for maps 0/1/2.");
		}
	}

	internal static void LoadJunkmanLimitsConfig()
	{
		JunkmanLimits = new Dictionary<long, int>();
		try
		{
			if (string.IsNullOrEmpty(LimitsConfigPath))
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[AutoStorage] Limits config path is not set. Junkman limits disabled.");
				}
				return;
			}
			if (!File.Exists(LimitsConfigPath))
			{
				ManualLogSource log2 = AutoStoragePlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"[AutoStorage] Limits config not found. Junkman limits disabled.");
				}
				return;
			}
			string text = File.ReadAllText(LimitsConfigPath, Encoding.UTF8);
			if (string.IsNullOrWhiteSpace(text))
			{
				ManualLogSource log3 = AutoStoragePlugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[AutoStorage] Limits config is empty. Junkman limits disabled.");
				}
				return;
			}
			JunkmanLimitsConfig junkmanLimitsConfig = ParseLimitsConfigJson(text);
			if (junkmanLimitsConfig == null || junkmanLimitsConfig.Limits == null)
			{
				ManualLogSource log4 = AutoStoragePlugin.Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"[AutoStorage] Limits config parse result is null. Junkman limits disabled.");
				}
				return;
			}
			foreach (JunkmanLimitEntry limit in junkmanLimitsConfig.Limits)
			{
				if (limit != null && limit.MaxAmount >= 0)
				{
					JunkmanLimits[limit.ItemId] = limit.MaxAmount;
				}
			}
			ManualLogSource log5 = AutoStoragePlugin.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[AutoStorage] Limits config loaded. Entries={JunkmanLimits.Count}.");
			}
		}
		catch (Exception ex)
		{
			JunkmanLimits.Clear();
			ManualLogSource log6 = AutoStoragePlugin.Log;
			if (log6 != null)
			{
				log6.LogError((object)("[AutoStorage] Exception while loading limits config: " + ex));
			}
		}
	}

	private static JunkmanLimitsConfig ParseLimitsConfigJson(string json)
	{
		JunkmanLimitsConfig junkmanLimitsConfig = new JunkmanLimitsConfig
		{
			Limits = new List<JunkmanLimitEntry>()
		};
		if (string.IsNullOrWhiteSpace(json))
		{
			return junkmanLimitsConfig;
		}
		try
		{
			string pattern = "{[^}]*\"ItemId\"\\s*:\\s*(?<id>-?\\d+)[^}]*\"MaxAmount\"\\s*:\\s*(?<max>\\d+)[^}]*}";
			foreach (Match item in Regex.Matches(json, pattern, RegexOptions.Singleline))
			{
				if (item.Success && long.TryParse(item.Groups["id"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(item.Groups["max"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					junkmanLimitsConfig.Limits.Add(new JunkmanLimitEntry
					{
						ItemId = result,
						MaxAmount = result2
					});
				}
			}
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[AutoStorage] Parsed limits config JSON: Entries={junkmanLimitsConfig.Limits.Count}");
			}
			return junkmanLimitsConfig;
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("[AutoStorage] ParseLimitsConfigJson failed: " + ex));
			}
			return null;
		}
	}

	public static bool TryGetJunkmanLimit(long itemId, out int maxAmount)
	{
		if (JunkmanLimits != null && JunkmanLimits.TryGetValue(itemId, out maxAmount))
		{
			return true;
		}
		maxAmount = 0;
		return false;
	}

	public static bool TryGetJunkmanLimitForItem(long itemId, out int maxAmount)
	{
		return TryGetJunkmanLimit(itemId, out maxAmount);
	}

	public static int GetJunkmanLimit(long itemId)
	{
		if (!TryGetJunkmanLimit(itemId, out var maxAmount))
		{
			return -1;
		}
		return maxAmount;
	}

	public static int GetJunkmanLimitForItem(long itemId)
	{
		return GetJunkmanLimit(itemId);
	}

	internal static void ExportMaterialCategories()
	{
		try
		{
			if (string.IsNullOrEmpty(ConfigDirectory))
			{
				return;
			}
			Directory.CreateDirectory(ConfigDirectory);
			if (File.Exists(MaterialCategoriesPath))
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[AutoStorage] Material categories already exist. Skip export.");
				}
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{\n");
			stringBuilder.Append("  \"Categories\": [\n");
			bool firstCategory = true;
			firstCategory = AppendCategory(stringBuilder, "fishing_trash_and_trophy", FishingTrashAndTrophyIds, firstCategory);
			firstCategory = AppendCategory(stringBuilder, "gathering", GatheringIds, firstCategory);
			firstCategory = AppendCategory(stringBuilder, "ore", OreIds, firstCategory);
			firstCategory = AppendCategory(stringBuilder, "ingot", IngotIds, firstCategory);
			firstCategory = AppendCategory(stringBuilder, "livestock_material", LivestockMaterialIds, firstCategory);
			stringBuilder.Append("\n  ]\n");
			stringBuilder.Append("}\n");
			File.WriteAllText(MaterialCategoriesPath, stringBuilder.ToString(), Encoding.UTF8);
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[AutoStorage] Material categories exported to: " + MaterialCategoriesPath));
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogError((object)("[AutoStorage] Failed to export material categories: " + ex));
			}
		}
	}

	private static bool AppendCategory(StringBuilder sb, string key, HashSet<long> ids, bool firstCategory)
	{
		if (ids == null || ids.Count == 0)
		{
			return firstCategory;
		}
		if (!firstCategory)
		{
			sb.Append(",\n");
		}
		sb.Append("    {\n");
		sb.Append("      \"key\": \"").Append(key).Append("\",\n");
		sb.Append("      \"itemIds\": [");
		List<long> list = ids.OrderBy((long id) => id).ToList();
		for (int i = 0; i < list.Count; i++)
		{
			if (i > 0)
			{
				sb.Append(", ");
			}
			sb.Append(list[i].ToString(CultureInfo.InvariantCulture));
		}
		sb.Append("]\n");
		sb.Append("    }");
		return false;
	}
}
public class AutoStorageController : MonoBehaviour
{
	private PlayerInventory _localInventory;

	private bool _loggedInventoryFound;

	private void Awake()
	{
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
	}

	private void Update()
	{
		try
		{
			if ((Object)(object)_localInventory == (Object)null || !((NetworkBehaviour)_localInventory).IsOwner)
			{
				TryFindLocalInventory();
			}
			if (!((Object)(object)_localInventory == (Object)null) && ((NetworkBehaviour)_localInventory).IsOwner)
			{
				GameManager instance = GameManager.Instance;
				if (!((Object)(object)instance == (Object)null) && instance.IsWorldLoaded())
				{
					HandleInput();
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] Controller Update failed: " + ex));
			}
		}
	}

	private void TryFindLocalInventory()
	{
		try
		{
			PlayerInventory[] array = Object.FindObjectsOfType<PlayerInventory>();
			foreach (PlayerInventory val in array)
			{
				if (!((Object)(object)val != (Object)null) || !((NetworkBehaviour)val).IsOwner)
				{
					continue;
				}
				_localInventory = val;
				if (!_loggedInventoryFound)
				{
					_loggedInventoryFound = true;
					ManualLogSource log = AutoStoragePlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)"[AutoStorage] Attached to local PlayerInventory.");
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("[AutoStorage] Error while finding PlayerInventory: " + ex));
			}
		}
	}

	private void HandleInput()
	{
		//IL_0011: 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)
		//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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		Keyboard current = Keyboard.current;
		if (current != null)
		{
			Key configuredKey = GetConfiguredKey(AutoStoragePlugin.KeyRegisterStorage, (Key)26);
			Key configuredKey2 = GetConfiguredKey(AutoStoragePlugin.KeyStoreAll, (Key)39);
			Key configuredKey3 = GetConfiguredKey(AutoStoragePlugin.KeyStoreCurrent, (Key)35);
			Key configuredKey4 = GetConfiguredKey(AutoStoragePlugin.KeyAutoStack, (Key)68);
			Key configuredKey5 = GetConfiguredKey(AutoStoragePlugin.KeyDropAll, (Key)16);
			KeyControl val = current[configuredKey];
			if (val != null && ((ButtonControl)val).wasPressedThisFrame)
			{
				HandleSetDeposit();
			}
			KeyControl val2 = current[configuredKey2];
			if (val2 != null && ((ButtonControl)val2).wasPressedThisFrame)
			{
				HandleStoreAllSlots();
			}
			KeyControl val3 = current[configuredKey3];
			if (val3 != null && ((ButtonControl)val3).wasPressedThisFrame)
			{
				HandleStoreCurrentSlot();
			}
			KeyControl val4 = current[configuredKey4];
			if (val4 != null && ((ButtonControl)val4).wasPressedThisFrame)
			{
				HandleAutoStackDeposits();
			}
			KeyControl val5 = current[configuredKey5];
			if (val5 != null && ((ButtonControl)val5).wasPressedThisFrame)
			{
				HandleDropAllExceptBagAndTools();
			}
		}
	}

	private static Key GetConfiguredKey(ConfigEntry<string> entry, Key fallback)
	{
		//IL_0003: 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)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		if (entry == null)
		{
			return fallback;
		}
		try
		{
			string value = entry.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			value = value.Trim();
			if (value.StartsWith("Key.", StringComparison.OrdinalIgnoreCase))
			{
				value = value.Substring("Key.".Length);
			}
			if (Enum.TryParse<Key>(value, ignoreCase: true, out Key result))
			{
				return result;
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"[AutoStorage] Invalid key config for '{((ConfigEntryBase)entry).Definition.Key}': {arg}");
			}
		}
		return fallback;
	}

	private bool TryGetCurrentSlot(out int slotIndex, out InventorySlot slot)
	{
		//IL_0004: 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)
		slotIndex = -1;
		slot = default(InventorySlot);
		if ((Object)(object)_localInventory == (Object)null || _localInventory.currentSlot == null)
		{
			return false;
		}
		slotIndex = _localInventory.currentSlot.Value;
		NetworkList<InventorySlot> slots = _localInventory.slots;
		if (slotIndex < 0 || slotIndex >= slots.Count)
		{
			return false;
		}
		slot = slots[slotIndex];
		return true;
	}

	protected static bool IsBagItem(ItemSO item)
	{
		return item is BagSO;
	}

	protected static bool IsToolItem(ItemSO item)
	{
		return item is ToolSO;
	}

	protected static ProductSO AsPerishableProduct(ItemSO item)
	{
		return (ProductSO)(object)((item is ProductSO) ? item : null);
	}

	protected static int GetRemainingDays(ProductSO product, int dayCounter)
	{
		if ((Object)(object)product == (Object)null || product.maxDays <= 0)
		{
			return int.MaxValue;
		}
		return product.maxDays - dayCounter;
	}

	protected static bool IsRotten(ProductSO product, int dayCounter)
	{
		return GetRemainingDays(product, dayCounter) <= 0;
	}

	protected static bool IsOneDayLeft(ProductSO product, int dayCounter)
	{
		if ((Object)(object)product == (Object)null || product.maxDays <= 0)
		{
			return false;
		}
		return GetRemainingDays(product, dayCounter) == 1;
	}

	private void HandleSetDeposit()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localInventory == (Object)null)
		{
			return;
		}
		string currentWorldKey = AutoStorageConfigManager.GetCurrentWorldKey();
		if (string.IsNullOrEmpty(currentWorldKey))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: world not ready");
			return;
		}
		InventorySlot currentInventorySlot = _localInventory.GetCurrentInventorySlot();
		if (currentInventorySlot.itemId == -1 || currentInventorySlot.amount <= 0)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: empty slot (no location set)");
			return;
		}
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		ItemSO itemById = instance.GetItemById(currentInventorySlot.itemId);
		if ((Object)(object)itemById == (Object)null)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: item data not found");
			return;
		}
		if (IsBagItem(itemById) || IsToolItem(itemById))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: bags and tools cannot be used as storage targets");
			return;
		}
		Vector3 val = ((Component)_localInventory).transform.position + itemById.bagDropPivotOffset;
		AutoStorageConfigManager.SetDepositForItem(currentWorldKey, currentInventorySlot.itemId, val);
		string text = ((!string.IsNullOrEmpty(itemById.itemName)) ? itemById.itemName : currentInventorySlot.itemId.ToString());
		AutoStoragePlugin.ShowNotification("AutoStorage: set location for " + text);
		ManualLogSource log = AutoStoragePlugin.Log;
		if (log != null)
		{
			log.LogInfo((object)$"[AutoStorage] Set deposit for itemId={currentInventorySlot.itemId} at {val} in world '{currentWorldKey}'.");
		}
	}

	private void HandleStoreAllSlots()
	{
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localInventory == (Object)null)
		{
			return;
		}
		string currentWorldKey = AutoStorageConfigManager.GetCurrentWorldKey();
		if (string.IsNullOrEmpty(currentWorldKey))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: world not ready");
			return;
		}
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		string worldTitle;
		try
		{
			worldTitle = instance.GetMarketTitle();
		}
		catch
		{
			worldTitle = string.Empty;
		}
		bool flag = AutoStoragePlugin.PreferOneDayLeftOverNormal != null && AutoStoragePlugin.PreferOneDayLeftOverNormal.Value;
		int num = 0;
		int num2 = 0;
		int count = _localInventory.slots.Count;
		for (int i = 0; i < count; i++)
		{
			InventorySlot val = _localInventory.slots[i];
			if (val.itemId == -1)
			{
				continue;
			}
			ItemSO itemById = instance.GetItemById(val.itemId);
			if ((Object)(object)itemById == (Object)null || IsBagItem(itemById) || IsToolItem(itemById))
			{
				continue;
			}
			ProductSO product = AsPerishableProduct(itemById);
			bool flag2 = IsRotten(product, val.dayCounter);
			bool flag3 = !flag2 && IsOneDayLeft(product, val.dayCounter);
			Vector3 position = Vector3.zero;
			bool flag4 = false;
			string locationLabel = null;
			if (val.amount == 0 || flag2)
			{
				if (!AutoStorageConfigManager.TryGetJunkmanPositionForCurrentMap(out position))
				{
					continue;
				}
				locationLabel = "Junkman";
				flag4 = true;
			}
			else
			{
				if (val.amount <= 0)
				{
					continue;
				}
				bool flag5 = false;
				if (flag3 && flag && AutoStorageConfigManager.TryGetOneDayLeftCellarPositionForCurrentMap(out position))
				{
					locationLabel = "Cellar(1 day left)";
					flag5 = true;
					flag4 = true;
				}
				if (!flag5)
				{
					if (AutoStorageConfigManager.TryGetDepositForItem(currentWorldKey, val.itemId, out position))
					{
						locationLabel = "Custom";
						flag4 = true;
					}
					else
					{
						if (!AutoStorageConfigManager.TryGetDefaultPositionForItem(val.itemId, worldTitle, out position, out locationLabel))
						{
							continue;
						}
						flag4 = true;
						if (flag3 && !flag && AutoStorageConfigManager.TryGetOneDayLeftCellarPositionForCurrentMap(out var position2))
						{
							position = position2;
							locationLabel = "Cellar(1 day left)";
						}
					}
				}
			}
			if (!flag4)
			{
				continue;
			}
			try
			{
				instance.SpawnItemAtPositionServerRpc(val.itemId, position, false, val.amount, val.cost, val.dayCounter);
				if (val.amount > 0 && !flag2)
				{
					num += val.amount;
				}
				num2++;
				_localInventory.slots[i] = new InventorySlot
				{
					itemId = -1L,
					amount = -1,
					cost = -1,
					dayCounter = -1
				};
			}
			catch (Exception arg)
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogError((object)$"[AutoStorage] StoreAll: failed to store itemId={val.itemId} in slot {i}: {arg}");
				}
			}
		}
		if (num2 <= 0)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: no items to store");
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"[AutoStorage] StoreAll: nothing was stored from inventory.");
			}
		}
		else
		{
			AutoStoragePlugin.ShowNotification($"AutoStorage: stored {num} items ({num2} stacks)");
		}
	}

	private void HandleStoreCurrentSlot()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localInventory == (Object)null)
		{
			return;
		}
		string currentWorldKey = AutoStorageConfigManager.GetCurrentWorldKey();
		if (string.IsNullOrEmpty(currentWorldKey))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: world not ready");
			return;
		}
		if (!TryGetCurrentSlot(out var slotIndex, out var slot))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: no active slot");
			return;
		}
		if (slot.itemId == -1)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: empty slot (no items to store)");
			return;
		}
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		string worldTitle;
		try
		{
			worldTitle = instance.GetMarketTitle();
		}
		catch
		{
			worldTitle = string.Empty;
		}
		ItemSO itemById = instance.GetItemById(slot.itemId);
		if ((Object)(object)itemById == (Object)null)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: item data not found");
			return;
		}
		if (IsBagItem(itemById) || IsToolItem(itemById))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: bags and tools are not stored");
			return;
		}
		ProductSO product = AsPerishableProduct(itemById);
		bool flag = IsRotten(product, slot.dayCounter);
		bool flag2 = !flag && IsOneDayLeft(product, slot.dayCounter);
		bool flag3 = AutoStoragePlugin.PreferOneDayLeftOverNormal != null && AutoStoragePlugin.PreferOneDayLeftOverNormal.Value;
		Vector3 position = Vector3.zero;
		bool flag4 = false;
		string locationLabel = null;
		if (slot.amount == 0 || flag)
		{
			if (!AutoStorageConfigManager.TryGetJunkmanPositionForCurrentMap(out position))
			{
				AutoStoragePlugin.ShowNotification("AutoStorage: Junkman location not configured");
				return;
			}
			locationLabel = "Junkman";
			flag4 = true;
		}
		else
		{
			if (slot.amount <= 0)
			{
				AutoStoragePlugin.ShowNotification("AutoStorage: invalid item amount");
				return;
			}
			bool flag5 = false;
			if (flag2 && flag3 && AutoStorageConfigManager.TryGetOneDayLeftCellarPositionForCurrentMap(out position))
			{
				locationLabel = "Cellar(1 day left)";
				flag5 = true;
				flag4 = true;
			}
			if (!flag5)
			{
				if (AutoStorageConfigManager.TryGetDepositForItem(currentWorldKey, slot.itemId, out position))
				{
					locationLabel = "Custom";
					flag4 = true;
				}
				else
				{
					if (!AutoStorageConfigManager.TryGetDefaultPositionForItem(slot.itemId, worldTitle, out position, out locationLabel))
					{
						AutoStoragePlugin.ShowNotification("AutoStorage: no storage location for this item");
						return;
					}
					flag4 = true;
					if (flag2 && !flag3 && AutoStorageConfigManager.TryGetOneDayLeftCellarPositionForCurrentMap(out var position2))
					{
						position = position2;
						locationLabel = "Cellar(1 day left)";
					}
				}
			}
		}
		if (!flag4)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: no valid storage position");
			return;
		}
		try
		{
			instance.SpawnItemAtPositionServerRpc(slot.itemId, position, false, slot.amount, slot.cost, slot.dayCounter);
			_localInventory.slots[slotIndex] = new InventorySlot
			{
				itemId = -1L,
				amount = -1,
				cost = -1,
				dayCounter = -1
			};
			int num = Math.Max(slot.amount, 0);
			AutoStoragePlugin.ShowNotification($"AutoStorage: stored {num} items (1 stack)");
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)string.Format("[AutoStorage] StoreCurrent: stored {0}x itemId={1} at {2} (location={3}, slotIndex={4}).", slot.amount, slot.itemId, position, locationLabel ?? "Unknown", slotIndex));
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)$"[AutoStorage] StoreCurrent: failed to store itemId={slot.itemId} in slot {slotIndex}: {arg}");
			}
		}
	}

	private void HandleAutoStackDeposits()
	{
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null || !instance.IsWorldLoaded())
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: world not ready");
			return;
		}
		AutoStoragePlugin.ShowNotification("AutoStorage: auto-stacking (please wait)...");
		string currentWorldKey = AutoStorageConfigManager.GetCurrentWorldKey();
		if (string.IsNullOrEmpty(currentWorldKey))
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: world not ready");
			return;
		}
		List<Vector3> allDepositPositionsForWorld = AutoStorageConfigManager.GetAllDepositPositionsForWorld(currentWorldKey);
		if (allDepositPositionsForWorld == null || allDepositPositionsForWorld.Count == 0)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: no registered storage locations");
			return;
		}
		Item[] array;
		try
		{
			array = Object.FindObjectsOfType<Item>();
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] Auto-stack: failed to enumerate items: " + ex));
			}
			AutoStoragePlugin.ShowNotification("AutoStorage: failed to scan items");
			return;
		}
		if (array == null || array.Length == 0)
		{
			AutoStoragePlugin.ShowNotification("AutoStorage: no items to stack");
			return;
		}
		Dictionary<string, List<Item>> dictionary = new Dictionary<string, List<Item>>();
		Item[] array2 = array;
		foreach (Item val in array2)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)val.itemSO == (Object)null)
			{
				continue;
			}
			int value;
			try
			{
				value = val.amount.Value;
			}
			catch
			{
				continue;
			}
			if (value <= 0)
			{
				continue;
			}
			ItemSO itemSO = val.itemSO;
			if (IsBagItem(itemSO) || IsToolItem(itemSO))
			{
				continue;
			}
			Vector3 position = ((Component)val).transform.position;
			int num = -1;
			for (int j = 0; j < allDepositPositionsForWorld.Count; j++)
			{
				Vector3 val2 = allDepositPositionsForWorld[j];
				if (position.x == val2.x && position.y == val2.y && position.z == val2.z)
				{
					num = j;
					break;
				}
			}
			if (num < 0)
			{
				continue;
			}
			int num2 = 0;
			int num3 = 0;
			ProductSO val3 = AsPerishableProduct(itemSO);
			if ((Object)(object)val3 != (Object)null && ((ItemSO)val3).amount > 1)
			{
				num2 = ((ItemSO)val3).amount;
				if (val3.maxDays > 0)
				{
					try
					{
						int value2 = val.dayCounter.Value;
						num3 = GetRemainingDays(val3, value2);
					}
					catch
					{
						num3 = 0;
					}
				}
			}
			if (num2 <= 1 && itemSO.stackSize > 1)
			{
				num2 = itemSO.stackSize;
				num3 = 0;
			}
			if (num2 > 1)
			{
				long id = itemSO.id;
				string key = num + "_" + id + "_" + num3 + "_" + num2;
				if (!dictionary.TryGetValue(key, out var value3))
				{
					value3 = (dictionary[key] = new List<Item>());
				}
				value3.Add(val);
			}
		}
		int num4 = 0;
		int num5 = 0;
		foreach (KeyValuePair<string, List<Item>> item in dictionary)
		{
			List<Item> value4 = item.Value;
			if (value4 == null || value4.Count <= 1)
			{
				continue;
			}
			Item val4 = value4[0];
			if ((Object)(object)val4 == (Object)null || (Object)(object)val4.itemSO == (Object)null)
			{
				continue;
			}
			ItemSO itemSO2 = val4.itemSO;
			ProductSO val5 = AsPerishableProduct(itemSO2);
			int num6 = 0;
			if ((Object)(object)val5 != (Object)null && ((ItemSO)val5).amount > 1)
			{
				num6 = ((ItemSO)val5).amount;
			}
			else if (itemSO2.stackSize > 1)
			{
				num6 = itemSO2.stackSize;
			}
			if (num6 <= 1)
			{
				continue;
			}
			int count = value4.Count;
			int[] array3 = new int[count];
			int num7 = 0;
			for (int k = 0; k < count; k++)
			{
				Item val6 = value4[k];
				if (!((Object)(object)val6 == (Object)null))
				{
					int num8;
					try
					{
						num8 = val6.amount.Value;
					}
					catch
					{
						num8 = 0;
					}
					array3[k] = num8;
					if (num8 > 0)
					{
						num7 += num8;
					}
				}
			}
			if (num7 <= 0)
			{
				continue;
			}
			int num9 = num7 / num6;
			int num10 = num7 % num6;
			int num11 = num9 + ((num10 > 0) ? 1 : 0);
			if (num11 <= 0)
			{
				num11 = 1;
			}
			if (num11 > count)
			{
				num11 = count;
			}
			value4.Sort((Item a, Item b) => ((Object)a).GetInstanceID().CompareTo(((Object)b).GetInstanceID()));
			int[] array4 = new int[count];
			int num12 = 0;
			for (int l = 0; l < count; l++)
			{
				if (num12 < num9)
				{
					array4[l] = num6;
					num12++;
				}
				else if (num12 == num9 && num10 > 0)
				{
					array4[l] = num10;
					num12++;
				}
				else
				{
					array4[l] = 0;
				}
			}
			bool flag = false;
			if (count > num11)
			{
				flag = true;
			}
			else
			{
				for (int m = 0; m < count; m++)
				{
					if (array4[m] != array3[m])
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				continue;
			}
			for (int n = 0; n < count; n++)
			{
				Item val7 = value4[n];
				if ((Object)(object)val7 == (Object)null)
				{
					continue;
				}
				int num13 = array4[n];
				if (num13 > 0)
				{
					try
					{
						val7.amount.Value = num13;
					}
					catch
					{
					}
				}
				else
				{
					num5++;
					RemoveWorldItem(val7);
				}
			}
			num4++;
		}
		ManualLogSource log2 = AutoStoragePlugin.Log;
		if (log2 != null)
		{
			log2.LogInfo((object)$"[AutoStorage] Auto-stack: changedGroups={num4}, removedItems={num5}.");
		}
		int num14 = 0;
		try
		{
			num14 = ApplyJunkmanLimitsAfterAutoStack(allDepositPositionsForWorld);
		}
		catch (Exception ex2)
		{
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogError((object)("[AutoStorage] Auto-stack: ApplyJunkmanLimitsAfterAutoStack failed: " + ex2));
			}
		}
		ManualLogSource log4 = AutoStoragePlugin.Log;
		if (log4 != null)
		{
			log4.LogInfo((object)$"[AutoStorage] Auto-stack: movedToJunkAmount={num14}.");
		}
		string text;
		if (num4 <= 0)
		{
			text = ((num14 <= 0) ? "AutoStorage: nothing to stack" : $"AutoStorage: moved {num14} items to Junkman");
		}
		else
		{
			text = $"AutoStorage: auto-stacked {num4} groups";
			if (num14 > 0)
			{
				text += $" (moved {num14} items to Junkman)";
			}
		}
		AutoStoragePlugin.ShowNotification(text);
	}

	private void RemoveWorldItem(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		try
		{
			try
			{
				item.amount.Value = 0;
			}
			catch
			{
			}
			Object.Destroy((Object)(object)((Component)item).gameObject);
		}
		catch (Exception ex)
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[AutoStorage] Auto-stack: failed to destroy item: " + ex));
			}
		}
	}

	private void HandleDropAllExceptBagAndTools()
	{
		//IL_0042: 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)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_localInventory == (Object)null)
		{
			return;
		}
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		NetworkList<InventorySlot> slots = _localInventory.slots;
		if (slots == null || slots.Count == 0)
		{
			return;
		}
		bool flag = false;
		for (int i = 0; i < slots.Count; i++)
		{
			InventorySlot val = slots[i];
			if (val.itemId == -1 || val.amount <= 0)
			{
				continue;
			}
			ItemSO itemById = instance.GetItemById(val.itemId);
			if ((Object)(object)itemById == (Object)null || IsBagItem(itemById) || IsToolItem(itemById))
			{
				continue;
			}
			Vector3 val2 = ((Component)_localInventory).transform.position + itemById.bagDropPivotOffset;
			if (itemById.stackSize > 1)
			{
				for (int j = 0; j < val.amount; j++)
				{
					instance.SpawnItemAtPositionServerRpc(val.itemId, val2, false, 1, val.cost, val.dayCounter);
				}
			}
			else
			{
				instance.SpawnItemAtPositionServerRpc(val.itemId, val2, false, val.amount, val.cost, val.dayCounter);
			}
			slots[i] = new InventorySlot
			{
				itemId = -1L,
				amount = -1,
				cost = -1,
				dayCounter = -1
			};
			flag = true;
		}
		if (flag && _localInventory.currentSlot != null)
		{
			_localInventory.currentSlot.Value = 0;
		}
	}

	private int ApplyJunkmanLimitsAfterAutoStack(List<Vector3> depositPositions)
	{
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: 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_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		if (AutoStorageConfigManager.JunkmanLimitTable == null || AutoStorageConfigManager.JunkmanLimitTable.Count == 0)
		{
			return 0;
		}
		GameManager instance = GameManager.Instance;
		if ((Object)(object)instance == (Object)null || !instance.IsWorldLoaded())
		{
			return 0;
		}
		if (!AutoStorageConfigManager.TryGetJunkmanPositionForCurrentMap(out var position))
		{
			ManualLogSource log = AutoStoragePlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)"[AutoStorage] ApplyJunkmanLimits: Junkman position not configured for this map.");
			}
			return 0;
		}
		Item[] array;
		try
		{
			array = Object.FindObjectsOfType<Item>();
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = AutoStoragePlugin.Log;
			if (log2 != null)
			{
				log2.LogError((object)("[AutoStorage] ApplyJunkmanLimits: failed to enumerate items: " + ex));
			}
			return 0;
		}
		if (array == null || array.Length == 0)
		{
			return 0;
		}
		Dictionary<long, List<Item>> dictionary = new Dictionary<long, List<Item>>();
		Item[] array2 = array;
		foreach (Item val in array2)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)val.itemSO == (Object)null)
			{
				continue;
			}
			int value;
			try
			{
				value = val.amount.Value;
			}
			catch
			{
				continue;
			}
			if (value <= 0)
			{
				continue;
			}
			long id = val.itemSO.id;
			if (!AutoStorageConfigManager.TryGetJunkmanLimitForItem(id, out var _))
			{
				continue;
			}
			Vector3 position2 = ((Component)val).transform.position;
			bool flag = false;
			for (int j = 0; j < depositPositions.Count; j++)
			{
				Vector3 val2 = depositPositions[j];
				Vector3 val3 = position2 - val2;
				if (((Vector3)(ref val3)).sqrMagnitude <= 1E-06f)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				if (!dictionary.TryGetValue(id, out var value2))
				{
					value2 = (dictionary[id] = new List<Item>());
				}
				value2.Add(val);
			}
		}
		int num = 0;
		foreach (KeyValuePair<long, List<Item>> item in dictionary)
		{
			long key = item.Key;
			List<Item> value3 = item.Value;
			if (!AutoStorageConfigManager.TryGetJunkmanLimitForItem(key, out var maxAmount2) || maxAmount2 <= 0)
			{
				continue;
			}
			int num2 = 0;
			foreach (Item item2 in value3)
			{
				if ((Object)(object)item2 == (Object)null)
				{
					continue;
				}
				try
				{
					int value4 = item2.amount.Value;
					if (value4 > 0)
					{
						num2 += value4;
					}
				}
				catch
				{
				}
			}
			if (num2 <= maxAmount2)
			{
				continue;
			}
			int num3 = num2 - maxAmount2;
			if (num3 <= 0)
			{
				continue;
			}
			int num4 = MoveAmountToJunkman(instance, value3, position, num3);
			num += num4;
			int num5 = 0;
			foreach (Item item3 in value3)
			{
				if ((Object)(object)item3 == (Object)null)
				{
					continue;
				}
				try
				{
					int value5 = item3.amount.Value;
					if (value5 > 0)
					{
						num5 += value5;
					}
				}
				catch
				{
				}
			}
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)("[AutoStorage] JunkmanLimit: itemId=" + key + " total=" + num2 + " limit=" + maxAmount2 + " moved=" + num4 + " remain=" + (num2 - num4)));
			}
		}
		return num;
	}

	private int MoveAmountToJunkman(GameManager gm, List<Item> items, Vector3 junkPos, int needToMove)
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gm == (Object)null || items == null || items.Count == 0 || needToMove <= 0)
		{
			return 0;
		}
		int maxPerStack = 1;
		try
		{
			ItemSO itemSO = items[0].itemSO;
			ProductSO val = (ProductSO)(object)((itemSO is ProductSO) ? itemSO : null);
			if (val != null)
			{
				maxPerStack = Math.Max(1, ((ItemSO)val).amount);
			}
			else
			{
				maxPerStack = Math.Max(1, itemSO.stackSize);
			}
		}
		catch
		{
			maxPerStack = 1;
		}
		items.Sort(delegate(Item a, Item b)
		{
			int num6 = Math.Max(0, a.amount.Value);
			int num7 = Math.Max(0, b.amount.Value);
			int num8 = num6 % maxPerStack;
			int value = num7 % maxPerStack;
			int num9 = num8.CompareTo(value);
			if (num9 != 0)
			{
				return num9;
			}
			num9 = num6.CompareTo(num7);
			return (num9 != 0) ? num9 : ((Object)a).GetInstanceID().CompareTo(((Object)b).GetInstanceID());
		});
		int num = 0;
		for (int i = 0; i < items.Count && needToMove > 0; i++)
		{
			Item val2 = items[i];
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.itemSO == (Object)null)
			{
				continue;
			}
			int num2 = 0;
			try
			{
				num2 = val2.amount.Value;
			}
			catch
			{
				continue;
			}
			if (num2 <= 0)
			{
				continue;
			}
			int num3 = Math.Min(num2, needToMove);
			if (num3 <= 0)
			{
				continue;
			}
			int num4 = 0;
			try
			{
				num4 = val2.dayCounter.Value;
			}
			catch
			{
			}
			try
			{
				gm.SpawnItemAtPositionServerRpc(val2.itemSO.id, junkPos, false, num3, 0, num4);
			}
			catch (Exception ex)
			{
				ManualLogSource log = AutoStoragePlugin.Log;
				if (log != null)
				{
					log.LogError((object)("[AutoStorage] JunkmanLimit: failed to spawn item: " + ex));
				}
				continue;
			}
			int num5 = num2 - num3;
			try
			{
				if (num5 > 0)
				{
					val2.amount.Value = num5;
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = AutoStoragePlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[AutoStorage] JunkmanLimit: failed to update item: " + ex2));
				}
			}
			num += num3;
			needToMove -= num3;
			ManualLogSource log3 = AutoStoragePlugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"[AutoStorage] MoveAmountToJunkman: moved {num3} from instance={((Object)val2).GetInstanceID()} (orig={num2}, now={num5})");
			}
		}
		return num;
	}
}