Decompiled source of WZC ValuablesScanner v1.0.1

plugins\WZC_ValuablesScanner.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public enum DisplayLanguage
{
	中文,
	English
}
[BepInPlugin("wzc.repo.valuables_scanner", "A.WZC_ValuablesScanner", "1.0.1")]
public sealed class WzcValuablesScannerPlugin : BaseUnityPlugin
{
	private sealed class ScanLabel
	{
		public Component Target;

		public PhysGrabObject PhysGrabObject;

		public Renderer[] Renderers = Array.Empty<Renderer>();

		public string DisplayName = string.Empty;

		public bool IsValuable;

		public bool IsItem;

		public bool IsCart;

		public Vector3 Position;

		public string PlainText = string.Empty;

		public string RichText = string.Empty;

		public int DistanceMeters;
	}

	public const string PluginGuid = "wzc.repo.valuables_scanner";

	public const string PluginVersion = "1.0.1";

	public const string PluginName = "A.WZC_ValuablesScanner";

	private static WzcValuablesScannerPlugin Instance;

	private const string InfoSection = "模组信息";

	private const string GlobalSection = "A.全局设置";

	private const string ScannerSection = "B.价值扫描";

	private const float MinimumScanIntervalSeconds = 0.1f;

	private const float ContainmentRefreshIntervalSeconds = 0.12f;

	private const float LocalPlayerRefreshIntervalSeconds = 1f;

	private static readonly FieldInfo ValuableCurrentValueField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ValuableValueSetField = typeof(ValuableObject).GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ValuablePhysGrabObjectField = typeof(ValuableObject).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemNameField = typeof(ItemAttributes).GetField("itemName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemValueField = typeof(ItemAttributes).GetField("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemPhysGrabObjectField = typeof(ItemAttributes).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemShopItemField = typeof(ItemAttributes).GetField("shopItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabObjectDeadField = typeof(PhysGrabObject).GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabObjectIsHiddenField = typeof(PhysGrabObject).GetField("isHidden", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabObjectPlayerGrabbingField = typeof(PhysGrabObject).GetField("playerGrabbing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabberGrabbedPhysGrabObjectField = typeof(PhysGrabber).GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabberGrabbedField = typeof(PhysGrabber).GetField("grabbed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabberPlayerAvatarField = typeof(PhysGrabber).GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabCartItemsInCartField = typeof(PhysGrabCart).GetField("itemsInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabCartInCartField = typeof(PhysGrabCart).GetField("physGrabInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabInCartObjectsField = typeof(PhysGrabInCart).GetField("inCartObjects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabInCartCartObjectPhysGrabObjectField = typeof(PhysGrabInCart).GetNestedType("CartObject", BindingFlags.Public | BindingFlags.NonPublic)?.GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo RoundDirectorInstanceField = typeof(RoundDirector).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo RoundDirectorDollarHaulListField = typeof(RoundDirector).GetField("dollarHaulList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PlayerIsLocalField = typeof(PlayerAvatar).GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PlayerTransformField = typeof(PlayerAvatar).GetField("playerTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private readonly List<ScanLabel> labels = new List<ScanLabel>();

	private readonly Dictionary<int, GUIStyle> labelStyleCache = new Dictionary<int, GUIStyle>();

	private readonly GUIContent labelContent = new GUIContent();

	private readonly HashSet<int> seenObjects = new HashSet<int>();

	private readonly HashSet<object> cartObjectSet = new HashSet<object>(ReferenceObjectComparer.Instance);

	private readonly HashSet<object> haulObjectSet = new HashSet<object>(ReferenceObjectComparer.Instance);

	private ConfigEntry<string> moduleNameInfo;

	private ConfigEntry<string> moduleVersionInfo;

	private ConfigEntry<string> contactInfo;

	private ConfigEntry<DisplayLanguage> displayLanguage;

	private ConfigEntry<bool> scannerEnabled;

	private ConfigEntry<bool> shareScansWithTeam;

	private ConfigEntry<bool> showValuables;

	private ConfigEntry<bool> showValuableNames;

	private ConfigEntry<bool> showValuablePrices;

	private ConfigEntry<bool> showValuableDistance;

	private ConfigEntry<bool> showItems;

	private ConfigEntry<bool> showItemDistance;

	private ConfigEntry<bool> showCarts;

	private ConfigEntry<string> scanKey;

	private ConfigEntry<int> scanHoldSeconds;

	private ConfigEntry<float> scanIntervalSeconds;

	private ConfigEntry<int> scanDistanceMeters;

	private ConfigEntry<int> fontSize;

	private ConfigEntry<int> farFontShrinkPercent;

	private float visibleTimer;

	private float scanCooldownTimer;

	private int containmentSetFrame = -1;

	private float nextContainmentRefreshTime;

	private int cachedLocalPositionFrame = -1;

	private Vector3 cachedLocalPosition;

	private int cachedCameraFrame = -1;

	private Camera cachedCamera;

	private float nextLocalPlayerRefreshTime;

	private PlayerAvatar cachedLocalPlayer;

	private PhysGrabber[] grabberObjectsCache = Array.Empty<PhysGrabber>();

	private float nextGrabberRefreshTime;

	private KeyCode cachedScanKey = (KeyCode)102;

	private string cachedScanKeyText = "f";

	private static DisplayLanguage InstanceLanguage
	{
		get
		{
			if (!((Object)(object)Instance == (Object)null) && Instance.displayLanguage != null)
			{
				return Instance.displayLanguage.Value;
			}
			return DisplayLanguage.中文;
		}
	}

	private void Awake()
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Expected O, but got Unknown
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Expected O, but got Unknown
		Instance = this;
		MakePluginHostPersistent();
		moduleNameInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组名称", "WZC_价值扫描器", new ConfigDescription("当前模组的中文名称。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 1000,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		moduleNameInfo.Value = "WZC_价值扫描器";
		moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "1.0.1", new ConfigDescription("当前模组版本号。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 990,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		moduleVersionInfo.Value = "1.0.1";
		contactInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "REPO交流QQ群", "824639225", new ConfigDescription("REPO游戏交流、BUG反馈、优化建议、功能请求请加QQ群。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 980,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		contactInfo.Value = "824639225";
		displayLanguage = ((BaseUnityPlugin)this).Config.Bind<DisplayLanguage>("A.全局设置", "语言/Language", DisplayLanguage.中文, ConfigDescriptionWithOrder("选择扫描标签显示语言。默认中文,English 会显示原始英文名称。", 1000));
		scannerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "启用", true, ConfigDescriptionWithOrder("关闭后整个价值扫描显示都不生效。", 900));
		shareScansWithTeam = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "信息共享队友", true, ConfigDescriptionWithOrder("开启后,扫描到的贵重品会走游戏原生发现同步,队友不装这个模组也能收到发现效果。默认开启。", 895));
		showValuables = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示贵重品", true, ConfigDescriptionWithOrder("显示可回收贵重品。名称、价格和距离可单独开关。", 890));
		showValuableNames = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示名称", false, ConfigDescriptionWithOrder("开启后,贵重品扫描标签会显示物品名称。默认关闭,只显示价格。", 889));
		showValuablePrices = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示价格", true, ConfigDescriptionWithOrder("开启后,贵重品扫描标签会显示当前价格。默认开启。", 888));
		showValuableDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示米数", true, ConfigDescriptionWithOrder("开启后,在贵重品价格后面显示距离米数。默认开启。", 887));
		showItems = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示装备武器", true, ConfigDescriptionWithOrder("显示枪、近战、血包、手雷等装备/武器,只显示名称。", 880));
		showItemDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示装备距离", true, ConfigDescriptionWithOrder("开启后,在装备/武器名称后面显示距离米数。默认开启。", 879));
		showCarts = ((BaseUnityPlugin)this).Config.Bind<bool>("B.价值扫描", "显示购物车", false, ConfigDescriptionWithOrder("开启后扫描时显示大车/小车文字。默认关闭。", 878));
		scanKey = ((BaseUnityPlugin)this).Config.Bind<string>("B.价值扫描", "扫描按键", "f", ConfigDescriptionWithOrder("按下这个按键后显示附近贵重品和装备。只需要写单个按键,例如 f、g、t。", 870));
		scanHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("B.价值扫描", "显示持续秒数", 3, ConfigDescriptionWithOrder("按下扫描按键后,物品价值标签持续显示多少秒。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), 860));
		scanIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("B.价值扫描", "扫描间隔/秒", 1f, ConfigDescriptionWithOrder("按下扫描按键后,多少秒内再次按下不会重新显示。最低会限制为0.1秒。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), 850));
		scanDistanceMeters = ((BaseUnityPlugin)this).Config.Bind<int>("B.价值扫描", "扫描距离/米", 30, ConfigDescriptionWithOrder("按下扫描按键时,只扫描并显示距离自己多少米以内的物品。默认30米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 300), 840));
		fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("B.价值扫描", "字体大小", 24, ConfigDescriptionWithOrder("局内扫描标签的字体大小。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 48), 830));
		farFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("B.价值扫描", "远处字体变小/%", 30, ConfigDescriptionWithOrder("距离较远时,文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), 820));
		UpdateCachedScanKey();
		scanKey.SettingChanged += delegate
		{
			UpdateCachedScanKey();
		};
		((BaseUnityPlugin)this).Logger.LogInfo((object)"wzc_valuables_scanner loaded.");
	}

	private void Update()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if (scannerEnabled == null || !scannerEnabled.Value)
		{
			visibleTimer = 0f;
			scanCooldownTimer = 0f;
			labels.Clear();
			return;
		}
		if (scanCooldownTimer > 0f)
		{
			scanCooldownTimer = Mathf.Max(0f, scanCooldownTimer - Time.deltaTime);
		}
		if (Input.GetKeyDown(cachedScanKey))
		{
			if (scanCooldownTimer > 0f)
			{
				return;
			}
			visibleTimer = Mathf.Max(0.1f, (float)((scanHoldSeconds == null) ? 3 : scanHoldSeconds.Value));
			scanCooldownTimer = ClampScanInterval((scanIntervalSeconds == null) ? 1f : scanIntervalSeconds.Value);
			RefreshLabels();
		}
		if (visibleTimer <= 0f)
		{
			labels.Clear();
		}
		else
		{
			visibleTimer -= Time.deltaTime;
		}
	}

	private void OnGUI()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_00ad: 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)
		Event current = Event.current;
		if ((current != null && (int)current.type != 7) || visibleTimer <= 0f || labels.Count == 0)
		{
			return;
		}
		Camera worldCameraCached = GetWorldCameraCached();
		if ((Object)(object)worldCameraCached == (Object)null || !TryGetLocalPosition(out var position))
		{
			return;
		}
		int num = Mathf.Max(1, (scanDistanceMeters == null) ? 30 : scanDistanceMeters.Value);
		if (!(visibleTimer > 0f) || labels.Count <= 0)
		{
			return;
		}
		RefreshContainmentSetsForFrame();
		for (int num2 = labels.Count - 1; num2 >= 0; num2--)
		{
			ScanLabel scanLabel = labels[num2];
			if (!TryRefreshLabel(scanLabel, position, num))
			{
				labels.RemoveAt(num2);
			}
			else
			{
				DrawLabel(worldCameraCached, scanLabel.Position, scanLabel.PlainText, scanLabel.RichText, scanLabel.DistanceMeters, num);
			}
		}
	}

	private void DrawLabel(Camera camera, Vector3 position, string plainText, string richText, int distanceMeters, int maxDistance)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		if (TryWorldToGuiPoint(camera, position, out var guiPosition))
		{
			int distanceScaledFontSize = GetDistanceScaledFontSize(Mathf.Clamp((fontSize == null) ? 24 : fontSize.Value, 8, 48), (farFontShrinkPercent == null) ? 30 : farFontShrinkPercent.Value, distanceMeters, maxDistance, 48);
			GUIStyle centeredStyle = GetCenteredStyle(distanceScaledFontSize, shadow: false);
			labelContent.text = plainText;
			Vector2 val = centeredStyle.CalcSize(labelContent);
			float num = Mathf.Clamp(val.x + 18f, 80f, 420f);
			float num2 = val.y + 6f;
			GUI.Label(new Rect(guiPosition.x - num / 2f, guiPosition.y - num2 / 2f, num, num2), richText, centeredStyle);
		}
	}

	private void RefreshLabels()
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		labels.Clear();
		seenObjects.Clear();
		bool flag = shareScansWithTeam != null && shareScansWithTeam.Value;
		if (!TryGetLocalPosition(out var position))
		{
			return;
		}
		float num = Mathf.Max(1, (scanDistanceMeters == null) ? 30 : scanDistanceMeters.Value);
		float num2 = num * num;
		ForceRefreshContainmentSets();
		Vector3 val2;
		if (showValuables == null || showValuables.Value)
		{
			ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
			foreach (ValuableObject val in array)
			{
				if (!IsObjectUsable(((Object)(object)val == (Object)null) ? null : ((Component)val).gameObject))
				{
					continue;
				}
				object? obj = ValuablePhysGrabObjectField?.GetValue(val);
				PhysGrabObject physGrabObject = (PhysGrabObject)((obj is PhysGrabObject) ? obj : null);
				if (IsPhysGrabObjectHiddenOrDead(physGrabObject) || IsHeldByLocalPlayer(physGrabObject) || IsObjectInCart((Component)(object)val, physGrabObject) || IsObjectInHaul((Component)(object)val, physGrabObject))
				{
					continue;
				}
				Renderer[] usableRenderers = GetUsableRenderers((Component)(object)val);
				Vector3 objectCenter = GetObjectCenter(((Component)val).transform, physGrabObject, usableRenderers);
				val2 = objectCenter - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude > num2)
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				seenObjects.Add(instanceID);
				int distanceMeters = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude));
				string text = BuildValuableLabelText(TranslateItemName(CleanName(((Object)((Component)val).gameObject).name)), Mathf.RoundToInt(GetValuableCurrentValue(val)), distanceMeters);
				if (!string.IsNullOrWhiteSpace(text))
				{
					labels.Add(new ScanLabel
					{
						Target = (Component)(object)val,
						PhysGrabObject = physGrabObject,
						IsValuable = true,
						DisplayName = TranslateItemName(CleanName(((Object)((Component)val).gameObject).name)),
						Renderers = usableRenderers,
						Position = objectCenter,
						PlainText = text,
						RichText = "<color=#00C832>" + text + "</color>",
						DistanceMeters = distanceMeters
					});
					if (flag)
					{
						RevealValuableToTeam(val);
					}
				}
			}
		}
		if (showItems == null || showItems.Value)
		{
			ItemAttributes[] array2 = Object.FindObjectsOfType<ItemAttributes>();
			bool flag2 = default(bool);
			foreach (ItemAttributes val3 in array2)
			{
				if (!IsObjectUsable(((Object)(object)val3 == (Object)null) ? null : ((Component)val3).gameObject) || (Object)(object)((Component)val3).GetComponent<ValuableObject>() != (Object)null)
				{
					continue;
				}
				object? obj2 = ItemPhysGrabObjectField?.GetValue(val3);
				PhysGrabObject physGrabObject2 = (PhysGrabObject)((obj2 is PhysGrabObject) ? obj2 : null);
				if (IsPhysGrabObjectHiddenOrDead(physGrabObject2) || IsHeldByLocalPlayer(physGrabObject2) || IsObjectInCart((Component)(object)val3, physGrabObject2) || IsObjectInHaul((Component)(object)val3, physGrabObject2))
				{
					continue;
				}
				object obj3 = ItemShopItemField?.GetValue(val3);
				int num3;
				if (obj3 is bool)
				{
					flag2 = (bool)obj3;
					num3 = 1;
				}
				else
				{
					num3 = 0;
				}
				if (((uint)num3 & (flag2 ? 1u : 0u)) != 0)
				{
					continue;
				}
				bool flag3 = IsCartObject((Component)(object)val3, physGrabObject2);
				if (flag3 && (showCarts == null || !showCarts.Value))
				{
					continue;
				}
				Renderer[] usableRenderers2 = GetUsableRenderers((Component)(object)val3);
				Vector3 objectCenter2 = GetObjectCenter(((Component)val3).transform, physGrabObject2, usableRenderers2);
				val2 = objectCenter2 - position;
				float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude;
				if (!(sqrMagnitude2 > num2))
				{
					string itemDisplayName = GetItemDisplayName(val3);
					if (!string.IsNullOrWhiteSpace(itemDisplayName))
					{
						int distanceMeters2 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude2));
						string text2 = BuildItemLabelText(itemDisplayName, distanceMeters2);
						labels.Add(new ScanLabel
						{
							Target = (Component)(object)val3,
							PhysGrabObject = physGrabObject2,
							IsItem = true,
							IsCart = flag3,
							DisplayName = itemDisplayName,
							Renderers = usableRenderers2,
							Position = objectCenter2,
							PlainText = text2,
							RichText = "<color=#62d8ff>" + text2 + "</color>",
							DistanceMeters = distanceMeters2
						});
					}
				}
			}
		}
		labels.Sort((ScanLabel a, ScanLabel b) => a.DistanceMeters.CompareTo(b.DistanceMeters));
	}

	private void RevealValuableToTeam(ValuableObject valuable)
	{
		if ((Object)(object)valuable == (Object)null)
		{
			return;
		}
		try
		{
			valuable.Discover((State)0);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Native valuable reveal failed: " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private static bool IsObjectUsable(GameObject gameObject)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gameObject != (Object)null && gameObject.activeInHierarchy)
		{
			Scene scene = gameObject.scene;
			return ((Scene)(ref scene)).IsValid();
		}
		return false;
	}

	private static bool IsPhysGrabObjectHiddenOrDead(PhysGrabObject physGrabObject)
	{
		if ((Object)(object)physGrabObject == (Object)null)
		{
			return false;
		}
		object obj = PhysGrabObjectDeadField?.GetValue(physGrabObject);
		bool flag = default(bool);
		int num;
		if (obj is bool)
		{
			flag = (bool)obj;
			num = 1;
		}
		else
		{
			num = 0;
		}
		if (((uint)num & (flag ? 1u : 0u)) != 0)
		{
			return true;
		}
		obj = PhysGrabObjectIsHiddenField?.GetValue(physGrabObject);
		bool flag2 = default(bool);
		int num2;
		if (obj is bool)
		{
			flag2 = (bool)obj;
			num2 = 1;
		}
		else
		{
			num2 = 0;
		}
		return (byte)((uint)num2 & (flag2 ? 1u : 0u)) != 0;
	}

	private bool IsObjectInCart(Component component, PhysGrabObject physGrabObject)
	{
		return IsObjectInReferenceSet(component, physGrabObject, cartObjectSet);
	}

	private bool IsObjectInHaul(Component component, PhysGrabObject physGrabObject)
	{
		return IsObjectInReferenceSet(component, physGrabObject, haulObjectSet);
	}

	private static bool IsObjectInReferenceSet(Component component, PhysGrabObject physGrabObject, HashSet<object> set)
	{
		if (set == null || set.Count == 0)
		{
			return false;
		}
		GameObject val = (((Object)(object)component == (Object)null) ? null : component.gameObject);
		GameObject val2 = (((Object)(object)physGrabObject == (Object)null) ? null : ((Component)physGrabObject).gameObject);
		foreach (object item in set)
		{
			if (item != null)
			{
				if (item == component || item == val || item == physGrabObject || item == val2)
				{
					return true;
				}
				GameObject objectGameObject = GetObjectGameObject(item);
				if ((Object)(object)objectGameObject != (Object)null && (objectGameObject == val || objectGameObject == val2))
				{
					return true;
				}
			}
		}
		return false;
	}

	private static bool IsCartObject(Component component, PhysGrabObject physGrabObject)
	{
		if ((Object)(object)component != (Object)null && ((Object)(object)component.GetComponent<PhysGrabCart>() != (Object)null || (Object)(object)component.GetComponentInParent<PhysGrabCart>() != (Object)null || (Object)(object)component.GetComponentInChildren<PhysGrabCart>(false) != (Object)null))
		{
			return true;
		}
		if ((Object)(object)physGrabObject != (Object)null)
		{
			if (!((Object)(object)((Component)physGrabObject).GetComponent<PhysGrabCart>() != (Object)null) && !((Object)(object)((Component)physGrabObject).GetComponentInParent<PhysGrabCart>() != (Object)null))
			{
				return (Object)(object)((Component)physGrabObject).GetComponentInChildren<PhysGrabCart>(false) != (Object)null;
			}
			return true;
		}
		return false;
	}

	private bool TryRefreshLabel(ScanLabel label, Vector3 localPosition, float maxDistance)
	{
		//IL_008e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		if (label == null || (Object)(object)label.Target == (Object)null || !IsObjectUsable(label.Target.gameObject))
		{
			return false;
		}
		PhysGrabObject physGrabObject = label.PhysGrabObject;
		if (IsPhysGrabObjectHiddenOrDead(physGrabObject) || IsHeldByLocalPlayer(physGrabObject) || IsObjectInCart(label.Target, physGrabObject) || IsObjectInHaul(label.Target, physGrabObject))
		{
			return false;
		}
		if (label.IsCart && (showCarts == null || !showCarts.Value))
		{
			return false;
		}
		Vector3 objectCenter = GetObjectCenter(label.Target.transform, physGrabObject, label.Renderers);
		Vector3 val = objectCenter - localPosition;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		if (sqrMagnitude > maxDistance * maxDistance)
		{
			return false;
		}
		int distanceMeters = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude));
		if (label.IsValuable)
		{
			Component target = label.Target;
			ValuableObject val2 = (ValuableObject)(object)((target is ValuableObject) ? target : null);
			if (val2 != null)
			{
				string text = BuildValuableLabelText(label.DisplayName, Mathf.RoundToInt(GetValuableCurrentValue(val2)), distanceMeters);
				if (string.IsNullOrWhiteSpace(text))
				{
					return false;
				}
				label.PlainText = text;
				label.RichText = "<color=#00C832>" + text + "</color>";
				goto IL_015a;
			}
		}
		if (label.IsItem)
		{
			string text2 = BuildItemLabelText(label.DisplayName, distanceMeters);
			if (string.IsNullOrWhiteSpace(text2))
			{
				return false;
			}
			label.PlainText = text2;
			label.RichText = "<color=#62d8ff>" + text2 + "</color>";
		}
		goto IL_015a;
		IL_015a:
		label.Position = objectCenter;
		label.DistanceMeters = distanceMeters;
		return true;
	}

	private static Renderer[] GetUsableRenderers(Component root)
	{
		if (!((Object)(object)root == (Object)null))
		{
			return root.GetComponentsInChildren<Renderer>(false);
		}
		return Array.Empty<Renderer>();
	}

	private bool IsHeldByLocalPlayer(PhysGrabObject physGrabObject)
	{
		if ((Object)(object)physGrabObject == (Object)null)
		{
			return false;
		}
		PlayerAvatar localPlayerCached = GetLocalPlayerCached();
		if ((Object)(object)localPlayerCached == (Object)null)
		{
			return false;
		}
		if (PhysGrabObjectPlayerGrabbingField?.GetValue(physGrabObject) is IEnumerable enumerable)
		{
			foreach (object item in enumerable)
			{
				if (IsLocalGrabberObject(item, localPlayerCached))
				{
					return true;
				}
			}
		}
		PhysGrabber[] grabberObjectsCached = GetGrabberObjectsCached();
		foreach (PhysGrabber val in grabberObjectsCached)
		{
			if (!((Object)(object)val == (Object)null) && PhysGrabberGrabbedPhysGrabObjectField?.GetValue(val) == physGrabObject)
			{
				object obj = PhysGrabberGrabbedField?.GetValue(val);
				if ((!(obj is bool) || (bool)obj) && IsLocalGrabberObject(val, localPlayerCached))
				{
					return true;
				}
			}
		}
		return false;
	}

	private PhysGrabber[] GetGrabberObjectsCached()
	{
		if (grabberObjectsCache != null && Time.unscaledTime < nextGrabberRefreshTime)
		{
			return grabberObjectsCache;
		}
		grabberObjectsCache = Object.FindObjectsOfType<PhysGrabber>(true) ?? Array.Empty<PhysGrabber>();
		nextGrabberRefreshTime = Time.unscaledTime + 0.12f;
		return grabberObjectsCache;
	}

	private static bool IsLocalGrabberObject(object grabberObject, PlayerAvatar localPlayer)
	{
		if (grabberObject == null || (Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		if (grabberObject == localPlayer)
		{
			return true;
		}
		Component val = (Component)((grabberObject is Component) ? grabberObject : null);
		if (val != null && (val.GetComponentInParent<PlayerAvatar>() == localPlayer || val.GetComponentInChildren<PlayerAvatar>(true) == localPlayer))
		{
			return true;
		}
		PhysGrabber val2 = (PhysGrabber)((grabberObject is PhysGrabber) ? grabberObject : null);
		if (val2 != null && PhysGrabberPlayerAvatarField?.GetValue(val2) == localPlayer)
		{
			return true;
		}
		return grabberObject.GetType().GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(grabberObject) == localPlayer;
	}

	private static Vector3 GetObjectCenter(Transform fallback, PhysGrabObject physGrabObject)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		return GetObjectCenter(fallback, physGrabObject, null);
	}

	private static Vector3 GetObjectCenter(Transform fallback, PhysGrabObject physGrabObject, Renderer[] renderers)
	{
		//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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = (((Object)(object)physGrabObject != (Object)null) ? ((Component)physGrabObject).transform.position : (((Object)(object)fallback == (Object)null) ? Vector3.zero : fallback.position));
		if (TryGetVisualBoundsCenter((Component)(object)fallback, val, renderers, out var center))
		{
			return center;
		}
		return val;
	}

	private static bool TryGetVisualBoundsCenter(Component root, Vector3 anchor, out Vector3 center)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return TryGetVisualBoundsCenter(root, anchor, null, out center);
	}

	private static bool TryGetVisualBoundsCenter(Component root, Vector3 anchor, Renderer[] cachedRenderers, out Vector3 center)
	{
		//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_0018: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_00b6: 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_00af: Unknown result type (might be due to invalid IL or missing references)
		center = Vector3.zero;
		if ((Object)(object)root == (Object)null)
		{
			return false;
		}
		Bounds val = default(Bounds);
		bool flag = false;
		Renderer[] array = cachedRenderers ?? GetUsableRenderers(root);
		foreach (Renderer val2 in array)
		{
			if ((Object)(object)val2 == (Object)null || !val2.enabled)
			{
				continue;
			}
			Bounds bounds = val2.bounds;
			Vector3 val3 = ((Bounds)(ref bounds)).size;
			if (((Vector3)(ref val3)).sqrMagnitude <= 0.0001f)
			{
				continue;
			}
			val3 = ((Bounds)(ref bounds)).extents;
			float num = Mathf.Max(1.5f, ((Vector3)(ref val3)).magnitude * 4f);
			val3 = ((Bounds)(ref bounds)).center - anchor;
			if (!(((Vector3)(ref val3)).sqrMagnitude > num * num))
			{
				if (!flag)
				{
					val = bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(bounds);
				}
			}
		}
		if (!flag)
		{
			return false;
		}
		center = ((Bounds)(ref val)).center;
		return true;
	}

	private static bool TryGetBoundsCenter(Component root, out Vector3 center)
	{
		//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_0018: 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_0057: 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_00a7: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		center = Vector3.zero;
		if ((Object)(object)root == (Object)null)
		{
			return false;
		}
		Bounds val = default(Bounds);
		bool flag = false;
		Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(false);
		foreach (Renderer val2 in componentsInChildren)
		{
			if (!((Object)(object)val2 == (Object)null) && val2.enabled)
			{
				if (!flag)
				{
					val = val2.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(val2.bounds);
				}
			}
		}
		if (!flag)
		{
			Collider[] componentsInChildren2 = root.GetComponentsInChildren<Collider>(false);
			foreach (Collider val3 in componentsInChildren2)
			{
				if (!((Object)(object)val3 == (Object)null) && val3.enabled)
				{
					if (!flag)
					{
						val = val3.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val3.bounds);
					}
				}
			}
		}
		if (!flag)
		{
			return false;
		}
		center = ((Bounds)(ref val)).center;
		return true;
	}

	private static void FillCartObjectSet(HashSet<object> result)
	{
		result.Clear();
		PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
		foreach (PhysGrabCart val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			AddEnumerableObjects(result, PhysGrabCartItemsInCartField?.GetValue(val));
			object obj = PhysGrabCartInCartField?.GetValue(val);
			if (!(((obj == null) ? null : PhysGrabInCartObjectsField?.GetValue(obj)) is IEnumerable enumerable))
			{
				continue;
			}
			foreach (object item in enumerable)
			{
				object obj2 = PhysGrabInCartCartObjectPhysGrabObjectField?.GetValue(item);
				if (obj2 != null)
				{
					result.Add(obj2);
				}
			}
		}
	}

	private void RefreshContainmentSetsForFrame()
	{
		if (containmentSetFrame != Time.frameCount)
		{
			containmentSetFrame = Time.frameCount;
			if (!(Time.unscaledTime < nextContainmentRefreshTime))
			{
				nextContainmentRefreshTime = Time.unscaledTime + 0.12f;
				FillCartAndHaulObjectSets();
			}
		}
	}

	private void ForceRefreshContainmentSets()
	{
		containmentSetFrame = Time.frameCount;
		nextContainmentRefreshTime = Time.unscaledTime + 0.12f;
		FillCartAndHaulObjectSets();
	}

	private void FillCartAndHaulObjectSets()
	{
		FillCartObjectSet(cartObjectSet);
		FillDollarHaulObjectSet(haulObjectSet);
	}

	private static void FillDollarHaulObjectSet(HashSet<object> result)
	{
		result.Clear();
		object obj = RoundDirectorInstanceField?.GetValue(null);
		object rawList = ((obj == null) ? null : RoundDirectorDollarHaulListField?.GetValue(obj));
		AddEnumerableObjects(result, rawList);
	}

	private static void AddEnumerableObjects(HashSet<object> result, object rawList)
	{
		if (!(rawList is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			if (item != null)
			{
				result.Add(item);
			}
		}
	}

	private static GameObject GetObjectGameObject(object value)
	{
		GameObject val = (GameObject)((value is GameObject) ? value : null);
		if (val != null)
		{
			return val;
		}
		Component val2 = (Component)((value is Component) ? value : null);
		if (val2 != null)
		{
			return val2.gameObject;
		}
		return null;
	}

	private static float GetValuableCurrentValue(ValuableObject valuable)
	{
		if ((Object)(object)valuable == (Object)null)
		{
			return 0f;
		}
		object obj = ValuableValueSetField?.GetValue(valuable);
		if (obj is bool && !(bool)obj)
		{
			return 0f;
		}
		if (ValuableCurrentValueField?.GetValue(valuable) is float num)
		{
			return Mathf.Max(0f, num);
		}
		return 0f;
	}

	private static string GetItemDisplayName(ItemAttributes item)
	{
		string text = ItemNameField?.GetValue(item) as string;
		if (!string.IsNullOrWhiteSpace(text))
		{
			return TranslateItemName(text.Trim());
		}
		return TranslateItemName(CleanName(((Object)(object)item == (Object)null) ? string.Empty : ((Object)((Component)item).gameObject).name));
	}

	private static string TranslateItemName(string rawName)
	{
		string text = CleanName(rawName);
		rawName = ItemNameLocalizer.CleanDisplayName(text);
		if (string.IsNullOrWhiteSpace(rawName))
		{
			rawName = (string.IsNullOrWhiteSpace(text) ? "未知物品" : text);
		}
		if (InstanceLanguage == DisplayLanguage.English)
		{
			return rawName;
		}
		return ItemNameLocalizer.Translate(rawName);
	}

	private static string CleanName(string rawName)
	{
		if (string.IsNullOrWhiteSpace(rawName))
		{
			return "未知物品";
		}
		string input = rawName.Replace("(Clone)", string.Empty).Trim();
		input = Regex.Replace(input, "\\s+", " ");
		if (!string.IsNullOrWhiteSpace(input))
		{
			return input;
		}
		return "未知物品";
	}

	private static string FormatMoney(int value)
	{
		return Math.Max(0, value).ToString("N0").Replace(".", ",");
	}

	private string BuildValuableLabelText(string name, int value, int distanceMeters)
	{
		List<string> list = new List<string>(3);
		if (showValuableNames == null || showValuableNames.Value)
		{
			list.Add(string.IsNullOrWhiteSpace(name) ? "Unknown" : name.Trim());
		}
		if (showValuablePrices == null || showValuablePrices.Value)
		{
			list.Add("$" + FormatMoney(value));
		}
		if (showValuableDistance == null || showValuableDistance.Value)
		{
			list.Add($"{Mathf.Max(0, distanceMeters)}m");
		}
		return string.Join(" ", list);
	}

	private string BuildItemLabelText(string name, int distanceMeters)
	{
		if (string.IsNullOrWhiteSpace(name))
		{
			return string.Empty;
		}
		if (showItemDistance == null || showItemDistance.Value)
		{
			return $"{name.Trim()} {Mathf.Max(0, distanceMeters)}m";
		}
		return name.Trim();
	}

	private bool TryGetLocalPosition(out Vector3 position)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0095: 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_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)
		//IL_005b: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		if (cachedLocalPositionFrame == Time.frameCount)
		{
			position = cachedLocalPosition;
			return true;
		}
		PlayerAvatar localPlayerCached = GetLocalPlayerCached();
		if ((Object)(object)localPlayerCached != (Object)null)
		{
			object? obj = PlayerTransformField?.GetValue(localPlayerCached);
			Transform val = (Transform)((obj is Transform) ? obj : null);
			position = (((Object)(object)val == (Object)null) ? ((Component)localPlayerCached).transform.position : val.position);
			cachedLocalPosition = position;
			cachedLocalPositionFrame = Time.frameCount;
			return true;
		}
		Camera worldCameraCached = GetWorldCameraCached();
		if ((Object)(object)worldCameraCached != (Object)null)
		{
			position = ((Component)worldCameraCached).transform.position;
			cachedLocalPosition = position;
			cachedLocalPositionFrame = Time.frameCount;
			return true;
		}
		position = Vector3.zero;
		return false;
	}

	private PlayerAvatar GetLocalPlayerCached()
	{
		if ((Object)(object)cachedLocalPlayer != (Object)null && (Object)(object)((Component)cachedLocalPlayer).gameObject != (Object)null && ((Component)cachedLocalPlayer).gameObject.activeInHierarchy && Time.unscaledTime < nextLocalPlayerRefreshTime)
		{
			return cachedLocalPlayer;
		}
		cachedLocalPlayer = GetLocalPlayer();
		nextLocalPlayerRefreshTime = Time.unscaledTime + 1f;
		return cachedLocalPlayer;
	}

	private static PlayerAvatar GetLocalPlayer()
	{
		PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>();
		PlayerAvatar[] array2 = array;
		bool flag = default(bool);
		foreach (PlayerAvatar val in array2)
		{
			if (!((Object)(object)val == (Object)null))
			{
				object obj = PlayerIsLocalField?.GetValue(val);
				int num;
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != 0)
				{
					return val;
				}
			}
		}
		if (array.Length == 0)
		{
			return null;
		}
		return array[0];
	}

	private static Camera GetWorldCamera()
	{
		return Camera.main ?? Object.FindObjectOfType<Camera>();
	}

	private Camera GetWorldCameraCached()
	{
		if (cachedCameraFrame == Time.frameCount && (Object)(object)cachedCamera != (Object)null)
		{
			return cachedCamera;
		}
		cachedCameraFrame = Time.frameCount;
		cachedCamera = GetWorldCamera();
		return cachedCamera;
	}

	private static bool TryWorldToGuiPoint(Camera camera, Vector3 worldPosition, out Vector2 guiPosition)
	{
		//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_0017: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		guiPosition = Vector2.zero;
		if ((Object)(object)camera == (Object)null)
		{
			return false;
		}
		Vector3 val = camera.WorldToScreenPoint(worldPosition);
		if (val.z <= 0f)
		{
			return false;
		}
		float num = ((camera.pixelWidth > 0) ? camera.pixelWidth : Screen.width);
		float num2 = ((camera.pixelHeight > 0) ? camera.pixelHeight : Screen.height);
		if ((Object)(object)camera.targetTexture != (Object)null)
		{
			num = Mathf.Max(1, ((Texture)camera.targetTexture).width);
			num2 = Mathf.Max(1, ((Texture)camera.targetTexture).height);
		}
		float num3 = val.x * ((float)Screen.width / Mathf.Max(1f, num));
		float num4 = val.y * ((float)Screen.height / Mathf.Max(1f, num2));
		guiPosition = new Vector2(num3, (float)Screen.height - num4);
		return true;
	}

	private GUIStyle GetCenteredStyle(int size, bool shadow)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<int, GUIStyle> dictionary = labelStyleCache;
		if (dictionary.TryGetValue(size, out var value))
		{
			return value;
		}
		GUIStyle val = new GUIStyle(GUI.skin.label)
		{
			alignment = (TextAnchor)4,
			richText = true,
			fontSize = size,
			fontStyle = (FontStyle)1,
			wordWrap = false,
			clipping = (TextClipping)0
		};
		val.normal.textColor = (Color)(shadow ? new Color(0f, 0f, 0f, 0.88f) : Color.white);
		dictionary[size] = val;
		return val;
	}

	private static int GetDistanceScaledFontSize(int baseSize, int shrinkPercent, float distance, float maxDistance, int maxSize)
	{
		baseSize = Mathf.Clamp(baseSize, 8, maxSize);
		shrinkPercent = Mathf.Clamp(shrinkPercent, 0, 75);
		if (maxDistance <= 0.1f || shrinkPercent <= 0)
		{
			return baseSize;
		}
		float num = Mathf.Clamp01(distance / maxDistance);
		float num2 = 1f - (float)shrinkPercent / 100f;
		float num3 = Mathf.Lerp(1f, num2, num);
		return Mathf.Clamp(Mathf.RoundToInt((float)baseSize * num3), 8, maxSize);
	}

	private void UpdateCachedScanKey()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		cachedScanKeyText = SanitizeKeyName((scanKey == null) ? "f" : scanKey.Value);
		if (!Enum.TryParse<KeyCode>(cachedScanKeyText, ignoreCase: true, out cachedScanKey))
		{
			cachedScanKey = (KeyCode)102;
			cachedScanKeyText = "f";
		}
		if (scanKey != null && scanKey.Value != cachedScanKeyText)
		{
			scanKey.Value = cachedScanKeyText;
		}
	}

	private static string SanitizeKeyName(string value)
	{
		if (string.IsNullOrWhiteSpace(value))
		{
			return "f";
		}
		string text = value.Trim();
		if (text.EndsWith("键", StringComparison.OrdinalIgnoreCase))
		{
			text = text.Substring(0, text.Length - 1);
		}
		return text.Trim().ToLowerInvariant();
	}

	private static float ClampScanInterval(float value)
	{
		return Mathf.Clamp(value, 0.1f, 5f);
	}

	private void MakePluginHostPersistent()
	{
		try
		{
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, AcceptableValueBase acceptableValues, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, acceptableValues, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private static void DrawInfo(ConfigEntryBase entry)
	{
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(entry.Definition.Key, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
		GUILayout.Label(entry.BoxedValue?.ToString() ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
		GUILayout.EndHorizontal();
	}
}
internal sealed class ReferenceObjectComparer : IEqualityComparer<object>
{
	public static readonly ReferenceObjectComparer Instance = new ReferenceObjectComparer();

	public new bool Equals(object x, object y)
	{
		return x == y;
	}

	public int GetHashCode(object obj)
	{
		if (obj != null)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
		return 0;
	}
}
internal static class ItemNameLocalizer
{
	private static readonly Dictionary<string, string> NameMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
	{
		{ "Item Upgrade", "升级物品" },
		{ "Upgrade", "升级" },
		{ "Gun", "枪" },
		{ "Shotgun", "霰弹枪" },
		{ "Tranq Gun", "麻醉枪" },
		{ "Tranq", "麻醉枪" },
		{ "Handgun", "手枪" },
		{ "Pistol", "手枪" },
		{ "Revolver", "左轮手枪" },
		{ "Grenade", "手雷" },
		{ "Stun Grenade", "眩晕手雷" },
		{ "Shockwave Grenade", "冲击波手雷" },
		{ "Explosive Grenade", "爆炸手雷" },
		{ "Mine", "地雷" },
		{ "Explosive Mine", "爆炸地雷" },
		{ "Health Pack", "血包" },
		{ "Healthpack", "血包" },
		{ "Medkit", "医疗包" },
		{ "First Aid", "急救包" },
		{ "Melee", "近战武器" },
		{ "Baseball Bat", "棒球棍" },
		{ "Bat", "球棒" },
		{ "Hammer", "锤子" },
		{ "Sword", "剑" },
		{ "Pan", "平底锅" },
		{ "Frying Pan", "平底锅" },
		{ "Cart", "购物车" },
		{ "Small Cart", "小购物车" },
		{ "Extraction Tracker", "提取点追踪器" },
		{ "Tracker", "追踪器" },
		{ "Map", "地图" },
		{ "Drone", "无人机" },
		{ "Orb", "球体" },
		{ "Crystal", "水晶" },
		{ "Diamond", "钻石" },
		{ "Gold", "黄金" },
		{ "Gold Bar", "金条" },
		{ "Money", "钱" },
		{ "Cash", "现金" },
		{ "Painting", "画作" },
		{ "Vase", "花瓶" },
		{ "Statue", "雕像" },
		{ "Crown", "王冠" },
		{ "Ring", "戒指" },
		{ "Necklace", "项链" },
		{ "Cup", "杯子" },
		{ "Trophy", "奖杯" },
		{ "Bottle", "瓶子" },
		{ "Box", "箱子" },
		{ "Crate", "木箱" },
		{ "Chest", "宝箱" },
		{ "Book", "书" },
		{ "Clock", "钟表" },
		{ "Lamp", "灯" },
		{ "Mirror", "镜子" },
		{ "Computer", "电脑" },
		{ "Phone", "电话" },
		{ "Radio", "收音机" },
		{ "Toy", "玩具" },
		{ "Robot", "机器人" },
		{ "Skull", "头骨" }
	};

	private static readonly Dictionary<string, string> WordMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
	{
		{ "upgrade", "升级" },
		{ "gun", "枪" },
		{ "shotgun", "霰弹枪" },
		{ "tranq", "麻醉" },
		{ "pistol", "手枪" },
		{ "revolver", "左轮" },
		{ "grenade", "手雷" },
		{ "stun", "眩晕" },
		{ "shockwave", "冲击波" },
		{ "explosive", "爆炸" },
		{ "mine", "地雷" },
		{ "health", "生命" },
		{ "pack", "包" },
		{ "medkit", "医疗包" },
		{ "melee", "近战" },
		{ "bat", "球棒" },
		{ "hammer", "锤子" },
		{ "sword", "剑" },
		{ "pan", "锅" },
		{ "cart", "购物车" },
		{ "small", "小" },
		{ "big", "大" },
		{ "large", "大" },
		{ "extraction", "提取" },
		{ "tracker", "追踪器" },
		{ "map", "地图" },
		{ "drone", "无人机" },
		{ "orb", "球" },
		{ "crystal", "水晶" },
		{ "diamond", "钻石" },
		{ "gold", "黄金" },
		{ "bar", "条" },
		{ "money", "钱" },
		{ "cash", "现金" },
		{ "painting", "画作" },
		{ "vase", "花瓶" },
		{ "statue", "雕像" },
		{ "crown", "王冠" },
		{ "ring", "戒指" },
		{ "necklace", "项链" },
		{ "cup", "杯子" },
		{ "trophy", "奖杯" },
		{ "bottle", "瓶子" },
		{ "box", "箱子" },
		{ "crate", "木箱" },
		{ "chest", "箱子" },
		{ "book", "书" },
		{ "clock", "钟表" },
		{ "lamp", "灯" },
		{ "mirror", "镜子" },
		{ "computer", "电脑" },
		{ "phone", "电话" },
		{ "radio", "收音机" },
		{ "toy", "玩具" },
		{ "robot", "机器人" },
		{ "skull", "头骨" },
		{ "wood", "木制" },
		{ "metal", "金属" },
		{ "silver", "银色" },
		{ "bronze", "青铜" },
		{ "red", "红色" },
		{ "blue", "蓝色" },
		{ "green", "绿色" },
		{ "black", "黑色" },
		{ "white", "白色" },
		{ "old", "旧" },
		{ "new", "新" }
	};

	public static string Translate(string rawName)
	{
		string text = CleanDisplayName(rawName);
		if (string.IsNullOrWhiteSpace(text))
		{
			return CleanName(rawName);
		}
		if (NameMap.TryGetValue(text, out var value))
		{
			return value;
		}
		string name = SplitWords(text);
		name = StripTypePrefix(name);
		if (NameMap.TryGetValue(name, out value))
		{
			return value;
		}
		string[] array = name.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
		if (array.Length == 0)
		{
			return text;
		}
		bool flag = false;
		List<string> list = new List<string>(array.Length);
		string[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			string text2 = Regex.Replace(array2[i], "[^A-Za-z0-9]", string.Empty);
			if (!string.IsNullOrWhiteSpace(text2) && !IsIgnoredTypeWord(text2))
			{
				int result;
				if (WordMap.TryGetValue(text2, out var value2))
				{
					list.Add(value2);
					flag = true;
				}
				else if (!int.TryParse(text2, out result))
				{
					list.Add(text2);
				}
			}
		}
		if (!flag || list.Count <= 0)
		{
			return text;
		}
		return string.Join("", list);
	}

	public static string CleanDisplayName(string rawName)
	{
		string text = CleanName(rawName);
		string text2 = StripTypePrefix(text);
		if (!string.IsNullOrWhiteSpace(text2))
		{
			return text2;
		}
		return text;
	}

	private static string StripTypePrefix(string name)
	{
		if (string.IsNullOrWhiteSpace(name))
		{
			return string.Empty;
		}
		return Regex.Replace(Regex.Replace(Regex.Replace(SplitWords(name), "^(valuable\\s*object|valuable|item)\\s+", string.Empty, RegexOptions.IgnoreCase), "\\s+(valuable\\s*object|valuable|item)$", string.Empty, RegexOptions.IgnoreCase), "\\s+", " ").Trim();
	}

	private static bool IsIgnoredTypeWord(string word)
	{
		if (!string.Equals(word, "valuable", StringComparison.OrdinalIgnoreCase) && !string.Equals(word, "object", StringComparison.OrdinalIgnoreCase))
		{
			return string.Equals(word, "item", StringComparison.OrdinalIgnoreCase);
		}
		return true;
	}

	private static string CleanName(string rawName)
	{
		if (string.IsNullOrWhiteSpace(rawName))
		{
			return string.Empty;
		}
		return Regex.Replace(Regex.Replace(rawName.Replace("(Clone)", string.Empty).Trim(), "[_\\-]+", " "), "\\s+", " ").Trim();
	}

	private static string SplitWords(string value)
	{
		return Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(value, "([a-z])([A-Z])", "$1 $2"), "([A-Za-z])(\\d)", "$1 $2"), "(\\d)([A-Za-z])", "$1 $2"), "[_\\-]+", " "), "\\s+", " ").Trim();
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public int? Order;

	public bool? ReadOnly;
}