Decompiled source of MandrakeKing v2.0.1

plugins/MandrakeKing.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.IO;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Voice.Unity;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.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 MandrakeKing
{
	internal static class L
	{
		public static bool English;

		public static string T(string chinese, string english)
		{
			if (!English)
			{
				return chinese;
			}
			return english;
		}

		public static void Apply(bool english)
		{
			English = english;
		}
	}
	internal sealed class MandrakeKingCore : MonoBehaviour
	{
		private object _playbackSource;

		private PropertyInfo _sourceClipProp;

		private PropertyInfo _sourceVolumeProp;

		private PropertyInfo _sourceSpatialBlendProp;

		private PropertyInfo _sourcePositionProp;

		private MethodInfo _sourcePlayMethod;

		private bool _playbackInitialized;

		private object _mandrakeClip;

		private string _clipSource;

		private float _clipGainFingerprint;

		private object _broadcastClip;

		private float _broadcastGainFingerprint;

		private int _broadcastSampleRate;

		private static readonly FieldInfo _sfxClipsField = typeof(SFX_Instance).GetField("clips", BindingFlags.Instance | BindingFlags.Public);

		private static Type _audioClipType;

		private static MethodInfo _audioClipCreate;

		private static MethodInfo _audioClipSetData;

		private static MethodInfo _audioClipLoadAudioData;

		private static PropertyInfo _audioClipNameProp;

		private static PropertyInfo _audioClipSamplesProp;

		private static PropertyInfo _audioClipChannelsProp;

		private static PropertyInfo _audioClipFrequencyProp;

		private static Type _audioSourceType;

		private static MethodInfo _audioSourcePlayAtPoint;

		private bool _isScreaming;

		private float _screamEndTime;

		private float _damageAccumulator;

		private float _damageWindowStart;

		private bool _damageWindowActive;

		private float _lastAutoTriggerTime;

		private Coroutine _medicineCoroutine;

		private static bool _medicineRunning;

		private static readonly int StatusCount = Enum.GetValues(typeof(STATUSTYPE)).Length;

		private const float StatusDisplayMax = 100f;

		private static readonly STATUSTYPE[] RemovableStatuses;

		private void InitializePlaybackSource()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			if (_audioSourceType == null)
			{
				return;
			}
			try
			{
				GameObject val = new GameObject("MandrakeKing_PlaybackSource");
				_playbackSource = val.AddComponent(_audioSourceType);
				_sourceClipProp = _audioSourceType.GetProperty("clip");
				_sourceVolumeProp = _audioSourceType.GetProperty("volume");
				_sourceSpatialBlendProp = _audioSourceType.GetProperty("spatialBlend");
				PropertyInfo property = _audioSourceType.GetProperty("transform");
				if (property != null)
				{
					Type propertyType = property.PropertyType;
					_sourcePositionProp = propertyType.GetProperty("position");
				}
				_sourcePlayMethod = _audioSourceType.GetMethod("Play", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
				_playbackInitialized = true;
				Plugin.Log.LogInfo((object)"[尖叫] 持久 AudioSource 初始化成功");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[尖叫] 持久 AudioSource 初始化失败:" + ex.Message));
			}
		}

		private void CacheReflection()
		{
			if (_sfxClipsField == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 反射未找到 SFX_Instance.clips 字段");
				return;
			}
			_audioClipType = _sfxClipsField.FieldType.GetElementType();
			if (_audioClipType == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 无法从 SFX_Instance.clips 反推 AudioClip 类型");
				return;
			}
			_audioClipNameProp = _audioClipType.GetProperty("name", BindingFlags.Instance | BindingFlags.Public);
			_audioClipSamplesProp = _audioClipType.GetProperty("samples", BindingFlags.Instance | BindingFlags.Public);
			_audioClipChannelsProp = _audioClipType.GetProperty("channels", BindingFlags.Instance | BindingFlags.Public);
			_audioClipFrequencyProp = _audioClipType.GetProperty("frequency", BindingFlags.Instance | BindingFlags.Public);
			_audioClipSetData = _audioClipType.GetMethod("SetData", BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
			{
				typeof(float[]),
				typeof(int)
			}, null);
			_audioClipLoadAudioData = _audioClipType.GetMethod("LoadAudioData", BindingFlags.Instance | BindingFlags.Public);
			MethodInfo[] methods = _audioClipType.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo.Name != "Create"))
				{
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length == 5 && !(parameters[0].ParameterType != typeof(string)) && !(parameters[1].ParameterType != typeof(int)) && !(parameters[2].ParameterType != typeof(int)) && !(parameters[3].ParameterType != typeof(int)) && !(parameters[4].ParameterType != typeof(bool)))
					{
						_audioClipCreate = methodInfo;
						break;
					}
				}
			}
			if (_audioClipCreate == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 反射未找到 AudioClip.Create(string,int,int,int,bool)");
				return;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				_audioSourceType = assemblies[i].GetType("UnityEngine.AudioSource");
				if (_audioSourceType != null)
				{
					break;
				}
			}
			if (_audioSourceType == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 反射未找到 UnityEngine.AudioSource 类型");
				return;
			}
			methods = _audioSourceType.GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "PlayClipAtPoint"))
				{
					ParameterInfo[] parameters2 = methodInfo2.GetParameters();
					if (parameters2.Length == 3 && parameters2[0].ParameterType == _audioClipType && parameters2[1].ParameterType == typeof(Vector3) && parameters2[2].ParameterType == typeof(float))
					{
						_audioSourcePlayAtPoint = methodInfo2;
						break;
					}
				}
			}
			if (_audioSourcePlayAtPoint == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 反射未找到 AudioSource.PlayClipAtPoint(AudioClip, Vector3, float)");
			}
			Plugin.Log.LogInfo((object)$"[尖叫] 反射缓存完成:AudioClip={_audioClipType?.Name}, Create={_audioClipCreate != null}, SetData={_audioClipSetData != null}, PlayAtPoint={_audioSourcePlayAtPoint != null}");
		}

		internal object GetOrLoadClip(float gain)
		{
			if (_mandrakeClip != null && _clipGainFingerprint == gain)
			{
				return _mandrakeClip;
			}
			if (_mandrakeClip != null)
			{
				Plugin.Log.LogInfo((object)$"[尖叫] 增益变化 ({_clipGainFingerprint:F2}→{gain:F2}),重建 AudioClip");
				_mandrakeClip = null;
			}
			if (gain <= 1f)
			{
				_mandrakeClip = TryLoadFromSceneSfx();
				if (_mandrakeClip != null)
				{
					_clipSource = "SceneSFX";
					_clipGainFingerprint = gain;
					Plugin.Log.LogInfo((object)$"[尖叫] 场景 SFX 加载成功 (gain={gain:F2}):{DescribeClip(_mandrakeClip)}");
					return _mandrakeClip;
				}
			}
			_mandrakeClip = TryLoadEmbeddedWav(gain);
			if (_mandrakeClip != null)
			{
				_clipSource = "EmbeddedWAV";
				_clipGainFingerprint = gain;
				Plugin.Log.LogInfo((object)$"[尖叫] 内嵌 WAV 加载成功 (gain={gain:F2} 烧入 PCM):{DescribeClip(_mandrakeClip)}");
				return _mandrakeClip;
			}
			Plugin.Log.LogWarning((object)"[尖叫] 两条路径都失败,无法加载 AudioClip");
			return null;
		}

		private object TryLoadFromSceneSfx()
		{
			try
			{
				Object[] array = Resources.FindObjectsOfTypeAll(typeof(SFX_Instance));
				if (array == null || array.Length == 0)
				{
					return null;
				}
				object obj = null;
				int num = -1;
				Object[] array2 = array;
				foreach (Object val in array2)
				{
					if (val == (Object)null || !(_sfxClipsField?.GetValue(val) is Array { Length: not 0 } array3))
					{
						continue;
					}
					object value = array3.GetValue(0);
					if (value != null)
					{
						int num2 = ScoreClipName(val.name ?? "");
						if (num2 > num)
						{
							num = num2;
							obj = value;
						}
					}
				}
				if (obj != null && num > 0)
				{
					return obj;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[尖叫] 场景 SFX 扫描失败:" + ex.Message));
			}
			return null;
		}

		private static int ScoreClipName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return 0;
			}
			if (name.IndexOf("Mandrake", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return 10;
			}
			if (name.IndexOf("Scream", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return 5;
			}
			return 0;
		}

		private object TryLoadEmbeddedWav(float gain, int targetRate = 0)
		{
			if (_audioClipType == null || _audioClipCreate == null || _audioClipSetData == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 反射未就绪,跳过加载");
				return null;
			}
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MandrakeKing.assets.Au_Mandrake_Scream.wav");
				if (stream == null)
				{
					Plugin.Log.LogWarning((object)"[尖叫] 内嵌资源未找到:MandrakeKing.assets.Au_Mandrake_Scream.wav");
					return null;
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				byte[] data = memoryStream.ToArray();
				WavParser.WavInfo wavInfo = WavParser.ParseWavHeader(data);
				if (wavInfo == null || wavInfo.TotalSamples <= 0 || wavInfo.Channels <= 0 || wavInfo.SampleRate <= 0)
				{
					Plugin.Log.LogWarning((object)"[尖叫] WAV 头解析失败");
					return null;
				}
				float[] array = WavParser.ExtractPcmToFloat(data, wavInfo);
				if (array == null || array.Length == 0)
				{
					Plugin.Log.LogWarning((object)"[尖叫] PCM 提取失败");
					return null;
				}
				ApplyGainToSamples(array, gain);
				int num = wavInfo.SampleRate;
				if (targetRate > 0 && targetRate != wavInfo.SampleRate)
				{
					array = ResampleLinear(array, wavInfo.Channels, wavInfo.SampleRate, targetRate);
					num = targetRate;
					Plugin.Log.LogInfo((object)$"[尖叫] 叫声重采样 {wavInfo.SampleRate}Hz → {targetRate}Hz({array.Length} 采样)");
				}
				object[] parameters = new object[5] { "MandrakeScream", array.Length, wavInfo.Channels, num, false };
				object obj = _audioClipCreate.Invoke(null, parameters);
				if (obj == null)
				{
					Plugin.Log.LogWarning((object)"[尖叫] AudioClip.Create 返回 null");
					return null;
				}
				object[] parameters2 = new object[2] { array, 0 };
				if (!(_audioClipSetData.Invoke(obj, parameters2) is bool flag) || !flag)
				{
					Plugin.Log.LogWarning((object)"[尖叫] AudioClip.SetData 返回 false");
					return null;
				}
				if (_audioClipLoadAudioData != null)
				{
					try
					{
						_audioClipLoadAudioData.Invoke(obj, null);
					}
					catch
					{
					}
				}
				return obj;
			}
			catch (TargetInvocationException ex)
			{
				Plugin.Log.LogWarning((object)("[尖叫] AudioClip 内部异常:" + (ex.InnerException?.Message ?? ex.Message)));
				return null;
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("[尖叫] 内嵌 WAV 加载失败:" + ex2.Message));
				return null;
			}
		}

		private static void ApplyGainToSamples(float[] samples, float gain)
		{
			if (gain != 1f)
			{
				for (int i = 0; i < samples.Length; i++)
				{
					float num = samples[i] * gain;
					samples[i] = ((num > 1f) ? 1f : ((num < -1f) ? (-1f) : num));
				}
			}
		}

		private static float[] ResampleLinear(float[] samples, int channels, int fromRate, int toRate)
		{
			if (channels <= 0 || fromRate <= 0 || toRate <= 0 || fromRate == toRate || samples.Length == 0)
			{
				return samples;
			}
			int num = samples.Length / channels;
			if (num <= 0)
			{
				return samples;
			}
			int num2 = (int)Math.Round((double)num * (double)toRate / (double)fromRate);
			if (num2 <= 0)
			{
				return samples;
			}
			float[] array = new float[num2 * channels];
			double num3 = (double)fromRate / (double)toRate;
			for (int i = 0; i < num2; i++)
			{
				double num4 = (double)i * num3;
				int num5 = (int)num4;
				if (num5 >= num - 1)
				{
					num5 = num - 1;
					for (int j = 0; j < channels; j++)
					{
						array[i * channels + j] = samples[num5 * channels + j];
					}
					continue;
				}
				int num6 = num5 + 1;
				float num7 = (float)(num4 - (double)num5);
				for (int k = 0; k < channels; k++)
				{
					float num8 = samples[num5 * channels + k];
					float num9 = samples[num6 * channels + k];
					array[i * channels + k] = num8 + (num9 - num8) * num7;
				}
			}
			return array;
		}

		internal object GetOrLoadBroadcastClip(float gain)
		{
			int encodedSampleRate = VoiceInjector.GetEncodedSampleRate();
			if (_broadcastClip != null && _broadcastGainFingerprint == gain && _broadcastSampleRate == encodedSampleRate)
			{
				return _broadcastClip;
			}
			_broadcastClip = TryLoadEmbeddedWav(gain, encodedSampleRate);
			if (_broadcastClip == null)
			{
				Plugin.Log.LogWarning((object)"[语音广播] 内嵌 WAV 加载失败,回退通用 Clip");
				_broadcastClip = GetOrLoadClip(gain);
				_broadcastGainFingerprint = gain;
				_broadcastSampleRate = encodedSampleRate;
				return _broadcastClip;
			}
			_broadcastGainFingerprint = gain;
			_broadcastSampleRate = encodedSampleRate;
			Plugin.Log.LogInfo((object)$"[语音广播] 广播 Clip 就绪 (gain={gain:F2}, 目标采样率={encodedSampleRate}):{DescribeClip(_broadcastClip)}");
			return _broadcastClip;
		}

		private string DescribeClip(object clip)
		{
			if (clip == null)
			{
				return "null";
			}
			try
			{
				string text = (_audioClipNameProp?.GetValue(clip) as string) ?? "?";
				object obj = _audioClipSamplesProp?.GetValue(clip);
				object obj2 = _audioClipChannelsProp?.GetValue(clip);
				object obj3 = _audioClipFrequencyProp?.GetValue(clip);
				return $"name={text}, samples={obj}, ch={obj2}, freq={obj3}";
			}
			catch
			{
				return clip.GetType().Name;
			}
		}

		internal void PlayLocalScream(Vector3 position)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.LocalMonitorEnabled.Value)
			{
				return;
			}
			object orLoadClip = GetOrLoadClip(1f);
			if (orLoadClip == null)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 无可用 AudioClip,跳过本地播放");
				return;
			}
			if (_audioSourcePlayAtPoint != null)
			{
				try
				{
					_audioSourcePlayAtPoint.Invoke(null, new object[3]
					{
						orLoadClip,
						position,
						Plugin.LocalMonitorGain.Value
					});
					Plugin.Log.LogInfo((object)"[尖叫] 本地播放成功(PlayClipAtPoint)");
					return;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[尖叫] 本地播放异常:" + (ex.InnerException?.Message ?? ex.Message)));
					return;
				}
			}
			Plugin.Log.LogWarning((object)"[尖叫] PlayClipAtPoint 反射不可用,跳过本地播放");
		}

		internal void PlayViaPersistentSource(object clip, Vector3 position, float volume, string tag)
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (clip == null)
			{
				Plugin.Log.LogWarning((object)("[尖叫] " + tag + ":无可用 AudioClip"));
				return;
			}
			if (!_playbackInitialized || _playbackSource == null)
			{
				Plugin.Log.LogWarning((object)("[尖叫] " + tag + ":持久 AudioSource 未初始化"));
				return;
			}
			try
			{
				_sourceClipProp?.SetValue(_playbackSource, clip);
				_sourceVolumeProp?.SetValue(_playbackSource, volume);
				_sourceSpatialBlendProp?.SetValue(_playbackSource, 1f);
				if (_sourcePositionProp != null)
				{
					object obj = _audioSourceType.GetProperty("transform")?.GetValue(_playbackSource);
					if (obj != null)
					{
						_sourcePositionProp.SetValue(obj, position);
					}
				}
				_sourcePlayMethod?.Invoke(_playbackSource, null);
				Plugin.Log.LogInfo((object)$"[尖叫] {tag}播放成功 pos={position}, vol={volume:F2}");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[尖叫] " + tag + "播放异常:" + (ex.InnerException?.Message ?? ex.Message)));
			}
		}

		private void Awake()
		{
			CacheReflection();
			InitializePlaybackSource();
			Plugin.Log.LogInfo((object)"[曼德拉草之王] 核心初始化完成");
		}

		internal void TriggerMandrakeScream(float duration)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (_isScreaming)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyConscious)
			{
				Plugin.Log.LogWarning((object)"[尖叫] 本地角色不可用,跳过");
				return;
			}
			_isScreaming = true;
			_screamEndTime = Time.time + duration;
			Plugin.Log.LogInfo((object)$"[尖叫] 触发!模式={Plugin.PrankMode.Value},持续={duration:F1}s");
			Vector3 center = localCharacter.Center;
			PlayLocalScream(center);
			BroadcastViaVoice(duration);
			if (Plugin.PrankMode.Value == 2)
			{
				_medicineCoroutine = ((MonoBehaviour)this).StartCoroutine(ApplyMedicineSaintOverTime(duration));
			}
		}

		private void BroadcastViaVoice(float duration)
		{
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null || (Object)(object)localCharacter.refs.view == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[语音广播] 无可用 photonView,无法广播");
					return;
				}
				EnsureVoiceInjector(localCharacter);
				object orLoadBroadcastClip = GetOrLoadBroadcastClip(Plugin.MandrakeGainForOthers.Value);
				if (orLoadBroadcastClip == null)
				{
					Plugin.Log.LogWarning((object)"[语音广播] 无可用 AudioClip");
					return;
				}
				VoiceInjector.StartScream(orLoadBroadcastClip, duration);
				Plugin.Log.LogInfo((object)$"[语音广播] 已通过语音通道广播叫声,持续 {duration:F1}s");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[语音广播] 广播失败:" + ex.Message));
			}
		}

		internal static void EnsureVoiceInjector(Character local)
		{
			if ((Object)(object)local == (Object)null)
			{
				return;
			}
			CharacterVoiceHandler[] componentsInChildren = ((Component)((Component)local).transform).GetComponentsInChildren<CharacterVoiceHandler>(true);
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				GameObject gameObject = ((Component)componentsInChildren[0]).gameObject;
				if ((Object)(object)gameObject.GetComponent<VoiceInjector>() == (Object)null)
				{
					gameObject.AddComponent<VoiceInjector>();
					Plugin.Log.LogInfo((object)"[语音广播] 已附加 VoiceInjector 到 CharacterVoiceHandler");
				}
			}
		}

		private void Update()
		{
			HandleManualScream();
			HandleAutoTrigger();
			MonitorScreamEnd();
		}

		private void HandleManualScream()
		{
			//IL_001f: 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_0025: 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)
			if (!_isScreaming && IsInGame() && !PanelHost.CapturingKey)
			{
				KeyCode value = Plugin.SoundKey.Value;
				if ((int)value != 0 && Input.GetKeyDown(value))
				{
					TriggerMandrakeScream(Plugin.ScreamDuration.Value);
				}
			}
		}

		private void HandleAutoTrigger()
		{
			if (_damageWindowActive && Time.time - _damageWindowStart > Plugin.AutoTriggerTimeWindowSeconds.Value)
			{
				_damageWindowActive = false;
				_damageAccumulator = 0f;
			}
		}

		private void MonitorScreamEnd()
		{
			if (_isScreaming && Time.time >= _screamEndTime)
			{
				_isScreaming = false;
				VoiceInjector.StopScream();
				Plugin.Log.LogInfo((object)"[尖叫] 结束");
			}
		}

		internal void OnDamageTaken(float amount)
		{
			Plugin.Log.LogInfo((object)$"[状态触发] 收到状态量: +{amount:F1} (累计={_damageAccumulator:F1}, 阈值={Plugin.AutoTriggerDamageThreshold.Value}, 启用={Plugin.AutoTriggerEnabled.Value})");
			if (Plugin.AutoTriggerEnabled.Value && !(amount <= 0f) && !_isScreaming)
			{
				float value = Plugin.AutoTriggerTimeWindowSeconds.Value;
				if (!_damageWindowActive || Time.time - _damageWindowStart > value)
				{
					_damageAccumulator = 0f;
					_damageWindowStart = Time.time;
					_damageWindowActive = true;
				}
				_damageAccumulator += amount;
				Plugin.Log.LogInfo((object)$"[状态触发] 累计: {_damageAccumulator:F1} / {Plugin.AutoTriggerDamageThreshold.Value}");
				if (_damageAccumulator >= Plugin.AutoTriggerDamageThreshold.Value && Time.time - _lastAutoTriggerTime > Plugin.AutoTriggerCooldownSeconds.Value)
				{
					Plugin.Log.LogInfo((object)"[状态触发] 触发自动尖叫!");
					_lastAutoTriggerTime = Time.time;
					_damageAccumulator = 0f;
					_damageWindowActive = false;
					TriggerMandrakeScream(Plugin.ScreamDuration.Value);
				}
			}
		}

		internal bool IsInGame()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null)
			{
				return localCharacter.data.fullyConscious;
			}
			return false;
		}

		internal string GetAudioStatus()
		{
			if (_mandrakeClip != null)
			{
				return $"已加载({_clipSource}, gain={_clipGainFingerprint:F2})";
			}
			return "未加载(首次触发尖叫时自动加载)";
		}

		private IEnumerator ApplyMedicineSaintOverTime(float totalDuration)
		{
			if (_medicineCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_medicineCoroutine);
				_medicineCoroutine = null;
			}
			if (_medicineRunning)
			{
				Plugin.Log.LogWarning((object)"[药圣] 已有协程在运行,跳过");
				yield break;
			}
			_medicineRunning = true;
			float interval = Plugin.SleepTickIntervalSeconds.Value;
			float value = Plugin.SleepRatePerSecond.Value;
			float ratePerSecond = value / 100f;
			float radius = Plugin.SleepRadiusMeters.Value;
			float elapsed = 0f;
			float totalApplied = 0f;
			float maxTotal = 1f;
			bool warnedNotMaster = false;
			Plugin.Log.LogInfo((object)$"[药圣] 开始:速率={value}/s(100=满状态条), 间隔={interval}s, 半径={radius}m");
			try
			{
				while (elapsed < totalDuration && totalApplied < maxTotal)
				{
					yield return (object)new WaitForSeconds(interval);
					elapsed += interval;
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter == (Object)null)
					{
						continue;
					}
					Vector3 center = localCharacter.Center;
					float num = Mathf.Min(ratePerSecond * interval, maxTotal - totalApplied);
					if (!PhotonNetwork.IsMasterClient)
					{
						if (!warnedNotMaster)
						{
							warnedNotMaster = true;
							Plugin.Log.LogWarning((object)"[药圣] 你不是房主,无法修改队友状态(仅房主可广播他人状态变化)");
						}
						totalApplied += num;
						continue;
					}
					int num2 = 0;
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && allCharacter.data.fullyConscious && !allCharacter.IsLocal && !(Vector3.Distance(center, allCharacter.Center) > radius) && ApplyMedicineSaintTo(allCharacter, num))
						{
							num2++;
						}
					}
					totalApplied += num;
					Plugin.Log.LogInfo((object)$"[药圣] tick: +{num * 100f:F1} 昏睡 (累计={totalApplied * 100f:F1}/100, 影响={num2}人)");
				}
			}
			finally
			{
				_medicineRunning = false;
			}
			Plugin.Log.LogInfo((object)$"[药圣] 结束:耗时={elapsed:F1}s, 累计={totalApplied * 100f:F1}/100");
			_medicineCoroutine = null;
		}

		private bool ApplyMedicineSaintTo(Character target, float amount)
		{
			//IL_0067: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (target.refs == null || (Object)(object)target.refs.afflictions == (Object)null || (Object)(object)target.refs.view == (Object)null)
				{
					return false;
				}
				CharacterAfflictions afflictions = target.refs.afflictions;
				float[] array = new float[StatusCount];
				array[6] += amount;
				float num = amount;
				for (int i = 0; i < RemovableStatuses.Length; i++)
				{
					if (!(num > 0f))
					{
						break;
					}
					STATUSTYPE val = RemovableStatuses[i];
					float currentStatus = afflictions.GetCurrentStatus(val);
					if (!(currentStatus <= 0f))
					{
						float num2 = Mathf.Min(currentStatus, num);
						array[val] -= num2;
						num -= num2;
					}
				}
				target.refs.view.RPC("RPC_ApplyStatusesFromFloatArray", (RpcTarget)0, new object[1] { array });
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[药圣] 施加失败:" + ex.Message));
				return false;
			}
		}

		static MandrakeKingCore()
		{
			STATUSTYPE[] array = new STATUSTYPE[8];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			RemovableStatuses = (STATUSTYPE[])(object)array;
		}
	}
	internal sealed class MandrakeKingMenu : ModPanelBase
	{
		private static readonly STATUSTYPE[] DefaultStatuses = (STATUSTYPE[])(object)new STATUSTYPE[3]
		{
			default(STATUSTYPE),
			(STATUSTYPE)3,
			(STATUSTYPE)10
		};

		protected override int WindowId => 73110;

		protected override string Title => L.T("曼德拉草之王", "Mandrake King");

		protected override string TitleNote => "v2.0.1";

		protected override float NavWidth => 112f;

		protected override float DefaultWidth => 720f;

		protected override float DefaultHeight => 580f;

		protected override string[] TabLabels => new string[5]
		{
			L.T("叫声", "Scream"),
			L.T("药圣曼德拉", "Saint"),
			L.T("自动触发", "Auto"),
			L.T("免疫", "Immune"),
			L.T("音频", "Audio")
		};

		protected override float LoadScale()
		{
			return Plugin.PanelScale.Value;
		}

		protected override void SaveScale(float value)
		{
			Plugin.PanelScale.Value = value;
		}

		protected override void DrawTab(int index)
		{
			switch (index)
			{
			case 0:
				DrawScreamTab();
				break;
			case 1:
				DrawSaintTab();
				break;
			case 2:
				DrawAutoTab();
				break;
			case 3:
				DrawImmunityTab();
				break;
			default:
				DrawAudioTab();
				break;
			}
		}

		protected override float DrawTitleBarExtras(float x)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			x -= 58f;
			if (GUI.Button(new Rect(x, 6f, 52f, 20f), L.English ? "中文" : "EN", PanelTheme.Button))
			{
				bool flag = !L.English;
				Plugin.UseEnglish.Value = flag;
				L.Apply(flag);
			}
			return x;
		}

		protected override void DrawStatusStrip()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Chip(L.T("房主 ", "Master ") + (PhotonNetwork.IsMasterClient ? L.T("是", "Yes") : L.T("否", "No")), PhotonNetwork.IsMasterClient);
			Chip(L.T("模式 ", "Mode ") + ((Plugin.PrankMode.Value == 2) ? L.T("药圣曼德拉", "Saint Mandrake") : L.T("仅音效", "Sound only")), ok: true);
			Chip(L.T("免疫 ", "Immune ") + (Plugin.ImmunityEnabled.Value ? L.T("开", "On") : L.T("关", "Off")), Plugin.ImmunityEnabled.Value);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		protected override void DrawNavFooter()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label(L.T("默认按键 ", "Key ") + ((object)Plugin.MenuKey.Value/*cast due to .constrained prefix*/).ToString(), PanelTheme.Hint, Array.Empty<GUILayoutOption>());
		}

		protected override void DrawFooterHint()
		{
			GUILayout.Label(L.T("拖动标题栏移动,右下角拖拽改大小。", "Drag the title bar to move, bottom-right corner to resize."), PanelTheme.Hint, Array.Empty<GUILayoutOption>());
		}

		private void DrawScreamTab()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			PanelWidgets.BeginCard(L.T("触发", "Trigger"));
			KeyBindRow(L.T("叫声按键", "Scream key"), Plugin.SoundKey.Value, delegate(KeyCode v)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				Plugin.SoundKey.Value = v;
			}, Plugin.SoundKey, L.T("点击右侧按钮后按下想要的键。", "Click the button then press the key you want."));
			float num = PanelWidgets.SliderRow(L.T("持续时间(秒)", "Duration (s)"), Plugin.ScreamDuration.Value, 0.1f, 30f, "0.0");
			if (!Mathf.Approximately(num, Plugin.ScreamDuration.Value))
			{
				Plugin.ScreamDuration.Value = num;
			}
			GUILayout.Space(4f);
			if (PanelWidgets.BtnWide(L.T("立即发出叫声", "Trigger scream now"), PanelTheme.ButtonPrimary))
			{
				Plugin.Core?.TriggerMandrakeScream(Plugin.ScreamDuration.Value);
				Notify(L.T("已发出叫声。", "Scream triggered."));
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("恶作剧模式", "Prank mode"));
			int num2 = PanelWidgets.ChipRow(new string[2]
			{
				L.T("仅音效", "Sound only"),
				L.T("药圣曼德拉", "Saint Mandrake")
			}, Plugin.PrankMode.Value - 1, 124f);
			if (num2 >= 0)
			{
				Plugin.PrankMode.Value = num2 + 1;
			}
			if (Plugin.PrankMode.Value == 2)
			{
				PanelWidgets.Info(L.T("对半径内的队友施加昏睡,同时移除其等量的其它负面状态。", "Puts nearby teammates to sleep and removes an equal amount of their other negative statuses."));
			}
			else
			{
				PanelWidgets.Info(L.T("只播放叫声,不产生任何状态效果。", "Plays the scream only, without any status effect."));
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("说明", "Notes"));
			PanelWidgets.Hint(L.T("叫声会混入语音通道广播,因此房间里没装这个 Mod 的玩家同样能听到。", "The scream is broadcast through the voice channel, so players without this mod can hear it too."));
			PanelWidgets.Hint(L.T("本地监听关闭后,自己听不到,其他人仍然能听到。", "With local monitor off you cannot hear it yourself, but others still can."));
			PanelWidgets.EndCard();
		}

		private void DrawSaintTab()
		{
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			PanelWidgets.BeginCard(L.T("效果范围", "Effect"));
			float num = PanelWidgets.SliderRow(L.T("作用半径(米)", "Radius (m)"), Plugin.SleepRadiusMeters.Value, 5f, 50f, "0");
			if (!Mathf.Approximately(num, Plugin.SleepRadiusMeters.Value))
			{
				Plugin.SleepRadiusMeters.Value = num;
			}
			float num2 = PanelWidgets.SliderRow(L.T("每秒昏睡量", "Sleep per second"), Plugin.SleepRatePerSecond.Value, 0.5f, 100f, "0.#");
			if (!Mathf.Approximately(num2, Plugin.SleepRatePerSecond.Value))
			{
				Plugin.SleepRatePerSecond.Value = num2;
			}
			float num3 = PanelWidgets.SliderRow(L.T("施加间隔(秒)", "Tick interval (s)"), Plugin.SleepTickIntervalSeconds.Value, 0.05f, 2f, "0.00");
			if (!Mathf.Approximately(num3, Plugin.SleepTickIntervalSeconds.Value))
			{
				Plugin.SleepTickIntervalSeconds.Value = num3;
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("数值口径", "Scale"));
			PanelWidgets.KV(L.T("满条", "Full bar"), "100");
			PanelWidgets.KV(L.T("每秒", "Per second"), PanelWidgets.Fmt(Plugin.SleepRatePerSecond.Value, "0.#"));
			PanelWidgets.KV(L.T("约需", "Takes about"), PanelWidgets.Fmt(100f / Mathf.Max(0.5f, Plugin.SleepRatePerSecond.Value), "0.0") + L.T(" 秒睡满", " s to fill"));
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("联机", "Online"));
			if (PhotonNetwork.IsMasterClient)
			{
				PanelWidgets.KVColored(L.T("房主", "Master client"), L.T("可以影响队友", "Can affect teammates"), PanelTheme.TxtOk);
			}
			else
			{
				PanelWidgets.KVColored(L.T("房主", "Master client"), L.T("只有视觉效果", "Local only"), PanelTheme.TxtWarn);
				PanelWidgets.Hint(L.T("游戏的状态同步 RPC 只接受房主发来的数据,因此不是房主时无法真正改变队友的状态。", "The game only accepts status updates from the master client, so teammates' statuses cannot be changed unless you are the master client."));
			}
			PanelWidgets.EndCard();
		}

		private void DrawAutoTab()
		{
			PanelWidgets.BeginCard(L.T("触发条件", "Condition"));
			bool flag = PanelWidgets.ToggleRow(Plugin.AutoTriggerEnabled.Value, L.T("受到所选状态影响时自动发出叫声", "Scream automatically when the selected statuses are gained"));
			if (flag != Plugin.AutoTriggerEnabled.Value)
			{
				Plugin.AutoTriggerEnabled.Value = flag;
			}
			float num = PanelWidgets.SliderRow(L.T("触发阈值", "Threshold"), Plugin.AutoTriggerDamageThreshold.Value, 1f, 100f, "0");
			if (!Mathf.Approximately(num, Plugin.AutoTriggerDamageThreshold.Value))
			{
				Plugin.AutoTriggerDamageThreshold.Value = num;
			}
			float num2 = PanelWidgets.SliderRow(L.T("统计窗口(秒)", "Window (s)"), Plugin.AutoTriggerTimeWindowSeconds.Value, 0.5f, 10f, "0.#");
			if (!Mathf.Approximately(num2, Plugin.AutoTriggerTimeWindowSeconds.Value))
			{
				Plugin.AutoTriggerTimeWindowSeconds.Value = num2;
			}
			float num3 = PanelWidgets.SliderRow(L.T("冷却时间(秒)", "Cooldown (s)"), Plugin.AutoTriggerCooldownSeconds.Value, 1f, 30f, "0.#");
			if (!Mathf.Approximately(num3, Plugin.AutoTriggerCooldownSeconds.Value))
			{
				Plugin.AutoTriggerCooldownSeconds.Value = num3;
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("计入的状态", "Counted statuses"));
			PanelWidgets.Hint(L.T("100 = 一整个状态条。", "100 equals one full bar."));
			GUILayout.Space(2f);
			DrawStatusGrid();
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (PanelWidgets.Btn(L.T("全选", "All"), 60f))
			{
				SetAllStatuses(value: true);
			}
			if (PanelWidgets.Btn(L.T("全不选", "None"), 70f))
			{
				SetAllStatuses(value: false);
			}
			if (PanelWidgets.Btn(L.T("还原默认", "Defaults"), 84f))
			{
				ResetStatuses();
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			PanelWidgets.EndCard();
		}

		private void DrawStatusGrid()
		{
			int statusCount = Plugin.StatusCount;
			for (int i = 0; i < statusCount; i += 3)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				for (int j = 0; j < 3 && i + j < statusCount; j++)
				{
					int num = i + j;
					string text = L.T(Plugin.GetStatusNameCn(num), Plugin.GetStatusNameEn(num));
					bool value = Plugin.AutoTriggerStatusEnabled[num].Value;
					bool flag = GUILayout.Toggle(value, " " + text, PanelTheme.Toggle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(158f) });
					if (flag != value)
					{
						Plugin.AutoTriggerStatusEnabled[num].Value = flag;
					}
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
		}

		private static void SetAllStatuses(bool value)
		{
			for (int i = 0; i < Plugin.StatusCount; i++)
			{
				Plugin.AutoTriggerStatusEnabled[i].Value = value;
			}
		}

		private static void ResetStatuses()
		{
			SetAllStatuses(value: false);
			STATUSTYPE[] defaultStatuses = DefaultStatuses;
			for (int i = 0; i < defaultStatuses.Length; i++)
			{
				int num = Plugin.IndexOfStatus(defaultStatuses[i]);
				if (num >= 0)
				{
					Plugin.AutoTriggerStatusEnabled[num].Value = true;
				}
			}
		}

		private void DrawImmunityTab()
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			PanelWidgets.BeginCard(L.T("曼德拉草昏睡免疫", "Mandrake drowsiness immunity"));
			bool flag = PanelWidgets.ToggleRow(Plugin.ImmunityEnabled.Value, L.T("免疫曼德拉草造成的昏睡", "Immune to drowsiness caused by the mandrake"));
			if (flag != Plugin.ImmunityEnabled.Value)
			{
				Plugin.ImmunityEnabled.Value = flag;
			}
			PanelWidgets.Hint(L.T("对游戏内曼德拉草的叫声,以及本 Mod 通过语音通道广播的叫声都有效。", "Works for both the in-game mandrake scream and screams broadcast by this mod."));
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("当前状态", "Current"));
			PanelWidgets.KVColored(L.T("免疫", "Immunity"), Plugin.ImmunityEnabled.Value ? L.T("已开启", "Enabled") : L.T("已关闭", "Disabled"), Plugin.ImmunityEnabled.Value ? PanelTheme.TxtOk : PanelTheme.TxtWeak);
			PanelWidgets.EndCard();
		}

		private void DrawAudioTab()
		{
			PanelWidgets.BeginCard(L.T("广播", "Broadcast"));
			float num = PanelWidgets.SliderRow(L.T("队友听到的增益", "Gain for others"), Plugin.MandrakeGainForOthers.Value, 0.1f, 5f, "0.00");
			if (!Mathf.Approximately(num, Plugin.MandrakeGainForOthers.Value))
			{
				Plugin.MandrakeGainForOthers.Value = num;
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("本地监听", "Local monitor"));
			bool flag = PanelWidgets.ToggleRow(Plugin.LocalMonitorEnabled.Value, L.T("在本地播放叫声", "Play the scream locally"));
			if (flag != Plugin.LocalMonitorEnabled.Value)
			{
				Plugin.LocalMonitorEnabled.Value = flag;
			}
			float num2 = PanelWidgets.SliderRow(L.T("本机音量", "Local volume"), Plugin.LocalMonitorGain.Value, 0f, 1f, "0.00");
			if (!Mathf.Approximately(num2, Plugin.LocalMonitorGain.Value))
			{
				Plugin.LocalMonitorGain.Value = num2;
			}
			PanelWidgets.Hint(L.T("声源留空时自动使用游戏内的曼德拉草叫声。", "Leave the clip name empty to use the in-game mandrake scream."));
			string text = PanelWidgets.TextBox(Plugin.MandrakeAudioClipName.Value, 260f);
			if (text != Plugin.MandrakeAudioClipName.Value)
			{
				Plugin.MandrakeAudioClipName.Value = text;
			}
			PanelWidgets.EndCard();
			PanelWidgets.BeginCard(L.T("状态", "Status"));
			PanelWidgets.KV(L.T("音频", "Audio"), Plugin.Core?.GetAudioStatus() ?? "-");
			PanelWidgets.EndCard();
		}

		private static void Chip(string label, bool ok)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001b: 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)
			GUIStyle val = new GUIStyle(PanelTheme.Chip);
			val.normal.textColor = (ok ? PanelTheme.TxtOk : PanelTheme.TxtWeak);
			val.fontSize = 12;
			GUILayout.Label(label, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(18f) });
			GUILayout.Space(4f);
		}
	}
	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 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUILayout.Label(L.T("缩放", "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(L.T("重置", "Reset"), PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(38f),
				GUILayout.Height(18f)
			}))
			{
				SetScale(1f);
			}
			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()
		{
		}

		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(118f) });
			bool flag = _captureToken != null && _captureToken == token;
			if (GUILayout.Button(flag ? L.T("请按下任意键…", "Press any key...") : (((int)current == 0) ? L.T("未绑定", "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(L.T("按 Esc 可取消设置。", "Press Esc to cancel."), 4f);
				}
			}
			if (GUILayout.Button(L.T("清除", "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_0054: 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(L.T("已取消按键设置。", "Key binding cancelled."));
				}
				else
				{
					_captureSetter?.Invoke(keyCode);
					Notify(L.T("已设置为 ", "Set to ") + ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString());
				}
				CancelCapture();
				current.Use();
			}
		}

		private void CancelCapture()
		{
			_captureSetter = null;
			_captureToken = null;
		}
	}
	internal sealed class PanelHost : MonoBehaviour
	{
		public ModPanelBase Panel { get; set; }

		public Func<KeyCode> ToggleKey { get; set; } = () => (KeyCode)283;

		public Action<string> LogError { get; set; } = delegate(string msg)
		{
			Debug.LogError((object)("[曼德拉草之王面板] " + msg));
		};

		public static PanelHost Instance { get; private set; }

		public static bool CapturingKey
		{
			get
			{
				if ((Object)(object)Instance != (Object)null && Instance.Panel != null)
				{
					return Instance.Panel.IsCapturingKey;
				}
				return false;
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (Panel == null)
			{
				return;
			}
			try
			{
				Func<KeyCode> toggleKey = ToggleKey;
				if (Pressed((KeyCode)((toggleKey != null) ? ((int)toggleKey()) : 0)))
				{
					Panel.Toggle();
				}
			}
			catch (Exception ex)
			{
				LogError?.Invoke("按键处理异常:" + ex.Message);
			}
			Panel.Tick();
		}

		private static bool Pressed(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return Input.GetKeyDown(key);
			}
			return false;
		}

		private void OnGUI()
		{
			try
			{
				Panel?.Draw();
			}
			catch (Exception arg)
			{
				LogError?.Invoke($"绘制面板异常:{arg}");
			}
		}

		private void OnDestroy()
		{
			Panel?.Close();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal static class PanelTheme
	{
		public static readonly Color ColWindow = Hex(1382172, 0.97f);

		public static readonly Color ColWindowEdge = Hex(3817552);

		public static readonly Color ColTitleBar = Hex(2172206);

		public static readonly Color ColNavBg = Hex(1711396, 0.9f);

		public static readonly Color ColCard = Hex(1974826, 0.92f);

		public static readonly Color ColCardEdge = Hex(3027775);

		public static readonly Color ColBtn = Hex(2567222);

		public static readonly Color ColBtnHover = Hex(3357255);

		public static readonly Color ColBtnActive = Hex(4278874);

		public static readonly Color ColBtnEdge = Hex(4015187);

		public static readonly Color ColPrimary = Hex(12092971);

		public static readonly Color ColPrimaryHover = Hex(14262835);

		public static readonly Color ColDanger = Hex(9321018);

		public static readonly Color ColDangerHover = Hex(11356489);

		public static readonly Color ColSelected = Hex(3095118);

		public static readonly Color ColSelectedEdge = Hex(5927065);

		public static readonly Color ColField = Hex(1053464);

		public static readonly Color ColFieldEdge = Hex(4344411);

		public static readonly Color TxtMain = Hex(15264495);

		public static readonly Color TxtSub = Hex(10989243);

		public static readonly Color TxtWeak = Hex(7962766);

		public static readonly Color TxtAccent = Hex(16763213);

		public static readonly Color TxtOk = Hex(7657114);

		public static readonly Color TxtWarn = Hex(15902298);

		public static readonly Color TxtBad = Hex(15428459);

		private static bool _built;

		private static readonly string[] FontCandidates = new string[10] { "Microsoft YaHei UI", "Microsoft YaHei", "微软雅黑", "Noto Sans SC", "Source Han Sans SC", "PingFang SC", "SimHei", "黑体", "SimSun", "宋体" };

		private static Font _cachedFont;

		private static bool _fontResolved;

		public static bool UseSystemFont { get; set; } = true;

		public static string FontName { get; private set; } = "(Unity 内置)";

		public static Action<string> Log { get; set; } = delegate(string msg)
		{
			PluginInfo.Log(msg);
		};

		public static GUIStyle Window { get; private set; }

		public static GUIStyle TitleBar { get; private set; }

		public static GUIStyle TitleText { get; private set; }

		public static GUIStyle TitleNote { get; private set; }

		public static GUIStyle NavBg { get; private set; }

		public static GUIStyle NavItem { get; private set; }

		public static GUIStyle NavItemOn { get; private set; }

		public static GUIStyle Card { get; private set; }

		public static GUIStyle CardTitle { get; private set; }

		public static GUIStyle Label { get; private set; }

		public static GUIStyle Sub { get; private set; }

		public static GUIStyle Hint { get; private set; }

		public static GUIStyle Value { get; private set; }

		public static GUIStyle Button { get; private set; }

		public static GUIStyle ButtonPrimary { get; private set; }

		public static GUIStyle ButtonDanger { get; private set; }

		public static GUIStyle Mini { get; private set; }

		public static GUIStyle Chip { get; private set; }

		public static GUIStyle ChipOn { get; private set; }

		public static GUIStyle Row { get; private set; }

		public static GUIStyle RowOn { get; private set; }

		public static GUIStyle Field { get; private set; }

		public static GUIStyle Toggle { get; private set; }

		public static GUIStyle Divider { get; private set; }

		public static GUIStyle Scroll { get; private set; }

		public static GUIStyle OnVideoLabel { get; private set; }

		public static GUIStyle Border { get; private set; }

		public static GUIStyle SliderTrack { get; private set; }

		public static GUIStyle SliderThumb { get; private set; }

		public static void Invalidate()
		{
			_built = false;
		}

		private static Color Hex(int rgb, float a = 1f)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)((rgb >> 16) & 0xFF) / 255f, (float)((rgb >> 8) & 0xFF) / 255f, (float)(rgb & 0xFF) / 255f, a);
		}

		public static void EnsureBuilt()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006f: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Expected O, but got Unknown
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: 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_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Expected O, but got Unknown
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Expected O, but got Unknown
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Expected O, but got Unknown
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Expected O, but got Unknown
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Expected O, but got Unknown
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Expected O, but got Unknown
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Expected O, but got Unknown
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Expected O, but got Unknown
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Expected O, but got Unknown
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Expected O, but got Unknown
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0651: Unknown result type (might be due to invalid IL or missing references)
			//IL_0656: Unknown result type (might be due to invalid IL or missing references)
			//IL_0660: Expected O, but got Unknown
			//IL_0665: Expected O, but got Unknown
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Expected O, but got Unknown
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_069e: Expected O, but got Unknown
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: 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_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0738: Expected O, but got Unknown
			//IL_073d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0742: Unknown result type (might be due to invalid IL or missing references)
			//IL_076d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0777: Expected O, but got Unknown
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0781: Unknown result type (might be due to invalid IL or missing references)
			if (!_built || Window == null || !((Object)(object)Window.normal.background != (Object)null))
			{
				_built = true;
				Font val = ResolveFont();
				Window = Solid(ColWindow, ColWindowEdge, 10, 1);
				Window.padding = new RectOffset(0, 0, 0, 0);
				Window.overflow = new RectOffset(0, 0, 0, 0);
				TitleBar = Solid(ColTitleBar, ColTitleBar, 10, 0);
				TitleBar.padding = new RectOffset(12, 12, 0, 0);
				TitleText = Text(val, 14, (FontStyle)1, TxtMain, (TextAnchor)3);
				TitleNote = Text(val, 10, (FontStyle)0, TxtWeak, (TextAnchor)3);
				Label = Text(val, 13, (FontStyle)0, TxtMain, (TextAnchor)3, wrap: true);
				Sub = Text(val, 12, (FontStyle)0, TxtSub, (TextAnchor)3, wrap: true);
				Hint = Text(val, 11, (FontStyle)0, TxtWeak, (TextAnchor)0, wrap: true);
				Value = Text(val, 13, (FontStyle)1, TxtAccent, (TextAnchor)3, wrap: true);
				CardTitle = Text(val, 13, (FontStyle)1, TxtMain, (TextAnchor)3);
				NavBg = Solid(ColNavBg, ColNavBg, 0, 0);
				NavBg.padding = new RectOffset(6, 6, 8, 8);
				NavItem = Clickable(val, 13, new Color(ColNavBg.r, ColNavBg.g, ColNavBg.b, 0f), ColBtnHover, ColSelected, TxtSub, TxtMain, 6, 0);
				NavItem.alignment = (TextAnchor)3;
				NavItem.padding = new RectOffset(10, 6, 0, 0);
				NavItem.margin = new RectOffset(0, 0, 1, 1);
				NavItemOn = Clickable(val, 13, ColSelected, ColSelected, ColSelected, TxtAccent, TxtAccent, 6, 1, ColSelectedEdge);
				NavItemOn.fontStyle = (FontStyle)1;
				NavItemOn.alignment = (TextAnchor)3;
				NavItemOn.padding = new RectOffset(10, 6, 0, 0);
				NavItemOn.margin = new RectOffset(0, 0, 1, 1);
				Card = Solid(ColCard, ColCardEdge, 8, 1);
				Card.padding = new RectOffset(10, 10, 8, 9);
				Card.margin = new RectOffset(0, 0, 3, 5);
				Button = Clickable(val, 12, ColBtn, ColBtnHover, ColBtnActive, TxtMain, Color.white, 6, 1, ColBtnEdge);
				ButtonPrimary = Clickable(val, 12, ColPrimary, ColPrimaryHover, ColPrimaryHover, Hex(1774600), Color.white, 6, 0);
				ButtonPrimary.fontStyle = (FontStyle)1;
				ButtonDanger = Clickable(val, 12, ColDanger, ColDangerHover, ColDangerHover, Hex(16771561), Color.white, 6, 0);
				Mini = Clickable(val, 11, ColBtn, ColBtnHover, ColBtnActive, TxtSub, Color.white, 5, 1, ColBtnEdge);
				Mini.padding = new RectOffset(4, 4, 0, 0);
				Chip = Clickable(val, 11, ColBtn, ColBtnHover, ColBtnActive, TxtSub, Color.white, 9, 1, ColBtnEdge);
				Chip.padding = new RectOffset(6, 6, 2, 2);
				ChipOn = Clickable(val, 11, ColSelected, ColSelected, ColSelected, TxtAccent, TxtAccent, 9, 1, ColSelectedEdge);
				ChipOn.fontStyle = (FontStyle)1;
				ChipOn.padding = new RectOffset(6, 6, 2, 2);
				Row = Clickable(val, 12, Hex(1777446, 0.55f), ColBtnHover, ColBtnActive, TxtMain, Color.white, 5, 0);
				Row.alignment = (TextAnchor)3;
				Row.padding = new RectOffset(8, 8, 0, 0);
				Row.margin = new RectOffset(0, 0, 1, 1);
				RowOn = Clickable(val, 12, ColSelected, ColSelected, ColSelected, TxtAccent, TxtAccent, 5, 1, ColSelectedEdge);
				RowOn.fontStyle = (FontStyle)1;
				RowOn.alignment = (TextAnchor)3;
				RowOn.padding = new RectOffset(8, 8, 0, 0);
				RowOn.margin = new RectOffset(0, 0, 1, 1);
				Field = new GUIStyle(GUI.skin.textField);
				ApplyBg(Field, Nine(ColField, ColFieldEdge, 5, 1), 6);
				Field.normal.textColor = TxtMain;
				Field.focused.textColor = Color.white;
				Field.hover.textColor = TxtMain;
				Field.alignment = (TextAnchor)3;
				Field.padding = new RectOffset(6, 6, 0, 0);
				Field.fontSize = 12;
				if ((Object)(object)val != (Object)null)
				{
					Field.font = val;
				}
				Toggle = new GUIStyle(GUI.skin.toggle);
				Toggle.normal.textColor = TxtSub;
				Toggle.onNormal.textColor = TxtAccent;
				Toggle.hover.textColor = TxtMain;
				Toggle.onHover.textColor = TxtAccent;
				Toggle.fontSize = 12;
				Toggle.padding = new RectOffset(20, 0, 0, 0);
				if ((Object)(object)val != (Object)null)
				{
					Toggle.font = val;
				}
				Divider = Solid(Hex(2896188), Hex(2896188), 0, 0);
				Scroll = new GUIStyle(GUI.skin.scrollView)
				{
					padding = new RectOffset(0, 4, 0, 0)
				};
				OnVideoLabel = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					alignment = (TextAnchor)3,
					padding = new RectOffset(5, 5, 0, 0),
					wordWrap = false
				};
				OnVideoLabel.normal.textColor = TxtMain;
				OnVideoLabel.normal.background = Nine(Hex(724241, 0.78f), Hex(724241, 0.78f), 5, 0);
				if ((Object)(object)val != (Object)null)
				{
					OnVideoLabel.font = val;
				}
				Border = Solid(Hex(724241, 0.95f), Hex(724241, 0.95f), 2, 0);
				SliderTrack = new GUIStyle(GUI.skin.horizontalSlider);
				ApplyBg(SliderTrack, Nine(ColField, ColFieldEdge, 4, 1), 5);
				SliderTrack.fixedHeight = 12f;
				SliderThumb = new GUIStyle(GUI.skin.horizontalSliderThumb);
				ApplyBg(SliderThumb, Nine(ColPrimaryHover, ColPrimaryHover, 5, 0), 6);
				SliderThumb.fixedWidth = 12f;
				SliderThumb.fixedHeight = 17f;
			}
		}

		private static GUIStyle Text(Font font, int size, FontStyle fs, Color color, TextAnchor anchor, bool wrap = false)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_003d: Expected O, but got Unknown
			//IL_0043: 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)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = size,
				fontStyle = fs,
				alignment = anchor,
				wordWrap = wrap,
				padding = new RectOffset(0, 0, 1, 1)
			};
			val.normal.textColor = color;
			val.hover.textColor = color;
			if ((Object)(object)font != (Object)null)
			{
				val.font = font;
			}
			return val;
		}

		private static GUIStyle Solid(Color fill, Color edge, int radius, int border)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_001a: Expected O, but got Unknown
			GUIStyle val = new GUIStyle();
			ApplyBg(val, Nine(fill, edge, radius, border), radius + border + 1);
			return val;
		}

		private static GUIStyle Clickable(Font font, int size, Color normal, Color hover, Color active, Color textNormal, Color textHover, int radius, int border, Color edge = default(Color))
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0043: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = size,
				alignment = (TextAnchor)4,
				wordWrap = false,
				padding = new RectOffset(6, 6, 0, 0),
				margin = new RectOffset(2, 2, 2, 2)
			};
			if ((Object)(object)font != (Object)null)
			{
				val.font = font;
			}
			int num = radius + border + 1;
			Texture2D background = Nine(normal, (border > 0) ? edge : normal, radius, border);
			Texture2D background2 = Nine(hover, (border > 0) ? edge : hover, radius, border);
			Texture2D background3 = Nine(active, (border > 0) ? edge : active, radius, border);
			val.border = new RectOffset(num, num, num, num);
			val.normal.background = background;
			val.hover.background = background2;
			val.active.background = background3;
			val.focused.background = background2;
			val.onNormal.background = background3;
			val.onHover.background = background2;
			val.onActive.background = background3;
			val.onFocused.background = background3;
			val.normal.textColor = textNormal;
			val.hover.textColor = textHover;
			val.active.textColor = textHover;
			val.focused.textColor = textHover;
			val.onNormal.textColor = textHover;
			val.onHover.textColor = textHover;
			val.onActive.textColor = textHover;
			val.onFocused.textColor = textHover;
			return val;
		}

		private static void ApplyBg(GUIStyle s, Texture2D tex, int slice)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			s.border = new RectOffset(slice, slice, slice, slice);
			s.normal.background = tex;
			s.hover.background = tex;
			s.active.background = tex;
			s.focused.background = tex;
			s.onNormal.background = tex;
			s.onHover.background = tex;
			s.onActive.background = tex;
			s.onFocused.background = tex;
		}

		private static Texture2D Nine(Color fill, Color edge, int radius, int border)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			int num = radius + border + 1;
			int num2 = Mathf.Max(4, num * 2 + 2);
			Texture2D val = new Texture2D(num2, num2, (TextureFormat)5, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
			Color[] array = (Color[])(object)new Color[num2 * num2];
			float num3 = Mathf.Max(0.001f, (float)(radius + border));
			float num4 = Mathf.Max(0f, num3 - (float)border);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num2; j++)
				{
					float num5 = (float)j + 0.5f;
					float num6 = (float)i + 0.5f;
					float num7 = Mathf.Max(0f, Mathf.Max(num3 - num5, num5 - ((float)num2 - num3)));
					float num8 = Mathf.Max(0f, Mathf.Max(num3 - num6, num6 - ((float)num2 - num3)));
					float num9 = Mathf.Sqrt(num7 * num7 + num8 * num8);
					float num10 = Mathf.Clamp01(num3 - num9 + 0.5f);
					float num11 = Mathf.Clamp01(num4 - num9 + 0.5f);
					Color val2 = ((border > 0) ? Color.Lerp(edge, fill, num11) : fill);
					val2.a *= num10;
					array[i * num2 + j] = val2;
				}
			}
			val.SetPixels(array);
			val.Apply(false, false);
			return val;
		}

		private static Font ResolveFont()
		{
			if (!UseSystemFont)
			{
				FontName = "(Unity 内置)";
				return null;
			}
			if (_fontResolved && (Object)(object)_cachedFont != (Object)null)
			{
				FontName = ((Object)_cachedFont).name;
				return _cachedFont;
			}
			_fontResolved = true;
			try
			{
				string[] oSInstalledFontNames = Font.GetOSInstalledFontNames();
				string[] fontCandidates = FontCandidates;
				foreach (string text in fontCandidates)
				{
					if (oSInstalledFontNames != null && Array.IndexOf(oSInstalledFontNames, text) >= 0)
					{
						Font val = Font.CreateDynamicFontFromOSFont(text, 14);
						if (!((Object)(object)val == (Object)null))
						{
							((Object)val).hideFlags = (HideFlags)61;
							_cachedFont = val;
							FontName = text;
							Log?.Invoke("面板字体已切换为系统字体:" + text);
							return val;
						}
					}
				}
				Log?.Invoke("未找到候选中文字体,沿用 Unity 内置字体。");
			}
			catch (Exception ex)
			{
				Log?.Invoke("加载系统字体失败,沿用内置字体:" + ex.Message);
			}
			FontName = "(Unity 内置)";
			return null;
		}
	}
	internal static class PanelWidgets
	{
		public static void BeginCard(string title = null)
		{
			GUILayout.BeginVertical(PanelTheme.Card, Array.Empty<GUILayoutOption>());
			if (!string.IsNullOrEmpty(title))
			{
				GUILayout.Label(title, PanelTheme.CardTitle, Array.Empty<GUILayoutOption>());
				Divider();
			}
		}

		public static void EndCard()
		{
			GUILayout.EndVertical();
		}

		public static void Divider()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }), GUIContent.none, PanelTheme.Divider);
			GUILayout.Space(4f);
		}

		public static void Info(string text)
		{
			GUILayout.Label(text, PanelTheme.Sub, Array.Empty<GUILayoutOption>());
		}

		public static void Hint(string text)
		{
			GUILayout.Label(text, PanelTheme.Hint, Array.Empty<GUILayoutOption>());
		}

		public static void Caption(string text, float width)
		{
			GUILayout.Label(text, PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(width) });
		}

		public static void KV(string label, string value, float labelWidth = 96f)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(labelWidth) });
			GUILayout.Label(value, PanelTheme.Value, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		public static void KVColored(string label, string value, Color color, float labelWidth = 96f)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0035: 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(labelWidth) });
			GUIStyle val = new GUIStyle(PanelTheme.Value);
			val.normal.textColor = color;
			GUILayout.Label(value, val, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
		}

		public static bool Btn(string label, float width, GUIStyle style = null, float height = 21f)
		{
			return GUILayout.Button(label, style ?? PanelTheme.Button, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(width),
				GUILayout.Height(height)
			});
		}

		public static bool BtnWide(string label, GUIStyle style = null, float height = 23f)
		{
			return GUILayout.Button(label, style ?? PanelTheme.Button, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(height)
			});
		}

		public static string TextBox(string value, float width)
		{
			return GUILayout.TextField(value ?? string.Empty, PanelTheme.Field, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(width),
				GUILayout.Height(20f)
			});
		}

		public static bool ToggleRow(bool value, string label, string hint = null)
		{
			bool result = GUILayout.Toggle(value, "  " + label, PanelTheme.Toggle, Array.Empty<GUILayoutOption>());
			if (!string.IsNullOrEmpty(hint))
			{
				Hint(hint);
			}
			return result;
		}

		public static float SliderRow(string label, float value, float min, float max, string format = "0.##", float labelWidth = 108f, float valueWidth = 52f)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(labelWidth) });
			float num = GUILayout.HorizontalSlider(value, min, max, PanelTheme.SliderTrack, PanelTheme.SliderThumb, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(18f) });
			GUILayout.Label(Fmt(num, format), PanelTheme.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(valueWidth) });
			GUILayout.EndHorizontal();
			return num;
		}

		public static float NumberRow(string label, float value, float step, float min, float max, string format = "0", float labelWidth = 108f, float valueWidth = 56f)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label, PanelTheme.Sub, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(labelWidth) });
			if (GUILayout.Button("-", PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(26f),
				GUILayout.Height(18f)
			}))
			{
				value = Mathf.Clamp(Mathf.Round(value - step), min, max);
			}
			GUILayout.Label(Fmt(value, format), PanelTheme.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(valueWidth) });
			if (GUILayout.Button("+", PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(26f),
				GUILayout.Height(18f)
			}))
			{
				value = Mathf.Clamp(Mathf.Round(value + step), min, max);
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			return value;
		}

		public static int ChipRow(string[] labels, int selected, float width = 62f)
		{
			int result = -1;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int i = 0; i < labels.Length; i++)
			{
				bool flag = selected == i;
				if (GUILayout.Button(labels[i], flag ? PanelTheme.ChipOn : PanelTheme.Chip, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(width),
					GUILayout.Height(20f)
				}))
				{
					result = i;
				}
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			return result;
		}

		public static string Fmt(float value, string format)
		{
			return value.ToString(format, CultureInfo.InvariantCulture);
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool),
		typeof(bool),
		typeof(bool),
		typeof(bool)
	})]
	internal static class Patch_AddStatus
	{
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (amount <= 0f)
				{
					return true;
				}
				if ((Object)(object)__instance.character == (Object)null || !__instance.character.IsLocal)
				{
					return true;
				}
				if ((int)statusType == 6 && Plugin.ImmunityEnabled.Value && (Patch_MandrakeScreaming.MandrakeImmunityActive || VoiceInjector.IsScreaming))
				{
					return false;
				}
				if (Plugin.IsAutoTriggerStatus(statusType))
				{
					Plugin.Core?.OnDamageTaken(amount * 100f);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[状态检测] 异常: " + ex.Message));
			}
			return true;
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class Patch_MandrakeScreaming
	{
		internal static volatile bool MandrakeImmunityActive;

		private static void Prefix(bool value)
		{
			MandrakeImmunityActive = value;
		}
	}
	[HarmonyPatch(typeof(CharacterVoiceHandler), "PushToTalk")]
	internal static class Patch_PushToTalk
	{
		internal static volatile int ForcedCount;

		private static FieldInfo _recorderField;

		private static bool Prefix(CharacterVoiceHandler __instance)
		{
			if (!VoiceInjector.IsScreaming)
			{
				return true;
			}
			Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent == (Object)null || !componentInParent.IsLocal)
			{
				return true;
			}
			__instance.transmitting = true;
			if (_recorderField == null)
			{
				_recorderField = typeof(CharacterVoiceHandler).GetField("m_Recorder", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _recorderField?.GetValue(__instance);
			Recorder val = (Recorder)((obj is Recorder) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				val.TransmitEnabled = true;
			}
			ForcedCount++;
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterVoiceHandler), "Update")]
	internal static class Patch_VoiceUpdate
	{
		internal static volatile int ForcedCount;

		internal static volatile int LastSkipTick;

		private static FieldInfo _recorderField;

		private static bool Prefix(CharacterVoiceHandler __instance)
		{
			if (!VoiceInjector.IsScreaming)
			{
				return true;
			}
			Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent == (Object)null || !componentInParent.IsLocal)
			{
				return true;
			}
			if (_recorderField == null)
			{
				_recorderField = typeof(CharacterVoiceHandler).GetField("m_Recorder", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			object? obj = _recorderField?.GetValue(__instance);
			Recorder val = (Recorder)((obj is Recorder) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				val.TransmitEnabled = true;
			}
			__instance.transmitting = true;
			ForcedCount++;
			LastSkipTick = Environment.TickCount;
			return false;
		}
	}
	[BepInPlugin("com.peak.mandrakeking", "曼德拉草之王", "2.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.peak.mandrakeking";

		public const string Name = "曼德拉草之王";

		public const string Version = "2.0.1";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> SoundKey;

		internal static ConfigEntry<int> PrankMode;

		internal static ConfigEntry<float> ScreamDuration;

		internal static ConfigEntry<bool> AutoTriggerEnabled;

		internal static ConfigEntry<float> AutoTriggerDamageThreshold;

		internal static ConfigEntry<float> AutoTriggerTimeWindowSeconds;

		internal static ConfigEntry<float> AutoTriggerCooldownSeconds;

		internal static ConfigEntry<bool>[] AutoTriggerStatusEnabled;

		internal static ConfigEntry<bool> ImmunityEnabled;

		internal static ConfigEntry<float> SleepRadiusMeters;

		internal static ConfigEntry<float> SleepRatePerSecond;

		internal static ConfigEntry<float> SleepTickIntervalSeconds;

		internal static ConfigEntry<string> MandrakeAudioClipName;

		internal static ConfigEntry<float> MandrakeGainForOthers;

		internal static ConfigEntry<bool> LocalMonitorEnabled;

		internal static ConfigEntry<float> LocalMonitorGain;

		internal static ConfigEntry<KeyCode> MenuKey;

		internal static ConfigEntry<bool> UseEnglish;

		internal static ConfigEntry<float> PanelScale;

		private static readonly STATUSTYPE[] SupportedStatuses;

		private static readonly string[] StatusNamesCn;

		private static readonly string[] StatusNamesEn;

		private static readonly bool[] StatusDefaults;

		private Harmony _harmony;

		internal static MandrakeKingCore Core;

		internal static Harmony Harmony => Instance?._harmony;

		internal static int StatusCount => SupportedStatuses.Length;

		internal static string GetStatusNameCn(int index)
		{
			if (index < 0 || index >= StatusNamesCn.Length)
			{
				return index.ToString();
			}
			return StatusNamesCn[index];
		}

		internal static string GetStatusNameEn(int index)
		{
			if (index < 0 || index >= StatusNamesEn.Length)
			{
				return index.ToString();
			}
			return StatusNamesEn[index];
		}

		internal static int IndexOfStatus(STATUSTYPE statusType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Array.IndexOf(SupportedStatuses, statusType);
		}

		internal static bool IsAutoTriggerStatus(STATUSTYPE statusType)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool>[] autoTriggerStatusEnabled = AutoTriggerStatusEnabled;
			if (autoTriggerStatusEnabled == null)
			{
				return false;
			}
			int num = IndexOfStatus(statusType);
			if (num >= 0 && num < autoTriggerStatusEnabled.Length)
			{
				return autoTriggerStatusEnabled[num].Value;
			}
			return false;
		}

		private void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Expected O, but got Unknown
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Expected O, but got Unknown
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Expected O, but got Unknown
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Expected O, but got Unknown
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Expected O, but got Unknown
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Expected O, but got Unknown
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			SoundKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Scream", "Sound Key", (KeyCode)104, "手动发出曼德拉草叫声的按键 / Key that triggers the scream manually");
			PrankMode = ((BaseUnityPlugin)this).Config.Bind<int>("Scream", "Prank Mode", 1, new ConfigDescription("恶作剧模式:1=仅音效,2=药圣曼德拉(催眠周围队友并移除其等量其它负面状态)\nMode: 1 = sound only, 2 = Saint Mandrake", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 2), Array.Empty<object>()));
			ScreamDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Scream", "Scream Duration Seconds", 3f, new ConfigDescription("单次叫声持续时间(秒)/ Scream dur