Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ItemDrawers v1.0.2
kg_ItemDrawers.dll
Decompiled 3 days agousing 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<DrawerComponent> 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<DrawerComponent> 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<DrawerComponent> 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<DrawerComponent> list = new List<DrawerComponent>(); 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<DrawerComponent> 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<ItemDrop>(); 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<DrawerComponent> 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<ItemDrop>(); 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<MethodInfo> 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<DrawerComponent> AllDrawers = new List<DrawerComponent>(); 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<ItemDrop>().m_itemData.m_shared.m_maxStackSize; private string LocalizedName => ObjectDB.instance.GetItemPrefab(CurrentPrefab).GetComponent<ItemDrop>().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<ZNetView>(); if (_znv.IsValid()) { AllDrawers.Add(this); _image = ((Component)((Component)this).transform.Find("Cube/Canvas/Image")).GetComponent<Image>(); if ((Object)(object)_defaultSprite == (Object)null) { _defaultSprite = _image.sprite; } _text = ((Component)((Component)this).transform.Find("Cube/Canvas/Text")).GetComponent<TMP_Text>(); 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<TMP_Text>(); _starIcon = _stars.Find("Img"); ApplyTextEffects(_text); ApplyTextEffects(_starsText); _znv.Register<string, int, int>("AddItem_Request", (Action<long, string, int, int>)RPC_AddItem); _znv.Register<string, int, int>("AddItem_Player", (Action<long, string, int, int>)RPC_AddItem_Player); _znv.Register<int>("WithdrawItem_Request", (Action<long, int>)RPC_WithdrawItem_Request); _znv.Register<string, int, int>("UpdateIcon", (Action<long, string, int, int>)RPC_UpdateIcon); _znv.Register<int>("ForceRemove", (Action<long, int>)RPC_ForceRemove); _znv.Register<DrawerOptions>("ApplyOptions", (Action<long, DrawerOptions>)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<ItemDrop>().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<RectTransform>(); _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<ItemDrop> enumerable = (IEnumerable<ItemDrop>)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<GameObject>(ItemDrawers.Explosion, ((Component)item).transform.position, Quaternion.identity); int stack = item.m_itemData.m_stack; ZNetView component = ((Component)item).GetComponent<ZNetView>(); 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("[<color=yellow><b>$KEY_Use</b></color>] open settings"); return stringBuilder.ToString().Localize(); } if (!ItemValid) { stringBuilder.AppendLine("<color=yellow><b>Use Hotbar to add item</b></color>"); return stringBuilder.ToString().Localize(); } int quality = Quality; string arg = ((quality > 1) ? $" (Quality: {quality})" : ""); stringBuilder.AppendLine($"<color=yellow><b>{LocalizedName}{arg}</b></color> ({CurrentAmount})"); stringBuilder.AppendLine("<color=yellow><b>Use Hotbar to add item</b></color>\n"); if (CurrentAmount <= 0) { stringBuilder.AppendLine("[<color=yellow><b>$KEY_Use</b></color>] or [<color=yellow><b>Left Alt + $KEY_Use</b></color>] to clear"); stringBuilder.AppendLine($"[<color=yellow><b>Left Shift + $KEY_Use</b></color>] to deposit all <color=yellow><b>{LocalizedName}</b></color> ({Utils.CustomCountItems(CurrentPrefab, quality)})"); return stringBuilder.ToString().Localize(); } stringBuilder.AppendLine($"[<color=yellow><b>$KEY_Use</b></color>] to withdraw stack ({ItemMaxStack})"); stringBuilder.AppendLine("[<color=yellow><b>Left Alt + $KEY_Use</b></color>] to withdraw single item"); stringBuilder.AppendLine($"[<color=yellow><b>Left Shift + $KEY_Use</b></color>] to deposit all <color=yellow><b>{LocalizedName}{arg}</b></color> ({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: <color=yellow><b>{CurrentOptions.drawer.LocalizedName}</b></color> ({CurrentOptions.drawer.CurrentAmount})", Array.Empty<GUILayoutOption>()); byte r = CurrentOptions.color.r; byte g = CurrentOptions.color.g; byte b = CurrentOptions.color.b; GUILayout.Label($"Text Color: <color=#{r:X2}{g:X2}{b:X2}><b>0123456789</b></color>", Array.Empty<GUILayoutOption>()); GUILayout.Label($"R: {r}", Array.Empty<GUILayoutOption>()); r = (byte)GUILayout.HorizontalSlider((float)(int)r, 0f, 255f, Array.Empty<GUILayoutOption>()); GUILayout.Label($"G: {g}", Array.Empty<GUILayoutOption>()); g = (byte)GUILayout.HorizontalSlider((float)(int)g, 0f, 255f, Array.Empty<GUILayoutOption>()); GUILayout.Label($"B: {b}", Array.Empty<GUILayoutOption>()); b = (byte)GUILayout.HorizontalSlider((float)(int)b, 0f, 255f, Array.Empty<GUILayoutOption>()); CurrentOptions.color = new Color32(r, g, b, byte.MaxValue); int pickupRange = CurrentOptions.pickupRange; GUILayout.Space(16f); GUILayout.Label(string.Format("Pickup Range: <color={0}><b>{1}</b></color>", (pickupRange > 0) ? "lime" : "red", pickupRange), Array.Empty<GUILayoutOption>()); pickupRange = (int)GUILayout.HorizontalSlider((float)pickupRange, 0f, (float)ItemDrawers.MaxDrawerPickupRange.Value, Array.Empty<GUILayoutOption>()); CurrentOptions.pickupRange = pickupRange; GUILayout.Space(16f); if (GUILayout.Button("<color=lime>Apply</color>", Array.Empty<GUILayoutOption>())) { 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<int> DrawerPickupRange; public static ConfigEntry<int> MaxDrawerPickupRange; public static ConfigEntry<Vector3> DefaultColor; public static ConfigEntry<string> ExcludeList; public static HashSet<string> ExcludeSet = new HashSet<string>(); public static ConfigEntry<bool> TextOutlineEnabled; public static ConfigEntry<float> TextOutlineWidth; public static ConfigEntry<Color> TextOutlineColor; public static ConfigEntry<bool> TextShadowEnabled; public static ConfigEntry<Color> TextShadowColor; public static ConfigEntry<float> TextShadowOffset; public static ConfigEntry<float> 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<string> 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<string>("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<int>("General", "DrawerPickupRange", 4, "Range at which you can pick up items from the drawer."); MaxDrawerPickupRange = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxDrawerPickupRange", 100, "Maximum range at which you can pick up items from the drawer."); DefaultColor = ((BaseUnityPlugin)this).Config.Bind<Vector3>("General", "DefaultColor", new Vector3(0.039f, 0.729f, 0.71f), "Default color of the drawer text."); TextOutlineEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("TextEffects", "OutlineEnabled", true, "Draw a black outline around the item-count digits for readability."); TextOutlineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("TextEffects", "OutlineWidth", 0.15f, new ConfigDescription("Outline thickness (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); TextOutlineColor = ((BaseUnityPlugin)this).Config.Bind<Color>("TextEffects", "OutlineColor", Color.black, "Outline color."); TextShadowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("TextEffects", "ShadowEnabled", true, "Draw a drop shadow under the item-count digits for readability."); TextShadowColor = ((BaseUnityPlugin)this).Config.Bind<Color>("TextEffects", "ShadowColor", new Color(0f, 0f, 0f, 0.6f), "Shadow color (alpha controls opacity)."); TextShadowOffset = ((BaseUnityPlugin)this).Config.Bind<float>("TextEffects", "ShadowOffset", 0.4f, new ConfigDescription("Shadow offset distance (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); TextShadowSoftness = ((BaseUnityPlugin)this).Config.Bind<float>("TextEffects", "ShadowSoftness", 0.15f, new ConfigDescription("Shadow softness/blur (0.0–1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _bundle = LoadAssetBundle("kg_itemdrawers"); Explosion = _bundle.LoadAsset<GameObject>("kg_ItemDrawer_Explosion"); NorseFont = NorseFontLoader.Load(); StationAuto.CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("StationAuto", "Enabled", true, "Master switch for auto-feed/deposit. Off = station integration does nothing."); StationAuto.CfgRadius = ((BaseUnityPlugin)this).Config.Bind<float>("StationAuto", "Radius", 8f, new ConfigDescription("Range (m) to search ItemDrawers around a station.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); StationAuto.CfgSmelterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("StationAuto", "SmelterRadius", 15f, new ConfigDescription("Range (m) for smelters/kilns pulling from ItemDrawers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); StationAuto.CfgFeed = ((BaseUnityPlugin)this).Config.Bind<bool>("StationAuto", "FeedFromDrawers", true, "Stations pull fuel/materials directly from nearby ItemDrawers."); StationAuto.CfgDeposit = ((BaseUnityPlugin)this).Config.Bind<bool>("StationAuto", "DepositToDrawers", true, "Cooking stations/beehives/sap collectors push finished output into matching nearby drawers."); StationAuto.CfgDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("StationAuto", "DebugLogs", false, "Verbose logging."); StationAuto.VReflect.Init(); QuickStackBridge.CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("QuickStackBridge", "Enabled", true, "Master switch."); QuickStackBridge.CfgQuickStackToDrawers = ((BaseUnityPlugin)this).Config.Bind<bool>("QuickStackBridge", "QuickStackToDrawers", true, "Quick Stack (P) also deposits stackable items into matching nearby ItemDrawers."); QuickStackBridge.CfgRestockFromDrawers = ((BaseUnityPlugin)this).Config.Bind<bool>("QuickStackBridge", "RestockFromDrawers", true, "Restock (L) also tops up partially filled stacks from matching nearby ItemDrawers."); QuickStackBridge.CfgDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("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<string>(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<GameObject>(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<int, GameObject> dictionary = (Dictionary<int, GameObject>)F_namedPrefabs.GetValue(__instance); List<GameObject> list = (List<GameObject>)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<Piece>(); if ((Object)(object)val == (Object)null) { val = drawerPrefab.AddComponent<Piece>(); } if (allDrawerPrefabName.Contains("Wood") || allDrawerPrefabName.Contains("NoModel")) { GameObject prefab = __instance.GetPrefab("woodwall"); if ((Object)(object)prefab != (Object)null) { val.m_placeEffect = prefab.GetComponent<Piece>().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<Piece>().m_placeEffect; } } else if (allDrawerPrefabName.Contains("Marble")) { GameObject prefab3 = __instance.GetPrefab("blackmarble_1x1"); if ((Object)(object)prefab3 != (Object)null) { val.m_placeEffect = prefab3.GetComponent<Piece>().m_placeEffect; } } if ((Object)(object)drawerPrefab.GetComponent<DrawerComponent>() == (Object)null) { drawerPrefab.AddComponent<DrawerComponent>(); } 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<Piece>(); 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<ItemDrop>()?.m_itemData.m_shared.m_buildPieces; if ((Object)(object)val == (Object)null) { return; } IReadOnlyList<(string, string, int)> allDrawerRecipes = ItemDrawers.AllDrawerRecipes; IReadOnlyList<string> 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<Piece>(); 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<ItemDrop>(), 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<DrawerComponent>(); 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<ZNetView> 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<ZNetView> list = new List<ZNetView>(); 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<bool> CfgEnabled; internal static ConfigEntry<bool> CfgQuickStackToDrawers; internal static ConfigEntry<bool> CfgRestockFromDrawers; internal static ConfigEntry<bool> 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<ItemData> 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<ZNetView> 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<int, float> _last = new Dictionary<int, float>(); 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<bool> CfgEnabled; internal static ConfigEntry<float> CfgRadius; internal static ConfigEntry<float> CfgSmelterRadius; internal static ConfigEntry<bool> CfgFeed; internal static ConfigEntry<bool> CfgDeposit; internal static ConfigEntry<bool> 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<ZNetView>(); 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<object>()); } } 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<ZNetView>(); 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<object>()); } } 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<ZNetView>(); 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<object>()); } } } } [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<ZNetView>(); 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<ZNetView>(); 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<ZNetView>(); 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<ItemData> 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<ItemDrop>(); 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<GameObject>(prefab, ((Component)localPlayer).transform.position + Vector3.up * 1.5f, Quaternion.identity).GetComponent<ItemDrop>(); 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<GameObject>(prefab, ((Component)localPlayer).transform.position + Vector3.up * 1.5f, Quaternion.identity); ItemDrop component3 = val.GetComponent<ItemDrop>(); 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<ItemDrop>(); while (stack > 0) { int num = Math.Min(stack, component.m_itemData.m_shared.m_maxStackSize); stack -= num; ItemDrop component2 = Object.Instantiate<GameObject>(prefab, pos, Quaternion.identity).GetComponent<ItemDrop>(); 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<ZNetView> 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<Drawer> AllDrawers { get { if (!_IsInstalled) { return new List<Drawer>(); } return ((List<ZNetView>)MI_GetAllDrawers.Invoke(null, null)).Select((ZNetView znv) => new Drawer(znv)).ToList(); } } public static List<Drawer> 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<Drawer>(); } return (from znv in (List<ZNetView>)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); } } }