Decompiled source of ValheimCraftFromContainers v1.0.0

plugins/ValheimCraftFromContainers.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ValheimCraftFromContainers")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ValheimCraftFromContainers")]
[assembly: AssemblyTitle("ValheimCraftFromContainers")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ValheimCraftFromContainers;

internal static class ContainerAccess
{
	private struct Origin
	{
		public Vector3 Pos;

		public float Range;
	}

	private static readonly List<Container> All = new List<Container>();

	private static float _nextScan = -1f;

	private static int _cacheFrame = -1;

	private static Player _cachePlayer;

	private static readonly List<Container> Cache = new List<Container>();

	private static readonly List<Container> Empty = new List<Container>();

	private static readonly List<Origin> Origins = new List<Origin>();

	private static readonly List<CraftingStation> Stations = new List<CraftingStation>();

	private static readonly List<CraftingStation> Covering = new List<CraftingStation>();

	private static FieldInfo _fPlacementGhost;

	private static FieldInfo _fAllStations;

	public static GameObject GetPlacementGhost(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		if (_fPlacementGhost == null)
		{
			_fPlacementGhost = AccessTools.Field(typeof(Player), "m_placementGhost");
		}
		object? obj = _fPlacementGhost?.GetValue(player);
		return (GameObject)((obj is GameObject) ? obj : null);
	}

	public static Vector3 GetBuildPoint(Player player)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		GameObject placementGhost = GetPlacementGhost(player);
		if ((Object)(object)placementGhost != (Object)null && placementGhost.activeInHierarchy)
		{
			return placementGhost.transform.position;
		}
		if (!((Object)(object)player != (Object)null))
		{
			return Vector3.zero;
		}
		return ((Component)player).transform.position;
	}

	public static List<CraftingStation> GetAllStations()
	{
		Stations.Clear();
		if (_fAllStations == null)
		{
			_fAllStations = AccessTools.Field(typeof(CraftingStation), "m_allStations");
		}
		if (_fAllStations != null && _fAllStations.GetValue(null) is List<CraftingStation> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i] != (Object)null)
				{
					Stations.Add(list[i]);
				}
			}
		}
		return Stations;
	}

	public static List<CraftingStation> GetCoveringStations(Vector3 point, string name)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		Covering.Clear();
		List<CraftingStation> allStations = GetAllStations();
		for (int i = 0; i < allStations.Count; i++)
		{
			CraftingStation val = allStations[i];
			if (!((Object)(object)val == (Object)null) && (string.IsNullOrEmpty(name) || !(val.m_name != name)))
			{
				float stationBuildRange = val.GetStationBuildRange();
				Vector3 val2 = point;
				val2.y = ((Component)val).transform.position.y;
				if (Vector3.Distance(((Component)val).transform.position, val2) < stationBuildRange)
				{
					Covering.Add(val);
				}
			}
		}
		return Covering;
	}

	public static bool IsStationCovering(Vector3 point, string name)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		List<CraftingStation> allStations = GetAllStations();
		for (int i = 0; i < allStations.Count; i++)
		{
			CraftingStation val = allStations[i];
			if (!((Object)(object)val == (Object)null) && !(val.m_name != name))
			{
				float stationBuildRange = val.GetStationBuildRange();
				Vector3 val2 = point;
				val2.y = ((Component)val).transform.position.y;
				if (Vector3.Distance(((Component)val).transform.position, val2) < stationBuildRange)
				{
					return true;
				}
			}
		}
		return false;
	}

	private static void Rescan()
	{
		_nextScan = Time.time + 5f;
		All.Clear();
		try
		{
			Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
			foreach (Container val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					All.Add(val);
				}
			}
		}
		catch
		{
			Container[] array = Object.FindObjectsOfType<Container>();
			foreach (Container val2 in array)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					All.Add(val2);
				}
			}
		}
	}

	public static List<Container> Find(Player player)
	{
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: 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_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			return Empty;
		}
		if ((Object)(object)player == (Object)(object)_cachePlayer && Time.frameCount == _cacheFrame)
		{
			return Cache;
		}
		if (Time.time >= _nextScan)
		{
			Rescan();
		}
		Cache.Clear();
		_cacheFrame = Time.frameCount;
		_cachePlayer = player;
		float num = Mathf.Max(0.5f, CraftFromContainersPlugin.Range.Value);
		bool value = CraftFromContainersPlugin.UseStationBuildRange.Value;
		Origins.Clear();
		Origins.Add(new Origin
		{
			Pos = ((Component)player).transform.position,
			Range = num
		});
		CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
		if ((Object)(object)currentCraftingStation != (Object)null && value)
		{
			Origins.Add(new Origin
			{
				Pos = ((Component)currentCraftingStation).transform.position,
				Range = Mathf.Max(num, currentCraftingStation.GetStationBuildRange())
			});
		}
		GameObject placementGhost = GetPlacementGhost(player);
		if ((Object)(object)placementGhost != (Object)null && placementGhost.activeInHierarchy && value)
		{
			List<CraftingStation> coveringStations = GetCoveringStations(placementGhost.transform.position, null);
			for (int i = 0; i < coveringStations.Count; i++)
			{
				CraftingStation val = coveringStations[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)currentCraftingStation))
				{
					Origins.Add(new Origin
					{
						Pos = ((Component)val).transform.position,
						Range = Mathf.Max(num, val.GetStationBuildRange())
					});
				}
			}
		}
		long playerID = player.GetPlayerID();
		for (int j = 0; j < All.Count; j++)
		{
			Container val2 = All[j];
			if ((Object)(object)val2 == (Object)null || val2.GetInventory() == null || (CraftFromContainersPlugin.RequireAccess.Value && !Accessible(val2, playerID)))
			{
				continue;
			}
			Vector3 position = ((Component)val2).transform.position;
			bool flag = false;
			for (int k = 0; k < Origins.Count; k++)
			{
				if (Vector3.Distance(position, Origins[k].Pos) <= Origins[k].Range)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				Cache.Add(val2);
			}
		}
		return Cache;
	}

	public static bool Accessible(Container c, long playerId)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		PrivacySetting privacy = c.m_privacy;
		if ((int)privacy != 0)
		{
			if ((int)privacy == 2)
			{
				return true;
			}
			return false;
		}
		Piece component = ((Component)c).GetComponent<Piece>();
		if ((Object)(object)component != (Object)null)
		{
			return component.GetCreator() == playerId;
		}
		return false;
	}

	public static int CountCombined(Player player, List<Container> containers, string name, int quality)
	{
		int num = ((Humanoid)player).GetInventory().CountItems(name, quality, true);
		for (int i = 0; i < containers.Count; i++)
		{
			Inventory inventory = containers[i].GetInventory();
			if (inventory != null)
			{
				num += inventory.CountItems(name, quality, true);
			}
		}
		return num;
	}

	public static int MaxByQuality(Player player, List<Container> containers, string name, int maxQuality)
	{
		int num = 0;
		for (int i = 1; i <= maxQuality; i++)
		{
			int num2 = CountCombined(player, containers, name, i);
			if (num2 > num)
			{
				num = num2;
			}
		}
		return num;
	}

	public static bool TakeFromContainers(Player player, List<Container> containers, string name, int quality, int amount)
	{
		int num = amount;
		for (int i = 0; i < containers.Count; i++)
		{
			if (num <= 0)
			{
				break;
			}
			Inventory inventory = containers[i].GetInventory();
			if (inventory != null)
			{
				int num2 = inventory.CountItems(name, quality, true);
				if (num2 > 0)
				{
					int num3 = Mathf.Min(num2, num);
					Claim(containers[i]);
					inventory.RemoveItem(name, num3, quality, true);
					num -= num3;
				}
			}
		}
		return num <= 0;
	}

	public static void Claim(Container c)
	{
		try
		{
			ZNetView component = ((Component)c).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner())
			{
				component.ClaimOwnership();
			}
		}
		catch
		{
		}
	}
}
[BepInPlugin("SuperVikingDepartment.ValheimCraftFromContainers", "ValheimCraftFromContainers", "1.0.0")]
public class CraftFromContainersPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "SuperVikingDepartment.ValheimCraftFromContainers";

	public const string PluginName = "ValheimCraftFromContainers";

	public const string PluginVersion = "1.0.0";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<float> Range;

	internal static ConfigEntry<bool> UseStationBuildRange;

	internal static ConfigEntry<bool> RequireAccess;

	internal static ConfigEntry<bool> DebugLogging;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "总开关。关闭后完全恢复原版行为(材料必须带在身上)。");
		Range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range", 10f, "以玩家为中心、搜索容器的半径(米)。打开制作台时,还会以制作台为中心再搜一遍,所以把箱子放在工作台旁边即可被使用。默认 10 米,与原版工作台建造半径一致。");
		UseStationBuildRange = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseStationBuildRange", true, "使用制作台自身的建造半径(会随台子升级/加装扩展而变大)作为搜索范围。开启后,箱子只要在制作台的建造圈内就能被使用。");
		RequireAccess = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RequireAccess", true, "只使用你有权访问的容器。私人箱子(Privacy=Private)仅其建造者可用;多人游戏里可以防止误用别人的私人箱子。");
		DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "DebugLogging", false, "输出补丁细节日志,用于排查问题。正常游玩建议关闭。");
		_harmony = new Harmony("SuperVikingDepartment.ValheimCraftFromContainers");
		try
		{
			Patches.Apply(_harmony);
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[CraftFromContainers] 挂载补丁失败:" + ex));
		}
		LogPatchStatus();
		Log.LogInfo((object)"ValheimCraftFromContainers loaded (v1.0.0)");
		Log.LogInfo((object)($"[CraftFromContainers] enabled={Enabled.Value}, range={Range.Value}, " + $"useStationBuildRange={UseStationBuildRange.Value}, requireAccess={RequireAccess.Value}"));
	}

	private static void LogPatchStatus()
	{
		CheckPatch(typeof(Player), "HaveRequirementItems");
		CheckPatch(typeof(Player), "HaveRequirements", new Type[2]
		{
			typeof(Piece),
			typeof(RequirementMode)
		});
		CheckPatch(typeof(Player), "ConsumeResources");
		CheckPatch(typeof(InventoryGui), "SetupRequirement");
	}

	private static void CheckPatch(Type type, string method, Type[] args = null)
	{
		MethodInfo methodInfo = ((args == null) ? AccessTools.Method(type, method, (Type[])null, (Type[])null) : AccessTools.Method(type, method, args, (Type[])null));
		if (methodInfo == null)
		{
			Log.LogError((object)("[CraftFromContainers][diag] " + type.Name + "." + method + " 未找到!游戏版本可能不兼容。"));
		}
		else
		{
			Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
			int valueOrDefault = (patchInfo?.Postfixes?.Count).GetValueOrDefault();
			int valueOrDefault2 = (patchInfo?.Prefixes?.Count).GetValueOrDefault();
			Log.LogInfo((object)$"[CraftFromContainers][diag] {type.Name}.{method}: prefix={valueOrDefault2}, postfix={valueOrDefault}");
		}
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
internal class Pending
{
	public string Name;

	public int Quality;

	public int Amount;
}
internal static class Patches
{
	private static Harmony _harmony;

	private static FieldInfo _fKnownStations;

	public static void Apply(Harmony harmony)
	{
		_harmony = harmony;
		Patch(Target(typeof(Player), "HaveRequirementItems"), null, "HaveRequirementItems_Post", "Player.HaveRequirementItems");
		Patch(Target(typeof(Player), "HaveRequirements", typeof(Piece), typeof(RequirementMode)), null, "HaveRequirementsPiece_Post", "Player.HaveRequirements(Piece, RequirementMode)");
		Patch(Target(typeof(Player), "ConsumeResources"), "ConsumeResources_Pre", "ConsumeResources_Post", "Player.ConsumeResources");
		Patch(Target(typeof(InventoryGui), "SetupRequirement"), null, "SetupRequirement_Post", "InventoryGui.SetupRequirement");
		Patch(Target(typeof(Hud), "SetupPieceInfo"), null, "SetupPieceInfo_Post", "Hud.SetupPieceInfo");
	}

	private static MethodInfo Target(Type type, string name, params Type[] args)
	{
		if (args.Length != 0)
		{
			return AccessTools.Method(type, name, args, (Type[])null);
		}
		return AccessTools.Method(type, name, (Type[])null, (Type[])null);
	}

	private static void Patch(MethodInfo target, string prefixName, string postfixName, string label)
	{
		//IL_003a: 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)
		if (target == null)
		{
			CraftFromContainersPlugin.Log.LogError((object)("[CraftFromContainers] 找不到目标方法 " + label + ",已跳过该补丁。"));
			return;
		}
		try
		{
			HarmonyMethod val = ((prefixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeof(Patches), prefixName, (Type[])null, (Type[])null)));
			HarmonyMethod val2 = ((postfixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeof(Patches), postfixName, (Type[])null, (Type[])null)));
			_harmony.Patch((MethodBase)target, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			CraftFromContainersPlugin.Log.LogInfo((object)("[CraftFromContainers] 已挂载补丁 " + label));
		}
		catch (Exception arg)
		{
			CraftFromContainersPlugin.Log.LogError((object)$"[CraftFromContainers] 挂载 {label} 失败:{arg}");
		}
	}

	private static bool Ready(Player player)
	{
		if (CraftFromContainersPlugin.Enabled.Value && (Object)(object)player != (Object)null)
		{
			return (Object)(object)player == (Object)(object)Player.m_localPlayer;
		}
		return false;
	}

	private static bool StationInRange(Player player, string stationName)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)CraftingStation.HaveBuildStationInRange(stationName, ((Component)player).transform.position) != (Object)null)
		{
			return true;
		}
		Vector3 buildPoint = ContainerAccess.GetBuildPoint(player);
		Vector3 val = buildPoint - ((Component)player).transform.position;
		if (((Vector3)(ref val)).sqrMagnitude > 0.0001f && (Object)(object)CraftingStation.HaveBuildStationInRange(stationName, buildPoint) != (Object)null)
		{
			return true;
		}
		return false;
	}

	private static void HaveRequirementItems_Post(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result)
	{
		if (__result || discover || !Ready(__instance) || piece.m_requireOnlyOneIngredient)
		{
			return;
		}
		List<Container> list = ContainerAccess.Find(__instance);
		if (list.Count != 0)
		{
			__result = SatisfiedByContainers(__instance, piece, qualityLevel, amount, list);
			if (__result && CraftFromContainersPlugin.DebugLogging.Value)
			{
				CraftFromContainersPlugin.Log.LogInfo((object)("[CraftFromContainers] 由容器满足配方需求:" + piece.m_item?.m_itemData?.m_shared?.m_name));
			}
		}
	}

	private static bool SatisfiedByContainers(Player player, Recipe recipe, int qualityLevel, int amount, List<Container> containers)
	{
		CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
		Requirement[] resources = recipe.m_resources;
		foreach (Requirement val in resources)
		{
			if ((!((Object)(object)currentCraftingStation != (Object)null) || currentCraftingStation.m_upgrader != val.m_upgraderResource) && (!((Object)(object)currentCraftingStation == (Object)null) || !val.m_upgraderResource) && !((Object)(object)val.m_resItem == (Object)null))
			{
				int num = val.GetAmount(qualityLevel) * amount;
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				if (ContainerAccess.MaxByQuality(player, containers, name, val.m_resItem.m_itemData.m_shared.m_maxQuality) < num)
				{
					return false;
				}
			}
		}
		return true;
	}

	private static void HaveRequirementsPiece_Post(Player __instance, Piece piece, RequirementMode mode, ref bool __result)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Invalid comparison between Unknown and I4
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (!__result && Ready(__instance) && ((int)mode == 0 || (int)mode == 2))
		{
			List<Container> list = ContainerAccess.Find(__instance);
			if (list.Count != 0)
			{
				__result = PieceSatisfiedByContainers(__instance, piece, mode, list);
			}
		}
	}

	private static bool PieceSatisfiedByContainers(Player player, Piece piece, RequirementMode mode, List<Container> containers)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Invalid comparison between Unknown and I4
		if ((Object)(object)piece.m_craftingStation != (Object)null)
		{
			if ((int)mode == 2)
			{
				if (!KnowsStation(player, piece.m_craftingStation.m_name))
				{
					return false;
				}
			}
			else if (!StationInRange(player, piece.m_craftingStation.m_name) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27))
			{
				return false;
			}
		}
		if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc))
		{
			return false;
		}
		if (ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey()))
		{
			return true;
		}
		Requirement[] resources = piece.m_resources;
		foreach (Requirement val in resources)
		{
			if ((Object)(object)val.m_resItem == (Object)null || val.m_amount <= 0)
			{
				continue;
			}
			string name = val.m_resItem.m_itemData.m_shared.m_name;
			if ((int)mode == 2)
			{
				if (ContainerAccess.CountCombined(player, containers, name, -1) <= 0)
				{
					return false;
				}
			}
			else if (ContainerAccess.CountCombined(player, containers, name, -1) < val.m_amount)
			{
				return false;
			}
		}
		return true;
	}

	private static bool KnowsStation(Player player, string stationName)
	{
		if (_fKnownStations == null)
		{
			_fKnownStations = AccessTools.Field(typeof(Player), "m_knownStations");
		}
		if (_fKnownStations == null)
		{
			return true;
		}
		if (_fKnownStations.GetValue(player) is IDictionary dictionary)
		{
			return dictionary.Contains(stationName);
		}
		return false;
	}

	private static void ConsumeResources_Pre(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality, int multiplier, out List<Pending> __state)
	{
		__state = null;
		if (!Ready(__instance) || ContainerAccess.Find(__instance).Count == 0)
		{
			return;
		}
		CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
		Inventory inventory = ((Humanoid)__instance).GetInventory();
		List<Pending> list = new List<Pending>();
		foreach (Requirement val in requirements)
		{
			if ((!((Object)(object)currentCraftingStation == (Object)null) && currentCraftingStation.m_upgrader != val.m_upgraderResource) || (!((Object)(object)currentCraftingStation != (Object)null) && val.m_upgraderResource) || !((Object)(object)val.m_resItem != (Object)null))
			{
				continue;
			}
			int num = val.GetAmount(qualityLevel) * multiplier;
			if (num > 0)
			{
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				int num2 = inventory.CountItems(name, itemQuality, true);
				int num3 = num - num2;
				if (num3 > 0)
				{
					list.Add(new Pending
					{
						Name = name,
						Quality = itemQuality,
						Amount = num3
					});
				}
			}
		}
		if (list.Count > 0)
		{
			__state = list;
		}
	}

	private static void ConsumeResources_Post(Player __instance, List<Pending> __state)
	{
		if (__state == null || !Ready(__instance))
		{
			return;
		}
		List<Container> list = ContainerAccess.Find(__instance);
		if (list.Count == 0)
		{
			return;
		}
		foreach (Pending item in __state)
		{
			ContainerAccess.TakeFromContainers(__instance, list, item.Name, item.Quality, item.Amount);
			if (CraftFromContainersPlugin.DebugLogging.Value)
			{
				CraftFromContainersPlugin.Log.LogInfo((object)$"[CraftFromContainers] 从容器补扣 {item.Name} x{item.Amount}");
			}
		}
	}

	private static void SetupRequirement_Post(Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier, bool __result)
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		if (!__result || !Ready(player) || (Object)(object)req.m_resItem == (Object)null)
		{
			return;
		}
		int num = req.GetAmount(quality) * craftMultiplier;
		if (num <= 0)
		{
			return;
		}
		List<Container> list = ContainerAccess.Find(player);
		if (list.Count == 0)
		{
			return;
		}
		string name = req.m_resItem.m_itemData.m_shared.m_name;
		if (ContainerAccess.CountCombined(player, list, name, -1) < num)
		{
			return;
		}
		Transform val = elementRoot.Find("res_amount");
		if ((Object)(object)val != (Object)null)
		{
			TMP_Text component = ((Component)val).GetComponent<TMP_Text>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = Color.white;
			}
		}
	}

	private static void SetupPieceInfo_Post(Hud __instance, Piece piece)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)piece == (Object)null || (Object)(object)piece.m_craftingStation == (Object)null)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!Ready(localPlayer))
		{
			return;
		}
		string name = piece.m_craftingStation.m_name;
		if ((Object)(object)CraftingStation.HaveBuildStationInRange(name, ((Component)localPlayer).transform.position) != (Object)null)
		{
			return;
		}
		Vector3 buildPoint = ContainerAccess.GetBuildPoint(localPlayer);
		Vector3 val = buildPoint - ((Component)localPlayer).transform.position;
		if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
		{
			return;
		}
		CraftingStation val2 = CraftingStation.HaveBuildStationInRange(name, buildPoint);
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		GameObject[] requirementItems = __instance.m_requirementItems;
		if (requirementItems == null || requirementItems.Length <= piece.m_resources.Length)
		{
			return;
		}
		GameObject val3 = requirementItems[piece.m_resources.Length];
		if ((Object)(object)val3 == (Object)null)
		{
			return;
		}
		Transform val4 = val3.transform.Find("res_icon");
		if ((Object)(object)val4 != (Object)null)
		{
			Image component = ((Component)val4).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = Color.white;
			}
		}
		Transform val5 = val3.transform.Find("res_amount");
		if ((Object)(object)val5 != (Object)null)
		{
			TMP_Text component2 = ((Component)val5).GetComponent<TMP_Text>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.text = "";
				((Graphic)component2).color = Color.white;
			}
		}
		try
		{
			val2.ShowAreaMarker();
		}
		catch
		{
		}
	}
}