Decompiled source of VirtualStorage v1.0.0

plugins\VirtualStorage.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SpaceCraft;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("VirtualStorage")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8140d4d451644dcda56a0246e60a799df212f60d")]
[assembly: AssemblyProduct("VirtualStorage")]
[assembly: AssemblyTitle("VirtualStorage")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace VirtualStorage
{
	[HarmonyPatch(typeof(StaticDataHandler), "LoadStaticData")]
	internal static class Patch_RegisterGroup
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_01ec: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			if (GroupsHandler.GetGroupViaId("VirtualStorageT1") == null)
			{
				Group val = GroupsHandler.GetGroupViaId("CraftStation2") ?? GroupsHandler.GetGroupViaId("CraftStation1");
				Group val2 = GroupsHandler.GetGroupViaId("Container2") ?? GroupsHandler.GetGroupViaId("Container1");
				if (val2 == null)
				{
					Plugin.Log.LogError((object)"[VirtualStorage] No base container group found – Virtual Storage will not be registered.");
					return;
				}
				GameObject val3 = BuildVisualPrefab(val, val2);
				Plugin.Log.LogInfo((object)("[VirtualStorage] Using prefab '" + ((Object)val3).name + "'."));
				GroupDataConstructible val4 = ScriptableObject.CreateInstance<GroupDataConstructible>();
				((GroupData)val4).id = "VirtualStorageT1";
				((GroupData)val4).associatedGameObject = val3;
				((GroupData)val4).icon = ((val != null) ? val.GetImage() : null) ?? val2.GetImage();
				val4.unitGenerationEnergy = -10000f;
				((GroupData)val4).inventorySize = 9999;
				GroupData groupData = val2.GetGroupData();
				GroupDataConstructible val5 = (GroupDataConstructible)(object)((groupData is GroupDataConstructible) ? groupData : null);
				val4.groupCategory = (GroupCategory)((val5 == null) ? 2 : ((int)val5.groupCategory));
				((GroupData)val4).logisticInterplanetaryType = (LogisticInterplanetaryType)1;
				((GroupData)val4).recipeIngredients = BuildRecipe(("Drone2", 1), ("MultiToolDeconstruct3", 1), ("MultiBuild", 1), ("CircuitBoard1", 1), ("SolarQuartz", 1), ("PulsarQuartz", 1), ("QuasarQuartz", 1), ("MagnetarQuartz", 1), ("BalzarQuartz", 1));
				((GroupData)val4).unlockingWorldUnit = (WorldUnitType)1;
				((GroupData)val4).unlockingValue = 0f;
				((GroupData)val4).terraformStageUnlock = null;
				((GroupData)val4).unlockInPlanets = new List<PlanetData>();
				((GroupData)val4).secondaryInventoriesSize = new List<int>();
				val4.notAllowedPlanetsRequirement = new List<PlanetData>();
				val4.terraStageRequirements = Array.Empty<TerraformStage>();
				GroupConstructible val6 = new GroupConstructible(val4);
				List<GroupDataItem> list = ((GroupData)val4).recipeIngredients ?? new List<GroupDataItem>();
				((Group)val6).SetRecipe(new Recipe(list));
				GroupsHandler.SetAllGroups(new List<Group>(GroupsHandler.GetAllGroups()) { (Group)(object)val6 });
				Plugin.Log.LogInfo((object)("[VirtualStorage] Registered group 'VirtualStorageT1' " + $"(energy: {val4.unitGenerationEnergy} kW, recipe: {((GroupData)val4).recipeIngredients?.Count ?? 0} ingredients)."));
			}
		}

		private static GameObject BuildVisualPrefab(Group? craftGroup, Group containerGroup)
		{
			return ((craftGroup != null) ? craftGroup.GetAssociatedGameObject() : null) ?? containerGroup.GetAssociatedGameObject();
		}

		private static List<GroupDataItem>? BuildRecipe(params (string id, int count)[] ingredients)
		{
			List<GroupDataItem> list = new List<GroupDataItem>();
			for (int i = 0; i < ingredients.Length; i++)
			{
				(string id, int count) tuple = ingredients[i];
				string item = tuple.id;
				int item2 = tuple.count;
				Group groupViaId = GroupsHandler.GetGroupViaId(item);
				GroupData obj = ((groupViaId != null) ? groupViaId.GetGroupData() : null);
				GroupDataItem val = (GroupDataItem)(object)((obj is GroupDataItem) ? obj : null);
				if (val != null && groupViaId is GroupItem)
				{
					for (int j = 0; j < item2; j++)
					{
						list.Add(val);
					}
				}
				else
				{
					Plugin.Log.LogWarning((object)("[VirtualStorage] Recipe ingredient '" + item + "' not found – skipping."));
				}
			}
			if (list.Count <= 0)
			{
				return null;
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(InventoryAssociated), "SetInventory")]
	internal static class Patch_UnlimitedInventory
	{
		public static readonly HashSet<int> VirtualStorageInventoryIds = new HashSet<int>();

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

		[HarmonyPostfix]
		private static void Postfix(InventoryAssociated __instance, Inventory inventory)
		{
			WorldObjectAssociated component = ((Component)__instance).GetComponent<WorldObjectAssociated>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			WorldObject worldObject = component.GetWorldObject();
			if (worldObject != null)
			{
				Group obj = worldObject.GetGroup();
				if (!(((obj != null) ? obj.GetId() : null) != "VirtualStorageT1"))
				{
					inventory.SetSize(int.MaxValue);
					VirtualStorageInventoryIds.Add(inventory.GetId());
					InventoryToWoId[inventory.GetId()] = worldObject.GetId();
					VirtualStorageLimits.Load(worldObject.GetId(), worldObject);
					Plugin.Log.LogInfo((object)$"[VirtualStorage] Inventory {inventory.GetId()} → unlimited (WO {worldObject.GetId()}).");
					SetupContainerBehavior(((Component)__instance).gameObject, worldObject.GetId());
				}
			}
		}

		private static void SetupContainerBehavior(GameObject go, int woId)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			ActionCrafter[] componentsInChildren = go.GetComponentsInChildren<ActionCrafter>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			ActionnableInteractive[] componentsInChildren2 = go.GetComponentsInChildren<ActionnableInteractive>();
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			MachineConvertRecipe[] componentsInChildren3 = go.GetComponentsInChildren<MachineConvertRecipe>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			Canvas[] componentsInChildren4 = go.GetComponentsInChildren<Canvas>();
			foreach (Canvas val in componentsInChildren4)
			{
				if ((Object)(object)((Component)val).gameObject != (Object)(object)go)
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
				else
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			if ((Object)(object)go.GetComponent<InventoryAssociatedProxy>() == (Object)null)
			{
				go.AddComponent<InventoryAssociatedProxy>();
			}
			if (!((Object)(object)go.GetComponent<ActionOpenable>() != (Object)null))
			{
				ActionOpenable obj = go.AddComponent<ActionOpenable>();
				obj.uiType = (UiType)3;
				obj.hideLogisticsButton = false;
				obj.infosHoverLocalizationId = "";
				Plugin.Log.LogInfo((object)$"[VirtualStorage] Instance configured as container (WO {woId}).");
			}
		}
	}
	[HarmonyPatch(typeof(Localization), "GetLocalizedString")]
	internal static class Patch_Localization
	{
		private const string NameKey = "GROUP_NAME_VirtualStorageT1";

		private const string DescKey = "GROUP_DESC_VirtualStorageT1";

		private static readonly Dictionary<string, string> _strings = new Dictionary<string, string>
		{
			["GROUP_NAME_VirtualStorageT1"] = "Virtual Storage",
			["GROUP_DESC_VirtualStorageT1"] = $"Unlimited storage capacity. Consumes {10000f:0} kW of power."
		};

		[HarmonyPrefix]
		private static bool Prefix(string stringCode, ref string __result)
		{
			if (_strings.TryGetValue(stringCode, out string value))
			{
				__result = value;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LogisticManager), "CreateNewTaskForWorldObject")]
	internal static class Patch_LogisticLimit
	{
		[HarmonyPrefix]
		private static bool Prefix(Inventory demandInventory, WorldObject worldObject, ref LogisticTask __result)
		{
			if (!Patch_UnlimitedInventory.VirtualStorageInventoryIds.Contains(demandInventory.GetId()))
			{
				return true;
			}
			if (!Patch_UnlimitedInventory.InventoryToWoId.TryGetValue(demandInventory.GetId(), out var value))
			{
				return true;
			}
			if (VirtualStorageLimits.DroneCanDeposit(demandInventory, value, worldObject.GetGroup()))
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(LogisticManager), "CreateNewTaskForWorldObjectForSpawnedObject")]
	internal static class Patch_LogisticLimitSpawned
	{
		[HarmonyPrefix]
		private static bool Prefix(Inventory demandInventory, WorldObject worldObject, ref LogisticTask __result)
		{
			if (!Patch_UnlimitedInventory.VirtualStorageInventoryIds.Contains(demandInventory.GetId()))
			{
				return true;
			}
			if (!Patch_UnlimitedInventory.InventoryToWoId.TryGetValue(demandInventory.GetId(), out var value))
			{
				return true;
			}
			if (VirtualStorageLimits.DroneCanDeposit(demandInventory, value, worldObject.GetGroup()))
			{
				return true;
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(LogisticSelector), "InitLogisticSelector")]
	internal static class Patch_LogisticDemandAll
	{
		internal static readonly Dictionary<LogisticSelector, GameObject> DemandEvTexts = new Dictionary<LogisticSelector, GameObject>();

		[HarmonyPostfix]
		private static void Postfix(LogisticSelector __instance, Inventory inventory)
		{
			if (Patch_UnlimitedInventory.VirtualStorageInventoryIds.Contains(inventory.GetId()) && !DemandEvTexts.ContainsKey(__instance))
			{
				AddDemandAllButton(__instance, inventory);
			}
		}

		private static void AddDemandAllButton(LogisticSelector selector, Inventory inventory)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_007f: 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_0116: Expected O, but got Unknown
			//IL_013e: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			GameObject supplyAllIcon = selector.supplyAllIcon;
			if (!((Object)(object)supplyAllIcon == (Object)null))
			{
				GroupSelector groupSelectorSupply = selector.groupSelectorSupply;
				RectTransform val = ((groupSelectorSupply != null) ? ((Component)groupSelectorSupply).GetComponent<RectTransform>() : null);
				GroupSelector groupSelectorDemand = selector.groupSelectorDemand;
				RectTransform val2 = ((groupSelectorDemand != null) ? ((Component)groupSelectorDemand).GetComponent<RectTransform>() : null);
				Vector3 val3 = (((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) ? (((Transform)val2).position - ((Transform)val).position) : Vector3.zero);
				GameObject val4 = Object.Instantiate<GameObject>(supplyAllIcon, supplyAllIcon.transform.parent);
				((Object)val4).name = "VSdemandAllIcon";
				RectTransform component = supplyAllIcon.GetComponent<RectTransform>();
				((Transform)val4.GetComponent<RectTransform>()).position = ((Transform)component).position + val3;
				Button component2 = val4.GetComponent<Button>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component2);
				}
				Button obj = val4.AddComponent<Button>();
				((Selectable)obj).targetGraphic = (Graphic)(object)(val4.GetComponent<Image>() ?? val4.GetComponentInChildren<Image>());
				((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
				{
					OnDemandAll(selector, inventory);
				});
				Image[] componentsInChildren = val4.GetComponentsInChildren<Image>();
				foreach (Image val5 in componentsInChildren)
				{
					((Graphic)val5).color = new Color(0.45f, 0.8f, 1f, ((Graphic)val5).color.a);
				}
				TMP_Text[] componentsInChildren2 = val4.GetComponentsInChildren<TMP_Text>();
				for (int num = 0; num < componentsInChildren2.Length; num++)
				{
					componentsInChildren2[num].text = "Import All";
				}
				Text[] componentsInChildren3 = val4.GetComponentsInChildren<Text>();
				for (int num = 0; num < componentsInChildren3.Length; num++)
				{
					componentsInChildren3[num].text = "Import All";
				}
				val4.AddComponent<EventHoverIncrease>().SetHoverGroupEvent(default(Vector3));
				val4.SetActive(true);
				GameObject val6 = null;
				if ((Object)(object)selector.everythingTextGameObject != (Object)null)
				{
					GameObject everythingTextGameObject = selector.everythingTextGameObject;
					val6 = Object.Instantiate<GameObject>(everythingTextGameObject, everythingTextGameObject.transform.parent);
					((Object)val6).name = "VSdemandEverythingText";
					((Transform)val6.GetComponent<RectTransform>()).position = ((Transform)everythingTextGameObject.GetComponent<RectTransform>()).position + val3;
					val6.SetActive(false);
				}
				DemandEvTexts[selector] = val6;
			}
		}

		private static void OnDemandAll(LogisticSelector selector, Inventory inventory)
		{
			LogisticManager manager = Managers.GetManager<LogisticManager>();
			LogisticEntity logisticEntity = inventory.GetLogisticEntity();
			selector.groupSelectorDemand.PopulateWithItems(manager.GetItemsToDisplayForLogistics(true, (HashSet<Group>)null));
			foreach (Group addedGroup in selector.groupSelectorDemand.GetAddedGroups())
			{
				logisticEntity.AddDemandGroup(addedGroup);
			}
			selector.groupSelectorDemand.PopulateWithItems(manager.GetItemsToDisplayForLogistics(false, (HashSet<Group>)null));
			InventoriesHandler.Instance.UpdateLogisticEntity(inventory);
		}
	}
	[HarmonyPatch(typeof(LogisticSelector), "SetListsDisplay")]
	internal static class Patch_LogisticDemandEverythingDisplay
	{
		private static readonly FieldInfo FInventory = typeof(LogisticSelector).GetField("_inventory", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPostfix]
		private static void Postfix(LogisticSelector __instance)
		{
			object? obj = FInventory?.GetValue(__instance);
			Inventory val = (Inventory)((obj is Inventory) ? obj : null);
			if (val != null && Patch_UnlimitedInventory.VirtualStorageInventoryIds.Contains(val.GetId()))
			{
				bool flag = val.GetLogisticEntity().GetDemandGroups().Count > 140;
				if (Patch_LogisticDemandAll.DemandEvTexts.TryGetValue(__instance, out GameObject value) && (Object)(object)value != (Object)null)
				{
					value.SetActive(flag);
				}
				if (flag)
				{
					__instance.groupListDemand.ClearGrid();
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryDisplayer), "TrueRefreshContent")]
	internal static class Patch_VirtualStorageDisplay
	{
		[HarmonyPrefix]
		private static bool Prefix(InventoryDisplayer __instance)
		{
			Inventory inventory = InventoryDisplayerReflection.GetInventory(__instance);
			if (inventory == null)
			{
				return true;
			}
			if (!Patch_UnlimitedInventory.VirtualStorageInventoryIds.Contains(inventory.GetId()))
			{
				return true;
			}
			Patch_UnlimitedInventory.InventoryToWoId.TryGetValue(inventory.GetId(), out var value);
			VirtualStorageDisplayer.Refresh(__instance, inventory, value);
			return false;
		}
	}
	[BepInPlugin("com.sgachoud.VirtualStorage", "VirtualStorage", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource Log;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			new Harmony("com.sgachoud.VirtualStorage").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VirtualStorage v1.0.0 loaded.");
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.sgachoud.VirtualStorage";

		public const string Name = "VirtualStorage";

		public const string Version = "1.0.0";

		public const string GroupId = "VirtualStorageT1";

		public const float EnergyConsumptionKw = 10000f;
	}
	internal static class InventoryDisplayerReflection
	{
		private static readonly FieldInfo FInventory = typeof(InventoryDisplayer).GetField("_inventory", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo FGrid = typeof(InventoryDisplayer).GetField("_grid", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo FOriginalSizeDelta = typeof(InventoryDisplayer).GetField("_originalSizeDelta", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo MSetIcons = typeof(InventoryDisplayer).GetMethod("SetIconsPositionRelativeToGrid", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo MConsume = typeof(InventoryDisplayer).GetMethod("Consume", BindingFlags.Instance | BindingFlags.NonPublic);

		public static Inventory? GetInventory(InventoryDisplayer d)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Inventory)FInventory.GetValue(d);
		}

		public static GridLayoutGroup? GetGrid(InventoryDisplayer d)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (GridLayoutGroup)FGrid.GetValue(d);
		}

		public static Vector2 GetOriginalSizeDelta(InventoryDisplayer d)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return (Vector2)FOriginalSizeDelta.GetValue(d);
		}

		public static void SetOriginalSizeDelta(InventoryDisplayer d, Vector2 v)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			FOriginalSizeDelta.SetValue(d, v);
		}

		public static void CallSetIconsPosition(InventoryDisplayer d)
		{
			MSetIcons?.Invoke(d, null);
		}

		public static void CallConsume(InventoryDisplayer d, WorldObject wo)
		{
			MConsume?.Invoke(d, new object[1] { wo });
		}
	}
	internal static class VirtualStorageDisplayer
	{
		private static readonly GroupInfosDisplayerBlocksSwitches TooltipFlags = new GroupInfosDisplayerBlocksSwitches
		{
			showName = true,
			showDescription = true,
			showMultipliers = true,
			showActions = false,
			showRecipe = false,
			showUnits = false,
			showInfos = true
		};

		private const float CellSize = 70f;

		private const float CellGap = 2f;

		private const float ScrollbarW = 12f;

		public static void Refresh(InventoryDisplayer displayer, Inventory inventory, int woId)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0055: 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_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_0032: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: 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_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			GridLayoutGroup grid = InventoryDisplayerReflection.GetGrid(displayer);
			if ((Object)(object)grid == (Object)null)
			{
				return;
			}
			Vector2 val = InventoryDisplayerReflection.GetOriginalSizeDelta(displayer);
			if (val == Vector2.zero)
			{
				val = ((Component)displayer).GetComponent<RectTransform>().sizeDelta;
				InventoryDisplayerReflection.SetOriginalSizeDelta(displayer, val);
			}
			((Component)displayer).GetComponent<RectTransform>().sizeDelta = val;
			EnsureScrollView(grid);
			grid.cellSize = new Vector2(70f, 70f);
			grid.spacing = new Vector2(2f, 2f);
			((LayoutGroup)grid).childAlignment = (TextAnchor)0;
			for (int num = ((Component)grid).transform.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Component)grid).transform.GetChild(num)).gameObject);
			}
			Dictionary<string, (int, WorldObject)> dictionary = CountByGroup(inventory);
			VisualsResourcesHandler manager = Managers.GetManager<VisualsResourcesHandler>();
			foreach (GroupItem item in GroupsHandler.GetGroupsItem())
			{
				if (!dictionary.TryGetValue(((Group)item).GetId(), out var value))
				{
					continue;
				}
				GameObject obj = Object.Instantiate<GameObject>(manager.GetInventoryBlock(), ((Component)grid).transform);
				InventoryBlock component = obj.GetComponent<InventoryBlock>();
				component.groupImage.sprite = ((Group)item).GetImage();
				((Graphic)component.groupImage).color = Color.white;
				if ((Object)(object)component.lockedImage != (Object)null)
				{
					component.lockedImage.SetActive(false);
				}
				if ((Object)(object)component.dropIcon != (Object)null)
				{
					component.dropIcon.SetActive(false);
				}
				if ((Object)(object)component.logisticIcon != (Object)null)
				{
					component.logisticIcon.SetActive(false);
				}
				if ((Object)(object)component.authorizedIcon != (Object)null)
				{
					((Component)component.authorizedIcon).gameObject.SetActive(false);
				}
				obj.AddComponent<EventHoverShowGroup>().SetHoverGroupEvent((Group)(object)item, TooltipFlags, default(Vector2), value.Item2, (GameObject)null);
				obj.AddComponent<EventHoverIncrease>().SetHoverGroupEvent(default(Vector3));
				GroupItem capturedGroup = item;
				Inventory capturedInventory = inventory;
				int capturedWoId = woId;
				InventoryDisplayer capturedDisp = displayer;
				EventTriggerCallbackData val2 = new EventTriggerCallbackData((Group)(object)item);
				EventsHelpers.AddTriggerEvent(obj, (EventTriggerType)4, (Action<EventTriggerCallbackData>)delegate(EventTriggerCallbackData data)
				{
					//IL_0015: 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_0026: 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_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0040: Invalid comparison between Unknown and I4
					//IL_00a3: 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)
					//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
					PointerEventData pointerEventData = data.pointerEventData;
					InputButton? val3 = ((pointerEventData != null) ? new InputButton?(pointerEventData.button) : ((InputButton?)null));
					if (val3 == (InputButton?)0 || (int)val3.GetValueOrDefault() == 1)
					{
						WorldObject val4 = null;
						foreach (WorldObject insideWorldObject in capturedInventory.GetInsideWorldObjects())
						{
							if (insideWorldObject.GetGroup().GetId() == ((Group)capturedGroup).GetId())
							{
								val4 = insideWorldObject;
								break;
							}
						}
						if (val4 != null)
						{
							if (val3 == (InputButton?)0)
							{
								InventoriesHandler.Instance.AnInventoryHasBeenClicked(capturedInventory, val4);
							}
							else
							{
								InventoryDisplayerReflection.CallConsume(capturedDisp, val4);
							}
						}
					}
				}, val2);
				EventsHelpers.AddTriggerEvent(obj, (EventTriggerType)7, (Action<EventTriggerCallbackData>)delegate(EventTriggerCallbackData data)
				{
					//IL_0025: Unknown result type (might be due to invalid IL or missing references)
					if (data.pointerEventData != null)
					{
						Keyboard current2 = Keyboard.current;
						if (current2 != null && current2.ctrlKey.isPressed)
						{
							bool reverse = data.pointerEventData.scrollDelta.y < 0f;
							VirtualStorageLimits.CycleLimit(capturedWoId, ((Group)capturedGroup).GetId(), reverse);
							Refresh(capturedDisp, capturedInventory, capturedWoId);
						}
						else
						{
							ScrollRect componentInChildren = ((Component)capturedDisp).GetComponentInChildren<ScrollRect>();
							if ((Object)(object)componentInChildren != (Object)null)
							{
								ExecuteEvents.Execute<IScrollHandler>(((Component)componentInChildren).gameObject, (BaseEventData)(object)data.pointerEventData, ExecuteEvents.scrollHandler);
							}
						}
					}
				}, val2);
				AttachCountBadge(obj, value.Item1);
				AttachLimitBadge(obj, VirtualStorageLimits.GetLimit(woId, ((Group)item).GetId()));
				obj.SetActive(true);
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)grid).GetComponent<RectTransform>());
			((MonoBehaviour)displayer).StartCoroutine(SnapIconsToLeft(displayer));
		}

		private static void EnsureScrollView(GridLayoutGroup grid)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_012c: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)((Component)grid).GetComponentInParent<ScrollRect>() != (Object)null))
			{
				Transform parent = ((Component)grid).transform.parent;
				GameObject val = new GameObject("VSViewport");
				val.transform.SetParent(parent, false);
				RectTransform val2 = val.AddComponent<RectTransform>();
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = new Vector2(-14f, 0f);
				((Graphic)val.AddComponent<Image>()).color = Color.white;
				val.AddComponent<Mask>().showMaskGraphic = false;
				((Component)grid).transform.SetParent(val.transform, false);
				RectTransform component = ((Component)grid).GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 1f);
				component.anchorMax = new Vector2(1f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = Vector2.zero;
				component.sizeDelta = Vector2.zero;
				if ((Object)(object)((Component)grid).GetComponent<ContentSizeFitter>() == (Object)null)
				{
					ContentSizeFitter obj = ((Component)grid).gameObject.AddComponent<ContentSizeFitter>();
					obj.horizontalFit = (FitMode)0;
					obj.verticalFit = (FitMode)2;
				}
				GameObject val3 = new GameObject("VSScrollbar");
				val3.transform.SetParent(parent, false);
				RectTransform obj2 = val3.AddComponent<RectTransform>();
				obj2.anchorMin = new Vector2(1f, 0f);
				obj2.anchorMax = new Vector2(1f, 1f);
				obj2.pivot = new Vector2(1f, 0.5f);
				obj2.anchoredPosition = Vector2.zero;
				obj2.sizeDelta = new Vector2(12f, 0f);
				((Graphic)val3.AddComponent<Image>()).color = new Color(0.12f, 0.12f, 0.12f, 0.85f);
				Scrollbar val4 = val3.AddComponent<Scrollbar>();
				val4.direction = (Direction)2;
				GameObject val5 = new GameObject("SlideArea");
				val5.transform.SetParent(val3.transform, false);
				RectTransform obj3 = val5.AddComponent<RectTransform>();
				obj3.anchorMin = Vector2.zero;
				obj3.anchorMax = Vector2.one;
				obj3.offsetMin = new Vector2(0f, 4f);
				obj3.offsetMax = new Vector2(0f, -4f);
				GameObject val6 = new GameObject("Handle");
				val6.transform.SetParent(val5.transform, false);
				RectTransform val7 = val6.AddComponent<RectTransform>();
				val7.anchorMin = Vector2.zero;
				val7.anchorMax = Vector2.one;
				val7.offsetMin = Vector2.zero;
				val7.offsetMax = Vector2.zero;
				Image val8 = val6.AddComponent<Image>();
				((Graphic)val8).color = new Color(0.55f, 0.55f, 0.55f, 0.9f);
				val4.handleRect = val7;
				((Selectable)val4).targetGraphic = (Graphic)(object)val8;
				ScrollRect obj4 = ((Component)parent).gameObject.AddComponent<ScrollRect>();
				obj4.viewport = val2;
				obj4.content = component;
				obj4.horizontal = false;
				obj4.vertical = true;
				obj4.verticalScrollbar = val4;
				obj4.verticalScrollbarVisibility = (ScrollbarVisibility)2;
				obj4.scrollSensitivity = 30f;
				obj4.movementType = (MovementType)2;
				obj4.inertia = false;
			}
		}

		private static IEnumerator SnapIconsToLeft(InventoryDisplayer displayer)
		{
			yield return (object)new WaitForEndOfFrame();
			GridLayoutGroup grid = InventoryDisplayerReflection.GetGrid(displayer);
			if (!((Object)(object)grid == (Object)null) && ((Component)grid).transform.childCount != 0 && !((Object)(object)displayer.iconsContainer == (Object)null))
			{
				Mask componentInParent = ((Component)grid).GetComponentInParent<Mask>();
				RectTransform obj = ((componentInParent != null) ? ((Component)componentInParent).GetComponent<RectTransform>() : null) ?? ((Component)grid).GetComponent<RectTransform>();
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				obj.GetWorldCorners(array);
				Vector3 position = ((Transform)((Component)((Component)grid).transform.GetChild(0)).GetComponent<RectTransform>()).position;
				((Transform)displayer.iconsContainer.GetComponent<RectTransform>()).position = new Vector3(array[1].x, position.y, position.z);
				displayer.iconsContainer.transform.SetAsLastSibling();
			}
		}

		private static Dictionary<string, (int count, WorldObject first)> CountByGroup(Inventory inventory)
		{
			Dictionary<string, (int, WorldObject)> dictionary = new Dictionary<string, (int, WorldObject)>();
			foreach (WorldObject insideWorldObject in inventory.GetInsideWorldObjects())
			{
				string id = insideWorldObject.GetGroup().GetId();
				if (dictionary.TryGetValue(id, out var value))
				{
					dictionary[id] = (value.Item1 + 1, value.Item2);
				}
				else
				{
					dictionary[id] = (1, insideWorldObject);
				}
			}
			return dictionary;
		}

		private static void AttachLimitBadge(GameObject parent, int limit)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			GameObject val = new GameObject("LimitBadge");
			val.transform.SetParent(parent.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = new Vector2(0f, 1f);
			obj.pivot = new Vector2(0f, 1f);
			obj.anchoredPosition = new Vector2(1f, -1f);
			obj.sizeDelta = new Vector2(36f, 18f);
			((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0.55f, 0.55f, 0.8f);
			GameObject val2 = new GameObject("LimitText");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = Vector2.zero;
			obj2.offsetMax = Vector2.zero;
			Text obj3 = val2.AddComponent<Text>();
			obj3.text = VirtualStorageLimits.FormatLimit(limit);
			obj3.fontSize = 12;
			obj3.fontStyle = (FontStyle)1;
			((Graphic)obj3).color = Color.white;
			obj3.alignment = (TextAnchor)4;
			obj3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			val.transform.SetAsLastSibling();
		}

		private static void AttachCountBadge(GameObject parent, int count)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			GameObject val = new GameObject("CountBadge");
			val.transform.SetParent(parent.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(1f, 0f);
			obj.anchorMax = new Vector2(1f, 0f);
			obj.pivot = new Vector2(1f, 0f);
			obj.anchoredPosition = new Vector2(-1f, 1f);
			obj.sizeDelta = new Vector2(36f, 18f);
			((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.65f);
			GameObject val2 = new GameObject("CountText");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = Vector2.zero;
			obj2.offsetMax = Vector2.zero;
			Text obj3 = val2.AddComponent<Text>();
			obj3.text = FormatCount(count);
			obj3.fontSize = 12;
			obj3.fontStyle = (FontStyle)1;
			((Graphic)obj3).color = Color.white;
			obj3.alignment = (TextAnchor)4;
			obj3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			val.transform.SetAsLastSibling();
		}

		private static string FormatCount(int n)
		{
			if (n < 1000000)
			{
				if (n < 10000)
				{
					return n.ToString();
				}
				return $"{n / 1000}k";
			}
			return $"{n / 1000000}M";
		}
	}
	internal static class VirtualStorageLimits
	{
		internal static readonly int[] Presets = new int[12]
		{
			-1, 1, 5, 10, 25, 50, 100, 250, 500, 1000,
			2500, 5000
		};

		private const string Prefix = "vs_lim:";

		private static readonly Dictionary<int, Dictionary<string, int>> _limits = new Dictionary<int, Dictionary<string, int>>();

		private static readonly Dictionary<int, WorldObject> _worldObjects = new Dictionary<int, WorldObject>();

		public static int GetLimit(int woId, string groupId)
		{
			if (!_limits.TryGetValue(woId, out Dictionary<string, int> value))
			{
				return -1;
			}
			if (!value.TryGetValue(groupId, out var value2))
			{
				return -1;
			}
			return value2;
		}

		public static void CycleLimit(int woId, string groupId, bool reverse = false)
		{
			if (!_worldObjects.TryGetValue(woId, out WorldObject value))
			{
				return;
			}
			int limit = GetLimit(woId, groupId);
			int num = 0;
			for (int i = 0; i < Presets.Length; i++)
			{
				if (Presets[i] == limit)
				{
					num = i;
					break;
				}
			}
			int limit2 = (reverse ? Presets[(num - 1 + Presets.Length) % Presets.Length] : Presets[(num + 1) % Presets.Length]);
			SetAndSave(woId, value, groupId, limit2);
		}

		public static bool DroneCanDeposit(Inventory inv, int woId, Group group)
		{
			int limit = GetLimit(woId, group.GetId());
			if (limit == -1)
			{
				return true;
			}
			int num = 0;
			foreach (WorldObject insideWorldObject in inv.GetInsideWorldObjects())
			{
				if (insideWorldObject.GetGroup().GetId() == group.GetId())
				{
					num++;
				}
			}
			return num < limit;
		}

		public static string FormatLimit(int limit)
		{
			if (limit >= 0)
			{
				return limit.ToString();
			}
			return "∞";
		}

		public static void Load(int woId, WorldObject wo)
		{
			_worldObjects[woId] = wo;
			_limits.Remove(woId);
			string text = wo.GetText();
			if (string.IsNullOrEmpty(text) || !text.StartsWith("vs_lim:"))
			{
				return;
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			string[] array = text.Substring("vs_lim:".Length).Split(';');
			foreach (string text2 in array)
			{
				if (!string.IsNullOrEmpty(text2))
				{
					int num = text2.IndexOf('=');
					if (num >= 0 && int.TryParse(text2.Substring(num + 1), out var result))
					{
						dictionary[text2.Substring(0, num)] = result;
					}
				}
			}
			if (dictionary.Count > 0)
			{
				_limits[woId] = dictionary;
			}
		}

		private static void SetAndSave(int woId, WorldObject wo, string groupId, int limit)
		{
			if (!_limits.TryGetValue(woId, out Dictionary<string, int> value))
			{
				value = new Dictionary<string, int>();
				_limits[woId] = value;
			}
			if (limit == -1)
			{
				value.Remove(groupId);
			}
			else
			{
				value[groupId] = limit;
			}
			Persist(wo, value);
		}

		private static void Persist(WorldObject wo, Dictionary<string, int> g)
		{
			if (g.Count == 0)
			{
				wo.SetText("");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder("vs_lim:");
			foreach (KeyValuePair<string, int> item in g)
			{
				stringBuilder.Append(item.Key).Append('=').Append(item.Value)
					.Append(';');
			}
			wo.SetText(stringBuilder.ToString());
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}