using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("VHModpackFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.24.0")] [assembly: AssemblyInformationalVersion("1.1.24")] [assembly: AssemblyProduct("VHModpackFix")] [assembly: AssemblyTitle("VHModpackFix")] [assembly: AssemblyVersion("1.1.24.0")] namespace Obelisk.VHModpackFix; internal static class AAABuildMenuLifecycleFixes { private const string PluginGuid = "Azumatt.AAABuildMenu"; private const string EnhancedMenuTypeName = "AAABuildMenu.EnhancedBuildMenu"; private const string PatchesTypeName = "AAABuildMenu.EnhancedBuildMenuPatches"; private const string PinnedTrackerTypeName = "AAABuildMenu.PinnedRecipeTracker"; private static readonly string[] HudReferenceFields = new string[29] { "_searchBarObject", "_searchInputField", "_scrollRect", "_clearSearchButton", "_filterButtonRow", "_allButton", "_canCraftButton", "_missingMaterialsButton", "_favoritesButton", "_recentButton", "_sortButton", "_sortButtonText", "_matchCountText", "_materialsButton", "_materialsDropdown", "_materialsSearchField", "_searchDebounceCoroutine", "_uiFont", "_tooltipPrefab", "_buttonSprite", "_hud", "_resizeHandle", "_moveHandle", "_vanillaButtonSprite", "SelectedPiece", "_materialsListContent", "_favoriteBorderSprite", "_allSprites", "_clickSfxPrefab" }; private static readonly string[] HudCollectionFields = new string[7] { "_selectedMaterials", "_favoriteStars", "_favoriteBorders", "_pinIndicators", "_prefabNameCache", "_categoryMasters", "_spriteCache" }; private static ConfigEntry _enabled; private static Type _enhancedMenuType; private static Type _patchesType; private static Type _pinnedTrackerType; private static FieldInfo _initializedField; private static FieldInfo _hudField; internal static void Init(Harmony harmony, ConfigFile config) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown _enabled = ConfigLayout.Bind(config, "AAABuildMenu", "Restore enhanced menu after world re-entry", defaultValue: true, "Clears only AAABuildMenu's HUD-bound static state when Valheim destroys a world HUD. Search, filters, the expanded grid, pin tracker, and controls are then created for the next world HUD. Favorites and saved settings are preserved. Restart Valheim after changing this setting.", "AAABuildMenu compatibility"); if (!_enabled.Value || !Chainloader.PluginInfos.ContainsKey("Azumatt.AAABuildMenu")) { return; } _enhancedMenuType = AccessTools.TypeByName("AAABuildMenu.EnhancedBuildMenu"); _patchesType = AccessTools.TypeByName("AAABuildMenu.EnhancedBuildMenuPatches"); _pinnedTrackerType = AccessTools.TypeByName("AAABuildMenu.PinnedRecipeTracker"); if (_enhancedMenuType == null) { VHModpackFixPlugin.LogWarning("AAABuildMenu lifecycle type 'AAABuildMenu.EnhancedBuildMenu' was not found; the re-entry fix was skipped.", null); return; } _initializedField = AccessTools.Field(_enhancedMenuType, "_isInitialized"); _hudField = AccessTools.Field(_enhancedMenuType, "_hud"); MethodInfo methodInfo = AccessTools.Method(typeof(Hud), "Awake", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Hud), "OnDestroy", (Type[])null, (Type[])null); if (_initializedField == null || _hudField == null || methodInfo == null || methodInfo2 == null) { VHModpackFixPlugin.LogWarning("AAABuildMenu lifecycle targets do not match the supported 1.0.1 layout; the re-entry fix was skipped.", null); return; } try { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(AAABuildMenuLifecycleFixes), "HudAwakePrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(AAABuildMenuLifecycleFixes), "HudOnDestroyPostfix", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); VHModpackFixPlugin.LogInfo("AAABuildMenu world re-entry lifecycle repair installed."); } catch (Exception exception) { VHModpackFixPlugin.LogWarning("Could not install the AAABuildMenu world re-entry lifecycle repair", exception); } } private static void HudAwakePrefix(Hud __instance) { if (IsEnabled() && IsInitialized() && _hudField.GetValue(null) != __instance) { ResetHudState(); } } private static void HudOnDestroyPostfix(Hud __instance) { if (IsEnabled() && _hudField.GetValue(null) == __instance) { ResetHudState(); } } private static void ResetHudState() { try { _initializedField.SetValue(null, false); for (int i = 0; i < HudReferenceFields.Length; i++) { SetStaticField(_enhancedMenuType, HudReferenceFields[i], null); } for (int j = 0; j < HudCollectionFields.Length; j++) { ClearStaticCollection(_enhancedMenuType, HudCollectionFields[j]); } SetStaticField(_enhancedMenuType, "_origCaptured", false); SetStaticField(_enhancedMenuType, "_maskAdjusted", false); SetStaticField(_enhancedMenuType, "_origMaskCaptured", false); SetStaticField(_enhancedMenuType, "_vanillaButtonUsesSpriteSwap", false); SetStaticField(_enhancedMenuType, "_vanillaButtonResolved", false); SetStaticField(_enhancedMenuType, "_hasVanillaButton", false); SetStaticField(_enhancedMenuType, "_origWinCaptured", false); SetStaticField(_enhancedMenuType, "_sfxResolved", false); SetStaticField(_enhancedMenuType, "Columns", 15); FieldInfo fieldInfo = AccessTools.Field(_enhancedMenuType, "_lastScrollCategory"); if (fieldInfo != null) { fieldInfo.SetValue(null, Enum.ToObject(fieldInfo.FieldType, -999)); } ResetFilterState(); AccessTools.Property(_enhancedMenuType, "NeedsRefresh")?.SetValue(null, true, null); SetStaticField(_patchesType, "_menuWasVisible", false); ResetPinnedTrackerState(); VHModpackFixPlugin.LogInfo("AAABuildMenu HUD-bound state cleared for the next world."); } catch (Exception exception) { VHModpackFixPlugin.LogWarning("Could not clear stale AAABuildMenu HUD state", exception); } } private static void ResetFilterState() { object obj = AccessTools.Field(_enhancedMenuType, "_currentFilter")?.GetValue(null); if (obj != null) { SetInstanceProperty(obj, "SearchTerm", string.Empty); SetInstanceProperty(obj, "ShowOnlyCraftable", false); SetInstanceProperty(obj, "ShowMissingMaterials", false); SetInstanceProperty(obj, "ShowFavoritesOnly", false); SetInstanceProperty(obj, "ShowRecentOnly", false); SetInstanceProperty(obj, "ShowAll", false); } } private static void ResetPinnedTrackerState() { if (!(_pinnedTrackerType == null)) { SetStaticField(_pinnedTrackerType, "_root", null); SetStaticField(_pinnedTrackerType, "_rootRect", null); SetStaticField(_pinnedTrackerType, "_contentRoot", null); SetStaticField(_pinnedTrackerType, "_title", null); SetStaticField(_pinnedTrackerType, "_font", null); SetStaticField(_pinnedTrackerType, "_nextRefresh", 0f); ClearStaticCollection(_pinnedTrackerType, "_pieceCache"); ClearStaticCollection(_pinnedTrackerType, "_rows"); ClearStaticCollection(_pinnedTrackerType, "_shownPins"); } } private static void SetStaticField(Type type, string fieldName, object value) { if (!(type == null)) { AccessTools.Field(type, fieldName)?.SetValue(null, value); } } private static void ClearStaticCollection(Type type, string fieldName) { if (!(type == null)) { object obj = AccessTools.Field(type, fieldName)?.GetValue(null); obj?.GetType().GetMethod("Clear", Type.EmptyTypes)?.Invoke(obj, null); } } private static void SetInstanceProperty(object instance, string propertyName, object value) { instance.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public)?.SetValue(instance, value, null); } private static bool IsEnabled() { return _enabled?.Value ?? false; } private static bool IsInitialized() { object obj = _initializedField?.GetValue(null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } internal static class AdventureBackpacksAutoStoreCompat { [HarmonyPatch(typeof(Player), "Message")] private static class PlayerMessagePatch { private static bool Prefix(MessageType type, string msg) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return !ShouldSuppressMessage(type, msg); } } private const string VanillaContainerType = "AzuAutoStore.Interfaces.VanillaContainers"; private const string KgDrawerType = "AzuAutoStore.Interfaces.kgDrawer"; private const string BackpackContainerType = "AzuAutoStore.Interfaces.BackpackContainer"; private const string BackpackInventoryMarker = "$vapok_mod_level"; private const string FavoriteBorderName = "AzuAutoStoreFavoritingBorder"; private const string BackpackFavoriteDataKey = "obelisk.vhmodpackfix.backpackFavorite"; private const string EpicLootCustomDataPrefix = "randyknapp.mods.epicloot#"; private static ConfigEntry _autoStoreEnabled; private static ConfigEntry _pickupRoutingEnabled; private static MethodInfo _getEquippedBackpack; private static MethodInfo _getBackpackInventory; private static MethodInfo _isBackpackItem; private static MethodInfo _inventoryChanged; private static FieldInfo _inventoryGuiCurrentContainer; private static FieldInfo _inventoryGuiDragObject; private static FieldInfo _containerNetworkView; private static MethodInfo _containerCheckAccess; private static MethodInfo _getNearbyContainers; private static MethodInfo _storeToContainer; private static MethodInfo _vanillaContainerGetInventory; private static PropertyInfo _containerGameObject; private static FieldInfo _playerRange; private static MethodInfo _isItemNameOrSlotFavorite; private static MethodInfo _createFavoriteBorder; private static FieldInfo _favoriteBorderColor; private static FieldInfo _favoritingModifier1; private static FieldInfo _favoritingModifier2; private static FieldInfo _favoritingToggleState; private static FieldInfo _inventoryGridInventory; private static FieldInfo _inventoryGridElements; private static FieldInfo _elementQueuedImage; private static MethodInfo _inventoryGridGetButtonPos; private static bool _backpackReady; private static bool _autoStoreReady; private static bool _autoStorePatched; private static bool _pickupPatched; private static bool _containerTransferPatched; private static bool _loadRecoveryPatched; private static bool _backpackSaveHotPathPatched; private static bool _favoritePatched; private static bool _pickupApiFailureLogged; private static bool _favoriteFailureLogged; private static bool _favoriteBordersDirty = true; private static Inventory _lastBorderInventory; private static InventoryGrid _lastBorderGrid; private static Image _lastBorderFirstQueuedImage; private static int _lastBorderElementCount = -1; private static int _pickupBackpackCacheFrame = -1; private static Player _pickupBackpackCachePlayer; private static Inventory _pickupBackpackCacheInventory; [ThreadStatic] private static bool _tryStoreScope; [ThreadStatic] private static bool _suppressAzuFailureMessage; [ThreadStatic] private static int _backpackStored; [ThreadStatic] private static Inventory _activeStoreInventory; [ThreadStatic] private static ItemData _activeStoreItem; [ThreadStatic] private static Vector2i _activeStoreOriginalPosition; [ThreadStatic] private static object[] _playerInvokeArguments; [ThreadStatic] private static object[] _itemInvokeArguments; [ThreadStatic] private static object[] _nearbyInvokeArguments; [ThreadStatic] private static object[] _storeInvokeArguments; internal static void Init(Harmony harmony, ConfigFile config) { _autoStoreEnabled = ConfigLayout.Bind(config, "AdventureBackpacks", "AdventureBackpacks AzuAutoStore compatibility", defaultValue: true, "Lets AzuAutoStore move eligible items from your equipped AdventureBackpacks backpack into nearby storage. Favorite items remain protected.", "Fixes"); _pickupRoutingEnabled = ConfigLayout.Bind(config, "AdventureBackpacks", "Auto-pick matching items into AdventureBackpacks", defaultValue: false, "When the equipped backpack already contains an item type, sends whole matching stacks there during automatic pickup, manual pickup, and quick transfer from an opened container. Epic Loot stack data is supported; unknown special data is left to the normal inventory for safety.", "Experimental"); if (harmony == null || !ResolveBackpackApi()) { return; } if (!_loadRecoveryPatched) { PatchBackpackLoadRecovery(harmony); } if (!_backpackSaveHotPathPatched) { PatchBackpackSaveHotPath(harmony); } if (!_pickupPatched) { PatchPickupRouting(harmony); } if (!_containerTransferPatched) { PatchContainerTransfers(harmony); } if (ResolveAutoStoreApi()) { if (!_autoStorePatched) { PatchAutoStore(harmony); } if (!_favoritePatched) { PatchFavoriteSupport(harmony); } } } private static bool ResolveBackpackApi() { if (_backpackReady) { return true; } Type type = FindLoadedType("AdventureBackpacks.Extensions.PlayerExtensions"); Type type2 = FindLoadedType("AdventureBackpacks.Extensions.ItemDataExtensions"); _getEquippedBackpack = ((type == null) ? null : AccessTools.Method(type, "GetEquippedBackpack", new Type[1] { typeof(Player) }, (Type[])null)); Type type3 = _getEquippedBackpack?.ReturnType; _getBackpackInventory = ((type3 == null) ? null : AccessTools.Method(type3, "GetInventory", Type.EmptyTypes, (Type[])null)); _isBackpackItem = ((type2 == null) ? null : AccessTools.Method(type2, "IsBackpack", new Type[1] { typeof(ItemData) }, (Type[])null)); _inventoryChanged = AccessTools.Method(typeof(Inventory), "Changed", Type.EmptyTypes, (Type[])null); _inventoryGuiCurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); _inventoryGuiDragObject = AccessTools.Field(typeof(InventoryGui), "m_dragGo"); _containerNetworkView = AccessTools.Field(typeof(Container), "m_nview"); _containerCheckAccess = AccessTools.Method(typeof(Container), "CheckAccess", new Type[1] { typeof(long) }, (Type[])null); _backpackReady = _getEquippedBackpack != null && _getBackpackInventory != null && _inventoryChanged != null; return _backpackReady; } private static bool ResolveAutoStoreApi() { if (_autoStoreReady) { return true; } Type type = FindLoadedType("AzuAutoStore.Util.Boxes"); Type type2 = FindLoadedType("AzuAutoStore.Util.Functions"); Type type3 = FindLoadedType("AzuAutoStore.Interfaces.IContainer"); Type type4 = FindLoadedType("AzuAutoStore.Interfaces.VanillaContainers"); Type type5 = FindLoadedType("AzuAutoStore.AzuAutoStorePlugin"); if (type == null || type2 == null || type3 == null) { return false; } _getNearbyContainers = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo method) { if (method.Name != "GetNearbyContainers" || !method.IsGenericMethodDefinition) { return false; } ParameterInfo[] parameters = method.GetParameters(); return parameters.Length == 2 && parameters[1].ParameterType == typeof(float); })?.MakeGenericMethod(typeof(Player)); _storeToContainer = AccessTools.DeclaredMethod(type2, "StoreToContainer", new Type[3] { type3, typeof(ItemData), typeof(Inventory) }, (Type[])null); _vanillaContainerGetInventory = ((type4 == null) ? null : AccessTools.Method(type4, "GetInventory", Type.EmptyTypes, (Type[])null)); _containerGameObject = AccessTools.Property(type3, "gameObject"); _playerRange = ((type5 == null) ? null : AccessTools.Field(type5, "PlayerRange")); ResolveFavoriteApi(type5); _autoStoreReady = _isBackpackItem != null && _getNearbyContainers != null && _storeToContainer != null; return _autoStoreReady; } private static void ResolveFavoriteApi(Type pluginType) { Type type = FindLoadedType("AzuAutoStore.Patches.Favoriting.UserConfig"); Type type2 = FindLoadedType("AzuAutoStore.Patches.Favoriting.FavoritingMode"); Type type3 = FindLoadedType("AzuAutoStore.Patches.Favoriting.BorderRenderer"); _isItemNameOrSlotFavorite = ((type == null) ? null : AccessTools.Method(type, "IsItemNameOrSlotFavorited", new Type[1] { typeof(ItemData) }, (Type[])null)); _createFavoriteBorder = ((type3 == null) ? null : AccessTools.Method(type3, "CreateBorderImage", new Type[1] { typeof(Image) }, (Type[])null)); _favoriteBorderColor = ((pluginType == null) ? null : AccessTools.Field(pluginType, "BorderColorFavoritedItem")); _favoritingModifier1 = ((pluginType == null) ? null : AccessTools.Field(pluginType, "FavoritingModifierKeybind1")); _favoritingModifier2 = ((pluginType == null) ? null : AccessTools.Field(pluginType, "FavoritingModifierKeybind2")); _favoritingToggleState = ((type2 == null) ? null : AccessTools.Field(type2, "hasCurrentlyToggledFavoriting")); _inventoryGridInventory = AccessTools.Field(typeof(InventoryGrid), "m_inventory"); _inventoryGridElements = AccessTools.Field(typeof(InventoryGrid), "m_elements"); _inventoryGridGetButtonPos = AccessTools.Method(typeof(InventoryGrid), "GetButtonPos", new Type[1] { typeof(GameObject) }, (Type[])null); } private static void PatchAutoStore(Harmony harmony) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_00f1: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown Type type = FindLoadedType("AzuAutoStore.Util.Functions"); Type type2 = FindLoadedType("AzuAutoStore.Patches.ContainerAwakePatch"); MethodInfo methodInfo = AccessTools.Method(type, "TryStore", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "StoreSuccess", new Type[1] { typeof(int) }, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(type2, "TryAddContainer", new Type[1] { typeof(Container) }, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(Inventory), "Changed", Type.EmptyTypes, (Type[])null); if (!(methodInfo == null) && !(methodInfo2 == null) && !(methodInfo4 == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "TryStorePrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "TryStoreFinalizer", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "StoreSuccessPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)_storeToContainer, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "SkipEquippedBackpackContainerPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "SkipPlayerContainerRegistrationPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "InventoryChangedPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _autoStorePatched = true; } } private static void PatchPickupRouting(Harmony harmony) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "Pickup", new Type[3] { typeof(GameObject), typeof(bool), typeof(bool) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "AutoPickup", new Type[1] { typeof(float) }, (Type[])null); if (methodInfo == null || methodInfo2 == null) { VHModpackFixPlugin.LogWarning("AdventureBackpacks pickup routing could not find the current Valheim pickup methods", null); return; } try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "PickupAddTranspiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); PatchAutoPickupMethod(harmony, methodInfo2); MethodInfo methodInfo3 = FindLoadedType("Valheim_Build_Camera.Utils")?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo method) { if (method.Name != "AutoPickup") { return false; } ParameterInfo[] parameters = method.GetParameters(); return parameters.Length == 2 && parameters[0].ParameterType == typeof(float) && parameters[1].ParameterType == typeof(GameCamera).MakeByRefType(); }); if (methodInfo3 != null) { PatchAutoPickupMethod(harmony, methodInfo3); } _pickupPatched = true; } catch (Exception exception) { VHModpackFixPlugin.LogWarning("AdventureBackpacks pickup routing could not be installed", Unwrap(exception)); } } private static void PatchContainerTransfers(Harmony harmony) { //IL_0080: 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_0099: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_018e: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(Inventory), "MoveItemToThis", new Type[2] { typeof(Inventory), typeof(ItemData) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Inventory), "MoveAll", new Type[1] { typeof(Inventory) }, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "MoveItemToThisPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "MoveAllPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Type type = FindLoadedType("InventorySlots.InventorySlotsPlugin"); MethodInfo methodInfo3 = ((type == null) ? null : AccessTools.Method(type, "SafeTakeAllItems", new Type[4] { typeof(Player), typeof(Inventory), typeof(Inventory), typeof(bool) }, (Type[])null)); if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "SafeTakeAllPrefix", (Type[])null, (Type[])null)) { priority = 800 }, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "SafeTakeAllPostfix", (Type[])null, (Type[])null)) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } _containerTransferPatched = methodInfo != null || methodInfo2 != null; } catch (Exception exception) { VHModpackFixPlugin.LogWarning("AdventureBackpacks container pickup routing could not be installed", Unwrap(exception)); } } private static void PatchBackpackLoadRecovery(Harmony harmony) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(Inventory), "AddItem", new Type[4] { typeof(ItemData), typeof(int), typeof(int), typeof(int) }, (Type[])null); if (methodInfo == null) { return; } try { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "RepairLoadedBackpackSlotPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _loadRecoveryPatched = true; } catch (Exception exception) { VHModpackFixPlugin.LogWarning("AdventureBackpacks legacy slot recovery could not be installed", Unwrap(exception)); } } private static void PatchBackpackSaveHotPath(Harmony harmony) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.DeclaredMethod(_getEquippedBackpack?.DeclaringType?.Assembly.GetType("AdventureBackpacks.Patches.InventoryPatches+InventoryChangedPatch", throwOnError: false), "Postfix", new Type[1] { typeof(Inventory) }, (Type[])null); if (methodInfo == null) { return; } try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "RemoveUnusedBackpackStackTraceTranspiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); _backpackSaveHotPathPatched = true; } catch (Exception exception) { VHModpackFixPlugin.LogWarning("AdventureBackpacks save-path optimization could not be installed", Unwrap(exception)); } } private static void PatchFavoriteSupport(Harmony harmony) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0168: 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_0181: Expected O, but got Unknown if (_isItemNameOrSlotFavorite == null || _inventoryGridGetButtonPos == null || _inventoryGridInventory == null || _inventoryGridElements == null) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGrid), "OnLeftClick", new Type[1] { typeof(UIInputHandler) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(InventoryGrid), "UpdateGui", new Type[2] { typeof(Player), typeof(ItemData) }, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return; } try { HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "BackpackLeftClickPrefix", (Type[])null, (Type[])null)); val.priority = 800; val.before = new string[3] { "Azumatt.AzuAutoStore", "sighsorry.InventorySlots", "goldenrevolver.quick_stack_store" }; harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val = new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "RenderFavoriteBordersPostfix", (Type[])null, (Type[])null)); val.priority = 0; val.after = new string[2] { "Azumatt.AzuAutoStore", "goldenrevolver.quick_stack_store" }; harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)_isItemNameOrSlotFavorite, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "AzuFavoriteCheckPrefix", (Type[])null, (Type[])null)) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _favoritePatched = true; } catch (Exception exception) { LogFavoriteFailure("AdventureBackpacks favorite-item support could not be installed", exception); } } private static void PatchAutoPickupMethod(Harmony harmony, MethodInfo method) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "AutoPickupCanAddTranspiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); } private static IEnumerable PickupAddTranspiler(IEnumerable instructions, MethodBase __originalMethod) { MethodInfo target = AccessTools.Method(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "AddPickupItem", (Type[])null, (Type[])null); return ReplaceSingleCall(instructions, target, replacement, __originalMethod); } private static IEnumerable AutoPickupCanAddTranspiler(IEnumerable instructions, MethodBase __originalMethod) { MethodInfo target = AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2] { typeof(ItemData), typeof(int) }, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(AdventureBackpacksAutoStoreCompat), "CanAddPickupItem", (Type[])null, (Type[])null); return ReplaceSingleCall(instructions, target, replacement, __originalMethod); } private static IEnumerable ReplaceSingleCall(IEnumerable instructions, MethodInfo target, MethodInfo replacement, MethodBase original) { List list = instructions.ToList(); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], target)) { list[i].opcode = OpCodes.Call; list[i].operand = replacement; return list; } } VHModpackFixPlugin.LogWarning("AdventureBackpacks pickup routing found no compatible call in " + original?.DeclaringType?.FullName + "." + original?.Name, null); return list; } private static IEnumerable RemoveUnusedBackpackStackTraceTranspiler(IEnumerable instructions, MethodBase __originalMethod) { List list = instructions.ToList(); ConstructorInfo objB = AccessTools.Constructor(typeof(StackTrace), Type.EmptyTypes, false); int num = -1; int num2 = 0; for (int i = 0; i < list.Count - 1; i++) { if (!(list[i].opcode != OpCodes.Newobj) && object.Equals(list[i].operand, objB) && !(list[i + 1].opcode != OpCodes.Pop)) { num = i; num2++; } } if (num2 != 1) { VHModpackFixPlugin.LogWarning($"AdventureBackpacks save-path optimization expected one unused StackTrace in {__originalMethod?.DeclaringType?.FullName}.{__originalMethod?.Name}, found {num2}", null); return list; } list[num].opcode = OpCodes.Nop; list[num].operand = null; list[num + 1].opcode = OpCodes.Nop; list[num + 1].operand = null; return list; } private static bool CanAddPickupItem(Inventory regularInventory, ItemData item, int stack) { if (regularInventory == null || item == null) { if (regularInventory != null && item != null) { return regularInventory.CanAddItem(item, stack); } return false; } if (regularInventory.CanAddItem(item, stack)) { return true; } int num = ((stack <= 0) ? item.m_stack : stack); if (TryGetPickupBackpack(regularInventory, item, out var backpackInventory, out var capacity) && capacity >= num) { return backpackInventory.CanAddItem(item, num); } return false; } private static bool AddPickupItem(Inventory regularInventory, ItemData item) { ConfigEntry pickupRoutingEnabled = _pickupRoutingEnabled; if (pickupRoutingEnabled == null || !pickupRoutingEnabled.Value || regularInventory == null || item == null || !TryGetPickupBackpack(regularInventory, item, out var backpackInventory, out var capacity) || capacity < item.m_stack || !backpackInventory.CanAddItem(item, item.m_stack)) { if (regularInventory != null && item != null) { return regularInventory.AddItem(item); } return false; } return backpackInventory.AddItem(item); } private static bool MoveItemToThisPrefix(Inventory __instance, Inventory fromInventory, ItemData item) { ConfigEntry pickupRoutingEnabled = _pickupRoutingEnabled; if (pickupRoutingEnabled == null || !pickupRoutingEnabled.Value || !IsCurrentOpenedContainerTransfer(__instance, fromInventory) || !TryMoveWholeStackToBackpack(__instance, fromInventory, item)) { return true; } return false; } private static void MoveAllPrefix(Inventory __instance, Inventory fromInventory) { ConfigEntry pickupRoutingEnabled = _pickupRoutingEnabled; if (pickupRoutingEnabled != null && pickupRoutingEnabled.Value) { RouteCurrentContainerItems(Player.m_localPlayer, __instance, fromInventory); } } private static void SafeTakeAllPrefix(Player player, Inventory playerInventory, Inventory containerInventory, out int __state) { ConfigEntry pickupRoutingEnabled = _pickupRoutingEnabled; __state = ((pickupRoutingEnabled != null && pickupRoutingEnabled.Value) ? RouteCurrentContainerItems(player, playerInventory, containerInventory) : 0); } private static void SafeTakeAllPostfix(ref int __result, int __state) { if (__state > 0) { __result += __state; } } private static int RouteCurrentContainerItems(Player player, Inventory playerInventory, Inventory containerInventory) { if ((Object)(object)player == (Object)null || playerInventory == null || containerInventory == null || player != Player.m_localPlayer || playerInventory != ((Humanoid)player).GetInventory() || !IsCurrentOpenedContainerTransfer(playerInventory, containerInventory)) { return 0; } int num = 0; List list = new List(containerInventory.GetAllItems()); list.Sort(delegate(ItemData left, ItemData right) { int num3 = left.m_gridPos.y.CompareTo(right.m_gridPos.y); return (num3 == 0) ? left.m_gridPos.x.CompareTo(right.m_gridPos.x) : num3; }); for (int num2 = 0; num2 < list.Count; num2++) { ItemData item = list[num2]; if (TryMoveWholeStackToBackpack(playerInventory, containerInventory, item)) { num++; } } return num; } private static bool IsCurrentOpenedContainerTransfer(Inventory playerInventory, Inventory containerInventory) { Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; Container val = (Container)(((Object)(object)instance == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null || playerInventory == null || containerInventory == null || playerInventory != ((Humanoid)localPlayer).GetInventory() || val.GetInventory() != containerInventory || (Object)(object)((Component)val).GetComponent() != (Object)null || !CanMutateOpenedContainerDirectly(val, localPlayer)) { return false; } Inventory val2 = TryGetEquippedBackpackInventory(localPlayer); if (val2 != null) { return containerInventory != val2; } return false; } private static bool CanMutateOpenedContainerDirectly(Container container, Player player) { try { if (_containerCheckAccess != null) { object obj = _containerCheckAccess.Invoke(container, new object[1] { player.GetPlayerID() }); if (obj is bool && !(bool)obj) { return false; } } object? obj2 = _containerNetworkView?.GetValue(container); ZNetView val = (ZNetView)((obj2 is ZNetView) ? obj2 : null); return (Object)(object)val == (Object)null || !val.IsValid() || val.IsOwner(); } catch { return false; } } private static bool TryMoveWholeStackToBackpack(Inventory playerInventory, Inventory sourceInventory, ItemData item) { if (item == null || item.m_stack <= 0 || !sourceInventory.ContainsItem(item) || !TryGetPickupBackpack(playerInventory, item, out var backpackInventory, out var capacity) || sourceInventory == backpackInventory) { return false; } int stack = item.m_stack; if (capacity < stack || !backpackInventory.CanAddItem(item, stack)) { return false; } List list = new List(backpackInventory.GetAllItems()); int[] array = new int[list.Count]; for (int i = 0; i < list.Count; i++) { array[i] = list[i].m_stack; } ItemData val = item.Clone(); val.m_stack = stack; if (!backpackInventory.AddItem(val)) { RestoreBackpackTransfer(backpackInventory, val, list, array); VHModpackFixPlugin.LogWarning("AdventureBackpacks rejected a pre-checked whole-stack transfer; the normal inventory transfer was kept", null); return false; } sourceInventory.RemoveItem(item); if (sourceInventory.ContainsItem(item)) { RestoreBackpackTransfer(backpackInventory, val, list, array); VHModpackFixPlugin.LogWarning("AdventureBackpacks accepted an item but its source container could not remove the original stack", null); return false; } return true; } private static void RestoreBackpackTransfer(Inventory backpackInventory, ItemData transfer, List previousItems, int[] previousStacks) { List allItems = backpackInventory.GetAllItems(); allItems.Remove(transfer); for (int i = 0; i < previousItems.Count; i++) { ItemData val = previousItems[i]; if (allItems.Contains(val)) { val.m_stack = previousStacks[i]; } } _inventoryChanged.Invoke(backpackInventory, null); } private static bool TryGetPickupBackpack(Inventory regularInventory, ItemData item, out Inventory backpackInventory, out int capacity) { backpackInventory = null; capacity = 0; Player localPlayer = Player.m_localPlayer; ConfigEntry pickupRoutingEnabled = _pickupRoutingEnabled; if (pickupRoutingEnabled == null || !pickupRoutingEnabled.Value || (Object)(object)localPlayer == (Object)null || regularInventory != ((Humanoid)localPlayer).GetInventory() || item?.m_shared == null || item.m_stack <= 0 || item.m_shared.m_maxStackSize <= 1 || item.m_shared.m_questItem || item.IsWeapon() || HasUnsafeCustomData(item)) { return false; } backpackInventory = GetPickupBackpackInventory(localPlayer); if (backpackInventory == null || backpackInventory == regularInventory) { return false; } List allItems = backpackInventory.GetAllItems(); if (allItems == null || allItems.Count == 0) { return false; } string name = item.m_shared.m_name; bool flag = false; bool flag2 = false; bool flag3 = false; int num = 0; for (int num2 = allItems.Count - 1; num2 >= 0; num2--) { ItemData val = allItems[num2]; if (val == null || val.m_stack <= 0) { allItems.RemoveAt(num2); flag3 = true; } else if (val.m_shared != null && string.Equals(val.m_shared.m_name, name, StringComparison.Ordinal)) { flag = true; if (HasUnsafeCustomData(val)) { flag2 = true; } else if (val.m_quality == item.m_quality && val.m_worldLevel == item.m_worldLevel && val.m_stack < val.m_shared.m_maxStackSize) { num += val.m_shared.m_maxStackSize - val.m_stack; } } } if (flag3) { _inventoryChanged.Invoke(backpackInventory, null); } if (!flag || flag2) { return false; } int num3 = Math.Max(0, backpackInventory.GetEmptySlots()); capacity = num + num3 * Math.Max(1, item.m_shared.m_maxStackSize); return capacity > 0; } private static Inventory GetPickupBackpackInventory(Player player) { int frameCount = Time.frameCount; if (frameCount != _pickupBackpackCacheFrame || player != _pickupBackpackCachePlayer) { _pickupBackpackCacheFrame = frameCount; _pickupBackpackCachePlayer = player; _pickupBackpackCacheInventory = TryGetEquippedBackpackInventory(player); } return _pickupBackpackCacheInventory; } private static bool HasUnsafeCustomData(ItemData item) { if (item?.m_customData == null || item.m_customData.Count == 0) { return false; } foreach (string key in item.m_customData.Keys) { if (!string.Equals(key, "obelisk.vhmodpackfix.backpackFavorite", StringComparison.Ordinal) && !key.StartsWith("randyknapp.mods.epicloot#", StringComparison.Ordinal)) { return true; } } return false; } private static bool RepairLoadedBackpackSlotPrefix(Inventory __instance, ItemData item, int amount, ref int x, ref int y, ref bool __result) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!IsAdventureBackpackInventory(__instance)) { return true; } if (item == null || amount <= 0 || item.m_stack <= 0) { __result = false; return false; } int width = __instance.GetWidth(); int height = __instance.GetHeight(); if (x >= 0 && x < width && y >= 0 && y < height) { return true; } Vector2i val = FindFreeSlot(__instance, width, height, y); if (val.x >= 0) { x = val.x; y = val.y; } return true; } private static bool SkipEquippedBackpackContainerPrefix(object container, ref int __result) { if (!IsEquippedAdventureBackpackContainer(container)) { return true; } __result = 0; return false; } private static bool SkipPlayerContainerRegistrationPrefix(Container container, ref bool __result) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)container == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)((Component)container).gameObject != (Object)(object)((Component)localPlayer).gameObject) { return true; } __result = false; return false; } private static void TryStorePrefix() { _tryStoreScope = false; _backpackStored = 0; ConfigEntry autoStoreEnabled = _autoStoreEnabled; if (autoStoreEnabled == null || !autoStoreEnabled.Value || !_autoStoreReady) { return; } try { _tryStoreScope = true; _backpackStored = StoreEquippedBackpack(); } catch (Exception exception) { _backpackStored = 0; VHModpackFixPlugin.LogWarning("AdventureBackpacks/AzuAutoStore integration failed", Unwrap(exception)); } } private static Exception TryStoreFinalizer(Exception __exception) { _tryStoreScope = false; _suppressAzuFailureMessage = false; _backpackStored = 0; ClearActiveStoreScope(); return __exception; } private static void StoreSuccessPrefix(ref int total) { if (_tryStoreScope) { total += _backpackStored; _backpackStored = 0; } } private static void InventoryChangedPrefix(Inventory __instance) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (__instance == _activeStoreInventory && _activeStoreItem != null) { _activeStoreItem.m_gridPos = _activeStoreOriginalPosition; } if (_favoritePatched && IsAdventureBackpackInventory(__instance)) { _favoriteBordersDirty = true; } } private static int StoreEquippedBackpack() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0; } Inventory val = TryGetEquippedBackpackInventory(localPlayer); if (val == null) { return 0; } RemoveInvalidRuntimeStacks(val); List allItems = val.GetAllItems(); if (allItems == null || allItems.Count == 0) { return 0; } object[] array = _nearbyInvokeArguments ?? (_nearbyInvokeArguments = new object[2]); array[0] = localPlayer; array[1] = GetPlayerRange(); object obj; try { obj = _getNearbyContainers.Invoke(null, array); } finally { array[0] = null; array[1] = null; } if (!(obj is IEnumerable enumerable)) { return 0; } List list = new List(allItems.Count); for (int i = 0; i < allItems.Count; i++) { ItemData val2 = allItems[i]; if (val2 != null && val2.m_stack > 0 && !val2.m_equipped && !IsBackpackItem(val2) && !IsBackpackStackFavorite(val2)) { list.Add(val2); } } int num = 0; foreach (object item in enumerable) { if (item == null || !IsSupportedContainer(item) || IsUnsafeSelfTarget(item, val, localPlayer)) { continue; } for (int num2 = list.Count - 1; num2 >= 0; num2--) { ItemData val3 = list[num2]; if (val3 == null || val3.m_stack <= 0 || !val.ContainsItem(val3)) { list.RemoveAt(num2); } else { num += StoreItem(item, val3, val, out var stopPass); if (stopPass) { return num; } if (val3.m_stack <= 0 || !val.ContainsItem(val3)) { list.RemoveAt(num2); } } } if (list.Count == 0) { break; } } return num; } private static int StoreItem(object container, ItemData sourceItem, Inventory sourceInventory, out bool stopPass) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0073: Unknown result type (might be due to invalid IL or missing references) stopPass = false; int stack = sourceItem.m_stack; Vector2i gridPos = sourceItem.m_gridPos; Exception ex = null; _activeStoreInventory = sourceInventory; _activeStoreItem = sourceItem; _activeStoreOriginalPosition = gridPos; sourceItem.m_gridPos = new Vector2i(-1, -1); _suppressAzuFailureMessage = true; object[] array = _storeInvokeArguments ?? (_storeInvokeArguments = new object[3]); array[0] = container; array[1] = sourceItem; array[2] = sourceInventory; try { _storeToContainer.Invoke(null, array); } catch (Exception exception) { ex = Unwrap(exception); } finally { sourceItem.m_gridPos = gridPos; _suppressAzuFailureMessage = false; array[0] = null; array[1] = null; array[2] = null; ClearActiveStoreScope(); } if (sourceItem.m_stack <= 0 && sourceInventory.ContainsItem(sourceItem) && !RemoveZeroStack(sourceInventory, sourceItem)) { stopPass = true; VHModpackFixPlugin.LogWarning("AdventureBackpacks/AzuAutoStore could not clear an exhausted backpack stack", null); } int num = (sourceInventory.ContainsItem(sourceItem) ? Math.Max(0, sourceItem.m_stack) : 0); int num2 = Math.Max(0, Math.Min(stack, stack - num)); if (ex != null) { stopPass = true; VHModpackFixPlugin.LogWarning((num2 > 0) ? "AdventureBackpacks/AzuAutoStore stopped after a container accepted part of a stack and then reported an error" : "AdventureBackpacks/AzuAutoStore stopped after a container rejected a backpack transfer with an error", ex); } return num2; } private static bool RemoveZeroStack(Inventory inventory, ItemData item) { inventory.RemoveItem(item); if (!inventory.ContainsItem(item)) { return true; } inventory.GetAllItems().Remove(item); _inventoryChanged.Invoke(inventory, null); return !inventory.ContainsItem(item); } private static void ClearActiveStoreScope() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (_activeStoreItem != null) { _activeStoreItem.m_gridPos = _activeStoreOriginalPosition; } _activeStoreInventory = null; _activeStoreItem = null; _activeStoreOriginalPosition = default(Vector2i); } private static bool BackpackLeftClickPrefix(InventoryGrid __instance, UIInputHandler clickHandler) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)clickHandler == (Object)null)) { object? obj = _inventoryGridInventory?.GetValue(__instance); Inventory val = (Inventory)((obj is Inventory) ? obj : null); if (val != null && IsAdventureBackpackInventory(val) && IsBackpackFavoritingInputHeld()) { Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; GameObject val2 = (GameObject)(((Object)(object)instance == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || (Object)(object)val2 != (Object)null) { return true; } Vector2i val3; try { val3 = (Vector2i)_inventoryGridGetButtonPos.Invoke(__instance, new object[1] { ((Component)clickHandler).gameObject }); } catch (Exception exception) { LogFavoriteFailure("AdventureBackpacks could not read the clicked backpack slot", exception); return true; } if (val3.x < 0 || val3.y < 0) { return true; } ItemData itemAt = val.GetItemAt(val3.x, val3.y); if (itemAt?.m_shared == null) { return true; } try { ToggleBackpackStackFavorite(itemAt); _inventoryChanged.Invoke(val, null); _favoriteBordersDirty = true; return false; } catch (Exception exception2) { LogFavoriteFailure("AdventureBackpacks could not update the AzuAutoStore favorite item", exception2); return true; } } } return true; } private static bool AzuFavoriteCheckPrefix(ItemData item, ref bool __result) { if (IsBackpackStackFavorite(item)) { __result = true; return false; } if (item != null && item == _activeStoreItem && IsAdventureBackpackInventory(_activeStoreInventory)) { __result = false; return false; } return true; } private static bool IsBackpackFavoritingInputHeld() { object obj = _favoritingToggleState?.GetValue(null); if (obj is bool && (bool)obj) { return true; } if (!IsShortcutHeld(_favoritingModifier1)) { return IsShortcutHeld(_favoritingModifier2); } return true; } private static bool IsShortcutHeld(FieldInfo shortcutField) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!(shortcutField?.GetValue(null) is ConfigEntry val)) { return false; } KeyboardShortcut value = val.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !UnityInput.Current.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!UnityInput.Current.GetKey(modifier)) { return false; } } return true; } private static void ToggleBackpackStackFavorite(ItemData item) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } if (!item.m_customData.Remove("obelisk.vhmodpackfix.backpackFavorite")) { item.m_customData["obelisk.vhmodpackfix.backpackFavorite"] = "1"; } } private static bool IsBackpackStackFavorite(ItemData item) { if (item?.m_customData != null) { return item.m_customData.ContainsKey("obelisk.vhmodpackfix.backpackFavorite"); } return false; } private static void RenderFavoriteBordersPostfix(InventoryGrid __instance) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) if (!_favoritePatched || (Object)(object)__instance == (Object)null) { return; } object? obj = _inventoryGridInventory?.GetValue(__instance); Inventory val = (Inventory)((obj is Inventory) ? obj : null); if (val == null || !IsAdventureBackpackInventory(val) || !(_inventoryGridElements?.GetValue(__instance) is IList list)) { return; } Image val2 = ((list.Count > 0) ? GetQueuedImage(list[0]) : null); if (_lastBorderGrid != __instance || _lastBorderInventory != val || _lastBorderElementCount != list.Count || _lastBorderFirstQueuedImage != val2) { _lastBorderGrid = __instance; _lastBorderInventory = val; _lastBorderElementCount = list.Count; _lastBorderFirstQueuedImage = val2; _favoriteBordersDirty = true; } if (!_favoriteBordersDirty) { return; } try { Color favoriteBorderColor = GetFavoriteBorderColor(); for (int i = 0; i < list.Count; i++) { Image val3 = FindFavoriteBorder(GetQueuedImage(list[i])); if ((Object)(object)val3 != (Object)null) { ((Behaviour)val3).enabled = false; } } int width = val.GetWidth(); List allItems = val.GetAllItems(); for (int j = 0; j < allItems.Count; j++) { ItemData val4 = allItems[j]; if (val4?.m_shared == null || val4.m_stack <= 0 || !IsBackpackStackFavorite(val4)) { continue; } int num = val4.m_gridPos.y * width + val4.m_gridPos.x; if (num >= 0 && num < list.Count) { Image queuedImage = GetQueuedImage(list[num]); Image val5 = FindFavoriteBorder(queuedImage) ?? CreateFavoriteBorder(queuedImage); if (!((Object)(object)val5 == (Object)null)) { ((Graphic)val5).color = favoriteBorderColor; ((Behaviour)val5).enabled = true; } } } _favoriteBordersDirty = false; } catch (Exception exception) { LogFavoriteFailure("AdventureBackpacks could not draw AzuAutoStore favorite borders", exception); } } private static Image GetQueuedImage(object element) { if (element == null) { return null; } if ((object)_elementQueuedImage == null) { _elementQueuedImage = AccessTools.Field(element.GetType(), "m_queued"); } object? obj = _elementQueuedImage?.GetValue(element); return (Image)((obj is Image) ? obj : null); } private static Image FindFavoriteBorder(Image queued) { Transform val = (((Object)(object)queued == (Object)null) ? null : ((Component)queued).transform.Find("AzuAutoStoreFavoritingBorder")); if (!((Object)(object)val == (Object)null)) { return ((Component)val).GetComponent(); } return null; } private static Image CreateFavoriteBorder(Image queued) { if ((Object)(object)queued == (Object)null || _createFavoriteBorder == null) { return null; } object? obj = _createFavoriteBorder.Invoke(null, new object[1] { queued }); return (Image)((obj is Image) ? obj : null); } private static Color GetFavoriteBorderColor() { //IL_005c: 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) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) object obj = _favoriteBorderColor?.GetValue(null); object obj2 = obj?.GetType().GetProperty("Value")?.GetValue(obj); if (obj2 is Color) { return (Color)obj2; } return new Color(1f, 0.8482759f, 0f, 1f); } private static void LogFavoriteFailure(string message, Exception exception) { if (!_favoriteFailureLogged) { _favoriteFailureLogged = true; VHModpackFixPlugin.LogWarning(message, Unwrap(exception)); } } private static void RemoveInvalidRuntimeStacks(Inventory inventory) { List list = ((inventory != null) ? inventory.GetAllItems() : null); if (list != null && list.RemoveAll((ItemData item) => item == null || item.m_stack <= 0) > 0) { _inventoryChanged.Invoke(inventory, null); } } private static Vector2i FindFreeSlot(Inventory inventory, int width, int height, int preferredRow) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (preferredRow >= 0 && preferredRow < height) { for (int i = 0; i < width; i++) { if (inventory.GetItemAt(i, preferredRow) == null) { return new Vector2i(i, preferredRow); } } } for (int j = 0; j < height; j++) { if (j == preferredRow) { continue; } for (int k = 0; k < width; k++) { if (inventory.GetItemAt(k, j) == null) { return new Vector2i(k, j); } } } return new Vector2i(-1, -1); } internal static Inventory TryGetEquippedBackpackInventory(Player player) { try { return GetEquippedBackpackInventory(player); } catch (Exception exception) { if (!_pickupApiFailureLogged) { _pickupApiFailureLogged = true; VHModpackFixPlugin.LogWarning("AdventureBackpacks compatibility could not read the equipped backpack", Unwrap(exception)); } return null; } } private static Inventory GetEquippedBackpackInventory(Player player) { object[] array = _playerInvokeArguments ?? (_playerInvokeArguments = new object[1]); array[0] = player; try { object obj = _getEquippedBackpack.Invoke(null, array); return (Inventory)((obj == null) ? null : /*isinst with value type is only supported in some contexts*/); } finally { array[0] = null; } } private static bool IsBackpackItem(ItemData item) { object[] array = _itemInvokeArguments ?? (_itemInvokeArguments = new object[1]); array[0] = item; try { object obj = _isBackpackItem?.Invoke(null, array); return obj is bool && (bool)obj; } finally { array[0] = null; } } private static bool IsAdventureBackpackInventory(Inventory inventory) { if (inventory == null) { return false; } string name = inventory.GetName(); if (!string.IsNullOrEmpty(name)) { return name.IndexOf("$vapok_mod_level", StringComparison.Ordinal) >= 0; } return false; } private static bool IsSupportedContainer(object container) { string fullName = container.GetType().FullName; if (!string.Equals(fullName, "AzuAutoStore.Interfaces.VanillaContainers", StringComparison.Ordinal) && !string.Equals(fullName, "AzuAutoStore.Interfaces.kgDrawer", StringComparison.Ordinal)) { return string.Equals(fullName, "AzuAutoStore.Interfaces.BackpackContainer", StringComparison.Ordinal); } return true; } private static bool IsEquippedAdventureBackpackContainer(object container) { if (container == null || !string.Equals(container.GetType().FullName, "AzuAutoStore.Interfaces.VanillaContainers", StringComparison.Ordinal)) { return false; } try { Player localPlayer = Player.m_localPlayer; object? obj = _containerGameObject?.GetValue(container); GameObject val = (GameObject)((obj is GameObject) ? obj : null); int result; if ((Object)(object)localPlayer != (Object)null && (Object)(object)val == (Object)(object)((Component)localPlayer).gameObject) { object? obj2 = _vanillaContainerGetInventory?.Invoke(container, null); Inventory val2 = (Inventory)((obj2 is Inventory) ? obj2 : null); if (val2 != null) { result = (IsAdventureBackpackInventory(val2) ? 1 : 0); goto IL_0078; } } result = 0; goto IL_0078; IL_0078: return (byte)result != 0; } catch { return false; } } private static bool IsUnsafeSelfTarget(object container, Inventory sourceInventory, Player player) { try { if (string.Equals(container.GetType().FullName, "AzuAutoStore.Interfaces.VanillaContainers", StringComparison.Ordinal)) { object? obj = _vanillaContainerGetInventory?.Invoke(container, null); Inventory val = (Inventory)((obj is Inventory) ? obj : null); if (val != null && val == sourceInventory) { return true; } } object? obj2 = _containerGameObject?.GetValue(container); GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null); return (Object)(object)val2 != (Object)null && (Object)(object)player != (Object)null && (Object)(object)val2 == (Object)(object)((Component)player).gameObject; } catch (Exception exception) { VHModpackFixPlugin.LogWarning("AdventureBackpacks/AzuAutoStore skipped a container whose target could not be verified", Unwrap(exception)); return true; } } private static float GetPlayerRange() { object obj = _playerRange?.GetValue(null); if (!(obj?.GetType().GetProperty("Value")?.GetValue(obj) is float num) || !(num > 0f)) { return 20f; } return num; } private static Type FindLoadedType(string fullName) { if (string.IsNullOrEmpty(fullName)) { return null; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } catch { } } return null; } private static Exception Unwrap(Exception exception) { if (!(exception is TargetInvocationException ex) || exception.InnerException == null) { return exception; } return ex.InnerException; } private static bool ShouldSuppressMessage(MessageType type, string message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if (!_suppressAzuFailureMessage || (int)type != 2 || string.IsNullOrEmpty(message)) { return false; } if (message.IndexOf("is not in nearby containers", StringComparison.Ordinal) < 0) { return message.IndexOf("cannot be stored based on configuration settings", StringComparison.Ordinal) >= 0; } return true; } } internal static class AdventureBackpacksContainerPanel { private const string ConfigRegistryTypeName = "AdventureBackpacks.Configuration.ConfigRegistry"; private const string InventoryGuiPatchesTypeName = "AdventureBackpacks.Patches.InventoryGuiPatches"; private const string PanelName = "VHModpackFix_AdventureBackpackPanel"; private static ConfigEntry _enabled; private static ConfigEntry _offsetX; private static ConfigEntry _offsetY; private static FieldInfo _currentContainerField; private static FieldInfo _dragItemField; private static FieldInfo _openWithInventoryField; private static FieldInfo _openWithHoverField; private static FieldInfo _backpackIsOpenField; private static RectTransform _panel; private static InventoryGrid _grid; private static TMP_Text _nameText; private static TMP_Text _weightText; private static InventoryGui _ownerGui; private static Inventory _shownInventory; private static bool _patched; private static bool _failureLogged; internal static void Init(Harmony harmony, ConfigFile config) { //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown _enabled = ConfigLayout.Bind(config, "AdventureBackpacks", "Show backpack beside opened containers", defaultValue: true, "When AdventureBackpacks' 'Open with Inventory' option is enabled, shows the equipped backpack beside a chest or other opened container.", "AdventureBackpacks UI"); _offsetX = ConfigLayout.Bind(config, "AdventureBackpacks", "Backpack panel offset X", 650f, "Horizontal backpack-panel offset from the opened container panel. Positive values move it right.", "AdventureBackpacks UI"); _offsetY = ConfigLayout.Bind(config, "AdventureBackpacks", "Backpack panel offset Y", 0f, "Vertical backpack-panel offset from the opened container panel. Positive values move it up.", "AdventureBackpacks UI"); if (harmony == null || AccessTools.TypeByName("AdventureBackpacks.Patches.InventoryGuiPatches") == null) { return; } ResolveFields(); if (!(_currentContainerField == null) && !(_dragItemField == null) && !_patched) { PatchPostfix(harmony, AccessTools.Method(typeof(InventoryGui), "Awake", (Type[])null, (Type[])null), "InventoryGuiAwakePostfix"); PatchPostfix(harmony, AccessTools.Method(typeof(InventoryGui), "UpdateContainer", (Type[])null, (Type[])null), "UpdateContainerPostfix"); PatchPostfix(harmony, AccessTools.Method(typeof(InventoryGui), "Hide", (Type[])null, (Type[])null), "HidePostfix"); PatchPostfix(harmony, AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null), "HidePostfix"); PatchPostfix(harmony, AccessTools.Method(typeof(InventoryGui), "OnDestroy", (Type[])null, (Type[])null), "OnDestroyPostfix"); MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "OnSelectedItem", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AdventureBackpacksContainerPanel), "OnSelectedItemPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } _patched = true; } } private static void ResolveFields() { _currentContainerField = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); _dragItemField = AccessTools.Field(typeof(InventoryGui), "m_dragItem"); Type type = AccessTools.TypeByName("AdventureBackpacks.Configuration.ConfigRegistry"); _openWithInventoryField = ((type == null) ? null : AccessTools.Field(type, "OpenWithInventory")); _openWithHoverField = ((type == null) ? null : AccessTools.Field(type, "OpenWithHoverInteract")); Type type2 = AccessTools.TypeByName("AdventureBackpacks.Patches.InventoryGuiPatches"); _backpackIsOpenField = ((type2 == null) ? null : AccessTools.Field(type2, "BackpackIsOpen")); } private static void PatchPostfix(Harmony harmony, MethodInfo original, string patchName) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (original != null) { harmony.Patch((MethodBase)original, (HarmonyMethod)null, new HarmonyMethod(typeof(AdventureBackpacksContainerPanel), patchName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void InventoryGuiAwakePostfix(InventoryGui __instance) { try { DestroyPanel(); CreatePanel(__instance); } catch (Exception exception) { DestroyPanel(); LogFailure("AdventureBackpacks side panel could not be created", exception); } } private static void UpdateContainerPostfix(InventoryGui __instance, Player player) { if ((Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null || __instance != _ownerGui) { HidePanel(); return; } try { RefreshPanel(__instance, player); } catch (Exception exception) { HidePanel(); LogFailure("AdventureBackpacks side panel was disabled after an unexpected UI error", exception); } } private static void RefreshPanel(InventoryGui gui, Player player) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panel == (Object)null) && !((Object)(object)_grid == (Object)null)) { ConfigEntry enabled = _enabled; if (enabled != null && enabled.Value && AdventureBackpacksOpenWithInventory() && !AdventureBackpackIsAlreadyOpen()) { object? value = _currentContainerField.GetValue(gui); Container val = (Container)((value is Container) ? value : null); if ((Object)(object)val == (Object)null || !val.IsOwner()) { HidePanel(); return; } Inventory val2 = AdventureBackpacksAutoStoreCompat.TryGetEquippedBackpackInventory(player); Inventory inventory = val.GetInventory(); if (val2 == null || inventory == null || val2 == inventory) { HidePanel(); return; } _panel.anchoredPosition = gui.m_container.anchoredPosition + new Vector2(_offsetX.Value, _offsetY.Value); bool num = !((Component)_panel).gameObject.activeSelf || _shownInventory != val2; if (!((Component)_panel).gameObject.activeSelf) { _shownInventory = val2; ((Component)_panel).gameObject.SetActive(true); } else if (_shownInventory != val2) { _shownInventory = val2; } object? value2 = _dragItemField.GetValue(gui); ItemData val3 = (ItemData)((value2 is ItemData) ? value2 : null); _grid.UpdateInventory(val2, (Player)null, val3); if (num) { _grid.ResetView(); } if ((Object)(object)_nameText != (Object)null) { string name = val2.GetName(); _nameText.text = ((Localization.instance == null) ? name : Localization.instance.Localize(name)); } if ((Object)(object)_weightText != (Object)null) { _weightText.text = Mathf.CeilToInt(val2.GetTotalWeight()).ToString(); } return; } } HidePanel(); } private static bool AdventureBackpacksOpenWithInventory() { ConfigEntry obj = _openWithInventoryField?.GetValue(null) as ConfigEntry; if (obj == null || !obj.Value) { return false; } ConfigEntry obj2 = _openWithHoverField?.GetValue(null) as ConfigEntry; if (obj2 == null) { return true; } return !obj2.Value; } private static bool AdventureBackpackIsAlreadyOpen() { object obj = _backpackIsOpenField?.GetValue(null); if (obj is bool) { return (bool)obj; } return false; } private static void CreatePanel(InventoryGui gui) { if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_container == (Object)null) { return; } GameObject val = Object.Instantiate(((Component)gui.m_container).gameObject, ((Transform)gui.m_container).parent, false); ((Object)val).name = "VHModpackFix_AdventureBackpackPanel"; _panel = val.GetComponent(); _ownerGui = gui; _grid = FindClonedComponent((Transform)(object)gui.m_container, (Transform)(object)_panel, gui.ContainerGrid); if ((Object)(object)_panel == (Object)null || (Object)(object)_grid == (Object)null) { DestroyPanel(); return; } _nameText = FindClonedComponent((Transform)(object)gui.m_container, (Transform)(object)_panel, gui.m_containerName); _weightText = FindClonedComponent((Transform)(object)gui.m_container, (Transform)(object)_panel, gui.m_containerWeight); Button val2 = FindClonedComponent