using 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();
}
}
}