Decompiled source of PeakCustomItemMod v1.10.30

BepInEx/plugins/createitem/PeakCustomItemMod.dll

Decompiled a week ago
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.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PEAKLib.Core;
using PEAKLib.Items;
using Peak.Afflictions;
using PeakCustomItemMod.Items;
using Photon.Pun;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakCustomItemMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PeakCustomItemMod")]
[assembly: AssemblyTitle("PeakCustomItemMod")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 PeakCustomItemMod
{
	internal static class ChineseDisplayNameIntegration
	{
		private static bool _patched;

		public static void Apply(ManualLogSource log)
		{
			try
			{
				if (!TryApply(log))
				{
					StartRetryer(log);
					log.LogInfo((object)"[中文物品名] PEAK_MENU_CN 尚未就绪,已启动延时重试挂载");
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[中文物品名] 挂载流程异常(不影响其它功能): " + ex.Message));
			}
		}

		internal static bool TryApply(ManualLogSource log)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			if (_patched)
			{
				return true;
			}
			try
			{
				Type type = AccessTools.TypeByName("P.E.A.K_MENU.Features.ItemSpawn.ItemCatalogService");
				if (type == null)
				{
					return false;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "ResolveDisplayName", new Type[1] { typeof(Item) }, (Type[])null);
				if (methodInfo == null)
				{
					log.LogWarning((object)"[中文物品名] 未找到 ResolveDisplayName(Item),跳过");
					return false;
				}
				Harmony val = new Harmony("Mr.PeakCustomItems.ChineseDisplayName");
				HarmonyMethod val2 = new HarmonyMethod(typeof(ResolveDisplayNamePatch).GetMethod("Prefix"));
				val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_patched = true;
				ForceRefreshCatalog(log);
				log.LogInfo((object)"[中文物品名] 已挂载:PEAK_MENU_CN 物品列表将优先显示中文");
				return true;
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[中文物品名] 单次挂载尝试失败(将重试): " + ex.Message));
				return false;
			}
		}

		private static void StartRetryer(ManualLogSource log)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("ChinesePatchRetryer");
				Object.DontDestroyOnLoad((Object)(object)val);
				ChinesePatchRetryer chinesePatchRetryer = val.AddComponent<ChinesePatchRetryer>();
				chinesePatchRetryer.Init(log);
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[中文物品名] 启动重试器失败(将放弃中文补丁): " + ex.Message));
			}
		}

		private static void ForceRefreshCatalog(ManualLogSource log)
		{
			try
			{
				Type type = AccessTools.TypeByName("P.E.A.K_MENU.Features.ItemSpawn.ItemSpawnRuntime");
				if (type == null)
				{
					return;
				}
				PropertyInfo propertyInfo = AccessTools.Property(type, "Catalog");
				if (propertyInfo == null || propertyInfo.GetGetMethod(nonPublic: true) == null)
				{
					return;
				}
				object value = propertyInfo.GetValue(null);
				if (value != null)
				{
					MethodInfo methodInfo = AccessTools.Method(value.GetType(), "ForceRefresh", (Type[])null, (Type[])null);
					if (!(methodInfo == null))
					{
						methodInfo.Invoke(value, null);
						log.LogInfo((object)"[中文物品名] 已强制刷新物品目录");
					}
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("[中文物品名] 强制刷新目录失败(可忽略): " + ex.Message));
			}
		}

		internal static void ForceRefreshOnce(ManualLogSource log)
		{
			ForceRefreshCatalog(log);
		}
	}
	internal class ChinesePatchRetryer : MonoBehaviour
	{
		private ManualLogSource _log;

		private int _attempts;

		private const int MaxAttempts = 60;

		public void Init(ManualLogSource log)
		{
			_log = log;
		}

		private IEnumerator Start()
		{
			while (_attempts < 60)
			{
				_attempts++;
				if (ChineseDisplayNameIntegration.TryApply(_log))
				{
					for (int i = 0; i < 10; i++)
					{
						ChineseDisplayNameIntegration.ForceRefreshOnce(_log);
						yield return (object)new WaitForSeconds(0.5f);
					}
					Object.Destroy((Object)(object)((Component)this).gameObject);
					yield break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			_log.LogWarning((object)"[中文物品名] 多次重试仍未找到 PEAK_MENU_CN,放弃中文补丁(不影响其它功能)");
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	internal static class ResolveDisplayNamePatch
	{
		public static bool Prefix(Item item, ref string __result)
		{
			try
			{
				if ((Object)(object)item != (Object)null)
				{
					string name = ((Object)item).name;
					if (!string.IsNullOrEmpty(name) && ChineseNameMap.Map.TryGetValue(name, out string value))
					{
						__result = value;
						return false;
					}
					string name2 = item.GetName();
					if (!string.IsNullOrEmpty(name2) && !name2.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase))
					{
						__result = name2;
						return false;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = CustomItemsPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[中文物品名] 解析物品名异常: " + ex.Message));
				}
			}
			return true;
		}
	}
	internal static class ChineseNameMap
	{
		public static readonly Dictionary<string, string> Map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "AK", "AK 突击步枪" },
			{ "Apple Berry Weird", "怪味苹果莓" },
			{ "ClimbingChalk", "攀岩粉" },
			{ "Cure-Some", "缓和药剂" },
			{ "Darkberry", "暗莓" },
			{ "Energy Elixir", "能量精油" },
			{ "Lollipop_Evil", "邪糖果" },
			{ "Matchbook", "火柴盒" },
			{ "Painkillers", "止痛药" },
			{ "Skyberry", "天空莓" },
			{ "Wand of Wind", "风之杖" },
			{ "Warpsketball", "传送篮球" },
			{ "Wonderberry", "奇幻莓" },
			{ "WildDogMilk", "野生狗奶" }
		};
	}
	[BepInPlugin("Mr.PeakCustomItems", "刘泽铭的奇思妙想", "1.10.30")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CustomItemsPlugin : BaseUnityPlugin
	{
		private ItemConfig _config = new ItemConfig();

		private bool _registered;

		private bool _spawned;

		private float _nextCheck = 2f;

		internal static ManualLogSource Log { get; private set; } = null;

		public static ModDefinition Definition { get; private set; } = null;

		public static string PluginDirectory { get; private set; } = "";

		private void Awake()
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Definition = ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info.Metadata);
			PluginDirectory = Path.GetDirectoryName(typeof(CustomItemsPlugin).Assembly.Location) ?? Paths.PluginPath;
			_config = ItemConfigLoader.LoadAll(PluginDirectory);
			if (_config.items.Length == 0)
			{
				Log.LogWarning((object)"没有找到任何物品配置,已生成示例物品(野生狗奶)");
				ItemConfigLoader.WriteExampleFolder(Path.Combine(PluginDirectory, "WildDogMilk"));
				_config = ItemConfigLoader.LoadAll(PluginDirectory);
			}
			ManualLogSource log = Log;
			string pluginDirectory = PluginDirectory;
			ItemConfigEntry[] items = _config.items;
			log.LogInfo((object)$"刘泽铭的奇思妙想 已加载(DLL: {pluginDirectory},配置条目数: {((items != null) ? items.Length : 0)})");
			try
			{
				GameObject val = new GameObject("PeakCustomItemEditor");
				val.AddComponent<ItemEditorUI>();
				Object.DontDestroyOnLoad((Object)(object)val);
				Log.LogInfo((object)"已加载游戏内物品编辑器(按 F11 开关)");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("游戏内编辑器初始化失败(不影响其他功能): " + ex.Message));
			}
			try
			{
				GameObject val2 = new GameObject("PetrifyBombManager");
				val2.AddComponent<PetrifyBombManager>();
				Object.DontDestroyOnLoad((Object)(object)val2);
			}
			catch (Exception ex2)
			{
				Log.LogWarning((object)("石化炸弹管理器初始化失败: " + ex2.Message));
			}
			try
			{
				ChineseDisplayNameIntegration.Apply(Log);
			}
			catch (Exception ex3)
			{
				Log.LogWarning((object)("中文物品名显示集成失败(不影响其它功能): " + ex3.Message));
			}
		}

		private void Update()
		{
			if (Time.unscaledTime < _nextCheck)
			{
				return;
			}
			_nextCheck = Time.unscaledTime + 2f;
			if (!_registered)
			{
				try
				{
					TryRegisterItems();
					return;
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"注册物品失败: {arg}");
					return;
				}
			}
			if (!_spawned)
			{
				TrySpawnCustomItems();
			}
		}

		private void TryRegisterItems()
		{
			if (_registered)
			{
				return;
			}
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			if ((Object)(object)instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects == null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count == 0)
			{
				Log.LogInfo((object)"ItemDatabase 尚未就绪,等待...");
				return;
			}
			int num = ConfigItemRegistry.RegisterFromConfig(_config, Definition);
			_registered = num > 0;
			Log.LogInfo((object)$"配置驱动注册完成:成功 {num} 个道具");
			if (num <= 0)
			{
				return;
			}
			foreach (ItemConfigEntry registeredEntry in ConfigItemRegistry.RegisteredEntries)
			{
				bool flag = string.IsNullOrWhiteSpace(registeredEntry.texture) && string.IsNullOrWhiteSpace(registeredEntry.icon);
				if (registeredEntry.dumpTemplateTexture || flag)
				{
					((MonoBehaviour)this).StartCoroutine(DumpTemplateDelayed(registeredEntry));
				}
			}
		}

		private void TrySpawnCustomItems()
		{
			if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient)
			{
				Log.LogInfo((object)"联机且非房主,不生成(等房主同步)");
				_spawned = true;
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				Log.LogInfo((object)"本地角色尚未出生,等待...");
			}
			else
			{
				SpawnCustomItems(localCharacter);
			}
		}

		private void SpawnCustomItems(Character player)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			//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_01bf: 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_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			List<ItemConfigEntry> registeredEntries = ConfigItemRegistry.RegisteredEntries;
			int num = 0;
			foreach (ItemConfigEntry item in registeredEntries)
			{
				if (item.spawn)
				{
					num++;
				}
			}
			if (num == 0)
			{
				Log.LogInfo((object)"配置中没有需要生成的道具");
				_spawned = true;
				return;
			}
			Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * 2f + Vector3.up * 0.5f;
			int num2 = 0;
			foreach (ItemConfigEntry item2 in registeredEntries)
			{
				if (!item2.spawn)
				{
					continue;
				}
				float num3 = item2.spawnChance ?? 100f;
				if (num3 <= 0f)
				{
					continue;
				}
				if (num3 < 100f && Random.Range(0f, 100f) > num3)
				{
					Log.LogInfo((object)$"{item2.name}: 未触发生成(概率 {num3:0.#}%)");
					continue;
				}
				string text = item2.runtimePrefabId;
				if (string.IsNullOrEmpty(text))
				{
					text = "0_Items/" + item2.name;
				}
				if (!NetworkPrefabManager.HasNetworkPrefab(text))
				{
					Log.LogWarning((object)("网络预制体不存在: " + text + ",跳过生成"));
					continue;
				}
				float num4 = ((float)num2 - (float)(num - 1) / 2f) * 1.1f;
				NetworkPrefabManager.SpawnNetworkPrefab(text, val + new Vector3(num4, 0f, 0f), Quaternion.identity, (byte)0, (object[])null);
				num2++;
			}
			_spawned = true;
			Log.LogInfo((object)$"已在玩家面前生成 {num2} 个自定义道具");
		}

		private IEnumerator DumpTemplateDelayed(ItemConfigEntry entry)
		{
			if ((Object)(object)entry.templateGo == (Object)null)
			{
				Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 模板引用为空,跳过"));
				yield break;
			}
			Texture2D src = null;
			Texture2D iconSrc = null;
			GameObject go = Object.Instantiate<GameObject>(entry.templateGo);
			if ((Object)(object)go != (Object)null)
			{
				go.SetActive(true);
				Log.LogInfo((object)(entry.name + ": dumpTemplateTexture 已实例化模板(" + entry.templateValue + "),轮询等待流式贴图加载..."));
				Item tmplItem = go.GetComponent<Item>();
				for (int i = 0; i < 10; i++)
				{
					if (!((Object)(object)src == (Object)null) && !((Object)(object)iconSrc == (Object)null))
					{
						break;
					}
					yield return (object)new WaitForSeconds(1f);
					if ((Object)(object)src == (Object)null)
					{
						src = ConfigItemRegistry.GrabTemplateTexture(tmplItem);
					}
					if ((Object)(object)iconSrc == (Object)null)
					{
						iconSrc = ConfigItemRegistry.GrabTemplateIcon(tmplItem);
					}
				}
				if ((Object)(object)src == (Object)null)
				{
					Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 实例化克隆未抓到 3D 贴图"));
					ConfigItemRegistry.LogTextureDiag(tmplItem, entry.name);
				}
				else
				{
					Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从实例化克隆抓到 3D 贴图 {((Texture)src).width}x{((Texture)src).height}");
				}
				if ((Object)(object)iconSrc != (Object)null)
				{
					Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从实例化克隆抓到物品栏图标 {((Texture)iconSrc).width}x{((Texture)iconSrc).height}");
				}
				else
				{
					Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 实例化克隆未抓到物品栏图标(UIData.icon 为空或尚未加载)"));
				}
				Object.Destroy((Object)(object)go);
			}
			if ((Object)(object)src == (Object)null || (Object)(object)iconSrc == (Object)null)
			{
				Log.LogInfo((object)(entry.name + ": dumpTemplateTexture 改从世界里的真实" + entry.templateValue + "抓取(请用菜单生成一个" + entry.templateValue + ",或等待其自然生成)"));
				for (int j = 0; j < 8; j++)
				{
					Item live = FindLiveTemplateItem(entry);
					if ((Object)(object)live != (Object)null)
					{
						if ((Object)(object)src == (Object)null)
						{
							src = ConfigItemRegistry.GrabTemplateTexture(live);
							if ((Object)(object)src != (Object)null)
							{
								Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从世界生成物抓到 3D 贴图 {((Texture)src).width}x{((Texture)src).height}");
							}
						}
						if ((Object)(object)iconSrc == (Object)null)
						{
							iconSrc = ConfigItemRegistry.GrabTemplateIcon(live);
							if ((Object)(object)iconSrc != (Object)null)
							{
								Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从世界生成物抓到物品栏图标 {((Texture)iconSrc).width}x{((Texture)iconSrc).height}");
							}
						}
						if ((Object)(object)src != (Object)null && (Object)(object)iconSrc != (Object)null)
						{
							break;
						}
					}
					yield return (object)new WaitForSeconds(1f);
				}
				if ((Object)(object)src == (Object)null)
				{
					ConfigItemRegistry.LogTextureDiag(FindLiveTemplateItem(entry), entry.name);
				}
			}
			entry.templateTexture = src;
			entry.templateIconTex = iconSrc;
			if (entry.dumpTemplateTexture && (Object)(object)src == (Object)null && (Object)(object)iconSrc != (Object)null)
			{
				Log.LogInfo((object)(entry.name + ": 3D 贴图抓取失败(模板可能是纯色/程序化材质),用物品栏图标代替导出为模板源"));
				src = iconSrc;
				entry.templateTexture = iconSrc;
			}
			if (entry.dumpTemplateTexture)
			{
				if ((Object)(object)src != (Object)null)
				{
					ConfigItemRegistry.DumpTemplateTexture(src, entry, entry.configDir ?? PluginDirectory);
				}
				if ((Object)(object)iconSrc != (Object)null)
				{
					ConfigItemRegistry.DumpTemplateIcon(iconSrc, entry, entry.configDir ?? PluginDirectory);
				}
			}
			if ((Object)(object)src != (Object)null)
			{
				if ((Object)(object)entry.runtimeItem != (Object)null)
				{
					ConfigItemRegistry.ApplyTemplateTextureToItem(entry.runtimeItem, entry);
				}
				ApplyTemplateTextureToLiveInstances(entry);
			}
			if ((Object)(object)src == (Object)null && (Object)(object)iconSrc == (Object)null)
			{
				Log.LogWarning((object)(entry.name + ": 模板贴图抓取两种来源都没抓到" + entry.templateValue + "的原生贴图/图标(继承模式将缺 3D 贴图)"));
			}
		}

		private void ApplyTemplateTextureToLiveInstances(ItemConfigEntry entry)
		{
			if ((Object)(object)entry.templateTexture == (Object)null)
			{
				return;
			}
			try
			{
				Item[] array = Object.FindObjectsOfType<Item>();
				Item[] array2 = array;
				foreach (Item val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						GameObject gameObject = ((Component)val).gameObject;
						string text = ((gameObject != null) ? ((Object)gameObject).name : null) ?? "";
						if (text.IndexOf(entry.name, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							ConfigItemRegistry.ApplyTemplateTextureToItem(val, entry);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)(entry.name + ": 套用模板贴图到场上实例失败: " + ex.Message));
			}
		}

		private Item? FindLiveTemplateItem(ItemConfigEntry entry)
		{
			try
			{
				Item[] array = Object.FindObjectsOfType<Item>();
				string text = (entry.templateValue ?? "").Trim();
				string text2 = text.ToLowerInvariant();
				Item[] array2 = array;
				foreach (Item val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						string a = val.UIData?.itemName ?? "";
						GameObject gameObject = ((Component)val).gameObject;
						string text3 = ((gameObject != null) ? ((Object)gameObject).name : null) ?? "";
						if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase) || string.Equals(text3, text, StringComparison.OrdinalIgnoreCase) || (text2.Contains("sports") && text3.IndexOf("sports", StringComparison.OrdinalIgnoreCase) >= 0))
						{
							return val;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)(entry.name + ": 查找世界里的" + entry.templateValue + "失败: " + ex.Message));
			}
			return null;
		}
	}
}
namespace PeakCustomItemMod.Items
{
	public class AllyBuffRpc : MonoBehaviour
	{
		private static readonly HashSet<int> _explodedViewIds = new HashSet<int>();

		private const float ExplosionKnockbackMultiplier = 2f;

		private const float ExplosionVertKnockbackAdd = 18f;

		[PunRPC]
		public void ApplyAllyBuffs(Vector3 origin, float radius, string buffsJoined, float time)
		{
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null || localCharacter.data.dead || !(Vector3.Distance(((Component)localCharacter).transform.position, origin) <= radius))
				{
					return;
				}
				string[] array = buffsJoined.Split(',');
				foreach (string text in array)
				{
					if (!string.IsNullOrWhiteSpace(text) && Enum.TryParse<AfflictionType>(text.Trim(), ignoreCase: true, out AfflictionType result))
					{
						Affliction val = Affliction.CreateBlankAffliction(result);
						if (val != null)
						{
							val.totalTime = Mathf.Max(0.1f, time);
							localCharacter.refs.afflictions.AddAffliction(val, false);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PeakCustomItem] AllyBuff RPC 处理失败: " + ex.Message));
			}
		}

		public static void BroadcastExplode(Vector3 pos, int itemViewId)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameUtils instance = GameUtils.instance;
				if (!((Object)(object)instance == (Object)null))
				{
					AllyBuffRpc allyBuffRpc = ((Component)instance).gameObject.GetComponent<AllyBuffRpc>() ?? ((Component)instance).gameObject.AddComponent<AllyBuffRpc>();
					if ((Object)(object)((MonoBehaviourPun)instance).photonView != (Object)null)
					{
						((MonoBehaviourPun)instance).photonView.RPC("WildDogMilkExplode", (RpcTarget)0, new object[2] { pos, itemViewId });
					}
					else
					{
						allyBuffRpc.ExplodeLocal(pos, itemViewId);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶爆炸广播失败: " + ex.Message));
			}
		}

		[PunRPC]
		public void WildDogMilkExplode(Vector3 pos, int itemViewId)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (itemViewId < 0 || _explodedViewIds.Add(itemViewId))
			{
				SpawnExplosion(pos);
				ConsumeItem(itemViewId);
			}
		}

		public void ExplodeLocal(Vector3 pos, int itemViewId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			SpawnExplosion(pos);
			ConsumeItem(itemViewId);
		}

		private void ConsumeItem(int itemViewId)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (itemViewId < 0)
			{
				return;
			}
			try
			{
				PhotonView val = PhotonView.Find(itemViewId);
				Item val2 = ((val != null) ? ((Component)val).GetComponent<Item>() : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)val2)
					{
						Player.localPlayer.EmptySlot(Character.localCharacter.refs.items.currentSelectedSlot);
					}
					val2.ClearDataFromBackpack();
					if ((Object)(object)((MonoBehaviourPun)val2).photonView != (Object)null && (((MonoBehaviourPun)val2).photonView.IsMine || PhotonNetwork.IsMasterClient))
					{
						PhotonNetwork.Destroy(((Component)val2).gameObject);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶消耗失败: " + ex.Message));
			}
		}

		private void SpawnExplosion(Vector3 pos)
		{
			//IL_0015: 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)
			//IL_004d: 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)
			try
			{
				GameObject nativeExplosionPrefab = ConfigItemRegistry.GetNativeExplosionPrefab();
				if ((Object)(object)nativeExplosionPrefab != (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(nativeExplosionPrefab, pos, Quaternion.identity);
					AmplifyAoeKnockback(val);
					Object.Destroy((Object)(object)val, 4f);
					return;
				}
				GameObject orBuildAoeExplosionPrefab = ConfigItemRegistry.GetOrBuildAoeExplosionPrefab();
				if ((Object)(object)orBuildAoeExplosionPrefab != (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(orBuildAoeExplosionPrefab, pos, Quaternion.identity);
					AmplifyAoeKnockback(val2);
					Object.Destroy((Object)(object)val2, 2f);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PeakCustomItem] 爆炸实例化失败: " + ex.Message));
			}
		}

		private static void AmplifyAoeKnockback(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				AOE[] componentsInChildren = go.GetComponentsInChildren<AOE>();
				foreach (AOE val in componentsInChildren)
				{
					val.knockback *= 2f;
					val.additionalVerticalKnockback += 18f;
				}
			}
		}
	}
	public static class ConfigItemRegistry
	{
		private static readonly HashSet<string> _dumpedTemplates = new HashSet<string>();

		private static readonly HashSet<string> _dumpedIcons = new HashSet<string>();

		private static GameObject _nativeExplosionPrefab;

		private static GameObject _dynamiteExplosionPrefab;

		private static bool _dbSearched;

		private static GameObject _aoeExplosionPrefab;

		public static List<ItemConfigEntry> RegisteredEntries { get; } = new List<ItemConfigEntry>();

		public static int RegisterFromConfig(ItemConfig config, ModDefinition definition)
		{
			RegisteredEntries.Clear();
			int num = 0;
			ItemConfigEntry[] items = config.items;
			foreach (ItemConfigEntry itemConfigEntry in items)
			{
				if (string.IsNullOrWhiteSpace(itemConfigEntry.name))
				{
					CustomItemsPlugin.Log.LogWarning((object)"配置里有个条目的 name 为空,已跳过");
					continue;
				}
				if (string.IsNullOrWhiteSpace(itemConfigEntry.displayName))
				{
					itemConfigEntry.displayName = itemConfigEntry.name;
				}
				try
				{
					Item val = FindTemplate(itemConfigEntry);
					if ((Object)(object)val == (Object)null)
					{
						CustomItemsPlugin.Log.LogWarning((object)(itemConfigEntry.name + ": 没有找到模板 (match=" + itemConfigEntry.templateMatch + ", value=" + itemConfigEntry.templateValue + "),已跳过"));
					}
					else
					{
						RegisterClone(val, itemConfigEntry, definition);
						RegisteredEntries.Add(itemConfigEntry);
						num++;
					}
				}
				catch (Exception arg)
				{
					CustomItemsPlugin.Log.LogError((object)$"{itemConfigEntry.name}: 注册失败: {arg}");
				}
			}
			if (num > 0 && LootData.AllSpawnWeightData != null)
			{
				LootData.PopulateLootData();
				CustomItemsPlugin.Log.LogInfo((object)"已重建 LootData 世界生成概率表,自定义物品按模板稀有度/生成池参与自然生成");
				VerifyNaturalSpawn();
			}
			if (num > 0)
			{
				EnsurePeakLibPrefabPool();
			}
			return num;
		}

		private static void EnsurePeakLibPrefabPool()
		{
			try
			{
				MethodInfo method = typeof(NetworkPrefabManager).GetMethod("Initialize", BindingFlags.Static | BindingFlags.NonPublic);
				if (method == null)
				{
					CustomItemsPlugin.Log.LogWarning((object)"未找到 NetworkPrefabManager.Initialize(PEAKLib 版本不兼容?),跳过网络生成池初始化");
					return;
				}
				method.Invoke(null, null);
				CustomItemsPlugin.Log.LogInfo((object)"Photon 网络生成池已切换为 PEAKLib CustomPrefabPool,自定义物品可正常网络生成");
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)("初始化 PEAKLib 网络生成池失败(不影响注册/注入/自然生成): " + ex.Message));
			}
		}

		private static Item? FindTemplate(ItemConfigEntry entry)
		{
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Invalid comparison between Unknown and I4
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Invalid comparison between Unknown and I4
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			List<Item> list = new List<Item>();
			if (instance.itemLookup != null)
			{
				list.AddRange(instance.itemLookup.Values);
			}
			if (((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects != null)
			{
				list.AddRange(((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects);
			}
			list = list.Where((Item i) => (Object)(object)i != (Object)null).Distinct().ToList();
			string value = entry.templateValue?.Trim() ?? "";
			switch ((entry.templateMatch ?? "").Trim().ToLowerInvariant())
			{
			case "exact":
				foreach (Item item in list)
				{
					if (ItemName(item).Equals(value, StringComparison.OrdinalIgnoreCase) || ((Object)(object)((Component)item).gameObject != (Object)null && ((Object)((Component)item).gameObject).name.Equals(value, StringComparison.OrdinalIgnoreCase)))
					{
						return item;
					}
				}
				break;
			case "tag":
			{
				if (!Enum.TryParse<ItemTags>(value, ignoreCase: true, out ItemTags result) || (int)result <= 0)
				{
					break;
				}
				foreach (Item item2 in list)
				{
					if ((item2.itemTags & result) > 0)
					{
						return item2;
					}
				}
				break;
			}
			default:
				foreach (Item item3 in list)
				{
					string text = ItemName(item3);
					if (text.Contains(value, StringComparison.OrdinalIgnoreCase) || ((Object)(object)((Component)item3).gameObject != (Object)null && ((Object)((Component)item3).gameObject).name.Contains(value, StringComparison.OrdinalIgnoreCase)))
					{
						return item3;
					}
				}
				break;
			}
			return null;
		}

		private static string ItemName(Item item)
		{
			try
			{
				if (item.UIData != null && !string.IsNullOrEmpty(item.UIData.itemName))
				{
					return item.UIData.itemName;
				}
			}
			catch
			{
			}
			return ((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : "";
		}

		public static Item RegisterClone(Item template, ItemConfigEntry entry, ModDefinition definition)
		{
			//IL_0175: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Invalid comparison between Unknown and I4
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Invalid comparison between Unknown and I4
			//IL_00f7: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject);
			((Object)val).name = entry.name;
			Object.DontDestroyOnLoad((Object)(object)val);
			Item component = val.GetComponent<Item>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("模板 " + ((Object)template).name + " 上没有 Item 组件");
			}
			if (component.UIData == null)
			{
				component.UIData = new ItemUIData();
			}
			component.UIData.itemName = entry.displayName;
			RegisterNameLocalization(entry);
			if (entry.tags != null && entry.tags.Length != 0)
			{
				ItemTags val2 = (ItemTags)0;
				string[] tags = entry.tags;
				foreach (string value in tags)
				{
					if (Enum.TryParse<ItemTags>(value, ignoreCase: true, out ItemTags result) && (int)result > 0)
					{
						val2 |= result;
					}
				}
				if ((int)val2 > 0)
				{
					component.itemTags = val2;
				}
			}
			ApplyLook(component, template, entry);
			try
			{
				if ((Object)(object)((Component)component).gameObject.GetComponent<RuntimeLookApplier>() == (Object)null)
				{
					((Component)component).gameObject.AddComponent<RuntimeLookApplier>().entry = entry;
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 运行时贴图组件挂载失败: " + ex.Message));
			}
			ApplyActionsAndCooking(component, entry);
			ApplyUses(component, entry);
			ApplyPetrifyBomb(component, entry);
			new ItemContent(component).Register(definition);
			ApplySpawnChance(component, template, entry);
			entry.runtimePrefabId = "0_Items/" + ((Object)((Component)component).gameObject).name;
			CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 网络预制体 = " + entry.runtimePrefabId));
			InjectToItemDatabase(SingletonAsset<ItemDatabase>.Instance, component, definition, entry.name);
			PeakMenuIntegrator.AddToVisibleItems(entry);
			entry.runtimeItem = component;
			CustomItemsPlugin.Log.LogInfo((object)$"已注册新道具: {entry.name} (显示名: {entry.displayName}, 标签: {component.itemTags}, 模板: {((Object)template).name})");
			return component;
		}

		private static void InjectToItemDatabase(ItemDatabase? db, Item item, ModDefinition definition, string entryName)
		{
			if ((Object)(object)db == (Object)null || db.itemLookup == null || ((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects == null)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entryName + ": ItemDatabase 未就绪,跳过注入"));
				return;
			}
			if (db.itemLookup.ContainsValue(item) || ((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects.Contains(item))
			{
				CustomItemsPlugin.Log.LogInfo((object)(entryName + ": 已在 ItemDatabase 中,跳过注入"));
				return;
			}
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(definition.Id + ((Object)((Component)item).gameObject).name));
			ushort num = BitConverter.ToUInt16(value, 0);
			bool flag = db.itemLookup.ContainsKey(num);
			while (db.itemLookup.ContainsKey(num))
			{
				num++;
			}
			item.itemID = num;
			((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects.Add(item);
			db.itemLookup.Add(num, item);
			CustomItemsPlugin.Log.LogInfo((object)(flag ? $"{entryName}: 已注入 ItemDatabase(itemID={num},与原物品冲突已顺延,当前共 {((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects.Count} 个物品)" : $"{entryName}: 已注入 ItemDatabase(itemID={num},当前共 {((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects.Count} 个物品)"));
		}

		private static void VerifyNaturalSpawn()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if (LootData.AllSpawnWeightData == null)
			{
				CustomItemsPlugin.Log.LogWarning((object)"自然生成验证:概率表尚未构建(进入一局后首次抽物品时才构建),跳过");
				return;
			}
			foreach (ItemConfigEntry registeredEntry in RegisteredEntries)
			{
				Item runtimeItem = registeredEntry.runtimeItem;
				if ((Object)(object)runtimeItem == (Object)null)
				{
					continue;
				}
				LootData component = ((Component)runtimeItem).GetComponent<LootData>();
				if ((Object)(object)component == (Object)null)
				{
					CustomItemsPlugin.Log.LogWarning((object)(registeredEntry.name + ": 无 LootData 组件 → 不参与世界自然生成(模板本身可能不进世界生成,属正常)"));
					continue;
				}
				List<string> list = new List<string>();
				foreach (KeyValuePair<SpawnPool, Dictionary<ushort, int>> allSpawnWeightDatum in LootData.AllSpawnWeightData)
				{
					if (allSpawnWeightDatum.Value.TryGetValue(runtimeItem.itemID, out var value))
					{
						list.Add($"{allSpawnWeightDatum.Key}(权重{value},占该池 {LootData.GetPercentageOdds(runtimeItem.itemID, allSpawnWeightDatum.Key):0.##}%)");
					}
				}
				if (list.Count == 0)
				{
					CustomItemsPlugin.Log.LogWarning((object)$"{registeredEntry.name}: ❌ 未出现在任何生成池!(itemID={runtimeItem.itemID},稀有度={component.Rarity},spawnLocations={component.spawnLocations})——模板可能本身不参与世界生成");
				}
				else
				{
					CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: ✅ 已确认进入世界生成表 (itemID={1},稀有度={2}) → {3}", registeredEntry.name, runtimeItem.itemID, component.Rarity, string.Join(";", list)));
				}
				try
				{
					bool flag = runtimeItem.IsValidToSpawn();
					CustomItemsPlugin.Log.LogInfo((object)(flag ? (registeredEntry.name + ": IsValidToSpawn(当前环境)=True,可被世界生成器抽取") : (registeredEntry.name + ": IsValidToSpawn(当前环境)=False(如 banInSolo 单人局或运行设置禁用),进局后视设置而定")));
				}
				catch (Exception ex)
				{
					CustomItemsPlugin.Log.LogWarning((object)(registeredEntry.name + ": IsValidToSpawn 判定失败(环境未就绪): " + ex.Message));
				}
			}
		}

		private static void ApplySpawnChance(Item item, Item template, ItemConfigEntry entry)
		{
			//IL_005b: 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)
			if (entry.spawnChance.HasValue)
			{
				entry.spawnChance = Mathf.Clamp(entry.spawnChance.Value, 0f, 100f);
				return;
			}
			LootData val = ((Component)item).GetComponent<LootData>() ?? ((Component)template).GetComponent<LootData>();
			if ((Object)(object)val != (Object)null && LootData.RarityWeights.TryGetValue(val.Rarity, out var value))
			{
				entry.spawnChance = value;
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: spawnChance 未配置,沿用模板({((Object)template).name})生成概率 = {value}(稀有度 {val.Rarity})");
			}
			else
			{
				entry.spawnChance = 100f;
				CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": spawnChance 未配置且模板(" + ((Object)template).name + ")无 LootData,默认 100(必出)"));
			}
		}

		internal static void ApplyLook(Item item, Item template, ItemConfigEntry entry)
		{
			string text = (string.IsNullOrEmpty(entry.configDir) ? CustomItemsPlugin.PluginDirectory : entry.configDir);
			try
			{
				entry.templateGo = ((Component)template).gameObject;
			}
			catch
			{
			}
			if (!string.IsNullOrWhiteSpace(entry.texture) || !string.IsNullOrWhiteSpace(entry.icon))
			{
				ApplyLookTextures(item, entry);
				return;
			}
			if (item.UIData != null && template.UIData != null && (Object)(object)template.UIData.icon != (Object)null)
			{
				item.UIData.icon = template.UIData.icon;
			}
			CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 贴图 = 继承模板材质 (" + ((Object)template).name + ")"));
		}

		internal static void ApplyLookTextures(Item item, ItemConfigEntry entry)
		{
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			string path = (string.IsNullOrEmpty(entry.configDir) ? CustomItemsPlugin.PluginDirectory : entry.configDir);
			if (!string.IsNullOrWhiteSpace(entry.icon))
			{
				string pngPath = Path.Combine(path, entry.icon);
				Texture2D val = TextureTools.LoadFromPng(pngPath);
				if ((Object)(object)val != (Object)null && item.UIData != null)
				{
					Texture2D icon = item.UIData.icon;
					if ((Object)(object)icon != (Object)null && ((Object)icon).name == Path.GetFileNameWithoutExtension(entry.icon))
					{
						Object.DestroyImmediate((Object)(object)icon);
					}
					item.UIData.icon = val;
				}
			}
			else if (!string.IsNullOrWhiteSpace(entry.texture))
			{
				string pngPath2 = Path.Combine(path, entry.texture);
				Texture2D val2 = TextureTools.LoadFromPng(pngPath2);
				if ((Object)(object)val2 != (Object)null && item.UIData != null)
				{
					item.UIData.icon = val2;
				}
			}
			if (string.IsNullOrWhiteSpace(entry.texture))
			{
				return;
			}
			string text = Path.Combine(path, entry.texture);
			Texture2D val3 = TextureTools.LoadFromPng(text);
			if ((Object)(object)val3 == (Object)null)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 贴图文件不存在或无法解析 " + text + ",无法应用"));
				return;
			}
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			string[] source = new string[10] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO", "_Texture1", "_Texture2", "_BaseColorMap", "_Albedo" };
			int num = 0;
			string text2 = null;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val4 in array)
			{
				if ((Object)(object)val4 == (Object)null)
				{
					continue;
				}
				Material material = val4.material;
				List<string> list = new List<string>();
				string[] texturePropertyNames = material.GetTexturePropertyNames();
				string[] array2 = texturePropertyNames;
				foreach (string text3 in array2)
				{
					if (source.Contains<string>(text3, StringComparer.OrdinalIgnoreCase) || (Object)(object)material.GetTexture(text3) != (Object)null)
					{
						list.Add(text3);
					}
				}
				if (list.Count == 0)
				{
					continue;
				}
				Texture texture = material.GetTexture(list[0]);
				Texture2D val5 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
				foreach (string item2 in list)
				{
					material.SetTexture(item2, (Texture)(object)val3);
				}
				if ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)val3 && ((Object)val5).name == Path.GetFileNameWithoutExtension(entry.texture))
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
				foreach (string item3 in list)
				{
					if (entry.textureOffset != null && entry.textureOffset.Length == 2)
					{
						material.SetTextureOffset(item3, new Vector2(entry.textureOffset[0], entry.textureOffset[1]));
					}
					if (entry.textureScale != null && entry.textureScale.Length == 2)
					{
						material.SetTextureScale(item3, new Vector2(entry.textureScale[0], entry.textureScale[1]));
					}
				}
				text2 = string.Join(",", list);
				num++;
			}
			if (num > 0)
			{
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 贴图 = {text},已替换 {num} 个渲染器的 {text2}");
			}
			else
			{
				CustomItemsPlugin.Log.LogWarning((object)$"{entry.name}: 贴图 = {text} 已加载,但没有渲染器可替换(共 {componentsInChildren.Length} 个渲染器均未命中主纹理属性)");
			}
		}

		internal static Texture2D? GrabTemplateTexture(Item? item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			string[] array = new string[16]
			{
				"_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO", "_BaseColorMap", "_AlbedoMap", "_Diffuse", "_DiffuseMap",
				"_ColorMap", "_MainTex_ST", "_MaskMap", "_BaseMap_ST", "_MainTex2", "_MainTex3"
			};
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material material = val.material;
				string[] array3 = array;
				foreach (string text in array3)
				{
					if (material.HasProperty(text))
					{
						Texture texture = material.GetTexture(text);
						Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
						if (val2 != null && ((Texture)val2).width > 0 && ((Texture)val2).height > 0)
						{
							return val2;
						}
					}
				}
			}
			return null;
		}

		internal static Texture2D? GrabTemplateIcon(Item? item)
		{
			if ((Object)(object)item == (Object)null || item.UIData == null)
			{
				return null;
			}
			Texture2D icon = item.UIData.icon;
			if (icon != null && ((Texture)icon).width > 0 && ((Texture)icon).height > 0)
			{
				return icon;
			}
			return null;
		}

		internal static void ApplyTemplateTextureToItem(Item item, ItemConfigEntry entry)
		{
			if ((Object)(object)item == (Object)null || entry == null || (Object)(object)entry.templateTexture == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" };
			int num = 0;
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material material = val.material;
				string text = null;
				string[] array3 = array;
				foreach (string text2 in array3)
				{
					if (material.HasProperty(text2))
					{
						text = text2;
						break;
					}
				}
				if (text != null)
				{
					material.SetTexture(text, (Texture)(object)entry.templateTexture);
					num++;
				}
			}
			if (num > 0)
			{
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 继承模式已把模板 3D 贴图套到 {num} 个渲染器");
			}
		}

		internal static void LogTextureDiag(Item? item, string entryName)
		{
			if ((Object)(object)item == (Object)null)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entryName + ": dumpTemplateTexture 诊断——物品为 null"));
				return;
			}
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" };
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"{entryName}: dumpTemplateTexture 诊断——共 {componentsInChildren.Length} 个渲染器:");
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material material = val.material;
				List<string> list = new List<string>();
				string[] array3 = array;
				foreach (string text in array3)
				{
					if (material.HasProperty(text))
					{
						Texture texture = material.GetTexture(text);
						object obj;
						if (!((Object)(object)texture == (Object)null))
						{
							Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
							obj = ((val2 != null) ? $"{((Texture)val2).width}x{((Texture)val2).height}" : ((object)texture).GetType().Name);
						}
						else
						{
							obj = "null";
						}
						string text2 = (string)obj;
						list.Add(text + "=" + text2);
					}
				}
				string[] obj2 = new string[7]
				{
					" [",
					((Object)val).name,
					"/",
					null,
					null,
					null,
					null
				};
				Shader shader = material.shader;
				obj2[3] = ((shader != null) ? ((Object)shader).name : null);
				obj2[4] = ":";
				obj2[5] = ((list.Count == 0) ? "无主纹理属性" : string.Join(",", list));
				obj2[6] = "]";
				stringBuilder.Append(string.Concat(obj2));
			}
			CustomItemsPlugin.Log.LogWarning((object)stringBuilder.ToString());
		}

		private static bool ReadbackToPng(Texture2D src, string outPath)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			int width = ((Texture)src).width;
			int height = ((Texture)src).height;
			RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit((Texture)(object)src, temporary);
			Texture2D val = new Texture2D(width, height, (TextureFormat)5, false);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			File.WriteAllBytes(outPath, ImageConversion.EncodeToPNG(val));
			Object.Destroy((Object)(object)val);
			return true;
		}

		internal static void DumpTemplateTexture(Texture2D src, ItemConfigEntry entry, string dir)
		{
			if ((Object)(object)src == (Object)null || string.IsNullOrWhiteSpace(dir) || _dumpedTemplates.Contains(entry.name))
			{
				return;
			}
			try
			{
				string text = Path.Combine(dir, entry.name + "_template_source.png");
				ReadbackToPng(src, text);
				_dumpedTemplates.Add(entry.name);
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已导出模板原生贴图 -> {text} ({((Texture)src).width}x{((Texture)src).height})");
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 导出模板贴图失败: " + ex.Message));
			}
		}

		internal static void DumpTemplateIcon(Texture2D src, ItemConfigEntry entry, string dir)
		{
			if ((Object)(object)src == (Object)null || string.IsNullOrWhiteSpace(dir) || _dumpedIcons.Contains(entry.name))
			{
				return;
			}
			try
			{
				string text = Path.Combine(dir, entry.name + "_template_icon_source.png");
				ReadbackToPng(src, text);
				_dumpedIcons.Add(entry.name);
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已导出模板物品栏图标 -> {text} ({((Texture)src).width}x{((Texture)src).height})");
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 导出模板物品栏图标失败: " + ex.Message));
			}
		}

		public static void ApplyUvToItem(Item item, ItemConfigEntry entry)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0066: 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_007d: 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)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null || string.IsNullOrWhiteSpace(entry.texture))
			{
				return;
			}
			Vector2 val = (Vector2)((entry.textureOffset != null && entry.textureOffset.Length == 2) ? new Vector2(entry.textureOffset[0], entry.textureOffset[1]) : Vector2.zero);
			Vector2 val2 = (Vector2)((entry.textureScale != null && entry.textureScale.Length == 2) ? new Vector2(entry.textureScale[0], entry.textureScale[1]) : Vector2.one);
			string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" };
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer val3 in array2)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Material material = val3.material;
				string[] array3 = array;
				foreach (string text in array3)
				{
					if (material.HasProperty(text))
					{
						material.SetTextureOffset(text, val);
						material.SetTextureScale(text, val2);
						break;
					}
				}
			}
		}

		private static void RegisterNameLocalization(ItemConfigEntry entry)
		{
			try
			{
				string text = (string.IsNullOrEmpty(entry.displayName) ? entry.name : entry.displayName);
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				Dictionary<string, List<string>> mainTable = LocalizedText.mainTable;
				string key = "NAME_" + text.ToUpperInvariant();
				if (!mainTable.ContainsKey(key))
				{
					int num = 15;
					List<string> list = new List<string>(num);
					for (int i = 0; i < num; i++)
					{
						list.Add(text);
					}
					mainTable[key] = list;
					mainTable["DESC_" + text.ToUpperInvariant()] = list;
					CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已注册名称本地化 '" + text + "'(NAME_/DESC_ key),UI 不再显示 LOC: 前缀"));
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 名称本地化注入失败(不影响注册): " + ex.Message));
			}
		}

		public static void ApplyActionsAndCooking(Item item, ItemConfigEntry entry)
		{
			try
			{
				ItemCooking val = ((Component)item).GetComponent<ItemCooking>();
				List<string> removeBeh = new List<string>();
				if (entry.removeCookingBehaviors != null)
				{
					removeBeh.AddRange(entry.removeCookingBehaviors);
				}
				if (entry.cooking?.removeBehaviors != null)
				{
					removeBeh.AddRange(entry.cooking.removeBehaviors);
				}
				removeBeh = removeBeh.Where((string s) => !string.IsNullOrWhiteSpace(s)).ToList();
				if (removeBeh.Count > 0)
				{
					if ((Object)(object)val == (Object)null)
					{
						CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 配置要移除烹饪行为,但模板没有 ItemCooking 组件,跳过"));
					}
					else
					{
						AdditionalCookingBehavior[] array = val.additionalCookingBehaviors.Where((AdditionalCookingBehavior b) => b != null && !removeBeh.Contains<string>(((object)b).GetType().Name, StringComparer.OrdinalIgnoreCase)).ToArray();
						int num = val.additionalCookingBehaviors.Length - array.Length;
						if (num > 0)
						{
							val.additionalCookingBehaviors = array;
							CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已移除 {1} 个烹饪行为: {2}", entry.name, num, string.Join(",", removeBeh)));
						}
					}
				}
				if (entry.removeActions != null && entry.removeActions.Length != 0)
				{
					List<string> want = entry.removeActions.Where((string s) => !string.IsNullOrWhiteSpace(s)).ToList();
					if (want.Count > 0)
					{
						List<ItemAction> list = (from a in ((Component)item).GetComponents<ItemAction>()
							where (Object)(object)a != (Object)null && want.Contains<string>(((object)a).GetType().Name, StringComparer.OrdinalIgnoreCase)
							select a).ToList();
						foreach (ItemAction item3 in list)
						{
							Object.Destroy((Object)(object)item3);
						}
						if (list.Count > 0)
						{
							CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已移除 {1} 个食用动作: {2}", entry.name, list.Count, string.Join(",", list.Select((ItemAction d) => ((object)d).GetType().Name))));
						}
					}
				}
				if (entry.addActions != null && entry.addActions.Length != 0)
				{
					int num2 = 0;
					HashSet<string> hashSet = (from a in ((Component)item).GetComponents<ItemAction>()
						where (Object)(object)a != (Object)null
						select a).Select(ActionKey).ToHashSet<string>(StringComparer.OrdinalIgnoreCase);
					ActionSpec[] addActions = entry.addActions;
					foreach (ActionSpec actionSpec in addActions)
					{
						if (actionSpec != null && !string.IsNullOrWhiteSpace(actionSpec.type))
						{
							string item2 = ActionKeyFor(actionSpec);
							if (!hashSet.Contains(item2) && TryAddAction(((Component)item).gameObject, actionSpec))
							{
								num2++;
								hashSet.Add(item2);
							}
						}
					}
					if (num2 > 0)
					{
						CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已添加 {num2} 个食用动作");
					}
				}
				if (entry.cooking == null)
				{
					return;
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)item).gameObject.AddComponent<ItemCooking>();
					CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 模板无 ItemCooking,已自动补加并启用烹饪"));
				}
				try
				{
					FieldInfo field = ((object)val).GetType().GetField("disableCooking", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null && field.FieldType == typeof(bool) && (bool)field.GetValue(val))
					{
						field.SetValue(val, false);
					}
				}
				catch
				{
				}
				if (entry.cooking.ignoreDefaultCook)
				{
					val.ignoreDefaultCookBehavior = true;
					CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已关闭默认烹饪逻辑(只保留配置的行为)"));
				}
				if (entry.cooking.wreckWhenCooked)
				{
					val.wreckWhenCooked = true;
					CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 烹饪即毁坏物品(wreckWhenCooked)"));
				}
				if (entry.cooking.addBehaviors == null || entry.cooking.addBehaviors.Length == 0)
				{
					return;
				}
				List<AdditionalCookingBehavior> list2 = new List<AdditionalCookingBehavior>();
				CookingBehaviorSpec[] addBehaviors = entry.cooking.addBehaviors;
				foreach (CookingBehaviorSpec cookingBehaviorSpec in addBehaviors)
				{
					if (cookingBehaviorSpec != null && !string.IsNullOrWhiteSpace(cookingBehaviorSpec.type))
					{
						AdditionalCookingBehavior val2 = BuildCookingBehavior(item, cookingBehaviorSpec);
						if (val2 != null)
						{
							val2.cookedAmountToTrigger = cookingBehaviorSpec.cookedAmountToTrigger;
							val2.onlyOnce = cookingBehaviorSpec.onlyOnce;
							list2.Add(val2);
							CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已添加烹饪行为 {cookingBehaviorSpec.type}(cookedAmountToTrigger={cookingBehaviorSpec.cookedAmountToTrigger}, onlyOnce={cookingBehaviorSpec.onlyOnce})");
						}
					}
				}
				val.additionalCookingBehaviors = list2.ToArray();
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"{entry.name}: 应用属性配置失败: {arg}");
			}
		}

		public static void ReapplyLive(ItemConfigEntry entry)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0083: 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_00cc: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			Item runtimeItem = entry.runtimeItem;
			if ((Object)(object)runtimeItem == (Object)null)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 克隆体尚未就绪,无法实时应用(等注册完成或重启)"));
				return;
			}
			try
			{
				if (runtimeItem.UIData == null)
				{
					runtimeItem.UIData = new ItemUIData();
				}
				runtimeItem.UIData.itemName = entry.displayName;
				RegisterNameLocalization(entry);
				if (entry.tags != null && entry.tags.Length != 0)
				{
					ItemTags val = (ItemTags)0;
					string[] tags = entry.tags;
					foreach (string value in tags)
					{
						if (Enum.TryParse<ItemTags>(value, ignoreCase: true, out ItemTags result) && (int)result > 0)
						{
							val |= result;
						}
					}
					if ((int)val > 0)
					{
						runtimeItem.itemTags = val;
					}
				}
				Item val2 = FindTemplate(entry);
				if ((Object)(object)val2 != (Object)null)
				{
					ApplyLook(runtimeItem, val2, entry);
				}
				else
				{
					CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 找不到模板,跳过贴图实时应用"));
				}
				ApplyActionsAndCooking(runtimeItem, entry);
				ApplyPetrifyBomb(runtimeItem, entry);
				CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已实时应用配置(贴图/名称/标签/属性)"));
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"{entry.name}: 实时应用失败: {arg}");
			}
		}

		private static bool TryAddAction(GameObject go, ActionSpec spec)
		{
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = spec.type.Trim().ToLowerInvariant();
				switch (text.StartsWith("action_") ? text.Substring("action_".Length) : text)
				{
				case "modifystatus":
				{
					Action_ModifyStatus val4 = go.AddComponent<Action_ModifyStatus>();
					val4.statusType = ParseEnum<STATUSTYPE>(spec.statusType, (STATUSTYPE)8);
					val4.changeAmount = spec.changeAmount;
					val4.ifSkeleton = spec.ifSkeleton;
					SetTrigger((ItemAction)(object)val4, spec.on);
					return true;
				}
				case "restorehunger":
				{
					Action_RestoreHunger val5 = go.AddComponent<Action_RestoreHunger>();
					val5.restorationAmount = spec.restorationAmount;
					SetTrigger((ItemAction)(object)val5, spec.on);
					return true;
				}
				case "applyaffliction":
				{
					Action_ApplyAffliction val3 = go.AddComponent<Action_ApplyAffliction>();
					if (Enum.TryParse<AfflictionType>(spec.affliction, ignoreCase: true, out AfflictionType result))
					{
						val3.affliction = Affliction.CreateBlankAffliction(result);
						if (val3.affliction != null && spec.totalTime > 0f)
						{
							val3.affliction.totalTime = spec.totalTime;
						}
					}
					SetTrigger((ItemAction)(object)val3, spec.on);
					return true;
				}
				case "giveextrastamina":
				{
					Action_GiveExtraStamina val2 = go.AddComponent<Action_GiveExtraStamina>();
					val2.amount = spec.amount;
					SetTrigger((ItemAction)(object)val2, spec.on);
					return true;
				}
				case "consume":
				{
					Action_Consume action2 = go.AddComponent<Action_Consume>();
					SetTrigger((ItemAction)(object)action2, spec.on);
					return true;
				}
				case "playanimation":
				{
					Action_PlayAnimation val = go.AddComponent<Action_PlayAnimation>();
					val.animationName = spec.animationName;
					SetTrigger((ItemAction)(object)val, spec.on);
					return true;
				}
				case "die":
				{
					Action_Die action = go.AddComponent<Action_Die>();
					SetTrigger((ItemAction)(object)action, spec.on);
					return true;
				}
				default:
					CustomItemsPlugin.Log.LogWarning((object)("未知食用动作类型: " + spec.type + "(可选 ModifyStatus/RestoreHunger/ApplyAffliction/GiveExtraStamina/Consume/PlayAnimation/Die)"));
					return false;
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)("添加食用动作 " + spec.type + " 失败: " + ex.Message));
				return false;
			}
		}

		private static void SetTrigger(ItemAction action, string on)
		{
			switch ((on ?? "").Trim().ToLowerInvariant())
			{
			case "":
				break;
			case "pressed":
				action.OnPressed = true;
				break;
			case "held":
				action.OnHeld = true;
				break;
			case "released":
				action.OnReleased = true;
				break;
			case "cancelled":
				action.OnCancelled = true;
				break;
			case "consumed":
				action.OnConsumed = true;
				break;
			case "secondarypressed":
				action.OnSecondaryPressed = true;
				break;
			case "secondaryheld":
				action.OnSecondaryHeld = true;
				break;
			case "secondarycastfinished":
				action.OnSecondaryCastFinished = true;
				break;
			case "secondarycancelled":
				action.OnSecondaryCancelled = true;
				break;
			default:
				action.OnCastFinished = true;
				break;
			}
		}

		private static string ActionKey(ItemAction a)
		{
			//IL_0016: 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)
			Action_ModifyStatus val = (Action_ModifyStatus)(object)((a is Action_ModifyStatus) ? a : null);
			if (val != null)
			{
				return $"modifystatus|{val.statusType}";
			}
			Action_ApplyAffliction val2 = (Action_ApplyAffliction)(object)((a is Action_ApplyAffliction) ? a : null);
			if (val2 != null)
			{
				Affliction affliction = val2.affliction;
				return $"applyaffliction|{((affliction != null) ? new AfflictionType?(affliction.GetAfflictionType()) : ((AfflictionType?)null))}";
			}
			return ((object)a).GetType().Name;
		}

		private static string ActionKeyFor(ActionSpec s)
		{
			string text = s.type.Trim();
			text = (text.StartsWith("action_", StringComparison.OrdinalIgnoreCase) ? text.Substring("action_".Length) : text);
			if (text.Equals("modifystatus", StringComparison.OrdinalIgnoreCase))
			{
				return "modifystatus|" + s.statusType;
			}
			if (text.Equals("applyaffliction", StringComparison.OrdinalIgnoreCase))
			{
				return "applyaffliction|" + s.affliction;
			}
			return "Action_" + text;
		}

		private static AdditionalCookingBehavior? BuildCookingBehavior(Item item, CookingBehaviorSpec spec)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_012e: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			switch (spec.type.Trim().ToLowerInvariant())
			{
			case "explode":
			{
				CookingBehavior_WildDogMilkExplode cookingBehavior_WildDogMilkExplode = new CookingBehavior_WildDogMilkExplode();
				((AdditionalCookingBehavior)cookingBehavior_WildDogMilkExplode).onlyOnce = true;
				EnsureExplosionPrefab(item, (AdditionalCookingBehavior)(object)cookingBehavior_WildDogMilkExplode);
				return (AdditionalCookingBehavior?)(object)cookingBehavior_WildDogMilkExplode;
			}
			case "changeafflictiontime":
			{
				Action_ApplyAffliction val = ((IEnumerable<Action_ApplyAffliction>)((Component)item).GetComponents<Action_ApplyAffliction>()).FirstOrDefault((Func<Action_ApplyAffliction, bool>)((Action_ApplyAffliction a) => (Object)(object)a != (Object)null));
				if ((Object)(object)val == (Object)null)
				{
					CustomItemsPlugin.Log.LogWarning((object)"烹饪行为 ChangeAfflictionTime 需要物品上有 Action_ApplyAffliction,但当前没有,已跳过");
					return null;
				}
				return (AdditionalCookingBehavior?)new CookingBehavior_ChangeAfflictionTime
				{
					action = val,
					change = spec.change
				};
			}
			case "afflictall":
			{
				if (!Enum.TryParse<AfflictionType>(spec.affliction, ignoreCase: true, out AfflictionType result2))
				{
					CustomItemsPlugin.Log.LogWarning((object)("烹饪行为 AfflictAll 需要合法的 affliction(如 Invincibility),当前为 '" + spec.affliction + "',已跳过"));
					return null;
				}
				return (AdditionalCookingBehavior?)(object)new CookingBehavior_AfflictAll
				{
					afflictionType = result2,
					totalTime = spec.totalTime,
					alsoExplode = false
				};
			}
			case "afflictallandexplode":
			{
				if (!Enum.TryParse<AfflictionType>(spec.affliction, ignoreCase: true, out AfflictionType result))
				{
					CustomItemsPlugin.Log.LogWarning((object)("烹饪行为 AfflictAllAndExplode 需要合法的 affliction,当前为 '" + spec.affliction + "',已跳过"));
					return null;
				}
				CookingBehavior_AfflictAll cookingBehavior_AfflictAll = new CookingBehavior_AfflictAll
				{
					afflictionType = result,
					totalTime = spec.totalTime,
					alsoExplode = true
				};
				EnsureExplosionPrefab(item, (AdditionalCookingBehavior)(object)cookingBehavior_AfflictAll);
				return (AdditionalCookingBehavior?)(object)cookingBehavior_AfflictAll;
			}
			default:
				CustomItemsPlugin.Log.LogWarning((object)("未知烹饪行为类型: " + spec.type + "(可选 Explode/ChangeAfflictionTime/AfflictAll/AfflictAllAndExplode)"));
				return null;
			}
		}

		private static void EnsureExplosionPrefab(Item item, AdditionalCookingBehavior behavior)
		{
			try
			{
				ItemCooking component = ((Component)item).GetComponent<ItemCooking>();
				if (!((Object)(object)component == (Object)null))
				{
					component.explosionPrefab = GetOrBuildAoeExplosionPrefab();
					CustomItemsPlugin.Log.LogInfo((object)(((Object)item).name + ": 已挂载自定义范围爆炸体(Injury 致死+击退+击飞,range=5)"));
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(((Object)item).name + ": 挂载爆炸体失败: " + ex.Message));
			}
		}

		public static GameObject GetNativeExplosionPrefab()
		{
			if ((Object)(object)_dynamiteExplosionPrefab == (Object)null && !_dbSearched)
			{
				ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
				if ((Object)(object)instance != (Object)null && instance.itemLookup != null)
				{
					_dbSearched = true;
					_dynamiteExplosionPrefab = ResolveDynamiteExplosionPrefab(instance);
					if ((Object)(object)_dynamiteExplosionPrefab != (Object)null)
					{
						CustomItemsPlugin.Log.LogInfo((object)"[爆炸] 已从 ItemDatabase 锁定 Dynamite.explosionPrefab(炸药同款)");
					}
					else
					{
						CustomItemsPlugin.Log.LogWarning((object)"[爆炸] ItemDatabase 中未找到带 Dynamite 组件的条目,回退场景扫描");
					}
				}
			}
			if ((Object)(object)_dynamiteExplosionPrefab != (Object)null)
			{
				_nativeExplosionPrefab = _dynamiteExplosionPrefab;
				return _nativeExplosionPrefab;
			}
			if ((Object)(object)_nativeExplosionPrefab != (Object)null)
			{
				return _nativeExplosionPrefab;
			}
			GameObject val = null;
			GameObject val2 = null;
			GameObject val3 = null;
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter?.refs?.movement?.explosionPrefab != (Object)null)
				{
					val2 = localCharacter.refs.movement.explosionPrefab;
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 读本地角色 explosionPrefab 失败: " + ex.Message));
			}
			if ((Object)(object)val2 == (Object)null)
			{
				try
				{
					if (Character.AllCharacters != null)
					{
						foreach (Character allCharacter in Character.AllCharacters)
						{
							if ((Object)(object)allCharacter?.refs?.movement?.explosionPrefab != (Object)null)
							{
								val2 = allCharacter.refs.movement.explosionPrefab;
								break;
							}
						}
					}
				}
				catch (Exception ex2)
				{
					CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 扫描角色 explosionPrefab 失败: " + ex2.Message));
				}
			}
			try
			{
				MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>();
				MonoBehaviour[] array2 = array;
				foreach (MonoBehaviour val4 in array2)
				{
					if ((Object)(object)val4 == (Object)null)
					{
						continue;
					}
					Type type = ((object)val4).GetType();
					FieldInfo field = type.GetField("explosionPrefab", BindingFlags.Instance | BindingFlags.Public);
					if (!(field != null) || !(field.FieldType == typeof(GameObject)))
					{
						continue;
					}
					object? value = field.GetValue(val4);
					GameObject val5 = (GameObject)((value is GameObject) ? value : null);
					if (!((Object)(object)val5 == (Object)null))
					{
						if ((Object)(object)val3 == (Object)null)
						{
							val3 = val5;
						}
						if ((Object)(object)val == (Object)null && (type.Name == "Dynamite" || type.FullName.EndsWith(".Dynamite", StringComparison.Ordinal)))
						{
							val = val5;
						}
					}
				}
			}
			catch (Exception ex3)
			{
				CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 扫描场景 explosionPrefab 失败: " + ex3.Message));
			}
			if ((Object)(object)val != (Object)null)
			{
				_nativeExplosionPrefab = val;
				CustomItemsPlugin.Log.LogInfo((object)"[爆炸] 已采用场上 Dynamite.explosionPrefab(炸药同款)作为原生爆炸视觉");
			}
			else if ((Object)(object)val2 != (Object)null)
			{
				_nativeExplosionPrefab = val2;
				CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 场上无 Dynamite,回退用 CharacterMovement.explosionPrefab(火箭引爆款)作为爆炸视觉");
			}
			else
			{
				if (!((Object)(object)val3 != (Object)null))
				{
					CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 未取得原生 explosionPrefab,将回退到自建爆炸体");
					return null;
				}
				_nativeExplosionPrefab = val3;
				CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 场上无 Dynamite/角色移动,回退用场景任意 explosionPrefab 作为爆炸视觉");
			}
			return _nativeExplosionPrefab;
		}

		private static GameObject ResolveDynamiteExplosionPrefab(ItemDatabase db)
		{
			try
			{
				foreach (KeyValuePair<ushort, Item> item in db.itemLookup)
				{
					Item value = item.Value;
					if (!((Object)(object)value == (Object)null))
					{
						Dynamite component = ((Component)value).GetComponent<Dynamite>();
						if ((Object)(object)component != (Object)null && (Object)(object)component.explosionPrefab != (Object)null)
						{
							return component.explosionPrefab;
						}
					}
				}
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 从 ItemDatabase 解析 Dynamite 失败: " + ex.Message));
			}
			return null;
		}

		public static GameObject GetOrBuildAoeExplosionPrefab()
		{
			if ((Object)(object)_aoeExplosionPrefab == (Object)null)
			{
				_aoeExplosionPrefab = BuildAoePrefab();
			}
			return _aoeExplosionPrefab;
		}

		private static GameObject BuildAoePrefab()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0015: 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)
			GameObject val = new GameObject("WildDogMilkExplosionAOE_Fallback");
			AOE val2 = val.AddComponent<AOE>();
			val2.mask = (LayerType)0;
			val2.auto = true;
			val2.onEnable = false;
			val2.range = 5f;
			val2.knockback = 25f;
			val2.additionalVerticalKnockback = 8f;
			val2.fallTime = 0.5f;
			val2.statusType = (STATUSTYPE)0;
			val2.statusAmount = 1.5f;
			val2.minFactor = 0.2f;
			val2.factorPow = 1f;
			val2.ignoreFactor = false;
			val2.requireLineOfSigh = false;
			val2.capFallDamage = true;
			val2.fallDamageCap = 1f;
			val2.fallDamageCapTime = 5f;
			val2.canLaunchItems = true;
			val2.itemKnockbackMultiplier = 1f;
			val2.worksOnCarriedScout = true;
			val2.useSingleDirection = false;
			val2.addtlStatus = (STATUSTYPE[])(object)new STATUSTYPE[0];
			val2.addlStatusAmountOverrides = new List<float>();
			val2.illegalStatus = "";
			val2.hasAffliction = false;
			val2.affliction = null;
			val.AddComponent<ExplosionFlash>();
			return val;
		}

		private static T ParseEnum<T>(string? value, T fallback) where T : struct
		{
			if (!string.IsNullOrWhiteSpace(value) && Enum.TryParse<T>(value.Replace("-", "").Replace(" ", ""), ignoreCase: true, out var result))
			{
				return result;
			}
			return fallback;
		}

		private static void ApplyPetrifyBomb(Item item, ItemConfigEntry entry)
		{
			if (entry.petrifyBomb == null)
			{
				return;
			}
			GameObject gameObject = ((Component)item).gameObject;
			PetrifyBombBehavior component = gameObject.GetComponent<PetrifyBombBehavior>();
			PetrifyBombBehavior petrifyBombBehavior = component ?? gameObject.AddComponent<PetrifyBombBehavior>();
			petrifyBombBehavior.spec = entry.petrifyBomb;
			petrifyBombBehavior.duration = entry.petrifyBomb.baseDuration;
			PetrifyBombBehavior.RegisterSpec(item, entry);
			if (entry.petrifyBomb.cookDurations != null && entry.petrifyBomb.cookDurations.Length != 0)
			{
				ItemCooking component2 = ((Component)item).GetComponent<ItemCooking>();
				if ((Object)(object)component2 != (Object)null)
				{
					List<AdditionalCookingBehavior> list = new List<AdditionalCookingBehavior>();
					if (component2.additionalCookingBehaviors != null)
					{
						list.AddRange(component2.additionalCookingBehaviors);
					}
					bool flag = false;
					foreach (AdditionalCookingBehavior item2 in list)
					{
						if (item2 is CookingBehavior_PetrifyBombDuration)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						list.Add((AdditionalCookingBehavior)(object)new CookingBehavior_PetrifyBombDuration
						{
							sourceItem = item,
							baseDuration = entry.petrifyBomb.baseDuration,
							cookDurations = entry.petrifyBomb.cookDurations
						});
						component2.additionalCookingBehaviors = list.ToArray();
					}
				}
				else
				{
					CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 模板没有 ItemCooking,烹饪升级将不生效(但基础石化炸弹仍可用)"));
				}
			}
			CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已挂载石化炸弹(基础时长 {1}s,烹饪升级 {2})", entry.name, entry.petrifyBomb.baseDuration, string.Join("/", entry.petrifyBomb.cookDurations)));
		}

		private static void ApplyUses(Item item, ItemConfigEntry entry)
		{
			if (!entry.uses.HasValue || (Object)(object)item == (Object)null)
			{
				return;
			}
			try
			{
				OptionableIntItemData data = item.GetData<OptionableIntItemData>((DataEntryKey)2);
				data.HasData = true;
				data.Value = entry.uses.Value;
				if (entry.uses.Value > 0)
				{
					item.SetUseRemainingPercentage(1f);
				}
				CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 可用次数已设为 {entry.uses.Value}");
			}
			catch (Exception ex)
			{
				CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 设置可用次数失败: " + ex.Message));
			}
		}
	}
	[Serializable]
	public class CookingBehavior_AfflictAll : AdditionalCookingBehavior
	{
		public AfflictionType afflictionType;

		public float totalTime;

		public bool alsoExplode;

		public bool includeBots = false;

		private static readonly FieldInfo? ItemCookingField = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic);

		protected override void TriggerBehaviour(int cookedAmount)
		{
			//IL_0139: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			object? obj = ItemCookingField?.GetValue(this);
			ItemCooking val = (ItemCooking)((obj is ItemCooking) ? obj : null);
			if (alsoExplode)
			{
				try
				{
					if (val != null)
					{
						val.Explode();
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[PeakCustomItem] 烹饪爆炸失败: " + ex.Message));
				}
			}
			int num = 0;
			List<Character> allCharacters = Character.AllCharacters;
			if (allCharacters == null)
			{
				return;
			}
			foreach (Character item in allCharacters)
			{
				if ((Object)(object)item == (Object)null || item.refs == null || (Object)(object)item.refs.afflictions == (Object)null || (!includeBots && item.isBot))
				{
					continue;
				}
				try
				{
					Affliction val2 = Affliction.CreateBlankAffliction(afflictionType);
					if (val2 != null)
					{
						if (totalTime > 0f)
						{
							val2.totalTime = totalTime;
						}
						item.refs.afflictions.AddAffliction(val2, false);
						num++;
					}
				}
				catch (Exception ex2)
				{
					Debug.LogWarning((object)$"[PeakCustomItem] 给 {((Object)item).name} 添加 {afflictionType} 失败: {ex2.Message}");
				}
			}
			Debug.Log((object)($"[PeakCustomItem] 烹饪全员效果: {afflictionType}({totalTime}s) 已添加给 {num} 名角色" + (alsoExplode ? "(并已爆炸)" : "")));
		}
	}
	[Serializable]
	public class CookingBehavior_PetrifyBombDuration : AdditionalCookingBehavior
	{
		public Item? sourceItem;

		public float baseDuration = 10f;

		public float[] cookDurations = new float[3] { 20f, 30f, 35f };

		private static FieldInfo? _itemCookingField;

		protected override void TriggerBehaviour(int cookedAmount)
		{
			Item val = ResolveItem();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			PetrifyBombBehavior component = ((Component)val).GetComponent<PetrifyBombBehavior>();
			if (!((Object)(object)component == (Object)null))
			{
				float num = baseDuration;
				int num2 = cookedAmount - 1;
				if (num2 >= 0 && num2 < cookDurations.Length)
				{
					num = cookDurations[num2];
				}
				else if (cookDurations.Length != 0)
				{
					num = cookDurations[cookDurations.Length - 1];
				}
				component.duration = num;
				CustomItemsPlugin.Log.LogInfo((object)$"[PeakCustomItem] 石化炸弹烹饪升级:cookedAmount={cookedAmount} → 时长 {num}s");
			}
		}

		private Item? ResolveItem()
		{
			if ((Object)(object)sourceItem != (Object)null)
			{
				return sourceItem;
			}
			try
			{
				if ((object)_itemCookingField == null)
				{
					_itemCookingField = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				object? obj = _itemCookingField?.GetValue(this);
				return ((ItemComponent)(((obj is ItemCooking) ? obj : null)?)).item;
			}
			catch
			{
				return null;
			}
		}
	}
	public class CookingBehavior_WildDogMilkExplode : AdditionalCookingBehavior
	{
		protected override void TriggerBehaviour(int cookedAmount)
		{
			//IL_005c: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? obj = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(this);
				ItemCooking val = (ItemCooking)((obj is ItemCooking) ? obj : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((ItemComponent)val).item == (Object)null))
				{
					Item item = ((ItemComponent)val).item;
					Vector3 position = ((Component)val).transform.position;
					int itemViewId = (((Object)(object)((MonoBehaviourPun)item).photonView != (Object)null) ? ((MonoBehaviourPun)item).photonView.ViewID : (-1));
					bool flag = (Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)item;
					bool flag2 = (Object)(object)((MonoBehaviourPun)item).photonView != (Object)null && ((MonoBehaviourPun)item).photonView.AmController;
					if (flag || flag2)
					{
						AllyBuffRpc.BroadcastExplode(position, itemViewId);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶爆炸触发失败: " + ex.Message));
			}
		}
	}
	public class ExplosionFlash : MonoBehaviour
	{
		public float duration = 0.55f;

		public float maxRadius = 5f;

		public Color color = new Color(1f, 0.55f, 0.15f, 0.7f);

		private float _t;

		private Transform _sphere;

		private MeshRenderer _r;

		private Light _light;

		private void Start()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0052: 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)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			val.transform.SetParent(((Component)this).transform, false);
			_sphere = val.transform;
			_r = val.GetComponent<MeshRenderer>();
			try
			{
				Material val2 = new Material(Shader.Find("Sprites/Default"));
				val2.color = color;
				val2.SetInt("_Cull", 0);
				((Renderer)_r).material = val2;
			}
			catch
			{
			}
			_light = val.AddComponent<Light>();
			_light.type = (LightType)2;
			_light.color = new Color(1f, 0.6f, 0.3f);
			_light.range = maxRadius * 1.6f;
			_light.intensity = 7f;
		}

		private void Update()
		{
			//IL_0066: 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)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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)
			_t += Time.deltaTime;
			float num = Mathf.Clamp01(_t / duration);
			if ((Object)(object)_r != (Object)null && (Object)(object)_sphere != (Object)null)
			{
				float num2 = Mathf.Lerp(0.6f, maxRadius * 2f, num);
				_sphere.localScale = Vector3.one * num2;
				Color val = ((Renderer)_r).material.color;
				val.a = color.a * (1f - num);
				((Renderer)_r).material.color = val;
			}
			if ((Object)(object)_light != (Object)null)
			{
				_light.intensity = 7f * (1f - num);
			}
			if (_t >= duration)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	[Serializable]
	public class ItemConfigEntry
	{
		public string name = "";

		public string displayName = "";

		public string templateMatch = "contains";

		public string templateValue = "milk";

		public string[] tags = Array.Empty<string>();

		public string texture = "";

		public string icon = "";

		public float[]? textureOffset = null;

		public float[]? textureScale = null;

		public string behavior = "";

		public string[] removeActions = Array.Empty<string>();

		public ActionSpec[] addActions = Array.Empty<ActionSpec>();

		public string[] removeCookingBehaviors = Array.Empty<string>();

		public CookingSpec? cooking = null;

		public bool spawn = true;

		public int? uses = null;

		public float? spawnChance = null;

		public bool dumpTemplateTexture = false;

		[JsonIgnore]
		internal GameObject? templateGo = null;

		[JsonIgnore]
		internal Texture2D? templateTexture = null;

		[JsonIgnore]
		internal Texture2D? templateIconTex = null;

		public PetrifyBombSpec? petrifyBomb = null;

		[JsonIgnore]
		public string configDir = "";

		[JsonIgnore]
		public string runtimePrefabId = "";

		[JsonIgnore]
		public Item runtimeItem = null;
	}
	[Serializable]
	public class PetrifyBombSpec
	{
		public float baseDuration = 10f;

		public string[]? buffAfflictions = null;

		public float[] cookDurations = new float[3] { 20f, 30f, 35f };

		public float rampCapDuringCountdown = 95f;

		public bool petrifyAtEnd = true;

		public float allyRadius = 0f;
	}
	[Serializable]
	public class ItemConfig
	{
		public ItemConfigEntry[] items = Array.Empty<ItemConfigEntry>();

		public bool liveReloadTexture = true;
	}
	[Serializable]
	public class ActionSpec
	{
		public string type = "";

		public string on = "CastFinished";

		public string statusType = "";

		public float changeAmount = 0f;

		public bool ifSkeleton = false;

		public float restorationAmount = 0f;

		public string affliction = "";

		public float totalTime = 0f;

		public float amount = 0f;

		public string animationName = "";
	}
	[Serializable]
	public class CookingBehaviorSpec
	{
		public string type = "";

		public int cookedAmountToTrigger = 1;

		public bool onlyOnce = true;

		public bool dontRunIfOutOfFuel = false;

		public string actionType = "Action_ApplyAffliction";

		public float change = 0f;

		public string affliction = "";

		public float totalTime = 0f;
	}
	[Serializable]
	public class CookingSpec
	{
		public bool ignoreDefaultCook = false;

		public bool wreckWhenCooked = false;

		public string[] removeBehaviors = Array.Empty<string>();

		public CookingBehaviorSpec[] addBehaviors = Array.Empty<CookingBehaviorSpec>();
	}
	public static class ItemConfigLoader
	{
		public static ItemConfig? Load(string path)
		{
			try
			{
				if (!File.Exists(path))
				{
					return null;
				}
				string text = File.ReadAllText(path);
				if (string.IsNullOrWhiteSpace(text))
				{
					return null;
				}
				ItemConfig itemConfig = JsonConvert.DeserializeObject<ItemConfig>(text);
				if (itemConfig == null || itemConfig.items == null)
				{
					return null;
				}
				return itemConfig;
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"读取物品配置失败 {path}: {arg}");
				return null;
			}
		}

		public static ItemConfig LoadAll(string rootDir)
		{
			List<ItemConfigEntry> list = new List<ItemConfigEntry>();
			string path = Path.Combine(rootDir, "itemconfig.json");
			if (File.Exists(path))
			{
				ItemConfig itemConfig = Load(path);
				if (itemConfig != null)
				{
					list.AddRange(itemConfig.items);
				}
			}
			try
			{
				string[] directories = Directory.GetDirectories(rootDir);
				foreach (string text in directories)
				{
					string path2 = Path.Combine(text, "itemconfig.json");
					if (!File.Exists(path2))
					{
						continue;
					}
					ItemConfig itemConfig2 = Load(path2);
					if (itemConfig2 == null || itemConfig2.items == null || itemConfig2.items.Length == 0)
					{
						continue;
					}
					ItemConfigEntry[] items = itemConfig2.items;
					foreach (ItemConfigEntry itemConfigEntry in items)
					{
						itemConfigEntry.configDir = text;
						if (string.IsNullOrWhiteSpace(itemConfigEntry.name))
						{
							itemConfigEntry.name = Path.GetFileName(text);
						}
					}
					list.AddRange(itemConfig2.items);
				}
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"扫描物品文件夹失败 {rootDir}: {arg}");
			}
			return new ItemConfig
			{
				items = list.ToArray()
			};
		}

		public static void WriteEntryToFolder(string dir, ItemConfigEntry entry)
		{
			try
			{
				Directory.CreateDirectory(dir);
				ItemConfig itemConfig = new ItemConfig();
				itemConfig.items = new ItemConfigEntry[1] { entry };
				ItemConfig itemConfig2 = itemConfig;
				string text = JsonConvert.SerializeObject((object)itemConfig2, (Formatting)1);
				string text2 = "// ============================================================\n//  新物品配置(由游戏内 F10 物品编辑器生成)\n" + $"//  模板: {entry.templateValue}  生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}\n" + "//  修改后重启游戏生效;贴图 PNG 放到本文件夹\n// ============================================================\n";
				File.WriteAllText(Path.Combine(dir, "itemconfig.json"), text2 + text);
				CustomItemsPlugin.Log.LogInfo((object)("已写入配置: " + Path.Combine(dir, "itemconfig.json")));
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"写入配置失败 {dir}: {arg}");
			}
		}

		public static void WriteExampleFolder(string dir)
		{
			try
			{
				Directory.CreateDirectory(dir);
				File.WriteAllText(Path.Combine(dir, "itemconfig.json"), "{\n  // ============================================================\n  //  示例物品:野生狗奶(以游戏内\"奶白金\"为模板)\n  //  用法:改 name/displayName → 重启游戏 → 进一局看到道具\n  //  texture/icon 留空 = 完全继承模板外观\n  //  spawnChance 留空(null) = 沿用模板生成概率;写 0~100 可覆盖\n  //  属性(v1.4.6 全部可选,不写 = 继承模板):\n  //    removeActions: 移除模板继承的食用动作,如 [\"Action_ApplyAffliction\"]\n  //    addActions:    添加食用动作,如 [{ \"type\": \"ModifyStatus\", \"on\": \"CastFinished\",\n  //                     \"statusType\": \"Hot\", \"changeAmount\": -0.5 }]\n  //                     type 可选 ModifyStatus/RestoreHunger/ApplyAffliction/\n  //                           GiveExtraStamina/Consume/PlayAnimation\n  //                     on 可选 Pressed/Held/Released/CastFinished/Cancelled/Consumed/Secondary*\n  //    removeCookingBehaviors: 移除烹饪行为,如 [\"CookingBehavior_ChangeAfflictionTime\"]\n  //    cooking: 烹饪配置,如 { \"ignoreDefaultCook\": true, \"addBehaviors\": [\n  //                { \"type\": \"Explode\" },\n  //                { \"type\": \"AfflictAllAndExplode\", \"affliction\": \"Invincibility\", \"totalTime\": 10 } ] }\n  //              addBehaviors type 可选 Explode/ChangeAfflictionTime/AfflictAll/AfflictAllAndExplode\n  //    石化炸弹(v1.6.0):加 \"petrifyBomb\": { \"baseDuration\": 10, \"cookDurations\": [20,30,35],\n  //              \"petrifyAtEnd\": true, \"explodeAtEnd\": true, \"splashRadius\": 6, \"splashPetrify\": 50 }\n  //              → 食用 10s 无敌+逐渐石化,结束满石化(变石头)+爆炸波及附近;烹饪逐次升级时长\n  //    ItemInfoDisplay 兼容(v1.6.3):addActions 挂标准动作即可显示属性(像官方物品):\n  //              ApplyAffliction→获得无敌 / RestoreHunger→恢复饱食 / ModifyStatus→状态增减\n  //              技巧:on 留空 \"\" = 纯装饰组件(不触发不生效,仅让属性面板显示,如石化)\n  // ============================================================\n  \"items\": [\n    {\n      \"name\": \"WildDogMilk\",\n      \"displayName\": \"野生狗奶\",\n      \"templateMatch\": \"contains\",\n      \"templateValue\": \"milk\",\n      \"tags\": [],\n      \"texture\": \"\",\n      \"icon\": \"\",\n      \"behavior\": \"\",\n      \"spawn\": true,\n      \"spawnChance\": null\n    }\n  ]\n}");
				CustomItemsPlugin.Log.LogInfo((object)("已生成示例物品文件夹: " + dir));
			}
			catch (Exception arg)
			{
				CustomItemsPlugin.Log.LogError((object)$"生成示例配置失败 {dir}: {arg}");
			}
		}
	}
	public class ItemEditorUI : MonoBehaviour
	{
		private static class PreviewRig
		{
			private const int Layer = 30;

			private static GameObject? _root;

			private static Camera? _cam;

			private static RenderTexture? _rt;

			private static int _lastItemId = -1;

			private static GameObject? _clone;

			private static Vector3 _center = Vector3.zero;

			private static float _radius = 2f;

			private static float _yaw = 0f;

			private static float _pitch = 12f;

			public static RenderTexture? RT => _rt;

			public static bool HasModel => (Object)(object)_clone != (Object)null;

			private static void EnsureBuilt()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				//IL_004c: 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)
				//IL_006d: Expected O, but got Unknown
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Expected O, but got Unknown
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Expected O, but got Unknown
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Expected O, but got Unknown
				if (!((Object)(object)_root != (Object)null))
				{
					_root = new GameObject("PeakPreviewStage");
					_root.layer = 30;
					_root.transform.position = new Vector3(0f, -10000f, 0f);
					Object.DontDestroyOnLoad((Object)(object)_root);
					GameObject val = new GameObject("PeakPreviewCam");
					val.transform.SetParent(_root.transform, false);
					_cam = val.AddComponent<Camera>();
					_cam.clearFlags = (CameraClearFlags)2;
					_cam.backgroundColor = new Color(0.14f, 0.14f, 0.17f, 1f);
					_cam.cullingMask = 1073741824;
					_cam.orthographic = false;
					_cam.nearClipPlane = 0.01f;
					_cam.farClipPlane = 100f;
					_cam.fieldOfView = 35f;
					((Behaviour)_cam).enabled = false;
					GameObject val2 = new GameObject("PeakPreviewKey");
					val2.transform.SetParent(_root.transform, false);
					Light val3 = val2.AddComponent<Light>();
					val3.type = (LightType)1;
					val3.intensity = 1.3f;
					val3.color = Color.white;
					val2.transform.rotation = Quaternion.Euler(40f, 35f, 0f);
					GameObject val4 = new GameObject("PeakPreviewFill");
					val4.transform.SetParent(_root.transform, false);
					Light val5 = val4.AddComponent<Light>();
					val5.type = (LightType)1;
					val5.intensity = 0.55f;
					val5.color = Color.white;
					val4.transform.rotation = Quaternion.Euler(-25f, -130f, 0f);
					_rt = new RenderTexture(512, 512, 24, (RenderTextureFormat)0);
					_rt.Create();
					_cam.targetTexture = _rt;
				}
			}

			public static void SetItem(Item item)
			{
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: 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_015a: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				EnsureBuilt();
				int num = (((Object)(object)item != (Object)null) ? ((Object)item).GetInstanceID() : (-1));
				if (num == _lastItemId)
				{
					return;
				}
				_lastItemId = num;
				for (int num2 = _root.transform.childCount - 1; num2 >= 0; num2--)
				{
					Transform child = _root.transform.GetChild(num2);
					bool flag;
					switch (((Object)child).name)
					{
					case "PeakPreviewCam":
					case "PeakPreviewKey":
					case "PeakPreviewFill":
						flag = true;
						break;
					default:
						flag = false;
						break;
					}
					if (!flag)
					{
						Object.Destroy((Object)(object)((Component)child).gameObject);
					}
				}
				_clone = null;