Decompiled source of OG Backpack v1.8.1

Backpack.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Backpack;
using Backpack.Config;
using HarmonyLib;
using Il2CppFishNet.Component.Spawning;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Levelling;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.Networking;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.Vehicles;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Linq;
using Il2CppTMPro;
using Il2CppVLB;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(BackpackMod), "OG Backpack", "1.8.1", "D-Kay", "https://www.nexusmods.com/schedule1/mods/818")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyMetadata("NexusModID", "818")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Backpack")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("1.8.1.0")]
[assembly: AssemblyInformationalVersion("1.8.1+de53a81d82a6053cca09145320aff996005d4b47")]
[assembly: AssemblyProduct("Backpack")]
[assembly: AssemblyTitle("Backpack")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.1.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Backpack
{
	public class BackpackMod : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Configuration.Instance.Load();
			Configuration.Instance.Save();
			Logger.Info("Backpack initialized.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			Configuration.Instance.Reset();
			if (!(sceneName != "Main"))
			{
				ConfigSyncManager.StartSync();
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	public class PlayerBackpack : MonoBehaviour
	{
		public const string StorageName = "Backpack";

		public const int MaxStorageSlots = 128;

		private bool _backpackEnabled = true;

		private StorageEntity _storage;

		public static PlayerBackpack Instance { get; private set; }

		public bool IsUnlocked => NetworkSingleton<LevelManager>.Instance.GetFullRank() >= Configuration.Instance.UnlockLevel;

		public bool IsOpen => Singleton<StorageMenu>.Instance.IsOpen && ((TMP_Text)Singleton<StorageMenu>.Instance.TitleLabel).text == "Backpack";

		public List<ItemSlot> ItemSlots => Enumerable.ToList<ItemSlot>(((Il2CppObjectBase)_storage.ItemSlots).Cast<IEnumerable<ItemSlot>>());

		public PlayerBackpack(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			_storage = ((Component)this).gameObject.GetComponentInParent<StorageEntity>();
			if ((Object)(object)_storage == (Object)null)
			{
				Logger.Error("Player does not have a BackpackStorage component!");
				return;
			}
			Logger.Info("Configuring backpack storage...");
			UpdateSize(Configuration.Instance.StorageSlots);
			OnStartClient(isOwner: true);
		}

		private void Update()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!_backpackEnabled || !IsUnlocked || !Input.GetKeyDown(Configuration.Instance.ToggleKey))
			{
				return;
			}
			try
			{
				if (IsOpen)
				{
					Close();
				}
				else
				{
					Open();
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error toggling backpack: " + ex.Message);
			}
		}

		public void SetBackpackEnabled(bool state)
		{
			if (!state)
			{
				Close();
			}
			_backpackEnabled = state;
		}

		public void Open()
		{
			if (_backpackEnabled && IsUnlocked && !Singleton<ManagementClipboard>.Instance.IsEquipped && !Singleton<StorageMenu>.Instance.IsOpen && !PlayerSingleton<Phone>.Instance.IsOpen)
			{
				StorageMenu instance = Singleton<StorageMenu>.Instance;
				instance.SlotGridLayout.constraintCount = _storage.DisplayRowCount;
				instance.Open("Backpack", string.Empty, ((Il2CppObjectBase)_storage).Cast<IItemSlotOwner>());
				_storage.SendAccessor(((NetworkBehaviour)Player.Local).NetworkObject);
			}
		}

		public void Close()
		{
			if (_backpackEnabled && IsOpen)
			{
				Singleton<StorageMenu>.Instance.CloseMenu();
				_storage.SendAccessor((NetworkObject)null);
			}
		}

		public bool ContainsItemsOfInterest(EStealthLevel maxStealthLevel)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0099: 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)
			for (int i = 0; i < _storage.ItemSlots.Count; i++)
			{
				List<ItemSlot> itemSlots = _storage.ItemSlots;
				ItemSlot val = ((Il2CppObjectBase)itemSlots[new Index(i).GetOffset(itemSlots.Count)]).Cast<ItemSlot>();
				if (((val != null) ? val.ItemInstance : null) == null)
				{
					continue;
				}
				ProductItemInstance val2 = ((Il2CppObjectBase)val.ItemInstance).TryCast<ProductItemInstance>();
				if (val2 == null)
				{
					if ((int)val.ItemInstance.Definition.legalStatus > 0)
					{
						return true;
					}
				}
				else if ((Object)(object)val2.AppliedPackaging == (Object)null || val2.AppliedPackaging.StealthLevel <= maxStealthLevel)
				{
					return true;
				}
			}
			return false;
		}

		public void Upgrade(int slotCount)
		{
			if ((slotCount >= 1 && slotCount <= 128) || 1 == 0)
			{
				int num = _storage.SlotCount + slotCount;
				if (num > 128)
				{
					Logger.Warning("Cannot upgrade backpack to more than {0} slots.", 128);
				}
				else
				{
					UpdateSize(num);
				}
			}
		}

		public void Downgrade(int slotCount, bool force = false)
		{
			if (slotCount < 1)
			{
				return;
			}
			if (!force && slotCount >= _storage.SlotCount)
			{
				Logger.Warning("Cannot downgrade backpack to zero slots. A minimum of one must remain.");
				return;
			}
			int num = _storage.SlotCount - slotCount;
			if (num < 1)
			{
				num = 1;
			}
			if (force)
			{
				UpdateSize(num);
				return;
			}
			bool flag = true;
			List<ItemSlot> range = _storage.ItemSlots.GetRange(num, _storage.SlotCount - num);
			for (int i = 0; i < range.Count; i++)
			{
				List<ItemSlot> val = range;
				ItemSlot val2 = ((Il2CppObjectBase)val[new Index(i).GetOffset(val.Count)]).Cast<ItemSlot>();
				if (((val2 != null) ? val2.ItemInstance : null) != null)
				{
					Logger.Warning("Downgrading backpack will remove item: " + ((Object)val2.ItemInstance.Definition).name);
					flag = false;
				}
			}
			if (!flag)
			{
				Logger.Warning("Cannot downgrade backpack due to items present in removed slots.");
			}
			else
			{
				UpdateSize(num);
			}
		}

		private void UpdateSize(int newSize)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			_storage.SlotCount = newSize;
			StorageEntity storage = _storage;
			if (1 == 0)
			{
			}
			int displayRowCount = ((newSize <= 20) ? ((int)Math.Ceiling((double)newSize / 5.0)) : ((newSize > 80) ? ((int)Math.Ceiling((double)newSize / 16.0)) : ((int)Math.Ceiling((double)newSize / 10.0))));
			if (1 == 0)
			{
			}
			storage.DisplayRowCount = displayRowCount;
			if (_storage.ItemSlots.Count > newSize)
			{
				_storage.ItemSlots.RemoveRange(newSize, _storage.ItemSlots.Count - newSize);
				return;
			}
			for (int i = _storage.ItemSlots.Count; i < newSize; i++)
			{
				ItemSlot val = new ItemSlot();
				if ((Delegate)(object)val.onItemDataChanged == (Delegate)null)
				{
					val.onItemDataChanged = Action.op_Implicit((Action)_storage.ContentsChanged);
				}
				else
				{
					((Delegate)val.onItemDataChanged).CombineImpl((Delegate)(object)Action.op_Implicit((Action)_storage.ContentsChanged));
				}
				val.SetSlotOwner(((Il2CppObjectBase)_storage).Cast<IItemSlotOwner>());
			}
		}

		private void OnStartClient(bool isOwner)
		{
			if (!isOwner)
			{
				Logger.Info("Destroying non-local player singleton: " + ((Object)this).name, null);
				Object.Destroy((Object)(object)this);
			}
			else if ((Object)(object)Instance != (Object)null)
			{
				Logger.Warning("Multiple instances of " + ((Object)this).name + " exist. Keeping prior instance reference.", null);
			}
			else
			{
				Instance = this;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	public static class Logger
	{
		public static void Debug(string message, params object[] args)
		{
			Melon<BackpackMod>.Logger.Msg(ConsoleColor.DarkMagenta, message, args);
		}

		public static void Info(string message, params object[] args)
		{
			Melon<BackpackMod>.Logger.Msg(message, args);
		}

		public static void Warning(string message, params object[] args)
		{
			Melon<BackpackMod>.Logger.Warning(message, args);
		}

		public static void Error(string message, params object[] args)
		{
			Melon<BackpackMod>.Logger.Error(message, args);
		}

		public static void Error(Exception exception, string message, params object[] args)
		{
			Melon<BackpackMod>.Logger.Error(string.Format(message, args), exception);
		}
	}
	public static class PlayerExtensions
	{
		public static StorageEntity GetBackpackStorage(this Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				throw new ArgumentNullException("player");
			}
			StorageEntity component = ((Component)player).gameObject.GetComponent<StorageEntity>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("Player does not have a BackpackStorage component.");
			}
			return component;
		}
	}
	public static class ResourceUtils
	{
		public static bool TryLoadTexture(string resourcePath, out Texture2D texture)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			texture = null;
			using Stream stream = typeof(ResourceUtils).Assembly.GetManifestResourceStream(resourcePath);
			if (stream == null)
			{
				Logger.Error("Failed to load resource: " + resourcePath);
				return false;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			texture = new Texture2D(0, 0);
			((Texture)texture).filterMode = (FilterMode)0;
			ImageConversion.LoadImage(texture, Il2CppStructArray<byte>.op_Implicit(array));
			return true;
		}
	}
}
namespace Backpack.Patches
{
	[HarmonyPatch(typeof(BodySearchBehaviour))]
	public static class BodySearchBehaviourPatch
	{
		[CompilerGenerated]
		private sealed class <CheckForItems>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public BodySearchBehaviour behaviour;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckForItems>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					((NPC)behaviour.officer).dialogueHandler.ShowWorldspaceDialogue("Hold on, let me see your backpack as well.", 5f);
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Singleton<BodySearchScreen>.Instance.IsOpen = false;
					behaviour.ConcludeSearch(!PlayerBackpack.Instance.ContainsItemsOfInterest(behaviour.MaxStealthLevel));
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[HarmonyPatch("SearchClean")]
		[HarmonyPrefix]
		public static bool SearchClean(BodySearchBehaviour __instance)
		{
			if (!PlayerBackpack.Instance.IsUnlocked || !Configuration.Instance.EnableSearch)
			{
				return true;
			}
			Singleton<BodySearchScreen>.Instance.onSearchClear.RemoveListener(UnityAction.op_Implicit((Action)__instance.SearchClean));
			Singleton<BodySearchScreen>.Instance.onSearchFail.RemoveListener(UnityAction.op_Implicit((Action)__instance.SearchFail));
			Singleton<BodySearchScreen>.Instance.IsOpen = true;
			MelonCoroutines.Start(CheckForItems(__instance));
			return false;
		}

		[IteratorStateMachine(typeof(<CheckForItems>d__1))]
		private static IEnumerator CheckForItems(BodySearchBehaviour behaviour)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckForItems>d__1(0)
			{
				behaviour = behaviour
			};
		}
	}
	[HarmonyPatch(typeof(Cart))]
	public static class CartPatch
	{
		[HarmonyPatch("GetWarning")]
		[HarmonyPostfix]
		public static void GetWarning(Cart __instance, ref bool __result, ref string warning)
		{
			if (PlayerBackpack.Instance.IsUnlocked && !warning.StartsWith("Vehicle") && __result)
			{
				List<ItemSlot> itemSlots = PlayerBackpack.Instance.ItemSlots;
				itemSlots.InsertRange(0, ((Il2CppObjectBase)PlayerSingleton<PlayerInventory>.Instance.hotbarSlots).Cast<IEnumerable<ItemSlot>>());
				if (__instance.Shop.WillCartFit(itemSlots))
				{
					warning = "Inventory won't fit everything. Some items will be placed in your backpack.";
				}
			}
		}
	}
	[HarmonyPatch(typeof(LevelManager))]
	public static class LevelManagerPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake(LevelManager __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null)
			{
				Logger.Error("LevelManager instance is null!");
				return;
			}
			if (!ResourceUtils.TryLoadTexture("Backpack.Assets.Icon.png", out var texture))
			{
				Logger.Error("Failed to load backpack icon texture.");
				return;
			}
			Sprite val = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f));
			Unlockable val2 = new Unlockable(Configuration.Instance.UnlockLevel, "Backpack", val);
			__instance.AddUnlockable(val2);
		}
	}
	[HarmonyPatch(typeof(PlayerManager))]
	public static class PlayerManagerPatch
	{
		[HarmonyPatch("TryGetPlayerData")]
		[HarmonyPostfix]
		public static void TryGetPlayerData(PlayerManager __instance, PlayerData data, ref string inventoryString)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (data != null)
			{
				List<string> loadedPlayerDataPaths = __instance.loadedPlayerDataPaths;
				String val = String.op_Implicit(loadedPlayerDataPaths[new Index(__instance.loadedPlayerData.IndexOf(data)).GetOffset(loadedPlayerDataPaths.Count)]);
				PlayerLoader val2 = new PlayerLoader();
				string text = default(string);
				if (!((Loader)val2).TryLoadFile(String.op_Implicit(val), "Backpack", ref text))
				{
					Logger.Warning("Failed to load player backpack under " + String.op_Implicit(val));
				}
				else
				{
					inventoryString = inventoryString + "|||" + text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	public static class PlayerPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void Awake(Player __instance)
		{
			if (!__instance.LocalExtraFiles.Contains("Backpack"))
			{
				Logger.Info("Registering backpack file for player.");
				__instance.LocalExtraFiles.Add("Backpack");
			}
		}

		[HarmonyPatch("WriteData")]
		[HarmonyPostfix]
		public static void WriteData(Player __instance, string parentFolderPath)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			StorageEntity backpackStorage = __instance.GetBackpackStorage();
			string jSON = new ItemSet(backpackStorage.ItemSlots).GetJSON();
			((Il2CppObjectBase)__instance).Cast<ISaveable>().WriteSubfile(parentFolderPath, "Backpack", jSON);
		}

		[HarmonyPatch("Load", new Type[]
		{
			typeof(PlayerData),
			typeof(string)
		})]
		[HarmonyPrefix]
		public static void Load(Player __instance, PlayerData data, string containerPath)
		{
			string text = default(string);
			if (!__instance.Loader.TryLoadFile(containerPath, "Backpack", ref text))
			{
				return;
			}
			Logger.Info("Loading local backpack data.");
			try
			{
				StorageEntity backpackStorage = __instance.GetBackpackStorage();
				DeserializedItemSet val = default(DeserializedItemSet);
				if (!ItemSet.TryDeserialize(text, ref val))
				{
					Logger.Error("Failed to deserialize backpack data.");
				}
				else
				{
					val.LoadTo(backpackStorage.ItemSlots);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error loading backpack data: " + ex.Message);
			}
		}

		[HarmonyPatch("LoadInventory")]
		[HarmonyPrefix]
		public static void LoadInventory(Player __instance, ref string contentsString)
		{
			if (string.IsNullOrEmpty(contentsString))
			{
				return;
			}
			if (!((NetworkBehaviour)__instance).IsOwner)
			{
				Logger.Info("Not the owner, skipping backpack data load.");
				return;
			}
			string[] array = contentsString.Split(new string[1] { "|||" }, StringSplitOptions.None);
			if (array.Length < 2)
			{
				return;
			}
			contentsString = array[0];
			string text = array[1];
			Logger.Info("Loading backpack data from network.");
			try
			{
				StorageEntity backpackStorage = __instance.GetBackpackStorage();
				DeserializedItemSet val = default(DeserializedItemSet);
				if (!ItemSet.TryDeserialize(text, ref val))
				{
					Logger.Error("Failed to deserialize backpack data.");
				}
				else
				{
					val.LoadTo(backpackStorage.ItemSlots);
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error loading backpack data: " + ex.Message);
			}
		}

		[HarmonyPatch("Activate")]
		[HarmonyPrefix]
		public static void Activate()
		{
			Logger.Info("Activating backpack");
			PlayerBackpack.Instance.SetBackpackEnabled(state: true);
		}

		[HarmonyPatch("Deactivate")]
		[HarmonyPrefix]
		public static void Deactivate()
		{
			Logger.Info("Deactivating backpack");
			PlayerBackpack.Instance.SetBackpackEnabled(state: false);
		}

		[HarmonyPatch("ExitAll")]
		[HarmonyPrefix]
		public static void ExitAll()
		{
			Logger.Info("Exiting all backpacks");
			PlayerBackpack.Instance.SetBackpackEnabled(state: false);
		}

		[HarmonyPatch("OnDied")]
		[HarmonyPrefix]
		public static void OnDied(Player __instance)
		{
			if (((NetworkBehaviour)__instance).Owner.IsLocalClient)
			{
				Logger.Info("Player died, disabling backpack");
				PlayerBackpack.Instance.SetBackpackEnabled(state: false);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerSpawner))]
	public static class PlayerSpawnerPatch
	{
		[HarmonyPatch("InitializeOnce")]
		[HarmonyPostfix]
		public static void InitializeOnce(PlayerSpawner __instance)
		{
			NetworkObject playerPrefab = __instance._playerPrefab;
			if (!Object.op_Implicit((Object)(object)playerPrefab))
			{
				Logger.Error("Player prefab is null!");
				return;
			}
			Player component = ((Component)playerPrefab).GetComponent<Player>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.Error("Player prefab does not have a Player component!");
				return;
			}
			Logger.Info("Adding backpack storage to player prefab...");
			StorageEntity orAddComponent = Utils.GetOrAddComponent<StorageEntity>(((Component)component).gameObject);
			orAddComponent.SlotCount = 128;
			orAddComponent.DisplayRowCount = 8;
			orAddComponent.StorageEntityName = "Backpack";
			orAddComponent.MaxAccessDistance = float.PositiveInfinity;
			Utils.GetOrAddComponent<PlayerBackpack>(component.LocalGameObject);
		}
	}
	[HarmonyPatch(typeof(ShopInterface))]
	public static class ShopInterfacePatch
	{
		[HarmonyPatch("GetAvailableSlots")]
		[HarmonyPostfix]
		public static void GetAvailableSlots(ShopInterface __instance, ref List<ItemSlot> __result)
		{
			if (!PlayerBackpack.Instance.IsUnlocked)
			{
				return;
			}
			LandVehicle loadingBayVehicle = __instance.GetLoadingBayVehicle();
			if ((Object)(object)loadingBayVehicle != (Object)null && __instance.Cart.LoadVehicleToggle.isOn)
			{
				return;
			}
			int count = PlayerSingleton<PlayerInventory>.Instance.hotbarSlots.Count;
			List<ItemSlot> itemSlots = PlayerBackpack.Instance.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				List<ItemSlot> val = itemSlots;
				ItemSlot val2 = ((Il2CppObjectBase)val[new Index(i).GetOffset(val.Count)]).TryCast<ItemSlot>();
				if (val2 != null)
				{
					__result.Insert(i + count, val2);
				}
			}
		}
	}
	[HarmonyPatch(typeof(StorageMenu))]
	public static class StorageMenuPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void Awake(StorageMenu __instance)
		{
			if (((Il2CppArrayBase<ItemSlotUI>)(object)__instance.SlotsUIs).Length >= 128)
			{
				return;
			}
			RectTransform slotContainer = __instance.SlotContainer;
			ItemSlotUI obj = ((Il2CppArrayBase<ItemSlotUI>)(object)__instance.SlotsUIs)[0];
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Error("StorageMenu prefab is null. Cannot create additional slots.");
				return;
			}
			ItemSlotUI[] array = (ItemSlotUI[])(object)new ItemSlotUI[128];
			for (int i = 0; i < 128; i++)
			{
				if (i < ((Il2CppArrayBase<ItemSlotUI>)(object)__instance.SlotsUIs).Length)
				{
					array[i] = ((Il2CppArrayBase<ItemSlotUI>)(object)__instance.SlotsUIs)[i];
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val, (Transform)(object)slotContainer);
				((Object)val2).name = $"{((Object)val).name} ({i})";
				val2.gameObject.SetActive(true);
				array[i] = val2.GetComponent<ItemSlotUI>();
			}
			__instance.SlotsUIs = Il2CppReferenceArray<ItemSlotUI>.op_Implicit(array);
		}

		[HarmonyPatch("Open", new Type[]
		{
			typeof(string),
			typeof(string),
			typeof(IItemSlotOwner)
		})]
		[HarmonyPostfix]
		public static void Open(StorageMenu __instance, string title, string subtitle, IItemSlotOwner owner)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			float num = __instance.SlotGridLayout.cellSize.y + __instance.SlotGridLayout.spacing.y;
			__instance.CloseButton.anchoredPosition = new Vector2(0f, (float)__instance.SlotGridLayout.constraintCount * (0f - num) - __instance.CloseButton.sizeDelta.y);
			if (__instance.SlotGridLayout.constraintCount > 4)
			{
				((Transform)__instance.Container).localPosition = new Vector3(0f, (float)(__instance.SlotGridLayout.constraintCount - 4) * num, 0f);
			}
		}

		[HarmonyPatch("CloseMenu")]
		[HarmonyPrefix]
		public static void CloseMenu(StorageMenu __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Transform)__instance.Container).localPosition = Vector3.zero;
		}
	}
}
namespace Backpack.Config
{
	public static class ConfigSyncManager
	{
		[CompilerGenerated]
		private sealed class <WaitForPayload>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private int <i>5__1;

			private string <payload>5__2;

			private Exception <e>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForPayload>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<payload>5__2 = null;
				<e>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0033: 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_0067: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__1 = 0;
					break;
				case 1:
				{
					<>1__state = -1;
					int num = <i>5__1 + 1;
					<i>5__1 = num;
					break;
				}
				}
				if (<i>5__1 < 10)
				{
					<payload>5__2 = SteamMatchmaking.GetLobbyData(Singleton<Lobby>.Instance.LobbySteamID, "Backpack_Config");
					if (string.IsNullOrEmpty(<payload>5__2))
					{
						<>2__current = (object)new WaitForSeconds(1f);
						<>1__state = 1;
						return true;
					}
					Logger.Info("Received payload from host: " + <payload>5__2);
					try
					{
						SyncFromHost(<payload>5__2);
					}
					catch (Exception ex)
					{
						<e>5__3 = ex;
						Logger.Error(<e>5__3, "Error while parsing payload: " + <payload>5__2);
					}
					return false;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const string Prefix = "Backpack_Config";

		private static readonly string ModVersion = typeof(BackpackMod).Assembly.GetName().Version?.ToString() ?? "1.0.0";

		public static void StartSync()
		{
			bool isHost = Singleton<Lobby>.Instance.IsHost;
			bool flag = !isHost && Singleton<Lobby>.Instance.IsInLobby;
			if (isHost)
			{
				SyncToClients();
			}
			else if (flag)
			{
				MelonCoroutines.Start(WaitForPayload());
			}
		}

		private static void SyncToClients()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(ModVersion);
			handler.AppendLiteral("[");
			stringBuilder3.Append(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder2);
			handler.AppendFormatted<ERank>(Configuration.Instance.UnlockLevel.Rank);
			handler.AppendLiteral(":");
			handler.AppendFormatted(Configuration.Instance.UnlockLevel.Tier);
			handler.AppendLiteral(",");
			stringBuilder4.Append(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Configuration.Instance.EnableSearch);
			handler.AppendLiteral(",");
			stringBuilder5.Append(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2);
			handler.AppendFormatted(Configuration.Instance.StorageSlots);
			handler.AppendLiteral(",");
			stringBuilder6.Append(ref handler);
			stringBuilder.Append(']');
			Logger.Info($"Syncing payload to clients: {stringBuilder}");
			Singleton<Lobby>.Instance.SetLobbyData("Backpack_Config", stringBuilder.ToString());
		}

		[IteratorStateMachine(typeof(<WaitForPayload>d__4))]
		private static IEnumerator WaitForPayload()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForPayload>d__4(0);
		}

		private static void SyncFromHost(string payload)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			string[] array = payload.Split(new char[3] { '[', ']', ',' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 2)
			{
				Logger.Warning("Invalid payload format: " + payload);
				return;
			}
			if (array[0] != ModVersion)
			{
				Logger.Warning("Mod version mismatch: " + array[0] + " != " + ModVersion);
				return;
			}
			string[] array2 = array[1].Split(':');
			if (array2.Length != 2 || !Enum.TryParse<ERank>(array2[0], out ERank result) || !int.TryParse(array2[1], out var result2))
			{
				Logger.Warning("Invalid unlock level format: " + array[1]);
				return;
			}
			Configuration.Instance.UnlockLevel = new FullRank(result, result2);
			Configuration.Instance.EnableSearch = bool.Parse(array[2]);
			Configuration.Instance.StorageSlots = int.Parse(array[3]);
		}
	}
	public class Configuration
	{
		private static Configuration _instance;

		private readonly string _configFile = Path.Combine("UserData", "Backpack.cfg");

		private readonly MelonPreferences_Category _generalCategory;

		private readonly MelonPreferences_Entry<KeyCode> _toggleKeyEntry;

		private readonly MelonPreferences_Entry<bool> _enableSearchEntry;

		private readonly MelonPreferences_Category _backpackCategory;

		private readonly MelonPreferences_Entry<FullRank> _unlockLevelEntry;

		private readonly MelonPreferences_Entry<int> _storageSlotsEntry;

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

		public KeyCode ToggleKey { get; set; }

		public bool EnableSearch { get; set; }

		public FullRank UnlockLevel { get; internal set; }

		public int StorageSlots { get; internal set; }

		public Configuration()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			_generalCategory = MelonPreferences.CreateCategory("General");
			_generalCategory.SetFilePath(_configFile, false);
			_toggleKeyEntry = _generalCategory.CreateEntry<KeyCode>("ToggleKey", (KeyCode)98, "Key to toggle backpack", (string)null, false, false, (ValueValidator)null, (string)null);
			_enableSearchEntry = _generalCategory.CreateEntry<bool>("EnableSearch", false, "Enable police search for backpack items", (string)null, false, false, (ValueValidator)null, (string)null);
			_backpackCategory = MelonPreferences.CreateCategory("Backpack");
			_backpackCategory.SetFilePath(_configFile, false);
			_unlockLevelEntry = _backpackCategory.CreateEntry<FullRank>("UnlockLevel", new FullRank((ERank)1, 1), "Required level to unlock", (string)null, false, false, (ValueValidator)null, (string)null);
			_storageSlotsEntry = _backpackCategory.CreateEntry<int>("StorageSlots", 12, "Number of total storage slots", (string)null, false, false, (ValueValidator)null, (string)null);
		}

		public void Load()
		{
			MelonPreferences.Load();
			Reset();
		}

		public void Reset()
		{
			//IL_0008: 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_0031: 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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			ToggleKey = _toggleKeyEntry.Value;
			EnableSearch = _enableSearchEntry.Value;
			UnlockLevel = new FullRank(_unlockLevelEntry.Value.Rank, Math.Clamp(_unlockLevelEntry.Value.Tier, 1, 5));
			StorageSlots = Math.Clamp(_storageSlotsEntry.Value, 1, 128);
		}

		public void Save()
		{
			//IL_0008: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			_toggleKeyEntry.Value = ToggleKey;
			_enableSearchEntry.Value = EnableSearch;
			_unlockLevelEntry.Value = new FullRank(UnlockLevel.Rank, Math.Clamp(UnlockLevel.Tier, 1, 5));
			_storageSlotsEntry.Value = Math.Clamp(StorageSlots, 1, 128);
			MelonPreferences.Save();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}