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 a month 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) { } } }