Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of UnifiedStorage v1.1.5
plugins\UnifiedStorage\UnifiedStorage.Core.dll
Decompiled 4 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("UnifiedStorage.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5d7be5f6efeb56f9a845ddaab6e91dfa01032b38")] [assembly: AssemblyProduct("UnifiedStorage.Core")] [assembly: AssemblyTitle("UnifiedStorage.Core")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UnifiedStorage.Core { public static class AggregationService { public static IReadOnlyList<AggregatedItem> Aggregate(IReadOnlyList<SourceStack> sourceStacks, Func<string, int>? resolveMaxStackSize = null) { Func<string, int> resolveMaxStackSize2 = resolveMaxStackSize; return (from item in (from s in sourceStacks where s.Amount > 0 group s by s.Key).Select(delegate(IGrouping<ItemKey, SourceStack> @group) { int num = ((resolveMaxStackSize2 != null) ? resolveMaxStackSize2(@group.Key.PrefabName) : @group.Max((SourceStack s) => s.StackSize)); if (num <= 0) { num = 1; } return new AggregatedItem { Key = @group.Key, DisplayName = (@group.Select((SourceStack s) => s.DisplayName).FirstOrDefault() ?? @group.Key.PrefabName), TotalAmount = @group.Sum((SourceStack s) => s.Amount), SourceCount = @group.Select((SourceStack s) => s.SourceId).Distinct().Count(), StackSize = num }; }) orderby item.DisplayName, item.TotalAmount descending select item).ToList(); } public static int CalculateVirtualSlots(IReadOnlyList<AggregatedItem> items) { return items.Sum((AggregatedItem i) => (i.StackSize <= 0) ? 1 : ((int)Math.Ceiling((double)i.TotalAmount / (double)i.StackSize))); } } public static class ChunkedTransfer { public static int ClampMeasuredMove(int requestedAmount, int beforeAmount, int afterAmount) { if (requestedAmount <= 0) { return 0; } int num = afterAmount - beforeAmount; if (num <= 0) { return 0; } return Math.Min(requestedAmount, num); } public static int Move(int requestedAmount, int maxChunkSize, Func<int, int> moveChunk) { if (moveChunk == null) { throw new ArgumentNullException("moveChunk"); } if (requestedAmount <= 0 || maxChunkSize <= 0) { return 0; } int num = requestedAmount; int num2 = 0; while (num > 0) { int num3 = Math.Min(maxChunkSize, num); int num4 = moveChunk(num3); if (num4 <= 0) { break; } if (num4 > num3) { num4 = num3; } num2 += num4; num -= num4; if (num4 < num3) { break; } } return num2; } } public sealed class ContainerSlot { public string SourceId { get; set; } = string.Empty; public int FreeSpace { get; set; } public float Distance { get; set; } } public static class DepositPlanner { public static DepositPlan Plan(IReadOnlyList<ContainerSlot> containers, int requestedAmount) { DepositPlan depositPlan = new DepositPlan { RequestedAmount = requestedAmount }; int num = Math.Max(0, requestedAmount); if (num <= 0 || containers.Count == 0) { return depositPlan; } int num2 = num; foreach (ContainerSlot item in (from c in containers where c.FreeSpace > 0 orderby c.Distance select c).ThenBy<ContainerSlot, string>((ContainerSlot c) => c.SourceId, StringComparer.Ordinal)) { if (num2 <= 0) { break; } int num3 = Math.Min(item.FreeSpace, num2); if (num3 > 0) { depositPlan.Deposits.Add(new PlannedDeposit { SourceId = item.SourceId, Amount = num3 }); num2 -= num3; } } depositPlan.PlannedAmount = num - num2; return depositPlan; } } public readonly struct ItemKey : IEquatable<ItemKey> { public string PrefabName { get; } public int Quality { get; } public int Variant { get; } public ItemKey(string prefabName, int quality, int variant) { PrefabName = prefabName ?? string.Empty; Quality = quality; Variant = variant; } public bool Equals(ItemKey other) { if (string.Equals(PrefabName, other.PrefabName, StringComparison.Ordinal) && Quality == other.Quality) { return Variant == other.Variant; } return false; } public override bool Equals(object? obj) { if (obj is ItemKey other) { return Equals(other); } return false; } public override int GetHashCode() { return ((17 * 23 + (PrefabName?.GetHashCode() ?? 0)) * 23 + Quality.GetHashCode()) * 23 + Variant.GetHashCode(); } } public sealed class AggregatedItem { public ItemKey Key { get; set; } public string DisplayName { get; set; } = string.Empty; public int TotalAmount { get; set; } public int SourceCount { get; set; } public int StackSize { get; set; } } public sealed class SearchResult { public IReadOnlyList<AggregatedItem> Items { get; set; } = Array.Empty<AggregatedItem>(); } public sealed class SourceStack { public ItemKey Key { get; set; } public string DisplayName { get; set; } = string.Empty; public int Amount { get; set; } public int StackSize { get; set; } public float Distance { get; set; } public string SourceId { get; set; } = string.Empty; } public sealed class PlannedTake { public string SourceId { get; set; } = string.Empty; public int Amount { get; set; } } public sealed class WithdrawPlan { public List<PlannedTake> Takes { get; set; } = new List<PlannedTake>(); public int RequestedAmount { get; set; } public int PlannedAmount { get; set; } } public sealed class PlannedDeposit { public string SourceId { get; set; } = string.Empty; public int Amount { get; set; } } public sealed class DepositPlan { public List<PlannedDeposit> Deposits { get; set; } = new List<PlannedDeposit>(); public int RequestedAmount { get; set; } public int PlannedAmount { get; set; } } public static class SearchService { public static SearchResult Filter(IReadOnlyList<AggregatedItem> items, string query) { if (items.Count == 0) { return new SearchResult(); } if (string.IsNullOrWhiteSpace(query)) { return new SearchResult { Items = items }; } string trimmed = query.Trim(); List<AggregatedItem> items2 = items.Where((AggregatedItem item) => item.DisplayName.IndexOf(trimmed, StringComparison.OrdinalIgnoreCase) >= 0).ToList(); return new SearchResult { Items = items2 }; } } public static class WithdrawPlanner { public static WithdrawPlan Plan(IReadOnlyList<SourceStack> sourceStacks, ItemKey key, int requestedAmount, int maxReceivable) { int val = Math.Max(0, requestedAmount); int num = Math.Max(0, Math.Min(val, maxReceivable)); int num2 = num; WithdrawPlan withdrawPlan = new WithdrawPlan { RequestedAmount = requestedAmount }; if (num2 <= 0) { return withdrawPlan; } foreach (SourceStack item in (from s in sourceStacks where s.Key.Equals(key) && s.Amount > 0 orderby s.Distance select s).ThenBy<SourceStack, string>((SourceStack s) => s.SourceId, StringComparer.Ordinal)) { if (num2 == 0) { break; } int num3 = Math.Min(item.Amount, num2); if (num3 > 0) { withdrawPlan.Takes.Add(new PlannedTake { SourceId = item.SourceId, Amount = num3 }); num2 -= num3; } } withdrawPlan.PlannedAmount = num - num2; return withdrawPlan; } } }
plugins\UnifiedStorage\UnifiedStorage.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using TMPro; using UnifiedStorage.Core; using UnifiedStorage.Mod.Config; using UnifiedStorage.Mod.Diagnostics; using UnifiedStorage.Mod.Domain; using UnifiedStorage.Mod.Models; using UnifiedStorage.Mod.Network; using UnifiedStorage.Mod.Patches; using UnifiedStorage.Mod.Pieces; using UnifiedStorage.Mod.Server; using UnifiedStorage.Mod.Session; using UnifiedStorage.Mod.Shared; using UnifiedStorage.Mod.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("UnifiedStorage")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5d7be5f6efeb56f9a845ddaab6e91dfa01032b38")] [assembly: AssemblyProduct("UnifiedStorage")] [assembly: AssemblyTitle("UnifiedStorage")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UnifiedStorage.Mod { [BepInPlugin("andre.valheim.unifiedstorage", "Unified Storage", "1.1.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class UnifiedStoragePlugin : BaseUnityPlugin { public const string PluginGuid = "andre.valheim.unifiedstorage"; public const string PluginName = "Unified Storage"; public const string PluginVersion = "1.1.5"; private const float WorldChangeRefreshMinInterval = 0.2f; private static bool _blockGameInput; private StorageConfig? _config; private StorageTrace? _trace; private Harmony? _harmony; private IContainerScanner? _scanner; private TerminalSessionService? _session; private TerminalAuthorityService? _authority; private TerminalRpcRoutes? _rpcRoutes; private UnifiedTerminalRegistrar? _pieceRegistrar; private TerminalUIManager? _ui; private bool _trackedInventoryDirty; private bool _isApplyingRefresh; private bool _wasDragging; private float _nextAllowedWorldRefreshAt; private string _lastSearch = string.Empty; private int _lastUiRevision = -1; private float _storagFullMessageCooldown; internal static UnifiedStoragePlugin? Instance { get; private set; } private void Awake() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown Instance = this; _config = new StorageConfig(((BaseUnityPlugin)this).Config); _trace = new StorageTrace(((BaseUnityPlugin)this).Logger, _config); _scanner = new ContainerScanner(_config); _authority = new TerminalAuthorityService(_scanner, ((BaseUnityPlugin)this).Logger); _rpcRoutes = new TerminalRpcRoutes(_authority, ((BaseUnityPlugin)this).Logger); _rpcRoutes.EnsureRegistered(); _session = new TerminalSessionService(_config, _scanner, _rpcRoutes, ((BaseUnityPlugin)this).Logger, _trace); _pieceRegistrar = new UnifiedTerminalRegistrar(_config, ((BaseUnityPlugin)this).Logger); _ui = new TerminalUIManager(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; _harmony = new Harmony("andre.valheim.unifiedstorage.patches"); _harmony.PatchAll(typeof(ContainerInteractPatch)); _harmony.PatchAll(typeof(InventoryAddItemPatch)); _harmony.PatchAll(typeof(InventoryAddItemAtPositionPatch)); _harmony.PatchAll(typeof(InventoryMoveItemToThisPatch)); _harmony.PatchAll(typeof(InventoryGuiHidePatch)); _harmony.PatchAll(typeof(InventoryGuiAwakePatch)); _harmony.PatchAll(typeof(InventoryGuiUpdatePatch)); _harmony.PatchAll(typeof(InventoryGridOnLeftClickPatch)); _harmony.PatchAll(typeof(InventoryGridOnRightClickPatch)); _harmony.PatchAll(typeof(InventoryGuiOnTakeAllPatch)); _harmony.PatchAll(typeof(InventoryGuiOnStackAllPatch)); _harmony.PatchAll(typeof(InventoryGuiOnDropOutsidePatch)); _harmony.PatchAll(typeof(InventoryChangedPatch)); _harmony.PatchAll(typeof(ZInputGetButtonPatch)); _harmony.PatchAll(typeof(ZInputGetButtonDownPatch)); _harmony.PatchAll(typeof(ZInputGetButtonUpPatch)); _harmony.PatchAll(typeof(ZInputGetKeyPatch)); _harmony.PatchAll(typeof(ZInputGetKeyDownPatch)); _harmony.PatchAll(typeof(ZInputGetKeyUpPatch)); _harmony.PatchAll(typeof(ChatHasFocusPatch)); _harmony.PatchAll(typeof(ContainerHoverTextPatch)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Unified Storage v1.1.5 loaded."); } private void Update() { _rpcRoutes?.EnsureRegistered(); _authority?.Tick(); _session?.Tick(); TryProcessWorldChangeRefresh(); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _session?.EndSession(); _blockGameInput = false; Instance = null; } private void OnVanillaPrefabsAvailable() { _pieceRegistrar?.RegisterPiece(); } internal void TryHandleChestInteract(Container container, Humanoid character) { if (_session != null) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && _session.HandleContainerInteract(container, val)) { _lastSearch = string.Empty; _ui?.ClearSearch(); } } } internal void OnInventoryGuiClosing() { _blockGameInput = false; _lastSearch = string.Empty; _trackedInventoryDirty = false; _isApplyingRefresh = false; _wasDragging = false; _lastUiRevision = -1; _session?.EndSession(); _ui?.Reset(); } internal void OnInventoryGuiAwake(InventoryGui gui) { _ui?.EnsureNativeUi(gui); } internal void OnInventoryGuiUpdate(InventoryGui gui) { if (_ui == null || _session == null) { return; } _ui.EnsureNativeUi(gui); _ui.UpdateChestInclusionToggle(gui); if (!_session.IsActive || !InventoryGui.IsVisible() || !gui.IsContainerOpen()) { _blockGameInput = false; _wasDragging = false; _ui.SetTakeAllButtonEnabled(gui, enabled: true); _ui.SetNativeUiVisible(visible: false); _ui.RestoreLayout(); _lastUiRevision = -1; return; } _ui.SetTakeAllButtonEnabled(gui, enabled: false); _ui.SetNativeUiVisible(visible: true); _ui.UpdateContainerName(gui); bool flag = ReflectionHelpers.IsDragInProgress(); if (flag && !_wasDragging) { OnContainerInteraction(); } _wasDragging = flag; _ui.ApplyExpandedLayout(gui, _session.ContentRows); if (_session.UiRevision != _lastUiRevision) { _lastUiRevision = _session.UiRevision; _ui.UpdateMetaText(_session.SlotsUsedDisplay, _session.SlotsTotalPhysical, _session.ChestsInRange); _ui.RefreshContainerGrid(gui); } _ui.UpdateSearchBinding(gui); UpdateSearchFocusState(); ProcessSearchChanges(gui); } internal static bool ShouldBlockGameInput() { return _blockGameInput; } internal bool IsUnifiedSessionActive() { if (_session != null) { return _session.IsActive; } return false; } internal bool ShouldBlockDeposit(Inventory targetInventory, ItemData? item = null) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (_session == null || !_session.IsActive || _session.IsApplyingProjection) { return false; } if (!_session.IsTerminalInventory(targetInventory)) { return false; } if ((Object)(object)item?.m_dropPrefab == (Object)null) { return _session.IsStorageFull; } ItemKey key = default(ItemKey); ((ItemKey)(ref key))..ctor(((Object)item.m_dropPrefab).name, item.m_quality, item.m_variant); if (_session.HasAnyCapacityFor(key)) { return false; } NotifyStorageFull(); return true; } private void NotifyStorageFull() { float unscaledTime = Time.unscaledTime; if (!(unscaledTime < _storagFullMessageCooldown)) { _storagFullMessageCooldown = unscaledTime + 2.5f; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "Storage is full.", 0, (Sprite)null); } } } internal int GetNearbyChestCount(Vector3 position) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (_scanner == null || _config == null) { return 0; } return _scanner.GetNearbyContainers(position, _config.ScanRadius.Value).Count; } internal void OnTrackedInventoryChanged(Inventory inventory) { if (!_isApplyingRefresh && _session != null && _session.IsActive && inventory != null && !_session.IsApplyingProjection && _session.IsTrackedInventory(inventory)) { _trackedInventoryDirty = true; } } internal void OnContainerInteraction() { if (_session != null && _session.IsActive && !((Object)(object)InventoryGui.instance == (Object)null)) { _trackedInventoryDirty = false; ExecuteSessionRefresh(delegate { _session.NotifyContainerInteraction(); }); _ui?.UpdateMetaText(_session.SlotsUsedDisplay, _session.SlotsTotalPhysical, _session.ChestsInRange); _ui?.RefreshContainerGrid(InventoryGui.instance); } } internal void OnInventoryGridInteraction(InventoryGrid grid) { if (_session != null && _session.IsActive && !((Object)(object)InventoryGui.instance == (Object)null) && !((Object)(object)grid == (Object)null)) { OnContainerInteraction(); } } private void ProcessSearchChanges(InventoryGui gui) { if (_ui != null && _session != null) { string searchText = _ui.SearchText; if (!string.Equals(searchText, _lastSearch, StringComparison.Ordinal)) { _lastSearch = searchText; _session.SetSearchQuery(_lastSearch); _ui.RefreshContainerGrid(gui); } } } private void UpdateSearchFocusState() { _blockGameInput = _ui != null && _ui.IsSearchFocused; } private void TryProcessWorldChangeRefresh() { if (_trackedInventoryDirty && _session != null && _session.IsActive && !((Object)(object)InventoryGui.instance == (Object)null) && InventoryGui.IsVisible() && InventoryGui.instance.IsContainerOpen() && !(Time.unscaledTime < _nextAllowedWorldRefreshAt) && !ReflectionHelpers.IsDragInProgress()) { _nextAllowedWorldRefreshAt = Time.unscaledTime + 0.2f; _trackedInventoryDirty = false; ExecuteSessionRefresh(delegate { _session.RefreshFromWorldChange(); }); _ui?.UpdateMetaText(_session.SlotsUsedDisplay, _session.SlotsTotalPhysical, _session.ChestsInRange); _ui?.RefreshContainerGrid(InventoryGui.instance); } } private void ExecuteSessionRefresh(Action refreshAction) { if (_isApplyingRefresh) { return; } _isApplyingRefresh = true; try { refreshAction(); } finally { _isApplyingRefresh = false; } } } } namespace UnifiedStorage.Mod.UI { public sealed class TerminalUIManager { private const int VisibleGridRows = 7; private const float FooterPanelBottomOffset = -70f; private const float FooterPanelHeight = 52f; private const float GridTopReserve = 124f; private const float ChestToggleTopOffset = -8f; private RectTransform? _nativeUiRoot; private TMP_Text? _metaText; private Image? _slotBarFill; private TMP_InputField? _searchInputField; private RectTransform? _chestToggleRoot; private Toggle? _chestIncludeToggle; private RectTransform? _containerRect; private Container? _boundChestForToggle; private Vector2 _originalContainerSize; private int _originalGridHeight; private Vector2 _originalGridOffsetMin; private Vector2 _originalGridOffsetMax; private bool _layoutCaptured; private bool _nativeBuilt; private bool _isApplyingChestToggle; private int _lastAppliedVisibleRows; public bool IsSearchFocused { get { if ((Object)(object)_searchInputField != (Object)null) { return _searchInputField.isFocused; } return false; } } public string SearchText { get { TMP_InputField? searchInputField = _searchInputField; return ((searchInputField != null) ? searchInputField.text : null) ?? string.Empty; } } public bool IsLayoutCaptured => _layoutCaptured; public event Action<string>? SearchValueChanged; public event Action<bool>? ChestToggleChanged; public void EnsureNativeUi(InventoryGui gui) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00bd: 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) if (!_nativeBuilt) { RectTransform containerRect = ReflectionHelpers.GetContainerRect(gui); if (!((Object)(object)containerRect == (Object)null)) { _containerRect = containerRect; TMP_Text containerName = ReflectionHelpers.GetContainerName(gui); GameObject val = new GameObject("US_NativePanel", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)containerRect, false); _nativeUiRoot = val.GetComponent<RectTransform>(); _nativeUiRoot.anchorMin = new Vector2(0f, 0f); _nativeUiRoot.anchorMax = new Vector2(1f, 0f); _nativeUiRoot.pivot = new Vector2(0.5f, 0f); _nativeUiRoot.anchoredPosition = new Vector2(0f, -70f); _nativeUiRoot.sizeDelta = new Vector2(0f, 52f); BuildSlotBar(val.transform, containerName); BuildSearchField(val.transform, containerName); EnsureChestToggleUi(containerRect, containerName); _nativeBuilt = true; SetNativeUiVisible(visible: false); SetChestToggleVisible(visible: false); } } } private void BuildSlotBar(Transform parent, TMP_Text? containerName) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00fe: Expected O, but got Unknown //IL_0121: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) float num = 20f; GameObject val = new GameObject("US_SlotBarBg", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, 0f); component.sizeDelta = new Vector2(-16f, num); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)component2).raycastTarget = false; GameObject val2 = new GameObject("US_SlotBarFill", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 0.5f); component3.offsetMin = new Vector2(2f, 2f); component3.offsetMax = new Vector2(2f, -2f); _slotBarFill = val2.GetComponent<Image>(); ((Graphic)_slotBarFill).color = new Color(0.85f, 0.75f, 0.2f, 0.85f); ((Graphic)_slotBarFill).raycastTarget = false; GameObject val3 = new GameObject("US_SlotLabel", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val3.transform.SetParent(val.transform, false); RectTransform component4 = val3.GetComponent<RectTransform>(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.offsetMin = new Vector2(6f, 0f); component4.offsetMax = new Vector2(-6f, 0f); _metaText = (TMP_Text?)(object)val3.GetComponent<TextMeshProUGUI>(); if ((Object)(object)containerName != (Object)null) { _metaText.font = containerName.font; _metaText.fontSharedMaterial = containerName.fontSharedMaterial; } _metaText.fontSize = 14f; ((Graphic)_metaText).color = new Color(1f, 1f, 1f, 0.95f); _metaText.alignment = (TextAlignmentOptions)514; ((Graphic)_metaText).raycastTarget = false; } private void BuildSearchField(Transform parent, TMP_Text? containerName) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0048: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: 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_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) float num = 22f; float num2 = -24f; GameObject val = new GameObject("US_SearchRow", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, num2); component.sizeDelta = new Vector2(-16f, num); GameObject val2 = new GameObject("US_SearchInput", new Type[3] { typeof(RectTransform), typeof(Image), typeof(TMP_InputField) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; ((Graphic)val2.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f); _searchInputField = val2.GetComponent<TMP_InputField>(); GameObject val3 = new GameObject("Viewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val3.transform.SetParent(val2.transform, false); RectTransform component3 = val3.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(8f, 2f); component3.offsetMax = new Vector2(-8f, -2f); GameObject val4 = new GameObject("Text", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val4.transform.SetParent(val3.transform, false); RectTransform component4 = val4.GetComponent<RectTransform>(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.offsetMin = Vector2.zero; component4.offsetMax = Vector2.zero; TextMeshProUGUI component5 = val4.GetComponent<TextMeshProUGUI>(); if ((Object)(object)containerName != (Object)null) { ((TMP_Text)component5).font = containerName.font; ((TMP_Text)component5).fontSharedMaterial = containerName.fontSharedMaterial; } ((TMP_Text)component5).fontSize = 14f; ((Graphic)component5).color = new Color(1f, 1f, 1f, 0.9f); ((TMP_Text)component5).alignment = (TextAlignmentOptions)4097; GameObject val5 = new GameObject("Placeholder", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val5.transform.SetParent(val3.transform, false); RectTransform component6 = val5.GetComponent<RectTransform>(); component6.anchorMin = Vector2.zero; component6.anchorMax = Vector2.one; component6.offsetMin = Vector2.zero; component6.offsetMax = Vector2.zero; TextMeshProUGUI component7 = val5.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component7).text = "Search items..."; if ((Object)(object)containerName != (Object)null) { ((TMP_Text)component7).font = containerName.font; ((TMP_Text)component7).fontSharedMaterial = containerName.fontSharedMaterial; } ((TMP_Text)component7).fontSize = 13f; ((Graphic)component7).color = new Color(1f, 1f, 1f, 0.35f); ((TMP_Text)component7).alignment = (TextAlignmentOptions)4097; ((TMP_Text)component7).fontStyle = (FontStyles)2; _searchInputField.textViewport = component3; _searchInputField.textComponent = (TMP_Text)(object)component5; _searchInputField.placeholder = (Graphic)(object)component7; _searchInputField.lineType = (LineType)0; ((UnityEvent<string>)(object)_searchInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { this.SearchValueChanged?.Invoke(value ?? string.Empty); }); } private void EnsureChestToggleUi(RectTransform container, TMP_Text? containerName) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00bf: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_chestToggleRoot != (Object)null) || !((Object)(object)_chestIncludeToggle != (Object)null)) { GameObject val = new GameObject("US_ChestIncludeToggle", new Type[2] { typeof(RectTransform), typeof(Toggle) }); val.transform.SetParent((Transform)(object)container, false); _chestToggleRoot = val.GetComponent<RectTransform>(); _chestToggleRoot.anchorMin = new Vector2(1f, 1f); _chestToggleRoot.anchorMax = new Vector2(1f, 1f); _chestToggleRoot.pivot = new Vector2(1f, 1f); _chestToggleRoot.anchoredPosition = new Vector2(-14f, -8f); _chestToggleRoot.sizeDelta = new Vector2(190f, 20f); Toggle component = val.GetComponent<Toggle>(); ((Selectable)component).transition = (Transition)0; component.isOn = true; _chestIncludeToggle = component; GameObject val2 = new GameObject("Background", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(val.transform, false); RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0.5f); component2.anchorMax = new Vector2(0f, 0.5f); component2.pivot = new Vector2(0f, 0.5f); component2.anchoredPosition = Vector2.zero; component2.sizeDelta = new Vector2(16f, 16f); Image component3 = val2.GetComponent<Image>(); ((Graphic)component3).color = new Color(0f, 0f, 0f, 0.62f); GameObject val3 = new GameObject("Checkmark", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform component4 = val3.GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.5f, 0.5f); component4.anchorMax = new Vector2(0.5f, 0.5f); component4.pivot = new Vector2(0.5f, 0.5f); component4.anchoredPosition = Vector2.zero; component4.sizeDelta = new Vector2(11f, 11f); Image component5 = val3.GetComponent<Image>(); ((Graphic)component5).color = new Color(0.82f, 0.93f, 0.66f, 1f); GameObject val4 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val4.transform.SetParent(val.transform, false); RectTransform component6 = val4.GetComponent<RectTransform>(); component6.anchorMin = new Vector2(0f, 0.5f); component6.anchorMax = new Vector2(1f, 0.5f); component6.pivot = new Vector2(0f, 0.5f); component6.anchoredPosition = new Vector2(22f, 0f); component6.sizeDelta = new Vector2(-22f, 18f); TextMeshProUGUI component7 = val4.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component7).text = "Include In Unified"; if ((Object)(object)containerName != (Object)null) { ((TMP_Text)component7).font = containerName.font; ((TMP_Text)component7).fontSize = containerName.fontSize * 0.52f; ((Graphic)component7).color = ((Graphic)containerName).color; ((TMP_Text)component7).fontSharedMaterial = containerName.fontSharedMaterial; } else { ((TMP_Text)component7).fontSize = 14f; ((Graphic)component7).color = Color.white; } ((TMP_Text)component7).alignment = (TextAlignmentOptions)4097; ((Selectable)component).targetGraphic = (Graphic)(object)component3; component.graphic = (Graphic)(object)component5; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)OnChestIncludeToggleChanged); } } public void UpdateChestInclusionToggle(InventoryGui gui) { if ((Object)(object)_chestToggleRoot == (Object)null || (Object)(object)_chestIncludeToggle == (Object)null || !InventoryGui.IsVisible() || !gui.IsContainerOpen()) { _boundChestForToggle = null; SetChestToggleVisible(visible: false); return; } Container currentContainer = ReflectionHelpers.GetCurrentContainer(gui); if ((Object)(object)currentContainer == (Object)null || UnifiedTerminal.IsTerminal(currentContainer)) { _boundChestForToggle = null; SetChestToggleVisible(visible: false); return; } SetChestToggleVisible(visible: true); bool flag = ChestInclusionRules.IsIncludedInUnified(currentContainer); if (_boundChestForToggle != currentContainer || _chestIncludeToggle.isOn != flag) { _isApplyingChestToggle = true; _chestIncludeToggle.isOn = flag; _isApplyingChestToggle = false; _boundChestForToggle = currentContainer; } } private void OnChestIncludeToggleChanged(bool includeInUnified) { if (!_isApplyingChestToggle) { InventoryGui instance = InventoryGui.instance; Container val = (((Object)(object)instance != (Object)null) ? ReflectionHelpers.GetCurrentContainer(instance) : null); if (!((Object)(object)val == (Object)null) && !UnifiedTerminal.IsTerminal(val)) { ChestInclusionRules.TrySetIncludedInUnified(val, includeInUnified); this.ChestToggleChanged?.Invoke(includeInUnified); } } } public void UpdateContainerName(InventoryGui gui) { TMP_Text containerName = ReflectionHelpers.GetContainerName(gui); if ((Object)(object)containerName != (Object)null && !string.Equals(containerName.text, "Storage Interface", StringComparison.Ordinal)) { containerName.text = "Storage Interface"; } } public void UpdateMetaText(int slotsUsed, int slotsTotal, int chestCount) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_metaText != (Object)null) { _metaText.text = $"{slotsUsed} / {slotsTotal}"; } if ((Object)(object)_slotBarFill != (Object)null) { float num = ((slotsTotal > 0) ? Mathf.Clamp01((float)slotsUsed / (float)slotsTotal) : 0f); Transform parent = ((Component)_slotBarFill).transform.parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); float num2; if (!((Object)(object)val != (Object)null)) { num2 = 100f; } else { Rect rect = val.rect; num2 = ((Rect)(ref rect)).width - 4f; } float num3 = num2; ((Component)_slotBarFill).GetComponent<RectTransform>().sizeDelta = new Vector2(num3 * num, 0f); if (num >= 0.95f) { ((Graphic)_slotBarFill).color = new Color(0.85f, 0.25f, 0.2f, 0.85f); } else if (num >= 0.75f) { ((Graphic)_slotBarFill).color = new Color(0.9f, 0.6f, 0.15f, 0.85f); } else { ((Graphic)_slotBarFill).color = new Color(0.85f, 0.75f, 0.2f, 0.85f); } } } public void UpdateSearchBinding(InventoryGui gui) { if (!((Object)(object)_searchInputField == (Object)null) && _searchInputField.isFocused && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271) || Input.GetKeyDown((KeyCode)27))) { _searchInputField.DeactivateInputField(false); } } public void ClearSearch() { if ((Object)(object)_searchInputField != (Object)null) { _searchInputField.text = string.Empty; } } public void ApplyExpandedLayout(InventoryGui gui, int contentRows) { //IL_002f: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_containerRect == (Object)null) { return; } InventoryGrid containerGrid = ReflectionHelpers.GetContainerGrid(gui); if ((Object)(object)containerGrid == (Object)null) { return; } if (!_layoutCaptured) { _originalContainerSize = _containerRect.sizeDelta; _originalGridHeight = ReflectionHelpers.GetGridHeight(containerGrid); RectTransform gridRoot = ReflectionHelpers.GetGridRoot(containerGrid); if ((Object)(object)gridRoot != (Object)null) { _originalGridOffsetMin = gridRoot.offsetMin; _originalGridOffsetMax = gridRoot.offsetMax; } _layoutCaptured = true; _lastAppliedVisibleRows = -1; } int num = Math.Max(1, Math.Min(contentRows, 7)); if (num != _lastAppliedVisibleRows) { _lastAppliedVisibleRows = num; ReflectionHelpers.SetGridHeight(containerGrid, num); float gridElementSpace = ReflectionHelpers.GetGridElementSpace(containerGrid); GameObject gridElementPrefab = ReflectionHelpers.GetGridElementPrefab(containerGrid); float num2 = 64f; RectTransform val = default(RectTransform); if ((Object)(object)gridElementPrefab != (Object)null && gridElementPrefab.TryGetComponent<RectTransform>(ref val)) { num2 = val.sizeDelta.y; } int num3 = Math.Max(0, num - _originalGridHeight); float num4 = (num2 + gridElementSpace) * (float)num3; _containerRect.sizeDelta = new Vector2(_originalContainerSize.x, _originalContainerSize.y + num4); RectTransform gridRoot2 = ReflectionHelpers.GetGridRoot(containerGrid); if ((Object)(object)gridRoot2 != (Object)null) { gridRoot2.offsetMax = new Vector2(_originalGridOffsetMax.x, -124f); gridRoot2.offsetMin = _originalGridOffsetMin; } } } public void RestoreLayout() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!_layoutCaptured || (Object)(object)InventoryGui.instance == (Object)null) { return; } InventoryGrid containerGrid = ReflectionHelpers.GetContainerGrid(InventoryGui.instance); if ((Object)(object)containerGrid != (Object)null) { ReflectionHelpers.SetGridHeight(containerGrid, _originalGridHeight); RectTransform gridRoot = ReflectionHelpers.GetGridRoot(containerGrid); if ((Object)(object)gridRoot != (Object)null) { gridRoot.offsetMin = _originalGridOffsetMin; gridRoot.offsetMax = _originalGridOffsetMax; } Inventory inventory = containerGrid.GetInventory(); if (inventory != null) { containerGrid.UpdateInventory(inventory, Player.m_localPlayer, (ItemData)null); } } if ((Object)(object)_containerRect != (Object)null) { _containerRect.sizeDelta = _originalContainerSize; } _layoutCaptured = false; _lastAppliedVisibleRows = -1; } public void RefreshContainerGrid(InventoryGui gui) { InventoryGrid containerGrid = ReflectionHelpers.GetContainerGrid(gui); if (!((Object)(object)containerGrid == (Object)null)) { Inventory inventory = containerGrid.GetInventory(); if (inventory != null) { containerGrid.UpdateInventory(inventory, Player.m_localPlayer, (ItemData)null); } } } public void SetNativeUiVisible(bool visible) { if ((Object)(object)_nativeUiRoot != (Object)null) { ((Component)_nativeUiRoot).gameObject.SetActive(visible); } } public void SetChestToggleVisible(bool visible) { if ((Object)(object)_chestToggleRoot != (Object)null) { ((Component)_chestToggleRoot).gameObject.SetActive(visible); } } public void SetTakeAllButtonEnabled(InventoryGui gui, bool enabled) { Button takeAllButton = ReflectionHelpers.GetTakeAllButton(gui); if ((Object)(object)takeAllButton != (Object)null) { ((Selectable)takeAllButton).interactable = enabled; } } public void Reset() { ClearSearch(); _boundChestForToggle = null; SetNativeUiVisible(visible: false); SetChestToggleVisible(visible: false); RestoreLayout(); } } } namespace UnifiedStorage.Mod.Shared { public sealed class DrawerSnapshot { public string SourceId { get; set; } = string.Empty; public ZNetView ZNetView { get; set; } public string Prefab { get; set; } = string.Empty; public int Amount { get; set; } public int Quality { get; set; } public Vector3 Position { get; set; } } public static class ItemDrawersApi { private static bool _initialized; private static bool _available; private static MethodInfo? _allDrawersMethod; public static bool IsAvailable { get { EnsureInitialized(); return _available; } } private static void EnsureInitialized() { if (!_initialized) { _initialized = true; Type type = Type.GetType("API.ClientSideV2, kg_ItemDrawers"); if (type == null) { _available = false; return; } _allDrawersMethod = type.GetMethod("AllDrawers", BindingFlags.Static | BindingFlags.Public); _available = _allDrawersMethod != null; } } public static List<DrawerSnapshot> GetAllDrawers() { EnsureInitialized(); if (!_available || _allDrawersMethod == null) { return new List<DrawerSnapshot>(); } if (!(_allDrawersMethod.Invoke(null, null) is IEnumerable<ZNetView> enumerable)) { return new List<DrawerSnapshot>(); } List<DrawerSnapshot> list = new List<DrawerSnapshot>(); foreach (ZNetView item in enumerable) { DrawerSnapshot drawerSnapshot = TryBuildSnapshot(item); if (drawerSnapshot != null) { list.Add(drawerSnapshot); } } return list; } public static List<DrawerSnapshot> GetDrawersInRange(Vector3 center, float radius) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_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) List<DrawerSnapshot> allDrawers = GetAllDrawers(); float num = radius * radius; List<DrawerSnapshot> list = new List<DrawerSnapshot>(); foreach (DrawerSnapshot item in allDrawers) { Vector3 val = item.Position - center; if (((Vector3)(ref val)).sqrMagnitude <= num) { list.Add(item); } } return list; } public static void AddToDrawer(DrawerSnapshot snapshot, string prefab, int amount, int quality) { if (!((Object)(object)snapshot.ZNetView == (Object)null)) { snapshot.ZNetView.InvokeRPC("AddItem_Request", new object[3] { prefab, amount, quality }); } } public static void ForceRemoveFromDrawer(DrawerSnapshot snapshot, int amount) { if (!((Object)(object)snapshot.ZNetView == (Object)null)) { snapshot.ZNetView.ClaimOwnership(); snapshot.ZNetView.InvokeRPC("ForceRemove", new object[1] { amount }); } } private static DrawerSnapshot? TryBuildSnapshot(ZNetView znv) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)znv == (Object)null) { return null; } ZDO zDO = znv.GetZDO(); if (zDO == null) { return null; } return new DrawerSnapshot { SourceId = ((object)(ZDOID)(ref zDO.m_uid)).ToString(), ZNetView = znv, Prefab = zDO.GetString("Prefab", ""), Amount = zDO.GetInt("Amount", 0), Quality = zDO.GetInt("Quality", 1), Position = ((Component)znv).transform.position }; } catch { return null; } } } public static class ReflectionHelpers { private static readonly FieldInfo? InventoryWidthField = typeof(Inventory).GetField("m_width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? InventoryHeightField = typeof(Inventory).GetField("m_height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo? InventoryGetWidthMethod = typeof(Inventory).GetMethod("GetWidth", BindingFlags.Instance | BindingFlags.Public); private static readonly MethodInfo? InventoryGetHeightMethod = typeof(Inventory).GetMethod("GetHeight", BindingFlags.Instance | BindingFlags.Public); private static readonly MethodInfo? ContainerCheckAccessMethod = typeof(Container).GetMethod("CheckAccess", BindingFlags.Instance | BindingFlags.Public); private static readonly FieldInfo? ContainerNameField = typeof(Container).GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo? ContainerSetInUseMethod = typeof(Container).GetMethod("SetInUse", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null); private static readonly FieldInfo? ContainerInUseField = typeof(Container).GetField("m_inUse", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? DragItemField = typeof(InventoryGui).GetField("m_dragItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? ContainerRectField = AccessTools.Field(typeof(InventoryGui), "m_container"); private static readonly FieldInfo? CurrentContainerField = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); private static readonly FieldInfo? ContainerGridField = AccessTools.Field(typeof(InventoryGui), "m_containerGrid"); private static readonly FieldInfo? ContainerNameTextField = AccessTools.Field(typeof(InventoryGui), "m_containerName"); private static readonly FieldInfo? TakeAllButtonField = AccessTools.Field(typeof(InventoryGui), "m_takeAllButton"); private static readonly FieldInfo? GridRootField = AccessTools.Field(typeof(InventoryGrid), "m_gridRoot"); private static readonly FieldInfo? GridHeightField = AccessTools.Field(typeof(InventoryGrid), "m_height"); private static readonly FieldInfo? GridElementPrefabField = AccessTools.Field(typeof(InventoryGrid), "m_elementPrefab"); private static readonly FieldInfo? GridElementSpaceField = AccessTools.Field(typeof(InventoryGrid), "m_elementSpace"); private static readonly FieldInfo? InventoryItemListField = AccessTools.Field(typeof(Inventory), "m_inventory"); private static readonly MethodInfo? InventoryChangedMethod = typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo?[] DropItemMethods = (from m in typeof(ItemDrop).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where string.Equals(m.Name, "DropItem", StringComparison.Ordinal) select m).ToArray(); public static int GetInventoryWidth(Inventory inventory) { object obj; if (InventoryGetWidthMethod != null) { obj = InventoryGetWidthMethod.Invoke(inventory, null); if (obj is int) { return (int)obj; } } obj = InventoryWidthField?.GetValue(inventory); if (obj is int) { return (int)obj; } return 1; } public static int GetInventoryHeight(Inventory inventory) { object obj; if (InventoryGetHeightMethod != null) { obj = InventoryGetHeightMethod.Invoke(inventory, null); if (obj is int) { return (int)obj; } } obj = InventoryHeightField?.GetValue(inventory); if (obj is int) { return (int)obj; } return 1; } public static void SetInventorySize(Inventory inventory, int width, int height) { InventoryWidthField?.SetValue(inventory, width); InventoryHeightField?.SetValue(inventory, height); } public static bool CanAccess(Container container, Player player) { if (ContainerCheckAccessMethod == null) { return true; } ParameterInfo[] parameters = ContainerCheckAccessMethod.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(long)) { return (bool)ContainerCheckAccessMethod.Invoke(container, new object[1] { player.GetPlayerID() }); } if (parameters.Length == 0) { return (bool)ContainerCheckAccessMethod.Invoke(container, null); } return true; } public static void SetContainerDisplayName(Container container, string displayName) { if (ContainerNameField?.FieldType == typeof(string)) { ContainerNameField.SetValue(container, displayName); } } public static void ForceReleaseContainerUse(Container container) { try { ContainerSetInUseMethod?.Invoke(container, new object[1] { false }); } catch { } try { if (ContainerInUseField?.FieldType == typeof(bool)) { ContainerInUseField.SetValue(container, false); } } catch { } } public static string BuildContainerUid(Container container) { ZNetView component = ((Component)container).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null) { return ((Object)container).GetInstanceID().ToString(); } return ((object)(ZDOID)(ref val.m_uid)).ToString(); } public static bool MatchKey(ItemData item, ItemKey key) { if ((Object)(object)item?.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == ((ItemKey)(ref key)).PrefabName && item.m_quality == ((ItemKey)(ref key)).Quality && item.m_variant == ((ItemKey)(ref key)).Variant) { return item.m_stack > 0; } return false; } public static int GetTotalAmount(Inventory inventory, ItemKey key) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (MatchKey(allItem, key)) { num += allItem.m_stack; } } return num; } public static int TryAddItemMeasured(Inventory inventory, ItemKey key, ItemData stack, int requestedAmount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) int totalAmount = GetTotalAmount(inventory, key); inventory.AddItem(stack); int totalAmount2 = GetTotalAmount(inventory, key); return ChunkedTransfer.ClampMeasuredMove(requestedAmount, totalAmount, totalAmount2); } public static ItemData? CreateItemStack(ItemKey key, int amount) { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(((ItemKey)(ref key)).PrefabName) : null); ItemDrop val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); if (val?.m_itemData == null) { return null; } ItemData obj2 = val.m_itemData.Clone(); obj2.m_quality = ((ItemKey)(ref key)).Quality; obj2.m_variant = ((ItemKey)(ref key)).Variant; obj2.m_stack = amount; return obj2; } public static int GetMaxStackSize(ItemKey key) { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(((ItemKey)(ref key)).PrefabName) : null); return (((obj != null) ? obj.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_maxStackSize).GetValueOrDefault(1); } public static int ResolveMaxStackSize(string prefabName) { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(prefabName) : null); return (((obj != null) ? obj.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_maxStackSize).GetValueOrDefault(1); } public static bool TryDropItem(ItemData item, int amount, Vector3 position, Quaternion rotation) { //IL_0131: 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) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) MethodInfo[] dropItemMethods = DropItemMethods; foreach (MethodInfo methodInfo in dropItemMethods) { if (methodInfo == null) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); try { if (parameters.Length == 4 && parameters[0].ParameterType == typeof(ItemData) && parameters[1].ParameterType == typeof(int) && parameters[2].ParameterType == typeof(Vector3) && parameters[3].ParameterType == typeof(Quaternion)) { methodInfo.Invoke(null, new object[4] { item, amount, position, rotation }); return true; } if (parameters.Length == 3 && parameters[0].ParameterType == typeof(ItemData) && parameters[1].ParameterType == typeof(int) && parameters[2].ParameterType == typeof(Vector3)) { methodInfo.Invoke(null, new object[3] { item, amount, position }); return true; } } catch { } } return false; } public static int GetSubgroupOrder(ItemKey key) { if (string.IsNullOrWhiteSpace(((ItemKey)(ref key)).PrefabName)) { return 999; } string text = ((ItemKey)(ref key)).PrefabName.ToLowerInvariant(); if (text.Contains("ore") || text.Contains("scrap") || text.Contains("metal") || text.Contains("ingot") || text.Contains("bar")) { return 10; } if (text.Contains("wood") || text.Contains("stone")) { return 20; } if (text.Contains("hide") || text.Contains("leather") || text.Contains("scale") || text.Contains("chitin")) { return 30; } if (text.Contains("food") || text.Contains("mead") || text.Contains("stew") || text.Contains("soup") || text.Contains("bread")) { return 40; } return 100; } public static List<ItemData>? GetInventoryItemList(Inventory inventory) { return InventoryItemListField?.GetValue(inventory) as List<ItemData>; } public static void AddItemDirectly(Inventory inventory, ItemData item, int x, int y) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) item.m_gridPos = new Vector2i(x, y); List<ItemData> inventoryItemList = GetInventoryItemList(inventory); if (inventoryItemList != null) { inventoryItemList.Add(item); } else { inventory.AddItem(item); } } public static void NotifyInventoryChanged(Inventory inventory) { InventoryChangedMethod?.Invoke(inventory, null); } public static void ClearInventory(Inventory? inventory) { if (inventory == null) { return; } MethodInfo method = typeof(Inventory).GetMethod("RemoveAll", BindingFlags.Instance | BindingFlags.Public); if (method != null) { method.Invoke(inventory, null); return; } foreach (ItemData item in inventory.GetAllItems().ToList()) { inventory.RemoveItem(item, item.m_stack); } } public static bool IsDragInProgress() { if ((Object)(object)InventoryGui.instance == (Object)null || DragItemField == null) { return false; } object? value = DragItemField.GetValue(InventoryGui.instance); ItemData val = (ItemData)((value is ItemData) ? value : null); if (val != null) { return val.m_stack > 0; } return false; } public static RectTransform? GetContainerRect(InventoryGui gui) { object? obj = ContainerRectField?.GetValue(gui); return (RectTransform?)((obj is RectTransform) ? obj : null); } public static Container? GetCurrentContainer(InventoryGui gui) { object? obj = CurrentContainerField?.GetValue(gui); return (Container?)((obj is Container) ? obj : null); } public static InventoryGrid? GetContainerGrid(InventoryGui gui) { object? obj = ContainerGridField?.GetValue(gui); return (InventoryGrid?)((obj is InventoryGrid) ? obj : null); } public static TMP_Text? GetContainerName(InventoryGui gui) { object? obj = ContainerNameTextField?.GetValue(gui); return (TMP_Text?)((obj is TMP_Text) ? obj : null); } public static Button? GetTakeAllButton(InventoryGui gui) { object? obj = TakeAllButtonField?.GetValue(gui); return (Button?)((obj is Button) ? obj : null); } public static RectTransform? GetGridRoot(InventoryGrid grid) { object? obj = GridRootField?.GetValue(grid); return (RectTransform?)((obj is RectTransform) ? obj : null); } public static int GetGridHeight(InventoryGrid grid) { object obj = GridHeightField?.GetValue(grid); if (obj is int) { return (int)obj; } return 4; } public static void SetGridHeight(InventoryGrid grid, int height) { GridHeightField?.SetValue(grid, height); } public static float GetGridElementSpace(InventoryGrid grid) { object obj = GridElementSpaceField?.GetValue(grid); if (obj is float) { return (float)obj; } return 2f; } public static GameObject? GetGridElementPrefab(InventoryGrid grid) { object? obj = GridElementPrefabField?.GetValue(grid); return (GameObject?)((obj is GameObject) ? obj : null); } } } namespace UnifiedStorage.Mod.Session { public sealed class TerminalSessionService { private sealed class PendingReservation { public string TokenId { get; set; } = string.Empty; public ItemKey Key { get; set; } public int ReservedAmount { get; set; } public float ExpiresAt { get; set; } public bool CommitRequested { get; set; } } private sealed class PendingDeposit { public string RequestId { get; set; } = string.Empty; public ItemKey Key { get; set; } public int Amount { get; set; } } private struct CachedSortEntry { public string DisplayName; public int TypeOrder; public int SubgroupOrder; } private const float CloseGraceSeconds = 0.35f; private const float ReservationTtlSeconds = 3f; private const float TrackedChestRefreshSeconds = 1f; private const float OpenSessionRetryBaseSeconds = 0.5f; private const float OpenSessionRetryMaxSeconds = 8f; private readonly StorageConfig _config; private readonly IContainerScanner _scanner; private readonly TerminalRpcRoutes _routes; private readonly ManualLogSource _logger; private readonly StorageTrace _trace; private readonly Dictionary<ItemKey, int> _authoritativeTotals = new Dictionary<ItemKey, int>(); private readonly Dictionary<ItemKey, int> _displayedTotals = new Dictionary<ItemKey, int>(); private readonly Dictionary<ItemKey, ItemData> _prototypes = new Dictionary<ItemKey, ItemData>(); private readonly Dictionary<ItemKey, int> _stackSizes = new Dictionary<ItemKey, int>(); private readonly List<PendingReservation> _pendingReservations = new List<PendingReservation>(); private readonly List<PendingDeposit> _pendingDeposits = new List<PendingDeposit>(); private readonly Dictionary<ItemKey, CachedSortEntry> _sortCache = new Dictionary<ItemKey, CachedSortEntry>(); private List<KeyValuePair<ItemKey, int>> _sortedItems = new List<KeyValuePair<ItemKey, int>>(); private long _lastProjectedContentHash; private Container? _terminal; private Player? _player; private List<ChestHandle> _trackedChests = new List<ChestHandle>(); private string _sessionId = string.Empty; private string _terminalUid = string.Empty; private string _searchQuery = string.Empty; private float _scanRadius; private float _pendingCloseSince = -1f; private float _nextTrackedChestRefreshAt; private float _nextSnapshotRetryAt; private bool _isApplyingProjection; private bool _hasAuthoritativeSnapshot; private int _slotsTotalPhysical; private int _slotsUsedDisplay; private int _chestCount; private long _revision; private int _openSessionFailureCount; private int _originalInventoryWidth; private int _originalInventoryHeight; private int _contentRows; private int _uiRevision; public bool IsActive { get { if ((Object)(object)_terminal != (Object)null) { return (Object)(object)_player != (Object)null; } return false; } } public bool IsApplyingProjection => _isApplyingProjection; public int SlotsTotalPhysical => _slotsTotalPhysical; public int SlotsUsedDisplay => _slotsUsedDisplay; public int ChestsInRange => _chestCount; public int UiRevision => _uiRevision; public int ContentRows => _contentRows; public bool IsStorageFull { get { if (_slotsTotalPhysical > 0) { return _slotsUsedDisplay >= _slotsTotalPhysical; } return false; } } public int SlotsUsedVirtual { get { //IL_002a: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (KeyValuePair<ItemKey, int> authoritativeTotal in _authoritativeTotals) { if (authoritativeTotal.Value > 0) { int value; int num2 = ((!_stackSizes.TryGetValue(authoritativeTotal.Key, out value) || value <= 0) ? 1 : value); num += (int)Math.Ceiling((double)authoritativeTotal.Value / (double)num2); } } return num; } } public TerminalSessionService(StorageConfig config, IContainerScanner scanner, TerminalRpcRoutes routes, ManualLogSource logger, StorageTrace trace) { _config = config; _scanner = scanner; _routes = routes; _logger = logger; _trace = trace; _routes.SessionSnapshotReceived += OnSessionSnapshotReceived; _routes.ReserveResultReceived += OnReserveResultReceived; _routes.ApplyResultReceived += OnApplyResultReceived; _routes.SessionDeltaReceived += OnSessionDeltaReceived; } public bool IsTerminalInventory(Inventory inventory) { if (!IsActive || (Object)(object)_terminal == (Object)null || inventory == null) { return false; } return inventory == _terminal.GetInventory(); } public bool HasDrawerPriorityFor(ItemKey key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return _trackedChests.Any((ChestHandle c) => c.Source.IsValid && c.Source.DepositPriority(key) == 0); } public bool HasAnyCapacityFor(ItemKey key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) int num = ReflectionHelpers.GetMaxStackSize(key); if (num <= 0) { num = 1; } foreach (ChestHandle trackedChest in _trackedChests) { if (trackedChest.Source.IsValid && trackedChest.Source.HasCapacityFor(key, num)) { return true; } } return false; } public bool IsTrackedInventory(Inventory inventory) { Inventory inventory2 = inventory; if (!IsActive || inventory2 == null || (Object)(object)_terminal == (Object)null) { return false; } Inventory inventory3 = _terminal.GetInventory(); if (inventory2 == inventory3) { return false; } return _trackedChests.Any((ChestHandle chest) => chest.Source.OwnsInventory(inventory2)); } public bool HandleContainerInteract(Container container, Player player) { if (!UnifiedTerminal.IsTerminal(container)) { return false; } BeginSession(container, player); return true; } public void BeginSession(Container terminal, Player player) { EndSession(); ReflectionHelpers.ForceReleaseContainerUse(terminal); _terminal = terminal; _player = player; _searchQuery = string.Empty; _sessionId = string.Empty; _terminalUid = ReflectionHelpers.BuildContainerUid(terminal); _pendingCloseSince = -1f; _scanRadius = _config.ScanRadius.Value; CaptureOriginalInventorySize(terminal.GetInventory()); _revision = 0L; _slotsTotalPhysical = 0; _slotsUsedDisplay = 0; _chestCount = 0; _hasAuthoritativeSnapshot = false; _openSessionFailureCount = 0; _nextSnapshotRetryAt = Time.unscaledTime; _pendingReservations.Clear(); _pendingDeposits.Clear(); _authoritativeTotals.Clear(); _displayedTotals.Clear(); _prototypes.Clear(); _stackSizes.Clear(); StorageTrace trace = _trace; Player? player2 = _player; trace.Dev(string.Format("Terminal opened by {0} (radius {1:0.0}m).", ((player2 != null) ? player2.GetPlayerName() : null) ?? "unknown", _scanRadius)); RefreshTrackedChestHandles(); RefreshTerminalInventoryFromAuthoritative(); RequestSessionSnapshot(); _uiRevision++; } public void Tick() { if (!IsActive || (Object)(object)_terminal == (Object)null) { return; } if ((Object)(object)InventoryGui.instance == (Object)null || !InventoryGui.IsVisible() || !InventoryGui.instance.IsContainerOpen()) { if (_pendingCloseSince < 0f) { _pendingCloseSince = Time.unscaledTime; } else if (Time.unscaledTime - _pendingCloseSince >= 0.35f) { EndSession(); } return; } _pendingCloseSince = -1f; if (Time.unscaledTime >= _nextTrackedChestRefreshAt) { RefreshTrackedChestHandles(); } if (!_hasAuthoritativeSnapshot && Time.unscaledTime >= _nextSnapshotRetryAt) { RequestSessionSnapshot(); } ExpireLocalReservations(); if (!ReflectionHelpers.IsDragInProgress()) { CommitPendingReservations(); } } public void SetSearchQuery(string query) { if (IsActive && !((Object)(object)_terminal == (Object)null)) { string text = query?.Trim() ?? string.Empty; if (!string.Equals(text, _searchQuery, StringComparison.Ordinal)) { _searchQuery = text; _lastProjectedContentHash = 0L; RefreshTerminalInventoryFromAuthoritative(); _uiRevision++; } } } public void NotifyContainerInteraction() { if (!IsActive || (Object)(object)_terminal == (Object)null) { return; } if (!IsSessionTerminal(_terminal)) { EndSession(); return; } Dictionary<ItemKey, int> dictionary = CaptureCurrentDisplayedTotals(); ApplyDisplayedDeltaAsOperations(dictionary); ReplaceDisplayedTotals(dictionary); if (!ReflectionHelpers.IsDragInProgress()) { CommitPendingReservations(); } } public void RefreshFromWorldChange() { if (IsActive && !((Object)(object)_terminal == (Object)null)) { if (!IsSessionTerminal(_terminal)) { EndSession(); } else { RequestSessionSnapshot(); } } } public void EndSession() { if (IsActive) { _trace.Dev("Terminal closed."); } if ((Object)(object)_terminal != (Object)null && !string.IsNullOrWhiteSpace(_terminalUid)) { _routes.RequestCloseSession(new CloseSessionRequestDto { RequestId = Guid.NewGuid().ToString("N"), SessionId = _sessionId, TerminalUid = _terminalUid, PlayerId = ResolveLocalPlayerId() }); } if ((Object)(object)_terminal != (Object)null) { ReflectionHelpers.ForceReleaseContainerUse(_terminal); ReflectionHelpers.ClearInventory(_terminal.GetInventory()); RestoreTerminalInventorySize(_terminal.GetInventory()); } _terminal = null; _player = null; _trackedChests.Clear(); _sessionId = string.Empty; _terminalUid = string.Empty; _searchQuery = string.Empty; _scanRadius = 0f; _pendingCloseSince = -1f; _nextTrackedChestRefreshAt = 0f; _nextSnapshotRetryAt = 0f; _pendingReservations.Clear(); _pendingDeposits.Clear(); _authoritativeTotals.Clear(); _displayedTotals.Clear(); _prototypes.Clear(); _stackSizes.Clear(); _sortCache.Clear(); _sortedItems.Clear(); _lastProjectedContentHash = 0L; _slotsTotalPhysical = 0; _slotsUsedDisplay = 0; _chestCount = 0; _revision = 0L; _hasAuthoritativeSnapshot = false; _openSessionFailureCount = 0; _contentRows = 0; _uiRevision++; } private void OnSessionSnapshotReceived(OpenSessionResponseDto response) { if (!IsActive) { return; } if (!response.Success) { if (IsIdentityFailure(response.Reason)) { EndSession(); return; } _openSessionFailureCount = Math.Min(_openSessionFailureCount + 1, 8); _nextSnapshotRetryAt = Time.unscaledTime + GetRetryDelay(_openSessionFailureCount); } else if (CanApplySnapshot(response.Snapshot)) { ApplySnapshot(response.Snapshot); } } private void OnReserveResultReceived(ReserveWithdrawResultDto result) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (IsActive && CanApplySnapshot(result.Snapshot)) { if (result.Success && !string.IsNullOrWhiteSpace(result.TokenId) && result.ReservedAmount > 0) { _trace.Dev($"Withdrew {result.ReservedAmount}x {GetDisplayName(result.Key)}."); _pendingReservations.Add(new PendingReservation { TokenId = result.TokenId, Key = result.Key, ReservedAmount = result.ReservedAmount, ExpiresAt = Time.unscaledTime + 3f }); } ApplySnapshot(result.Snapshot); } } private void OnApplyResultReceived(ApplyResultDto result) { if (!IsActive) { return; } if (string.Equals(result.OperationType, "deposit", StringComparison.Ordinal)) { HandleDepositResult(result); } if (string.Equals(result.OperationType, "commit", StringComparison.Ordinal)) { if (result.Success) { RemovePendingToken(result.TokenId); } else { MarkPendingCommitAsRetryable(result.TokenId); RequestSessionSnapshot(); } } else if (string.Equals(result.OperationType, "cancel", StringComparison.Ordinal) && !result.Success) { RemovePendingToken(result.TokenId); RequestSessionSnapshot(); } if (CanApplySnapshot(result.Snapshot)) { ApplySnapshot(result.Snapshot); } else if (!result.Success) { RequestSessionSnapshot(); } } private void OnSessionDeltaReceived(SessionDeltaDto delta) { if (IsActive && string.Equals(delta.TerminalUid, _terminalUid, StringComparison.Ordinal) && (string.IsNullOrWhiteSpace(delta.SessionId) || string.IsNullOrWhiteSpace(_sessionId) || string.Equals(delta.SessionId, _sessionId, StringComparison.Ordinal)) && delta.Revision >= _revision) { ApplySnapshot(delta.Snapshot); } } private bool CanApplySnapshot(SessionSnapshotDto snapshot) { if (!IsActive || (Object)(object)_terminal == (Object)null) { return false; } if (!string.Equals(snapshot.TerminalUid, _terminalUid, StringComparison.Ordinal)) { return false; } if (!string.IsNullOrWhiteSpace(snapshot.SessionId) && !string.IsNullOrWhiteSpace(_sessionId) && !string.Equals(snapshot.SessionId, _sessionId, StringComparison.Ordinal)) { return false; } return true; } private void ApplySnapshot(SessionSnapshotDto snapshot) { //IL_00ce: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_0192: Unknown result type (might be due to invalid IL or missing references) if (!CanApplySnapshot(snapshot) || snapshot.Revision < _revision) { return; } if (!string.IsNullOrWhiteSpace(snapshot.SessionId)) { _sessionId = snapshot.SessionId; } _revision = snapshot.Revision; _slotsTotalPhysical = snapshot.SlotsTotalPhysical; _slotsUsedDisplay = snapshot.SlotsUsedVirtual; _chestCount = snapshot.ChestCount; _hasAuthoritativeSnapshot = true; _openSessionFailureCount = 0; _nextSnapshotRetryAt = Time.unscaledTime + 60f; int count = _authoritativeTotals.Count; _authoritativeTotals.Clear(); _stackSizes.Clear(); foreach (AggregatedItem item in snapshot.Items) { if (item.TotalAmount <= 0) { continue; } _authoritativeTotals[item.Key] = item.TotalAmount; _stackSizes[item.Key] = ((item.StackSize <= 0) ? 1 : item.StackSize); if (!_prototypes.ContainsKey(item.Key)) { ObjectDB instance = ObjectDB.instance; object obj; ItemKey key; if (instance == null) { obj = null; } else { key = item.Key; obj = instance.GetItemPrefab(((ItemKey)(ref key)).PrefabName); } ItemDrop val = ((obj != null) ? ((GameObject)obj).GetComponent<ItemDrop>() : null); if (val?.m_itemData != null) { ItemData val2 = val.m_itemData.Clone(); key = item.Key; val2.m_quality = ((ItemKey)(ref key)).Quality; key = item.Key; val2.m_variant = ((ItemKey)(ref key)).Variant; _prototypes[item.Key] = val2; } } } if (_authoritativeTotals.Count != count) { _sortCache.Clear(); } _trace.Dev($"Storage updated: {_chestCount} chest(s), {_authoritativeTotals.Count} item type(s)."); RefreshTrackedChestHandles(); RefreshTerminalInventoryFromAuthoritative(); _uiRevision++; } private void RefreshTerminalInventoryFromAuthoritative() { //IL_0084: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_terminal == (Object)null) { return; } Inventory inventory = _terminal.GetInventory(); if (inventory == null) { return; } long num = ComputeContentHash(); if (num == _lastProjectedContentHash) { return; } _lastProjectedContentHash = num; _isApplyingProjection = true; try { ReflectionHelpers.ClearInventory(inventory); _displayedTotals.Clear(); int num2 = Math.Max(1, ReflectionHelpers.GetInventoryWidth(inventory)); RebuildSortedItems(); int num3 = 0; foreach (KeyValuePair<ItemKey, int> sortedItem in _sortedItems) { int value; int num4 = ((!_stackSizes.TryGetValue(sortedItem.Key, out value) || value <= 0) ? 1 : value); num3 += (int)Math.Ceiling((double)sortedItem.Value / (double)num4); } int num5 = ((_slotsTotalPhysical > _slotsUsedDisplay) ? 1 : 0); int num6 = Math.Max(1, num3 + num5); _contentRows = Math.Max(1, (int)Math.Ceiling((float)num6 / (float)num2)); ReflectionHelpers.SetInventorySize(inventory, num2, _contentRows); int num7 = 0; foreach (KeyValuePair<ItemKey, int> sortedItem2 in _sortedItems) { int num8 = sortedItem2.Value; int value2; int num9 = ((!_stackSizes.TryGetValue(sortedItem2.Key, out value2) || value2 <= 0) ? 1 : value2); while (num8 > 0) { int num10 = Math.Min(num9, num8); ItemData val = CreateProjectedItem(sortedItem2.Key, num10, num9); if (val == null) { break; } int x = num7 % num2; int y = num7 / num2; ReflectionHelpers.AddItemDirectly(inventory, val, x, y); num7++; num8 -= num10; } _displayedTotals[sortedItem2.Key] = sortedItem2.Value - num8; } ReflectionHelpers.NotifyInventoryChanged(inventory); } finally { _isApplyingProjection = false; } } private long ComputeContentHash() { //IL_0021: 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) long num = 17L; foreach (KeyValuePair<ItemKey, int> authoritativeTotal in _authoritativeTotals) { long num2 = num * 31; ItemKey key = authoritativeTotal.Key; num = num2 + ((object)(ItemKey)(ref key)).GetHashCode(); num = num * 31 + authoritativeTotal.Value; } return num * 31 + _searchQuery.GetHashCode(); } private void RebuildSortedItems() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) _sortedItems.Clear(); foreach (KeyValuePair<ItemKey, int> authoritativeTotal in _authoritativeTotals) { if (authoritativeTotal.Value > 0) { EnsureSortCacheEntry(authoritativeTotal.Key); if (MatchesSearch(_sortCache[authoritativeTotal.Key].DisplayName)) { _sortedItems.Add(authoritativeTotal); } } } _sortedItems.Sort(delegate(KeyValuePair<ItemKey, int> a, KeyValuePair<ItemKey, int> b) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) CachedSortEntry cachedSortEntry = _sortCache[a.Key]; CachedSortEntry cachedSortEntry2 = _sortCache[b.Key]; int num = cachedSortEntry.TypeOrder.CompareTo(cachedSortEntry2.TypeOrder); if (num != 0) { return num; } num = cachedSortEntry.SubgroupOrder.CompareTo(cachedSortEntry2.SubgroupOrder); if (num != 0) { return num; } num = string.Compare(cachedSortEntry.DisplayName, cachedSortEntry2.DisplayName, StringComparison.OrdinalIgnoreCase); return (num != 0) ? num : b.Value.CompareTo(a.Value); }); } private void EnsureSortCacheEntry(ItemKey key) { //IL_0006: 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_0021: 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_003c: Unknown result type (might be due to invalid IL or missing references) if (!_sortCache.ContainsKey(key)) { _sortCache[key] = new CachedSortEntry { DisplayName = GetDisplayName(key), TypeOrder = GetItemTypeOrder(key), SubgroupOrder = ReflectionHelpers.GetSubgroupOrder(key) }; } } private ItemData? CreateProjectedItem(ItemKey key, int amount, int maxStackSize) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!_prototypes.TryGetValue(key, out ItemData value)) { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab(((ItemKey)(ref key)).PrefabName) : null); ItemDrop val = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); if (val?.m_itemData == null) { return null; } value = val.m_itemData.Clone(); value.m_quality = ((ItemKey)(ref key)).Quality; value.m_variant = ((ItemKey)(ref key)).Variant; _prototypes[key] = value; } ItemData obj2 = value.Clone(); obj2.m_stack = amount; return obj2; } private bool MatchesSearch(string displayName) { if (!string.IsNullOrWhiteSpace(_searchQuery)) { return displayName.IndexOf(_searchQuery, StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private void RefreshTrackedChestHandles() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_terminal == (Object)null) { _trackedChests.Clear(); _nextTrackedChestRefreshAt = Time.unscaledTime + 1f; } else { _trackedChests = _scanner.GetNearbyContainers(((Component)_terminal).transform.position, _scanRadius, _terminal).ToList(); _nextTrackedChestRefreshAt = Time.unscaledTime + 1f; } } private void ApplyDisplayedDeltaAsOperations(Dictionary<ItemKey, int> currentDisplayed) { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) HashSet<ItemKey> hashSet = new HashSet<ItemKey>(_displayedTotals.Keys); hashSet.UnionWith(currentDisplayed.Keys); foreach (ItemKey item in hashSet) { int value; int num = (_displayedTotals.TryGetValue(item, out value) ? value : 0); int value2; int num2 = (currentDisplayed.TryGetValue(item, out value2) ? value2 : 0) - num; if (num2 < 0) { RequestReserveWithdraw(item, -num2); } else if (num2 > 0) { RequestCancelAndOrDeposit(item, num2); } } } private void RequestReserveWithdraw(ItemKey key, int amount) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (amount > 0) { _routes.RequestReserveWithdraw(new ReserveWithdrawRequestDto { RequestId = Guid.NewGuid().ToString("N"), SessionId = _sessionId, OperationId = Guid.NewGuid().ToString("N"), TerminalUid = _terminalUid, PlayerId = ResolveLocalPlayerId(), ExpectedRevision = _revision, Key = key, Amount = amount }); } } private void RequestCancelAndOrDeposit(ItemKey key, int amount) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) if (amount <= 0) { return; } int num = amount; foreach (PendingReservation item in _pendingReservations.Where(delegate(PendingReservation r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) ItemKey key2 = r.Key; return ((ItemKey)(ref key2)).Equals(key) && r.ReservedAmount > 0; }).ToList()) { if (num <= 0) { break; } int num2 = Math.Min(num, item.ReservedAmount); if (num2 > 0) { _routes.RequestCancelReservation(new CancelReservationRequestDto { RequestId = Guid.NewGuid().ToString("N"), SessionId = _sessionId, OperationId = Guid.NewGuid().ToString("N"), TerminalUid = _terminalUid, PlayerId = ResolveLocalPlayerId(), TokenId = item.TokenId, Amount = num2 }); item.ReservedAmount -= num2; num -= num2; if (item.ReservedAmount <= 0) { _pendingReservations.Remove(item); } } } if (num > 0) { string requestId = Guid.NewGuid().ToString("N"); _pendingDeposits.Add(new PendingDeposit { RequestId = requestId, Key = key, Amount = num }); _routes.RequestDeposit(new DepositRequestDto { RequestId = requestId, SessionId = _sessionId, OperationId = Guid.NewGuid().ToString("N"), TerminalUid = _terminalUid, PlayerId = ResolveLocalPlayerId(), ExpectedRevision = _revision, Key = key, Amount = num }); } } private void CommitPendingReservations() { foreach (PendingReservation item in _pendingReservations.Where((PendingReservation r) => !r.CommitRequested && r.ReservedAmount > 0).ToList()) { _routes.RequestCommitReservation(new CommitReservationRequestDto { RequestId = Guid.NewGuid().ToString("N"), SessionId = _sessionId, OperationId = Guid.NewGuid().ToString("N"), TerminalUid = _terminalUid, TokenId = item.TokenId }); item.CommitRequested = true; } } private void ExpireLocalReservations() { float unscaledTime = Time.unscaledTime; bool flag = false; for (int num = _pendingReservations.Count - 1; num >= 0; num--) { if (!(_pendingReservations[num].ExpiresAt > unscaledTime)) { _pendingReservations.RemoveAt(num); flag = true; } } if (flag) { RequestSessionSnapshot(); } } private void RequestSessionSnapshot() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (IsActive && !((Object)(object)_terminal == (Object)null)) { _routes.RequestOpenSession(new OpenSessionRequestDto { RequestId = Guid.NewGuid().ToString("N"), SessionId = _sessionId, TerminalUid = _terminalUid, PlayerId = ResolveLocalPlayerId(), AnchorX = ((Component)_terminal).transform.position.x, AnchorY = ((Component)_terminal).transform.position.y, AnchorZ = ((Component)_terminal).transform.position.z, Radius = _scanRadius }); _nextSnapshotRetryAt = Time.unscaledTime + 0.5f; } } private Dictionary<ItemKey, int> CaptureCurrentDisplayedTotals() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Dictionary<ItemKey, int> dictionary = new Dictionary<ItemKey, int>(); if ((Object)(object)_terminal == (Object)null) { return dictionary; } Inventory inventory = _terminal.GetInventory(); if (inventory == null) { return dictionary; } ItemKey key = default(ItemKey); foreach (ItemData allItem in inventory.GetAllItems()) { if (!((Object)(object)allItem?.m_dropPrefab == (Object)null) && allItem.m_stack > 0) { ((ItemKey)(ref key))..ctor(((Object)allItem.m_dropPrefab).name, allItem.m_quality, allItem.m_variant); dictionary[key] = (dictionary.TryGetValue(key, out var value) ? (value + allItem.m_stack) : allItem.m_stack); } } return dictionary; } private void ReplaceDisplayedTotals(Dictionary<ItemKey, int> totals) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) _displayedTotals.Clear(); foreach (KeyValuePair<ItemKey, int> total in totals) { _displayedTotals[total.Key] = total.Value; } } private bool IsSessionTerminal(Container container) { if ((Object)(object)container != (Object)null && !string.IsNullOrWhiteSpace(_terminalUid)) { return string.Equals(ReflectionHelpers.BuildContainerUid(container), _terminalUid, StringComparison.Ordinal); } return false; } private void HandleDepositResult(ApplyResultDto result) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) ApplyResultDto result2 = result; PendingDeposit pendingDeposit = _pendingDeposits.FirstOrDefault((PendingDeposit p) => string.Equals(p.RequestId, result2.RequestId, StringComparison.Ordinal)); if (pendingDeposit != null) { _pendingDeposits.Remove(pendingDeposit); if (result2.Success) { _trace.Dev($"Deposited {result2.AppliedAmount}x {GetDisplayName(pendingDeposit.Key)}."); } else if (ShouldRestoreFailedDeposit(result2.Reason)) { RestoreToLocalPlayerInventory(pendingDeposit.Key, pendingDeposit.Amount); } } } private void RestoreToLocalPlayerInventory(ItemKey key, int amount) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (amount > 0 && !((Object)(object)_player == (Object)null)) { int num = ReflectionHelpers.GetMaxStackSize(key); if (num <= 0) { num = 1; } Inventory inventory = ((Humanoid)_player).GetInventory(); int num2 = ChunkedTransfer.Move(amount, num, (Func<int, int>)delegate(int chunkAmount) { //IL_0001: 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) ItemData val = ReflectionHelpers.CreateItemStack(key, chunkAmount); return (val != null) ? ReflectionHelpers.TryAddItemMeasured(inventory, key, val, chunkAmount) : 0; }); int num3 = amount - num2; if (num3 > 0) { DropNearPlayer(key, num3); } } } private void DropNearPlayer(ItemKey key, int amount) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player == (Object)null || amount <= 0) { return; } int num = ReflectionHelpers.GetMaxStackSize(key); if (num <= 0) { num = 1; } int num2 = amount; while (num2 > 0) { int num3 = Math.Min(num, num2); ItemData val = ReflectionHelpers.CreateItemStack(key, num3); if (val != null && ReflectionHelpers.TryDropItem(val, num3, ((Component)_player).transform.position + ((Component)_player).transform.forward + Vector3.up, Quaternion.identity)) { num2 -= num3; continue; } break; } } private void RemovePendingToken(string tokenId) { string tokenId2 = tokenId; if (!string.IsNullOrWhiteSpace(tokenId2)) { _pendingReservations.RemoveAll((PendingReservation r) => string.Equals(r.TokenId, tokenId2, StringComparison.Ordinal)); } } private void MarkPendingCommitAsRetryable(string tokenId) { string tokenId2 = tokenId; foreach (PendingReservation item in _pendingReservations.Where((PendingReservation r) => string.Equals(r.TokenId, tokenId2, StringComparison.Ordinal))) { item.CommitRequested = false; } } private long ResolveLocalPlayerId() { if (!((Object)(object)_player != (Object)null)) { return 0L; } return _player.GetPlayerID(); } private string GetDisplayName(ItemKey key) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (_prototypes.TryGetValue(key, out ItemData value)) { string name = value.m_shared.m_name; Localization instance = Localization.instance; string text = ((instance != null) ? instance.Localize(name) : null); if (string.IsNullOrEmpty(text)) { return name; } return text; } return ((ItemKey)(ref key)).PrefabName; } private int GetItemTypeOrder(ItemKey key) { //IL_0006: 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_001c: Expected I4, but got Unknown if (_prototypes.TryGetValue(key, out ItemData value)) { return (int)value.m_shared.m_itemType; } return int.MaxValue; } private void CaptureOriginalInventorySize(Inventory? inventory) { if (inventory == null) { _originalInventoryWidth = 8; _originalInventoryHeight = 4; } else { _originalInventoryWidth = ReflectionHelpers.GetInventoryWidth(inventory); _originalInventoryHeight = ReflectionHelpers.GetInventoryHeight(inventory); } } private void RestoreTerminalInventorySize(Inventory? inventory) { if (inventory != null && _originalInventoryWidth > 0 && _originalInventoryHeight > 0) { ReflectionHelpers.SetInventorySize(inventory, _originalInventoryWidth, _originalInventoryHeight); } } private static bool ShouldRestoreFailedDeposit(string reason) { if (!string.IsNullOrWhiteSpace(reason)) { switch (reason) { default: return reason == "Unable to resolve player identity"; case "Conflict": case "Player not found": case "Player has no matching item": case "Player/terminal has no matching item": case "Session not found": case "No storage space": case "Player identity mismatch": return true; } } return false; } private static bool IsIdentityFailure(string reason) { if (!(reason == "Player identity mismatch")) { return reason == "Unable to resolve player identity"; } return true; } private static float GetRetryDelay(int failureCount) { if (failureCount <= 0) { return 0.5f; } int num = Math.Min(6, failureCount - 1); float num2 = 0.5f * Mathf.Pow(2f, (float)num); return Mathf.Min(8f, num2); } } } namespace UnifiedStorage.Mod.Server { public static class ChestInclusionRules { private const string IncludeInUnifiedKey = "US_IncludeInUnified"; private static readonly HashSet<string> VanillaChestPrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "piece_chest", "piece_chest_wood", "piece_chest_private", "piece_chest_blackmetal" }; public static bool IsVanillaChest(Container? container) { if ((Object)(object)container == (Object)null) { return false; } string item = NormalizePrefabName(((Object)((Component)container).gameObject).name); return VanillaChestPrefabNames.Contains(item); } public static bool IsIncludedInUnified(Container? container) { if ((Object)(object)container == (Object)null) { return false; } return IsIncludedInUnified(((Component)container).GetComponent<ZNetView>()); } public static bool IsIncludedInUnified(ZNetView? znetView) { ZDO val = ((znetView != null) ? znetView.GetZDO() : null); if (val == null) { return true; } return val.GetBool("US_IncludeInUnified", true); } public static bool TrySetIncludedInUnified(Container? container, bool includeInUnified) { if ((Object)(object)container == (Object)null) { return false; } return TrySetIncludedInUnified(((Component)container).GetComponent<ZNetView>(), includeInUnified); } public static bool TrySetIncludedInUnified(ZNetView? znetView, bool includeInUnified) { ZDO val = ((znetView != null) ? znetView.GetZDO() : null); if (val == null) { return false; } try { if ((Object)(object)znetView != (Object)null && !znetView.IsOwner()) { znetView.ClaimOwnership(); } } catch { } val.Set("US_IncludeInUnified", includeInUnified); return true; } private static string NormalizePrefabName(string name) { if (name.EndsWith("(Clone)", StringComparison.Ordinal)) { return name.Substring(0, name.Length - "(Clone)".Length); } return name; } } public sealed class ContainerScanner : IContainerScanner { private readonly StorageConfig _config; public ContainerScanner(StorageConfig config) { _config = config; } public IReadOnlyList<ChestHandle> GetNearbyContainers(Vector3 center, float radius, Container? ignoreContainer = null) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) Container ignoreContainer2 = ignoreContainer; int maxContainersScannedLimit = _config.MaxContainersScannedLimit; IEnumerable<ChestHandle> first = from handle in (from container in (from container in Object.FindObjectsByType<Container>((FindObjectsSortMode)0) where (Object)(object)container != (Object)null select container).Where(IsStaticChest) where (Object)(object)ignoreContainer2 == (Object)null || (Object)(object)container != (Object)(object)ignoreContainer2 where !UnifiedTerminal.IsTerminal(container) select container).Where(ChestInclusionRules.IsIncludedInUnified).Select(delegate(Container container) { //IL_0001: 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) float distance = Vector3.Distance(center, ((Component)container).transform.position); string sourceId = BuildSourceId(container); IStorageSource source = new ContainerStorageSource(sourceId, container, distance, _config); return new ChestHandle(sourceId, source, distance); }) where handle.Distance <= radius select handle; IEnumerable<ChestHandle> second = BuildDrawerHandles(center, radius); return (from handle in first.Concat(second) orderby handle.Distance, handle.SourceId select handle).Take(maxContainersScannedLimit).ToList(); } private static IEnumerable<ChestHandle> BuildDrawerHandles(Vector3 center, float radius) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!ItemDrawersApi.IsAvailable) { yield break; } foreach (DrawerSnapshot item in ItemDrawersApi.GetDrawersInRange(center, radius)) { if (ChestInclusionRules.IsIncludedInUnified(item.ZNetView)) { float distance = Vector3.Distance(center, item.Position); IStorageSource source = new DrawerStorageSource(item, distance); yield return new ChestHandle(item.SourceId, source, distance); } } } private static bool IsStaticChest(Container container) { if (!((Component)container).gameObject.activeInHierarchy) { return false; } if ((Object)(object)((Component)container).GetComponentInParent<Vagon>() != (Object)null) { return false; } if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null) { return false; } return true; } private static string BuildSourceId(Container container) { ZNetView component = ((Component)container).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val != null) { return ((object)(ZDOID)(ref val.m_uid)).ToString(); } return ((Object)container).GetInstanceID().ToString(); } } public sealed class ContainerStorageSource : IStorageSource { private readonly Container _container; private readonly StorageConfig _config; public string SourceId { get; } public float Distance { get; } public bool IsValid { get { if ((Object)(object)_container != (Object)null) { return ((Component)_container).gameObject.activeInHierarchy; } return false; } } public int PhysicalSlotCount { get { Inventory inventory = _container.GetInventory(); if (inventory == null) { return 0; } return ReflectionHelpers.GetInventoryWidth(inventory) * ReflectionHelpers.GetInventoryHeight(inventory); } } public int DisplaySlotsUsed { get { Inventory inventory = _container.GetInventory(); if (inventory == null) { return 0; } return inventory.GetAllItems().Count; } } public ContainerStorageSource(string sourceId, Container container, float distance, StorageConfig config) { SourceId = sourceId; _container = container; Distance = distance; _config = config; } public IReadOnlyList<SourceStack> ReadStacks() { //IL_0052: 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 refe