Decompiled source of Scrap Clean v1.1.0

plugins/ScrapClean.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using ExitGames.Client.Photon.StructWrapping;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ScrapClean")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+c2e83835c8cbb5e6276cb69f0fbe350b25ee779a")]
[assembly: AssemblyProduct("ScrapClean")]
[assembly: AssemblyTitle("ScrapClean")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace ScrapClean;

internal static class CenterCache
{
	private const float PruneInterval = 5f;

	private static readonly Dictionary<GameObject, Renderer[]> RendererCache = new Dictionary<GameObject, Renderer[]>(512);

	private static readonly Dictionary<GameObject, int> ChildCountCache = new Dictionary<GameObject, int>(512);

	private static readonly List<GameObject> DeadScratch = new List<GameObject>(16);

	private static float _nextPrune;

	internal static bool TryGetRenderers(GameObject go, List<Renderer> results)
	{
		results.Clear();
		if ((Object)(object)go == (Object)null)
		{
			return false;
		}
		PruneIfStale();
		Renderer[] renderers = GetRenderers(go);
		for (int i = 0; i < renderers.Length; i++)
		{
			if ((Object)(object)renderers[i] != (Object)null)
			{
				results.Add(renderers[i]);
			}
		}
		return results.Count > 0;
	}

	private static Renderer[] GetRenderers(GameObject go)
	{
		int childCount = go.transform.childCount;
		if (RendererCache.TryGetValue(go, out var value) && value != null && ChildCountCache.TryGetValue(go, out var value2) && value2 == childCount && !HasDeadEntry(value))
		{
			return value;
		}
		Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
		RendererCache[go] = componentsInChildren;
		ChildCountCache[go] = childCount;
		return componentsInChildren;
	}

	private static bool HasDeadEntry(Renderer[] renderers)
	{
		for (int i = 0; i < renderers.Length; i++)
		{
			if ((Object)(object)renderers[i] == (Object)null)
			{
				return true;
			}
		}
		return false;
	}

	internal static bool TryGetBounds(GameObject go, out Bounds bounds)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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)
		bounds = default(Bounds);
		if ((Object)(object)go == (Object)null)
		{
			return false;
		}
		PruneIfStale();
		Renderer[] renderers = GetRenderers(go);
		bool flag = false;
		foreach (Renderer val in renderers)
		{
			if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy)
			{
				continue;
			}
			Bounds bounds2 = val.bounds;
			Vector3 size = ((Bounds)(ref bounds2)).size;
			if (!(((Vector3)(ref size)).sqrMagnitude <= 1E-06f))
			{
				if (!flag)
				{
					bounds = bounds2;
					flag = true;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(bounds2);
				}
			}
		}
		return flag;
	}

	internal static Vector3 Center(GameObject go)
	{
		//IL_0009: 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_001b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)go == (Object)null)
		{
			return Vector3.zero;
		}
		if (TryGetBounds(go, out var bounds))
		{
			return ((Bounds)(ref bounds)).center;
		}
		return go.transform.position;
	}

	internal static Vector3 AimReferencePoint(GameObject go, Vector3 rayOrigin, Vector3 rayDirection)
	{
		//IL_0009: 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_002c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)go == (Object)null)
		{
			return Vector3.zero;
		}
		if (!TryGetBounds(go, out var bounds))
		{
			return go.transform.position;
		}
		float num = Vector3.Dot(((Bounds)(ref bounds)).center - rayOrigin, rayDirection);
		if (num < 0f)
		{
			return ((Bounds)(ref bounds)).center;
		}
		Vector3 val = rayOrigin + rayDirection * num;
		return ((Bounds)(ref bounds)).ClosestPoint(val);
	}

	internal static Vector3 OcclusionReferencePoint(GameObject go, Vector3 rayOrigin)
	{
		//IL_0009: 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_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)go == (Object)null)
		{
			return Vector3.zero;
		}
		if (!TryGetBounds(go, out var bounds))
		{
			return go.transform.position;
		}
		return ((Bounds)(ref bounds)).ClosestPoint(rayOrigin);
	}

	internal static void Forget(GameObject go)
	{
		if ((Object)(object)go != (Object)null)
		{
			RendererCache.Remove(go);
			ChildCountCache.Remove(go);
		}
	}

	internal static void Clear()
	{
		RendererCache.Clear();
		ChildCountCache.Clear();
		_nextPrune = 0f;
	}

	private static void PruneIfStale()
	{
		if (Time.unscaledTime < _nextPrune)
		{
			return;
		}
		_nextPrune = Time.unscaledTime + 5f;
		DeadScratch.Clear();
		foreach (KeyValuePair<GameObject, Renderer[]> item in RendererCache)
		{
			if ((Object)(object)item.Key == (Object)null)
			{
				DeadScratch.Add(item.Key);
			}
		}
		for (int i = 0; i < DeadScratch.Count; i++)
		{
			RendererCache.Remove(DeadScratch[i]);
			ChildCountCache.Remove(DeadScratch[i]);
		}
	}
}
internal struct CleanResult
{
	internal int Removed;

	internal int Requested;

	internal int Skipped;
}
internal static class Cleaner
{
	private struct PendingTarget
	{
		internal GameObject Root;

		internal PhotonView View;

		internal Item Item;

		internal float Deadline;

		internal float ClaimAt;
	}

	private const float TakeoverTimeout = 2.5f;

	private const float FixedClaimDelay = 0.9f;

	private static readonly List<PendingTarget> Pending = new List<PendingTarget>();

	private static readonly List<PendingTarget> PendingScratch = new List<PendingTarget>();

	private static bool IsLocallyOwned(PhotonView view)
	{
		if ((Object)(object)view == (Object)null)
		{
			return false;
		}
		if (view.IsMine)
		{
			return true;
		}
		int num = LocalActorNumber();
		if (num <= 0)
		{
			return false;
		}
		if (view.OwnerActorNr == num)
		{
			return true;
		}
		if (view.CreatorActorNr == num)
		{
			if (view.OwnerActorNr != 0 && view.Owner != null)
			{
				return view.Owner.IsInactive;
			}
			return true;
		}
		return false;
	}

	private static int LocalActorNumber()
	{
		if (PhotonNetwork.LocalPlayer == null)
		{
			return -1;
		}
		return PhotonNetwork.LocalPlayer.ActorNumber;
	}

	private static bool EnsureLocalOwnership(PhotonView view)
	{
		if ((Object)(object)view == (Object)null)
		{
			return false;
		}
		if (view.IsMine)
		{
			return true;
		}
		int num = LocalActorNumber();
		if (num <= 0)
		{
			return false;
		}
		try
		{
			view.OwnerActorNr = num;
			view.ControllerActorNr = num;
		}
		catch (Exception ex)
		{
			SCLog.Warn("接管所有权失败:" + ((Object)view).name + " :: " + ex.Message);
		}
		return view.IsMine;
	}

	internal static bool DestroyWithOwnership(PhotonView view, GameObject root)
	{
		if ((Object)(object)view == (Object)null || (Object)(object)root == (Object)null)
		{
			return false;
		}
		if (view.IsMine)
		{
			return DestroyNow(root);
		}
		int ownerActorNr = view.OwnerActorNr;
		int controllerActorNr = view.ControllerActorNr;
		if (!EnsureLocalOwnership(view))
		{
			return false;
		}
		if (DestroyNow(root))
		{
			return true;
		}
		try
		{
			view.OwnerActorNr = ownerActorNr;
			view.ControllerActorNr = controllerActorNr;
		}
		catch (Exception ex)
		{
			SCLog.Verbose("还原所有权失败:" + ex.Message);
		}
		return false;
	}

	internal static void Tick()
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		if (Pending.Count == 0)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		PendingScratch.Clear();
		PendingScratch.AddRange(Pending);
		Pending.Clear();
		for (int i = 0; i < PendingScratch.Count; i++)
		{
			PendingTarget item = PendingScratch[i];
			if ((Object)(object)item.Root == (Object)null || (Object)(object)item.View == (Object)null)
			{
				continue;
			}
			bool isMine = item.View.IsMine;
			if (isMine || unscaledTime >= item.ClaimAt)
			{
				if ((Object)(object)item.Item != (Object)null && ((int)item.Item.itemState != 0 || !item.Root.activeInHierarchy))
				{
					SCLog.Info("目标已被拾取,取消清理:" + ((Object)item.Root).name);
				}
				else if (DestroyWithOwnership(item.View, item.Root))
				{
					if (!isMine)
					{
						SCLog.Info("对方未响应,本机接管并清理:" + ((Object)item.Root).name);
					}
				}
				else
				{
					SCLog.Warn("接管并清理失败,放弃:" + ((Object)item.Root).name);
				}
			}
			else if (unscaledTime >= item.Deadline)
			{
				if (item.ClaimAt < float.MaxValue)
				{
					SCLog.Warn("接管并清理超时,放弃:" + ((Object)item.Root).name);
				}
				else
				{
					SCLog.Warn("对端未在规定时间内删除,放弃:" + ((Object)item.Root).name);
				}
			}
			else
			{
				Pending.Add(item);
			}
		}
	}

	internal static void Reset()
	{
		Pending.Clear();
	}

	internal static bool CleanSingle(ScrapTarget target, out string failure, out bool requested)
	{
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		failure = null;
		requested = false;
		if ((Object)(object)target.Root == (Object)null || (Object)(object)target.View == (Object)null)
		{
			failure = "目标已消失";
			return false;
		}
		if (!TargetScanner.IsStillValid(target))
		{
			failure = "目标状态已改变";
			return false;
		}
		if (IsLocallyOwned(target.View))
		{
			if (!DestroyWithOwnership(target.View, target.Root))
			{
				failure = "无法取得该物体的所有权";
				return false;
			}
			CleanCompanion(target);
			return true;
		}
		if (!ScrapCleanConfig.AllowOwnershipTakeover.Value)
		{
			failure = "该物体不属于你";
			return false;
		}
		if ((int)target.View.OwnershipTransfer != 0)
		{
			if (!RequestTakeover(target.Root, target.View, target.Item))
			{
				failure = "无法请求所有权(未连接房间)";
				return false;
			}
			CleanCompanion(target);
			requested = true;
			return true;
		}
		if (!CleanRequestRelay.RequestRemoteDelete(target.View))
		{
			failure = "无法清理该物体";
			return false;
		}
		QueueFixedClaim(target);
		CleanCompanion(target);
		requested = true;
		return true;
	}

	private static void MarkHandled(ScrapTarget target, HashSet<int> handled)
	{
		if ((Object)(object)target.View != (Object)null && target.View.ViewID != 0)
		{
			handled.Add(target.View.ViewID);
		}
		GameObject companion = target.Companion;
		if (!((Object)(object)companion == (Object)null))
		{
			PhotonView component = companion.GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && component.ViewID != 0)
			{
				handled.Add(component.ViewID);
			}
		}
	}

	private static void CleanCompanion(ScrapTarget target)
	{
		GameObject companion = target.Companion;
		if ((Object)(object)companion == (Object)null)
		{
			return;
		}
		PhotonView component = companion.GetComponent<PhotonView>();
		if (!((Object)(object)component == (Object)null))
		{
			if (IsLocallyOwned(component))
			{
				DestroyWithOwnership(component, companion);
			}
			else if (CleanRequestRelay.RequestRemoteDelete(component))
			{
				QueueFixedClaim(component, companion, null);
			}
		}
	}

	internal static CleanResult CleanArea(Vector3 center, float radius, List<ScrapTarget> targets, out string failure)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		failure = null;
		CleanResult result = default(CleanResult);
		float num = radius * radius;
		HashSet<int> hashSet = new HashSet<int>();
		for (int i = 0; i < targets.Count; i++)
		{
			ScrapTarget target = targets[i];
			if ((Object)(object)target.Root == (Object)null || (Object)(object)target.View == (Object)null || (target.View.ViewID != 0 && hashSet.Contains(target.View.ViewID)))
			{
				continue;
			}
			Vector3 val = target.Center - center;
			if (((Vector3)(ref val)).sqrMagnitude > num || !TargetScanner.IsStillValid(target))
			{
				continue;
			}
			if (IsLocallyOwned(target.View))
			{
				if (!DestroyWithOwnership(target.View, target.Root))
				{
					result.Skipped++;
					continue;
				}
				MarkHandled(target, hashSet);
				CleanCompanion(target);
				result.Removed++;
			}
			else if (!ScrapCleanConfig.AllowOwnershipTakeover.Value)
			{
				result.Skipped++;
			}
			else if ((int)target.View.OwnershipTransfer != 0)
			{
				if (!RequestTakeover(target.Root, target.View, target.Item))
				{
					result.Skipped++;
					continue;
				}
				MarkHandled(target, hashSet);
				CleanCompanion(target);
				result.Requested++;
			}
			else if (CleanRequestRelay.RequestRemoteDelete(target.View))
			{
				QueueFixedClaim(target);
				MarkHandled(target, hashSet);
				CleanCompanion(target);
				result.Requested++;
			}
			else
			{
				result.Skipped++;
			}
		}
		if (result.Removed == 0 && result.Requested == 0 && result.Skipped > 0)
		{
			failure = "圆内目标均无法清理";
		}
		return result;
	}

	internal static bool CanClean(ScrapTarget target, out string reason)
	{
		reason = null;
		if ((Object)(object)target.Root == (Object)null || (Object)(object)target.View == (Object)null)
		{
			reason = "目标已消失";
			return false;
		}
		if (IsLocallyOwned(target.View))
		{
			return true;
		}
		if (!ScrapCleanConfig.AllowOwnershipTakeover.Value)
		{
			reason = "不属于你";
			return false;
		}
		return true;
	}

	private static void QueueFixedClaim(ScrapTarget target)
	{
		QueueFixedClaim(target.View, target.Root, target.Item);
	}

	private static void QueueFixedClaim(PhotonView view, GameObject root, Item item)
	{
		if ((Object)(object)root == (Object)null || (Object)(object)view == (Object)null || !ScrapCleanConfig.AllowOwnershipTakeover.Value)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		for (int i = 0; i < Pending.Count; i++)
		{
			if ((Object)(object)Pending[i].Root == (Object)(object)root)
			{
				PendingTarget value = Pending[i];
				value.Deadline = unscaledTime + 2.5f;
				value.ClaimAt = unscaledTime + 0.9f;
				Pending[i] = value;
				return;
			}
		}
		Pending.Add(new PendingTarget
		{
			Root = root,
			View = view,
			Item = item,
			Deadline = unscaledTime + 2.5f,
			ClaimAt = unscaledTime + 0.9f
		});
	}

	private static bool RequestTakeover(GameObject root, PhotonView view, Item item)
	{
		if (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)
		{
			return false;
		}
		int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1));
		if (num <= 0)
		{
			return false;
		}
		for (int i = 0; i < Pending.Count; i++)
		{
			if ((Object)(object)Pending[i].Root == (Object)(object)root)
			{
				PendingTarget value = Pending[i];
				value.Deadline = Time.unscaledTime + 2.5f;
				Pending[i] = value;
				return true;
			}
		}
		Pending.Add(new PendingTarget
		{
			Root = root,
			View = view,
			Item = item,
			Deadline = Time.unscaledTime + 2.5f,
			ClaimAt = float.MaxValue
		});
		try
		{
			view.TransferOwnership(num);
		}
		catch (Exception ex)
		{
			SCLog.Warn("请求接管所有权失败:" + ((Object)root).name + " :: " + ex.Message);
		}
		return true;
	}

	private static bool DestroyNow(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return false;
		}
		string text;
		try
		{
			text = ((Object)root).name;
		}
		catch (Exception)
		{
			text = "<已销毁>";
		}
		try
		{
			if (PhotonNetwork.InRoom || PhotonNetwork.OfflineMode)
			{
				PhotonNetwork.Destroy(root);
			}
			else
			{
				Object.Destroy((Object)(object)root);
			}
			CenterCache.Forget(root);
			return true;
		}
		catch (Exception ex2)
		{
			SCLog.Warn("删除物体失败:" + text + " :: " + ex2.Message);
			return false;
		}
	}
}
internal enum CleanModeKind
{
	Single,
	Area
}
[DefaultExecutionOrder(-300)]
internal sealed class CleanMode : MonoBehaviour
{
	private const float MinSingleRange = 1f;

	private readonly List<ScrapTarget> _targets = new List<ScrapTarget>(256);

	private readonly HighlightRenderer _highlight = new HighlightRenderer();

	private CleanModeKind _mode;

	private bool _active;

	private CleanUI _ui;

	private GroundRing _ring;

	private ScrapTarget _nearest;

	private bool _hasNearest;

	private string _labelText;

	private GameObject _labelTargetRoot;

	private int _labelAngle = -1;

	private bool _hasLabelTarget;

	private bool _fovWarned;

	private readonly HashSet<string> _loggedRejects = new HashSet<string>();

	private const int MaxLoggedRejects = 2048;

	internal bool SuppressGameplayInput { get; private set; }

	private static float HintHold()
	{
		ConfigEntry<float> toastSeconds = ScrapCleanConfig.ToastSeconds;
		if (toastSeconds == null || !(toastSeconds.Value > 0f))
		{
			return 2f;
		}
		return toastSeconds.Value;
	}

	private static float AimMaxDistance()
	{
		ConfigEntry<float> singleRange = ScrapCleanConfig.SingleRange;
		float num = ((singleRange != null && singleRange.Value > 0f) ? singleRange.Value : 100f);
		return Mathf.Max(1f, num);
	}

	private static float AreaRadiusSafe()
	{
		return Mathf.Clamp(ScrapCleanConfig.AreaRadius?.Value ?? 3f, 0.5f, 50f);
	}

	private static Vector3 PlayerCenter(Character local)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			return local.Center;
		}
		catch (Exception)
		{
			return ((Component)local).transform.position;
		}
	}

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		_ui = ((Component)this).gameObject.AddComponent<CleanUI>();
		GameObject val = new GameObject("ScrapCleanRingHost");
		val.transform.SetParent(((Component)this).transform, false);
		_ring = val.AddComponent<GroundRing>();
		CleanRequestRelay.Ensure(((Component)this).gameObject);
		HarmonyPatches.Register(this);
		SceneManager.sceneLoaded += OnSceneLoaded;
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		TargetScanner.Invalidate();
		CenterCache.Clear();
		CleanRequestRelay.ResetRequestCooldowns();
		_loggedRejects.Clear();
		SCLog.ResetDiagnostics();
		if (_active)
		{
			ExitMode(silent: true);
		}
	}

	private void OnDisable()
	{
		SuppressGameplayInput = false;
		_highlight.Clear();
		_ring?.SetVisible(visible: false);
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		HarmonyPatches.Register(null);
		ExitMode(silent: true);
		SuppressGameplayInput = false;
		_highlight.Clear();
		CenterCache.Clear();
		TargetScanner.Invalidate();
	}

	private void Update()
	{
		try
		{
			Tick();
		}
		catch (Exception ex)
		{
			SCLog.Error("清理模式更新出错,已退出:" + ex);
			try
			{
				ExitMode(silent: false);
			}
			finally
			{
				SuppressGameplayInput = false;
			}
		}
	}

	private void Tick()
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		Cleaner.Tick();
		bool num = IsContextValid();
		if (!num && _active)
		{
			ExitMode(silent: true);
		}
		if (!num)
		{
			SuppressGameplayInput = false;
			_highlight.Clear();
			_ring?.SetVisible(visible: false);
			_ui?.HideSelectionLabel();
			_ui?.HideImmediate();
			return;
		}
		bool flag = IsInputBlocked(GUIManager.instance);
		if (SCInput.KeyDown(ScrapCleanConfig.ToggleKey.Value))
		{
			if (_active)
			{
				ExitMode(silent: false);
			}
			else if (!flag)
			{
				EnterMode();
			}
			return;
		}
		if (!_active)
		{
			SuppressGameplayInput = false;
			_highlight.EndFrame();
			_ring?.SetVisible(visible: false);
			_ui?.HideSelectionLabel();
			return;
		}
		if (flag)
		{
			SuppressGameplayInput = false;
			_highlight.Clear();
			_ring?.SetVisible(visible: false);
			_ui?.HideSelectionLabel();
			_ui?.HideImmediate();
			return;
		}
		SuppressGameplayInput = true;
		HandleScroll();
		Vector3 val = PlayerCenter(Character.localCharacter);
		Vector3 val2;
		float num2;
		if (_mode == CleanModeKind.Area)
		{
			if (!TryGetAimPoint(out var point, out var normal))
			{
				_targets.Clear();
				_hasNearest = false;
				_highlight.Clear();
				_ring?.SetVisible(visible: false);
				SetLabel("范围清理:请将准星对准要清理的表面");
				if (SCInput.LeftClickDown())
				{
					_ui?.ShowHint("请将准星对准要清理的表面", 1.2f);
				}
				return;
			}
			val2 = point;
			num2 = AreaRadiusSafe();
			_ring?.Rebuild(point, num2, normal);
		}
		else
		{
			val2 = val;
			num2 = Mathf.Max(1f, ScrapCleanConfig.SingleRange.Value);
			_ring?.SetVisible(visible: false);
		}
		TargetScanner.Collect(val2, num2, _targets);
		HandleHighlight(val2, num2);
		if (SCInput.LeftClickDown())
		{
			HandleClick();
		}
	}

	private static bool IsInputBlocked(GUIManager gui)
	{
		if ((Object)(object)gui == (Object)null)
		{
			return true;
		}
		try
		{
			if (gui.windowBlockingInput || gui.wheelActive || GUIManager.InPauseMenu)
			{
				return true;
			}
		}
		catch (Exception ex)
		{
			SCLog.WarnThrottled("gui.blocked", "读取游戏 UI 状态失败,本次视为被 UI 占用:" + ex.Message);
			return true;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null)
		{
			if (!localCharacter.data.usingEmoteWheel)
			{
				return localCharacter.data.usingBackpackWheel;
			}
			return true;
		}
		return false;
	}

	private void LogAimDiagnostics()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (ScrapCleanConfig.VerboseLogs == null || !ScrapCleanConfig.VerboseLogs.Value)
		{
			return;
		}
		MainCamera instance = MainCamera.instance;
		if ((Object)(object)instance == (Object)null)
		{
			SCLog.Verbose("准星诊断:MainCamera 为空。");
			return;
		}
		Transform transform = ((Component)instance).transform;
		RaycastHit val = HelperFunctions.LineCheck(transform.position, transform.position + transform.forward * AimMaxDistance(), (LayerType)0, 0f, (QueryTriggerInteraction)1);
		if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
		{
			SCLog.Verbose("准星诊断:射线未命中任何实体层。");
			return;
		}
		GameObject gameObject = ((Component)((RaycastHit)(ref val)).collider).gameObject;
		SCLog.Verbose("准星诊断:命中 " + ((Object)gameObject).name + " 距离 " + ((RaycastHit)(ref val)).distance.ToString("0.0") + "m 层 " + LayerMask.LayerToName(gameObject.layer) + " IsItem=" + ((Object)(object)gameObject.GetComponentInParent<Item>() != (Object)null) + " IsPhotonView=" + ((Object)(object)gameObject.GetComponentInParent<PhotonView>() != (Object)null));
	}

	private void HandleScroll()
	{
		int num = SCInput.ScrollNotch();
		if (num != 0)
		{
			_mode = ((_mode == CleanModeKind.Single) ? CleanModeKind.Area : CleanModeKind.Single);
			AnnounceMode(num > 0);
		}
	}

	private void AnnounceMode(bool upward)
	{
		if (_mode == CleanModeKind.Single)
		{
			_ui?.ShowSwitch("▣ 单选清理", "滚轮切换模式 · 左键清理目标", upward, HintHold());
		}
		else
		{
			_ui?.ShowSwitch("◎ 范围清理", "滚轮切换模式 · 左键清理圆内目标", upward, HintHold());
		}
	}

	private void HandleHighlight(Vector3 queryCenter, float queryRadius)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (_mode == CleanModeKind.Area)
		{
			_hasNearest = false;
			_nearest = default(ScrapTarget);
			int num = 0;
			for (int i = 0; i < _targets.Count; i++)
			{
				ScrapTarget scrapTarget = _targets[i];
				if (!((Object)(object)scrapTarget.Root == (Object)null))
				{
					Vector3 val = scrapTarget.Center - queryCenter;
					if (!(((Vector3)(ref val)).sqrMagnitude > queryRadius * queryRadius))
					{
						_highlight.Mark(scrapTarget.Root);
						num++;
					}
				}
			}
			_highlight.EndFrame();
			SetLabel((num > 0) ? ("范围清理:将清理 " + num + " 个目标") : "范围清理:圆内没有目标");
			return;
		}
		_hasNearest = TryFindAimedTarget(out _nearest, out var bestAngle);
		if (_hasNearest)
		{
			_highlight.Mark(_nearest.Root);
			int num2 = Mathf.RoundToInt(bestAngle);
			if (!_hasLabelTarget || (Object)(object)_labelTargetRoot != (Object)(object)_nearest.Root || _labelAngle != num2)
			{
				_labelTargetRoot = _nearest.Root;
				_labelAngle = num2;
				_hasLabelTarget = true;
				SetLabel(KindName(_nearest.Kind) + ":" + Truncate(_nearest.Label, 24) + "(偏角 " + num2 + "°)");
			}
		}
		else
		{
			_hasLabelTarget = false;
			SetLabel("请将准星对准要清理的目标");
		}
		_highlight.EndFrame();
	}

	private void SetLabel(string text)
	{
		if (!string.Equals(_labelText, text, StringComparison.Ordinal))
		{
			_labelText = text;
			_ui?.SetSelectionLabel(text);
		}
	}

	private static string KindName(ScrapKind kind)
	{
		if (kind != ScrapKind.Dropped)
		{
			return "放置物";
		}
		return "掉落物";
	}

	private void HandleClick()
	{
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		LogAimDiagnostics();
		if (_mode == CleanModeKind.Single)
		{
			if (!_hasNearest)
			{
				_ui?.ShowHint("附近没有可清理的目标", 1.2f);
				return;
			}
			SCLog.Info("清理尝试(单选):" + ((Object)_nearest.Root).name + " 类型 " + KindName(_nearest.Kind) + " IsMine=" + _nearest.View.IsMine + " Owner=" + _nearest.View.OwnerActorNr + " Creator=" + _nearest.View.CreatorActorNr + " 本地=" + ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)) + " 所有权 " + ((object)Unsafe.As<OwnershipOption, OwnershipOption>(ref _nearest.View.OwnershipTransfer)/*cast due to .constrained prefix*/).ToString());
			if (!Cleaner.CanClean(_nearest, out var reason))
			{
				_ui?.ShowHint(reason, 1.2f);
				return;
			}
			string text = Truncate(_nearest.Label, 18);
			if (!Cleaner.CleanSingle(_nearest, out var failure, out var requested))
			{
				SCLog.Warn("清理失败:" + ((Object)_nearest.Root).name + " :: " + failure);
				_ui?.ShowHint(failure ?? "清理失败", 1.2f);
				return;
			}
			SCLog.Info("清理" + (requested ? "请求" : "执行") + "成功:" + ((Object)_nearest.Root).name);
			_ui?.ShowHint(requested ? ("已请求清理:" + text) : ("已清理:" + text), 0.9f);
			_hasNearest = false;
			_nearest = default(ScrapTarget);
			return;
		}
		if (!TryGetAimPoint(out var point, out var _))
		{
			_ui?.ShowHint("请将准星对准要清理的表面", 1.2f);
			return;
		}
		float radius = AreaRadiusSafe();
		string failure2;
		CleanResult cleanResult = Cleaner.CleanArea(point, radius, _targets, out failure2);
		int num = cleanResult.Removed + cleanResult.Requested;
		if (num == 0)
		{
			_ui?.ShowHint(failure2 ?? "圆内没有可清理的目标", 1.2f);
			return;
		}
		string text2 = "已清理 " + num + " 个目标";
		if (cleanResult.Requested > 0)
		{
			text2 = text2 + "(" + cleanResult.Requested + " 个已请求)";
		}
		if (cleanResult.Skipped > 0)
		{
			text2 = text2 + ",跳过 " + cleanResult.Skipped;
		}
		_ui?.ShowHint(text2, 1.2f);
	}

	private bool TryFindAimedTarget(out ScrapTarget best, out float bestAngle)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//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_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: 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_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: 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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		best = default(ScrapTarget);
		bestAngle = float.MaxValue;
		MainCamera instance = MainCamera.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		if ((Object)(object)((Component)instance).GetComponent<Camera>() == (Object)null)
		{
			return false;
		}
		Transform transform = ((Component)instance).transform;
		Vector3 position = transform.position;
		Vector3 forward = transform.forward;
		Vector3 val = position + forward * 0.05f;
		float num = AimMaxDistance();
		float num2 = num * num;
		bool result = false;
		float num3 = float.MaxValue;
		for (int i = 0; i < _targets.Count; i++)
		{
			ScrapTarget scrapTarget = _targets[i];
			if ((Object)(object)scrapTarget.Root == (Object)null || (Object)(object)scrapTarget.View == (Object)null)
			{
				continue;
			}
			Vector3 val2 = scrapTarget.Center - position;
			if (((Vector3)(ref val2)).sqrMagnitude > num2)
			{
				continue;
			}
			bool flag;
			try
			{
				flag = MainCamera.PointWouldBeInFieldOfView(transform, scrapTarget.Center, 1.35f);
			}
			catch (Exception ex)
			{
				WarnFovOnce(ex);
				continue;
			}
			if (!flag)
			{
				continue;
			}
			Vector3 val3 = CenterCache.AimReferencePoint(scrapTarget.Root, position, forward);
			Vector3 val4 = CenterCache.OcclusionReferencePoint(scrapTarget.Root, position);
			Vector3 val5 = val3 - position;
			float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude;
			if (sqrMagnitude <= 0.0001f || sqrMagnitude > num2)
			{
				continue;
			}
			bool flag2;
			try
			{
				flag2 = MainCamera.PointWouldBeInFieldOfView(transform, val3, 1f);
			}
			catch (Exception ex2)
			{
				WarnFovOnce(ex2);
				continue;
			}
			if (!flag2)
			{
				LogRejectOnce(((Object)scrapTarget.Root).name, "不在视野锥内", null);
				continue;
			}
			float num4 = Vector3.Distance(position, val4);
			RaycastHit val6 = HelperFunctions.LineCheck(val, val4, (LayerType)1, 0f, (QueryTriggerInteraction)1);
			if ((Object)(object)((RaycastHit)(ref val6)).collider != (Object)null && ((RaycastHit)(ref val6)).distance < num4 - 0.15f)
			{
				LogRejectOnce(((Object)scrapTarget.Root).name, "被遮挡", " 遮挡物 " + ((Object)((Component)((RaycastHit)(ref val6)).collider).gameObject).name + " 遮挡距离 " + ((RaycastHit)(ref val6)).distance.ToString("0.0") + " 目标距离 " + num4.ToString("0.0"));
			}
			else
			{
				float num5 = Vector3.Angle(forward, val5);
				if (num5 < bestAngle - 0.001f || (Mathf.Abs(num5 - bestAngle) <= 0.001f && sqrMagnitude < num3))
				{
					best = scrapTarget;
					bestAngle = num5;
					num3 = sqrMagnitude;
					result = true;
				}
			}
		}
		return result;
	}

	private static void WarnOnce(ref bool flag, string message)
	{
		if (!flag)
		{
			flag = true;
			SCLog.Warn(message);
		}
	}

	private void WarnFovOnce(Exception ex)
	{
		if (!_fovWarned)
		{
			_fovWarned = true;
			SCLog.Warn("视野判定异常,已跳过该目标:" + ((ex != null) ? ex.Message : "unknown"));
		}
	}

	private void LogRejectOnce(string rootName, string reason, string detail)
	{
		if (ScrapCleanConfig.VerboseLogs != null && ScrapCleanConfig.VerboseLogs.Value && _loggedRejects.Add(rootName))
		{
			if (_loggedRejects.Count > 2048)
			{
				_loggedRejects.Clear();
			}
			SCLog.Verbose("单选拒绝(" + reason + "):" + rootName + (detail ?? string.Empty));
		}
	}

	private static bool TryGetAimPoint(out Vector3 point, out Vector3 normal)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		point = Vector3.zero;
		normal = Vector3.up;
		MainCamera instance = MainCamera.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		Transform transform = ((Component)instance).transform;
		RaycastHit val = HelperFunctions.LineCheck(transform.position, transform.position + transform.forward * AimMaxDistance(), (LayerType)1, 0f, (QueryTriggerInteraction)1);
		if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
		{
			return false;
		}
		point = ((RaycastHit)(ref val)).point;
		normal = ((RaycastHit)(ref val)).normal;
		return true;
	}

	private static bool IsContextValid()
	{
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null)
		{
			return false;
		}
		if ((Object)(object)GUIManager.instance == (Object)null)
		{
			return false;
		}
		if (LoadingScreenHandler.loading)
		{
			return false;
		}
		if ((Object)(object)localCharacter.data == (Object)null || localCharacter.data.dead || localCharacter.data.fullyPassedOut)
		{
			return false;
		}
		return true;
	}

	private void EnterMode()
	{
		_active = true;
		_mode = CleanModeKind.Single;
		SuppressGameplayInput = true;
		_labelText = null;
		_labelTargetRoot = null;
		_hasLabelTarget = false;
		SCInput.ResetScrollTracking();
		_ui?.ShowMode("▣ 单选清理", "滚轮切换模式 · 左键清理目标", entering: true, HintHold());
		SCLog.Info("进入清理模式。");
	}

	private void ExitMode(bool silent)
	{
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		bool active = _active;
		_active = false;
		SuppressGameplayInput = false;
		SCInput.ResetScrollTracking();
		_hasNearest = false;
		_nearest = default(ScrapTarget);
		_labelText = null;
		_labelTargetRoot = null;
		_hasLabelTarget = false;
		_targets.Clear();
		try
		{
			Cleaner.Reset();
			_highlight.Clear();
			_ring?.SetVisible(visible: false);
			_ui?.HideSelectionLabel();
			if (active && !silent)
			{
				_ui?.ShowMode("○ 退出清理", "按 " + ((object)ScrapCleanConfig.ToggleKey.Value/*cast due to .constrained prefix*/).ToString() + " 重新进入", entering: false, HintHold());
			}
			else if (active)
			{
				_ui?.HideImmediate();
			}
		}
		finally
		{
			SuppressGameplayInput = false;
		}
		if (active)
		{
			SCLog.Info("退出清理模式。");
		}
	}

	private static string Truncate(string value, int max)
	{
		if (string.IsNullOrEmpty(value) || value.Length <= max)
		{
			return value;
		}
		return value.Substring(0, max) + "…";
	}
}
internal sealed class CleanRequestRelay : MonoBehaviour, IOnEventCallback
{
	private const byte EventCode = 190;

	private const byte KeyViewId = 1;

	private const byte KeyActor = 2;

	private const float RequestCooldown = 2f;

	private static CleanRequestRelay _instance;

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

	private static readonly List<int> ExpiredScratch = new List<int>(16);

	private bool _subscribed;

	private void OnEnable()
	{
		TrySubscribe();
	}

	private void OnDisable()
	{
		if (_subscribed)
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
			_subscribed = false;
		}
	}

	private void Update()
	{
		if (!_subscribed)
		{
			TrySubscribe();
		}
	}

	private void TrySubscribe()
	{
		if (_subscribed)
		{
			return;
		}
		try
		{
			PhotonNetwork.AddCallbackTarget((object)this);
			_subscribed = true;
		}
		catch (Exception ex)
		{
			SCLog.Verbose("注册网络回调等待中:" + ex.Message);
		}
	}

	internal static CleanRequestRelay Ensure(GameObject host)
	{
		if ((Object)(object)_instance != (Object)null && (Object)(object)((Component)_instance).gameObject == (Object)(object)host)
		{
			return _instance;
		}
		_instance = host.GetComponent<CleanRequestRelay>();
		if ((Object)(object)_instance == (Object)null)
		{
			_instance = host.AddComponent<CleanRequestRelay>();
		}
		return _instance;
	}

	internal static bool RequestRemoteDelete(PhotonView view)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: 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_007f: Expected O, but got Unknown
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)view == (Object)null || view.ViewID < 1)
		{
			return false;
		}
		if (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)
		{
			return false;
		}
		float unscaledTime = Time.unscaledTime;
		PruneRecentRequests(unscaledTime);
		int viewID = view.ViewID;
		if (RecentRequests.TryGetValue(viewID, out var value) && unscaledTime < value)
		{
			return true;
		}
		Hashtable val = new Hashtable();
		val.Add((byte)1, (object)viewID);
		val.Add((byte)2, (object)((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : 0));
		Hashtable val2 = val;
		try
		{
			RaiseEventOptions val3 = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			};
			bool num = PhotonNetwork.RaiseEvent((byte)190, (object)val2, val3, SendOptions.SendReliable);
			if (num)
			{
				RecentRequests[viewID] = unscaledTime + 2f;
			}
			return num;
		}
		catch (Exception ex)
		{
			SCLog.Warn("发送清理请求失败:" + ex.Message);
			return false;
		}
	}

	internal static void ResetRequestCooldowns()
	{
		RecentRequests.Clear();
	}

	private static void PruneRecentRequests(float now)
	{
		if (RecentRequests.Count == 0)
		{
			return;
		}
		ExpiredScratch.Clear();
		foreach (KeyValuePair<int, float> recentRequest in RecentRequests)
		{
			if (now >= recentRequest.Value)
			{
				ExpiredScratch.Add(recentRequest.Key);
			}
		}
		for (int i = 0; i < ExpiredScratch.Count; i++)
		{
			RecentRequests.Remove(ExpiredScratch[i]);
		}
	}

	public void OnEvent(EventData photonEvent)
	{
		if (photonEvent == null || photonEvent.Code != 190)
		{
			return;
		}
		try
		{
			object customData = photonEvent.CustomData;
			Hashtable val = (Hashtable)((customData is Hashtable) ? customData : null);
			if (val == null || !val.ContainsKey((byte)1))
			{
				return;
			}
			int num = ToInt(val[(byte)1]);
			int num2 = (val.ContainsKey((byte)2) ? ToInt(val[(byte)2]) : 0);
			if (num < 1)
			{
				return;
			}
			PhotonView photonView = PhotonNetwork.GetPhotonView(num);
			if ((Object)(object)photonView == (Object)null)
			{
				return;
			}
			int num3 = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1));
			bool flag = photonView.IsMine;
			if (!flag && num3 > 0)
			{
				if (photonView.OwnerActorNr == num3)
				{
					flag = true;
				}
				else if (photonView.CreatorActorNr == num3)
				{
					flag = photonView.OwnerActorNr == 0 || photonView.Owner == null || photonView.Owner.IsInactive;
				}
			}
			if (!flag)
			{
				return;
			}
			if (!photonView.isRuntimeInstantiated || (Object)(object)((Component)photonView).GetComponent<Character>() != (Object)null)
			{
				SCLog.Warn("忽略一条异常的清理请求(目标类型不允许):" + ((Object)((Component)photonView).gameObject).name);
				return;
			}
			if (!photonView.IsMine)
			{
				try
				{
					photonView.OwnerActorNr = num3;
					photonView.ControllerActorNr = num3;
				}
				catch (Exception ex)
				{
					SCLog.Verbose("修正所有权失败(请求侧):" + ex.Message);
				}
			}
			SCLog.Info("响应玩家的清理请求,删除本地持有的物体:" + ((Object)((Component)photonView).gameObject).name + "(发起者 Actor=" + num2 + ")");
			DestroyCompanionRope(((Component)photonView).gameObject);
			Cleaner.DestroyWithOwnership(photonView, ((Component)photonView).gameObject);
		}
		catch (Exception ex2)
		{
			SCLog.Warn("处理清理请求失败:" + ex2.Message);
		}
	}

	private static void DestroyCompanionRope(GameObject anchorRoot)
	{
		RopeAnchorWithRope component = anchorRoot.GetComponent<RopeAnchorWithRope>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		GameObject ropeInstance = component.ropeInstance;
		if (!((Object)(object)ropeInstance == (Object)null))
		{
			PhotonView component2 = ropeInstance.GetComponent<PhotonView>();
			if (!((Object)(object)component2 == (Object)null))
			{
				Cleaner.DestroyWithOwnership(component2, ropeInstance);
			}
		}
	}

	private static int ToInt(object value)
	{
		if (value is int)
		{
			return (int)value;
		}
		if (value is byte)
		{
			return (byte)value;
		}
		StructWrapper val = (StructWrapper)((value is StructWrapper) ? value : null);
		if (val != null)
		{
			object obj = val.Box();
			if (obj is int)
			{
				return (int)obj;
			}
			if (obj is byte)
			{
				return (byte)obj;
			}
		}
		try
		{
			return Convert.ToInt32(value);
		}
		catch (Exception)
		{
			return 0;
		}
	}
}
[DefaultExecutionOrder(-300)]
internal sealed class CleanUI : MonoBehaviour
{
	private enum Phase
	{
		Hidden,
		SlideIn,
		Hold,
		SlideOut
	}

	private const float FontSize = 34f;

	private const float SubFontSize = 22f;

	private const float CenterYOffset = -320f;

	private const float LabelYOffset = -440f;

	private const float PanelWidth = 560f;

	private const float SlideTime = 0.18f;

	private const float SlideDistance = 44f;

	private static readonly Color TextColor = new Color(0.98f, 0.99f, 1f, 1f);

	private static readonly Color SubColor = new Color(0.62f, 0.88f, 1f, 1f);

	private static readonly Color PanelColor = new Color(0.035f, 0.055f, 0.085f, 0.78f);

	private static readonly Color AccentColor = new Color(0.3f, 0.76f, 1f, 1f);

	private GameObject _canvasObject;

	private CanvasGroup _group;

	private RectTransform _panelRect;

	private TextMeshProUGUI _titleText;

	private TextMeshProUGUI _subText;

	private float _titleRow;

	private float _subRow;

	private GameObject _labelCanvas;

	private TextMeshProUGUI _labelText;

	private bool _labelBuilt;

	private bool _built;

	private bool _fontWarned;

	private Phase _phase;

	private float _phaseStart;

	private float _holdSeconds;

	private float _slideInFrom;

	private float _slideOutTo;

	private float _slideOutFrom;

	private float _alphaFrom = 1f;

	private string _pendingTitle;

	private string _pendingSub;

	private float _appliedAlpha = -1f;

	private float _appliedOffset = float.NaN;

	private void OnDestroy()
	{
		if ((Object)(object)_canvasObject != (Object)null)
		{
			Object.Destroy((Object)(object)_canvasObject);
			_canvasObject = null;
		}
		if ((Object)(object)_labelCanvas != (Object)null)
		{
			Object.Destroy((Object)(object)_labelCanvas);
			_labelCanvas = null;
		}
		_group = null;
		_panelRect = null;
		_titleText = null;
		_subText = null;
		_labelText = null;
	}

	private void Update()
	{
		if (_phase == Phase.Hidden)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		float num = unscaledTime - _phaseStart;
		switch (_phase)
		{
		case Phase.SlideIn:
		{
			float num4 = Mathf.Clamp01(num / 0.18f);
			float num5 = EaseOutCubic(num4);
			Apply(Mathf.Lerp(_slideInFrom, 0f, num5), num5);
			if (!(num4 < 1f))
			{
				_phase = Phase.Hold;
				_phaseStart = unscaledTime;
			}
			break;
		}
		case Phase.Hold:
			Apply(0f, 1f);
			if (num >= _holdSeconds)
			{
				_phase = Phase.SlideOut;
				_phaseStart = unscaledTime;
				_slideOutFrom = 0f;
				_alphaFrom = 1f;
			}
			break;
		case Phase.SlideOut:
		{
			float num2 = Mathf.Clamp01(num / 0.18f);
			float num3 = EaseInCubic(num2);
			Apply(Mathf.Lerp(_slideOutFrom, _slideOutTo, num3), Mathf.Lerp(_alphaFrom, 0f, num3));
			if (!(num2 < 1f))
			{
				if (_pendingTitle != null)
				{
					CommitPending();
					_slideInFrom = ((_slideOutTo > 0f) ? (-44f) : 44f);
					_phase = Phase.SlideIn;
					_phaseStart = unscaledTime;
				}
				else
				{
					_phase = Phase.Hidden;
					SetCanvasVisible(visible: false);
				}
			}
			break;
		}
		}
	}

	private void CommitPending()
	{
		if (_pendingTitle != null)
		{
			((TMP_Text)_titleText).text = _pendingTitle;
			_pendingTitle = null;
		}
		if (_pendingSub != null)
		{
			((TMP_Text)_subText).text = _pendingSub;
			ApplyPanelLayout(!string.IsNullOrEmpty(_pendingSub));
			_pendingSub = null;
		}
	}

	private void Apply(float offsetY, float alpha)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_panelRect == (Object)null || (Object)(object)_group == (Object)null)
		{
			_phase = Phase.Hidden;
			return;
		}
		if (!Mathf.Approximately(offsetY, _appliedOffset))
		{
			_appliedOffset = offsetY;
			_panelRect.anchoredPosition = new Vector2(0f, -320f + offsetY);
		}
		if (!Mathf.Approximately(alpha, _appliedAlpha))
		{
			_appliedAlpha = alpha;
			_group.alpha = alpha;
		}
	}

	private void SetCanvasVisible(bool visible)
	{
		if ((Object)(object)_canvasObject != (Object)null && _canvasObject.activeSelf != visible)
		{
			_canvasObject.SetActive(visible);
		}
		if (!visible)
		{
			_appliedAlpha = -1f;
			_appliedOffset = float.NaN;
		}
	}

	private void BeginVisible()
	{
		EnsureBuilt();
		if (_built)
		{
			SetCanvasVisible(visible: true);
			_appliedAlpha = -1f;
			_appliedOffset = float.NaN;
		}
	}

	private void EnsureBuilt()
	{
		if (_built || (Object)(object)GUIManager.instance == (Object)null)
		{
			return;
		}
		try
		{
			BuildHierarchy();
			_built = true;
			SetCanvasVisible(visible: false);
		}
		catch (Exception ex)
		{
			SCLog.Warn("构建提示 UI 失败:" + ex.Message);
			if ((Object)(object)_canvasObject != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasObject);
				_canvasObject = null;
			}
			_group = null;
			_panelRect = null;
			_titleText = null;
			_subText = null;
		}
	}

	internal void ShowMode(string title, string subtitle, bool entering, float holdSeconds)
	{
		BeginVisible();
		if (_built)
		{
			_pendingTitle = null;
			_pendingSub = null;
			((TMP_Text)_titleText).text = title;
			((TMP_Text)_subText).text = subtitle;
			ApplyPanelLayout(!string.IsNullOrEmpty(subtitle));
			_slideInFrom = (entering ? (-44f) : 44f);
			_slideOutTo = (entering ? 44f : (-44f));
			_holdSeconds = Mathf.Max(0.05f, holdSeconds);
			Apply(_slideInFrom, 0f);
			_phase = Phase.SlideIn;
			_phaseStart = Time.unscaledTime;
		}
	}

	internal void ShowSwitch(string title, string subtitle, bool upward, float holdSeconds)
	{
		BeginVisible();
		if (_built)
		{
			_slideOutTo = (upward ? 44f : (-44f));
			_slideInFrom = (upward ? (-44f) : 44f);
			_holdSeconds = Mathf.Max(0.05f, holdSeconds);
			if (_phase == Phase.Hidden)
			{
				((TMP_Text)_titleText).text = title;
				((TMP_Text)_subText).text = subtitle;
				ApplyPanelLayout(!string.IsNullOrEmpty(subtitle));
				_pendingTitle = null;
				_pendingSub = null;
				Apply(_slideInFrom, 0f);
				_phase = Phase.SlideIn;
				_phaseStart = Time.unscaledTime;
			}
			else
			{
				_pendingTitle = title;
				_pendingSub = subtitle;
				_slideOutFrom = (float.IsNaN(_appliedOffset) ? 0f : _appliedOffset);
				_alphaFrom = ((_appliedAlpha < 0f) ? 1f : _appliedAlpha);
				_phase = Phase.SlideOut;
				_phaseStart = Time.unscaledTime;
			}
		}
	}

	internal void ShowHint(string title, float holdSeconds)
	{
		ShowMode(title, string.Empty, entering: true, holdSeconds);
	}

	internal void SetSelectionLabel(string text)
	{
		if ((Object)(object)GUIManager.instance == (Object)null)
		{
			return;
		}
		if (!_labelBuilt)
		{
			try
			{
				BuildLabel();
				_labelBuilt = true;
			}
			catch (Exception ex)
			{
				SCLog.Warn("构建目标信息条失败:" + ex.Message);
				if ((Object)(object)_labelCanvas != (Object)null)
				{
					Object.Destroy((Object)(object)_labelCanvas);
					_labelCanvas = null;
				}
				_labelText = null;
				return;
			}
		}
		if (!((Object)(object)_labelText == (Object)null))
		{
			bool flag = !string.IsNullOrEmpty(text);
			if ((Object)(object)_labelCanvas != (Object)null && _labelCanvas.activeSelf != flag)
			{
				_labelCanvas.SetActive(flag);
			}
			if (flag && !string.Equals(((TMP_Text)_labelText).text, text, StringComparison.Ordinal))
			{
				((TMP_Text)_labelText).text = text;
			}
		}
	}

	internal void HideSelectionLabel()
	{
		if ((Object)(object)_labelCanvas != (Object)null && _labelCanvas.activeSelf)
		{
			_labelCanvas.SetActive(false);
		}
	}

	internal void HideImmediate()
	{
		_pendingTitle = null;
		_pendingSub = null;
		_phase = Phase.Hidden;
		SetCanvasVisible(visible: false);
	}

	private void ApplyPanelLayout(bool hasSub)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_panelRect == (Object)null))
		{
			float titleRow = _titleRow;
			float subRow = _subRow;
			float num = (hasSub ? (titleRow + subRow + 18f) : (titleRow + 18f));
			Vector2 sizeDelta = _panelRect.sizeDelta;
			if (!Mathf.Approximately(sizeDelta.y, num))
			{
				_panelRect.sizeDelta = new Vector2(sizeDelta.x, num);
			}
			if ((Object)(object)_subText != (Object)null && ((Component)_subText).gameObject.activeSelf != hasSub)
			{
				((Component)_subText).gameObject.SetActive(hasSub);
			}
		}
	}

	private void BuildHierarchy()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_0119: 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_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: 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_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: 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_02e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: 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)
		_canvasObject = new GameObject("ScrapCleanCanvas");
		_canvasObject.transform.SetParent(((Component)this).transform, false);
		Canvas obj = _canvasObject.AddComponent<Canvas>();
		obj.renderMode = (RenderMode)0;
		obj.sortingOrder = 560;
		CanvasScaler obj2 = _canvasObject.AddComponent<CanvasScaler>();
		obj2.uiScaleMode = (ScaleMode)1;
		obj2.referenceResolution = new Vector2(1920f, 1080f);
		obj2.screenMatchMode = (ScreenMatchMode)0;
		obj2.matchWidthOrHeight = 1f;
		_group = _canvasObject.AddComponent<CanvasGroup>();
		_group.interactable = false;
		_group.blocksRaycasts = false;
		TMP_FontAsset font = ResolveFont();
		float num = RowHeight(34f, font);
		float num2 = RowHeight(22f, font);
		_titleRow = num;
		_subRow = num2;
		float num3 = num + num2 + 18f;
		Image val = CreatePanel("ToastPanel", _canvasObject.transform, PanelColor);
		_panelRect = (RectTransform)((Component)val).transform;
		_panelRect.anchorMin = new Vector2(0.5f, 0.5f);
		_panelRect.anchorMax = new Vector2(0.5f, 0.5f);
		_panelRect.pivot = new Vector2(0.5f, 0.5f);
		_panelRect.anchoredPosition = new Vector2(0f, -320f);
		_panelRect.sizeDelta = new Vector2(560f, num3);
		RectTransform val2 = (RectTransform)((Component)CreatePanel("Accent", ((Component)val).transform, AccentColor)).transform;
		val2.anchorMin = new Vector2(0f, 0f);
		val2.anchorMax = new Vector2(0f, 1f);
		val2.pivot = new Vector2(0f, 0.5f);
		val2.anchoredPosition = Vector2.zero;
		val2.sizeDelta = new Vector2(5f, 0f);
		_titleText = CreateText("Title", ((Component)val).transform, 34f, (TextAlignmentOptions)514, TextColor, font);
		RectTransform val3 = (RectTransform)((TMP_Text)_titleText).transform;
		val3.anchorMin = new Vector2(0f, 1f);
		val3.anchorMax = new Vector2(1f, 1f);
		val3.pivot = new Vector2(0.5f, 1f);
		val3.offsetMin = new Vector2(20f, -6f - num);
		val3.offsetMax = new Vector2(-16f, -6f);
		_subText = CreateText("Sub", ((Component)val).transform, 22f, (TextAlignmentOptions)514, SubColor, font);
		RectTransform val4 = (RectTransform)((TMP_Text)_subText).transform;
		val4.anchorMin = new Vector2(0f, 1f);
		val4.anchorMax = new Vector2(1f, 1f);
		val4.pivot = new Vector2(0.5f, 1f);
		val4.offsetMin = new Vector2(20f, -6f - num - num2);
		val4.offsetMax = new Vector2(-16f, -6f - num);
	}

	private static float RowHeight(float fontSize, TMP_FontAsset font)
	{
		float num = 1.6f;
		if ((Object)(object)font != (Object)null)
		{
			num = Mathf.Max(num, RatioOf(font));
			if (font.fallbackFontAssetTable != null)
			{
				for (int i = 0; i < font.fallbackFontAssetTable.Count; i++)
				{
					TMP_FontAsset val = font.fallbackFontAssetTable[i];
					if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)font)
					{
						num = Mathf.Max(num, RatioOf(val));
					}
				}
			}
		}
		num = Mathf.Clamp(num, 1.2f, 2.6f);
		return Mathf.Ceil(fontSize * num) + 4f;
	}

	private static float RatioOf(TMP_FontAsset font)
	{
		//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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if (!((Object)(object)font == (Object)null))
		{
			FaceInfo faceInfo = ((TMP_Asset)font).faceInfo;
			if (!(((FaceInfo)(ref faceInfo)).pointSize <= 0f))
			{
				faceInfo = ((TMP_Asset)font).faceInfo;
				float lineHeight = ((FaceInfo)(ref faceInfo)).lineHeight;
				faceInfo = ((TMP_Asset)font).faceInfo;
				return lineHeight / ((FaceInfo)(ref faceInfo)).pointSize;
			}
		}
		return 1.6f;
	}

	private TMP_FontAsset ResolveFont()
	{
		FontFallbackSwapper instance = FontFallbackSwapper.instance;
		if ((Object)(object)instance != (Object)null && (Object)(object)instance.mainBaseFont != (Object)null)
		{
			return instance.mainBaseFont;
		}
		GUIManager instance2 = GUIManager.instance;
		if ((Object)(object)instance2 != (Object)null)
		{
			if ((Object)(object)instance2.interactNameText != (Object)null && (Object)(object)((TMP_Text)instance2.interactNameText).font != (Object)null)
			{
				return ((TMP_Text)instance2.interactNameText).font;
			}
			if ((Object)(object)instance2.interactPromptText != (Object)null && (Object)(object)((TMP_Text)instance2.interactPromptText).font != (Object)null)
			{
				return ((TMP_Text)instance2.interactPromptText).font;
			}
			if ((Object)(object)instance2.itemPromptMain != (Object)null && (Object)(object)((TMP_Text)instance2.itemPromptMain).font != (Object)null)
			{
				return ((TMP_Text)instance2.itemPromptMain).font;
			}
		}
		if (!_fontWarned)
		{
			_fontWarned = true;
			SCLog.Warn("未能取到游戏字体,已回退到 TMP 默认字体(中文可能显示为方块)。");
		}
		return TMP_Settings.defaultFontAsset;
	}

	private static Image CreatePanel(string name, Transform parent, Color color)
	{
		//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)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
		{
			layer = UiLayer()
		};
		val.transform.SetParent(parent, false);
		Image val2 = val.AddComponent<Image>();
		((Graphic)val2).color = color;
		((Graphic)val2).raycastTarget = false;
		RectTransform val3 = (RectTransform)val.transform;
		((Transform)val3).localScale = Vector3.one;
		((Transform)val3).localRotation = Quaternion.identity;
		val3.anchoredPosition3D = Vector3.zero;
		return val2;
	}

	private static TextMeshProUGUI CreateText(string name, Transform parent, float size, TextAlignmentOptions alignment, Color color, TMP_FontAsset font)
	{
		//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)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
		{
			layer = UiLayer()
		};
		val.transform.SetParent(parent, false);
		TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
		if ((Object)(object)font != (Object)null)
		{
			((TMP_Text)val2).font = font;
		}
		((TMP_Text)val2).fontSize = size;
		((TMP_Text)val2).enableAutoSizing = false;
		((TMP_Text)val2).alignment = alignment;
		((Graphic)val2).color = color;
		((TMP_Text)val2).richText = false;
		((Graphic)val2).raycastTarget = false;
		((TMP_Text)val2).margin = Vector4.zero;
		((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
		((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
		RectTransform val3 = (RectTransform)val.transform;
		((Transform)val3).localScale = Vector3.one;
		((Transform)val3).localRotation = Quaternion.identity;
		val3.anchoredPosition3D = Vector3.zero;
		return val2;
	}

	private static int UiLayer()
	{
		int num = LayerMask.NameToLayer("UI");
		if (num < 0)
		{
			return 5;
		}
		return num;
	}

	private void BuildLabel()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		_labelCanvas = new GameObject("ScrapCleanLabelCanvas");
		_labelCanvas.transform.SetParent(((Component)this).transform, false);
		Canvas obj = _labelCanvas.AddComponent<Canvas>();
		obj.renderMode = (RenderMode)0;
		obj.sortingOrder = 559;
		CanvasScaler obj2 = _labelCanvas.AddComponent<CanvasScaler>();
		obj2.uiScaleMode = (ScaleMode)1;
		obj2.referenceResolution = new Vector2(1920f, 1080f);
		obj2.screenMatchMode = (ScreenMatchMode)0;
		obj2.matchWidthOrHeight = 1f;
		TMP_FontAsset font = ResolveFont();
		float num = RowHeight(22f, font);
		Image val = CreatePanel("LabelBg", _labelCanvas.transform, new Color(0.03f, 0.05f, 0.08f, 0.62f));
		RectTransform val2 = (RectTransform)((Component)val).transform;
		val2.anchorMin = new Vector2(0.5f, 0.5f);
		val2.anchorMax = new Vector2(0.5f, 0.5f);
		val2.pivot = new Vector2(0.5f, 0.5f);
		val2.anchoredPosition = new Vector2(0f, -440f);
		val2.sizeDelta = new Vector2(420f, num + 12f);
		_labelText = CreateText("LabelText", ((Component)val).transform, 22f, (TextAlignmentOptions)514, TextColor, font);
		RectTransform val3 = (RectTransform)((TMP_Text)_labelText).transform;
		val3.anchorMin = Vector2.zero;
		val3.anchorMax = Vector2.one;
		val3.pivot = new Vector2(0.5f, 0.5f);
		val3.offsetMin = new Vector2(10f, 5f);
		val3.offsetMax = new Vector2(-10f, -5f);
		_labelCanvas.SetActive(false);
	}

	private static float EaseOutCubic(float t)
	{
		float num = 1f - t;
		return 1f - num * num * num;
	}

	private static float EaseInCubic(float t)
	{
		return t * t * t;
	}
}
internal sealed class GroundRing : MonoBehaviour
{
	private const int MaxSegments = 128;

	private const float SegmentSpacing = 0.12f;

	private const float DashRatio = 0.55f;

	private const float DashChunkLength = 0.4f;

	private const float LineWidth = 0.055f;

	private const float VerticalBand = 0.12f;

	private const float SnapRadius = 0.08f;

	private const float SnapDistance = 1.6f;

	private static readonly int BaseColorId = Shader.PropertyToID("_BaseColor");

	private static readonly int LegacyColorId = Shader.PropertyToID("_Color");

	private static readonly int CullId = Shader.PropertyToID("_Cull");

	private MeshFilter _filter;

	private MeshRenderer _renderer;

	private Mesh _mesh;

	private Material _material;

	private bool _materialReady;

	private int _segments = 128;

	private readonly List<Vector3> _vertices = new List<Vector3>(1024);

	private readonly List<int> _triangles = new List<int>(1536);

	private readonly Vector3[] _points = (Vector3[])(object)new Vector3[129];

	private readonly bool[] _valid = new bool[129];

	private void Awake()
	{
		//IL_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		_filter = ((Component)this).gameObject.AddComponent<MeshFilter>();
		_renderer = ((Component)this).gameObject.AddComponent<MeshRenderer>();
		((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)_renderer).receiveShadows = false;
		((Renderer)_renderer).lightProbeUsage = (LightProbeUsage)0;
		((Renderer)_renderer).reflectionProbeUsage = (ReflectionProbeUsage)0;
		_mesh = new Mesh
		{
			name = "ScrapCleanRing",
			indexFormat = (IndexFormat)1
		};
		_mesh.MarkDynamic();
		_filter.sharedMesh = _mesh;
		_material = CreateMaterial();
		if ((Object)(object)_material != (Object)null)
		{
			((Renderer)_renderer).sharedMaterial = _material;
			_materialReady = true;
		}
		else
		{
			SCLog.Warn("找不到可用的无光照 shader,范围清理的圆形指示器将不可见(清理功能不受影响)。");
		}
		((Renderer)_renderer).enabled = false;
	}

	private void OnDestroy()
	{
		if ((Object)(object)_mesh != (Object)null)
		{
			Object.Destroy((Object)(object)_mesh);
			_mesh = null;
		}
		if ((Object)(object)_material != (Object)null)
		{
			Object.Destroy((Object)(object)_material);
			_material = null;
		}
	}

	internal void SetVisible(bool visible)
	{
		if ((Object)(object)_renderer != (Object)null && ((Renderer)_renderer).enabled != visible)
		{
			((Renderer)_renderer).enabled = visible;
		}
	}

	internal void Rebuild(Vector3 center, float radius, Vector3 surfaceNormal)
	{
		//IL_0073: 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_0078: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_mesh == (Object)null || (Object)(object)_renderer == (Object)null || (Object)(object)_filter == (Object)null)
		{
			return;
		}
		if (!_materialReady || radius <= 0.01f)
		{
			if ((Object)(object)_mesh != (Object)null)
			{
				_mesh.Clear();
			}
			SetVisible(visible: false);
			return;
		}
		Vector3 val = ((((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref surfaceNormal)).normalized : Vector3.up);
		Vector3 val2 = ((Mathf.Abs(Vector3.Dot(val, Vector3.up)) < 0.9f) ? Vector3.up : Vector3.forward);
		Vector3 val3 = Vector3.Cross(val, val2);
		Vector3 normalized = ((Vector3)(ref val3)).normalized;
		val3 = Vector3.Cross(val, normalized);
		Vector3 normalized2 = ((Vector3)(ref val3)).normalized;
		float num = MathF.PI * 2f * radius;
		_segments = Mathf.Clamp(Mathf.CeilToInt(num / 0.12f), 24, 128);
		SampleRing(center, radius, val, normalized, normalized2);
		_vertices.Clear();
		_triangles.Clear();
		float num2 = 0.4f;
		float num3 = 0.17999999f / Mathf.Max(0.01f, 0.55f);
		float num4 = num / (float)_segments;
		float num5 = Mathf.Max(1.5f, num4 * 3f);
		float num6 = 0f;
		bool flag = true;
		for (int i = 0; i < _segments; i++)
		{
			Vector3 val4 = _points[i];
			Vector3 val5 = _points[i + 1];
			if (!_valid[i] || !_valid[i + 1])
			{
				flag = true;
				num6 = 0f;
				continue;
			}
			float num7 = Vector3.Distance(val4, val5);
			if (num7 <= 0.0001f || num7 > num5)
			{
				flag = true;
				num6 = 0f;
				continue;
			}
			num6 += num7;
			if (flag && num6 > num2)
			{
				flag = false;
				num6 = 0f;
			}
			else if (!flag && num6 > num3)
			{
				flag = true;
				num6 = 0f;
			}
			if (flag)
			{
				AppendSegment(val4, val5, val);
			}
		}
		_mesh.Clear();
		if (_vertices.Count == 0)
		{
			SetVisible(visible: false);
			return;
		}
		_mesh.SetVertices(_vertices);
		_mesh.SetTriangles(_triangles, 0);
		_mesh.RecalculateBounds();
		SetVisible(visible: true);
	}

	private void SampleRing(Vector3 center, float radius, Vector3 normal, Vector3 tangent, Vector3 bitangent)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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_0071: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		int num = LayerMask.op_Implicit(HelperFunctions.terrainMapMask);
		float num2 = 3.2f;
		RaycastHit val3 = default(RaycastHit);
		RaycastHit val4 = default(RaycastHit);
		for (int i = 0; i <= _segments; i++)
		{
			float num3 = (float)i / (float)_segments * MathF.PI * 2f;
			float num4 = Mathf.Cos(num3);
			float num5 = Mathf.Sin(num3);
			Vector3 val = center + (tangent * num4 + bitangent * num5) * radius + normal * 1.6f;
			Vector3 val2 = -normal;
			if (Physics.Raycast(val, val2, ref val3, num2, num, (QueryTriggerInteraction)1))
			{
				_points[i] = ((RaycastHit)(ref val3)).point;
				_valid[i] = true;
			}
			else if (Physics.SphereCast(val, 0.08f, val2, ref val3, num2, num, (QueryTriggerInteraction)1))
			{
				if (Physics.Raycast(((RaycastHit)(ref val3)).point + normal * 0.08f, val2, ref val4, 0.21f, num, (QueryTriggerInteraction)1))
				{
					_points[i] = ((RaycastHit)(ref val4)).point;
				}
				else
				{
					_points[i] = ((RaycastHit)(ref val3)).point;
				}
				_valid[i] = true;
			}
			else
			{
				_valid[i] = false;
			}
		}
	}

	private void AppendSegment(Vector3 a, Vector3 b, Vector3 normal)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: 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: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0028: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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_0064: 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_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: 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_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: 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_008b: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: 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_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = b - a;
		float magnitude = ((Vector3)(ref val)).magnitude;
		if (!(magnitude <= 0.0001f))
		{
			val /= magnitude;
			Vector3 val2 = Vector3.Cross(val, normal);
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				val2 = Vector3.Cross(val, Vector3.up);
			}
			if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
			{
				val2 = ((Vector3)(ref val2)).normalized * 0.0275f;
				Vector3 val3 = normal * 0.02f;
				AppendQuad(a - val2 + val3, a + val2 + val3, b + val2 + val3, b - val2 + val3);
				AppendQuad(a + val3, a + normal * 0.12f + val3, b + normal * 0.12f + val3, b + val3);
			}
		}
	}

	private void AppendQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3)
	{
		//IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		int count = _vertices.Count;
		_vertices.Add(v0);
		_vertices.Add(v1);
		_vertices.Add(v2);
		_vertices.Add(v3);
		_triangles.Add(count);
		_triangles.Add(count + 1);
		_triangles.Add(count + 2);
		_triangles.Add(count);
		_triangles.Add(count + 2);
		_triangles.Add(count + 3);
	}

	private static Material CreateMaterial()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		string[] array = new string[3] { "Universal Render Pipeline/Unlit", "UI/Default", "Sprites/Default" };
		for (int i = 0; i < array.Length; i++)
		{
			Shader val = Shader.Find(array[i]);
			if (!((Object)(object)val == (Object)null))
			{
				Material val2 = new Material(val)
				{
					name = "ScrapCleanRingMat",
					hideFlags = (HideFlags)52
				};
				if (val2.HasProperty(CullId))
				{
					val2.SetInt(CullId, 0);
				}
				if (((Object)val).name.StartsWith("UI/", StringComparison.Ordinal) || ((Object)val).name.StartsWith("Sprites/", StringComparison.Ordinal))
				{
					val2.renderQueue = 2000;
				}
				ApplyColor(val2, new Color(0.42f, 0.92f, 1f, 1f));
				SCLog.Verbose("圆形指示器使用 shader: " + array[i]);
				return val2;
			}
		}
		return null;
	}

	private static void ApplyColor(Material mat, Color color)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (mat.HasProperty(BaseColorId))
		{
			mat.SetColor(BaseColorId, color);
		}
		if (mat.HasProperty(LegacyColorId))
		{
			mat.SetColor(LegacyColorId, color);
		}
	}
}
internal static class HarmonyPatches
{
	private static CleanMode _mode;

	private static bool _inputWarned;

	internal static void Apply(Harmony harmony)
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(CharacterInput), "Sample", new Type[1] { typeof(bool) }, (Type[])null);
			if (methodInfo == null)
			{
				SCLog.Error("找不到 CharacterInput.Sample(bool),输入抑制补丁未安装(清理时可能误用手持道具)。");
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(HarmonyPatches), "SamplePostfix", (Type[])null, (Type[])null);
			if (methodInfo2 == null)
			{
				SCLog.Error("找不到补丁方法本体,输入抑制补丁未安装。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			SCLog.Info("已安装 CharacterInput.Sample 输入抑制补丁。");
		}
		catch (Exception ex)
		{
			SCLog.Error("安装输入抑制补丁失败。", ex);
		}
	}

	internal static void Register(CleanMode mode)
	{
		_mode = mode;
	}

	private static void SamplePostfix()
	{
		try
		{
			CleanMode mode = _mode;
			if (!((Object)(object)mode == (Object)null) && mode.SuppressGameplayInput)
			{
				CharacterInput val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.input : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.usePrimaryWasPressed = false;
					val.usePrimaryIsPressed = false;
					val.useSecondaryWasPressed = false;
					val.useSecondaryIsPressed = false;
					val.scrollInput = 0f;
					val.scrollForwardWasPressed = false;
					val.scrollBackwardWasPressed = false;
					val.scrollForwardIsPressed = false;
					val.scrollBackwardIsPressed = false;
				}
			}
		}
		catch (Exception ex)
		{
			if (!_inputWarned)
			{
				_inputWarned = true;
				SCLog.Warn("输入抑制补丁出错(后续相同错误不再重复输出):" + ex);
			}
		}
	}
}
internal sealed class HighlightRenderer
{
	private static readonly int InteractableId = Item.PROPERTY_INTERACTABLE;

	private readonly HashSet<Renderer> _lit = new HashSet<Renderer>();

	private readonly HashSet<Renderer> _marked = new HashSet<Renderer>();

	private readonly MaterialPropertyBlock _block = new MaterialPropertyBlock();

	private readonly List<Renderer> _rendererScratch = new List<Renderer>(32);

	private readonly List<Renderer> _restoreScratch = new List<Renderer>(32);

	internal void Mark(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		_rendererScratch.Clear();
		if (!CenterCache.TryGetRenderers(root, _rendererScratch))
		{
			return;
		}
		for (int i = 0; i < _rendererScratch.Count; i++)
		{
			Renderer val = _rendererScratch[i];
			if ((Object)(object)val != (Object)null)
			{
				_marked.Add(val);
			}
		}
	}

	internal void EndFrame()
	{
		if (_marked.Count == 0 && _lit.Count == 0)
		{
			return;
		}
		foreach (Renderer item in _marked)
		{
			if (!((Object)(object)item == (Object)null))
			{
				_lit.Add(item);
				Apply(item, 1f);
			}
		}
		_restoreScratch.Clear();
		foreach (Renderer item2 in _lit)
		{
			if (!((Object)(object)item2 != (Object)null) || !_marked.Contains(item2))
			{
				_restoreScratch.Add(item2);
			}
		}
		for (int i = 0; i < _restoreScratch.Count; i++)
		{
			Renderer val = _restoreScratch[i];
			_lit.Remove(val);
			if ((Object)(object)val != (Object)null)
			{
				Apply(val, 0f);
			}
		}
		_marked.Clear();
	}

	internal void Clear()
	{
		foreach (Renderer item in _lit)
		{
			if ((Object)(object)item != (Object)null)
			{
				Apply(item, 0f);
			}
		}
		_lit.Clear();
		_marked.Clear();
	}

	private void Apply(Renderer renderer, float value)
	{
		if ((Object)(object)renderer == (Object)null || (value <= 0f && IsGameHovered(renderer)))
		{
			return;
		}
		try
		{
			renderer.GetPropertyBlock(_block);
			_block.SetFloat(InteractableId, value);
			renderer.SetPropertyBlock(_block);
		}
		catch
		{
		}
	}

	private static bool IsGameHovered(Renderer renderer)
	{
		Interaction instance = Interaction.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return false;
		}
		IInteractible currentHovered = instance.currentHovered;
		if (currentHovered == null)
		{
			return false;
		}
		Transform transform = currentHovered.GetTransform();
		if ((Object)(object)transform == (Object)null)
		{
			return false;
		}
		if (!((Object)(object)((Component)renderer).transform == (Object)(object)transform))
		{
			return ((Component)renderer).transform.IsChildOf(transform);
		}
		return true;
	}
}
internal static class SCInput
{
	private static bool _legacyBroken;

	private static readonly Dictionary<KeyCode, Key> SpecialMap = new Dictionary<KeyCode, Key>
	{
		{
			(KeyCode)48,
			(Key)50
		},
		{
			(KeyCode)49,
			(Key)41
		},
		{
			(KeyCode)50,
			(Key)42
		},
		{
			(KeyCode)51,
			(Key)43
		},
		{
			(KeyCode)52,
			(Key)44
		},
		{
			(KeyCode)53,
			(Key)45
		},
		{
			(KeyCode)54,
			(Key)46
		},
		{
			(KeyCode)55,
			(Key)47
		},
		{
			(KeyCode)56,
			(Key)48
		},
		{
			(KeyCode)57,
			(Key)49
		},
		{
			(KeyCode)13,
			(Key)2
		},
		{
			(KeyCode)96,
			(Key)4
		},
		{
			(KeyCode)316,
			(Key)74
		},
		{
			(KeyCode)317,
			(Key)74
		},
		{
			(KeyCode)319,
			(Key)59
		},
		{
			(KeyCode)306,
			(Key)55
		},
		{
			(KeyCode)305,
			(Key)56
		},
		{
			(KeyCode)310,
			(Key)57
		},
		{
			(KeyCode)309,
			(Key)58
		},
		{
			(KeyCode)300,
			(Key)73
		},
		{
			(KeyCode)256,
			(Key)84
		},
		{
			(KeyCode)257,
			(Key)85
		},
		{
			(KeyCode)258,
			(Key)86
		},
		{
			(KeyCode)259,
			(Key)87
		},
		{
			(KeyCode)260,
			(Key)88
		},
		{
			(KeyCode)261,
			(Key)89
		},
		{
			(KeyCode)262,
			(Key)90
		},
		{
			(KeyCode)263,
			(Key)91
		},
		{
			(KeyCode)264,
			(Key)92
		},
		{
			(KeyCode)265,
			(Key)93
		},
		{
			(KeyCode)266,
			(Key)82
		},
		{
			(KeyCode)267,
			(Key)78
		},
		{
			(KeyCode)268,
			(Key)79
		},
		{
			(KeyCode)269,
			(Key)81
		},
		{
			(KeyCode)270,
			(Key)80
		},
		{
			(KeyCode)271,
			(Key)77
		},
		{
			(KeyCode)272,
			(Key)83
		}
	};

	private static readonly Dictionary<KeyCode, Key> ResolvedCache = new Dictionary<KeyCode, Key>();

	private const float Cooldown = 0.3f;

	private static float _lastScroll;

	private static float _cooldownUntil;

	internal static bool KeyDown(KeyCode code)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		Key val = Resolve(code);
		if ((int)val != 0)
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				try
				{
					KeyControl val2 = current[val];
					if (val2 != null)
					{
						return ((ButtonControl)val2).wasPressedThisFrame;
					}
				}
				catch (ArgumentOutOfRangeException)
				{
					ResolvedCache[code] = (Key)0;
				}
			}
		}
		return LegacyKeyDown(code);
	}

	internal static int ScrollNotch()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		Mouse current = Mouse.current;
		float num = ((current != null) ? ((InputControl<Vector2>)(object)current.scroll).ReadValue().y : LegacyScroll());
		float num2 = num - _lastScroll;
		_lastScroll = num;
		if (Mathf.Abs(num2) <= 0.01f)
		{
			return 0;
		}
		if (Time.unscaledTime < _cooldownUntil)
		{
			return 0;
		}
		if (Mathf.Abs(num) <= 0.01f)
		{
			return 0;
		}
		_cooldownUntil = Time.unscaledTime + 0.3f;
		if (!(num2 > 0f))
		{
			return -1;
		}
		return 1;
	}

	internal static void ResetScrollTracking()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		Mouse current = Mouse.current;
		_lastScroll = ((current != null) ? ((InputControl<Vector2>)(object)current.scroll).ReadValue().y : 0f);
		_cooldownUntil = 0f;
	}

	internal static bool LeftClickDown()
	{
		Mouse current = Mouse.current;
		if (current != null)
		{
			return current.leftButton.wasPressedThisFrame;
		}
		return LegacyKeyDown((KeyCode)323);
	}

	private unsafe static Key Resolve(KeyCode code)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown r