Decompiled source of BulkBoxWheel v1.0.0

BepInEx/plugins/BulkBoxWheel.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BulkBoxWheel.Configuration;
using BulkBoxWheel.Features.BulkCarry;
using BulkBoxWheel.Localization;
using HarmonyLib;
using Mirror;
using UnityEngine;
using UnityEngine.EventSystems;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BulkBoxWheel")]
[assembly: AssemblyDescription("Bulk Box Wheel mod for Supermarket Together by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("BulkBoxWheel")]
[assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ac2c2e4-0d2a-42f8-95ef-f3ebbb7e9cf8")]
[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 BulkBoxWheel
{
	[BepInPlugin("IceBoxStudio.SupermarketTogether.BulkBoxWheel", "BulkBoxWheel", "1.0.0")]
	public class BulkBoxWheel : BaseUnityPlugin
	{
		public static BulkBoxWheel _Instance;

		private Harmony _harmony;

		private bool patchesApplied;

		public static BulkBoxWheel Instance => _Instance;

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			_Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Logger.LogInfo((object)"=============================================");
				Logger.LogInfo((object)("BulkBoxWheel " + ModLocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
				Logger.LogInfo((object)(ModLocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
				ApplyPatches();
				Logger.LogInfo((object)("BulkBoxWheel " + ModLocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
				Logger.LogInfo((object)"=============================================");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("BulkBoxWheel 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void ApplyPatches()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (!patchesApplied)
			{
				try
				{
					_harmony = new Harmony("IceBoxStudio.SupermarketTogether.BulkBoxWheel");
					_harmony.PatchAll();
					patchesApplied = true;
					return;
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("BulkBoxWheel 应用补丁错误: " + ex.Message + "\n" + ex.StackTrace));
					return;
				}
			}
			Logger.LogInfo((object)ModLocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.SupermarketTogether.BulkBoxWheel";

		public const string PLUGIN_NAME = "BulkBoxWheel";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace BulkBoxWheel.Patches
{
	[HarmonyPatch(typeof(LocalizationManager), "GetLocalizationString")]
	internal static class GameLocalizationManagerPatch
	{
		private static void Postfix(string key, ref string __result)
		{
			if (!string.IsNullOrEmpty(key) && key.StartsWith("bbw."))
			{
				string localizedText = ModLocalizationManager.Instance.GetLocalizedText(key);
				if (!string.IsNullOrEmpty(localizedText) && localizedText != key)
				{
					__result = localizedText;
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerNetwork), "Start")]
	internal static class PlayerNetworkStartPatch
	{
		private static void Postfix(PlayerNetwork __instance)
		{
			BulkCarryController.InitializeForPlayer(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerNetwork), "Update")]
	internal static class PlayerNetworkUpdatePatch
	{
		private static void Postfix(PlayerNetwork __instance)
		{
			BulkCarryController.OnPlayerUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(Data_Container), "GetStorageBox")]
	internal static class DataContainerGetStorageBoxPatch
	{
		private static bool Prefix(Data_Container __instance, int boxIndex)
		{
			return !BulkCarryController.TryPickupAdditionalStorageBox(__instance, boxIndex);
		}

		private static void Postfix()
		{
			BulkCarryController.OnRegularBoxStateChanged();
		}
	}
	[HarmonyPatch(typeof(Data_Container), "AddItemToRow")]
	internal static class DataContainerAddItemToRowPatch
	{
		private static void Postfix()
		{
			BulkCarryController.OnRegularBoxStateChanged();
		}
	}
	[HarmonyPatch(typeof(Data_Container), "RemoveItemFromRow")]
	internal static class DataContainerRemoveItemFromRowPatch
	{
		private static void Postfix()
		{
			BulkCarryController.OnRegularBoxStateChanged();
		}
	}
	[HarmonyPatch(typeof(MiniTransportBehaviour), "GetStorageBox")]
	internal static class MiniTransportGetStorageBoxPatch
	{
		private static bool Prefix(MiniTransportBehaviour __instance, int boxIndex)
		{
			return !BulkCarryController.TryPickupAdditionalMiniTransportBox(__instance, boxIndex);
		}

		private static void Postfix()
		{
			BulkCarryController.OnRegularBoxStateChanged();
		}
	}
	[HarmonyPatch(typeof(GameCanvas), "CreateCanvasNotification")]
	internal static class GameCanvasCreateCanvasNotificationPatch
	{
		private static bool Prefix(string hash)
		{
			if (hash == "message7" && BulkCarryController.ShouldSuppressHoldingItemNotification())
			{
				return false;
			}
			return true;
		}
	}
}
namespace BulkBoxWheel.Localization
{
	public static class LocalizationHelper
	{
		public static Dictionary<string, string> GetDefaultTranslations(string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			switch (language)
			{
			case "Localization_CH1":
				dictionary.Add("plugin.initializing", "开始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
				dictionary.Add("config.max_carry_boxes", "最大可持有箱子数量");
				dictionary.Add("config.show_switch_notifications", "显示切换提示");
				dictionary.Add("bbw.switch", "已切换箱子:");
				dictionary.Add("bbw.full", "手上已经拿不下更多箱子了。");
				break;
			case "Localization_CH2":
				dictionary.Add("plugin.initializing", "開始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "補丁已套用,跳過...");
				dictionary.Add("config.max_carry_boxes", "最大可持有箱子數量");
				dictionary.Add("config.show_switch_notifications", "顯示切換提示");
				dictionary.Add("bbw.switch", "已切換箱子:");
				dictionary.Add("bbw.full", "手上已經拿不下更多箱子了。");
				break;
			default:
				dictionary.Add("plugin.initializing", "Initializing...");
				dictionary.Add("plugin.author_prefix", "Author: ");
				dictionary.Add("plugin.initialized", "Initialized successfully!");
				dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
				dictionary.Add("config.max_carry_boxes", "Maximum Carried Boxes");
				dictionary.Add("config.show_switch_notifications", "Show Switch Notifications");
				dictionary.Add("bbw.switch", "Switched box: ");
				dictionary.Add("bbw.full", "You cannot carry any more boxes.");
				break;
			case "Localization_JP":
				dictionary.Add("plugin.initializing", "初期化中...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初期化に成功しました!");
				dictionary.Add("plugin.patches_skipped", "パッチは既に適用されているため、スキップします...");
				dictionary.Add("config.max_carry_boxes", "持持できる箱の最大数");
				dictionary.Add("config.show_switch_notifications", "切り替え通知を表示");
				dictionary.Add("bbw.switch", "切り替えた箱:");
				dictionary.Add("bbw.full", "これ以上箱を持てません。");
				break;
			}
			return dictionary;
		}
	}
	public class ModLocalizationManager
	{
		private const string ChineseSimplifiedLocale = "Localization_CH1";

		private const string ChineseTraditionalLocale = "Localization_CH2";

		private const string EnglishLocale = "Localization_EN";

		private const string JapaneseLocale = "Localization_JP";

		private static ModLocalizationManager _instance;

		private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();

		private string _currentLocale = "Localization_CH1";

		public static readonly string[] SupportedLanguages = new string[4] { "Localization_CH1", "Localization_CH2", "Localization_EN", "Localization_JP" };

		public static ModLocalizationManager Instance => _instance ?? (_instance = new ModLocalizationManager());

		private ModLocalizationManager()
		{
			Initialize();
		}

		public void Initialize()
		{
			string[] supportedLanguages = SupportedLanguages;
			foreach (string text in supportedLanguages)
			{
				Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text);
				if (defaultTranslations != null && defaultTranslations.Count != 0)
				{
					_localizations[text] = defaultTranslations;
				}
			}
			RefreshCurrentLocale();
		}

		public string GetLocalizedText(string key, params object[] args)
		{
			RefreshCurrentLocale();
			string text = ResolveCurrentLocale();
			if (TryGetLocalizedText(text, key, out var text2) || (text != "Localization_EN" && TryGetLocalizedText("Localization_EN", key, out text2)))
			{
				return FormatLocalizedText(text2, args);
			}
			return key;
		}

		private string ResolveCurrentLocale()
		{
			if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
			{
				_currentLocale = "Localization_EN";
			}
			return _currentLocale;
		}

		private bool TryGetLocalizedText(string locale, string key, out string text)
		{
			text = null;
			if (!string.IsNullOrEmpty(locale) && _localizations.TryGetValue(locale, out var value))
			{
				return value.TryGetValue(key, out text);
			}
			return false;
		}

		private static string FormatLocalizedText(string text, object[] args)
		{
			if (args == null || args.Length == 0)
			{
				return text;
			}
			return string.Format(text, args);
		}

		private void RefreshCurrentLocale()
		{
			string currentGameLocale = GetCurrentGameLocale();
			if (!string.IsNullOrEmpty(currentGameLocale))
			{
				_currentLocale = MapGameLocaleToModLocale(currentGameLocale);
			}
		}

		private string GetCurrentGameLocale()
		{
			string text = Application.persistentDataPath + "/Settings/GameOptions.es3";
			if (!ES3.KeyExists("GameLanguage", text))
			{
				return null;
			}
			return ES3.Load<string>("GameLanguage", text);
		}

		private static string MapGameLocaleToModLocale(string gameLocale)
		{
			switch (gameLocale)
			{
			case "Localization_CH1":
			case "Localization_CH2":
			case "Localization_JP":
			case "Localization_EN":
				return gameLocale;
			default:
				return "Localization_EN";
			}
		}
	}
}
namespace BulkBoxWheel.Features.BulkCarry
{
	internal static class BulkCarryController
	{
		private static readonly List<BulkCarrySlot> _slots = new List<BulkCarrySlot>();

		private static readonly MethodInfo _updateContainer = AccessTools.Method(typeof(Data_Container), "CmdUpdateArrayValuesStorage", (Type[])null, (Type[])null);

		private static readonly MethodInfo _updateMiniTransport = AccessTools.Method(typeof(MiniTransportBehaviour), "CmdUpdateArrayValuesStorage", (Type[])null, (Type[])null);

		private static readonly MethodInfo _syncBoxColor = AccessTools.Method(typeof(PlayerNetwork), "CmdSetBoxColorToEveryone", (Type[])null, (Type[])null);

		private static int _activeIndex;

		private static float _nextScrollTime;

		private static float _nextPickupTime;

		private static bool _waitingForReequip;

		private static float _nextReequipTime;

		internal static void Reset()
		{
			_slots.Clear();
			_activeIndex = 0;
			_nextScrollTime = 0f;
			_nextPickupTime = 0f;
			_waitingForReequip = false;
			_nextReequipTime = 0f;
		}

		internal static void InitializeForPlayer(PlayerNetwork player)
		{
			if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).isLocalPlayer)
			{
				Reset();
			}
		}

		internal static bool TryPickupAdditionalStorageBox(Data_Container container, int boxIndex)
		{
			PlayerNetwork player = FindLocalPlayer();
			if (!CanTakeMore(player))
			{
				return false;
			}
			int num = boxIndex * 2;
			if (num < 0 || num + 1 >= container.productInfoArray.Length)
			{
				return false;
			}
			int num2 = container.productInfoArray[num];
			int num3 = container.productInfoArray[num + 1];
			if (num2 < 0 || num3 <= 0)
			{
				return false;
			}
			SyncHeldBox(player);
			if (_slots.Count == 0)
			{
				return false;
			}
			BulkCarrySlot bulkCarrySlot = _slots[_activeIndex];
			if (bulkCarrySlot.ProductId == num2 && bulkCarrySlot.Quantity > 0)
			{
				return false;
			}
			if (IsFull())
			{
				Notify("bbw.full");
				return true;
			}
			AddSlot(num2, num3);
			ApplySlot(player, showNotification: false);
			int num4 = (Object.op_Implicit((Object)(object)((Component)container).transform.Find("CanvasSigns")) ? num2 : (-1));
			_updateContainer?.Invoke(container, new object[3] { num, num4, -1 });
			return true;
		}

		internal static bool TryPickupAdditionalMiniTransportBox(MiniTransportBehaviour container, int boxIndex)
		{
			PlayerNetwork player = FindLocalPlayer();
			if (!CanTakeMore(player))
			{
				return false;
			}
			int num = boxIndex * 2;
			if (num < 0 || num + 1 >= container.productInfoArray.Length)
			{
				return false;
			}
			int num2 = container.productInfoArray[num];
			int num3 = container.productInfoArray[num + 1];
			if (num2 < 0 || num3 <= 0)
			{
				return false;
			}
			SyncHeldBox(player);
			if (_slots.Count == 0)
			{
				return false;
			}
			BulkCarrySlot bulkCarrySlot = _slots[_activeIndex];
			if (bulkCarrySlot.ProductId == num2 && bulkCarrySlot.Quantity > 0)
			{
				return false;
			}
			if (IsFull())
			{
				Notify("bbw.full");
				return true;
			}
			AddSlot(num2, num3);
			ApplySlot(player, showNotification: false);
			int num4 = (Object.op_Implicit((Object)(object)((Component)container).transform.Find("CanvasSigns")) ? num2 : (-1));
			_updateMiniTransport?.Invoke(container, new object[3] { num, num4, -1 });
			return true;
		}

		internal static void OnRegularBoxStateChanged(PlayerNetwork player)
		{
			if (!IsLocalPlayerReady(player))
			{
				return;
			}
			if (player.equippedItem == 1 && player.extraParameter1 >= 0)
			{
				_waitingForReequip = false;
				SyncHeldBox(player);
				if (_slots.Count == 0)
				{
					return;
				}
				BulkCarrySlot bulkCarrySlot = _slots[_activeIndex];
				bulkCarrySlot.ProductId = player.extraParameter1;
				bulkCarrySlot.Quantity = player.extraParameter2;
				if (bulkCarrySlot.Quantity <= 0 && bulkCarrySlot.Quantity != 0)
				{
					RemoveSlot();
					if (_slots.Count > 0)
					{
						ApplySlot(player, showNotification: false);
					}
					else
					{
						ClearBox(player);
					}
				}
			}
			else if (player.equippedItem == 0 && _slots.Count > 0)
			{
				if (_waitingForReequip)
				{
					ApplySlot(player, showNotification: false);
					return;
				}
				RemoveSlot();
				if (_slots.Count > 0)
				{
					_waitingForReequip = true;
					ApplySlot(player, showNotification: false);
				}
				else
				{
					Reset();
				}
			}
			else if (player.equippedItem != 0 && player.equippedItem != 1 && _slots.Count > 0)
			{
				_waitingForReequip = false;
				Reset();
			}
		}

		internal static void OnRegularBoxStateChanged()
		{
			OnRegularBoxStateChanged(FindLocalPlayer());
		}

		internal static void OnPlayerUpdate(PlayerNetwork player)
		{
			if (IsLocalPlayerReady(player))
			{
				SyncHeldBox(player);
				PickupWorldBox(player);
				HandleScroll(player);
				OnRegularBoxStateChanged(player);
			}
		}

		internal static bool ShouldSuppressHoldingItemNotification()
		{
			PlayerNetwork val = FindLocalPlayer();
			if (!IsLocalPlayerReady(val))
			{
				return false;
			}
			if (val.equippedItem == 1 && val.extraParameter1 >= 0 && val.extraParameter2 >= 0)
			{
				return ConfigManager.Instance.MaxCarryBoxes.Value > 1;
			}
			return false;
		}

		private static void PickupWorldBox(PlayerNetwork player)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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)
			RaycastHit val = default(RaycastHit);
			if (_slots.Count == 0 || player.equippedItem != 1 || (Object)(object)Camera.main == (Object)null || Time.unscaledTime < _nextPickupTime || !Input.GetMouseButtonDown(0) || !Physics.Raycast(((Component)Camera.main).transform.position, ((Component)Camera.main).transform.forward, ref val, 4f, LayerMask.op_Implicit(player.interactableMask)))
			{
				return;
			}
			BoxData component = ((Component)((RaycastHit)(ref val)).transform).GetComponent<BoxData>();
			if (!((Object)(object)component == (Object)null) && component.productID >= 0 && component.numberOfProducts > 0)
			{
				if (IsFull())
				{
					_nextPickupTime = Time.unscaledTime + 0.15f;
					Notify("bbw.full");
					return;
				}
				AddSlot(component.productID, component.numberOfProducts);
				ApplySlot(player, showNotification: false);
				_nextPickupTime = Time.unscaledTime + 0.15f;
				((Component)GameData.Instance).GetComponent<NetworkSpawner>().CmdDestroyBox(((Component)component).gameObject);
			}
		}

		private static void HandleScroll(PlayerNetwork player)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (_slots.Count <= 1 || !CanInput() || IsUiBlocked() || Time.unscaledTime < _nextScrollTime)
			{
				return;
			}
			int num = 0;
			float y = Input.mouseScrollDelta.y;
			if (y > 0.01f)
			{
				num = 1;
			}
			else if (y < -0.01f)
			{
				num = -1;
			}
			if (num != 0)
			{
				_activeIndex += num;
				if (_activeIndex < 0)
				{
					_activeIndex = _slots.Count - 1;
				}
				else if (_activeIndex >= _slots.Count)
				{
					_activeIndex = 0;
				}
				_nextScrollTime = Time.unscaledTime + 0.1f;
				ApplySlot(player, showNotification: true);
			}
		}

		private static void ApplySlot(PlayerNetwork player, bool showNotification)
		{
			if (!IsLocalPlayerReady(player) || _slots.Count == 0)
			{
				return;
			}
			ClampIndex();
			BulkCarrySlot bulkCarrySlot = _slots[_activeIndex];
			player.extraParameter1 = bulkCarrySlot.ProductId;
			player.extraParameter2 = bulkCarrySlot.Quantity;
			if (player.equippedItem != 1)
			{
				if (Time.unscaledTime >= _nextReequipTime)
				{
					_nextReequipTime = Time.unscaledTime + 0.1f;
					player.CmdChangeEquippedItem(1);
				}
			}
			else
			{
				_waitingForReequip = false;
			}
			if (player.equippedItem == 1 && (Object)(object)player.instantiatedOBJ != (Object)null)
			{
				ProductListing.Instance.SetBoxColor(player.instantiatedOBJ, bulkCarrySlot.ProductId);
				player.UpdateBoxContents(bulkCarrySlot.ProductId);
				_syncBoxColor?.Invoke(player, new object[1] { bulkCarrySlot.ProductId });
			}
			if (showNotification && ConfigManager.Instance != null && ConfigManager.Instance.ShowSwitchNotifications.Value)
			{
				string text = (((Object)(object)LocalizationManager.instance != (Object)null) ? LocalizationManager.instance.GetLocalizationString("product" + bulkCarrySlot.ProductId) : bulkCarrySlot.ProductId.ToString());
				GameCanvas instance = GameCanvas.Instance;
				if (instance != null)
				{
					instance.CreateCompoundWarning("bbw.switch", text);
				}
			}
		}

		private static void ClearBox(PlayerNetwork player)
		{
			player.extraParameter1 = -1;
			player.extraParameter2 = -1;
			if (player.equippedItem != 0)
			{
				player.CmdChangeEquippedItem(0);
			}
		}

		private static void SyncHeldBox(PlayerNetwork player)
		{
			if (player.equippedItem == 1 && player.extraParameter1 >= 0 && player.extraParameter2 >= 0)
			{
				if (_slots.Count == 0)
				{
					_slots.Add(new BulkCarrySlot(player.extraParameter1, player.extraParameter2));
					_activeIndex = 0;
				}
				else
				{
					ClampIndex();
					_slots[_activeIndex].ProductId = player.extraParameter1;
					_slots[_activeIndex].Quantity = player.extraParameter2;
				}
			}
		}

		private static void RemoveSlot()
		{
			if (_slots.Count != 0)
			{
				ClampIndex();
				_slots.RemoveAt(_activeIndex);
				if (_activeIndex >= _slots.Count)
				{
					_activeIndex = _slots.Count - 1;
				}
				if (_activeIndex < 0)
				{
					_activeIndex = 0;
				}
			}
		}

		private static void AddSlot(int productId, int quantity)
		{
			_slots.Insert(0, new BulkCarrySlot(productId, quantity));
			_activeIndex = 0;
		}

		private static void ClampIndex()
		{
			if (_activeIndex < 0)
			{
				_activeIndex = 0;
			}
			if (_activeIndex >= _slots.Count)
			{
				_activeIndex = _slots.Count - 1;
			}
		}

		private static bool CanTakeMore(PlayerNetwork player)
		{
			if (IsLocalPlayerReady(player) && player.equippedItem == 1 && player.extraParameter1 >= 0)
			{
				return player.extraParameter2 >= 0;
			}
			return false;
		}

		private static bool IsFull()
		{
			if (ConfigManager.Instance != null)
			{
				return _slots.Count >= ConfigManager.Instance.MaxCarryBoxes.Value;
			}
			return false;
		}

		private static bool CanInput()
		{
			return (Object)(object)Camera.main != (Object)null;
		}

		private static bool IsUiBlocked()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)EventSystem.current.currentSelectedGameObject != (Object)null)
			{
				return true;
			}
			if (Cursor.visible || (int)Cursor.lockState != 1)
			{
				return true;
			}
			if ((Object)(object)GameCanvas.Instance == (Object)null)
			{
				return false;
			}
			if (!IsPanelOpen("Builder") && !IsPanelOpen("SurveillanceContainer") && !IsPanelOpen("EndDayStats") && !IsPanelOpen("SavingContainer"))
			{
				return IsPanelOpen("HostDisconnect");
			}
			return true;
		}

		private static bool IsPanelOpen(string panelPath)
		{
			Transform val = ((Component)GameCanvas.Instance).transform.Find(panelPath);
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject.activeInHierarchy;
			}
			return false;
		}

		private static bool IsLocalPlayerReady(PlayerNetwork player)
		{
			if ((Object)(object)player != (Object)null && ((NetworkBehaviour)player).isLocalPlayer)
			{
				return ConfigManager.Instance != null;
			}
			return false;
		}

		private static PlayerNetwork FindLocalPlayer()
		{
			PlayerNetwork[] array = Object.FindObjectsByType<PlayerNetwork>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null && ((NetworkBehaviour)array[i]).isLocalPlayer)
				{
					return array[i];
				}
			}
			return null;
		}

		private static void Notify(string key)
		{
			if ((Object)(object)GameCanvas.Instance != (Object)null)
			{
				GameCanvas.Instance.CreateCanvasNotification(key);
			}
		}
	}
	internal sealed class BulkCarrySlot
	{
		public int ProductId { get; set; }

		public int Quantity { get; set; }

		public BulkCarrySlot(int productId, int quantity)
		{
			ProductId = productId;
			Quantity = quantity;
		}
	}
}
namespace BulkBoxWheel.Configuration
{
	public class ConfigManager
	{
		private static ConfigManager _instance;

		private readonly ConfigFile _configFile;

		private readonly Dictionary<string, ConfigEntry<bool>> _boolConfigs = new Dictionary<string, ConfigEntry<bool>>();

		private readonly Dictionary<string, ConfigEntry<string>> _stringConfigs = new Dictionary<string, ConfigEntry<string>>();

		private readonly Dictionary<string, ConfigEntry<int>> _intConfigs = new Dictionary<string, ConfigEntry<int>>();

		private readonly Dictionary<string, ConfigEntry<float>> _floatConfigs = new Dictionary<string, ConfigEntry<float>>();

		private readonly Dictionary<string, ConfigEntry<KeyCode>> _keyCodeConfigs = new Dictionary<string, ConfigEntry<KeyCode>>();

		public static ConfigManager Instance => _instance;

		public ConfigEntry<int> MaxCarryBoxes { get; private set; }

		public ConfigEntry<bool> ShowSwitchNotifications { get; private set; }

		private ConfigManager(ConfigFile configFile)
		{
			_configFile = configFile;
			InitializeDefaultConfigs();
		}

		public static void Initialize(ConfigFile configFile)
		{
			if (_instance == null)
			{
				_instance = new ConfigManager(configFile);
			}
		}

		private void InitializeDefaultConfigs()
		{
			MaxCarryBoxes = RegisterIntRange("BulkCarry", "MaxCarryBoxes", GetLocalizedDescription("config.max_carry_boxes"), 8, 2, 12);
			ShowSwitchNotifications = RegisterBool("BulkCarry", "ShowSwitchNotifications", GetLocalizedDescription("config.show_switch_notifications"), defaultValue: true);
		}

		private string GetLocalizedDescription(string key)
		{
			return ModLocalizationManager.Instance?.GetLocalizedText(key) ?? key;
		}

		public ConfigEntry<bool> RegisterBool(string section, string key, string description, bool defaultValue)
		{
			ConfigEntry<bool> val = _configFile.Bind<bool>(section, key, defaultValue, description);
			_boolConfigs[key] = val;
			return val;
		}

		public ConfigEntry<string> RegisterString(string section, string key, string description, string defaultValue)
		{
			ConfigEntry<string> val = _configFile.Bind<string>(section, key, defaultValue, description);
			_stringConfigs[key] = val;
			return val;
		}

		public ConfigEntry<KeyCode> RegisterKeyCode(string section, string key, string description, KeyCode defaultValue)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<KeyCode> val = _configFile.Bind<KeyCode>(section, key, defaultValue, description);
			_keyCodeConfigs[key] = val;
			return val;
		}

		public ConfigEntry<int> RegisterInt(string section, string key, string description, int defaultValue)
		{
			ConfigEntry<int> val = _configFile.Bind<int>(section, key, defaultValue, description);
			_intConfigs[key] = val;
			return val;
		}

		public ConfigEntry<int> RegisterIntRange(string section, string key, string description, int defaultValue, int minValue, int maxValue)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ConfigEntry<int> val = _configFile.Bind<int>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(minValue, maxValue), Array.Empty<object>()));
			_intConfigs[key] = val;
			return val;
		}

		public ConfigEntry<float> RegisterFloat(string section, string key, string description, float defaultValue)
		{
			ConfigEntry<float> val = _configFile.Bind<float>(section, key, defaultValue, description);
			_floatConfigs[key] = val;
			return val;
		}

		public ConfigEntry<float> RegisterFloatRange(string section, string key, string description, float defaultValue, float minValue, float maxValue)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ConfigEntry<float> val = _configFile.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(minValue, maxValue), Array.Empty<object>()));
			_floatConfigs[key] = val;
			return val;
		}
	}
}