Decompiled source of ValheimDepositAll v1.0.1

plugins/ValheimDepositAll.dll

Decompiled a month ago
using System;
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.Events;
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("ValheimDepositAll")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ValheimDepositAll")]
[assembly: AssemblyTitle("ValheimDepositAll")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace ValheimDepositAll;

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 readonly List<Origin> Origins = new List<Origin>();

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

	public static List<Container> Find(Player player)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		Result.Clear();
		if ((Object)(object)player == (Object)null)
		{
			return Result;
		}
		ScanIfStale();
		float num = Mathf.Max(0.5f, DepositAllPlugin.Range.Value);
		bool value = DepositAllPlugin.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())
			});
		}
		long playerID = player.GetPlayerID();
		for (int i = 0; i < All.Count; i++)
		{
			Container val = All[i];
			if (!((Object)(object)val == (Object)null) && val.GetInventory() != null && (!DepositAllPlugin.RequireAccess.Value || Accessible(val, playerID)) && InRange(((Component)val).transform.position))
			{
				Result.Add(val);
			}
		}
		Vector3 origin = ((Component)player).transform.position;
		Result.Sort((Container a, Container b) => Vector3.SqrMagnitude(((Component)a).transform.position - origin).CompareTo(Vector3.SqrMagnitude(((Component)b).transform.position - origin)));
		return Result;
	}

	private static bool InRange(Vector3 pos)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < Origins.Count; i++)
		{
			if (Vector3.Distance(pos, Origins[i].Pos) <= Origins[i].Range)
			{
				return true;
			}
		}
		return false;
	}

	private static void ScanIfStale()
	{
		if (Time.time < _nextScan && All.Count > 0)
		{
			return;
		}
		_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 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 void Claim(Container c)
	{
		try
		{
			ZNetView component = ((Component)c).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner())
			{
				component.ClaimOwnership();
			}
		}
		catch
		{
		}
	}

	public static bool ContainsSameKind(Inventory inv, ItemData item)
	{
		if (inv == null || item == null)
		{
			return false;
		}
		string name = item.m_shared.m_name;
		List<ItemData> allItems = inv.GetAllItems();
		for (int i = 0; i < allItems.Count; i++)
		{
			ItemData val = allItems[i];
			if (val != null && val.m_shared.m_name == name)
			{
				return true;
			}
		}
		return false;
	}

	public static int FreeSpaceFor(Inventory inv, ItemData item)
	{
		if (inv == null || item == null)
		{
			return 0;
		}
		int num = Mathf.Max(1, item.m_shared.m_maxStackSize);
		int num2 = 0;
		List<ItemData> allItems = inv.GetAllItems();
		for (int i = 0; i < allItems.Count; i++)
		{
			ItemData val = allItems[i];
			if (val != null && SameStack(val, item))
			{
				num2 += num - val.m_stack;
			}
		}
		return num2 + inv.GetEmptySlots() * num;
	}

	private static bool SameStack(ItemData a, ItemData b)
	{
		if (a.m_shared.m_name == b.m_shared.m_name && a.m_quality == b.m_quality && a.m_worldLevel == b.m_worldLevel)
		{
			return a.m_stack < Mathf.Max(1, a.m_shared.m_maxStackSize);
		}
		return false;
	}
}
[BepInPlugin("SuperVikingDepartment.ValheimDepositAll", "ValheimDepositAll", "1.0.1")]
public class DepositAllPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "SuperVikingDepartment.ValheimDepositAll";

	public const string PluginName = "ValheimDepositAll";

	public const string PluginVersion = "1.0.1";

	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> KeepEquipped;

	internal static ConfigEntry<bool> SkipHotbar;

	internal static ConfigEntry<bool> AddButton;

	internal static ConfigEntry<string> ButtonLabel;

	internal static ConfigEntry<bool> ShowMessage;

	internal static ConfigEntry<bool> DebugLogging;

	internal static MethodInfo UpdateRecipeMethod;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: 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)仅其建造者可用;多人游戏里可以防止把东西塞进别人的私人箱子。");
		KeepEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "KeepEquipped", true, "保留身上已装备的物品(武器、护甲、腰带、工具等),不把它们塞进箱子。关闭后连装备也会被分发,可能把自己扒光,请谨慎。");
		SkipHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SkipHotbar", true, "保留快捷栏里的物品(按键 1-8 切换的背包第一行),不把它们塞进箱子。方便保留常用的食物、药水、工具。");
		AddButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddButton", true, "是否在制作台界面里添加「分发」按钮。关闭后本 mod 不做任何界面改动。改完需重启游戏。");
		ButtonLabel = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ButtonLabel", "", "「分发」按钮上显示的文字。留空 = 自动:中文界面显示「分发」,其他语言显示「Deposit」。");
		ShowMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMessage", true, "分发完成后在屏幕中央提示结果(分发了几件、有几件没能放进箱子)。");
		DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "DebugLogging", false, "输出分发细节日志,用于排查问题。正常游玩建议关闭。");
		_harmony = new Harmony("SuperVikingDepartment.ValheimDepositAll");
		try
		{
			Patches.Apply(_harmony);
		}
		catch (Exception ex)
		{
			Log.LogError((object)("[DepositAll] 挂载补丁失败:" + ex));
		}
		LogPatchStatus();
		Log.LogInfo((object)"ValheimDepositAll loaded (v1.0.1)");
		Log.LogInfo((object)($"[DepositAll] enabled={Enabled.Value}, range={Range.Value}, " + $"useStationBuildRange={UseStationBuildRange.Value}, requireAccess={RequireAccess.Value}, " + $"keepEquipped={KeepEquipped.Value}, skipHotbar={SkipHotbar.Value}, addButton={AddButton.Value}"));
	}

	private static void LogPatchStatus()
	{
		UpdateRecipeMethod = AccessTools.Method(typeof(InventoryGui), "UpdateRecipe", new Type[2]
		{
			typeof(Player),
			typeof(float)
		}, (Type[])null);
		if (UpdateRecipeMethod == null)
		{
			Log.LogError((object)"[DepositAll][diag] InventoryGui.UpdateRecipe(Player, float) 未找到!游戏版本可能不兼容,按钮将不会出现。");
			return;
		}
		Patches patchInfo = Harmony.GetPatchInfo((MethodBase)UpdateRecipeMethod);
		int valueOrDefault = (patchInfo?.Postfixes?.Count).GetValueOrDefault();
		Log.LogInfo((object)$"[DepositAll][diag] InventoryGui.UpdateRecipe: prefix={(patchInfo?.Prefixes?.Count).GetValueOrDefault()}, postfix={valueOrDefault}");
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		Patches.Cleanup();
	}
}
internal static class Distributor
{
	internal struct Result
	{
		public int Moved;

		public int Leftover;

		public int Containers;

		public bool SawCandidates;

		public int LeftoverNoSpace;

		public int LeftoverNoChest;
	}

	private static readonly MethodInfo MChanged = AccessTools.Method(typeof(Inventory), "Changed", new Type[2]
	{
		typeof(bool),
		typeof(bool)
	}, (Type[])null);

	internal static Result Run(Player player)
	{
		Result result = default(Result);
		if ((Object)(object)player == (Object)null)
		{
			return result;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return result;
		}
		List<Container> list = ContainerAccess.Find(player);
		if (list.Count == 0)
		{
			return result;
		}
		result.SawCandidates = true;
		List<ItemData> list2 = new List<ItemData>(inventory.GetAllItems());
		bool value = DepositAllPlugin.KeepEquipped.Value;
		bool value2 = DepositAllPlugin.SkipHotbar.Value;
		HashSet<Container> hashSet = new HashSet<Container>();
		HashSet<Container> hashSet2 = new HashSet<Container>();
		for (int i = 0; i < list2.Count; i++)
		{
			ItemData val = list2[i];
			if (val == null || val.m_stack <= 0 || (value && ((Humanoid)player).IsItemEquiped(val)) || (value2 && val.m_gridPos.y == 0))
			{
				continue;
			}
			int num = val.m_stack;
			bool flag = false;
			for (int j = 0; j < list.Count; j++)
			{
				if (num <= 0)
				{
					break;
				}
				Container val2 = list[j];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Inventory inventory2 = val2.GetInventory();
				if (inventory2 == null || !ContainerAccess.ContainsSameKind(inventory2, val))
				{
					continue;
				}
				flag = true;
				int num2 = ContainerAccess.FreeSpaceFor(inventory2, val);
				if (num2 > 0)
				{
					if (!hashSet.Contains(val2))
					{
						ContainerAccess.Claim(val2);
						hashSet.Add(val2);
					}
					int num3 = MoveInto(inventory, val, inventory2, Mathf.Min(num2, num));
					if (num3 > 0)
					{
						num -= num3;
						result.Moved += num3;
						hashSet2.Add(val2);
					}
				}
			}
			if (num > 0)
			{
				result.Leftover += num;
				if (flag)
				{
					result.LeftoverNoSpace += num;
				}
				else
				{
					result.LeftoverNoChest += num;
				}
			}
		}
		if (result.Moved > 0)
		{
			NotifyChanged(inventory);
		}
		result.Containers = hashSet2.Count;
		if (DepositAllPlugin.DebugLogging.Value)
		{
			DepositAllPlugin.Log.LogInfo((object)($"[DepositAll] 分发完成:moved={result.Moved}, leftover={result.Leftover}, " + $"usedContainers={result.Containers}, 范围内容器={list.Count}"));
		}
		return result;
	}

	private static int MoveInto(Inventory from, ItemData item, Inventory target, int amount)
	{
		int stack = item.m_stack;
		if (stack <= 0)
		{
			return 0;
		}
		int num = Mathf.Min(amount, stack);
		if (num <= 0)
		{
			return 0;
		}
		try
		{
			if (!from.GetAllItems().Contains(item))
			{
				return 0;
			}
		}
		catch
		{
			return 0;
		}
		ItemData val;
		try
		{
			val = item.Clone();
		}
		catch (Exception ex)
		{
			DepositAllPlugin.Log.LogError((object)("[DepositAll] 复制物品失败:" + ex));
			return 0;
		}
		if (val == null)
		{
			return 0;
		}
		val.m_stack = num;
		val.m_equipped = false;
		string name = item.m_shared.m_name;
		int num2 = CountExact(target, name, item.m_quality, item.m_worldLevel);
		target.AddItem(val);
		int num3 = CountExact(target, name, item.m_quality, item.m_worldLevel) - num2;
		if (num3 <= 0)
		{
			return 0;
		}
		if (num3 > num)
		{
			num3 = num;
		}
		from.RemoveItem(item, num3);
		NotifyChanged(target);
		return num3;
	}

	private static int CountExact(Inventory inv, string name, int quality, int worldLevel)
	{
		int num = 0;
		List<ItemData> allItems = inv.GetAllItems();
		for (int i = 0; i < allItems.Count; i++)
		{
			ItemData val = allItems[i];
			if (val != null && !(val.m_shared.m_name != name) && val.m_quality == quality && val.m_worldLevel == worldLevel)
			{
				num += val.m_stack;
			}
		}
		return num;
	}

	private static void NotifyChanged(Inventory inv)
	{
		try
		{
			MChanged?.Invoke(inv, new object[2] { false, false });
		}
		catch
		{
		}
	}

	internal static string FormatResult(Result r)
	{
		string text = $"已分发 {r.Moved} 件到 {r.Containers} 个箱子";
		string text2 = $"Deposited {r.Moved} item(s) into {r.Containers} container(s)";
		if (r.Leftover > 0)
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			if (r.LeftoverNoChest > 0)
			{
				list.Add($"{r.LeftoverNoChest} 件没有对应分类的箱子");
				list2.Add($"{r.LeftoverNoChest} had no matching container");
			}
			if (r.LeftoverNoSpace > 0)
			{
				list.Add($"{r.LeftoverNoSpace} 件因箱子已满");
				list2.Add($"{r.LeftoverNoSpace} did not fit (full)");
			}
			if (list.Count == 0)
			{
				text += $",{r.Leftover} 件留在身上";
				text2 += $", {r.Leftover} kept in inventory";
			}
			else
			{
				text = text + "," + string.Join(",", list) + ",留在身上";
				text2 = text2 + ", " + string.Join(", ", list2) + ", kept in inventory";
			}
		}
		return Patches.L(text, text2);
	}
}
internal static class Patches
{
	private const string ButtonName = "DepositAllButton";

	private static GameObject _buttonGo;

	private static TMP_Text _label;

	private static Transform _anchor;

	public static void Apply(Harmony harmony)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		MethodInfo methodInfo = DepositAllPlugin.UpdateRecipeMethod ?? AccessTools.Method(typeof(InventoryGui), "UpdateRecipe", new Type[2]
		{
			typeof(Player),
			typeof(float)
		}, (Type[])null);
		if (methodInfo == null)
		{
			DepositAllPlugin.Log.LogError((object)"[DepositAll] 找不到 InventoryGui.UpdateRecipe,无法挂载按钮补丁");
			return;
		}
		harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Patches), "UpdateRecipe_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		DepositAllPlugin.Log.LogInfo((object)"[DepositAll] 已挂载补丁 InventoryGui.UpdateRecipe");
	}

	private static void UpdateRecipe_Postfix(InventoryGui __instance, Player player)
	{
		if (!DepositAllPlugin.Enabled.Value || !DepositAllPlugin.AddButton.Value || (Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null)
		{
			return;
		}
		EnsureButton(__instance);
		if ((Object)(object)_buttonGo == (Object)null)
		{
			return;
		}
		bool flag = true;
		if (_buttonGo.activeSelf != flag)
		{
			_buttonGo.SetActive(flag);
		}
		Button component = _buttonGo.GetComponent<Button>();
		if ((Object)(object)component != (Object)null)
		{
			bool flag2 = !((Character)player).IsTeleporting() && !((Character)player).IsDead();
			if (((Selectable)component).interactable != flag2)
			{
				((Selectable)component).interactable = flag2;
			}
		}
	}

	private static void EnsureButton(InventoryGui gui)
	{
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Expected O, but got Unknown
		if ((Object)(object)_buttonGo != (Object)null || (Object)(object)gui.m_craftButton == (Object)null)
		{
			return;
		}
		Transform transform = ((Component)gui.m_craftButton).transform;
		Transform parent = transform.parent;
		if ((Object)(object)parent == (Object)null)
		{
			return;
		}
		Transform val = parent.Find("DepositAllButton");
		if ((Object)(object)val != (Object)null)
		{
			_buttonGo = ((Component)val).gameObject;
			_label = ((Component)val).GetComponentInChildren<TMP_Text>(true);
			_anchor = transform;
			ApplyLabel();
			return;
		}
		GameObject val2;
		try
		{
			val2 = Object.Instantiate<GameObject>(((Component)transform).gameObject, parent);
		}
		catch (Exception ex)
		{
			DepositAllPlugin.Log.LogError((object)("[DepositAll] 创建界面按钮失败:" + ex));
			return;
		}
		((Object)val2).name = "DepositAllButton";
		val2.transform.SetSiblingIndex(transform.GetSiblingIndex() + 1);
		UITooltip component = val2.GetComponent<UITooltip>();
		if ((Object)(object)component != (Object)null)
		{
			Object.Destroy((Object)(object)component);
		}
		TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)componentInChildren).gameObject);
		}
		GameObject val3 = new GameObject("Label", new Type[1] { typeof(RectTransform) });
		val3.transform.SetParent(val2.transform, false);
		RectTransform component2 = val3.GetComponent<RectTransform>();
		component2.anchorMin = Vector2.zero;
		component2.anchorMax = Vector2.one;
		component2.offsetMin = Vector2.zero;
		component2.offsetMax = Vector2.zero;
		TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val4).fontSize = 18f;
		((Graphic)val4).color = Color.white;
		((Graphic)val4).raycastTarget = false;
		TMP_Text componentInChildren2 = ((Component)gui.m_craftButton).GetComponentInChildren<TMP_Text>(true);
		if ((Object)(object)componentInChildren2 != (Object)null)
		{
			((TMP_Text)val4).font = componentInChildren2.font;
			((TMP_Text)val4).fontSize = componentInChildren2.fontSize;
			((Graphic)val4).color = ((Graphic)componentInChildren2).color;
		}
		_label = (TMP_Text)(object)val4;
		Button component3 = val2.GetComponent<Button>();
		if ((Object)(object)component3 != (Object)null)
		{
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			((UnityEvent)component3.onClick).AddListener(new UnityAction(OnDepositClicked));
			((Selectable)component3).interactable = true;
		}
		else
		{
			DepositAllPlugin.Log.LogWarning((object)"[DepositAll] 克隆出的按钮对象上没有 Button 组件");
		}
		val2.AddComponent<DepositButtonPlacement>().Bind((RectTransform)(object)((transform is RectTransform) ? transform : null));
		RectTransform val5 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
		if ((Object)(object)val5 != (Object)null && (Object)(object)((Component)parent).GetComponent<LayoutGroup>() != (Object)null)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(val5);
		}
		_buttonGo = val2;
		_anchor = transform;
		ApplyLabel();
		try
		{
			LayoutGroup component4 = ((Component)parent).GetComponent<LayoutGroup>();
			LayoutGroup val6 = (((Object)(object)parent.parent != (Object)null) ? ((Component)parent.parent).GetComponent<LayoutGroup>() : null);
			DepositAllPlugin.Log.LogInfo((object)("[DepositAll] 已添加界面按钮:父节点=" + ((Object)parent).name + ",布局组=" + (((Object)(object)component4 != (Object)null) ? ((object)component4).GetType().Name : "无") + ",父父节点布局组=" + (((Object)(object)val6 != (Object)null) ? ((object)val6).GetType().Name : "无") + "," + $"兄弟数={parent.childCount},制作按钮兄弟序号={transform.GetSiblingIndex()}"));
		}
		catch (Exception ex2)
		{
			DepositAllPlugin.Log.LogWarning((object)("[DepositAll] 打印按钮布局信息失败:" + ex2.Message));
		}
	}

	private static void OnDepositClicked()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).IsDead())
		{
			return;
		}
		Distributor.Result r;
		try
		{
			r = Distributor.Run(localPlayer);
		}
		catch (Exception ex)
		{
			DepositAllPlugin.Log.LogError((object)("[DepositAll] 分发失败:" + ex));
			Message(L("分发失败,详见日志", "Deposit failed, see log"));
			return;
		}
		if (DepositAllPlugin.ShowMessage.Value)
		{
			if (!r.SawCandidates)
			{
				Message(L("附近没有可用的箱子", "No accessible containers nearby"));
			}
			else if (r.Moved <= 0 && r.Leftover > 0 && r.LeftoverNoChest == r.Leftover)
			{
				Message(L("附近箱子中没有对应分类,未分发任何物品", "No nearby container holds this kind of item"));
			}
			else if (r.Moved <= 0 && r.Leftover > 0)
			{
				Message(L("同类箱子已满,没有分发任何物品", "Matching containers are full, nothing was deposited"));
			}
			else if (r.Moved <= 0 && r.Leftover <= 0)
			{
				Message(L("身上没有可分发的物品", "Nothing to deposit"));
			}
			else
			{
				Message(Distributor.FormatResult(r));
			}
		}
	}

	internal static void ApplyLabel()
	{
		if (!((Object)(object)_label == (Object)null))
		{
			string text = ((DepositAllPlugin.ButtonLabel != null) ? DepositAllPlugin.ButtonLabel.Value : null);
			if (string.IsNullOrEmpty(text))
			{
				text = L("分发", "Deposit");
			}
			_label.text = text;
		}
	}

	internal static bool IsChinese()
	{
		try
		{
			Localization instance = Localization.instance;
			string text = ((instance != null) ? instance.GetSelectedLanguage() : null);
			return text == "Chinese" || text == "Chinese_Trad";
		}
		catch
		{
			return false;
		}
	}

	internal static string L(string zh, string en)
	{
		if (!IsChinese())
		{
			return en;
		}
		return zh;
	}

	internal static void Message(string msg)
	{
		try
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, msg, 0, (Sprite)null, false);
			}
		}
		catch
		{
		}
	}

	public static void Cleanup()
	{
		if ((Object)(object)_buttonGo != (Object)null)
		{
			Object.Destroy((Object)(object)_buttonGo);
		}
		_buttonGo = null;
		_label = null;
		_anchor = null;
	}
}
internal class DepositButtonPlacement : MonoBehaviour
{
	private RectTransform _self;

	private RectTransform _target;

	private bool _sized;

	private const float GapY = 4f;

	public void Bind(RectTransform target)
	{
		ref RectTransform self = ref _self;
		Transform transform = ((Component)this).transform;
		self = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		_target = target;
	}

	private void LateUpdate()
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: 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)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_self == (Object)null || (Object)(object)_target == (Object)null)
		{
			return;
		}
		Transform parent = ((Transform)_self).parent;
		bool num = (Object)(object)parent != (Object)null && (Object)(object)((Component)parent).GetComponent<LayoutGroup>() != (Object)null;
		if (!_sized)
		{
			_self.sizeDelta = _target.sizeDelta;
			_self.anchorMin = _target.anchorMin;
			_self.anchorMax = _target.anchorMax;
			_self.pivot = _target.pivot;
			_sized = true;
		}
		if (!num)
		{
			Rect rect = _target.rect;
			float num2;
			if (!(((Rect)(ref rect)).height > 1f))
			{
				num2 = _target.sizeDelta.y;
			}
			else
			{
				rect = _target.rect;
				num2 = ((Rect)(ref rect)).height;
			}
			float num3 = num2;
			if (!(num3 <= 1f))
			{
				_self.anchoredPosition = new Vector2(_target.anchoredPosition.x, _target.anchoredPosition.y - num3 - 4f);
			}
		}
	}
}