using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Managers; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; using kg_ItemDrawers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("kg_ItemDrawers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("kg_ItemDrawers")] [assembly: AssemblyTitle("kg_ItemDrawers")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 kg_ItemDrawers { internal static class BuildBridge { private const float BuildRange = 20f; private static bool _applied; internal static void Apply(Harmony harmony) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown if (_applied) { return; } _applied = true; MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "HaveRequirements")) { MethodInfo method = typeof(BuildBridge).GetMethod("HaveRequirementsPostfix", BindingFlags.Static | BindingFlags.NonPublic); try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ItemDrawers.Instance.Log.LogInfo((object)("BuildBridge: patched HaveRequirements(" + string.Join(", ", GetParamTypes(methodInfo)) + ")")); } catch (Exception ex) { ItemDrawers.Instance.Log.LogWarning((object)("BuildBridge: failed to patch HaveRequirements: " + ex.Message)); } } } methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "ConsumeResources")) { MethodInfo method2 = typeof(BuildBridge).GetMethod("ConsumeResourcesPrefix", BindingFlags.Static | BindingFlags.NonPublic); try { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ItemDrawers.Instance.Log.LogInfo((object)("BuildBridge: patched ConsumeResources(" + string.Join(", ", GetParamTypes(methodInfo2)) + ")")); } catch (Exception ex2) { ItemDrawers.Instance.Log.LogWarning((object)("BuildBridge: failed to patch ConsumeResources: " + ex2.Message)); } } } } private static string[] GetParamTypes(MethodInfo mi) { ParameterInfo[] parameters = mi.GetParameters(); string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType.Name; } return array; } [UsedImplicitly] private static void HaveRequirementsPostfix(Player __instance, ref bool __result, object[] __args) { if (__result || (Object)(object)__instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } Requirement[] array = null; int quality = 0; if (__args != null) { foreach (object obj in __args) { Piece val = (Piece)((obj is Piece) ? obj : null); if (val != null && val?.m_resources != null) { array = val.m_resources; continue; } Recipe val2 = (Recipe)((obj is Recipe) ? obj : null); if (val2 != null && val2?.m_resources != null) { array = val2.m_resources; } else if (obj is Requirement[] array2) { array = array2; } else if (obj is int num) { quality = num; } } } if (array != null) { CheckAndSupplement(__instance, array, quality, ref __result); } } private static void CheckAndSupplement(Player player, Requirement[] resources, int quality, ref bool __result) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (resources == null || (Object)(object)ObjectDB.instance == (Object)null) { return; } List list = FindNearbyDrawers(((Component)player).transform.position); if (list.Count == 0) { return; } foreach (Requirement val in resources) { if (!((Object)(object)val?.m_resItem == (Object)null) && val.m_amount > 0) { int num = val.m_amount * (quality + 1); string name = val.m_resItem.m_itemData.m_shared.m_name; Inventory inventory = ((Humanoid)player).GetInventory(); int num2 = ((inventory != null) ? inventory.CountItems(name, -1, true) : 0); int num3 = CountInDrawers(list, name); if (num2 + num3 < num) { return; } } } __result = true; } [UsedImplicitly] private static void ConsumeResourcesPrefix(Player __instance, object[] __args) { if ((Object)(object)__instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } Requirement[] array = null; int quality = 0; if (__args != null) { foreach (object obj in __args) { Piece val = (Piece)((obj is Piece) ? obj : null); if (val != null && val?.m_resources != null) { array = val.m_resources; continue; } Recipe val2 = (Recipe)((obj is Recipe) ? obj : null); if (val2 != null && val2?.m_resources != null) { array = val2.m_resources; } else if (obj is Requirement[] array2) { array = array2; } else if (obj is int num) { quality = num; } } } if (array != null) { ConsumeFromDrawers(__instance, array, quality); } } private static void ConsumeFromDrawers(Player player, Requirement[] resources, int quality) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (resources == null || (Object)(object)ObjectDB.instance == (Object)null) { return; } List list = FindNearbyDrawers(((Component)player).transform.position); if (list.Count == 0) { return; } foreach (Requirement val in resources) { if (!((Object)(object)val?.m_resItem == (Object)null) && val.m_amount > 0) { int num = val.m_amount * (quality + 1); string name = val.m_resItem.m_itemData.m_shared.m_name; Inventory inventory = ((Humanoid)player).GetInventory(); int num2 = ((inventory != null) ? inventory.CountItems(name, -1, true) : 0); int num3 = num - num2; if (num3 > 0) { WithdrawFromDrawers(list, name, num3); } } } } private static List FindNearbyDrawers(Vector3 pos) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if ((Object)(object)allDrawer == (Object)null || (Object)(object)allDrawer._znv == (Object)null || !allDrawer._znv.IsValid()) { continue; } Component val = (Component)(object)allDrawer; if ((Object)(object)val == (Object)null) { continue; } try { if (Vector3.Distance(val.transform.position, pos) <= 20f) { list.Add(allDrawer); } } catch { } } return list; } private static int CountInDrawers(List drawers, string itemName) { if ((Object)(object)ObjectDB.instance == (Object)null) { return 0; } int num = 0; foreach (DrawerComponent drawer in drawers) { if ((Object)(object)drawer == (Object)null || (Object)(object)drawer._znv == (Object)null || !drawer._znv.IsValid()) { continue; } ZDO zDO = drawer._znv.GetZDO(); if (zDO == null) { continue; } string text = zDO.GetString("Prefab", ""); if (string.IsNullOrEmpty(text)) { continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent(); if (!((Object)(object)component == (Object)null) && component.m_itemData.m_shared.m_name == itemName) { num += zDO.GetInt("Amount", 0); } } } return num; } private static int WithdrawFromDrawers(List drawers, string itemName, int needed) { if ((Object)(object)ObjectDB.instance == (Object)null) { return 0; } int num = 0; foreach (DrawerComponent drawer in drawers) { if (num >= needed) { break; } if ((Object)(object)drawer == (Object)null || (Object)(object)drawer._znv == (Object)null || !drawer._znv.IsValid()) { continue; } ZDO zDO = drawer._znv.GetZDO(); if (zDO == null) { continue; } string text = zDO.GetString("Prefab", ""); if (string.IsNullOrEmpty(text)) { continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if ((Object)(object)itemPrefab == (Object)null) { continue; } ItemDrop component = itemPrefab.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData.m_shared.m_name != itemName) { continue; } int num2 = zDO.GetInt("Amount", 0); int num3 = Mathf.Min(needed - num, num2); if (num3 > 0) { int num4 = num2 - num3; if (!drawer._znv.IsOwner()) { drawer._znv.ClaimOwnership(); } zDO.Set("Amount", num4); drawer._znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { text, num4, zDO.GetInt("Quality", 1) }); num += num3; } } return num; } } public class DrawerComponent : MonoBehaviour, Interactable, Hoverable { private struct DrawerOptions : ISerializableParameter { public DrawerComponent drawer; public Color32 color; public int pickupRange; public void Serialize(ref ZPackage pkg) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) pkg.Write(Utils.ColorToVec3(color)); pkg.Write(pickupRange); } public void Deserialize(ref ZPackage pkg) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) color = Utils.Vec3ToColor(pkg.ReadVector3()); pickupRange = pkg.ReadInt(); } } [HarmonyPatch] private static class IsVisible { [HarmonyTargetMethods] [UsedImplicitly] private static IEnumerable Methods() { yield return AccessTools.Method(typeof(TextInput), "IsVisible", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(StoreGui), "IsVisible", (Type[])null, (Type[])null); } [HarmonyPostfix] [UsedImplicitly] private static void SetTrue(ref bool __result) { __result |= ShowUI; } } [CompilerGenerated] private static class DisplayClassO { public static WindowFunction CachedWindow; } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__Window; } public static readonly List AllDrawers = new List(); private static readonly FieldInfo F_s_instances = AccessTools.Field(typeof(ItemDrop), "s_instances"); private static Sprite _defaultSprite; private Image _image; private TMP_Text _text; private Transform _stars; private TMP_Text _starsText; private Transform _starIcon; private static bool ShowUI; private static DrawerOptions CurrentOptions; private static bool _effectsLogged; public ZNetView _znv { get; private set; } public string CurrentPrefab { get { return _znv.GetZDO().GetString("Prefab", ""); } set { _znv.GetZDO().Set("Prefab", value); } } public int CurrentAmount { get { return _znv.GetZDO().GetInt("Amount", 0); } set { _znv.GetZDO().Set("Amount", value); } } public int PickupRange { get { return _znv.GetZDO().GetInt("PickupRange", ItemDrawers.DrawerPickupRange.Value); } set { _znv.GetZDO().Set("PickupRange", value); } } public int Quality { get { return _znv.GetZDO().GetInt("Quality", 1); } set { _znv.GetZDO().Set("Quality", value); } } private Color CurrentColor { get { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return Color32.op_Implicit(Utils.Vec3ToColor(_znv.GetZDO().GetVec3("Color", ItemDrawers.DefaultColor.Value))); } set { //IL_0010: 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_0016: Unknown result type (might be due to invalid IL or missing references) _znv.GetZDO().Set("Color", Utils.ColorToVec3(Color32.op_Implicit(value))); } } public bool ItemValid { get { if (!string.IsNullOrEmpty(CurrentPrefab)) { return (Object)(object)ObjectDB.instance.GetItemPrefab(CurrentPrefab) != (Object)null; } return false; } } private int ItemMaxStack => ObjectDB.instance.GetItemPrefab(CurrentPrefab).GetComponent().m_itemData.m_shared.m_maxStackSize; private string LocalizedName => ObjectDB.instance.GetItemPrefab(CurrentPrefab).GetComponent().m_itemData.m_shared.m_name.Localize(); private bool DoRepeat { get { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (Object.op_Implicit((Object)Player.m_localPlayer) && ItemValid) { return PickupRange > 0; } return false; } } public bool ItemValidCheck(string prefab) { if (!string.IsNullOrEmpty(prefab)) { return (Object)(object)ObjectDB.instance.GetItemPrefab(prefab) != (Object)null; } return false; } private void OnDestroy() { AllDrawers.Remove(this); } private void Awake() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) _znv = ((Component)this).GetComponent(); if (_znv.IsValid()) { AllDrawers.Add(this); _image = ((Component)((Component)this).transform.Find("Cube/Canvas/Image")).GetComponent(); if ((Object)(object)_defaultSprite == (Object)null) { _defaultSprite = _image.sprite; } _text = ((Component)((Component)this).transform.Find("Cube/Canvas/Text")).GetComponent(); if ((Object)(object)ItemDrawers.NorseFont != (Object)null) { _text.font = ItemDrawers.NorseFont; } _text.fontSize /= 2f; ((Graphic)_text).color = CurrentColor; _stars = ((Component)this).transform.Find("Cube/Canvas/Stars"); _starsText = ((Component)_stars.Find("Quality")).GetComponent(); _starIcon = _stars.Find("Img"); ApplyTextEffects(_text); ApplyTextEffects(_starsText); _znv.Register("AddItem_Request", (Action)RPC_AddItem); _znv.Register("AddItem_Player", (Action)RPC_AddItem_Player); _znv.Register("WithdrawItem_Request", (Action)RPC_WithdrawItem_Request); _znv.Register("UpdateIcon", (Action)RPC_UpdateIcon); _znv.Register("ForceRemove", (Action)RPC_ForceRemove); _znv.Register("ApplyOptions", (Action)RPC_ApplyOptions); RPC_UpdateIcon(0L, CurrentPrefab, CurrentAmount, Quality); float num = Random.Range(2.5f, 3f); ((MonoBehaviour)this).InvokeRepeating("Repeat", num, num); } } private static void ApplyTextEffects(TMP_Text text) { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null) { return; } try { Material fontMaterial = text.fontMaterial; if ((Object)(object)fontMaterial == (Object)null) { return; } Shader val = Shader.Find("TextMeshPro/Distance Field") ?? Shader.Find("Hidden/TextMeshPro/Distance Field"); if ((Object)(object)val != (Object)null && (Object)(object)fontMaterial.shader != (Object)(object)val) { string text2 = (((Object)(object)fontMaterial.shader != (Object)null) ? ((Object)fontMaterial.shader).name : "null"); fontMaterial.shader = val; if (!_effectsLogged) { _effectsLogged = true; ItemDrawers.Instance.Log.LogInfo((object)("ApplyTextEffects: shader was '" + text2 + "', switched to '" + ((Object)val).name + "'")); } } else if ((Object)(object)val == (Object)null && !_effectsLogged) { _effectsLogged = true; ItemDrawers.Instance.Log.LogInfo((object)"ApplyTextEffects: full SDF shader not found — outline/shadow will not work."); } if (ItemDrawers.TextOutlineEnabled != null && ItemDrawers.TextOutlineEnabled.Value) { fontMaterial.EnableKeyword("OUTLINE_ON"); fontMaterial.SetFloat("_OutlineWidth", ItemDrawers.TextOutlineWidth.Value); fontMaterial.SetColor("_OutlineColor", ItemDrawers.TextOutlineColor.Value); fontMaterial.SetFloat("_OutlineSoftness", 0f); } if (ItemDrawers.TextShadowEnabled != null && ItemDrawers.TextShadowEnabled.Value) { fontMaterial.EnableKeyword("UNDERLAY_ON"); fontMaterial.SetColor("_UnderlayColor", ItemDrawers.TextShadowColor.Value); fontMaterial.SetFloat("_UnderlayOffsetX", ItemDrawers.TextShadowOffset.Value); fontMaterial.SetFloat("_UnderlayOffsetY", 0f - ItemDrawers.TextShadowOffset.Value); fontMaterial.SetFloat("_UnderlaySoftness", ItemDrawers.TextShadowSoftness.Value); fontMaterial.SetFloat("_UnderlayDilate", 0f); } text.havePropertiesChanged = true; ((Graphic)text).SetAllDirty(); } catch (Exception ex) { try { ItemDrawers.Instance.Log.LogInfo((object)("ApplyTextEffects: " + ex.Message)); } catch { } } } private void RPC_ApplyOptions(long sender, DrawerOptions options) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0014: Unknown result type (might be due to invalid IL or missing references) if (_znv.IsOwner()) { CurrentColor = Color32.op_Implicit(options.color); PickupRange = Mathf.Min(ItemDrawers.MaxDrawerPickupRange.Value, options.pickupRange); } ((Graphic)_text).color = Color32.op_Implicit(options.color); } private void RPC_ForceRemove(long sender, int amount) { amount = Mathf.Min(amount, CurrentAmount); CurrentAmount -= amount; _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { CurrentPrefab, CurrentAmount, Quality }); } private void RPC_WithdrawItem_Request(long sender, int amount) { if (CurrentAmount <= 0 || !ItemValid) { CurrentPrefab = ""; CurrentAmount = 0; Quality = 1; _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { "", 0, 0 }); } else if (amount > 0) { amount = Mathf.Min(amount, CurrentAmount); CurrentAmount -= amount; _znv.InvokeRPC(sender, "AddItem_Player", new object[3] { CurrentPrefab, amount, Quality }); _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { CurrentPrefab, CurrentAmount, Quality }); } } private void RPC_AddItem_Player(long _, string prefab, int amount, int quality) { Utils.InstantiateItem(ZNetScene.instance.GetPrefab(prefab), amount, quality); } private void RPC_UpdateIcon(long _, string prefab, int amount, int quality) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!ItemValidCheck(prefab)) { _image.sprite = _defaultSprite; ((Component)_stars).gameObject.SetActive(false); ((Component)_text).gameObject.SetActive(false); return; } _image.sprite = ObjectDB.instance.GetItemPrefab(prefab).GetComponent().m_itemData.GetIcon(); _text.text = amount.ToString(); ((Component)_text).gameObject.SetActive(true); ((Component)_stars).gameObject.SetActive(quality > 1); if (quality > 1) { _starsText.text = quality.ToString(); ((Component)_starIcon).GetComponent(); _starIcon.localPosition = new Vector3((quality >= 10) ? 9f : 0f, 5.25f, 0f); } } private void RPC_AddItem(long sender, string prefab, int amount, int quality) { //IL_005b: 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_006a: 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) if (!_znv.IsOwner() || amount <= 0) { return; } quality = Math.Max(1, quality); string currentPrefab = CurrentPrefab; if (ItemValid && (currentPrefab != prefab || Quality != quality)) { Utils.InstantiateAtPos(ZNetScene.instance.GetPrefab(currentPrefab), CurrentAmount, Quality, ((Component)this).transform.position + Vector3.up * 1.5f); return; } int num = (CurrentAmount = (ItemValid ? (CurrentAmount + amount) : amount)); int num3 = num; if (currentPrefab != prefab) { CurrentPrefab = prefab; Quality = quality; } _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num3, quality }); } private void Repeat() { //IL_0053: 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_005d: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_znv == (Object)null || !_znv.IsValid() || !_znv.IsOwner() || !DoRepeat) { return; } string currentPrefab = CurrentPrefab; int quality = Quality; Vector3 vector = ((Component)this).transform.position + Vector3.up; IEnumerable enumerable = (IEnumerable)F_s_instances.GetValue(null); if (enumerable == null) { return; } foreach (ItemDrop item in enumerable.Where((ItemDrop drop) => Vector3.Distance(((Component)drop).transform.position, vector) < (float)PickupRange)) { if (((Object)item.m_itemData.m_dropPrefab).name != currentPrefab || item.m_itemData.m_quality != quality) { continue; } if (!item.CanPickup(false)) { item.RequestOwn(); continue; } Object.Instantiate(ItemDrawers.Explosion, ((Component)item).transform.position, Quaternion.identity); int stack = item.m_itemData.m_stack; ZNetView component = ((Component)item).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { component.ClaimOwnership(); ZNetScene.instance.Destroy(((Component)item).gameObject); CurrentAmount += stack; _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { currentPrefab, CurrentAmount, quality }); } } } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (((Character)user).IsCrouching()) { CurrentOptions.drawer = this; CurrentOptions.color = Color32.op_Implicit(CurrentColor); CurrentOptions.pickupRange = PickupRange; ShowUI = true; return true; } if (!ItemValid) { return false; } if (Input.GetKey((KeyCode)308)) { _znv.InvokeRPC("WithdrawItem_Request", new object[1] { 1 }); return true; } if (Input.GetKey((KeyCode)304)) { int quality = Quality; int num = Utils.CustomCountItems(CurrentPrefab, quality); if (num <= 0) { return true; } Utils.CustomRemoveItems(CurrentPrefab, num, quality); _znv.InvokeRPC("AddItem_Request", new object[3] { CurrentPrefab, num, quality }); return true; } _znv.InvokeRPC("WithdrawItem_Request", new object[1] { ItemMaxStack }); return true; } public bool UseItem(Humanoid user, ItemData item) { GameObject dropPrefab = item.m_dropPrefab; string text = (((Object)(object)dropPrefab != (Object)null) ? ((Object)dropPrefab).name : null); if (string.IsNullOrEmpty(text)) { return false; } if (ItemDrawers.ExcludeSet.Contains(text) && !Player.m_debugMode) { return false; } if (!string.IsNullOrEmpty(CurrentPrefab) && (CurrentPrefab != text || Quality != item.m_quality)) { return false; } int stack = item.m_stack; if (stack <= 0) { return false; } user.GetInventory().RemoveItem(item); _znv.InvokeRPC("AddItem_Request", new object[3] { text, stack, item.m_quality }); return true; } public string GetHoverText() { StringBuilder stringBuilder = new StringBuilder(); if (((Character)Player.m_localPlayer).IsCrouching()) { stringBuilder.AppendLine("[$KEY_Use] open settings"); return stringBuilder.ToString().Localize(); } if (!ItemValid) { stringBuilder.AppendLine("Use Hotbar to add item"); return stringBuilder.ToString().Localize(); } int quality = Quality; string arg = ((quality > 1) ? $" (Quality: {quality})" : ""); stringBuilder.AppendLine($"{LocalizedName}{arg} ({CurrentAmount})"); stringBuilder.AppendLine("Use Hotbar to add item\n"); if (CurrentAmount <= 0) { stringBuilder.AppendLine("[$KEY_Use] or [Left Alt + $KEY_Use] to clear"); stringBuilder.AppendLine($"[Left Shift + $KEY_Use] to deposit all {LocalizedName} ({Utils.CustomCountItems(CurrentPrefab, quality)})"); return stringBuilder.ToString().Localize(); } stringBuilder.AppendLine($"[$KEY_Use] to withdraw stack ({ItemMaxStack})"); stringBuilder.AppendLine("[Left Alt + $KEY_Use] to withdraw single item"); stringBuilder.AppendLine($"[Left Shift + $KEY_Use] to deposit all {LocalizedName}{arg} ({Utils.CustomCountItems(CurrentPrefab, quality)})"); return stringBuilder.ToString().Localize(); } public string GetHoverName() { return "Item Drawer"; } public static void ProcessInput() { if (Input.GetKeyDown((KeyCode)27) && ShowUI) { ShowUI = false; Menu.instance.OnClose(); } } public static void ProcessGUI() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006c: Expected O, but got Unknown if (!ShowUI) { return; } GUI.backgroundColor = Color.white; Rect val = new Rect((float)Screen.width / 2f - 150f, (float)Screen.height / 2f - 150f, 300f, 300f); object obj = DisplayClassO.CachedWindow; if (obj == null) { object obj2 = <>O.<0>__Window; if (obj2 == null) { WindowFunction val2 = Window; <>O.<0>__Window = val2; obj2 = (object)val2; } DisplayClassO.CachedWindow = (WindowFunction)obj2; obj = obj2; } GUI.Window(218102318, val, (WindowFunction)obj, "Item Drawer Options"); } private static void Window(int id) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) if ((Object)CurrentOptions.drawer == (Object)null || !CurrentOptions.drawer._znv.IsValid()) { ShowUI = false; return; } GUILayout.Label($"Current Drawer: {CurrentOptions.drawer.LocalizedName} ({CurrentOptions.drawer.CurrentAmount})", Array.Empty()); byte r = CurrentOptions.color.r; byte g = CurrentOptions.color.g; byte b = CurrentOptions.color.b; GUILayout.Label($"Text Color: 0123456789", Array.Empty()); GUILayout.Label($"R: {r}", Array.Empty()); r = (byte)GUILayout.HorizontalSlider((float)(int)r, 0f, 255f, Array.Empty()); GUILayout.Label($"G: {g}", Array.Empty()); g = (byte)GUILayout.HorizontalSlider((float)(int)g, 0f, 255f, Array.Empty()); GUILayout.Label($"B: {b}", Array.Empty()); b = (byte)GUILayout.HorizontalSlider((float)(int)b, 0f, 255f, Array.Empty()); CurrentOptions.color = new Color32(r, g, b, byte.MaxValue); int pickupRange = CurrentOptions.pickupRange; GUILayout.Space(16f); GUILayout.Label(string.Format("Pickup Range: {1}", (pickupRange > 0) ? "lime" : "red", pickupRange), Array.Empty()); pickupRange = (int)GUILayout.HorizontalSlider((float)pickupRange, 0f, (float)ItemDrawers.MaxDrawerPickupRange.Value, Array.Empty()); CurrentOptions.pickupRange = pickupRange; GUILayout.Space(16f); if (GUILayout.Button("Apply", Array.Empty())) { CurrentOptions.drawer._znv.InvokeRPC(ZNetView.Everybody, "ApplyOptions", new object[1] { CurrentOptions }); ShowUI = false; } } } [BepInPlugin("kg.ItemDrawers", "BROHEIM ItemDrawers", "1.0.0")] public class ItemDrawers : BaseUnityPlugin { public static ItemDrawers Instance; private static Harmony _harmony; public static ConfigEntry DrawerPickupRange; public static ConfigEntry MaxDrawerPickupRange; public static ConfigEntry DefaultColor; public static ConfigEntry ExcludeList; public static HashSet ExcludeSet = new HashSet(); public static ConfigEntry TextOutlineEnabled; public static ConfigEntry TextOutlineWidth; public static ConfigEntry TextOutlineColor; public static ConfigEntry TextShadowEnabled; public static ConfigEntry TextShadowColor; public static ConfigEntry TextShadowOffset; public static ConfigEntry TextShadowSoftness; public static GameObject Explosion; public static TMP_FontAsset NorseFont; private static AssetBundle _bundle; private static readonly string[] DrawerPrefabNames = new string[7] { "kg_ItemDrawer_Wood", "kg_ItemDrawer_Stone", "kg_ItemDrawer_Marble", "kg_ItemDrawerPanel_Wood", "kg_ItemDrawerPanel_Stone", "kg_ItemDrawerPanel_Marble", "kg_ItemDrawer_NoModel" }; private static readonly (string name, string item, int amount)[] DrawerRecipes = new(string, string, int)[7] { ("$piece_kg_ItemDrawer_Wood", "Wood", 10), ("$piece_kg_ItemDrawer_Stone", "Stone", 10), ("$piece_kg_ItemDrawer_Marble", "BlackMarble", 10), ("$piece_kg_ItemDrawerPanel_Wood", "Wood", 10), ("$piece_kg_ItemDrawerPanel_Stone", "Stone", 10), ("$piece_kg_ItemDrawerPanel_Marble", "BlackMarble", 10), ("$piece_kg_ItemDrawer_NoModel", "GreydwarfEye", 10) }; internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger; internal static IReadOnlyList AllDrawerPrefabNames => DrawerPrefabNames; internal static IReadOnlyList<(string name, string item, int amount)> AllDrawerRecipes => DrawerRecipes; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Expected O, but got Unknown //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Expected O, but got Unknown Instance = this; PieceManager.Instance.AddPieceCategory("itemdrawers"); ExcludeList = ((BaseUnityPlugin)this).Config.Bind("General", "ExcludeList", "", "List of items to exclude in the drawer. Leave blank to include all items."); ExcludeList.SettingChanged += ResetList; ResetList(null, null); DrawerPickupRange = ((BaseUnityPlugin)this).Config.Bind("General", "DrawerPickupRange", 4, "Range at which you can pick up items from the drawer."); MaxDrawerPickupRange = ((BaseUnityPlugin)this).Config.Bind("General", "MaxDrawerPickupRange", 100, "Maximum range at which you can pick up items from the drawer."); DefaultColor = ((BaseUnityPlugin)this).Config.Bind("General", "DefaultColor", new Vector3(0.039f, 0.729f, 0.71f), "Default color of the drawer text."); TextOutlineEnabled = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "OutlineEnabled", true, "Draw a black outline around the item-count digits for readability."); TextOutlineWidth = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "OutlineWidth", 0.15f, new ConfigDescription("Outline thickness (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); TextOutlineColor = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "OutlineColor", Color.black, "Outline color."); TextShadowEnabled = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "ShadowEnabled", true, "Draw a drop shadow under the item-count digits for readability."); TextShadowColor = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "ShadowColor", new Color(0f, 0f, 0f, 0.6f), "Shadow color (alpha controls opacity)."); TextShadowOffset = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "ShadowOffset", 0.4f, new ConfigDescription("Shadow offset distance (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); TextShadowSoftness = ((BaseUnityPlugin)this).Config.Bind("TextEffects", "ShadowSoftness", 0.15f, new ConfigDescription("Shadow softness/blur (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); _bundle = LoadAssetBundle("kg_itemdrawers"); Explosion = _bundle.LoadAsset("kg_ItemDrawer_Explosion"); NorseFont = NorseFontLoader.Load(); StationAuto.CfgEnabled = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "Enabled", true, "Master switch for auto-feed/deposit. Off = station integration does nothing."); StationAuto.CfgRadius = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "Radius", 8f, new ConfigDescription("Range (m) to search ItemDrawers around a station.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 50f), Array.Empty())); StationAuto.CfgSmelterRadius = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "SmelterRadius", 15f, new ConfigDescription("Range (m) for smelters/kilns pulling from ItemDrawers.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 50f), Array.Empty())); StationAuto.CfgFeed = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "FeedFromDrawers", true, "Stations pull fuel/materials directly from nearby ItemDrawers."); StationAuto.CfgDeposit = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "DepositToDrawers", true, "Cooking stations/beehives/sap collectors push finished output into matching nearby drawers."); StationAuto.CfgDebug = ((BaseUnityPlugin)this).Config.Bind("StationAuto", "DebugLogs", false, "Verbose logging."); StationAuto.VReflect.Init(); QuickStackBridge.CfgEnabled = ((BaseUnityPlugin)this).Config.Bind("QuickStackBridge", "Enabled", true, "Master switch."); QuickStackBridge.CfgQuickStackToDrawers = ((BaseUnityPlugin)this).Config.Bind("QuickStackBridge", "QuickStackToDrawers", true, "Quick Stack (P) also deposits stackable items into matching nearby ItemDrawers."); QuickStackBridge.CfgRestockFromDrawers = ((BaseUnityPlugin)this).Config.Bind("QuickStackBridge", "RestockFromDrawers", true, "Restock (L) also tops up partially filled stacks from matching nearby ItemDrawers."); QuickStackBridge.CfgDebug = ((BaseUnityPlugin)this).Config.Bind("QuickStackBridge", "DebugLogs", false, "Verbose logging."); Harmony val = new Harmony("kg.ItemDrawers"); _harmony = val; val.PatchAll(Assembly.GetExecutingAssembly()); AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoaded; TryInitQuickStackBridge(); Log.LogInfo((object)"BROHEIM ItemDrawers loaded."); } private static void OnAssemblyLoaded(object sender, AssemblyLoadEventArgs args) { if (!(args.LoadedAssembly.GetName().Name != "QuickStackStore")) { TryInitQuickStackBridge(); AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoaded; } } private static void TryInitQuickStackBridge() { if (!QuickStackBridge.QssReflect.Ready) { QuickStackBridge.QssReflect.Init(); if (QuickStackBridge.QssReflect.Ready) { QuickStackBridgePatch.Apply(_harmony); RestockBridgePatch.Apply(_harmony); Instance.Log.LogInfo((object)"QuickStackBridge patches applied (deferred)."); } } } private void OnGUI() { DrawerComponent.ProcessGUI(); } private void Update() { DrawerComponent.ProcessInput(); } private void ResetList(object sender, EventArgs e) { ExcludeSet = new HashSet(ExcludeList.Value.Replace(" ", "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)); } private static AssetBundle LoadAssetBundle(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().First((string s) => s.EndsWith(filename + ".bundle") || s.EndsWith(filename)); using Stream stream = executingAssembly.GetManifestResourceStream(name); return AssetBundle.LoadFromStream(stream); } internal static GameObject GetDrawerPrefab(string name) { return _bundle.LoadAsset(name); } } public static class NorseFontLoader { private static TMP_FontAsset _cached; private static bool _tried; public static TMP_FontAsset Load() { if (_tried) { return _cached; } _tried = true; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string s) => s.EndsWith("Norse-Bold.ttf") || s.EndsWith("Norse-Bold")); if (text == null) { ItemDrawers.Instance.Log.LogInfo((object)"NorseFontLoader: Norse-Bold.ttf not found in embedded resources."); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); byte[] bytes = memoryStream.ToArray(); string text2 = Path.Combine(Application.temporaryCachePath, "BROHEIM_Norse-Bold.ttf"); File.WriteAllBytes(text2, bytes); try { MethodInfo methodInfo = (from m in typeof(TMP_FontAsset).GetMethods(BindingFlags.Static | BindingFlags.Public) where m.Name == "CreateFontAsset" && m.GetParameters().Length == 7 && m.GetParameters()[0].ParameterType == typeof(string) select m).FirstOrDefault(); if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; array[0] = text2; array[1] = 0; array[2] = 90; array[3] = 9; Type parameterType = parameters[4].ParameterType; array[4] = Enum.ToObject(parameterType, 4165); array[5] = 1024; array[6] = 1024; object? obj = methodInfo.Invoke(null, array); TMP_FontAsset val = (TMP_FontAsset)((obj is TMP_FontAsset) ? obj : null); if ((Object)(object)val != (Object)null) { val.atlasPopulationMode = (AtlasPopulationMode)1; Object.DontDestroyOnLoad((Object)(object)val); _cached = val; ItemDrawers.Instance.Log.LogInfo((object)"NorseFontLoader: loaded Norse font via file path (Strategy 1)."); return _cached; } } } catch (Exception ex) { ItemDrawers.Instance.Log.LogInfo((object)("NorseFontLoader: Strategy 1 failed (" + ex.Message + ").")); } try { Font val2 = Font.CreateDynamicFontFromOSFont(text2, 90); if ((Object)(object)val2 != (Object)null) { val2.RequestCharactersInTexture("0123456789", 90); MethodInfo method = typeof(TMP_FontAsset).GetMethod("CreateFontAsset", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Font) }, null); if (method != null) { object? obj2 = method.Invoke(null, new object[1] { val2 }); TMP_FontAsset val3 = (TMP_FontAsset)((obj2 is TMP_FontAsset) ? obj2 : null); if ((Object)(object)val3 != (Object)null) { val3.atlasPopulationMode = (AtlasPopulationMode)1; Object.DontDestroyOnLoad((Object)(object)val3); Object.DontDestroyOnLoad((Object)(object)val2); _cached = val3; ItemDrawers.Instance.Log.LogInfo((object)"NorseFontLoader: loaded Norse font via Unity Font (Strategy 2)."); return _cached; } } } } catch (Exception ex2) { ItemDrawers.Instance.Log.LogInfo((object)("NorseFontLoader: Strategy 2 failed (" + ex2.Message + ").")); } try { Font val4 = Font.CreateDynamicFontFromOSFont("Norse-Bold", 90); if ((Object)(object)val4 != (Object)null) { val4.RequestCharactersInTexture("0123456789", 90); MethodInfo method2 = typeof(TMP_FontAsset).GetMethod("CreateFontAsset", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Font) }, null); if (method2 != null) { object? obj3 = method2.Invoke(null, new object[1] { val4 }); TMP_FontAsset val5 = (TMP_FontAsset)((obj3 is TMP_FontAsset) ? obj3 : null); if ((Object)(object)val5 != (Object)null) { val5.atlasPopulationMode = (AtlasPopulationMode)1; Object.DontDestroyOnLoad((Object)(object)val5); Object.DontDestroyOnLoad((Object)(object)val4); _cached = val5; ItemDrawers.Instance.Log.LogInfo((object)"NorseFontLoader: loaded Norse font via OS font name (Strategy 3)."); return _cached; } } } } catch (Exception ex3) { ItemDrawers.Instance.Log.LogInfo((object)("NorseFontLoader: Strategy 3 failed (" + ex3.Message + ").")); } ItemDrawers.Instance.Log.LogInfo((object)"NorseFontLoader: all strategies failed, using default font with size/color changes only."); return null; } catch (Exception ex4) { ItemDrawers.Instance.Log.LogInfo((object)("NorseFontLoader: could not load Norse font (" + ex4.Message + "), using default font with size/color changes.")); return null; } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetScene_Awake_Patch { private static readonly FieldInfo F_namedPrefabs = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); private static readonly FieldInfo F_prefabs = AccessTools.Field(typeof(ZNetScene), "m_prefabs"); [UsedImplicitly] private static void Postfix(ZNetScene __instance) { //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = (Dictionary)F_namedPrefabs.GetValue(__instance); List list = (List)F_prefabs.GetValue(__instance); dictionary[StringExtensionMethods.GetStableHashCode(((Object)ItemDrawers.Explosion).name)] = ItemDrawers.Explosion; foreach (string allDrawerPrefabName in ItemDrawers.AllDrawerPrefabNames) { GameObject drawerPrefab = ItemDrawers.GetDrawerPrefab(allDrawerPrefabName); if ((Object)(object)drawerPrefab == (Object)null) { ItemDrawers.Instance.Log.LogWarning((object)("Drawer prefab '" + allDrawerPrefabName + "' not found in AssetBundle!")); continue; } Piece val = drawerPrefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = drawerPrefab.AddComponent(); } if (allDrawerPrefabName.Contains("Wood") || allDrawerPrefabName.Contains("NoModel")) { GameObject prefab = __instance.GetPrefab("woodwall"); if ((Object)(object)prefab != (Object)null) { val.m_placeEffect = prefab.GetComponent().m_placeEffect; } } else if (allDrawerPrefabName.Contains("Stone")) { GameObject prefab2 = __instance.GetPrefab("stone_wall_1x1"); if ((Object)(object)prefab2 != (Object)null) { val.m_placeEffect = prefab2.GetComponent().m_placeEffect; } } else if (allDrawerPrefabName.Contains("Marble")) { GameObject prefab3 = __instance.GetPrefab("blackmarble_1x1"); if ((Object)(object)prefab3 != (Object)null) { val.m_placeEffect = prefab3.GetComponent().m_placeEffect; } } if ((Object)(object)drawerPrefab.GetComponent() == (Object)null) { drawerPrefab.AddComponent(); } int stableHashCode = StringExtensionMethods.GetStableHashCode(allDrawerPrefabName); dictionary[stableHashCode] = drawerPrefab; if (!list.Contains(drawerPrefab)) { list.Add(drawerPrefab); } } PieceCategory category = (PieceCategory)(((??)PieceManager.Instance.GetPieceCategory("itemdrawers")) ?? 4); foreach (string allDrawerPrefabName2 in ItemDrawers.AllDrawerPrefabNames) { GameObject drawerPrefab2 = ItemDrawers.GetDrawerPrefab(allDrawerPrefabName2); if (!((Object)(object)drawerPrefab2 == (Object)null)) { Piece component = drawerPrefab2.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_category = category; } } } ItemDrawers.Instance.Log.LogInfo((object)$"BROHEIM ItemDrawers: registered {ItemDrawers.AllDrawerPrefabNames.Count} drawer prefabs."); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ObjectDB_Awake_Patch { [UsedImplicitly] private static void Postfix(ObjectDB __instance) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown if ((Object)(object)__instance.GetItemPrefab("YmirRemains") == (Object)null) { return; } GameObject itemPrefab = __instance.GetItemPrefab("Hammer"); if ((Object)(object)itemPrefab == (Object)null) { return; } PieceTable val = itemPrefab.GetComponent()?.m_itemData.m_shared.m_buildPieces; if ((Object)(object)val == (Object)null) { return; } IReadOnlyList<(string, string, int)> allDrawerRecipes = ItemDrawers.AllDrawerRecipes; IReadOnlyList allDrawerPrefabNames = ItemDrawers.AllDrawerPrefabNames; for (int i = 0; i < allDrawerPrefabNames.Count && i < allDrawerRecipes.Count; i++) { string text = allDrawerPrefabNames[i]; (string, string, int) tuple = allDrawerRecipes[i]; string item = tuple.Item1; string item2 = tuple.Item2; int item3 = tuple.Item3; GameObject drawerPrefab = ItemDrawers.GetDrawerPrefab(text); if ((Object)(object)drawerPrefab == (Object)null) { continue; } Piece component = drawerPrefab.GetComponent(); if ((Object)(object)component == (Object)null) { continue; } component.m_name = item; GameObject itemPrefab2 = __instance.GetItemPrefab(item2); if ((Object)(object)itemPrefab2 != (Object)null) { component.m_resources = (Requirement[])(object)new Requirement[1] { new Requirement { m_resItem = itemPrefab2.GetComponent(), m_amount = item3, m_recover = true } }; } component.m_craftingStation = null; component.m_allowedInDungeons = true; int stableHashCode = StringExtensionMethods.GetStableHashCode(text); bool flag = false; foreach (GameObject piece in val.m_pieces) { if ((Object)(object)piece != (Object)null && StringExtensionMethods.GetStableHashCode(((Object)piece).name) == stableHashCode) { flag = true; break; } } if (!flag) { val.m_pieces.Add(drawerPrefab); } } ItemDrawers.Instance.Log.LogInfo((object)"BROHEIM ItemDrawers: added drawer pieces to hammer build table."); } } [HarmonyPatch(typeof(Piece), "DropResources")] public static class Piece_OnDestroy_Patch { [UsedImplicitly] private static void Postfix(Piece __instance) { //IL_0043: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) DrawerComponent component = ((Component)__instance).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.ItemValid && component.CurrentAmount > 0) { Utils.InstantiateAtPos(ZNetScene.instance.GetPrefab(component.CurrentPrefab), component.CurrentAmount, 1, ((Component)__instance).transform.position + Vector3.up); } } } internal static class QuickStackBridge { internal static class QssReflect { internal static bool Ready; internal static MethodInfo GetPlayerConfig; internal static MethodInfo IsItemNameOrSlotFavorited; private static Type _qsNested; private static Type _rsNested; private static FieldInfo _fQuickStackRange; private static FieldInfo _fRestockRange; private static FieldInfo _fQuickStackHotbar; private static FieldInfo _fRestockHotbar; private static Type _qssConfigType; internal static void Init() { try { _qssConfigType = AccessTools.TypeByName("QuickStackStore.QSSConfig"); if (_qssConfigType == null) { Ready = false; return; } GetPlayerConfig = AccessTools.Method("QuickStackStore.UserConfig:GetPlayerConfig", (Type[])null, (Type[])null); IsItemNameOrSlotFavorited = AccessTools.Method("QuickStackStore.UserConfig:IsItemNameOrSlotFavorited", (Type[])null, (Type[])null); _qsNested = AccessTools.Inner(_qssConfigType, "QuickStackConfig"); _rsNested = AccessTools.Inner(_qssConfigType, "RestockConfig"); if (_qsNested != null) { _fQuickStackRange = AccessTools.Field(_qsNested, "QuickStackToNearbyRange"); _fQuickStackHotbar = AccessTools.Field(_qsNested, "QuickStackIncludesHotkeyBar"); } if (_rsNested != null) { _fRestockRange = AccessTools.Field(_rsNested, "RestockFromNearbyRange"); _fRestockHotbar = AccessTools.Field(_rsNested, "RestockIncludesHotkeyBar"); } Ready = GetPlayerConfig != null && IsItemNameOrSlotFavorited != null; } catch { Ready = false; } } internal static float QuickStackRange() { try { if (_fQuickStackRange == null) { return 50f; } object value = _fQuickStackRange.GetValue(null); return (float)value.GetType().GetProperty("Value").GetValue(value, null); } catch { return 50f; } } internal static float RestockRange() { try { if (_fRestockRange == null) { return 50f; } object value = _fRestockRange.GetValue(null); return (float)value.GetType().GetProperty("Value").GetValue(value, null); } catch { return 50f; } } internal static bool QuickStackIncludesHotbar() { try { if (_fQuickStackHotbar == null) { return true; } object value = _fQuickStackHotbar.GetValue(null); return (bool)value.GetType().GetProperty("Value").GetValue(value, null); } catch { return true; } } internal static bool RestockIncludesHotbar() { try { if (_fRestockHotbar == null) { return true; } object value = _fRestockHotbar.GetValue(null); return (bool)value.GetType().GetProperty("Value").GetValue(value, null); } catch { return true; } } internal static bool IsFavorited(Player player, ItemData item) { try { object obj = GetPlayerConfig.Invoke(null, new object[1] { player.GetPlayerID() }); if (obj == null) { return false; } return (bool)IsItemNameOrSlotFavorited.Invoke(obj, new object[1] { item }); } catch { return false; } } } internal static class Drawers { internal static ZNetView Find(Vector3 pos, float radius, string prefab, int quality) { //IL_0058: 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) if (string.IsNullOrEmpty(prefab)) { return null; } foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if (!((Object)(object)allDrawer == (Object)null) && !((Object)(object)allDrawer._znv == (Object)null) && allDrawer._znv.IsValid()) { ZDO zDO = allDrawer._znv.GetZDO(); if (zDO != null && !(Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius) && !(zDO.GetString("Prefab", "") != prefab) && zDO.GetInt("Quality", 1) == quality) { return allDrawer._znv; } } } return null; } internal static List FindWithStock(Vector3 pos, float radius, string prefab, int quality) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0079: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrEmpty(prefab)) { return list; } foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if (!((Object)(object)allDrawer == (Object)null) && !((Object)(object)allDrawer._znv == (Object)null) && allDrawer._znv.IsValid()) { ZDO zDO = allDrawer._znv.GetZDO(); if (zDO != null && !(Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius) && !(zDO.GetString("Prefab", "") != prefab) && zDO.GetInt("Quality", 1) == quality && zDO.GetInt("Amount", 0) > 0) { list.Add(allDrawer._znv); } } } list.Sort((ZNetView a, ZNetView b) => Vector3.Distance(((Component)a).transform.position, pos).CompareTo(Vector3.Distance(((Component)b).transform.position, pos))); return list; } internal static void Add(ZNetView znv, string prefab, int quality, int count) { if ((Object)(object)znv == (Object)null || !znv.IsValid() || count <= 0) { return; } ZDO zDO = znv.GetZDO(); if (zDO != null) { int num = zDO.GetInt("Amount", 0); if (!znv.IsOwner()) { znv.ClaimOwnership(); } zDO.Set("Amount", num + count); znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num + count, quality }); } } internal static void Withdraw(ZNetView znv, string prefab, int quality, int count) { if ((Object)(object)znv == (Object)null || !znv.IsValid() || count <= 0) { return; } ZDO zDO = znv.GetZDO(); if (zDO != null) { int num = zDO.GetInt("Amount", 0); int num2 = Math.Max(0, num - count); if (!znv.IsOwner()) { znv.ClaimOwnership(); } zDO.Set("Amount", num2); znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num2, quality }); } } } internal static class Util { private static MethodInfo _miChanged; internal static Inventory GetInventory(Player player) { if (player == null) { return null; } return ((Humanoid)player).GetInventory(); } internal static void MarkChanged(Inventory inv) { if (inv == null) { return; } try { if (_miChanged == null) { _miChanged = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null); } _miChanged?.Invoke(inv, null); } catch (Exception ex) { Dbg("MarkChanged failed: " + ex.Message); } } internal static string PrefabName(ItemData item) { if (item == null) { return null; } if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name; } return null; } } internal static ConfigEntry CfgEnabled; internal static ConfigEntry CfgQuickStackToDrawers; internal static ConfigEntry CfgRestockFromDrawers; internal static ConfigEntry CfgDebug; internal static bool Active => CfgEnabled.Value; internal static void Dbg(string s) { if (CfgDebug.Value) { ItemDrawers.Instance.Log.LogInfo((object)s); } } } internal static class QuickStackBridgePatch { internal static void Apply(Harmony harmony) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method("QuickStackStore.QuickStackModule:ReportQuickStackResult", (Type[])null, (Type[])null); if (!(methodInfo == null)) { MethodInfo methodInfo2 = AccessTools.Method(typeof(QuickStackBridgePatch), "Prefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void Prefix(Player player, ref int movedCount) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (!QuickStackBridge.Active || !QuickStackBridge.CfgQuickStackToDrawers.Value || (Object)(object)player == (Object)null || !((Character)player).IsOwner() || ((Character)player).IsTeleporting()) { return; } float num = QuickStackBridge.QssReflect.QuickStackRange(); if (num <= 0f) { return; } Inventory inventory = QuickStackBridge.Util.GetInventory(player); if (inventory == null) { return; } bool flag = QuickStackBridge.QssReflect.QuickStackIncludesHotbar(); Vector3 position = ((Component)player).transform.position; int num2 = 0; List allItems = inventory.GetAllItems(); for (int num3 = allItems.Count - 1; num3 >= 0; num3--) { ItemData val = allItems[num3]; if (val != null && val.m_shared != null && val.m_shared.m_maxStackSize >= 1 && !val.m_equipped && !QuickStackBridge.QssReflect.IsFavorited(player, val) && (val.m_gridPos.y != 0 || flag)) { string text = QuickStackBridge.Util.PrefabName(val); if (!string.IsNullOrEmpty(text)) { ZNetView val2 = QuickStackBridge.Drawers.Find(position, num, text, val.m_quality); if (!((Object)(object)val2 == (Object)null)) { int stack = val.m_stack; QuickStackBridge.Drawers.Add(val2, text, val.m_quality, stack); inventory.RemoveItem(val); num2++; QuickStackBridge.Dbg($"QS->drawer: +{stack} {text} q{val.m_quality}"); } } } } if (num2 > 0) { QuickStackBridge.Util.MarkChanged(inventory); movedCount += num2; QuickStackBridge.Dbg($"QuickStack bridge moved {num2} stack(s) into drawers."); } } } internal static class RestockBridgePatch { internal static void Apply(Harmony harmony) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method("QuickStackStore.RestockModule:ReportRestockResult", (Type[])null, (Type[])null); if (!(methodInfo == null)) { MethodInfo methodInfo2 = AccessTools.Method(typeof(RestockBridgePatch), "Prefix", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void Prefix(Player player, ref int movedCount, ref int partiallyFilledCount, int totalCount) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (!QuickStackBridge.Active || !QuickStackBridge.CfgRestockFromDrawers.Value || (Object)(object)player == (Object)null || !((Character)player).IsOwner() || ((Character)player).IsTeleporting() || totalCount <= 0) { return; } float num = QuickStackBridge.QssReflect.RestockRange(); if (num <= 0f) { return; } Inventory inventory = QuickStackBridge.Util.GetInventory(player); if (inventory == null) { return; } bool flag = QuickStackBridge.QssReflect.RestockIncludesHotbar(); Vector3 position = ((Component)player).transform.position; int num2 = 0; int num3 = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem == null || allItem.m_shared == null) { continue; } int maxStackSize = allItem.m_shared.m_maxStackSize; if (maxStackSize <= 1 || allItem.m_equipped || QuickStackBridge.QssReflect.IsFavorited(player, allItem) || (allItem.m_gridPos.y == 0 && !flag) || allItem.m_stack >= maxStackSize || (allItem.m_customData != null && allItem.m_customData.Count > 0)) { continue; } string text = QuickStackBridge.Util.PrefabName(allItem); if (string.IsNullOrEmpty(text)) { continue; } int num4 = maxStackSize - allItem.m_stack; List list = QuickStackBridge.Drawers.FindWithStock(position, num, text, allItem.m_quality); int num5 = 0; foreach (ZNetView item in list) { if (num4 <= 0) { break; } int num6 = item.GetZDO().GetInt("Amount", 0); if (num6 > 0) { int num7 = Math.Min(num4, num6); QuickStackBridge.Drawers.Withdraw(item, text, allItem.m_quality, num7); num4 -= num7; num5 += num7; } } if (num5 > 0) { allItem.m_stack += num5; if (allItem.m_stack >= maxStackSize) { num2++; } else { num3++; } QuickStackBridge.Dbg($"Restock<-drawer: +{num5} {text} q{allItem.m_quality}"); } } if (num2 > 0 || num3 > 0) { QuickStackBridge.Util.MarkChanged(inventory); movedCount += num2; partiallyFilledCount += num3; if (movedCount > totalCount) { movedCount = totalCount; } QuickStackBridge.Dbg($"Restock bridge: +{num2} full, +{num3} partial from drawers."); } } } internal static class StationAuto { internal static class VReflect { internal static MethodInfo Smelter_GetFuel; internal static MethodInfo Smelter_GetQueueSize; internal static MethodInfo Cook_GetFuel; internal static MethodInfo Cook_GetSlot; internal static MethodInfo Cook_IsItemDone; internal static MethodInfo Cook_SetSlot; internal static MethodInfo Ferm_GetStatus; internal static MethodInfo Bee_GetHoneyLevel; internal static MethodInfo Sap_GetLevel; internal static Type CookStatusType; internal static object CookStatusZero; internal static void Init() { Smelter_GetFuel = AccessTools.Method(typeof(Smelter), "GetFuel", (Type[])null, (Type[])null); Smelter_GetQueueSize = AccessTools.Method(typeof(Smelter), "GetQueueSize", (Type[])null, (Type[])null); Cook_GetFuel = AccessTools.Method(typeof(CookingStation), "GetFuel", (Type[])null, (Type[])null); Cook_GetSlot = AccessTools.Method(typeof(CookingStation), "GetSlot", (Type[])null, (Type[])null); Cook_IsItemDone = AccessTools.Method(typeof(CookingStation), "IsItemDone", (Type[])null, (Type[])null); Cook_SetSlot = AccessTools.Method(typeof(CookingStation), "SetSlot", (Type[])null, (Type[])null); Ferm_GetStatus = AccessTools.Method(typeof(Fermenter), "GetStatus", (Type[])null, (Type[])null); Bee_GetHoneyLevel = AccessTools.Method(typeof(Beehive), "GetHoneyLevel", (Type[])null, (Type[])null); Sap_GetLevel = AccessTools.Method(typeof(SapCollector), "GetLevel", (Type[])null, (Type[])null); CookStatusType = AccessTools.Inner(typeof(CookingStation), "Status"); if (CookStatusType != null) { CookStatusZero = Enum.ToObject(CookStatusType, 0); } } } internal static class Drawers { internal static int Take(Vector3 pos, float radius, string prefab, int count) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (count <= 0 || string.IsNullOrEmpty(prefab)) { return 0; } int num = 0; foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if (num >= count) { break; } if ((Object)(object)allDrawer == (Object)null || (Object)(object)allDrawer._znv == (Object)null || !allDrawer._znv.IsValid()) { continue; } ZDO zDO = allDrawer._znv.GetZDO(); if (zDO == null || Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius || zDO.GetString("Prefab", "") != prefab) { continue; } int num2 = zDO.GetInt("Amount", 0); if (num2 > 0) { int num3 = Math.Min(count - num, num2); int num4 = zDO.GetInt("Quality", 1); if (!allDrawer._znv.IsOwner()) { allDrawer._znv.ClaimOwnership(); } zDO.Set("Amount", num2 - num3); allDrawer._znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num2 - num3, num4 }); num += num3; } } return num; } internal static ZNetView Find(Vector3 pos, float radius, string prefab, int quality) { //IL_0058: 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) if (string.IsNullOrEmpty(prefab)) { return null; } foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if (!((Object)(object)allDrawer == (Object)null) && !((Object)(object)allDrawer._znv == (Object)null) && allDrawer._znv.IsValid()) { ZDO zDO = allDrawer._znv.GetZDO(); if (zDO != null && !(Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius) && !(zDO.GetString("Prefab", "") != prefab) && zDO.GetInt("Quality", 1) == quality) { return allDrawer._znv; } } } return null; } internal static void Add(ZNetView znv, string prefab, int quality, int count) { if ((Object)(object)znv == (Object)null || !znv.IsValid() || count <= 0) { return; } ZDO zDO = znv.GetZDO(); if (zDO != null) { int num = zDO.GetInt("Amount", 0); if (!znv.IsOwner()) { znv.ClaimOwnership(); } zDO.Set("Amount", num + count); znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num + count, quality }); } } } internal static class Throttle { private static readonly Dictionary _last = new Dictionary(); private const float Interval = 1f; internal static bool Ready(GameObject go) { int instanceID = ((Object)go).GetInstanceID(); float time = Time.time; if (_last.TryGetValue(instanceID, out var value) && time - value < 1f) { return false; } _last[instanceID] = time; return true; } } internal static ConfigEntry CfgEnabled; internal static ConfigEntry CfgRadius; internal static ConfigEntry CfgSmelterRadius; internal static ConfigEntry CfgFeed; internal static ConfigEntry CfgDeposit; internal static ConfigEntry CfgDebug; internal static bool Active => CfgEnabled.Value; internal static float Radius => Mathf.Clamp(CfgRadius.Value, 1f, 50f); internal static float SmelterRadius => Mathf.Clamp(CfgSmelterRadius.Value, 1f, 50f); internal static float MaxFeedRadius => Mathf.Max(Radius, SmelterRadius); internal static void Dbg(string s) { if (CfgDebug.Value) { ItemDrawers.Instance.Log.LogInfo((object)s); } } internal static string PrefabName(ItemDrop drop) { if (!((Object)(object)drop == (Object)null)) { return ((Object)((Component)drop).gameObject).name; } return null; } internal static string ConvFrom(object conversion) { object? value = AccessTools.Field(conversion.GetType(), "m_from").GetValue(conversion); return PrefabName((ItemDrop)((value is ItemDrop) ? value : null)); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class Player_OnSpawned_Patch { private static void Postfix() { DrawerRangeFixer.Run(force: true); } } [HarmonyPatch(typeof(Player), "Update")] internal static class Player_Update_Patch { private static void Postfix() { DrawerRangeFixer.Run(); } } [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] internal static class Smelter_Patch { private static void Prefix(Smelter __instance) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_012f: Unknown result type (might be due to invalid IL or missing references) if (!StationAuto.Active || !StationAuto.CfgFeed.Value || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } Vector3 position = ((Component)__instance).transform.position; float smelterRadius = StationAuto.SmelterRadius; float num = (float)StationAuto.VReflect.Smelter_GetFuel.Invoke(__instance, null); int num2 = __instance.m_maxFuel - (int)Math.Ceiling(num); if ((Object)(object)__instance.m_fuelItem != (Object)null && num2 > 0) { string prefab = StationAuto.PrefabName(__instance.m_fuelItem); int num3 = StationAuto.Drawers.Take(position, smelterRadius, prefab, num2); for (int i = 0; i < num3; i++) { component.InvokeRPC("RPC_AddFuel", Array.Empty()); } } int num4 = (int)StationAuto.VReflect.Smelter_GetQueueSize.Invoke(__instance, null); int num5 = __instance.m_maxOre - num4; if (num5 <= 0 || __instance.m_conversion == null) { return; } foreach (object item in (IEnumerable)__instance.m_conversion) { string text = StationAuto.ConvFrom(item); if (!string.IsNullOrEmpty(text)) { int num6 = StationAuto.Drawers.Take(position, smelterRadius, text, num5); for (int j = 0; j < num6; j++) { component.InvokeRPC("RPC_AddOre", new object[1] { text }); } num5 -= num6; if (num5 <= 0) { break; } } } } } [HarmonyPatch(typeof(CookingStation), "UpdateCooking")] internal static class CookingStation_Patch { private static void Prefix(CookingStation __instance) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (!StationAuto.Active || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } Vector3 position = ((Component)__instance).transform.position; float radius = StationAuto.Radius; if (StationAuto.CfgFeed.Value) { float num = (float)StationAuto.VReflect.Cook_GetFuel.Invoke(__instance, null); int num2 = __instance.m_maxFuel - (int)Math.Ceiling(num); if ((Object)(object)__instance.m_fuelItem != (Object)null && num2 > 0) { string prefab = StationAuto.PrefabName(__instance.m_fuelItem); int num3 = StationAuto.Drawers.Take(position, radius, prefab, num2); for (int i = 0; i < num3; i++) { component.InvokeRPC("RPC_AddFuel", Array.Empty()); } } int num4 = CountFreeSlots(__instance); if (num4 > 0 && __instance.m_conversion != null) { foreach (object item in (IEnumerable)__instance.m_conversion) { string text = StationAuto.ConvFrom(item); if (!string.IsNullOrEmpty(text)) { int num5 = StationAuto.Drawers.Take(position, radius, text, num4); for (int j = 0; j < num5; j++) { component.InvokeRPC("RPC_AddItem", new object[1] { text }); } num4 -= num5; if (num4 <= 0) { break; } } } } } if (!StationAuto.CfgDeposit.Value) { return; } int length = __instance.m_slots.Length; for (int k = 0; k < length; k++) { object[] array = new object[4] { k, null, null, null }; StationAuto.VReflect.Cook_GetSlot.Invoke(__instance, array); string text2 = array[1] as string; if (!string.IsNullOrEmpty(text2) && (bool)StationAuto.VReflect.Cook_IsItemDone.Invoke(__instance, new object[1] { text2 })) { ZNetView val = StationAuto.Drawers.Find(position, radius, text2, 1); if (!((Object)(object)val == (Object)null)) { StationAuto.VReflect.Cook_SetSlot.Invoke(__instance, new object[4] { k, "", 0f, StationAuto.VReflect.CookStatusZero }); component.InvokeRPC(ZNetView.Everybody, "RPC_SetSlotVisual", new object[2] { k, "" }); StationAuto.Drawers.Add(val, text2, 1, 1); break; } } } } private static int CountFreeSlots(CookingStation cs) { int length = cs.m_slots.Length; int num = 0; for (int i = 0; i < length; i++) { object[] array = new object[4] { i, null, null, null }; StationAuto.VReflect.Cook_GetSlot.Invoke(cs, array); if (string.IsNullOrEmpty(array[1] as string)) { num++; } } return num; } } [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] internal static class Fireplace_Patch { private static void Prefix(Fireplace __instance) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (!StationAuto.Active || !StationAuto.CfgFeed.Value || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || !__instance.m_canRefill || __instance.m_infiniteFuel || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } float num = component.GetZDO().GetFloat("fuel", 0f); int num2 = (int)__instance.m_maxFuel - (int)Math.Ceiling(num); if (!((Object)(object)__instance.m_fuelItem == (Object)null) && num2 > 0) { int num3 = StationAuto.Drawers.Take(((Component)__instance).transform.position, prefab: StationAuto.PrefabName(__instance.m_fuelItem), radius: StationAuto.Radius, count: num2); for (int i = 0; i < num3; i++) { component.InvokeRPC("RPC_AddFuel", Array.Empty()); } } } } [HarmonyPatch(typeof(Fermenter), "SlowUpdate")] internal static class Fermenter_Patch { private static void Postfix(Fermenter __instance) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (!StationAuto.Active || !StationAuto.CfgFeed.Value || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || (int)StationAuto.VReflect.Ferm_GetStatus.Invoke(__instance, null) != 0 || __instance.m_conversion == null || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } Vector3 position = ((Component)__instance).transform.position; float radius = StationAuto.Radius; foreach (object item in (IEnumerable)__instance.m_conversion) { string text = StationAuto.ConvFrom(item); if (!string.IsNullOrEmpty(text) && StationAuto.Drawers.Take(position, radius, text, 1) > 0) { component.InvokeRPC("RPC_AddItem", new object[1] { text }); break; } } } } [HarmonyPatch(typeof(Beehive), "UpdateBees")] internal static class Beehive_Patch { private static void Postfix(Beehive __instance) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) if (!StationAuto.Active || !StationAuto.CfgDeposit.Value || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || (Object)(object)__instance.m_honeyItem == (Object)null || (int)StationAuto.VReflect.Bee_GetHoneyLevel.Invoke(__instance, null) <= 0 || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } Vector3 position = ((Component)__instance).transform.position; float radius = StationAuto.Radius; string prefab = StationAuto.PrefabName(__instance.m_honeyItem); while ((int)StationAuto.VReflect.Bee_GetHoneyLevel.Invoke(__instance, null) > 0) { ZNetView val = StationAuto.Drawers.Find(position, radius, prefab, 1); if (!((Object)(object)val == (Object)null)) { int num = (int)StationAuto.VReflect.Bee_GetHoneyLevel.Invoke(__instance, null); component.GetZDO().Set("level", num - 1); StationAuto.Drawers.Add(val, prefab, 1, 1); continue; } break; } } } [HarmonyPatch(typeof(SapCollector), "UpdateTick")] internal static class SapCollector_Patch { private static void Postfix(SapCollector __instance) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) if (!StationAuto.Active || !StationAuto.CfgDeposit.Value || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner() || (Object)(object)__instance.m_spawnItem == (Object)null || (int)StationAuto.VReflect.Sap_GetLevel.Invoke(__instance, null) <= 0 || !StationAuto.Throttle.Ready(((Component)__instance).gameObject)) { return; } Vector3 position = ((Component)__instance).transform.position; float radius = StationAuto.Radius; string prefab = StationAuto.PrefabName(__instance.m_spawnItem); while ((int)StationAuto.VReflect.Sap_GetLevel.Invoke(__instance, null) > 0) { ZNetView val = StationAuto.Drawers.Find(position, radius, prefab, 1); if (!((Object)(object)val == (Object)null)) { int num = (int)StationAuto.VReflect.Sap_GetLevel.Invoke(__instance, null); component.GetZDO().Set("level", num - 1); StationAuto.Drawers.Add(val, prefab, 1, 1); continue; } break; } } } internal static class DrawerRangeFixer { private static float _lastFix; private const float FixInterval = 10f; internal static void Run(bool force = false) { if (!StationAuto.Active) { return; } float time = Time.time; if (!force && time - _lastFix < 10f) { return; } _lastFix = time; int num = Mathf.RoundToInt(StationAuto.MaxFeedRadius); int num2 = 0; foreach (DrawerComponent allDrawer in DrawerComponent.AllDrawers) { if ((Object)(object)allDrawer == (Object)null || (Object)(object)allDrawer._znv == (Object)null || !allDrawer._znv.IsValid()) { continue; } ZDO zDO = allDrawer._znv.GetZDO(); if (zDO != null && zDO.GetInt("PickupRange", 0) < num) { if (!allDrawer._znv.IsOwner()) { allDrawer._znv.ClaimOwnership(); } zDO.Set("PickupRange", num); num2++; } } if (num2 > 0) { ItemDrawers.Instance.Log.LogInfo((object)$"DrawerAuto: boosted PickupRange to {num} on {num2} drawer(s)."); } } } public static class Utils { private static readonly MethodInfo M_ItemDrop_Save = AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null); public static string Localize(this string s) { return Localization.instance.Localize(s); } public static Vector3 ColorToVec3(Color32 c) { //IL_0000: 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_001a: 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) return new Vector3((float)(int)c.r / 255f, (float)(int)c.g / 255f, (float)(int)c.b / 255f); } public static Color32 Vec3ToColor(Vector3 v) { //IL_0000: 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_001a: 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) return new Color32((byte)(v.x * 255f), (byte)(v.y * 255f), (byte)(v.z * 255f), byte.MaxValue); } public static int CustomCountItems(string prefab, int level) { int num = 0; foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == prefab && level == allItem.m_quality) { num += allItem.m_stack; } } return num; } public static void CustomRemoveItems(string prefab, int amount, int level) { Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); List allItems = inventory.GetAllItems(); for (int num = allItems.Count - 1; num >= 0; num--) { ItemData val = allItems[num]; if ((Object)(object)val.m_dropPrefab != (Object)null && ((Object)val.m_dropPrefab).name == prefab && val.m_quality == level) { int num2 = Mathf.Min(val.m_stack, amount); val.m_stack -= num2; amount -= num2; if (amount <= 0) { break; } } } allItems.RemoveAll((ItemData x) => x.m_stack <= 0); typeof(Inventory).GetMethod("Changed")?.Invoke(inventory, null); } public static void InstantiateItem(GameObject prefab, int stack, int level) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)localPlayer) || !Object.op_Implicit((Object)prefab)) { return; } ItemDrop component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { return; } if (component.m_itemData.m_shared.m_maxStackSize > 1) { while (stack > 0) { int num = Math.Min(stack, component.m_itemData.m_shared.m_maxStackSize); stack -= num; ItemDrop component2 = Object.Instantiate(prefab, ((Component)localPlayer).transform.position + Vector3.up * 1.5f, Quaternion.identity).GetComponent(); component2.m_itemData.m_stack = num; component2.m_itemData.m_durability = component.m_itemData.GetMaxDurability(); M_ItemDrop_Save.Invoke(component2, null); if (((Humanoid)localPlayer).GetInventory().CanAddItem(((Component)component2).gameObject, -1)) { ((Humanoid)localPlayer).GetInventory().AddItem(component2.m_itemData); ZNetScene.instance.Destroy(((Component)component2).gameObject); } } return; } for (int i = 0; i < stack; i++) { GameObject val = Object.Instantiate(prefab, ((Component)localPlayer).transform.position + Vector3.up * 1.5f, Quaternion.identity); ItemDrop component3 = val.GetComponent(); component3.m_itemData.m_quality = level; component3.m_itemData.m_durability = component3.m_itemData.GetMaxDurability(); M_ItemDrop_Save.Invoke(component3, null); if (((Humanoid)localPlayer).GetInventory().CanAddItem(val, -1)) { ((Humanoid)localPlayer).GetInventory().AddItem(component3.m_itemData); ZNetScene.instance.Destroy(val); } } } public static void InstantiateAtPos(GameObject prefab, int stack, int level, Vector3 pos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)Player.m_localPlayer) && Object.op_Implicit((Object)prefab)) { ItemDrop component = prefab.GetComponent(); while (stack > 0) { int num = Math.Min(stack, component.m_itemData.m_shared.m_maxStackSize); stack -= num; ItemDrop component2 = Object.Instantiate(prefab, pos, Quaternion.identity).GetComponent(); component2.m_itemData.m_stack = num; float maxDurability = component.m_itemData.GetMaxDurability(); component2.m_itemData.m_durability = maxDurability; M_ItemDrop_Save.Invoke(component2, null); } } } } } namespace API { public static class ClientSideV2 { public static List AllDrawers() { return (from d in DrawerComponent.AllDrawers where (Object)(object)d != (Object)null && (Object)(object)d._znv != (Object)null && d._znv.IsValid() select d._znv).ToList(); } } public static class ItemDrawers_API { public class Drawer(ZNetView znv) { public string Prefab = znv.GetZDO().GetString("Prefab", ""); public int Amount = znv.GetZDO().GetInt("Amount", 0); public int Quality = znv.GetZDO().GetInt("Quality", 1); public void Remove(int amount) { znv.ClaimOwnership(); znv.InvokeRPC("ForceRemove", new object[1] { amount }); } public void Withdraw(int amount) { znv.InvokeRPC("WithdrawItem_Request", new object[1] { amount }); } public void Add(int amount, int quality) { znv.InvokeRPC("AddItem_Request", new object[3] { Prefab, amount, quality }); } } private static readonly bool _IsInstalled; private static readonly MethodInfo MI_GetAllDrawers; public static List AllDrawers { get { if (!_IsInstalled) { return new List(); } return ((List)MI_GetAllDrawers.Invoke(null, null)).Select((ZNetView znv) => new Drawer(znv)).ToList(); } } public static List AllDrawersInRange(Vector3 pos, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!_IsInstalled) { return new List(); } return (from znv in (List)MI_GetAllDrawers.Invoke(null, null) where Vector3.Distance(((Component)znv).transform.position, pos) <= range select new Drawer(znv)).ToList(); } static ItemDrawers_API() { Type type = Type.GetType("API.ClientSideV2, kg_ItemDrawers"); if ((object)type == null) { _IsInstalled = false; return; } _IsInstalled = true; MI_GetAllDrawers = type.GetMethod("AllDrawers", BindingFlags.Static | BindingFlags.Public); } } }