using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CraftFromContainers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.9.0.0")] [assembly: AssemblyInformationalVersion("3.9.0")] [assembly: AssemblyProduct("CraftFromContainers")] [assembly: AssemblyTitle("CraftFromContainers")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.9.0.0")] [module: UnverifiableCode] namespace CraftFromContainers; [BepInPlugin("aedenthorn.CraftFromContainers", "Craft From Containers", "3.9.0")] public class BepInExPlugin : BaseUnityPlugin { public class ConnectionParams { public GameObject connection; public Vector3 stationPos; } [HarmonyPatch(typeof(FejdStartup), "Awake")] public static class FejdStartup_Awake_Patch { public static void Postfix(FejdStartup __instance) { if (modEnabled.Value) { CheckOdinsQOLConfig(); } } } [HarmonyPatch(typeof(Container), "Awake")] public static class Container_Awake_Patch { public static void Postfix(Container __instance, ZNetView ___m_nview) { ((MonoBehaviour)context).StartCoroutine(AddContainer(__instance, ___m_nview)); } } [HarmonyPatch(typeof(Container), "OnDestroyed")] public static class Container_OnDestroyed_Patch { public static void Prefix(Container __instance) { containerList.Remove(__instance); } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_Patch { public static void Prefix(InventoryGui __instance) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && wasAllowed != AllowByKey()) { AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null)?.Invoke(__instance, new object[1] { false }); } } } [HarmonyPatch(typeof(Fireplace), "Interact")] public static class Fireplace_Interact_Patch { public static bool Prefix(Fireplace __instance, Humanoid user, bool hold, ref bool __result, ZNetView ___m_nview) { //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0236: 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) __result = true; bool flag = CheckKeyHeld(fillAllModKey.Value); Inventory inventory = user.GetInventory(); if (!AllowByKey() || hold || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !flag)) { return true; } if (!___m_nview.HasOwner()) { ___m_nview.ClaimOwnership(); } if (flag && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { int num = (int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true)); inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num, -1, true); typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(inventory, new object[0]); for (int i = 0; i < num; i++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } ((Character)user).Message((MessageType)2, "$msg_fireadding", 0, (Sprite)null, false); __result = false; } if (!inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel) { foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item == null || !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel)) { continue; } if (fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name} but it's forbidden by config"); continue; } int num2 = ((!flag) ? 1 : ((int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)item.m_stack))); if (num2 > 0) { num2 -= (leaveOne.Value ? 1 : 0); } if (num2 != 0) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name}, taking {num2}"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); if (__result) { ((Character)user).Message((MessageType)2, "$msg_fireadding", 0, (Sprite)null, false); } for (int j = 0; j < num2; j++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } __result = false; if (!flag || (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) >= __instance.m_maxFuel) { return false; } } } } return __result; } } [HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")] public static class CookingStation_OnAddFuelSwitch_Patch { public static bool Prefix(CookingStation __instance, ref bool __result, Humanoid user, ItemData item, ZNetView ___m_nview) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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) Dbgl("looking for fuel"); if (!modEnabled.Value || !AllowByKey() || item != null || (float)((object)__instance).GetType().GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) > (float)(__instance.m_maxFuel - 1) || user.GetInventory().HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { return true; } Dbgl("missing fuel in player inventory"); foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item2 = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item2 != null && (!leaveOne.Value || item2.m_stack > 1)) { if (!fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking one"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); ((Character)user).Message((MessageType)2, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null, false); ___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty()); __result = true; return false; } Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); } } return true; } } [HarmonyPatch(typeof(CookingStation), "FindCookableItem")] public static class CookingStation_FindCookableItem_Patch { public static void Postfix(CookingStation __instance, ref ItemData __result) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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) Dbgl("looking for cookable"); if (!modEnabled.Value || !AllowByKey() || __result != null || (__instance.m_requireFire && !(bool)typeof(CookingStation).GetMethod("IsFireLit", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0])) || (int)typeof(CookingStation).GetMethod("GetFreeSlot", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) == -1) { return; } Dbgl("missing cookable in player inventory"); List nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (ItemConversion item2 in __instance.m_conversion) { foreach (Container item3 in nearbyContainers) { ItemData item = item3.GetInventory().GetItem(item2.m_from.m_itemData.m_shared.m_name, -1, false); if (item != null && (!leaveOne.Value || item.m_stack > 1)) { if (!oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item.m_dropPrefab).name)) { Dbgl($"container at {((Component)item3).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name}, taking one"); __result = item; item3.GetInventory().RemoveItem(item2.m_from.m_itemData.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item3, new object[0]); return; } Dbgl($"container at {((Component)item3).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name} but it's forbidden by config"); } } } } } [HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")] public static class Smelter_OnHoverAddFuel_Patch { public static void Postfix(Smelter __instance, ref string __result) { if (modEnabled.Value) { string value = fillAllModKey.Value; if (value != null && value.Length > 0) { __result = __result + "\n[" + fillAllModKey.Value + "+$KEY_Use] $piece_smelter_add max"; } } } } [HarmonyPatch(typeof(Smelter), "OnHoverAddOre")] public static class Smelter_OnHoverAddOre_Patch { public static void Postfix(Smelter __instance, ref string __result) { if (modEnabled.Value) { string value = fillAllModKey.Value; if (value != null && value.Length > 0) { __result = __result + "\n[" + fillAllModKey.Value + "+$KEY_Use] " + __instance.m_addOreTooltip + " max"; } } } } [HarmonyPatch(typeof(Smelter), "OnAddOre")] public static class Smelter_OnAddOre_Patch { public static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ZNetView ___m_nview) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) bool flag = CheckKeyHeld(fillAllModKey.Value); if (!modEnabled.Value || (!AllowByKey() && !flag) || item != null || Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue() >= __instance.m_maxOre) { return true; } Inventory inventory = user.GetInventory(); foreach (ItemConversion item4 in __instance.m_conversion) { if (inventory.HaveItem(item4.m_from.m_itemData.m_shared.m_name, true) && !flag) { return true; } } Dictionary dictionary = new Dictionary(); List nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (ItemConversion item5 in __instance.m_conversion) { if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue() >= __instance.m_maxOre || (dictionary.Any() && !flag)) { break; } string name = item5.m_from.m_itemData.m_shared.m_name; if (flag && inventory.HaveItem(name, true)) { ItemData item2 = inventory.GetItem(name, -1, false); if (oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"player has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); continue; } int num = ((!flag) ? 1 : Mathf.Min(__instance.m_maxOre - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue(), inventory.CountItems(name, -1, true))); if (!dictionary.ContainsKey(name)) { dictionary[name] = 0; } dictionary[name] += num; inventory.RemoveItem(item5.m_from.m_itemData.m_shared.m_name, num, -1, true); for (int i = 0; i < num; i++) { ___m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)item2.m_dropPrefab).name }); } ((Character)user).Message((MessageType)1, $"$msg_added {num} {name}", 0, (Sprite)null, false); if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue() >= __instance.m_maxOre) { break; } } foreach (Container item6 in nearbyContainers) { ItemData item3 = item6.GetInventory().GetItem(name, -1, false); if (item3 == null) { continue; } if (oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item3.m_dropPrefab).name)) { Dbgl($"container at {((Component)item6).transform.position} has {item3.m_stack} {((Object)item3.m_dropPrefab).name} but it's forbidden by config"); continue; } int num2 = ((!flag) ? 1 : Mathf.Min(__instance.m_maxOre - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue(), item6.GetInventory().CountItems(name, -1, true))); if (num2 > 0) { num2 -= (leaveOne.Value ? 1 : 0); } if (num2 != 0) { if (!dictionary.ContainsKey(name)) { dictionary[name] = 0; } dictionary[name] += num2; Dbgl($"container at {((Component)item6).transform.position} has {item3.m_stack} {((Object)item3.m_dropPrefab).name}, taking {num2}"); item6.GetInventory().RemoveItem(name, num2, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item6, new object[0]); for (int j = 0; j < num2; j++) { ___m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)item3.m_dropPrefab).name }); } ((Character)user).Message((MessageType)1, $"$msg_added {num2} {name}", 0, (Sprite)null, false); if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty()).GetValue() >= __instance.m_maxOre || !flag) { break; } } } } if (!dictionary.Any()) { ((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null, false); } else { List list = new List(); foreach (KeyValuePair item7 in dictionary) { list.Add($"$msg_added {item7.Value} {item7.Key}"); } ((Character)user).Message((MessageType)2, string.Join("\n", list), 0, (Sprite)null, false); } return false; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] public static class Smelter_OnAddFuel_Patch { public static bool Prefix(Smelter __instance, ref bool __result, ZNetView ___m_nview, Humanoid user, ItemData item) { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) bool flag = CheckKeyHeld(fillAllModKey.Value); Inventory inventory = user.GetInventory(); if (!modEnabled.Value || (!AllowByKey() && !flag) || item != null || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !flag)) { return true; } __result = true; int num = 0; if ((float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) > (float)(__instance.m_maxFuel - 1)) { ((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null, false); __result = false; return false; } if (flag && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { int num2 = (int)Mathf.Min((float)__instance.m_maxFuel - (float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true)); inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true); for (int i = 0; i < num2; i++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } num += num2; ((Character)user).Message((MessageType)1, "$msg_fireadding", 0, (Sprite)null, false); __result = false; } foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item2 = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item2 == null) { continue; } if (fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); continue; } int num3 = ((!flag) ? 1 : ((int)Mathf.Min((float)__instance.m_maxFuel - (float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]), (float)item2.m_stack))); if (num3 > 0) { num3 -= (leaveOne.Value ? 1 : 0); } if (num3 != 0) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking {num3}"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num3, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); for (int j = 0; j < num3; j++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } num += num3; ((Character)user).Message((MessageType)1, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null, false); __result = false; if (!flag || Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) >= __instance.m_maxFuel) { return false; } } } if (num == 0) { ((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null, false); } else { ((Character)user).Message((MessageType)2, $"$msg_added {num} {__instance.m_fuelItem.m_itemData.m_shared.m_name}", 0, (Sprite)null, false); } return __result; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement")] public static class InventoryGui_SetupRequirement_Patch { public static void Postfix(InventoryGui __instance, Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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) if (!modEnabled.Value || !AllowByKey() || !((Object)(object)req.m_resItem != (Object)null)) { return; } int num = ((Humanoid)player).GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true); int num2 = req.GetAmount(quality) * craftMultiplier; if (num2 <= 0) { return; } TMP_Text component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent(); if (num < num2) { foreach (Container nearbyContainer in GetNearbyContainers(((Component)Player.m_localPlayer).transform.position)) { num += nearbyContainer.GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true); } if (num >= num2) { ((Graphic)component).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? flashColor.Value : unFlashColor.Value); } } if (resourceString.Value.Trim().Length > 0) { component.text = string.Format(resourceString.Value, num, num2); } else { component.text = num2.ToString(); } } } public static class InventoryGui_UpdateRecipeList_Patch { public static void Postfix(InventoryGui __instance, List ___m_recipeList) { if (!modEnabled.Value || !AllowByKey() || ___m_recipeList.Count == 0) { return; } foreach (GameObject ___m_recipe in ___m_recipeList) { _ = ___m_recipe; } } } [HarmonyPatch(typeof(Player), "HaveRequirementItems")] public static class HaveRequirementItems_Patch { public static void Postfix(Player __instance, ref bool __result, Recipe piece, bool discover, int qualityLevel, HashSet ___m_knownMaterial, int amount) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if ((!modEnabled.Value | __result) || discover || !AllowByKey()) { return; } int num = (leaveOne.Value ? 1 : 0); List nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int num2 = val.GetAmount(qualityLevel) * amount; int num3 = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num3 >= num2) { continue; } foreach (Container item in nearbyContainers) { num3 += Math.Max(0, item.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) - num); } if (num3 < num2) { return; } } __result = true; } } [HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")] public static class UpdateKnownRecipesList_Patch { public static void Prefix() { skip = true; } public static void Postfix() { skip = false; } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] public static class HaveRequirements_Patch { public static void Postfix(Player __instance, ref bool __result, Piece piece, RequirementMode mode, HashSet ___m_knownMaterial, Dictionary ___m_knownStations) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 //IL_00c7: 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_0066: Invalid comparison between Unknown and I4 //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Invalid comparison between Unknown and I4 //IL_01c5: Unknown result type (might be due to invalid IL or missing references) if ((!modEnabled.Value | __result) || skip || __instance == null) { return; } Transform transform = ((Component)__instance).transform; if (!((transform != null) ? new Vector3?(transform.position) : ((Vector3?)null)).HasValue || !AllowByKey()) { return; } if (Object.op_Implicit((Object)(object)piece.m_craftingStation)) { if ((int)mode == 1 || (int)mode == 2) { if (!___m_knownStations.ContainsKey(piece.m_craftingStation.m_name)) { return; } } else if (!Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position))) { return; } } if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc)) { return; } List nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); int num = (leaveOne.Value ? 1 : 0); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0) { continue; } if ((int)mode == 1) { if (!___m_knownMaterial.Contains(val.m_resItem.m_itemData.m_shared.m_name)) { return; } } else if ((int)mode == 2) { if (((Humanoid)__instance).GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { continue; } bool flag = false; foreach (Container item in nearbyContainers) { if (item.GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { flag = true; break; } } if (!flag) { return; } } else { if ((int)mode != 0 || ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) >= val.m_amount) { continue; } int num2 = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); foreach (Container item2 in nearbyContainers) { try { num2 += Math.Max(0, item2.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) - num); if (num2 >= val.m_amount) { break; } } catch { } } if (num2 < val.m_amount) { return; } } } __result = true; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] public static class ConsumeResources_Patch { public static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality, int multiplier) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !AllowByKey()) { return true; } Inventory inventory = ((Humanoid)__instance).GetInventory(); List nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (Requirement val in requirements) { if (!Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int num = val.GetAmount(qualityLevel) * multiplier; if (num <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num2 = inventory.CountItems(name, -1, true); Dbgl($"have {num2}/{num} {name} in player inventory"); inventory.RemoveItem(name, Math.Min(num2, num), itemQuality, true); if (num2 >= num) { continue; } foreach (Container item2 in nearbyContainers) { Inventory val2 = ((item2 != null) ? item2.GetInventory() : null); if (val2 == null) { continue; } Mathf.Min(val2.CountItems(name, -1, true), num - num2); Dbgl($"Container at {((Component)item2).transform.position} has {val2.CountItems(name, -1, true)}"); for (int j = 0; j < val2.GetAllItems().Count; j++) { ItemData item = val2.GetItem(j); if (!(item?.m_shared?.m_name == name)) { continue; } Dbgl($"Container has a total items count of {val2.GetAllItems().Count}"); Dbgl($"Got stack of {item.m_stack} {name}"); int num3 = Mathf.Min(item.m_stack, num - num2); if (num3 == item.m_stack) { if (leaveOne.Value && val2.CountItems(name, -1, true) == item.m_stack) { num3--; item.m_stack -= num3; } else { val2.RemoveItem(j); j--; } } else { item.m_stack -= num3; } num2 += num3; Dbgl($"total amount is now {num2}/{num} {name}"); if (num2 >= num) { Dbgl("Got enough, breaking"); break; } } Dbgl("Saving container"); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item2, new object[0]); Dbgl("Setting inventory changed"); MethodInfo methodInfo = AccessTools.Method(typeof(Inventory), "Changed", new Type[2] { typeof(bool), typeof(bool) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(val2, new object[2] { true, false }); } else { AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null)?.Invoke(val2, new object[0]); } if (num2 >= num) { Dbgl("consumed enough " + name); break; } } } return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] public static class UpdatePlacementGhost_Patch { public static void Postfix(Player __instance, bool flashGuardStone) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !showGhostConnections.Value) { return; } FieldInfo field = typeof(Player).GetField("m_placementGhost", BindingFlags.Instance | BindingFlags.NonPublic); GameObject val = ((!(field != null)) ? ((GameObject)null) : ((GameObject)field.GetValue(__instance))); if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent() == (Object)null) { return; } FieldInfo field2 = typeof(CraftingStation).GetField("m_allStations", BindingFlags.Static | BindingFlags.NonPublic); List list = ((field2 != null) ? ((List)field2.GetValue(null)) : null); if ((Object)(object)connectionVfxPrefab == (Object)null) { GameObject[] array = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[]; foreach (GameObject val2 in array) { if (((Object)val2).name == "vfx_ExtensionConnection") { connectionVfxPrefab = val2; break; } } } if ((Object)(object)connectionVfxPrefab == (Object)null || list == null) { return; } bool flag = false; foreach (CraftingStation item in list) { int num = ConnectionExists(item); bool flag2 = num != -1; if (Vector3.Distance(((Component)item).transform.position, val.transform.position) < maxRange.Value) { flag = true; Vector3 connectionEffectPoint = item.GetConnectionEffectPoint(); Vector3 val3 = val.transform.position + Vector3.up * ghostConnectionStartOffset.Value; ConnectionParams connectionParams = null; if (!flag2) { connectionParams = new ConnectionParams(); connectionParams.stationPos = item.GetConnectionEffectPoint(); connectionParams.connection = Object.Instantiate(connectionVfxPrefab, connectionEffectPoint, Quaternion.identity); } else { connectionParams = containerConnections[num]; } if ((Object)(object)connectionParams.connection != (Object)null) { Vector3 val4 = val3 - connectionEffectPoint; Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized); connectionParams.connection.transform.position = connectionEffectPoint; connectionParams.connection.transform.rotation = rotation; connectionParams.connection.transform.localScale = new Vector3(1f, 1f, ((Vector3)(ref val4)).magnitude); } if (!flag2) { containerConnections.Add(connectionParams); } } else if (flag2) { Object.Destroy((Object)(object)containerConnections[num].connection); containerConnections.RemoveAt(num); } } if (flag && (Object)(object)context != (Object)null) { ((MonoBehaviour)context).CancelInvoke("StopConnectionEffects"); ((MonoBehaviour)context).Invoke("StopConnectionEffects", ghostConnectionRemovalDelay.Value); } } } [HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")] public static class DoCrafting_Patch { public static bool Prefix(InventoryGui __instance, KeyValuePair ___m_selectedRecipe, ItemData ___m_craftUpgradeItem, bool ___m_multiCrafting, int ___m_multiCraftAmount) { if (!modEnabled.Value || !AllowByKey() || !CheckKeyHeld(pullItemsKey.Value) || (Object)(object)___m_selectedRecipe.Key == (Object)null) { return true; } int num = ((___m_craftUpgradeItem == null) ? 1 : (___m_craftUpgradeItem.m_quality + 1)); if (num > ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_maxQuality) { return true; } Dbgl("pulling resources to player inventory for crafting item " + ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_name); int multiple = ((!___m_multiCrafting) ? 1 : ___m_multiCraftAmount); PullResources(Player.m_localPlayer, ___m_selectedRecipe.Key.m_resources, num, multiple); return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] public static class UpdatePlacement_Patch { public static bool Prefix(Player __instance, bool takeInput, float dt, PieceTable ___m_buildPieces, GameObject ___m_placementGhost) { if (!modEnabled.Value || !AllowByKey() || !CheckKeyHeld(pullItemsKey.Value) || !((Character)__instance).InPlaceMode() || !takeInput || Hud.IsPieceSelectionVisible()) { return true; } if (Input.GetMouseButtonDown(0) || Input.GetKeyDown((KeyCode)330)) { Piece selectedPiece = ___m_buildPieces.GetSelectedPiece(); if ((Object)(object)selectedPiece != (Object)null) { if (selectedPiece.m_repairPiece) { return true; } if ((Object)(object)___m_placementGhost != (Object)null && (int)typeof(Player).GetField("m_placementStatus", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) == 0) { Dbgl("pulling resources to player inventory for piece " + ((Object)selectedPiece).name); PullResources(__instance, selectedPiece.m_resources, 0, 1); } } return false; } return true; } } [HarmonyPatch(typeof(Turret), "UseItem")] public static class Turret_UseItem_Patch { public static void Prefix(Turret __instance, Humanoid user, ref ItemData item) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown if (!modEnabled.Value || !AllowByKey() || item != null || !(user is Player)) { Dbgl($"Not allowed {AllowByKey()} {item == null} {user is Player}"); return; } item = user.GetInventory().GetAmmoItem(__instance.m_ammoType, (__instance.GetAmmo() > 0) ? __instance.GetAmmoType() : null); if (item == null) { Dbgl("No item found in inventory, checking containers for " + __instance.GetAmmoType()); GameObject prefab = ZNetScene.instance.GetPrefab(__instance.GetAmmoType()); if (!Object.op_Implicit((Object)(object)prefab)) { Dbgl("No prefab found for " + __instance.GetAmmoType()); Dbgl("Turret '" + ((Object)__instance).name + "' is trying to fire but has no ammo or default ammo!"); return; } PullResources((Player)(object)((user is Player) ? user : null), (Requirement[])(object)new Requirement[1] { new Requirement { m_amount = 1, m_resItem = prefab.GetComponent() } }, prefab.GetComponent().m_itemData.m_quality, 1); } } } public static class HaveRequirements_Patch2_broken { public static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown List list = new List(instructions); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (!(val.opcode == OpCodes.Callvirt) || !((object)val).ToString().Contains("IsDLCInstalled")) { continue; } int num = -1; for (int j = i + 1; j < i + 5; j++) { if (list[j].opcode == OpCodes.Ret) { num = j; break; } } if (num != -1) { int num2 = num + 1; List