Decompiled source of Prophecy v1.1.5

plugins/Prophecy.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Prophecy.UI;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Prophecy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.5.0")]
[assembly: AssemblyInformationalVersion("1.1.5+bc60c27975fba971172241945f8da26b2a201750")]
[assembly: AssemblyProduct("Prophecy")]
[assembly: AssemblyTitle("Prophecy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Prophecy
{
	internal static class ModConfig
	{
		private sealed class ColorSlot
		{
			private string _cachedStr;

			private Color _cachedColor;

			private string _cachedHex;

			private bool _hasValue;

			private void Refresh(string str, Color fallback)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if (!_hasValue || !string.Equals(str, _cachedStr, StringComparison.Ordinal))
				{
					_cachedStr = str;
					_cachedColor = ParseColor(str, fallback);
					_cachedHex = ColorUtility.ToHtmlStringRGB(_cachedColor);
					_hasValue = true;
				}
			}

			public Color Get(string str, Color fallback)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Refresh(str, fallback);
				return _cachedColor;
			}

			public string GetHex(string str, Color fallback)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				Refresh(str, fallback);
				return _cachedHex;
			}
		}

		public static ConfigEntry<bool> Enabled_BigGhostTracker;

		public static ConfigEntry<bool> Enabled_TornadoTracker;

		public static ConfigEntry<bool> Enabled_BridgeCapacity;

		public static ConfigEntry<bool> Enabled_SnowStormTimer;

		public static ConfigEntry<bool> Enabled_FungusWindTimer;

		public static ConfigEntry<bool> Enabled_RainTimer;

		public static ConfigEntry<LangMode> Language;

		public static ConfigEntry<KeyCode> PanelKey;

		public static ConfigEntry<float> PanelScale;

		public static ConfigEntry<string> Color_BigGhost_Str;

		public static ConfigEntry<string> Color_Tornado_Str;

		public static ConfigEntry<string> Color_Bridge_Str;

		public static ConfigEntry<string> Color_StormWind_Str;

		public static ConfigEntry<string> Color_Rain_Str;

		public static ConfigEntry<float> TextSize_UI;

		public static ConfigEntry<bool> ShowBackground;

		public static ConfigEntry<float> UI_PosX;

		public static ConfigEntry<float> UI_PosY;

		public static ConfigEntry<float> BiomeQueryInterval;

		public static ConfigEntry<float> CountdownRefreshInterval;

		public const string DefWindowBg = "#15171C";

		public const string DefTitleBar = "#21252E";

		public const string DefNavBg = "#1A1D24";

		public const string DefCardBg = "#1E222A";

		public const string DefCardEdge = "#39404E";

		public const string DefButtonBg = "#272C36";

		public const string DefFieldBg = "#101318";

		public const string DefAccent = "#FFC94D";

		public const string DefTextMain = "#E8EAEF";

		public const string DefTextSub = "#C3CAD6";

		public const string DefTextHint = "#A6AFBE";

		public const string DefOk = "#74D69A";

		public const string DefWarn = "#F2A65A";

		public const string DefBad = "#EB6B6B";

		public static ConfigEntry<string> ColorWindowBg;

		public static ConfigEntry<string> ColorTitleBar;

		public static ConfigEntry<string> ColorNavBg;

		public static ConfigEntry<string> ColorCardBg;

		public static ConfigEntry<string> ColorCardEdge;

		public static ConfigEntry<string> ColorButtonBg;

		public static ConfigEntry<string> ColorFieldBg;

		public static ConfigEntry<string> ColorAccent;

		public static ConfigEntry<string> ColorTextMain;

		public static ConfigEntry<string> ColorTextSub;

		public static ConfigEntry<string> ColorTextHint;

		public static ConfigEntry<string> ColorOk;

		public static ConfigEntry<string> ColorWarn;

		public static ConfigEntry<string> ColorBad;

		private static ConfigFile _file;

		private static readonly ColorSlot _slotBigGhost = new ColorSlot();

		private static readonly ColorSlot _slotTornado = new ColorSlot();

		private static readonly ColorSlot _slotBridge = new ColorSlot();

		private static readonly ColorSlot _slotStormWind = new ColorSlot();

		private static readonly ColorSlot _slotRain = new ColorSlot();

		public static Color Color_BigGhost => _slotBigGhost.Get(Color_BigGhost_Str.Value, Color.red);

		public static Color Color_Tornado => _slotTornado.Get(Color_Tornado_Str.Value, Color.yellow);

		public static Color Color_Bridge => _slotBridge.Get(Color_Bridge_Str.Value, Color.cyan);

		public static Color Color_StormWind => _slotStormWind.Get(Color_StormWind_Str.Value, new Color(1f, 0.5f, 0f));

		public static Color Color_Rain => _slotRain.Get(Color_Rain_Str.Value, new Color(0.3f, 0.6f, 0.9f));

		public static string Color_BigGhost_Hex => _slotBigGhost.GetHex(Color_BigGhost_Str.Value, Color.red);

		public static string Color_Tornado_Hex => _slotTornado.GetHex(Color_Tornado_Str.Value, Color.yellow);

		public static string Color_Bridge_Hex => _slotBridge.GetHex(Color_Bridge_Str.Value, Color.cyan);

		public static string Color_StormWind_Hex => _slotStormWind.GetHex(Color_StormWind_Str.Value, new Color(1f, 0.5f, 0f));

		public static string Color_Rain_Hex => _slotRain.GetHex(Color_Rain_Str.Value, new Color(0.3f, 0.6f, 0.9f));

		public static void Init(ConfigFile config)
		{
			//IL_010c: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Expected O, but got Unknown
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Expected O, but got Unknown
			_file = config;
			Enabled_BigGhostTracker = config.Bind<bool>("功能开关", "大幽灵追踪器", true, "雾沼地图显示大幽灵生成倒计时与目标玩家");
			Enabled_TornadoTracker = config.Bind<bool>("功能开关", "龙卷风追踪器", true, "方山地图显示龙卷风生成倒计时");
			Enabled_BridgeCapacity = config.Bind<bool>("功能开关", "木桥承载显示", true, "准星对准木桥时显示承载人数");
			Enabled_SnowStormTimer = config.Bind<bool>("功能开关", "雪山风暴倒计时", true, "雪山地图显示风暴刮起/结束倒计时");
			Enabled_FungusWindTimer = config.Bind<bool>("功能开关", "森蕈风倒计时", true, "森蕈地图显示狂风刮起/结束倒计时");
			Enabled_RainTimer = config.Bind<bool>("功能开关", "雨林下雨计时", true, "雨林地图显示下雨开始/结束倒计时");
			Language = config.Bind<LangMode>("通用", "界面语言", LangMode.Auto, "Auto=跟随系统,也可强制中文或英文");
			PanelKey = config.Bind<KeyCode>("通用", "面板按键", (KeyCode)283, "打开/关闭设置面板的按键");
			PanelScale = config.Bind<float>("通用", "面板缩放", 1f, "设置面板整体缩放倍率(0.6 - 2.5)");
			Color_BigGhost_Str = config.Bind<string>("颜色设置", "大幽灵追踪颜色", ColorToString(Color.red), "大幽灵文字颜色(RRGGBB)");
			Color_Tornado_Str = config.Bind<string>("颜色设置", "龙卷风追踪颜色", ColorToString(Color.yellow), "龙卷风文字颜色(RRGGBB)");
			Color_Bridge_Str = config.Bind<string>("颜色设置", "木桥承载颜色", ColorToString(Color.cyan), "木桥承载文字颜色(RRGGBB)");
			Color_StormWind_Str = config.Bind<string>("颜色设置", "风暴/狂风颜色", ColorToString(new Color(1f, 0.5f, 0f)), "风暴、狂风文字颜色(RRGGBB)");
			Color_Rain_Str = config.Bind<string>("颜色设置", "雨林下雨颜色", ColorToString(new Color(0.3f, 0.6f, 0.9f)), "雨林下雨文字颜色(RRGGBB)");
			TextSize_UI = config.Bind<float>("显示设置", "UI文字大小", 18f, "屏幕 UI 文字的大小");
			ShowBackground = config.Bind<bool>("显示设置", "显示背景", true, "在文字后绘制半透明背景");
			UI_PosX = config.Bind<float>("显示设置", "倒计时文字横向位置", 10f, "左侧倒计时文字列的起点 X(屏幕像素)");
			UI_PosY = config.Bind<float>("显示设置", "倒计时文字纵向位置", 10f, "左侧倒计时文字的起点 Y(屏幕像素,从上往下)");
			BiomeQueryInterval = config.Bind<float>("显示设置", "地图查询间隔秒", 2f, new ConfigDescription("每隔多久重新判定一次当前地图(秒)。越大越省性能,但进入新地图后倒计时最多延迟这么久才出现。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
			CountdownRefreshInterval = config.Bind<float>("显示设置", "倒计时刷新间隔秒", 0.5f, new ConfigDescription("倒计时刷新频率(秒):每隔多久重新读取一次游戏数据。越小数字越精准、越跟手,但性能消耗越高;越大越省性能,数字更新越慢。默认 0.5。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1.5f), Array.Empty<object>()));
			BindPanelColors(config);
		}

		private static void BindPanelColors(ConfigFile config)
		{
			ColorWindowBg = config.Bind<string>("面板配色", "窗口背景色", "#15171C", "控制面板窗口的底色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorTitleBar = config.Bind<string>("面板配色", "标题栏背景色", "#21252E", "标题栏底色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorNavBg = config.Bind<string>("面板配色", "导航栏背景色", "#1A1D24", "左侧页签栏底色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorCardBg = config.Bind<string>("面板配色", "卡片背景色", "#1E222A", "内容卡片底色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorCardEdge = config.Bind<string>("面板配色", "卡片描边色", "#39404E", "卡片与分隔线的描边色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorButtonBg = config.Bind<string>("面板配色", "按钮背景色", "#272C36", "普通按钮底色(悬停/按下会自动变亮),格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorFieldBg = config.Bind<string>("面板配色", "输入框背景色", "#101318", "输入框与滑条轨道底色,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorAccent = config.Bind<string>("面板配色", "强调色", "#FFC94D", "关键功能色:数值、选中项、页签高亮、滑条滑块与主按钮,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorTextMain = config.Bind<string>("面板配色", "主文字色", "#E8EAEF", "标题、卡片标题、按钮等主要文字,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorTextSub = config.Bind<string>("面板配色", "正文文字色", "#C3CAD6", "说明文字与表单标签,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorTextHint = config.Bind<string>("面板配色", "小字文字色", "#A6AFBE", "脚注与提示小字,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorOk = config.Bind<string>("面板配色", "正常状态色", "#74D69A", "「已开启」等正常状态,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorWarn = config.Bind<string>("面板配色", "警告状态色", "#F2A65A", "需要注意的提醒,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
			ColorBad = config.Bind<string>("面板配色", "错误状态色", "#EB6B6B", "异常与危险操作的文字,格式 #RRGGBB。面板「配色」页可直接调整,点「恢复默认」还原。");
		}

		public static float SafePanelScale()
		{
			return Mathf.Clamp((PanelScale != null) ? PanelScale.Value : 1f, 0.6f, 2.5f);
		}

		public static void Save()
		{
			if (_file != null)
			{
				_file.Save();
			}
		}

		private static string ColorToString(Color c)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return "#" + ColorUtility.ToHtmlStringRGB(c);
		}

		public static Color ParseColor(string str, Color fallback)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Color val = default(Color);
				if (str.StartsWith("#") && str.Length == 7)
				{
					return ColorUtility.TryParseHtmlString(str, ref val) ? val : fallback;
				}
				Color val2 = default(Color);
				if (str.Length == 6)
				{
					return ColorUtility.TryParseHtmlString("#" + str, ref val2) ? val2 : fallback;
				}
			}
			catch
			{
			}
			return fallback;
		}
	}
	public enum LangMode
	{
		Auto,
		Zh,
		En
	}
	public static class L10n
	{
		public static bool IsChinese()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			switch (ModConfig.Language.Value)
			{
			case LangMode.Zh:
				return true;
			case LangMode.En:
				return false;
			default:
				try
				{
					CultureInfo currentUICulture = CultureInfo.CurrentUICulture;
					if (currentUICulture != null && !string.IsNullOrEmpty(currentUICulture.Name))
					{
						return currentUICulture.Name.StartsWith("zh", StringComparison.OrdinalIgnoreCase);
					}
				}
				catch
				{
				}
				try
				{
					SystemLanguage systemLanguage = Application.systemLanguage;
					return (int)systemLanguage == 40 || (int)systemLanguage == 41;
				}
				catch
				{
				}
				return false;
			}
		}

		public static string T(string zh, string en)
		{
			if (!IsChinese())
			{
				return en;
			}
			return zh;
		}

		public static string F(string zh, string en, params object[] args)
		{
			return string.Format(IsChinese() ? zh : en, args);
		}

		public static bool ContainsAny(string text, params string[] keywords)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			foreach (string value in keywords)
			{
				if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		public static bool ContainsAny(string text, string k0, string k1)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (!string.IsNullOrEmpty(k0) && text.IndexOf(k0, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (!string.IsNullOrEmpty(k1) && text.IndexOf(k1, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			return false;
		}
	}
	public static class ExtraInfoOverlay
	{
		private struct UIText
		{
			public Vector2 Position;

			public string Text;

			public Color Color;
		}

		private delegate Object[] FindObjectsByTypeDel(Type type, FindObjectsSortMode sortMode);

		private delegate Object[] FindObjectsOfTypeDel(Type type);

		private delegate Object FindFirstObjectByTypeDel(Type type);

		private delegate Object FindObjectOfTypeDel(Type type);

		private sealed class QueryCache
		{
			public object[] Items;

			public float Expire;
		}

		private static GUIStyle _uiStyle;

		private static Texture2D _bgTexture;

		private static Camera _mainCamera;

		private static int _lastUIFontSize = -1;

		private static readonly GUIContent _sharedContent = new GUIContent();

		private static readonly Dictionary<string, Vector2> _uiMeasure = new Dictionary<string, Vector2>(64);

		private const int MEASURE_CACHE_MAX = 128;

		private static float _nextBiomeQueryTime = -999f;

		private static BiomeType _cachedBiomeValue;

		private static readonly List<UIText> _uiTexts = new List<UIText>();

		private static float _lastBigGhostCollectTime = 0f;

		private static float _lastTornadoCollectTime = 0f;

		private static bool _tornadoWasPresent = false;

		private static float _lastTornadoSpawnTime = -999f;

		private static bool _ghostWasPresent = false;

		private static float _lastGhostSpawnTime = -999f;

		private static float _lastSnowStormCollectTime = 0f;

		private static float _lastFungusWindCollectTime = 0f;

		private static float _lastRainCollectTime = 0f;

		private const float BRIDGE_CHECK_INTERVAL = 0.2f;

		private const float BRIDGE_RAY_MAX_DIST = 20f;

		private const float BRIDGE_SPHERE_RADIUS = 0.25f;

		private const float BRIDGE_UNDER_MAX_DIST = 3f;

		private const float BRIDGE_MISS_DIAG_INTERVAL = 2f;

		private const float DEFAULT_COUNTDOWN_INTERVAL = 0.5f;

		private const float MIN_COUNTDOWN_INTERVAL = 0.2f;

		private const float MAX_COUNTDOWN_INTERVAL = 1.5f;

		private static float _lastBridgeCheckTime = 0f;

		private static string _heldText1;

		private static string _heldText3;

		private static string _heldText4;

		private static string _heldText5;

		private static string _heldText6;

		private static bool _initialized = false;

		private static readonly RaycastHit[] _bridgeRayHits = (RaycastHit[])(object)new RaycastHit[32];

		private static string _lastBridgeText;

		private static float _lastBridgeShowTime = -999f;

		private const float BRIDGE_HOLD_TIME = 1.5f;

		private static int _bridgeMissDiagCount = 0;

		private static float _lastBridgeMissDiagTime = -999f;

		private static int _bridgeUnderMismatchDiag = 0;

		private static object _cachedTornado;

		private static Type _itemType;

		private static FieldInfo _itemDestroyTickField;

		private static FieldInfo _itemItemIdField;

		private static FieldInfo _itemMainRendererField;

		private static Type _ghostBallSpawnerType;

		private static FieldInfo _ghostCurrentSpawnTimeField;

		private static FieldInfo _ghostTickField;

		private static FieldInfo _ghostCurrentBallField;

		private static FieldInfo _ghostTimeBetweenSpawnsField;

		private static Type _ghostBallType;

		private static PropertyInfo _ghostBallTargetProperty;

		private static Type _tornadoSpawnerType;

		private static FieldInfo _tornadoUntilNextField;

		private static Type _tornadoType;

		private static Type _breakableBridgeType;

		private static Type _jungleVineType;

		private static FieldInfo _bridgeHoldsPeopleField;

		private static FieldInfo _bridgePeopleOnBridgeField;

		private static FieldInfo _bridgePeopleDictField;

		private static FieldInfo _bridgeIsShakingField;

		private static FieldInfo _bridgeIsBreakingField;

		private static FieldInfo _bridgeIsFallenField;

		private static Type _windChillZoneType;

		private static FieldInfo _windActiveField;

		private static FieldInfo _windUntilSwitchField;

		private static FieldInfo _windInsideBoundsField;

		private static FieldInfo _windDisableSettingField;

		private static FieldInfo _windBoundsField;

		private const float BIOME_ZONE_MAX_DISTANCE = 300f;

		private const float BIOME_ZONE_BOUNDS_MARGIN = 100f;

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

		private static BiomeType _lastLoggedBiome = (BiomeType)(-2);

		private static Type _stormVisualType;

		private static FieldInfo _stormTypeField;

		private static Type _biomeType;

		private static FieldInfo _biomeTypeField;

		private static FieldInfo _mapSegmentBiomeField;

		private static FindObjectsByTypeDel _findObjectsByTypeDel;

		private static FindObjectsOfTypeDel _findObjectsOfTypeDel;

		private static FindFirstObjectByTypeDel _findFirstObjectByTypeDel;

		private static FindObjectOfTypeDel _findObjectOfTypeDel;

		private static readonly object[] EmptyObjects = new object[0];

		private const float SCENE_QUERY_TTL = 1.5f;

		private static readonly Dictionary<Type, QueryCache> _multiQueryCache = new Dictionary<Type, QueryCache>();

		private static readonly Dictionary<Type, QueryCache> _singleQueryCache = new Dictionary<Type, QueryCache>();

		private static readonly Dictionary<int, int> _stormKindCache = new Dictionary<int, int>();

		private static float CountdownInterval()
		{
			return Mathf.Clamp((ModConfig.CountdownRefreshInterval != null) ? ModConfig.CountdownRefreshInterval.Value : 0.5f, 0.2f, 1.5f);
		}

		private static void RemoveTexts(string k0, string k1)
		{
			for (int num = _uiTexts.Count - 1; num >= 0; num--)
			{
				if (L10n.ContainsAny(_uiTexts[num].Text, k0, k1))
				{
					_uiTexts.RemoveAt(num);
				}
			}
		}

		public static void Initialize()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			_mainCamera = Camera.main;
			_bgTexture = new Texture2D(1, 1);
			_bgTexture.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.7f));
			_bgTexture.Apply();
			CacheReflectionFields();
			CacheReflectionMethods();
			_initialized = true;
		}

		private static void RebuildStyles()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			int num = Mathf.RoundToInt(ModConfig.TextSize_UI.Value);
			if (num != _lastUIFontSize || _uiStyle == null)
			{
				_lastUIFontSize = num;
				_uiMeasure.Clear();
				_uiStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = num,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)0,
					richText = true
				};
			}
		}

		private static Vector2 MeasureCached(Dictionary<string, Vector2> cache, GUIStyle style, string text)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (cache.TryGetValue(text, out var value))
			{
				return value;
			}
			if (cache.Count >= 128)
			{
				cache.Clear();
			}
			_sharedContent.text = text;
			return cache[text] = style.CalcSize(_sharedContent);
		}

		private static BiomeType CachedBiome()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime >= _nextBiomeQueryTime)
			{
				float num = ((ModConfig.BiomeQueryInterval != null) ? ModConfig.BiomeQueryInterval.Value : 2f);
				if (num < 0.5f)
				{
					num = 0.5f;
				}
				_nextBiomeQueryTime = unscaledTime + num;
				_cachedBiomeValue = GetCurrentBiome();
			}
			return _cachedBiomeValue;
		}

		public static void UpdateOverlay()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_0588: Unknown result type (might be due to invalid IL or missing references)
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_064b: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Invalid comparison between Unknown and I4
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Invalid comparison between Unknown and I4
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Invalid comparison between Unknown and I4
			//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Invalid comparison between Unknown and I4
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Invalid comparison between Unknown and I4
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				Initialize();
			}
			if ((Object)(object)_mainCamera == (Object)null)
			{
				_mainCamera = Camera.main;
			}
			if ((Object)(object)_mainCamera == (Object)null)
			{
				_uiTexts.Clear();
				return;
			}
			if (!HasLocalCharacter())
			{
				_uiTexts.Clear();
				return;
			}
			float time = Time.time;
			RemoveTexts("大幽灵", "Big Ghost");
			if (ModConfig.Enabled_BigGhostTracker.Value)
			{
				if (time - _lastBigGhostCollectTime >= CountdownInterval())
				{
					_lastBigGhostCollectTime = time;
					try
					{
						CollectBigGhostInfo();
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("大幽灵采集异常: " + ex.Message));
					}
				}
				if (_heldText6 != null)
				{
					_uiTexts.Add(new UIText
					{
						Position = new Vector2(ModConfig.UI_PosX.Value, ModConfig.UI_PosY.Value),
						Text = _heldText6,
						Color = ModConfig.Color_BigGhost
					});
				}
			}
			RemoveTexts("龙卷风", "Tornado");
			if (ModConfig.Enabled_TornadoTracker.Value)
			{
				if (time - _lastTornadoCollectTime >= CountdownInterval())
				{
					_lastTornadoCollectTime = time;
					try
					{
						CollectTornadoInfo();
					}
					catch (Exception ex2)
					{
						Plugin.Log.LogWarning((object)("龙卷风采集异常: " + ex2.Message));
					}
				}
				if (_heldText5 != null)
				{
					_uiTexts.Add(new UIText
					{
						Position = new Vector2(ModConfig.UI_PosX.Value, ModConfig.UI_PosY.Value + 50f),
						Text = _heldText5,
						Color = ModConfig.Color_Tornado
					});
				}
			}
			RemoveTexts("木桥", "Bridge");
			if (ModConfig.Enabled_BridgeCapacity.Value)
			{
				bool flag = false;
				try
				{
					Character localCharacter = Character.localCharacter;
					flag = (Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.isReaching;
				}
				catch
				{
					flag = false;
				}
				if (flag && time - _lastBridgeCheckTime >= 0.2f)
				{
					_lastBridgeCheckTime = time;
					try
					{
						CollectBridgeInfo();
					}
					catch (Exception ex3)
					{
						Plugin.Log.LogWarning((object)("木桥采集异常: " + ex3.Message));
					}
					if (_lastBridgeText == null && _bridgeMissDiagCount < 30 && _breakableBridgeType != null && (Object)(object)_mainCamera != (Object)null && (Object)(object)Character.localCharacter != (Object)null && (int)CachedBiome() >= 0 && time - _lastBridgeMissDiagTime >= 2f)
					{
						_lastBridgeMissDiagTime = time;
						try
						{
							Vector3 position = ((Component)_mainCamera).transform.position;
							Ray val = _mainCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
							int num = Physics.RaycastNonAlloc(val, _bridgeRayHits, 20f, -1, (QueryTriggerInteraction)2);
							StringBuilder stringBuilder = new StringBuilder();
							Transform val2 = null;
							for (int i = 0; i < num; i++)
							{
								Collider collider = ((RaycastHit)(ref _bridgeRayHits[i])).collider;
								if (!((Object)(object)collider == (Object)null))
								{
									if ((Object)(object)val2 == (Object)null)
									{
										val2 = ((Component)collider).transform;
									}
									if (stringBuilder.Length > 0)
									{
										stringBuilder.Append(" | ");
									}
									stringBuilder.Append($"{HierarchyPath(((Component)collider).transform)}@{((RaycastHit)(ref _bridgeRayHits[i])).distance:F1}m/layer{((Component)collider).gameObject.layer}");
								}
							}
							if (stringBuilder.Length == 0)
							{
								stringBuilder.Append("无命中");
							}
							_bridgeMissDiagCount++;
							string text = (((Object)(object)val2 != (Object)null) ? (";首命中链组件:" + HierarchyComponents(val2)) : "");
							Plugin.Log.LogWarning((object)string.Format("[{0}] 木桥诊断:相机={1} 原点={2} 方向={3} 命中{4}个({5});场景:{6}{7}", "Prophecy", ((Object)_mainCamera).name, ((Ray)(ref val)).origin, ((Ray)(ref val)).direction, num, stringBuilder, BridgeSceneSummary(position), text));
						}
						catch
						{
						}
					}
				}
				if (_lastBridgeText != null && time - _lastBridgeShowTime < 1.5f)
				{
					_uiTexts.Add(new UIText
					{
						Position = new Vector2((float)Screen.width / 2f, (float)Screen.height / 2f + 80f),
						Text = _lastBridgeText,
						Color = ModConfig.Color_Bridge
					});
				}
			}
			RemoveTexts("风暴", "Snow Storm");
			if (ModConfig.Enabled_SnowStormTimer.Value)
			{
				BiomeType val3 = CachedBiome();
				if ((int)val3 != -1 && (int)val3 != 2)
				{
					_heldText1 = null;
					LogBiomeGateBlocked("雪风暴", val3);
				}
				else if (time - _lastSnowStormCollectTime >= CountdownInterval())
				{
					_lastSnowStormCollectTime = time;
					try
					{
						CollectStormWindInfo(showFungus: false);
					}
					catch (Exception ex4)
					{
						Plugin.Log.LogWarning((object)("风暴采集异常: " + ex4.Message));
					}
				}
				if (_heldText1 != null)
				{
					_uiTexts.Add(new UIText
					{
						Position = new Vector2(ModConfig.UI_PosX.Value, ModConfig.UI_PosY.Value + 80f),
						Text = _heldText1,
						Color = ModConfig.Color_StormWind
					});
				}
			}
			RemoveTexts("森蕈风", "Fungus Wind");
			if (ModConfig.Enabled_FungusWindTimer.Value)
			{
				BiomeType val4 = CachedBiome();
				if ((int)val4 != -1 && (int)val4 != 7)
				{
					_heldText4 = null;
					LogBiomeGateBlocked("森蕈风", val4);
				}
				else if (time - _lastFungusWindCollectTime >= CountdownInterval())
				{
					_lastFungusWindCollectTime = time;
					try
					{
						CollectStormWindInfo(showFungus: true);
					}
					catch (Exception ex5)
					{
						Plugin.Log.LogWarning((object)("森蕈风采集异常: " + ex5.Message));
					}
				}
				if (_heldText4 != null)
				{
					_uiTexts.Add(new UIText
					{
						Position = new Vector2(ModConfig.UI_PosX.Value, ModConfig.UI_PosY.Value + 110f),
						Text = _heldText4,
						Color = ModConfig.Color_StormWind
					});
				}
			}
			RemoveTexts("雨林下雨", "Rain");
			if (!ModConfig.Enabled_RainTimer.Value)
			{
				return;
			}
			if (time - _lastRainCollectTime >= CountdownInterval())
			{
				_lastRainCollectTime = time;
				try
				{
					CollectRainInfo();
				}
				catch (Exception ex6)
				{
					Plugin.Log.LogWarning((object)("雨林下雨采集异常: " + ex6.Message));
				}
			}
			if (_heldText3 != null)
			{
				_uiTexts.Add(new UIText
				{
					Position = new Vector2(ModConfig.UI_PosX.Value, ModConfig.UI_PosY.Value + 140f),
					Text = _heldText3,
					Color = ModConfig.Color_Rain
				});
			}
		}

		public static void Cleanup()
		{
			if ((Object)(object)_bgTexture != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)_bgTexture);
				_bgTexture = null;
			}
			_initialized = false;
		}

		public static void ClearAllTexts()
		{
			_uiTexts.Clear();
		}

		private static bool HasLocalCharacter()
		{
			try
			{
				return (Object)(object)Character.localCharacter != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		private static BiomeType GetCurrentBiome()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected I4, but got Unknown
			BiomeType val;
			try
			{
				val = (BiomeType)((!((Object)(object)Singleton<MapHandler>.Instance != (Object)null)) ? (-1) : ((int)Singleton<MapHandler>.Instance.GetCurrentBiome()));
			}
			catch
			{
				val = (BiomeType)(-1);
			}
			if (val != _lastLoggedBiome)
			{
				_lastLoggedBiome = val;
				_diagLoggedTags.Clear();
				_stormKindCache.Clear();
				ClearSceneQueryCaches();
				_cachedTornado = null;
				_bridgeMissDiagCount = 0;
				_lastBridgeMissDiagTime = -999f;
				_tornadoWasPresent = false;
				_lastTornadoSpawnTime = -999f;
				_ghostWasPresent = false;
				_lastGhostSpawnTime = -999f;
				Plugin.Log.LogInfo((object)string.Format("[{0}] 当前地图 biome: {1}({2})", "Prophecy", val, (int)val));
			}
			return val;
		}

		private static void LogBiomeGateBlocked(string tag, BiomeType current)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected I4, but got Unknown
			if (_diagLoggedTags.Add(tag))
			{
				Plugin.Log.LogWarning((object)(string.Format("[{0}] {1}:当前地图判定为 {2}({3}),", "Prophecy", tag, current, (int)current) + "未进入该功能的采集流程,倒计时不会显示"));
			}
		}

		public static void OnGUI()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!_initialized)
				{
					Initialize();
				}
				if (_uiTexts.Count == 0)
				{
					return;
				}
				RebuildStyles();
				if (_uiStyle == null)
				{
					return;
				}
				Rect val2 = default(Rect);
				foreach (UIText uiText in _uiTexts)
				{
					Vector2 val = MeasureCached(_uiMeasure, _uiStyle, uiText.Text);
					((Rect)(ref val2))..ctor(uiText.Position.x, uiText.Position.y, val.x + 10f, val.y + 5f);
					if (ModConfig.ShowBackground.Value)
					{
						GUI.DrawTexture(val2, (Texture)(object)_bgTexture);
					}
					GUI.contentColor = uiText.Color;
					GUI.Label(val2, uiText.Text, _uiStyle);
					GUI.contentColor = Color.white;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("覆盖层绘制异常: " + ex));
			}
		}

		private static string HierarchyPath(Transform t)
		{
			List<string> list = new List<string>();
			bool flag = false;
			bool flag2 = false;
			Transform val = t;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 6)
			{
				list.Add(((Object)val).name);
				if (!flag && _breakableBridgeType != null && (Object)(object)((Component)val).GetComponent(_breakableBridgeType) != (Object)null)
				{
					flag = true;
				}
				if (!flag2 && _jungleVineType != null && (Object)(object)((Component)val).GetComponent(_jungleVineType) != (Object)null)
				{
					flag2 = true;
				}
				val = val.parent;
				num++;
			}
			string text = (flag ? "<桥>" : (flag2 ? "<藤>" : ""));
			return string.Join("/", list) + text;
		}

		private static string BridgeSceneSummary(Vector3 camPos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return BridgeTypeSummary(_breakableBridgeType, camPos, "桥") + ";" + BridgeTypeSummary(_jungleVineType, camPos, "藤");
		}

		private static string BridgeTypeSummary(Type t, Vector3 camPos, string label)
		{
			//IL_0075: 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)
			if (t == null)
			{
				return label + "=类型未找到";
			}
			Object[] array = Object.FindObjectsByType(t, (FindObjectsSortMode)0);
			Object[] array2 = Object.FindObjectsByType(t, (FindObjectsInactive)1, (FindObjectsSortMode)0);
			if (array2 == null || array2.Length == 0)
			{
				return label + "=0";
			}
			int num = ((array != null) ? array.Length : 0);
			float num2 = float.MaxValue;
			string text = "";
			List<string> list = new List<string>();
			Object[] array3 = array2;
			foreach (Object obj in array3)
			{
				Component val = (Component)(object)((obj is Component) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					float num3 = Vector3.Distance(camPos, val.transform.position);
					if (num3 < num2)
					{
						num2 = num3;
						text = ((Object)val).name;
					}
					if (num == 0 && list.Count < 3)
					{
						list.Add(ScenePath(val.transform));
					}
				}
			}
			if (num == 0)
			{
				return string.Format("{0}=0激活/{1}总(未激活: {2})", label, array2.Length, string.Join(" , ", list));
			}
			return $"{label}={num}激活/{array2.Length}总,最近{text}@{num2:F1}m";
		}

		private static string ScenePath(Transform t)
		{
			List<string> list = new List<string>();
			Transform val = t;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 8)
			{
				list.Insert(0, ((Object)val).name);
				val = val.parent;
				num++;
			}
			return string.Join("/", list);
		}

		private static string HierarchyComponents(Transform t)
		{
			StringBuilder stringBuilder = new StringBuilder();
			Transform val = t;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 5)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(" | ");
				}
				Component[] components = ((Component)val).GetComponents<Component>();
				List<string> list = new List<string>();
				Component[] array = components;
				foreach (Component val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						Behaviour val3 = (Behaviour)(object)((val2 is Behaviour) ? val2 : null);
						list.Add(((object)val2).GetType().Name + (((Object)(object)val3 != (Object)null && !val3.enabled) ? "(禁用)" : ""));
						if (list.Count >= 6)
						{
							list.Add("...");
							break;
						}
					}
				}
				stringBuilder.Append(((Object)val).name).Append('[').Append(string.Join(",", list))
					.Append(']');
				val = val.parent;
				num++;
			}
			return stringBuilder.ToString();
		}

		private static Component ProbeBridgeAt(Camera cam, Vector2 viewport)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			Ray val = cam.ViewportPointToRay(new Vector3(viewport.x, viewport.y, 0f));
			Component val2 = null;
			float num = float.MaxValue;
			int num2;
			try
			{
				num2 = Physics.RaycastNonAlloc(val, _bridgeRayHits, 20f, -1, (QueryTriggerInteraction)2);
			}
			catch
			{
				return null;
			}
			for (int i = 0; i < num2; i++)
			{
				Collider collider = ((RaycastHit)(ref _bridgeRayHits[i])).collider;
				if (!((Object)(object)collider == (Object)null))
				{
					Component componentInParent;
					try
					{
						componentInParent = ((Component)collider).GetComponentInParent(_breakableBridgeType);
					}
					catch
					{
						continue;
					}
					if (!((Object)(object)componentInParent == (Object)null) && ((RaycastHit)(ref _bridgeRayHits[i])).distance < num)
					{
						num = ((RaycastHit)(ref _bridgeRayHits[i])).distance;
						val2 = componentInParent;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			try
			{
				num2 = Physics.SphereCastNonAlloc(val, 0.25f, _bridgeRayHits, 20f, -1, (QueryTriggerInteraction)2);
			}
			catch
			{
				return null;
			}
			for (int j = 0; j < num2; j++)
			{
				Collider collider2 = ((RaycastHit)(ref _bridgeRayHits[j])).collider;
				if (!((Object)(object)collider2 == (Object)null))
				{
					Component componentInParent2;
					try
					{
						componentInParent2 = ((Component)collider2).GetComponentInParent(_breakableBridgeType);
					}
					catch
					{
						continue;
					}
					if (!((Object)(object)componentInParent2 == (Object)null) && ((RaycastHit)(ref _bridgeRayHits[j])).distance < num)
					{
						num = ((RaycastHit)(ref _bridgeRayHits[j])).distance;
						val2 = componentInParent2;
					}
				}
			}
			return val2;
		}

		private static Component ProbeBridgeUnderPlayer()
		{
			//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)
			if (_breakableBridgeType == null)
			{
				return null;
			}
			Character localCharacter;
			try
			{
				localCharacter = Character.localCharacter;
			}
			catch
			{
				return null;
			}
			if ((Object)(object)localCharacter == (Object)null)
			{
				return null;
			}
			int num;
			try
			{
				num = Physics.RaycastNonAlloc(localCharacter.Center, Vector3.down, _bridgeRayHits, 3f, -1, (QueryTriggerInteraction)2);
			}
			catch
			{
				return null;
			}
			Component result = null;
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				Collider collider = ((RaycastHit)(ref _bridgeRayHits[i])).collider;
				if (!((Object)(object)collider == (Object)null))
				{
					Component componentInParent;
					try
					{
						componentInParent = ((Component)collider).GetComponentInParent(_breakableBridgeType);
					}
					catch
					{
						continue;
					}
					if (!((Object)(object)componentInParent == (Object)null) && ((RaycastHit)(ref _bridgeRayHits[i])).distance < num2)
					{
						num2 = ((RaycastHit)(ref _bridgeRayHits[i])).distance;
						result = componentInParent;
					}
				}
			}
			return result;
		}

		private static void CollectBridgeInfo()
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			if (_breakableBridgeType == null)
			{
				return;
			}
			Camera mainCamera = _mainCamera;
			if ((Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			Component val = ProbeBridgeUnderPlayer();
			if ((Object)(object)val != (Object)null && _bridgeUnderMismatchDiag < 5)
			{
				Component val2 = ProbeBridgeAt(mainCamera, new Vector2(0.5f, 0.5f));
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val)
				{
					_bridgeUnderMismatchDiag++;
					int num = ((_bridgeHoldsPeopleField != null) ? ((int)_bridgeHoldsPeopleField.GetValue(val)) : 0);
					int num2 = ((_bridgeHoldsPeopleField != null) ? ((int)_bridgeHoldsPeopleField.GetValue(val2)) : 0);
					try
					{
						Plugin.Log.LogWarning((object)string.Format("[{0}] 木桥目标不一致:脚下={1}(上限{2}),准星={3}(上限{4});已改为显示脚下桥", "Prophecy", HierarchyPath(val.transform), num, HierarchyPath(val2.transform), num2));
					}
					catch
					{
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ProbeBridgeAt(mainCamera, new Vector2(0.5f, 0.5f));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ProbeBridgeAt(mainCamera, new Vector2(0.48f, 0.5f));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ProbeBridgeAt(mainCamera, new Vector2(0.52f, 0.5f));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ProbeBridgeAt(mainCamera, new Vector2(0.5f, 0.48f));
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ProbeBridgeAt(mainCamera, new Vector2(0.5f, 0.52f));
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Component val3 = val;
			int num3 = ((_bridgeHoldsPeopleField != null) ? ((int)_bridgeHoldsPeopleField.GetValue(val3)) : 0);
			bool flag = true;
			try
			{
				PhotonView component = val3.GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null)
				{
					flag = component.IsMine;
				}
			}
			catch
			{
				flag = true;
			}
			int num4 = 0;
			if (flag)
			{
				if (_bridgePeopleOnBridgeField != null)
				{
					try
					{
						num4 = (int)_bridgePeopleOnBridgeField.GetValue(val3);
					}
					catch
					{
						num4 = 0;
					}
				}
				else if (_bridgePeopleDictField != null)
				{
					try
					{
						if (_bridgePeopleDictField.GetValue(val3) is IDictionary dictionary)
						{
							num4 = dictionary.Count;
						}
					}
					catch
					{
						num4 = 0;
					}
				}
			}
			bool flag2 = _bridgeIsShakingField != null && (bool)_bridgeIsShakingField.GetValue(val3);
			bool flag3 = _bridgeIsBreakingField != null && (bool)_bridgeIsBreakingField.GetValue(val3);
			string text;
			if (_bridgeIsFallenField != null && (bool)_bridgeIsFallenField.GetValue(val3))
			{
				text = L10n.T("木桥: 已坍塌", "Bridge: collapsed");
			}
			else if (!flag)
			{
				text = ((flag2 || flag3) ? L10n.F("木桥承载上限: {0} 人(⚠正在断裂)", "Bridge capacity: {0} (⚠ breaking)", num3) : L10n.F("木桥承载上限: {0} 人", "Bridge capacity: {0}", num3));
			}
			else
			{
				int num5 = Math.Max(0, num3 - num4);
				text = ((flag2 || flag3) ? L10n.F("木桥承载: {0}/{1}(⚠正在断裂)", "Bridge: {0}/{1} (⚠ breaking)", num4, num3) : ((num5 > 0) ? L10n.F("木桥承载: {0}/{1}(还能站{2}人)", "Bridge: {0}/{1} ({2} more)", num4, num3, num5) : L10n.F("木桥承载: {0}/{1}(已满,再上即断)", "Bridge: {0}/{1} (full, next breaks)", num4, num3)));
			}
			_lastBridgeText = "<color=#" + ModConfig.Color_Bridge_Hex + ">" + text + "</color>";
			_lastBridgeShowTime = Time.time;
		}

		private static void CollectBigGhostInfo()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)CachedBiome() != 8)
			{
				_heldText6 = null;
				return;
			}
			object obj = FindObjectByTypeCached(_ghostBallSpawnerType);
			if (obj == null)
			{
				_heldText6 = null;
				return;
			}
			bool isMasterClient = PhotonNetwork.IsMasterClient;
			string text = L10n.T("无", "none");
			object obj2 = null;
			bool flag = false;
			if (_ghostCurrentBallField != null)
			{
				obj2 = _ghostCurrentBallField.GetValue(obj);
				flag = (Object)((obj2 is Object) ? obj2 : null) != (Object)null;
				if (flag && _ghostBallTargetProperty != null)
				{
					object? value = _ghostBallTargetProperty.GetValue(obj2);
					Character val = (Character)((value is Character) ? value : null);
					if ((Object)(object)val != (Object)null)
					{
						text = ((Object)val).name;
					}
				}
			}
			string text2;
			if (isMasterClient)
			{
				if (flag)
				{
					text2 = L10n.F("大幽灵: 已生成,目标 {0}", "Big Ghost: spawned, target {0}", text);
				}
				else
				{
					float num = ((_ghostCurrentSpawnTimeField != null) ? ((float)_ghostCurrentSpawnTimeField.GetValue(obj)) : 0f);
					float num2 = ((_ghostTickField != null) ? ((float)_ghostTickField.GetValue(obj)) : 0f);
					float num3 = Math.Max(0f, num - num2);
					text2 = L10n.F("在雾里待 {0:F1}s 后生成大幽灵\n目标: {1}", "Big Ghost spawns after {0:F1}s in fog\nTarget: {1}", num3, text);
				}
			}
			else if (flag)
			{
				if (!_ghostWasPresent)
				{
					_lastGhostSpawnTime = Time.time;
				}
				_ghostWasPresent = true;
				float num4 = Math.Max(0f, Time.time - _lastGhostSpawnTime);
				text2 = L10n.F("大幽灵: 生成中,目标 {0}(已持续 {1:F0}s)", "Big Ghost: active, target {0} ({1:F0}s)", text, num4);
			}
			else
			{
				_ghostWasPresent = false;
				if (_lastGhostSpawnTime > 0f)
				{
					float num5 = Time.time - _lastGhostSpawnTime;
					float num6 = 0f;
					if (_ghostTimeBetweenSpawnsField != null)
					{
						try
						{
							num6 = ((Vector2)_ghostTimeBetweenSpawnsField.GetValue(obj)).y;
						}
						catch
						{
							num6 = 0f;
						}
					}
					string text3 = ((num6 > 0f && num5 > num6 + 30f) ? L10n.T("(可能本局未启用大幽灵)", " (may be disabled)") : ((!(num6 > 0f)) ? L10n.T("(预计稍后再次生成)", " (next soon)") : L10n.F("(预计 {0:F0}~{1:F0}s 内再次生成)", " (next in {0:F0}-{1:F0}s)", ((Vector2)_ghostTimeBetweenSpawnsField.GetValue(obj)).x, num6)));
					text2 = L10n.F("大幽灵: 距上次生成已过 {0:F0}s{1}", "Big Ghost: {0:F0}s since last{1}", num5, text3);
				}
				else
				{
					text2 = L10n.T("大幽灵: 房主计时中", "Big Ghost: host counting");
				}
			}
			_heldText6 = "<color=#" + ModConfig.Color_BigGhost_Hex + ">" + text2 + "</color>";
		}

		private static void CollectTornadoInfo()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if ((int)CachedBiome() != 6)
			{
				_heldText5 = null;
				return;
			}
			if (PhotonNetwork.IsMasterClient)
			{
				object[] array = FindObjectsByTypeCached(_tornadoSpawnerType);
				if (array == null || array.Length == 0)
				{
					_heldText5 = null;
					return;
				}
				Character localCharacter = Character.localCharacter;
				object obj = null;
				float num = float.MaxValue;
				object[] array2 = array;
				foreach (object obj2 in array2)
				{
					if (!IsAlive(obj2))
					{
						continue;
					}
					if ((Object)(object)localCharacter != (Object)null)
					{
						object obj3 = ((obj2 is Component) ? obj2 : null);
						Transform val = ((obj3 != null) ? ((Component)obj3).transform : null);
						if ((Object)(object)val != (Object)null)
						{
							float num2 = Vector3.Distance(((Component)localCharacter).transform.position, val.position);
							if (num2 > num)
							{
								continue;
							}
							num = num2;
						}
					}
					obj = obj2;
				}
				if (obj == null)
				{
					_heldText5 = null;
					return;
				}
				float val2 = ((_tornadoUntilNextField != null) ? ((float)_tornadoUntilNextField.GetValue(obj)) : 0f);
				_heldText5 = "<color=#" + ModConfig.Color_Tornado_Hex + ">" + L10n.F("龙卷风: {0:F1}s 后生成", "Tornado: spawns in {0:F1}s", Math.Max(0f, val2)) + "</color>";
				return;
			}
			object cachedTornado = _cachedTornado;
			bool flag = cachedTornado != null && (Object)((cachedTornado is Object) ? cachedTornado : null) != (Object)null;
			if (!flag)
			{
				_cachedTornado = null;
				object[] array3 = FindObjectsByTypeCached(_tornadoType, cache: false);
				if (array3 != null && array3.Length != 0 && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)null)
				{
					_cachedTornado = array3[0];
					flag = true;
				}
			}
			if (flag)
			{
				if (!_tornadoWasPresent)
				{
					_lastTornadoSpawnTime = Time.time;
				}
				_tornadoWasPresent = true;
				float num3 = Math.Max(0f, Time.time - _lastTornadoSpawnTime);
				_heldText5 = "<color=#" + ModConfig.Color_Tornado_Hex + ">" + L10n.F("龙卷风: 生成中(已持续 {0:F0}s)", "Tornado: active ({0:F0}s)", num3) + "</color>";
				return;
			}
			_tornadoWasPresent = false;
			if (_lastTornadoSpawnTime > 0f)
			{
				float num4 = Time.time - _lastTornadoSpawnTime;
				string text = ((num4 <= 330f) ? L10n.F("龙卷风: 距上次生成已过 {0:F0}s(预计 30~300s 内再次生成)", "Tornado: {0:F0}s since last (next in 30-300s)", num4) : L10n.F("龙卷风: 距上次生成已过 {0:F0}s(可能本局未启用龙卷风)", "Tornado: {0:F0}s since last (may be disabled)", num4));
				_heldText5 = "<color=#" + ModConfig.Color_Tornado_Hex + ">" + text + "</color>";
			}
			else
			{
				_heldText5 = "<color=#" + ModConfig.Color_Tornado_Hex + ">" + L10n.T("龙卷风: 房主计时中", "Tornado: host counting") + "</color>";
			}
		}

		private static void CacheReflectionFields()
		{
			_itemType = ResolveType("Item");
			if (_itemType != null)
			{
				_itemDestroyTickField = _itemType.GetField("destroyTick", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_itemItemIdField = _itemType.GetField("itemID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_itemMainRendererField = _itemType.GetField("mainRenderer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_ghostBallSpawnerType = ResolveType("Peak.GhostBallSpawner");
			if (_ghostBallSpawnerType != null)
			{
				_ghostCurrentSpawnTimeField = _ghostBallSpawnerType.GetField("currentSpawnTime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_ghostTickField = _ghostBallSpawnerType.GetField("tick", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_ghostCurrentBallField = _ghostBallSpawnerType.GetField("currentGhostBall", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_ghostTimeBetweenSpawnsField = _ghostBallSpawnerType.GetField("timeBetweenSpawns", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_ghostBallType = ResolveType("Peak.GhostBall");
			if (_ghostBallType != null)
			{
				_ghostBallTargetProperty = _ghostBallType.GetProperty("target", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_tornadoSpawnerType = ResolveType("TornadoSpawner");
			if (_tornadoSpawnerType != null)
			{
				_tornadoUntilNextField = _tornadoSpawnerType.GetField("untilNext", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_tornadoType = ResolveType("Tornado");
			_breakableBridgeType = ResolveType("BreakableBridge");
			if (_breakableBridgeType != null)
			{
				_bridgeHoldsPeopleField = _breakableBridgeType.GetField("holdsPeople", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_bridgePeopleOnBridgeField = _breakableBridgeType.GetField("peopleOnBridge", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_bridgePeopleDictField = _breakableBridgeType.GetField("peopleOnBridgeDict", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_bridgeIsShakingField = _breakableBridgeType.GetField("isShaking", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_bridgeIsBreakingField = _breakableBridgeType.GetField("isBreaking", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_bridgeIsFallenField = _breakableBridgeType.GetField("isFallen", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_jungleVineType = ResolveType("JungleVine");
			_windChillZoneType = ResolveType("WindChillZone");
			if (_windChillZoneType != null)
			{
				_windActiveField = _windChillZoneType.GetField("windActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_windUntilSwitchField = _windChillZoneType.GetField("untilSwitch", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_windInsideBoundsField = _windChillZoneType.GetField("localCharacterInsideBounds", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_windDisableSettingField = _windChillZoneType.GetField("disableIfSettingDisabled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_windBoundsField = _windChillZoneType.GetField("windZoneBounds", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_stormVisualType = ResolveType("StormVisual");
			if (_stormVisualType != null)
			{
				_stormTypeField = _stormVisualType.GetField("stormType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			_biomeType = ResolveType("Biome");
			if (_biomeType != null)
			{
				_biomeTypeField = _biomeType.GetField("biomeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			Type type = ResolveType("MapHandler")?.GetNestedType("MapSegment", BindingFlags.Public | BindingFlags.NonPublic);
			if (type != null)
			{
				_mapSegmentBiomeField = type.GetField("_biome", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			LogReflectionStatus();
		}

		private static Type ResolveType(string typeName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(typeName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static void LogReflectionStatus()
		{
			Plugin.Log.LogInfo((object)("[反射] GhostBallSpawner: " + ((_ghostCurrentSpawnTimeField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] GhostBall.timeBetweenSpawns: " + ((_ghostTimeBetweenSpawnsField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] GhostBall.target: " + ((_ghostBallTargetProperty != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] TornadoSpawner: " + ((_tornadoUntilNextField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] Tornado: " + ((_tornadoType != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] BreakableBridge: " + ((_bridgeHoldsPeopleField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] Item: " + ((_itemDestroyTickField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] WindChillZone: " + ((_windUntilSwitchField != null) ? "OK" : "FAIL") + " / disableIfSettingDisabled: " + ((_windDisableSettingField != null) ? "OK" : "FAIL") + " / localCharacterInsideBounds: " + ((_windInsideBoundsField != null) ? "OK" : "FAIL") + " / windZoneBounds: " + ((_windBoundsField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] StormVisual.stormType: " + ((_stormTypeField != null) ? "OK" : "FAIL")));
			Plugin.Log.LogInfo((object)("[反射] Biome.biomeType: " + ((_biomeTypeField != null) ? "OK" : "FAIL") + " / MapSegment._biome: " + ((_mapSegmentBiomeField != null) ? "OK" : "FAIL")));
		}

		private static void CacheReflectionMethods()
		{
			MethodInfo method = typeof(Object).GetMethod("FindObjectsByType", new Type[2]
			{
				typeof(Type),
				typeof(FindObjectsSortMode)
			});
			if (method != null)
			{
				try
				{
					_findObjectsByTypeDel = (FindObjectsByTypeDel)Delegate.CreateDelegate(typeof(FindObjectsByTypeDel), method);
				}
				catch
				{
					_findObjectsByTypeDel = null;
				}
			}
			if (_findObjectsByTypeDel == null)
			{
				MethodInfo method2 = typeof(Object).GetMethod("FindObjectsOfType", new Type[1] { typeof(Type) });
				if (method2 != null)
				{
					try
					{
						_findObjectsOfTypeDel = (FindObjectsOfTypeDel)Delegate.CreateDelegate(typeof(FindObjectsOfTypeDel), method2);
					}
					catch
					{
						_findObjectsOfTypeDel = null;
					}
				}
			}
			MethodInfo method3 = typeof(Object).GetMethod("FindFirstObjectByType", new Type[1] { typeof(Type) });
			if (method3 != null)
			{
				try
				{
					_findFirstObjectByTypeDel = (FindFirstObjectByTypeDel)Delegate.CreateDelegate(typeof(FindFirstObjectByTypeDel), method3);
				}
				catch
				{
					_findFirstObjectByTypeDel = null;
				}
			}
			if (_findFirstObjectByTypeDel != null)
			{
				return;
			}
			MethodInfo method4 = typeof(Object).GetMethod("FindObjectOfType", new Type[1] { typeof(Type) });
			if (method4 != null)
			{
				try
				{
					_findObjectOfTypeDel = (FindObjectOfTypeDel)Delegate.CreateDelegate(typeof(FindObjectOfTypeDel), method4);
				}
				catch
				{
					_findObjectOfTypeDel = null;
				}
			}
		}

		private static bool IsAlive(object o)
		{
			if (o != null)
			{
				return (Object)((o is Object) ? o : null) != (Object)null;
			}
			return false;
		}

		private static void ClearSceneQueryCaches()
		{
			_multiQueryCache.Clear();
			_singleQueryCache.Clear();
		}

		private static object FindObjectByTypeCached(Type type)
		{
			if (type == null)
			{
				return null;
			}
			float unscaledTime = Time.unscaledTime;
			if (_singleQueryCache.TryGetValue(type, out var value) && unscaledTime < value.Expire && value.Items != null && value.Items.Length != 0)
			{
				object obj = value.Items[0];
				if (obj != null && (Object)((obj is Object) ? obj : null) != (Object)null)
				{
					return obj;
				}
			}
			object obj2 = null;
			try
			{
				if (_findFirstObjectByTypeDel != null)
				{
					obj2 = _findFirstObjectByTypeDel(type);
				}
				else if (_findObjectOfTypeDel != null)
				{
					obj2 = _findObjectOfTypeDel(type);
				}
			}
			catch
			{
				obj2 = null;
			}
			if (obj2 != null)
			{
				if (value == null)
				{
					value = new QueryCache();
					_singleQueryCache[type] = value;
				}
				value.Items = new object[1] { obj2 };
				value.Expire = unscaledTime + 1.5f;
			}
			return obj2;
		}

		private static object[] FindObjectsByTypeCached(Type type, bool cache = true)
		{
			if (type == null)
			{
				return EmptyObjects;
			}
			float unscaledTime = Time.unscaledTime;
			QueryCache value = null;
			if (cache && _multiQueryCache.TryGetValue(type, out value) && value.Items != null && unscaledTime < value.Expire)
			{
				for (int i = 0; i < value.Items.Length; i++)
				{
					if (IsAlive(value.Items[i]))
					{
						return value.Items;
					}
				}
			}
			object[] array2;
			try
			{
				if (_findObjectsByTypeDel != null)
				{
					object[] array = _findObjectsByTypeDel(type, (FindObjectsSortMode)0);
					array2 = array;
				}
				else if (_findObjectsOfTypeDel != null)
				{
					object[] array = _findObjectsOfTypeDel(type);
					array2 = array;
				}
				else
				{
					array2 = EmptyObjects;
				}
			}
			catch
			{
				array2 = EmptyObjects;
			}
			if (array2 == null)
			{
				array2 = EmptyObjects;
			}
			if (cache && array2.Length != 0)
			{
				if (value == null)
				{
					value = new QueryCache();
					_multiQueryCache[type] = value;
				}
				value.Items = array2;
				value.Expire = unscaledTime + 1.5f;
			}
			return array2;
		}

		private static void CollectStormWindInfo(bool showFungus)
		{
			object[] array = FindObjectsByTypeCached(_windChillZoneType);
			if (array == null || array.Length == 0)
			{
				ClearStormText(showFungus);
				LogStormDiagnostic(showFungus, null, 0, "场景内未找到任何 WindChillZone 实例");
				return;
			}
			object obj = null;
			int num = 0;
			float num2 = float.MaxValue;
			bool flag = false;
			bool flag2 = false;
			object[] array2 = array;
			foreach (object obj2 in array2)
			{
				if (!IsAlive(obj2))
				{
					continue;
				}
				if (obj == null)
				{
					obj = obj2;
				}
				if (!ZoneMatchesCurrentBiome(obj2))
				{
					continue;
				}
				num++;
				if (ResolveStormKind(obj2) == ((!showFungus) ? 1 : 2))
				{
					float num3 = ((_windUntilSwitchField != null) ? ((float)_windUntilSwitchField.GetValue(obj2)) : (-1f));
					bool flag3 = _windActiveField != null && (bool)_windActiveField.GetValue(obj2);
					if (num3 >= 0f && num3 < num2)
					{
						num2 = num3;
						flag = flag3;
						flag2 = true;
					}
				}
			}
			if (!flag2 || num2 == float.MaxValue)
			{
				ClearStormText(showFungus);
				LogStormDiagnostic(showFungus, obj, num, $"共 {array.Length} 个风区,归属校验通过的 {num} 个,无一命中期望类型 {((!showFungus) ? 1 : 2)}");
				return;
			}
			string text = (showFungus ? L10n.T("森蕈风", "Fungus Wind") : L10n.T("风暴", "Snow Storm"));
			string text2 = (flag ? L10n.F("{0}刮完: {1:F1}s", "{0} ends in {1:F1}s", text, Math.Max(0f, num2)) : L10n.F("{0}: {1:F1}s 后刮起", "{0}: starts in {1:F1}s", text, Math.Max(0f, num2)));
			if (showFungus)
			{
				_heldText4 = "<color=#" + ModConfig.Color_StormWind_Hex + ">" + text2 + "</color>";
			}
			else
			{
				_heldText1 = "<color=#" + ModConfig.Color_StormWind_Hex + ">" + text2 + "</color>";
			}
		}

		private static void ClearStormText(bool showFungus)
		{
			if (showFungus)
			{
				_heldText4 = null;
			}
			else
			{
				_heldText1 = null;
			}
		}

		private static void LogStormDiagnostic(bool showFungus, object zone, int passCount, string reason)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected I4, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			string text = (showFungus ? "森蕈风" : "雪风暴");
			if (!_diagLoggedTags.Add(text))
			{
				return;
			}
			BiomeType val = CachedBiome();
			string text2 = $"{val}({(int)val})";
			if (zone == null)
			{
				Plugin.Log.LogWarning((object)("[Prophecy] " + text + ":当前 biome=" + text2 + "," + reason + ",倒计时不会显示"));
				return;
			}
			string arg = "未知";
			string arg2 = "?";
			string arg3 = "?";
			try
			{
				object obj = ((zone is Component) ? zone : null);
				Transform val2 = ((obj != null) ? ((Component)obj).transform : null);
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)val2 != (Object)null && (Object)(object)localCharacter != (Object)null && (Object)(object)((Component)localCharacter).transform != (Object)null)
				{
					arg = $"{Vector3.Distance(((Component)localCharacter).transform.position, val2.position):F1}m";
				}
			}
			catch
			{
			}
			try
			{
				if (_windInsideBoundsField != null && _windInsideBoundsField.GetValue(zone) is bool flag)
				{
					arg2 = flag.ToString();
				}
			}
			catch
			{
			}
			try
			{
				arg3 = ResolveStormKind(zone).ToString();
			}
			catch
			{
			}
			Plugin.Log.LogWarning((object)("[Prophecy] " + text + ":当前 biome=" + text2 + "," + reason + ";" + $"首个风区诊断——类型判定={arg3},归属校验通过数={passCount}," + $"距玩家 {arg},localCharacterInsideBounds={arg2},距离阈值 {300f}m"));
		}

		private static int ResolveStormKind(object zone)
		{
			Object val = (Object)((zone is Object) ? zone : null);
			int num = ((val != (Object)null) ? val.GetInstanceID() : 0);
			if (num != 0 && _stormKindCache.TryGetValue(num, out var value))
			{
				return value;
			}
			int num2 = ResolveStormKindUncached(zone);
			if (num != 0 && num2 >= 0)
			{
				_stormKindCache[num] = num2;
			}
			return num2;
		}

		private static int ResolveStormKindUncached(object zone)
		{
			if (_windDisableSettingField != null)
			{
				try
				{
					object value = _windDisableSettingField.GetValue(zone);
					if (value != null)
					{
						switch ((int)Convert.ToInt64(value))
						{
						case 1250:
							return 0;
						case 1800:
							return 2;
						case 1900:
							return 1;
						}
					}
				}
				catch
				{
				}
			}
			bool isSnow = false;
			bool isWind = false;
			bool isRain = false;
			ReadStormType(zone, out isSnow, out isWind, out isRain);
			if (isSnow)
			{
				return 1;
			}
			if (isWind)
			{
				return 2;
			}
			if (isRain)
			{
				return 0;
			}
			return -1;
		}

		private static void ReadStormType(object zone, out bool isSnow, out bool isWind, out bool isRain)
		{
			isSnow = false;
			isWind = false;
			isRain = false;
			try
			{
				object obj = ((zone is Component) ? zone : null);
				Transform val = ((obj != null) ? ((Component)obj).transform : null);
				if ((Object)(object)val == (Object)null || _stormVisualType == null || _stormTypeField == null)
				{
					return;
				}
				Component[] componentsInChildren = ((Component)val).GetComponentsInChildren(_stormVisualType, false);
				foreach (Component val2 in componentsInChildren)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						switch ((int)_stormTypeField.GetValue(val2))
						{
						case 0:
							isRain = true;
							break;
						case 1:
							isSnow = true;
							break;
						case 2:
							isWind = true;
							break;
						}
					}
				}
				if (isSnow | isWind | isRain)
				{
					return;
				}
				componentsInChildren = ((Component)val).GetComponentsInChildren(_stormVisualType, true);
				foreach (Component val3 in componentsInChildren)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						switch ((int)_stormTypeField.GetValue(val3))
						{
						case 0:
							isRain = true;
							break;
						case 1:
							isSnow = true;
							break;
						case 2:
							isWind = true;
							break;
						}
					}
				}
			}
			catch
			{
			}
		}

		private static bool ZoneMatchesCurrentBiome(object zone)
		{
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Invalid comparison between I4 and Unknown
			object obj = ((zone is Component) ? zone : null);
			Transform val = ((obj != null) ? ((Component)obj).transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			try
			{
				MapSegment currentMapSegment = MapHandler.CurrentMapSegment;
				GameObject val2 = ((currentMapSegment != null) ? currentMapSegment.segmentParent : null);
				if ((Object)(object)val2 != (Object)null && val.IsChildOf(val2.transform))
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				bool flag = default(bool);
				int num;
				if (_windInsideBoundsField != null)
				{
					object value = _windInsideBoundsField.GetValue(zone);
					if (value is bool)
					{
						flag = (bool)value;
						num = 1;
					}
					else
					{
						num = 0;
					}
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != 0)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				if (_biomeType != null && _biomeTypeField != null)
				{
					Component componentInParent = ((Component)val).GetComponentInParent(_biomeType, true);
					if ((Object)(object)componentInParent != (Object)null)
					{
						object value2 = _biomeTypeField.GetValue(componentInParent);
						if (value2 != null)
						{
							BiomeType val3 = (BiomeType)Convert.ToInt64(value2);
							if (val3 == CachedBiome())
							{
								return true;
							}
							try
							{
								MapSegment currentMapSegment2 = MapHandler.CurrentMapSegment;
								if (currentMapSegment2 != null && _mapSegmentBiomeField != null)
								{
									object value3 = _mapSegmentBiomeField.GetValue(currentMapSegment2);
									if (value3 != null && (int)Convert.ToInt64(value3) == (int)val3)
									{
										return true;
									}
								}
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null)
				{
					return false;
				}
				Vector3 center = localCharacter.Center;
				if (_windBoundsField != null && _windBoundsField.GetValue(zone) is Bounds val4)
				{
					Vector3 extents = ((Bounds)(ref val4)).extents;
					if (((Vector3)(ref extents)).sqrMagnitude > 0f && Vector3.Distance(((Bounds)(ref val4)).ClosestPoint(center), center) <= 100f)
					{
						return true;
					}
				}
				Transform transform = ((Component)localCharacter).transform;
				if ((Object)(object)transform != (Object)null && Vector3.Distance(transform.position, val.position) <= 300f)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void CollectRainInfo()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)CachedBiome() != 1)
			{
				_heldText3 = null;
				return;
			}
			object[] array = FindObjectsByTypeCached(_windChillZoneType);
			if (array == null || array.Length == 0)
			{
				_heldText3 = null;
				return;
			}
			float num = float.MaxValue;
			bool flag = false;
			bool flag2 = false;
			object[] array2 = array;
			foreach (object obj in array2)
			{
				if (IsAlive(obj) && ZoneMatchesCurrentBiome(obj) && ResolveStormKind(obj) == 0)
				{
					float num2 = ((_windUntilSwitchField != null) ? ((float)_windUntilSwitchField.GetValue(obj)) : (-1f));
					bool flag3 = _windActiveField != null && (bool)_windActiveField.GetValue(obj);
					if (num2 >= 0f && num2 < num)
					{
						num = num2;
						flag = flag3;
						flag2 = true;
					}
				}
			}
			if (!flag2 || num == float.MaxValue)
			{
				_heldText3 = null;
				return;
			}
			string text = (flag ? L10n.F("雨林下雨结束: {0:F1}s", "Rain ends in {0:F1}s", Math.Max(0f, num)) : L10n.F("雨林下雨: {0:F1}s 后开始", "Rain starts in {0:F1}s", Math.Max(0f, num)));
			_heldText3 = "<color=#" + ModConfig.Color_Rain_Hex + ">" + text + "</color>";
		}
	}
	public class OverlayRenderer : MonoBehaviour
	{
		private void OnGUI()
		{
			try
			{
				ExtraInfoOverlay.OnGUI();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("覆盖层渲染异常: " + ex));
			}
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.peak.prophecy";

		public const string PLUGIN_NAME = "Prophecy";

		public const string PLUGIN_VERSION = "1.1.5";
	}
	[BepInPlugin("com.peak.prophecy", "Prophecy", "1.1.5")]
	public class Plugin : BaseUnityPlugin
	{
		private GameObject _overlayObject;

		private GameObject _panelObject;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Instance = this;
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			_overlayObject = new GameObject("Prophecy_Overlay");
			_overlayObject.AddComponent<OverlayRenderer>();
			Object.DontDestroyOnLoad((Object)(object)_overlayObject);
			PanelTheme.Log = delegate(string msg)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)msg);
			};
			PanelTheme.PaletteSync = ProphecyPalette.Sync;
			_panelObject = new GameObject("Prophecy_Panel");
			Object.DontDestroyOnLoad((Object)(object)_panelObject);
			PanelHost panelHost = _panelObject.AddComponent<PanelHost>();
			panelHost.Panel = new ProphecyPanel();
			panelHost.ToggleKey = () => ModConfig.PanelKey.Value;
			panelHost.LogError = delegate(string msg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)msg);
			};
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Prophecy] v1.1.5 已加载");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  大幽灵追踪: {ModConfig.Enabled_BigGhostTracker.Value}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  龙卷风追踪: {ModConfig.Enabled_TornadoTracker.Value}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  木桥承载: {ModConfig.Enabled_BridgeCapacity.Value}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  雪山风暴倒计时: {ModConfig.Enabled_SnowStormTimer.Value}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  森蕈风倒计时: {ModConfig.Enabled_FungusWindTimer.Value}");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"  雨林下雨计时: {ModConfig.Enabled_RainTimer.Value}");
		}

		private void Update()
		{
			try
			{
				ExtraInfoOverlay.UpdateOverlay();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("主循环异常: " + ex));
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_panelObject != (Object)null)
			{
				Object.Destroy((Object)(object)_panelObject);
			}
			if ((Object)(object)_overlayObject != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayObject);
			}
			ExtraInfoOverlay.Cleanup();
		}
	}
}
namespace Prophecy.UI
{
	internal abstract class ModPanelBase
	{
		protected const float TitleBarHeight = 32f;

		private const float MinScale = 0.6f;

		private const float MaxScale = 2.5f;

		protected const float ScaleStep = 0.1f;

		private bool _visible;

		private int _tab;

		private Rect _rect;

		private float _scale = 1f;

		private bool _scaleLoaded;

		private bool _resizing;

		private Vector2 _scroll;

		private string _toast;

		private float _toastUntil;

		private bool _savedCursorVisible;

		private bool _cursorForced;

		private Action<KeyCode> _captureSetter;

		private object _captureToken;

		protected virtual int WindowId => 61851;

		protected abstract string Title { get; }

		protected virtual string TitleNote => null;

		protected abstract string[] TabLabels { get; }

		protected virtual float MinWidth => 560f;

		protected virtual float MaxWidth => 1100f;

		protected virtual float MinHeight => 320f;

		protected virtual float MaxHeight => 1000f;

		protected virtual float NavWidth => 104f;

		protected virtual float DefaultWidth => 700f;

		protected virtual float DefaultHeight => 560f;

		public bool Visible => _visible;

		protected int CurrentTab => _tab;

		public bool IsCapturingKey => _captureToken != null;

		protected float Scale => _scale;

		protected abstract void DrawTab(int index);

		protected virtual void DrawStatusStrip()
		{
		}

		protected virtual void OnOpen()
		{
		}

		protected virtual void OnTabChanged(int index)
		{
		}

		protected virtual float LoadScale()
		{
			return 1f;
		}

		protected virtual void SaveScale(float value)
		{
		}

		protected ModPanelBase()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			_rect = new Rect(28f, 28f, DefaultWidth, DefaultHeight);
		}

		public void Toast(string text, float seconds = 2.5f)
		{
			Notify(text, seconds);
		}

		public Rect WindowRectPixels()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			float num = (_scaleLoaded ? _scale : 1f);
			return new Rect(((Rect)(ref _rect)).x * num, ((Rect)(ref _rect)).y * num, ((Rect)(ref _rect)).width * num, ((Rect)(ref _rect)).height * num);
		}

		public void Toggle()
		{
			_visible = !_visible;
			if (_visible)
			{
				OnOpen();
			}
			else
			{
				CancelCapture();
			}
			UpdateCursor();
		}

		public void Close()
		{
			_visible = false;
			CancelCapture();
			UpdateCursor();
		}

		public void Tick()
		{
			UpdateCursor();
		}

		protected void Notify(string text, float seconds = 2.5f)
		{
			_toast = text;
			_toastUntil = Time.unscaledTime + seconds;
		}

		private void UpdateCursor()
		{
			if (_visible)
			{
				if (!_cursorForced)
				{
					_savedCursorVisible = Cursor.visible;
					_cursorForced = true;
				}
				if (!Cursor.visible)
				{
					Cursor.visible = true;
				}
			}
			else if (_cursorForced)
			{
				_cursorForced = false;
				Cursor.visible = _savedCursorVisible;
			}
		}

		public void Draw()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				if (!_scaleLoaded)
				{
					_scaleLoaded = true;
					_scale = Mathf.Clamp(LoadScale(), 0.6f, 2.5f);
				}
				PanelTheme.EnsureBuilt();
				HandleKeyCapture();
				Matrix4x4 matrix = GUI.matrix;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(_scale, _scale, 1f));
				((Rect)(ref _rect)).width = Mathf.Clamp(((Rect)(ref _rect)).width, MinWidth, MaxWidth);
				((Rect)(ref _rect)).height = Mathf.Clamp(((Rect)(ref _rect)).height, MinHeight, MaxHeight);
				float num = (float)Screen.width / _scale;
				float num2 = (float)Screen.height / _scale;
				((Rect)(ref _rect)).x = Mathf.Clamp(((Rect)(ref _rect)).x, 0f - ((Rect)(ref _rect)).width + 120f, Mathf.Max(0f, num - 120f));
				((Rect)(ref _rect)).y = Mathf.Clamp(((Rect)(ref _rect)).y, 0f, Mathf.Max(0f, num2 - 40f));
				_rect = GUI.Window(WindowId, _rect, new WindowFunction(DrawWindowInternal), GUIContent.none, PanelTheme.Window);
				GUI.matrix = matrix;
			}
		}

		private void DrawWindowInternal(int id)
		{
			//IL_003c: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			DrawTitleBar();
			GUILayout.Space(38f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawNav();
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Space(2f);
			DrawStatusStrip();
			_scroll = GUILayout.BeginScrollView(_scroll, false, false, GUIStyle.none, GUI.skin.verticalScrollbar, PanelTheme.Scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			DrawTab(_tab);
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.EndHorizontal();
			DrawFooter();
			DrawResizeHandle();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _rect)).width - 120f, 32f));
		}

		protected virtual float DrawTitleBarExtras(float x)
		{
			return x;
		}

		private void DrawTitleBar()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(new Rect(0f, 0f, ((Rect)(ref _rect)).width, 32f), GUIContent.none, PanelTheme.TitleBar);
			float x = PanelTheme.TitleText.CalcSize(new GUIContent(Title)).x;
			GUI.Label(new Rect(12f, 0f, x + 6f, 32f), Title, PanelTheme.TitleText);
			if (!string.IsNullOrEmpty(TitleNote))
			{
				GUI.Label(new Rect(12f + x + 8f, 0f, 320f, 32f), TitleNote, PanelTheme.TitleNote);
			}
			float num = ((Rect)(ref _rect)).width - 8f - 26f;
			if (GUI.Button(new Rect(num, 6f, 26f, 20f), "×", PanelTheme.Button))
			{
				Close();
			}
			DrawTitleBarExtras(num);
		}

		private void DrawNav()
		{
			GUILayout.BeginVertical(PanelTheme.NavBg, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(NavWidth),
				GUILayout.ExpandHeight(true)
			});
			string[] tabLabels = TabLabels;
			for (int i = 0; i < tabLabels.Length; i++)
			{
				bool flag = _tab == i;
				if (GUILayout.Button(tabLabels[i], flag ? PanelTheme.NavItemOn : PanelTheme.NavItem, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }) && !flag)
				{
					_tab = i;
					OnTabChanged(i);
				}
			}
			GUILayout.FlexibleSpace();
			DrawNavFooter();
			GUILayout.EndVertical();
		}

		protected virtual void DrawNavFooter()
		{
		}

		private void DrawFooter()
		{
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUILayout.Label(Loc("缩放", "Zoom"), PanelTheme.Hint, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) });
			if (GUILayout.Button("-", PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(24f),
				GUILayout.Height(18f)
			}))
			{
				SetScale(_scale - 0.1f);
			}
			GUILayout.Label(PanelWidgets.Fmt(_scale, "0.0") + "x", PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) });
			if (GUILayout.Button("+", PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(24f),
				GUILayout.Height(18f)
			}))
			{
				SetScale(_scale + 0.1f);
			}
			if (GUILayout.Button(Loc("重置", "Reset"), PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(38f),
				GUILayout.Height(18f)
			}))
			{
				SetScale(1f);
			}
			DrawFooterExtras();
			GUILayout.Space(10f);
			if (!string.IsNullOrEmpty(_toast) && Time.unscaledTime < _toastUntil)
			{
				GUIStyle val = new GUIStyle(PanelTheme.Sub);
				val.normal.textColor = PanelTheme.TxtOk;
				GUILayout.Label(_toast, val, Array.Empty<GUILayoutOption>());
			}
			else
			{
				DrawFooterHint();
			}
			GUILayout.FlexibleSpace();
			GUILayout.Space(18f);
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
		}

		protected virtual void DrawFooterHint()
		{
		}

		protected virtual void DrawFooterExtras()
		{
		}

		protected virtual string Loc(string chinese, string english)
		{
			return chinese;
		}

		private void DrawResizeHandle()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Invalid comparison between Unknown and I4
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref _rect)).width - 16f, ((Rect)(ref _rect)).height - 16f, 14f, 14f);
			GUI.Label(val, "◢", PanelTheme.Hint);
			Event current = Event.current;
			if (current != null)
			{
				if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
				{
					_resizing = true;
					current.Use();
				}
				else if (_resizing && (int)current.type == 3)
				{
					((Rect)(ref _rect)).width = Mathf.Clamp(current.mousePosition.x + 8f, MinWidth, MaxWidth);
					((Rect)(ref _rect)).height = Mathf.Clamp(current.mousePosition.y + 8f, MinHeight, MaxHeight);
					current.Use();
				}
				else if (_resizing && (int)current.type == 1)
				{
					_resizing = false;
					current.Use();
				}
			}
		}

		protected void SetScale(float value)
		{
			_scale = Mathf.Clamp(Mathf.Round(value * 100f) / 100f, 0.6f, 2.5f);
			SaveScale(_scale);
		}

		protected unsafe void KeyBindRow(string label, KeyCode current, Action<KeyCode> setter, object token, string hint = null)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(132f) });
			bool flag = _captureToken != null && _captureToken == token;
			if (GUILayout.Button(flag ? Loc("请按下任意键…", "Press any key...") : (((int)current == 0) ? Loc("未绑定", "Not bound") : ((object)(*(KeyCode*)(&current))/*cast due to .constrained prefix*/).ToString()), flag ? PanelTheme.ChipOn : PanelTheme.Button, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(140f),
				GUILayout.Height(21f)
			}))
			{
				if (flag)
				{
					CancelCapture();
				}
				else
				{
					_captureSetter = setter;
					_captureToken = token;
					GUIUtility.keyboardControl = 0;
					Notify(Loc("按 Esc 可取消设置。", "Press Esc to cancel."), 4f);
				}
			}
			if (GUILayout.Button(Loc("清除", "Clear"), PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(46f),
				GUILayout.Height(21f)
			}))
			{
				setter?.Invoke((KeyCode)0);
			}
			GUILayout.EndHorizontal();
			if (!string.IsNullOrEmpty(hint))
			{
				GUILayout.Label(hint, PanelTheme.Hint, Array.Empty<GUILayoutOption>());
			}
		}

		private unsafe void HandleKeyCapture()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (_captureToken == null)
			{
				return;
			}
			Event current = Event.current;
			if (current == null || (int)current.type != 4)
			{
				return;
			}
			KeyCode keyCode = current.keyCode;
			if ((int)keyCode != 0)
			{
				if ((int)keyCode == 27)
				{
					Notify(Loc("已取消按键设置。", "Key binding cancelled."));
				}
				else
				{
					_captureSetter?.Invoke(keyCode);
					Notify(Loc("已设置为 ", "Set to ") + ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString());
				}
				CancelCapture();
				current.Use();
			}
		}

		private void CancelCapture()
		{
			_captureSetter = null;
			_captureToken = null;
		}
	}
	internal sealed class PanelColorItem
	{
		public string Name;

		public string NameEn;

		public string Note;

		public string NoteEn;

		public string Fallback;

		public Func<string> Read;

		public Action<string> Write;
	}
	internal sealed class PanelColorPreset
	{
		public string Name;

		public string NameEn;

		public string[] Hex;
	}
	internal sealed class PanelContrastPair
	{
		public string Name;

		public string NameEn;

		public Func<Color> Fore;

		public Func<Color> Back;

		public float Recommend;
	}
	internal sealed class PanelColorPicker
	{
		private readonly IList<PanelColorItem> _items;

		private readonly IList<PanelColorPreset> _presets;

		private readonly IList<PanelContrastPair> _contrast;

		private readonly Func<string, string, string> _loc;

		private readonly Action _save;

		private readonly Action<string> _notify;

		private readonly string[] _buffer;

		private readonly string[] _synced;

		private int _editing = -1;

		public PanelColorPicker(IList<PanelColorItem> items, IList<PanelColorPreset> presets, IList<PanelContrastPair> contrast, Func<string, string, string> loc, Action save, Action<string> notify)
		{
			_items = items;
			_presets = presets;
			_contrast = contrast;
			_loc = loc;
			_save = save;
			_notify = notify;
			int num = items?.Count ?? 0;
			_buffer = new string[num];
			_synced = new string[num];
		}

		public void Draw()
		{
			if (_items != null && _items.Count != 0)
			{
				DrawPresets();
				DrawColorCard();
				DrawContrastCard();
			}
		}

		private void DrawPresets()
		{
			PanelWidgets.BeginCard(_loc("配色预设", "Presets"));
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (PanelWidgets.Btn(_loc("恢复默认", "Defaults"), 96f))
			{
				for (int i = 0; i < _items.Count; i++)
				{
					WriteItem(_items[i], _items[i].Fallback);
				}
				AfterPreset(_loc("已恢复默认配色。", "Default colours restored."));
			}
			if (_presets != null)
			{
				for (int j = 0; j < _presets.Count; j++)
				{
					PanelColorPreset panelColorPreset = _presets[j];
					if (PanelWidgets.Btn(_loc(panelColorPreset.Name, panelColorPreset.NameEn), 96f))
					{
						for (int k = 0; k < _items.Count && k < panelColorPreset.Hex.Length; k++)
						{
							WriteItem(_items[k], panelColorPreset.Hex[k]);
						}
						AfterPreset(_loc("已改用", "Applied ") + _loc(panelColorPreset.Name, panelColorPreset.NameEn) + _loc("。", "."));
					}
				}
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			PanelWidgets.Hint(_loc("想让小字更清楚就调亮「小字文字色」;下面的对比度检查可以量化这件事。", "To make small text easier to read, brighten the hint colour; the contrast check below quantifies it."));
			PanelWidgets.EndCard();
		}

		private void AfterPreset(string toast)
		{
			if (_save != null)
			{
				_save();
			}
			_editing = -1;
			for (int i = 0; i < _buffer.Length; i++)
			{
				_buffer[i] = null;
				_synced[i] = null;
			}
			if (_notify != null)
			{
				_notify(toast);
			}
		}

		private void DrawColorCard()
		{
			PanelWidgets.BeginCard(_loc("颜色", "Colors"));
			for (int i = 0; i < _items.Count; i++)
			{
				DrawColorRow(i);
			}
			PanelWidgets.Hint(_loc("颜色即时生效并写入配置文件;填错格式的那一项会被忽略,面板保持上一次的有效颜色。", "Changes apply immediately and are saved to the config file. A malformed entry is ignored and the previous colour stays."));
			PanelWidgets.EndCard();
		}

		private void DrawColorRow(int index)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL o