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.InteropServices; 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) + DrawerComponent.CountEnchantedFromZdo(zDO); } } } 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)) { int num2 = zDO.GetInt("Amount", 0); int num3 = Mathf.Min(needed - num, num2); if (num3 > 0) { drawer._znv.InvokeRPC("ForceRemove", new object[1] { num3 }); 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 static Sprite _circleSprite; private Image _image; private TMP_Text _text; private Transform _stars; private TMP_Text _starsText; private Transform _starIcon; private Image _rarityCircle; 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 string EnchantedData { get { return _znv.GetZDO().GetString("EnchantedB64", ""); } set { _znv.GetZDO().Set("EnchantedB64", value ?? ""); } } public int EnchantedCount { get { ZNetView znv = _znv; return CountEnchantedFromZdo((znv != null) ? znv.GetZDO() : null); } } public int TotalCount => CurrentAmount + EnchantedCount; 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 { get { if (EnchantedCount > 0) { List<(string, ItemData)> enchantedItems = GetEnchantedItems(); if (enchantedItems.Count > 0) { string epicLootDisplayName = Utils.GetEpicLootDisplayName(enchantedItems[0].Item2); if (!string.IsNullOrEmpty(epicLootDisplayName)) { return epicLootDisplayName; } } } return 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 List<(string prefabName, ItemData item)> GetEnchantedItems() { string enchantedData = EnchantedData; if (string.IsNullOrEmpty(enchantedData)) { return new List<(string, ItemData)>(); } byte[] bytes; try { bytes = Convert.FromBase64String(enchantedData); } catch { return new List<(string, ItemData)>(); } return Utils.DeserializeNamedItemList(bytes, (string name) => ObjectDB.instance.GetItemPrefab(name)); } private void SetEnchantedItems(List<(string prefabName, ItemData item)> items) { ZDO zDO = _znv.GetZDO(); if (items == null || items.Count == 0) { EnchantedData = ""; zDO.Set("EncCount", 0); return; } byte[] array = Utils.SerializeNamedItemList(items); if (array == null || array.Length == 0) { EnchantedData = ""; zDO.Set("EncCount", 0); } else { EnchantedData = Convert.ToBase64String(array); zDO.Set("EncCount", items.Count); } } public static int CountEnchantedFromZdo(ZDO zdo) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (zdo == null) { return 0; } string text = zdo.GetString("EnchantedB64", ""); if (string.IsNullOrEmpty(text)) { if (zdo.IsOwner() && zdo.GetInt("EncCount", 0) != 0) { zdo.Set("EncCount", 0); } return 0; } int num = zdo.GetInt("EncCount", 0); if (num > 0) { return num; } try { byte[] array = Convert.FromBase64String(text); if (array == null || array.Length < 4) { return 0; } int num2 = new ZPackage(array).ReadInt(); if (num2 < 0) { return 0; } if (num2 > 0 && zdo.IsOwner()) { zdo.Set("EncCount", num2); } return num2; } catch { return 0; } } private void InvokeUpdateIcon() { //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) string currentPrefab = CurrentPrefab; int totalCount = TotalCount; int quality = Quality; ZDO zDO = _znv.GetZDO(); if (zDO != null) { zDO.Set("Total", totalCount); } if (ItemDrawers.RarityColorEnabled != null && ItemDrawers.RarityColorEnabled.Value && EnchantedCount > 0 && !string.IsNullOrEmpty(currentPrefab) && ItemValidCheck(currentPrefab)) { List<(string, ItemData)> enchantedItems = GetEnchantedItems(); if (enchantedItems.Count > 0) { ItemData item = enchantedItems[0].Item2; int epicLootRarity = Utils.GetEpicLootRarity(item); ItemDrawers.DLog($"InvokeUpdateIcon: rarity={epicLootRarity} encCount={EnchantedCount} customDataKeys={(item?.m_customData?.Count).GetValueOrDefault()} prefab={currentPrefab}"); if (epicLootRarity > 0) { Color rarityColor = Utils.GetRarityColor(epicLootRarity); Vector3 val = Utils.ColorToVec3(Color32.op_Implicit(rarityColor)); zDO.Set("RarityColor", val); ItemDrawers.DLog($"InvokeUpdateIcon: rarity={epicLootRarity} color=({rarityColor.r},{rarityColor.g},{rarityColor.b}) vec=({val.x},{val.y},{val.z}) applied"); } else { ItemDrawers.DLog("InvokeUpdateIcon: rarity<=0, no color set. customData keys: " + string.Join(",", item?.m_customData?.Keys ?? new Dictionary().Keys)); } } else { ItemDrawers.DLog($"InvokeUpdateIcon: GetEnchantedItems returned {enchantedItems.Count} items, encCount={EnchantedCount}"); } } else if (EnchantedCount <= 0) { zDO.Set("RarityColor", new Vector3(-1f, -1f, -1f)); } if (string.IsNullOrEmpty(currentPrefab) || !ItemValidCheck(currentPrefab)) { _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { "", 0, 0 }); } else { _znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { currentPrefab, totalCount, quality }); } } 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 static void PurgeLegacyEnchantedByteArray(ZDO zdo) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (zdo == null) { return; } try { int stableHashCode = StringExtensionMethods.GetStableHashCode("EnchantedData"); FieldInfo fieldInfo = AccessTools.Field(typeof(ZDOExtraData), "s_byteArrays"); if (fieldInfo == null) { return; } object value = fieldInfo.GetValue(null); if (value == null) { return; } MethodInfo methodInfo = AccessTools.Method(value.GetType(), "TryGetValue", (Type[])null, (Type[])null); if (methodInfo == null) { return; } object[] array = new object[2] { zdo.m_uid, null }; if ((bool)methodInfo.Invoke(value, array)) { object obj = array[1]; if (obj != null) { AccessTools.Method(obj.GetType(), "Remove", new Type[1] { typeof(int) }, (Type[])null)?.Invoke(obj, new object[1] { stableHashCode }); } } } catch (Exception ex) { try { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("PurgeLegacyEnchantedByteArray: " + ex.Message)); } } } catch { } } } private static Sprite GetCircleSprite() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circleSprite != (Object)null) { return _circleSprite; } int num = 32; Texture2D val = new Texture2D(num, num, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; Color32[] array = (Color32[])(object)new Color32[num * num]; float num2 = (float)num / 2f; float num3 = (float)num / 2f - 1f; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num4 = (float)j + 0.5f - num2; float num5 = (float)i + 0.5f - num2; float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5); if (num6 <= num3) { array[i * num + j] = Color32.op_Implicit(Color.white); } else if (num6 <= num3 + 1f) { float num7 = Mathf.Clamp01(num3 + 1f - num6); array[i * num + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num7 * 255f)); } else { array[i * num + j] = new Color32((byte)0, (byte)0, (byte)0, (byte)0); } } } val.SetPixels32(array); val.Apply(); _circleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f); return _circleSprite; } private void CreateRarityCircle(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("RarityCircle"); val.transform.SetParent(parent, false); RectTransform val2 = val.GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent(); } val2.anchorMin = new Vector2(1f, 1f); val2.anchorMax = new Vector2(1f, 1f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(16f, 16f); val2.anchoredPosition = new Vector2(-8f, -8f); _rarityCircle = val.AddComponent(); _rarityCircle.sprite = GetCircleSprite(); ((Graphic)_rarityCircle).color = Color.white; ((Graphic)_rarityCircle).raycastTarget = false; ((Component)_rarityCircle).gameObject.SetActive(false); } 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"); CreateRarityCircle(((Component)_image).transform); ApplyTextEffects(_text); ApplyTextEffects(_starsText); PurgeLegacyEnchantedByteArray(_znv.GetZDO()); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && !_znv.IsOwner()) { _znv.ClaimOwnership(); ItemDrawers.DLog("Awake: claimed ZDO ownership on server for drawer"); } _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); _znv.Register("AddEnchanted_Request", (Action)RPC_AddEnchanted); _znv.Register("AddEnchanted_Player", (Action)RPC_AddEnchanted_Player); _znv.Register("WithdrawEnchanted_Request", (Action)RPC_WithdrawEnchanted_Request); RPC_UpdateIcon(0L, CurrentPrefab, TotalCount, 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) { if (_znv.IsOwner() && amount > 0) { int currentAmount = CurrentAmount; amount = Mathf.Min(amount, CurrentAmount); CurrentAmount -= amount; ItemDrawers.DLog($"ForceRemove: {CurrentPrefab} -{amount} ({currentAmount}->{CurrentAmount}) enc={EnchantedCount} sender={sender}"); if (CurrentAmount <= 0 && EnchantedCount <= 0) { CurrentPrefab = ""; CurrentAmount = 0; Quality = 1; } InvokeUpdateIcon(); } } private void RPC_WithdrawItem_Request(long sender, int amount) { if (CurrentAmount <= 0 || !ItemValid) { if (EnchantedCount <= 0) { CurrentPrefab = ""; CurrentAmount = 0; Quality = 1; } InvokeUpdateIcon(); } else if (amount > 0) { amount = Mathf.Min(amount, CurrentAmount); CurrentAmount -= amount; _znv.InvokeRPC(sender, "AddItem_Player", new object[3] { CurrentPrefab, amount, Quality }); InvokeUpdateIcon(); } } 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_014e: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) int num = amount; if (string.IsNullOrEmpty(prefab) || !ItemValidCheck(prefab)) { _image.sprite = _defaultSprite; ((Component)_stars).gameObject.SetActive(false); ((Component)_text).gameObject.SetActive(false); if ((Object)(object)_text != (Object)null) { _text.text = ""; } if ((Object)(object)_rarityCircle != (Object)null) { ((Component)_rarityCircle).gameObject.SetActive(false); } return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if ((Object)(object)itemPrefab == (Object)null) { ((Component)_text).gameObject.SetActive(false); return; } _image.sprite = itemPrefab.GetComponent().m_itemData.GetIcon(); _text.text = ((num > 0) ? num.ToString() : "0"); _text.ForceMeshUpdate(false, false); ((Component)_text).gameObject.SetActive(true); ((Component)_stars).gameObject.SetActive(quality > 1); if (quality > 1) { _starsText.text = quality.ToString(); _starIcon.localPosition = new Vector3((quality >= 10) ? 9f : 0f, 5.25f, 0f); } if (ItemDrawers.RarityColorEnabled != null && ItemDrawers.RarityColorEnabled.Value && (Object)(object)_rarityCircle != (Object)null) { ZNetView znv = _znv; ZDO val = ((znv != null) ? znv.GetZDO() : null); if (val != null) { Vector3 vec = val.GetVec3("RarityColor", new Vector3(-1f, -1f, -1f)); if (vec.x >= 0f && vec.y >= 0f && vec.z >= 0f) { Color32 val2 = Utils.Vec3ToColor(vec); ((Graphic)_rarityCircle).color = Color32.op_Implicit(val2); ((Component)_rarityCircle).gameObject.SetActive(true); object[] obj = new object[11] { vec.x, vec.y, vec.z, val2.r, val2.g, val2.b, val2.a, ((Component)_rarityCircle).gameObject.activeSelf, null, null, null }; Transform parent = ((Component)_rarityCircle).transform.parent; obj[8] = ((parent != null) ? ((Object)parent).name : null); RectTransform rectTransform = ((Graphic)_rarityCircle).rectTransform; float num2; Rect rect; if (rectTransform == null) { num2 = 0f; } else { rect = rectTransform.rect; num2 = ((Rect)(ref rect)).width; } obj[9] = num2; RectTransform rectTransform2 = ((Graphic)_rarityCircle).rectTransform; float num3; if (rectTransform2 == null) { num3 = 0f; } else { rect = rectTransform2.rect; num3 = ((Rect)(ref rect)).height; } obj[10] = num3; ItemDrawers.DLog(string.Format("RPC_UpdateIcon: SHOW circle RarityColor=({0},{1},{2}) color32=({3},{4},{5},{6}) active={7} parent={8} size={9}x{10}", obj)); } else { ((Component)_rarityCircle).gameObject.SetActive(false); ItemDrawers.DLog($"RPC_UpdateIcon: HIDE circle RarityColor=({vec.x},{vec.y},{vec.z}) (no rarity)"); } } } else if ((Object)(object)_rarityCircle != (Object)null) { ((Component)_rarityCircle).gameObject.SetActive(false); } if ((Object)(object)_text != (Object)null) { ((Graphic)_text).color = CurrentColor; } } private void RPC_AddItem(long sender, string prefab, int amount, int quality) { if (!_znv.IsOwner()) { ItemDrawers.DLog($"AddItem ignore: not owner prefab={prefab} x{amount}"); return; } if (amount <= 0 || string.IsNullOrEmpty(prefab)) { ItemDrawers.DLog($"AddItem REJECT: amount={amount} prefab={prefab}"); return; } quality = Math.Max(1, quality); if (TotalCount <= 0 && !string.IsNullOrEmpty(CurrentPrefab) && CurrentPrefab != prefab) { CurrentPrefab = ""; CurrentAmount = 0; Quality = 1; SetEnchantedItems(null); } string currentPrefab = CurrentPrefab; if (!string.IsNullOrEmpty(currentPrefab) && TotalCount > 0 && (currentPrefab != prefab || Quality != quality)) { ItemDrawers.DLog($"AddItem REJECT mismatch: have={currentPrefab} q{Quality} got={prefab} q{quality} x{amount} — returning"); _znv.InvokeRPC(sender, "AddItem_Player", new object[3] { prefab, amount, quality }); } else { CurrentAmount = ((TotalCount > 0 || CurrentAmount > 0) ? (CurrentAmount + amount) : amount); CurrentPrefab = prefab; Quality = quality; ItemDrawers.DLog($"AddItem OK: {prefab} +{amount} q{quality} => Amount={CurrentAmount} Total={TotalCount}"); InvokeUpdateIcon(); } } private void RPC_AddEnchanted(long sender, string prefab, int quality, string itemDataBase64) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) ItemDrawers.DLog($"RPC_AddEnchanted ENTRY: sender={sender} prefab={prefab} q{quality} b64len={itemDataBase64?.Length ?? 0}"); if (!_znv.IsOwner() || string.IsNullOrEmpty(itemDataBase64)) { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)$"RPC_AddEnchanted: rejected (owner={_znv.IsOwner()}, empty={string.IsNullOrEmpty(itemDataBase64)})"); } } return; } quality = Math.Max(1, quality); byte[] array = null; try { array = Convert.FromBase64String(itemDataBase64); } catch (Exception ex) { ItemDrawers instance2 = ItemDrawers.Instance; if (instance2 != null) { ManualLogSource log2 = instance2.Log; if (log2 != null) { log2.LogWarning((object)("RPC_AddEnchanted: base64 decode failed: " + ex.Message)); } } return; } if (array == null || array.Length == 0) { ItemDrawers instance3 = ItemDrawers.Instance; if (instance3 != null) { ManualLogSource log3 = instance3.Log; if (log3 != null) { log3.LogWarning((object)$"RPC_AddEnchanted: decoded bytes empty (len={((array != null) ? array.Length : 0)})"); } } return; } ItemDrawers.DLog($"RPC_AddEnchanted: decoded {array.Length} bytes"); string currentPrefab = CurrentPrefab; if (ItemValid && !string.IsNullOrEmpty(currentPrefab) && currentPrefab != prefab) { if (CurrentAmount > 0) { Utils.InstantiateAtPos(ZNetScene.instance.GetPrefab(currentPrefab), CurrentAmount, Quality, ((Component)this).transform.position + Vector3.up * 1.5f); CurrentAmount = 0; } List<(string, ItemData)> enchantedItems = GetEnchantedItems(); if (enchantedItems.Count > 0) { foreach (var item3 in enchantedItems) { string item = item3.Item1; ItemData item2 = item3.Item2; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item); if ((Object)(object)itemPrefab != (Object)null) { Utils.DropEnchantedItem(itemPrefab, item2, ((Component)this).transform.position + Vector3.up * 1.5f); } } SetEnchantedItems(new List<(string, ItemData)>()); } } CurrentPrefab = prefab; Quality = quality; GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(prefab); if ((Object)(object)itemPrefab2 == (Object)null) { ItemDrawers instance4 = ItemDrawers.Instance; if (instance4 != null) { ManualLogSource log4 = instance4.Log; if (log4 != null) { log4.LogWarning((object)("RPC_AddEnchanted: prefab '" + prefab + "' not found in ObjectDB!")); } } return; } ItemData val = Utils.DeserializeItemData(array, itemPrefab2); if (val == null) { ItemDrawers instance5 = ItemDrawers.Instance; if (instance5 != null) { ManualLogSource log5 = instance5.Log; if (log5 != null) { log5.LogWarning((object)("RPC_AddEnchanted: DeserializeItemData returned null for prefab '" + prefab + "'!")); } } return; } ItemDrawers.DLog($"RPC_AddEnchanted: deserialized OK, customData keys={val.m_customData?.Count ?? 0}"); List<(string, ItemData)> enchantedItems2 = GetEnchantedItems(); if (ItemDrawers.StackOnlySameEnchantment != null && ItemDrawers.StackOnlySameEnchantment.Value && enchantedItems2.Count > 0 && !Utils.CustomDataEquals(enchantedItems2[0].Item2?.m_customData, val.m_customData)) { ItemDrawers instance6 = ItemDrawers.Instance; if (instance6 != null) { ManualLogSource log6 = instance6.Log; if (log6 != null) { log6.LogInfo((object)("RPC_AddEnchanted REJECT: enchantment mismatch (drawer has different enchantment for " + prefab + ")")); } } byte[] array2 = Utils.SerializeItemData(val); if (array2 != null && array2.Length != 0) { string text = Convert.ToBase64String(array2); _znv.InvokeRPC(sender, "AddEnchanted_Player", new object[1] { text }); } } else { enchantedItems2.Add((prefab, val)); SetEnchantedItems(enchantedItems2); ItemDrawers.DLog($"AddEnchanted OK: {prefab} q{quality} enc={enchantedItems2.Count} EncCount={EnchantedCount} EnchantedB64={EnchantedData.Length} chars customDataKeys={val.m_customData?.Count ?? 0}"); InvokeUpdateIcon(); } } private void RPC_AddEnchanted_Player(long _, string itemDataBase64) { ItemDrawers.DLog($"RPC_AddEnchanted_Player ENTRY: b64len={itemDataBase64?.Length ?? 0}"); if (string.IsNullOrEmpty(itemDataBase64)) { return; } byte[] array = null; try { array = Convert.FromBase64String(itemDataBase64); } catch (Exception ex) { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("RPC_AddEnchanted_Player: base64 decode failed: " + ex.Message)); } } return; } if (array == null || array.Length == 0) { return; } string currentPrefab = CurrentPrefab; if (string.IsNullOrEmpty(currentPrefab)) { ItemDrawers instance2 = ItemDrawers.Instance; if (instance2 != null) { ManualLogSource log2 = instance2.Log; if (log2 != null) { log2.LogWarning((object)"RPC_AddEnchanted_Player: CurrentPrefab is empty!"); } } return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(currentPrefab); if ((Object)(object)itemPrefab == (Object)null) { ItemDrawers instance3 = ItemDrawers.Instance; if (instance3 != null) { ManualLogSource log3 = instance3.Log; if (log3 != null) { log3.LogWarning((object)("RPC_AddEnchanted_Player: prefab '" + currentPrefab + "' not found!")); } } return; } ItemData val = Utils.DeserializeItemData(array, itemPrefab); if (val == null) { ItemDrawers instance4 = ItemDrawers.Instance; if (instance4 != null) { ManualLogSource log4 = instance4.Log; if (log4 != null) { log4.LogWarning((object)"RPC_AddEnchanted_Player: DeserializeItemData returned null!"); } } } else { ItemDrawers.DLog($"RPC_AddEnchanted_Player: deserialized OK, customData keys={val.m_customData?.Count ?? 0}"); Utils.InstantiateEnchantedItem(itemPrefab, val); } } private void RPC_WithdrawEnchanted_Request(long sender, int amount) { List<(string, ItemData)> enchantedItems = GetEnchantedItems(); ItemDrawers.DLog($"RPC_WithdrawEnchanted_Request: sender={sender} amount={amount} listCount={enchantedItems.Count}"); int num = Math.Min(amount, enchantedItems.Count); if (num <= 0) { if (CurrentAmount <= 0) { CurrentPrefab = ""; CurrentAmount = 0; Quality = 1; } InvokeUpdateIcon(); return; } for (int i = 0; i < num; i++) { var (text, val) = enchantedItems[enchantedItems.Count - 1]; enchantedItems.RemoveAt(enchantedItems.Count - 1); byte[] array = Utils.SerializeItemData(val); if (array == null || array.Length == 0) { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("RPC_WithdrawEnchanted: SerializeItemData failed for " + text + "!")); } } } else { string text2 = Convert.ToBase64String(array); ItemDrawers.DLog($"RPC_WithdrawEnchanted: sending {text} bytes={array.Length} b64={text2.Length} customDataKeys={val.m_customData?.Count ?? 0}"); _znv.InvokeRPC(sender, "AddEnchanted_Player", new object[1] { text2 }); } } SetEnchantedItems(enchantedItems); ItemDrawers.DLog($"RPC_WithdrawEnchanted: done, remaining enc={enchantedItems.Count}"); if (enchantedItems.Count == 0 && CurrentAmount <= 0) { CurrentPrefab = ""; Quality = 1; } InvokeUpdateIcon(); } 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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)) { string name = ((Object)item.m_itemData.m_dropPrefab).name; if (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()) { continue; } if (!component.IsOwner()) { item.RequestOwn(); continue; } if (Utils.HasCustomData(item.m_itemData)) { List<(string, ItemData)> enchantedItems = GetEnchantedItems(); if (ItemDrawers.StackOnlySameEnchantment != null && ItemDrawers.StackOnlySameEnchantment.Value && enchantedItems.Count > 0 && !Utils.CustomDataEquals(enchantedItems[0].Item2?.m_customData, item.m_itemData.m_customData)) { ItemDrawers.DLog("Repeat: SKIP auto-pickup — enchantment mismatch for " + name); continue; } enchantedItems.Add((name, item.m_itemData)); SetEnchantedItems(enchantedItems); } else { CurrentAmount += stack; } ZNetScene.instance.Destroy(((Component)item).gameObject); InvokeUpdateIcon(); } } 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)) { if (EnchantedCount > 0) { _znv.InvokeRPC("WithdrawEnchanted_Request", new object[1] { 1 }); } else { _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; } if (EnchantedCount > 0) { _znv.InvokeRPC("WithdrawEnchanted_Request", new object[1] { 1 }); } else { _znv.InvokeRPC("WithdrawItem_Request", new object[1] { ItemMaxStack }); } return true; } public bool UseItem(Humanoid user, ItemData item) { string prefabName = Utils.GetPrefabName(item); if (string.IsNullOrEmpty(prefabName)) { ItemDrawers.DLog("UseItem REJECT: cannot resolve prefab (dropPrefab=" + (((Object)(object)item?.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : "null") + " shared=" + item?.m_shared?.m_name + ")"); if (user != null) { ((Character)user).Message((MessageType)2, ModLocalization.MsgUnknownItem.Localize(), 0, (Sprite)null); } return false; } if (ItemDrawers.ExcludeSet.Contains(prefabName) && !Player.m_debugMode) { ItemDrawers.DLog("UseItem REJECT: excluded " + prefabName); if (user != null) { ((Character)user).Message((MessageType)2, string.Format(ModLocalization.MsgExcluded.Localize(), prefabName), 0, (Sprite)null); } return false; } bool flag = TotalCount <= 0; if (!string.IsNullOrEmpty(CurrentPrefab) && !flag && (CurrentPrefab != prefabName || Quality != item.m_quality)) { ItemDrawers.DLog($"UseItem REJECT: drawer has {CurrentPrefab} q{Quality}, item is {prefabName} q{item.m_quality}"); if (user != null) { ((Character)user).Message((MessageType)2, string.Format(ModLocalization.MsgHasPrefab.Localize(), CurrentPrefab), 0, (Sprite)null); } return false; } int stack = item.m_stack; if (stack <= 0) { ItemDrawers.DLog("UseItem REJECT: stack<=0"); return false; } if (Utils.HasCustomData(item)) { if (ItemDrawers.StackOnlySameEnchantment != null && ItemDrawers.StackOnlySameEnchantment.Value && EnchantedCount > 0) { List<(string, ItemData)> enchantedItems = GetEnchantedItems(); if (enchantedItems.Count > 0 && !Utils.CustomDataEquals(enchantedItems[0].Item2?.m_customData, item.m_customData)) { ItemDrawers.DLog("UseItem REJECT: enchantment mismatch (drawer has different enchantment for " + prefabName + ")"); if (user != null) { ((Character)user).Message((MessageType)2, ModLocalization.MsgDiffEnchant.Localize(), 0, (Sprite)null); } return false; } } byte[] array = Utils.SerializeItemData(item); if (array == null || array.Length == 0) { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)"UseItem: SerializeItemData failed — item not removed."); } } return false; } string text = Convert.ToBase64String(array); ItemDrawers.DLog($"UseItem ENCHANTED: {prefabName} q{item.m_quality} keys={item.m_customData.Count} bytes={array.Length} b64={text.Length}"); user.GetInventory().RemoveItem(item); _znv.InvokeRPC("AddEnchanted_Request", new object[3] { prefabName, item.m_quality, text }); return true; } ItemDrawers.DLog($"UseItem VANILLA: {prefabName} x{stack} q{item.m_quality} → AddItem_Request (drawerAmount={CurrentAmount})"); user.GetInventory().RemoveItem(item); _znv.InvokeRPC("AddItem_Request", new object[3] { prefabName, stack, Math.Max(1, item.m_quality) }); return true; } public string GetHoverText() { StringBuilder stringBuilder = new StringBuilder(); if (((Character)Player.m_localPlayer).IsCrouching()) { stringBuilder.AppendLine("[$KEY_Use] " + ModLocalization.HoverOpenSettings.Localize()); return stringBuilder.ToString().Localize(); } if (!ItemValid) { stringBuilder.AppendLine("" + ModLocalization.HoverUseHotbar.Localize() + ""); return stringBuilder.ToString().Localize(); } int quality = Quality; string text = ((quality > 1) ? (" (" + string.Format(ModLocalization.HoverQuality.Localize(), quality) + ")") : ""); int totalCount = TotalCount; stringBuilder.AppendLine($"{LocalizedName}{text} ({totalCount})"); stringBuilder.AppendLine("" + ModLocalization.HoverUseHotbar.Localize() + "\n"); if (totalCount <= 0) { stringBuilder.AppendLine("[$KEY_Use] " + ModLocalization.HoverClear.Localize()); stringBuilder.AppendLine($"[Left Shift + $KEY_Use] {ModLocalization.HoverDepositAll.Localize()} {LocalizedName} ({Utils.CustomCountItems(CurrentPrefab, quality)})"); return stringBuilder.ToString().Localize(); } stringBuilder.AppendLine($"[$KEY_Use] {ModLocalization.HoverWithdrawStack.Localize()} ({ItemMaxStack})"); stringBuilder.AppendLine("[Left Alt + $KEY_Use] " + ModLocalization.HoverWithdrawSingle.Localize()); stringBuilder.AppendLine($"[Left Shift + $KEY_Use] {ModLocalization.HoverDepositAll.Localize()} {LocalizedName}{text} ({Utils.CustomCountItems(CurrentPrefab, quality)})"); return stringBuilder.ToString().Localize(); } public string GetHoverName() { return ModLocalization.HoverName.Localize(); } 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_008e: Expected O, but got Unknown //IL_0089: 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, ModLocalization.GuiTitle.Localize()); } 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_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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($"{ModLocalization.GuiCurrentDrawer.Localize()} {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($"{ModLocalization.GuiTextColor.Localize()} 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(ModLocalization.GuiPickupRange.Localize() + " {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("" + ModLocalization.GuiApply.Localize() + "", Array.Empty())) { CurrentOptions.drawer._znv.InvokeRPC(ZNetView.Everybody, "ApplyOptions", new object[1] { CurrentOptions }); ShowUI = false; } } } public static class EpicLootDisplayNamePatch { private static bool _initialized; private static bool _enabled; private static MethodInfo _tryGetLegendaryInfo; private static MethodInfo _getMagicItemMethod; private static FieldInfo _magicItemDisplayNameField; private static FieldInfo _magicItemLegendaryIDField; public static bool IsEnabled => _enabled; public static void Init(Harmony harmonyInstance = null) { //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; try { Assembly assembly = Array.Find(AppDomain.CurrentDomain.GetAssemblies(), (Assembly a) => a.GetName().Name == "EpicLoot"); if (assembly == null) { ItemDrawers.DLog("EpicLootDisplayNamePatch: EpicLoot not found, patch disabled"); return; } Type type = assembly.GetType("EpicLoot.LegendarySystem.UniqueLegendaryHelper") ?? assembly.GetType("EpicLoot.UniqueLegendaryHelper"); Type type2 = assembly.GetType("EpicLoot.ItemDataExtensions"); Type type3 = assembly.GetType("EpicLoot.MagicItem"); if (type == null || type2 == null || type3 == null) { ItemDrawers.DLog("EpicLootDisplayNamePatch: required types not found"); return; } _tryGetLegendaryInfo = type.GetMethod("TryGetLegendaryInfo", BindingFlags.Static | BindingFlags.Public); _getMagicItemMethod = type2.GetMethod("GetMagicItem", new Type[1] { typeof(ItemData) }); _magicItemDisplayNameField = type3.GetField("DisplayName", BindingFlags.Instance | BindingFlags.Public); _magicItemLegendaryIDField = type3.GetField("LegendaryID", BindingFlags.Instance | BindingFlags.Public); if (_tryGetLegendaryInfo == null || _getMagicItemMethod == null || _magicItemDisplayNameField == null || _magicItemLegendaryIDField == null) { ItemDrawers.DLog("EpicLootDisplayNamePatch: required members not found"); return; } MethodInfo method = type2.GetMethod("GetDisplayName", new Type[1] { typeof(ItemData) }); if (method == null) { ItemDrawers.DLog("EpicLootDisplayNamePatch: GetDisplayName method not found"); return; } MethodInfo method2 = typeof(EpicLootDisplayNamePatch).GetMethod("PostfixDisplayName", BindingFlags.Static | BindingFlags.NonPublic); Harmony val = (Harmony)(((object)harmonyInstance) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if (val == null) { ItemDrawers.DLog("EpicLootDisplayNamePatch: harmony instance not available"); return; } val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _enabled = true; ItemDrawers.DLog("EpicLootDisplayNamePatch: patch applied successfully"); } catch (Exception arg) { ItemDrawers.DLog($"EpicLootDisplayNamePatch init failed: {arg}"); } } private static void PostfixDisplayName(ref string __result, ItemData itemData) { if (!_enabled || itemData == null) { return; } try { object obj = _getMagicItemMethod.Invoke(null, new object[1] { itemData }); if (obj == null) { return; } string text = (string)_magicItemLegendaryIDField.GetValue(obj); if (string.IsNullOrEmpty(text)) { return; } object[] array = new object[2] { text, null }; if (!(bool)_tryGetLegendaryInfo.Invoke(null, array)) { return; } object obj2 = array[1]; if (obj2 == null) { return; } FieldInfo field = obj2.GetType().GetField("Name", BindingFlags.Instance | BindingFlags.Public); if (field == null) { return; } string text2 = (string)field.GetValue(obj2); if (string.IsNullOrEmpty(text2)) { return; } string text3 = (string)_magicItemDisplayNameField.GetValue(obj); if (text2 == text3) { return; } string text4 = ""; if (!string.IsNullOrEmpty(text3) && !string.IsNullOrEmpty(__result)) { int num = __result.IndexOf(text3, StringComparison.Ordinal); if (num >= 0) { text4 = __result.Substring(num + text3.Length); } } ItemDrawers.DLog("EpicLootDisplayNamePatch: replacing '" + text3 + "' with '" + text2 + "' for LegendaryID=" + text); __result = text2 + text4; } catch (Exception ex) { ItemDrawers.DLog("EpicLootDisplayNamePatch postfix failed: " + ex.Message); } } } [BepInPlugin("kg.ItemDrawers", "Cybrp ItemDrawers", "1.2.6")] public class ItemDrawers : BaseUnityPlugin { private const string TiffanyAnsi = "\u001b[38;2;10;186;181m"; private const string AnsiReset = "\u001b[0m"; private const int StdOutputHandle = -11; private const uint EnableVirtualTerminalProcessing = 4u; public static readonly byte[] BuildStampBytes = new byte[16] { 66, 82, 79, 72, 69, 73, 77, 95, 73, 68, 95, 49, 95, 48, 95, 51 }; 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 ConfigEntry CfgDepositLogs; 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 ConfigEntry StackOnlySameEnchantment; public static ConfigEntry RarityColorEnabled; 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) }; private static bool _epicLootPatchApplied; public static string BuildStamp => Encoding.ASCII.GetString(BuildStampBytes); internal ManualLogSource Log => ((BaseUnityPlugin)this).Logger; internal static IReadOnlyList AllDrawerPrefabNames => DrawerPrefabNames; internal static IReadOnlyList<(string name, string item, int amount)> AllDrawerRecipes => DrawerRecipes; [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); private static void TryEnableVirtualTerminal() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) try { if (((object)Application.platform/*cast due to .constrained prefix*/).ToString().Contains("Windows")) { IntPtr stdHandle = GetStdHandle(-11); if (!(stdHandle == IntPtr.Zero) && !(stdHandle == new IntPtr(-1)) && GetConsoleMode(stdHandle, out var lpMode) && (lpMode & 4) == 0) { SetConsoleMode(stdHandle, lpMode | 4); } } } catch { } } private static TextWriter GetBepInExConsoleStream() { try { Type type = AccessTools.TypeByName("BepInEx.ConsoleManager"); if (type == null) { return null; } return AccessTools.Property(type, "ConsoleStream")?.GetValue(null) as TextWriter; } catch { return null; } } private static void SetBepInExConsoleColor(ConsoleColor color) { try { AccessTools.Method(AccessTools.TypeByName("BepInEx.ConsoleManager"), "SetConsoleColor", new Type[1] { typeof(ConsoleColor) }, (Type[])null)?.Invoke(null, new object[1] { color }); } catch { } } private static void PrintLoadBanner() { string[] array = new string[3] { "█▀▀\u2003█▄█\u2003█▄▄\u2003█▀█\u2003█▀█\u2003 \u2003▄▄\u2003 \u2003█\u2003▀█▀\u2003█▀▀\u2003█▀▄▀█\u2003█▀▄\u2003█▀█\u2003▄▀█\u2003█░█░█\u2003█▀▀\u2003█▀█\u2003█▀", "█▄▄\u2003░█░\u2003█▄█\u2003█▀▄\u2003█▀▀\u2003 \u2003░░\u2003 \u2003█\u2003░█░\u2003██▄\u2003█░▀░█\u2003█▄▀\u2003█▀▄\u2003█▀█\u2003▀▄▀▄▀\u2003██▄\u2003█▀▄\u2003▄█", " Cybrp ItemDrawers v1.2.6" }; try { TryEnableVirtualTerminal(); TextWriter bepInExConsoleStream = GetBepInExConsoleStream(); string[] array2; if (bepInExConsoleStream != null) { bepInExConsoleStream.WriteLine(); array2 = array; foreach (string text in array2) { bepInExConsoleStream.WriteLine("\u001b[38;2;10;186;181m" + text + "\u001b[0m"); } bepInExConsoleStream.WriteLine(); bepInExConsoleStream.Flush(); return; } SetBepInExConsoleColor(ConsoleColor.Cyan); Console.Out.WriteLine(); array2 = array; foreach (string value in array2) { Console.Out.WriteLine(value); } Console.Out.WriteLine(); SetBepInExConsoleColor(ConsoleColor.Gray); } catch { } } internal static void DLog(string msg) { if (CfgDepositLogs == null || !CfgDepositLogs.Value) { return; } ItemDrawers instance = Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogInfo((object)msg); } } } private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Expected O, but got Unknown Instance = this; PrintLoadBanner(); 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())); StackOnlySameEnchantment = ((BaseUnityPlugin)this).Config.Bind("Enchanted", "StackOnlySameEnchantment", true, "When true, enchanted/modded items only stack in a drawer if their m_customData (enchantments, effects) are identical. When false, all enchanted items of the same prefab+quality stack together."); RarityColorEnabled = ((BaseUnityPlugin)this).Config.Bind("Enchanted", "RarityColorEnabled", true, "When true, the drawer text color changes based on EpicLoot rarity (Magic=blue, Rare=yellow, Epic=purple, Legendary=teal, Mythic=orange). Overrides the default text color for enchanted drawers."); _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 (only from matching non-empty drawers)."); 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 (NOT into empty drawers)."); 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."); CfgDepositLogs = ((BaseUnityPlugin)this).Config.Bind("Debug", "DepositLogs", true, "Log UseItem / AddItem / ForceRemove / AddEnchanted with reasons."); ModLocalization.Init(); Harmony val = new Harmony("kg.ItemDrawers"); _harmony = val; val.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Cybrp ItemDrawers {BuildStamp} (v1.2.6) loaded. stamp[0]={BuildStampBytes[0]} FeedFromDrawers={StationAuto.CfgFeed.Value}"); AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoaded; TryInitQuickStackBridge(); TryInitEpicLootPatch(); AppDomain.CurrentDomain.AssemblyLoad += OnEpicLootLoaded; } 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 static void TryInitEpicLootPatch() { if (!_epicLootPatchApplied && !(Array.Find(AppDomain.CurrentDomain.GetAssemblies(), (Assembly a) => a.GetName().Name == "EpicLoot") == null)) { EpicLootDisplayNamePatch.Init(_harmony); _epicLootPatchApplied = EpicLootDisplayNamePatch.IsEnabled; if (_epicLootPatchApplied) { Instance.Log.LogInfo((object)"EpicLootDisplayNamePatch applied (deferred)."); } } } private static void OnEpicLootLoaded(object sender, AssemblyLoadEventArgs args) { if (!(args.LoadedAssembly.GetName().Name != "EpicLoot")) { TryInitEpicLootPatch(); AppDomain.CurrentDomain.AssemblyLoad -= OnEpicLootLoaded; } } private void OnGUI() { DrawerComponent.ProcessGUI(); } private void Update() { DrawerComponent.ProcessInput(); ModLocalization.TryDeferredRegister(); } 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 ModLocalization { private static readonly Dictionary> _translations = new Dictionary>(); private static string _currentLanguage = "English"; public static readonly string HoverName = "$broheim_id_hover_name"; public static readonly string MsgUnknownItem = "$broheim_id_msg_unknown"; public static readonly string MsgExcluded = "$broheim_id_msg_excluded"; public static readonly string MsgHasPrefab = "$broheim_id_msg_has_prefab"; public static readonly string MsgDiffEnchant = "$broheim_id_msg_diff_enchant"; public static readonly string HoverOpenSettings = "$broheim_id_hover_open_settings"; public static readonly string HoverUseHotbar = "$broheim_id_hover_use_hotbar"; public static readonly string HoverQuality = "$broheim_id_hover_quality"; public static readonly string HoverClear = "$broheim_id_hover_clear"; public static readonly string HoverDepositAll = "$broheim_id_hover_deposit_all"; public static readonly string HoverWithdrawStack = "$broheim_id_hover_withdraw_stack"; public static readonly string HoverWithdrawSingle = "$broheim_id_hover_withdraw_single"; public static readonly string GuiTitle = "$broheim_id_gui_title"; public static readonly string GuiCurrentDrawer = "$broheim_id_gui_current_drawer"; public static readonly string GuiTextColor = "$broheim_id_gui_text_color"; public static readonly string GuiPickupRange = "$broheim_id_gui_pickup_range"; public static readonly string GuiApply = "$broheim_id_gui_apply"; private static int _initAttempts = 0; private static string _overrideLanguage = null; private static readonly FieldInfo F_m_translations = typeof(Localization).GetField("m_translations", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo M_AddWord = typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(string) }, null); private static readonly MethodInfo M_GetSelectedLanguage = typeof(Localization).GetMethod("GetSelectedLanguage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); private static readonly FieldInfo F_m_language = typeof(Localization).GetField("m_language", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static bool _loggedLanguageSource; public static void Init() { LoadEmbedded(); RegisterCurrent(); } public static void OnLanguageChanged(string lang = null) { if (!string.IsNullOrEmpty(lang)) { _overrideLanguage = lang; } RegisterCurrent(); } public static void TryDeferredRegister() { if (_initAttempts < 5) { _initAttempts++; RegisterCurrent(); } } private static void LoadEmbedded() { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (!text.StartsWith("kg_ItemDrawers.Translations.")) { continue; } string text2 = text.Substring("kg_ItemDrawers.Translations.".Length); if (text2.EndsWith(".json")) { text2 = text2.Substring(0, text2.Length - 5); } try { using Stream stream = executingAssembly.GetManifestResourceStream(text); using StreamReader streamReader = new StreamReader(stream); Dictionary dictionary = ParseSimpleJson(streamReader.ReadToEnd()); _translations[text2] = dictionary; ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogInfo((object)$"ModLocalization: loaded {dictionary.Count} tokens for '{text2}'"); } } } catch (Exception ex) { ItemDrawers instance2 = ItemDrawers.Instance; if (instance2 != null) { ManualLogSource log2 = instance2.Log; if (log2 != null) { log2.LogWarning((object)("ModLocalization: failed to load '" + text + "': " + ex.Message)); } } } } if (_translations.ContainsKey("English")) { return; } ItemDrawers instance3 = ItemDrawers.Instance; if (instance3 != null) { ManualLogSource log3 = instance3.Log; if (log3 != null) { log3.LogWarning((object)"ModLocalization: English.json not found — using empty fallback"); } } _translations["English"] = new Dictionary(); } private static void RegisterCurrent() { _currentLanguage = GetCurrentLanguage(); Dictionary forLanguage = GetForLanguage(_currentLanguage); if (Localization.instance == null) { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)"ModLocalization: Localization.instance is null — deferring registration"); } } return; } int num = 0; if (M_AddWord != null) { foreach (KeyValuePair item in forLanguage) { try { string text = (item.Key.StartsWith("$") ? item.Key.Substring(1) : item.Key); M_AddWord.Invoke(Localization.instance, new object[2] { text, item.Value }); num++; } catch { } } } if (num == 0 && F_m_translations != null) { Dictionary dictionary = (Dictionary)F_m_translations.GetValue(Localization.instance); if (dictionary != null) { foreach (KeyValuePair item2 in forLanguage) { string key = (item2.Key.StartsWith("$") ? item2.Key.Substring(1) : item2.Key); dictionary[key] = item2.Value; num++; } } else { ItemDrawers instance2 = ItemDrawers.Instance; if (instance2 != null) { ManualLogSource log2 = instance2.Log; if (log2 != null) { log2.LogWarning((object)"ModLocalization: m_translations dictionary is null"); } } } } if (num == 0) { FieldInfo[] fields = typeof(Localization).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string arg = string.Join(", ", fields.Select((FieldInfo f) => f.Name + ":" + f.FieldType.Name)); ItemDrawers instance3 = ItemDrawers.Instance; if (instance3 != null) { ManualLogSource log3 = instance3.Log; if (log3 != null) { log3.LogWarning((object)$"ModLocalization: FAILED to register tokens. AddWord={M_AddWord != null}, m_translations={F_m_translations != null}. Fields: {arg}"); } } return; } ItemDrawers instance4 = ItemDrawers.Instance; if (instance4 != null) { ManualLogSource log4 = instance4.Log; if (log4 != null) { log4.LogInfo((object)string.Format("ModLocalization: registered {0} tokens for language '{1}' (method: {2})", num, _currentLanguage, (M_AddWord != null) ? "AddWord" : "reflection")); } } } private static string GetCurrentLanguage() { if (!string.IsNullOrEmpty(_overrideLanguage)) { return _overrideLanguage; } try { Localization instance = Localization.instance; if (instance == null) { return "English"; } if (M_GetSelectedLanguage != null) { string text = M_GetSelectedLanguage.Invoke(instance, null) as string; if (!string.IsNullOrEmpty(text)) { LogLanguageSourceOnce("GetSelectedLanguage", text); return text; } } if (F_m_language != null) { string text2 = F_m_language.GetValue(instance) as string; if (!string.IsNullOrEmpty(text2)) { LogLanguageSourceOnce("m_language", text2); return text2; } } } catch (Exception ex) { ItemDrawers instance2 = ItemDrawers.Instance; if (instance2 != null) { ManualLogSource log = instance2.Log; if (log != null) { log.LogWarning((object)("ModLocalization: GetCurrentLanguage failed: " + ex.Message)); } } } return "English"; } private static void LogLanguageSourceOnce(string source, string lang) { if (_loggedLanguageSource) { return; } _loggedLanguageSource = true; ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogInfo((object)("ModLocalization: language from " + source + " = '" + lang + "'")); } } } private static Dictionary GetForLanguage(string lang) { if (_translations.TryGetValue(lang, out var value) && value.Count > 0) { return value; } if (_translations.TryGetValue("English", out var value2) && value2.Count > 0) { return value2; } return new Dictionary(); } private static Dictionary ParseSimpleJson(string json) { Dictionary dictionary = new Dictionary(); if (string.IsNullOrEmpty(json)) { return dictionary; } json = json.Trim(); if (json.StartsWith("{")) { json = json.Substring(1); } if (json.EndsWith("}")) { json = json.Substring(0, json.Length - 1); } int i = 0; while (i < json.Length) { for (; i < json.Length && (json[i] == ' ' || json[i] == ',' || json[i] == '\n' || json[i] == '\r' || json[i] == '\t'); i++) { } if (i >= json.Length || json[i] != '"') { break; } string key = ReadString(json, ref i); for (; i < json.Length && json[i] != ':'; i++) { } for (i++; i < json.Length && (json[i] == ' ' || json[i] == '\n' || json[i] == '\r' || json[i] == '\t'); i++) { } if (i < json.Length && json[i] == '"') { string value = ReadString(json, ref i); dictionary[key] = value; } } return dictionary; } private static string ReadString(string json, ref int i) { i++; StringBuilder stringBuilder = new StringBuilder(); while (i < json.Length) { char c = json[i]; if (c == '\\' && i + 1 < json.Length) { char c2 = json[i + 1]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case '/': stringBuilder.Append('/'); break; default: stringBuilder.Append(c2); break; } i += 2; } else { if (c == '"') { i++; break; } stringBuilder.Append(c); i++; } } return stringBuilder.ToString(); } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] internal static class LocalizationLanguageChangePatch { [HarmonyPostfix] internal static void Postfix(string language) { try { ModLocalization.OnLanguageChanged(language); } catch { } } } 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, "Cybrp_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)$"Cybrp 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)"Cybrp 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_00aa: 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) { return; } Vector3 pos = ((Component)__instance).transform.position + Vector3.up; if (component.CurrentAmount > 0) { Utils.InstantiateAtPos(ZNetScene.instance.GetPrefab(component.CurrentPrefab), component.CurrentAmount, component.Quality, pos); } List<(string, ItemData)> enchantedItems = component.GetEnchantedItems(); if (enchantedItems.Count <= 0) { return; } foreach (var item3 in enchantedItems) { string item = item3.Item1; ItemData item2 = item3.Item2; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item); if ((Object)(object)itemPrefab != (Object)null) { Utils.DropEnchantedItem(itemPrefab, item2, pos); } } } } 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 { bool flag = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { if (assemblies[i].GetName().Name == "QuickStackStore") { flag = true; break; } } if (!flag) { Ready = false; return; } _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 int TotalOnZdo(ZDO zdo) { if (zdo == null) { return 0; } return zdo.GetInt("Amount", 0) + DrawerComponent.CountEnchantedFromZdo(zdo); } internal static ZNetView Find(Vector3 pos, float radius, string prefab, int quality, ItemData item = null) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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()) { continue; } ZDO zDO = allDrawer._znv.GetZDO(); if (zDO == null || Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius) { continue; } string text = zDO.GetString("Prefab", ""); if (string.IsNullOrEmpty(text) || text != prefab || zDO.GetInt("Quality", 1) != quality) { continue; } if (item != null && Utils.HasCustomData(item) && ItemDrawers.StackOnlySameEnchantment != null && ItemDrawers.StackOnlySameEnchantment.Value && DrawerComponent.CountEnchantedFromZdo(zDO) > 0) { List<(string, ItemData)> enchantedItems = allDrawer.GetEnchantedItems(); if (enchantedItems.Count > 0 && !Utils.CustomDataEquals(enchantedItems[0].Item2?.m_customData, item.m_customData)) { continue; } } 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 && TotalOnZdo(zDO) > 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 BroadcastIcon(ZNetView znv, string prefab, int quality) { if ((Object)(object)znv == (Object)null || !znv.IsValid()) { return; } ZDO zDO = znv.GetZDO(); if (zDO != null) { int num = TotalOnZdo(zDO); zDO.Set("Total", num); if (num <= 0 || string.IsNullOrEmpty(prefab)) { znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { "", 0, 0 }); } else { znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num, quality }); } } } internal static void Add(ZNetView znv, string prefab, int quality, int count) { if (!((Object)(object)znv == (Object)null) && znv.IsValid() && count > 0 && !string.IsNullOrEmpty(prefab)) { znv.InvokeRPC("AddItem_Request", new object[3] { prefab, count, quality }); } } internal static bool AddEnchanted(ZNetView znv, ItemData item) { if ((Object)(object)znv == (Object)null || !znv.IsValid() || item == null) { return false; } string text = Util.PrefabName(item); if (string.IsNullOrEmpty(text)) { return false; } byte[] array = Utils.SerializeItemData(item); if (array == null || array.Length == 0) { return false; } string text2 = Convert.ToBase64String(array); znv.InvokeRPC("AddEnchanted_Request", new object[3] { text, item.m_quality, text2 }); return true; } internal static void Withdraw(ZNetView znv, string prefab, int quality, int count) { if (!((Object)(object)znv == (Object)null) && znv.IsValid() && count > 0) { znv.InvokeRPC("ForceRemove", new object[1] { count }); } } } 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) { return Utils.GetPrefabName(item); } } 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_00e7: 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, val); if (!((Object)(object)val2 == (Object)null)) { if (Utils.HasCustomData(val)) { if (QuickStackBridge.Drawers.AddEnchanted(val2, val)) { inventory.RemoveItem(val); num2++; QuickStackBridge.Dbg($"QS->drawer (enchanted): {text} q{val.m_quality}"); } } else { 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (count <= 0 || string.IsNullOrEmpty(prefab)) { return 0; } if (!CfgFeed.Value) { 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() || !allDrawer._znv.IsOwner()) { continue; } ZDO zDO = allDrawer._znv.GetZDO(); if (zDO != null && !(Vector3.Distance(((Component)allDrawer).transform.position, pos) > radius) && !(zDO.GetString("Prefab", "") != prefab)) { int num2 = zDO.GetInt("Amount", 0); if (num2 > 0) { int num3 = Math.Min(count - num, num2); zDO.Set("Amount", num2 - num3); int num4 = DrawerComponent.CountEnchantedFromZdo(zDO); zDO.Set("Total", num2 - num3 + num4); allDrawer._znv.InvokeRPC(ZNetView.Everybody, "UpdateIcon", new object[3] { prefab, num2 - num3 + num4, zDO.GetInt("Quality", 1) }); Dbg($"FeedTake: {prefab} -{num3} from drawer (left={num2 - num3})"); 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 && !string.IsNullOrEmpty(prefab)) { znv.InvokeRPC("AddItem_Request", new object[3] { prefab, 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) { continue; } if (!allDrawer._znv.IsOwner()) { if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { continue; } 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 byte[] SerializeItemData(ItemData item) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown try { ZPackage val = new ZPackage(); val.Write(item.m_stack); val.Write(item.m_durability); val.Write(item.m_quality); val.Write(item.m_variant); val.Write(item.m_crafterID); val.Write(item.m_crafterName); val.Write(item.m_worldLevel); int num = item.m_customData?.Count ?? 0; val.Write(num); if (num > 0) { foreach (KeyValuePair customDatum in item.m_customData) { val.Write(customDatum.Key ?? ""); val.Write(customDatum.Value ?? ""); } } byte[] array = val.GetArray(); ItemDrawers.DLog($"SerializeItemData: stack={item.m_stack} q={item.m_quality} cdCount={num} bytes={array.Length}"); return array; } catch (Exception ex) { try { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("SerializeItemData failed: " + ex.Message)); } } } catch { } return null; } } public static ItemData DeserializeItemData(byte[] bytes, GameObject prefab) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //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_0036: Expected O, but got Unknown if (bytes == null || bytes.Length == 0 || (Object)(object)prefab == (Object)null) { return null; } try { ZPackage val = new ZPackage(bytes); ItemData val2 = new ItemData { m_shared = prefab.GetComponent().m_itemData.m_shared }; val2.m_stack = val.ReadInt(); val2.m_durability = val.ReadSingle(); val2.m_quality = val.ReadInt(); val2.m_variant = val.ReadInt(); val2.m_crafterID = val.ReadLong(); val2.m_crafterName = val.ReadString(); val2.m_worldLevel = val.ReadInt(); int num = val.ReadInt(); if (num > 0) { val2.m_customData = new Dictionary(); for (int i = 0; i < num; i++) { string key = val.ReadString(); string value = val.ReadString(); val2.m_customData[key] = value; } } val2.m_dropPrefab = prefab; ItemDrawers.DLog($"DeserializeItemData: stack={val2.m_stack} q={val2.m_quality} cdCount={num} bytes={bytes.Length}"); return val2; } catch (Exception ex) { try { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("DeserializeItemData failed: " + ex.Message)); } } } catch { } return null; } } public static byte[] SerializeNamedItemList(List<(string prefabName, ItemData item)> items) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(items.Count); foreach (var (text, item) in items) { val.Write(text ?? ""); byte[] array = SerializeItemData(item); if (array == null) { array = Array.Empty(); } val.Write(array); } return val.GetArray(); } public static List<(string prefabName, ItemData item)> DeserializeNamedItemList(byte[] bytes, Func getPrefab) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown List<(string, ItemData)> list = new List<(string, ItemData)>(); if (bytes == null || bytes.Length == 0) { return list; } try { ZPackage val = new ZPackage(bytes); int num = val.ReadInt(); if (num < 0 || num > 10000) { return list; } for (int i = 0; i < num; i++) { string text = val.ReadString(); byte[] array = val.ReadByteArray(); if (string.IsNullOrEmpty(text) || array == null || array.Length == 0) { continue; } GameObject val2 = getPrefab(text); if (!((Object)(object)val2 == (Object)null)) { ItemData val3 = DeserializeItemData(array, val2); if (val3 != null) { list.Add((text, val3)); } } } } catch (Exception ex) { try { ItemDrawers instance = ItemDrawers.Instance; if (instance != null) { ManualLogSource log = instance.Log; if (log != null) { log.LogWarning((object)("DeserializeNamedItemList failed: " + ex.Message)); } } } catch { } } return list; } public static bool HasCustomData(ItemData item) { if (item?.m_customData == null || item.m_customData.Count == 0) { return false; } if (item.m_shared != null && item.m_shared.m_maxStackSize > 1) { return false; } return true; } public static bool CustomDataEquals(Dictionary a, Dictionary b) { if (a == null && b == null) { return true; } if (a == null || b == null) { return false; } if (a.Count != b.Count) { return false; } foreach (KeyValuePair item in a) { if (!b.TryGetValue(item.Key, out var value)) { return false; } if (value != item.Value) { return false; } } return true; } public static int GetEpicLootRarity(ItemData item) { if (item?.m_customData == null || item.m_customData.Count == 0) { ItemDrawers.DLog("GetEpicLootRarity: no customData, item=" + (item?.m_shared?.m_name ?? "null")); return -1; } if (!item.m_customData.TryGetValue("randyknapp.mods.epicloot#EpicLoot.MagicItemComponent", out var value) || string.IsNullOrEmpty(value)) { ItemDrawers.DLog("GetEpicLootRarity: no EpicLoot key in customData (keys=" + string.Join(",", item.m_customData.Keys) + ")"); return -1; } try { ItemDrawers.DLog("GetEpicLootRarity: raw json (first 200 chars)=" + value.Substring(0, Math.Min(200, value.Length))); int num = value.IndexOf("\"Rarity\""); if (num < 0) { ItemDrawers.DLog("GetEpicLootRarity: 'Rarity' field not found in json"); return -1; } num = value.IndexOf(':', num); if (num < 0) { return -1; } for (num++; num < value.Length && (value[num] == ' ' || value[num] == '\t' || value[num] == '\n'); num++) { } int num2 = num; for (; num < value.Length && char.IsDigit(value[num]); num++) { } if (int.TryParse(value.Substring(num2, num - num2), out var result)) { ItemDrawers.DLog($"GetEpicLootRarity: parsed rarity={result}"); return result; } ItemDrawers.DLog("GetEpicLootRarity: failed to parse rarity from '" + value.Substring(num2, num - num2) + "'"); } catch (Exception ex) { ItemDrawers.DLog("GetEpicLootRarity: exception: " + ex.Message); } return -1; } public static string GetEpicLootDisplayName(ItemData item) { if (item == null) { return null; } try { Assembly assembly = Array.Find(AppDomain.CurrentDomain.GetAssemblies(), (Assembly a) => a.GetName().Name == "EpicLoot"); if (assembly == null) { return null; } Type type = assembly.GetType("EpicLoot.ItemDataExtensions"); if (type == null) { return null; } MethodInfo method = type.GetMethod("GetDisplayName", new Type[1] { typeof(ItemData) }); if (method == null) { return null; } return method.Invoke(null, new object[1] { item }) as string; } catch (Exception ex) { ItemDrawers.DLog("GetEpicLootDisplayName: " + ex.Message); return null; } } public static Color GetRarityColor(int rarity) { //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0357: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "EpicLoot"); if (assembly != null) { string[] array = new string[5] { "_mythicRarityColor", "_legendaryRarityColor", "_epicRarityColor", "_rareRarityColor", "_magicRarityColor" }; int[] array2 = new int[5] { 5, 4, 3, 2, 1 }; Type type = assembly.GetType("EpicLoot.EpicLoot"); if (type != null) { for (int num = 0; num < array.Length; num++) { if (rarity == array2[num]) { FieldInfo field = type.GetField(array[num], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { Color val = (Color)field.GetValue(null); ItemDrawers.DLog($"GetRarityColor: using EpicLoot field {array[num]} for rarity {rarity}: ({val.r},{val.g},{val.b})"); return val; } } } } Type[] types = assembly.GetTypes(); foreach (Type type2 in types) { for (int num3 = 0; num3 < array.Length; num3++) { if (rarity == array2[num3]) { FieldInfo field2 = type2.GetField(array[num3], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && field2.FieldType == typeof(Color)) { Color val2 = (Color)field2.GetValue(null); ItemDrawers.DLog($"GetRarityColor: using EpicLoot {type2.Name}.{array[num3]} for rarity {rarity}: ({val2.r},{val2.g},{val2.b})"); return val2; } } } } ItemDrawers.DLog($"GetRarityColor: EpicLoot assembly found but rarity color fields not found for rarity {rarity}"); } } catch (Exception ex) { ItemDrawers.DLog("GetRarityColor: EpicLoot API failed: " + ex.Message); } Color val3 = (Color)(rarity switch { 1 => new Color(0f, 0f, 1f), 2 => new Color(1f, 1f, 0f), 3 => new Color(0.63f, 0.32f, 1f), 4 => new Color(0f, 0.5f, 0.5f), 5 => new Color(1f, 0.55f, 0f), _ => new Color(1f, 1f, 1f), }); ItemDrawers.DLog($"GetRarityColor: using fallback color for rarity {rarity}: ({val3.r},{val3.g},{val3.b})"); return val3; } public static string GetPrefabName(ItemData item) { if (item == null) { return null; } if ((Object)(object)item.m_dropPrefab != (Object)null) { string name = ((Object)item.m_dropPrefab).name; if (!string.IsNullOrEmpty(name)) { return name; } } if (item.m_shared == null || (Object)(object)ObjectDB.instance == (Object)null) { return null; } List items = ObjectDB.instance.m_items; if (items == null) { return null; } foreach (GameObject item2 in items) { if (!((Object)(object)item2 == (Object)null)) { ItemDrop component = item2.GetComponent(); if (component?.m_itemData?.m_shared != null && component.m_itemData.m_shared.m_name == item.m_shared.m_name) { return ((Object)item2).name; } } } return 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 (!HasCustomData(allItem) && (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 (!HasCustomData(val) && (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); } } } public static void InstantiateEnchantedItem(GameObject prefab, ItemData savedData) { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)localPlayer) || !Object.op_Implicit((Object)prefab) || savedData == null) { ItemDrawers.DLog("InstantiateEnchantedItem: skipped (null player/prefab/data)"); } else { if ((Object)(object)prefab.GetComponent() == (Object)null) { return; } ItemDrop component = Object.Instantiate(prefab, ((Component)localPlayer).transform.position + Vector3.up * 1.5f, Quaternion.identity).GetComponent(); int num = savedData.m_customData?.Count ?? 0; ItemDrawers.DLog($"InstantiateEnchantedItem: prefab={((Object)prefab).name} savedKeys={num}"); component.m_itemData.m_stack = savedData.m_stack; component.m_itemData.m_durability = savedData.m_durability; component.m_itemData.m_quality = savedData.m_quality; component.m_itemData.m_variant = savedData.m_variant; component.m_itemData.m_crafterID = savedData.m_crafterID; component.m_itemData.m_crafterName = savedData.m_crafterName; component.m_itemData.m_worldLevel = savedData.m_worldLevel; if (savedData.m_customData != null && savedData.m_customData.Count > 0) { component.m_itemData.m_customData = new Dictionary(savedData.m_customData); ItemDrawers.DLog($"InstantiateEnchantedItem: copied customData keys={component.m_itemData.m_customData.Count}"); foreach (KeyValuePair customDatum in component.m_itemData.m_customData) { ItemDrawers.DLog(" customData[" + customDatum.Key + "] = " + customDatum.Value.Substring(0, Math.Min(customDatum.Value.Length, 80)) + "..."); } } else { ItemDrawers.DLog("InstantiateEnchantedItem: WARNING — savedData has no customData!"); } try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "EpicLoot"); if (assembly != null) { object obj = (assembly.GetType("EpicLoot.Data.ItemExtensions")?.GetMethod("Data", new Type[1] { typeof(ItemData) }))?.Invoke(null, new object[1] { component.m_itemData }); ItemDrawers.DLog("InstantiateEnchantedItem: Data() = " + ((obj == null) ? "null" : obj.GetType().Name)); if (obj != null) { obj.GetType().GetMethod("LoadAll")?.Invoke(obj, null); ItemDrawers.DLog("InstantiateEnchantedItem: LoadAll() called"); } MethodInfo methodInfo = assembly.GetType("EpicLoot.ItemDataExtensions")?.GetMethod("GetMagicItem", new Type[1] { typeof(ItemData) }); object obj2 = methodInfo?.Invoke(null, new object[1] { component.m_itemData }); ItemDrawers.DLog("InstantiateEnchantedItem: EpicLoot GetMagicItem() = " + ((obj2 == null) ? "null" : obj2.GetType().Name)); if (obj2 == null && obj != null) { Type type = assembly.GetType("EpicLoot.MagicItemComponent"); MethodInfo method = obj.GetType().GetMethod("Get"); if (method != null && type != null) { object obj3 = method.MakeGenericMethod(type).Invoke(obj, new object[1] { "" }); ItemDrawers.DLog("InstantiateEnchantedItem: Get() = " + ((obj3 == null) ? "null" : obj3.GetType().Name)); if (obj3 != null) { obj3.GetType().GetMethod("Load")?.Invoke(obj3, null); ItemDrawers.DLog("InstantiateEnchantedItem: MagicItemComponent.Load() called"); obj2 = methodInfo?.Invoke(null, new object[1] { component.m_itemData }); ItemDrawers.DLog("InstantiateEnchantedItem: after Load(), GetMagicItem() = " + ((obj2 == null) ? "null" : obj2.GetType().Name)); } } } } } catch (Exception ex) { ItemDrawers.DLog("InstantiateEnchantedItem: EpicLoot cache warm failed: " + ex.Message); } if (((Humanoid)localPlayer).GetInventory().CanAddItem(((Component)component).gameObject, -1)) { ((Humanoid)localPlayer).GetInventory().AddItem(component.m_itemData); ZNetScene.instance.Destroy(((Component)component).gameObject); ItemDrawers.DLog("InstantiateEnchantedItem: added to inventory OK"); } else { ItemDrawers.DLog("InstantiateEnchantedItem: CanAddItem=false, item lost!"); } } } public static void DropEnchantedItem(GameObject prefab, ItemData savedData, Vector3 pos) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null || savedData == null) { return; } ItemDrop component = Object.Instantiate(prefab, pos, Quaternion.identity).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.m_itemData.m_stack = savedData.m_stack; component.m_itemData.m_durability = savedData.m_durability; component.m_itemData.m_quality = savedData.m_quality; component.m_itemData.m_variant = savedData.m_variant; component.m_itemData.m_crafterID = savedData.m_crafterID; component.m_itemData.m_crafterName = savedData.m_crafterName; component.m_itemData.m_worldLevel = savedData.m_worldLevel; if (savedData.m_customData != null && savedData.m_customData.Count > 0) { component.m_itemData.m_customData = new Dictionary(savedData.m_customData); } M_ItemDrop_Save.Invoke(component, null); } } } [HarmonyPatch(typeof(ZPackage), "Write", new Type[] { typeof(byte[]) })] internal static class ZPackage_Write_ByteArray_NullGuard { [HarmonyPrefix] private static void Prefix(ref byte[] array) { if (array == null) { array = Array.Empty(); } } } } 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) + DrawerComponent.CountEnchantedFromZdo(znv.GetZDO()); 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); } } }