Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Cabinet Item Storage v0.0.4
NicholaScott.LethalCompany.CabinetStorage.dll
Decompiled 2 years agousing System; using System.Collections; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using GameNetcodeStuff; using HarmonyLib; using NicholaScott.BepInEx.Utils.Configuration; using NicholaScott.BepInEx.Utils.Instancing; using NicholaScott.BepInEx.Utils.Patching; using NicholaScott.LethalCompany.API; using Unity.Collections; using Unity.Netcode; 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: AssemblyTitle("NicholaScott.LethalCompany.CabinetStorage")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("NicholaScott.LethalCompany.CabinetStorage")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1268DCF6-2C4D-46DB-B877-1F13F206E02D")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace NicholaScott.LethalCompany.CabinetStorage; public class CabinetManager : MonoBehaviour { private enum NetworkMessageType { ServerRequestSync, ServerSpawnItem, ClientSyncNewItem } private const string NetTransferCabinetData = "CabMagTransferData"; private const string StoringText = "Storing {0}..."; private const string GrabbingText = "Taking {0}..."; private const string EmptyHoverText = "[USE] Empty Drawer"; private const string HoverText = "({0}) {1}"; private Sprite emptyIcon; private (InteractTrigger trigger, LethalInventory inventory)[] slots = new(InteractTrigger, LethalInventory)[6]; private static string StoreFormatted(string heldItemName) { return $"Storing {heldItemName}..."; } private static string GrabFormatted(string storedItemName) { return $"Taking {storedItemName}..."; } private static string HoverFormatted(int storedCount, string storedItemName) { return $"({storedCount}) {storedItemName}"; } private static Item ItemFromID(string id) { return StartOfRound.Instance.allItemsList.itemsList.First((Item f) => f.itemName.ToLower().Replace(" ", "") == id); } private static string ItemToID(Item item) { return item.itemName.ToLower().Replace(" ", ""); } private static Sprite GrabEmptyIcon() { return Extensions.FindPrefabByName<Item>(StartOfRound.Instance, new string[2] { "gold", "bar" }).itemIcon; } private static IEnumerator WaitUntilNotTheSame(InteractTrigger trigger) { bool stillSame = true; float cfgCDTime = Singleton<CabinetStorage, CabinetStorage.Configuration>.Configuration.CooldownBetweenInteract; while (stillSame) { yield return (object)new WaitForSeconds(5f); if (Math.Abs(trigger.cooldownTime - cfgCDTime) > 0.01f) { Singleton<CabinetStorage>.Logger.LogInfo((object)$"Cabinet Storage InteractTrigger had it's cooldown time overwitten to {trigger.cooldownTime}. Changing back to {cfgCDTime}."); stillSame = false; trigger.cooldownTime = cfgCDTime; } } } private static InteractTrigger CreateNewInteractTrigger(int id, Transform attachTo) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0060: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown GameObject val = new GameObject($"Drawer {id}", new Type[2] { typeof(SphereCollider), typeof(InteractTrigger) }); val.transform.SetParent(attachTo); int num = id % 2; Vector3 val2 = attachTo.up * ((id <= 1) ? (-0.55f) : ((id < 4) ? 0f : 0.55f)); Vector3 val3 = attachTo.right * 0.4f * ((num == 0) ? (-1f) : 0.75f); val.transform.localPosition = attachTo.forward * 0.45f + val2 + val3; val.layer = LayerMask.NameToLayer("InteractableObject"); val.tag = "InteractTrigger"; SphereCollider component = val.GetComponent<SphereCollider>(); InteractTrigger component2 = val.GetComponent<InteractTrigger>(); component.radius = 0.25f; ((Collider)component).enabled = true; component2.interactable = true; component2.holdInteraction = true; component2.timeToHold = 0.4f; component2.cooldownTime = Singleton<CabinetStorage, CabinetStorage.Configuration>.Configuration.CooldownBetweenInteract; ((MonoBehaviour)component2).StartCoroutine(WaitUntilNotTheSame(component2)); component2.timeToHoldSpeedMultiplier = 1f; component2.hoverTip = "[USE] Empty Drawer"; component2.onInteractEarly = new InteractEvent(); component2.onInteract = new InteractEvent(); component2.onCancelAnimation = new InteractEvent(); component2.onStopInteract = new InteractEvent(); component2.holdingInteractEvent = new InteractEventFloat(); ((UnityEvent<PlayerControllerB>)(object)component2.onInteractEarly).AddListener((UnityAction<PlayerControllerB>)delegate { AutoSingleton<CabinetManager>.Instance.PrepareHoldTip(id); }); ((UnityEvent<PlayerControllerB>)(object)component2.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate { AutoSingleton<CabinetManager>.Instance.TakeOrStoreHeldItem(id); }); return component2; } private void Awake() { emptyIcon = GrabEmptyIcon(); InitializeSlots(); } private void Start() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < slots.Length; i++) { slots[i].inventory.RegisterNetworkMessages("CabMagTransferData", $"Slot{i}"); } NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("CabMagTransferData", new HandleNamedMessageDelegate(NetworkMessageReceived)); if (NetworkManager.Singleton.IsServer) { LoadCabinetDataIfExists(); } else { RequestSyncServerRPC(0uL); } } private void SpawnItemServerRPC(ReducedItem item = default(ReducedItem), ulong client = 0uL, bool received = false, FastBufferReader data = default(FastBufferReader)) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (received) { item = ReducedItem.Read(data); Item val = ItemFromID(item.ID); GameObject val2 = Object.Instantiate<GameObject>(val.spawnPrefab, ((Component)this).transform.position + Vector3.up, Quaternion.identity, StartOfRound.Instance.elevatorTransform); GrabbableObject component = val2.GetComponent<GrabbableObject>(); component.fallTime = 1f; component.hasHitGround = true; component.scrapPersistedThroughRounds = true; component.isInElevator = true; component.isInShipRoom = true; ((ReducedItem)(ref item)).ApplyToGrabbable(component); ((NetworkBehaviour)component).NetworkObject.Spawn(false); SyncNewItemClientRPC(NetworkObjectReference.op_Implicit(((NetworkBehaviour)component).NetworkObject), item, 0uL); return; } FastBufferWriter val3 = default(FastBufferWriter); ((FastBufferWriter)(ref val3))..ctor(128, (Allocator)2, -1); try { int num = 1; ((FastBufferWriter)(ref val3)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((ReducedItem)(ref item)).Write(val3); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("CabMagTransferData", 0uL, val3, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val3)).Dispose(); } } private void RequestSyncServerRPC(ulong client = 0uL, bool received = false, FastBufferReader data = default(FastBufferReader)) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (received) { for (int i = 0; i < slots.Length; i++) { slots[i].inventory.SyncAllClientRPC(false, client, false, default(FastBufferReader)); } return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); try { int num = 0; ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("CabMagTransferData", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private IEnumerator waitUntilSpawnToAssignData(NetworkObjectReference netObjRef, ReducedItem item) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) float startTime = Time.realtimeSinceStartup; NetworkObject networkObject = null; while (Time.realtimeSinceStartup - startTime <= 8f && !((NetworkObjectReference)(ref netObjRef)).TryGet(ref networkObject, (NetworkManager)null)) { yield return (object)new WaitForSeconds(0.03f); } if (!((Object)(object)networkObject == (Object)null)) { yield return (object)new WaitForEndOfFrame(); GrabbableObject grabbable = ((Component)networkObject).GetComponent<GrabbableObject>(); grabbable.fallTime = 1f; grabbable.hasHitGround = true; grabbable.scrapPersistedThroughRounds = true; grabbable.isInElevator = true; grabbable.isInShipRoom = true; ((ReducedItem)(ref item)).ApplyToGrabbable(grabbable); } } private void SyncNewItemClientRPC(NetworkObjectReference netObjToSync = default(NetworkObjectReference), ReducedItem item = default(ReducedItem), ulong client = 0uL, bool received = false, FastBufferReader data = default(FastBufferReader)) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0086: Unknown result type (might be due to invalid IL or missing references) if (received) { ((FastBufferReader)(ref data)).ReadValueSafe<NetworkObjectReference>(ref netObjToSync, default(ForNetworkSerializable)); item = ReducedItem.Read(data); ((MonoBehaviour)this).StartCoroutine(waitUntilSpawnToAssignData(netObjToSync, item)); return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, -1); try { int num = 2; ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<NetworkObjectReference>(ref netObjToSync, default(ForNetworkSerializable)); ((ReducedItem)(ref item)).Write(val); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("CabMagTransferData", client, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } private void NetworkMessageReceived(ulong senderID, FastBufferReader message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) int num = default(int); ((FastBufferReader)(ref message)).ReadValueSafe<int>(ref num, default(ForPrimitives)); Singleton<CabinetStorage>.Logger.LogInfo((object)$"[CabinetManager] Received network message {(NetworkMessageType)num}"); switch ((NetworkMessageType)num) { case NetworkMessageType.ServerRequestSync: RequestSyncServerRPC(senderID, received: true, message); break; case NetworkMessageType.ServerSpawnItem: { FastBufferReader data = message; SpawnItemServerRPC(default(ReducedItem), senderID, received: true, data); break; } case NetworkMessageType.ClientSyncNewItem: { FastBufferReader data = message; SyncNewItemClientRPC(default(NetworkObjectReference), default(ReducedItem), 0uL, received: true, data); break; } default: throw new ArgumentOutOfRangeException(); } } public void OnDestroy() { for (int i = 0; i < slots.Length; i++) { slots[i].inventory.PostContentsChanged -= UpdateHoverInformation; } NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler("CabMagTransferData"); } private bool CanStoreItemInSlot(GrabbableObject item, int slot) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)item)) { return false; } Item tItem = item.itemProperties; bool flag = slots[slot].inventory.Contents.Count == 0; bool flag2 = !flag && ItemFromID(slots[slot].inventory.Contents[0].ID).isScrap; bool isScrap = tItem.isScrap; bool result = !flag && ItemToID(tItem) == slots[slot].inventory.Contents[0].ID; if (!StartOfRound.Instance.allItemsList.itemsList.Exists((Item f) => ItemToID(f) == ItemToID(tItem))) { return false; } if (flag) { return true; } if (flag2 && isScrap) { return true; } return result; } private void TakeOrStoreHeldItem(int slot) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; GrabbableObject val = (Object.op_Implicit((Object)(object)localPlayerController.currentlyHeldObjectServer) ? localPlayerController.currentlyHeldObjectServer : localPlayerController.currentlyHeldObject); if (CanStoreItemInSlot(val, slot)) { slots[slot].inventory.AddItemServerRPC(val); localPlayerController.DespawnHeldObject(); } else if (slots[slot].inventory.Contents.Count > 0) { SpawnItemServerRPC(slots[slot].inventory.Contents[0], 0uL); slots[slot].inventory.RemoveItemServerRPC(0, 0uL, false, default(FastBufferReader)); } } private void UpdateHoverInformation() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) for (int j = 0; j < slots.Length; j++) { if (slots[j].inventory.Contents.Count == 0) { slots[j].trigger.hoverTip = "[USE] Empty Drawer"; slots[j].trigger.hoverIcon = emptyIcon; continue; } Item val = ItemFromID(slots[j].inventory.Contents[0].ID); slots[j].trigger.hoverTip = (val.isScrap ? $"({slots[j].inventory.Contents.Count}) Scrap worth ${slots[j].inventory.Contents.Aggregate(0, (int i, ReducedItem item) => i + item.CreditValue)}" : HoverFormatted(slots[j].inventory.Contents.Count, val.itemName)); slots[j].trigger.hoverIcon = val.itemIcon; } } private void PrepareHoldTip(int slot) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; GrabbableObject val = (Object.op_Implicit((Object)(object)localPlayerController.currentlyHeldObjectServer) ? localPlayerController.currentlyHeldObjectServer : localPlayerController.currentlyHeldObject); if (CanStoreItemInSlot(val, slot)) { slots[slot].trigger.timeToHoldSpeedMultiplier = 1f; slots[slot].trigger.holdTip = StoreFormatted(val.itemProperties.itemName); } else if (slots[slot].inventory.Contents.Count != 0) { slots[slot].trigger.holdTip = GrabFormatted(ItemFromID(slots[slot].inventory.Contents[0].ID).itemName); } else { slots[slot].trigger.timeToHoldSpeedMultiplier = 0.1f; slots[slot].trigger.holdTip = "Nothing to Store/Take!"; } } private void InitializeSlots() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown for (int i = 0; i < slots.Length; i++) { slots[i] = (CreateNewInteractTrigger(i, ((Component)this).transform), new LethalInventory()); slots[i].inventory.PostContentsChanged += UpdateHoverInformation; slots[i].trigger.hoverTip = "[USE] Empty Drawer"; slots[i].trigger.hoverIcon = emptyIcon; } } private void LoadCabinetDataIfExists() { for (int i = 0; i < slots.Length; i++) { slots[i].inventory.LoadInventoryContents($"Slot{i}", ""); } UpdateHoverInformation(); } internal void SaveCabinetData() { for (int i = 0; i < slots.Length; i++) { slots[i].inventory.SaveInventoryContents($"Slot{i}", ""); } } } [BepInPlugin("NicholaScott.LethalCompany.CabinetStorage", "Cabinet Item Storage", "0.0.4")] [BepInDependency("NicholaScott.BepInEx.Utils", "1.2.1")] [BepInDependency("NicholaScott.LethalCompany.API", "0.0.5")] public class CabinetStorage : BaseUnityPlugin { public struct Configuration { public float CooldownBetweenInteract; } private void Awake() { Singleton<CabinetStorage>.Instance = this; Singleton<CabinetStorage, Configuration>.Configuration = Extensions.BindStruct<Configuration>(((BaseUnityPlugin)this).Config, new Configuration { CooldownBetweenInteract = 0.25f }); Extensions.PatchAttribute<Production>(Assembly.GetExecutingAssembly(), ((BaseUnityPlugin)this).Info.Metadata.GUID, (Action<object>)null); } } [Production] public static class CabinetPatches { private static CabinetManager manager; [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] public static void BindToFileCabinet(StartOfRound __instance) { Singleton<CabinetStorage>.Logger.LogInfo((object)NetworkManager.Singleton.IsServer); int fileCabId = __instance.unlockablesList.unlockables.FindIndex((UnlockableItem un) => un.unlockableName.ToLower().Contains("cabinet")); PlaceableShipObject val = Object.FindObjectsOfType<PlaceableShipObject>().First((PlaceableShipObject pc) => pc.unlockableID == fileCabId); manager = ((Component)val).gameObject.AddComponent<CabinetManager>(); } [HarmonyPatch(typeof(GameNetworkManager), "SaveItemsInShip")] [HarmonyPostfix] public static void SaveFileCabinet() { if (Object.op_Implicit((Object)(object)manager)) { manager.SaveCabinetData(); } } }