Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of OG Backpack v1.8.1
Backpack.dll
Decompiled 10 months agousing 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) { } } }