Decompiled source of WZC UI v1.1.4

plugins\WZC_UI.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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_UI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+15b47d01bb3e350705597778c7083ed77b8254b9")]
[assembly: AssemblyProduct("WZC_UI")]
[assembly: AssemblyTitle("WZC_UI")]
[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 TeammateDisplayMode
{
	常显,
	按键显示
}
public enum DisplayMode
{
	文字显示,
	原生UI显示
}
public enum DisplayLanguage
{
	中文,
	English
}
[BepInPlugin("local.repo.enemycountoverlay", "A.WZC_UI", "1.1.4")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "local.repo.enemycountoverlay";

	public const string PluginVersion = "1.1.4";

	public const string PluginName = "A.WZC_UI";

	private static Plugin Instance;

	private const float MinimumRefreshIntervalSeconds = 0.1f;

	private const float ProximityAutoShowLingerSeconds = 5f;

	private const float EnemyProximityPopSeconds = 1.2f;

	private const float EnemyProximityPopFontMultiplier = 2f;

	private const float PlayerColorRefreshIntervalSeconds = 0.5f;

	private const float RunLevelInactiveGraceSeconds = 4f;

	private const string TeammateIcon = "\ud83e\udd16";

	private const string CartIcon = "\ud83d\uded2";

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

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

	private const string TeammateConfigSection = "B.好友局内显示";

	private const string EnemyWorldConfigSection = "C.敌人局内显示";

	private const string CartWorldConfigSection = "D.购物车局内显示";

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

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

	private static readonly FieldInfo PlayerNameField = typeof(PlayerAvatar).GetField("playerName", 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 PlayerAvatarVisualsField = typeof(PlayerAvatar).GetField("playerAvatarVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PlayerAvatarVisualsColorField = typeof(PlayerAvatarVisuals).GetField("color", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PlayerAvatarVisualsColorSetField = typeof(PlayerAvatarVisuals).GetField("colorSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

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

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

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

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

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

	private static readonly FieldInfo DeathHeadTriggeredPositionField = typeof(PlayerDeathHead).GetField("triggeredPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo DeathHeadOverridePositionTransformField = typeof(PlayerDeathHead).GetField("overridePositionTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

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

	private static readonly FieldInfo SpectateCameraPlayerField = typeof(SpectateCamera).GetField("player", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo SpectateCameraPlayerOverrideField = typeof(SpectateCamera).GetField("playerOverride", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo SpectateCameraMainCameraField = typeof(SpectateCamera).GetField("MainCamera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyParentField = typeof(Enemy).GetField("EnemyParent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyTypeField = typeof(Enemy).GetField("Type", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyCenterTransformField = typeof(Enemy).GetField("CenterTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyParentNameField = typeof(EnemyParent).GetField("enemyName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyParentSpawnedField = typeof(EnemyParent).GetField("Spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo EnemyHealthField = typeof(Enemy).GetField("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

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

	private static readonly FieldInfo GoalUiTextField = typeof(GoalUI).GetField("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(GoalUI).GetField("uiText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly GUIContent ReusableGuiContent = new GUIContent();

	private static readonly CultureInfo MoneyCulture = CultureInfo.GetCultureInfo("en-US");

	private static readonly HashSet<int> BoundsVisitedBuffer = new HashSet<int>();

	private static readonly List<Renderer> BoundsRendererBuffer = new List<Renderer>();

	private static readonly List<Collider> BoundsColliderBuffer = new List<Collider>();

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

	private static int playerAliveFrameCacheFrame = -1;

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

	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 ValuablePhotonViewField = typeof(ValuableObject).GetField("photonView", 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 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 PhysGrabCartCurrentStateField = typeof(PhysGrabCart).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

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

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

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

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

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

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

	private static readonly FieldInfo ItemEquippableCurrentStateField = typeof(ItemEquippable).GetField("currentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemEquippableIsEquippedField = typeof(ItemEquippable).GetField("isEquipped", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemEquippableIsEquippingField = typeof(ItemEquippable).GetField("isEquipping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabObjectGrabbedField = typeof(PhysGrabObject).GetField("grabbed", 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 PhysGrabberIsPushingField = typeof(PhysGrabber).GetField("isPushing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo PhysGrabberIsPullingField = typeof(PhysGrabber).GetField("isPulling", 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 RoundDirectorCurrentHaulField = typeof(RoundDirector).GetField("currentHaul", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static int cachedWorldLabelCameraFrame = -1;

	private static Camera cachedWorldLabelCamera;

	private static int cachedRunLevelActiveFrame = -1;

	private static bool cachedRunLevelActive;

	private static int cachedLocalPlayerFrame = -1;

	private static PlayerAvatar cachedLocalPlayer;

	private static ConfigEntry<string> keyCaptureEntry;

	private static readonly HashSet<int> valuablesCurrentlyInDollarHaul = new HashSet<int>();

	private static readonly Dictionary<Type, PropertyInfo> PhotonViewIdPropertyCache = new Dictionary<Type, PropertyInfo>();

	private static readonly Dictionary<Type, FieldInfo> PhotonViewIdFieldCache = new Dictionary<Type, FieldInfo>();

	private static readonly Dictionary<Type, PropertyInfo> PhotonViewOwnerPropertyCache = new Dictionary<Type, PropertyInfo>();

	private static readonly Dictionary<Type, PropertyInfo> PhotonOwnerNickNamePropertyCache = new Dictionary<Type, PropertyInfo>();

	private ConfigEntry<string> moduleNameInfo;

	private ConfigEntry<string> moduleVersionInfo;

	private ConfigEntry<string> contactInfo;

	private ConfigEntry<bool> modEnabled;

	private ConfigEntry<bool> overlayEnabled;

	private ConfigEntry<bool> sectionSpacing;

	private ConfigEntry<DisplayLanguage> displayLanguage;

	private ConfigEntry<bool> enemyNicknameEnabled;

	private ConfigEntry<DisplayMode> displayMode;

	private ConfigEntry<int> fontSize;

	private ConfigEntry<float> updateInterval;

	private ConfigEntry<int> overlayOffsetX;

	private ConfigEntry<int> overlayOffsetY;

	private ConfigEntry<bool> showEnemySection;

	private ConfigEntry<bool> showBreakdown;

	private ConfigEntry<bool> showTotalEnemyCount;

	private ConfigEntry<bool> showValueSection;

	private ConfigEntry<bool> showMapLostValue;

	private ConfigEntry<bool> showExplorationProgress;

	private ConfigEntry<bool> showMapTotalValue;

	private ConfigEntry<bool> showCurrentRunSubmittedFunds;

	private ConfigEntry<bool> showShopRemainingFunds;

	private ConfigEntry<bool> showLevelInfo;

	private ConfigEntry<bool> showTeammateInfoSection;

	private ConfigEntry<bool> showDeadTeammates;

	private ConfigEntry<bool> showAliveTeammates;

	private ConfigEntry<bool> showPlayerCounts;

	private ConfigEntry<bool> teammateOverlayEnabled;

	private ConfigEntry<bool> teammateAliveOverlayEnabled;

	private ConfigEntry<bool> teammateDeadOverlayEnabled;

	private ConfigEntry<int> teammateFontSize;

	private ConfigEntry<float> teammateLabelHeightOffset;

	private ConfigEntry<int> teammateFarFontShrinkPercent;

	private ConfigEntry<float> teammateUpdateInterval;

	private ConfigEntry<TeammateDisplayMode> teammateDisplayMode;

	private ConfigEntry<string> teammateToggleKey;

	private ConfigEntry<int> teammateHoldSeconds;

	private ConfigEntry<bool> teammateProximityAutoShowEnabled;

	private ConfigEntry<int> teammateProximityAutoShowDistance;

	private ConfigEntry<bool> enemyOverlayEnabled;

	private ConfigEntry<int> enemyFontSize;

	private ConfigEntry<int> enemyFarFontShrinkPercent;

	private ConfigEntry<float> enemyUpdateInterval;

	private ConfigEntry<TeammateDisplayMode> enemyDisplayMode;

	private ConfigEntry<string> enemyToggleKey;

	private ConfigEntry<int> enemyHoldSeconds;

	private ConfigEntry<bool> enemyProximityAutoShowEnabled;

	private ConfigEntry<int> enemyProximityAutoShowDistance;

	private ConfigEntry<bool> cartSectionEnabled;

	private ConfigEntry<bool> cartOverlayEnabled;

	private ConfigEntry<bool> smallCartOverlayEnabled;

	private ConfigEntry<int> cartFontSize;

	private ConfigEntry<int> cartFarFontShrinkPercent;

	private ConfigEntry<float> cartLabelHeightOffset;

	private ConfigEntry<float> cartUpdateInterval;

	private GameObject overlayObject;

	private GameObject overlayCanvasObject;

	private Canvas overlayCanvas;

	private RectTransform overlayRect;

	private TextMeshProUGUI overlayLabel;

	private Harmony valuableHaulHarmony;

	private string overlayText = string.Empty;

	private string lastNativeOverlayText;

	private int lastNativeOverlayFontSize = -1;

	private int lastNativeOverlayOffsetX = int.MinValue;

	private int lastNativeOverlayOffsetY = int.MinValue;

	private bool lastNativeOverlayShowBreakdown;

	private string lastPlainOverlaySource;

	private string lastPlainOverlayText = string.Empty;

	private string lastTextOverlaySource;

	private int lastTextOverlayFontSize = -1;

	private bool lastTextOverlayShowBreakdown;

	private int lastTextOverlayOffsetX = int.MinValue;

	private int lastTextOverlayOffsetY = int.MinValue;

	private int lastTextOverlayScreenWidth = -1;

	private int lastTextOverlayScreenHeight = -1;

	private Rect cachedTextOverlayRect;

	private Rect cachedTextOverlayShadowRect;

	private float cachedTextOverlayWidth;

	private string cachedTextOverlayPlainText = string.Empty;

	private readonly List<EnemyLabelInfo> enemyLabels = new List<EnemyLabelInfo>();

	private readonly List<WzcUiCartDistance> cartDistanceCache = new List<WzcUiCartDistance>();

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

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

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

	private readonly List<int> reusableIntKeys = new List<int>();

	private readonly List<int> reusableSnapshotKeys = new List<int>();

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

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

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

	private readonly Dictionary<int, bool> smallCartTypeCache = new Dictionary<int, bool>();

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

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

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

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

	private readonly List<Enemy> activeEnemyBuffer = new List<Enemy>();

	private readonly Dictionary<string, int> enemyBreakdownBuffer = new Dictionary<string, int>();

	private readonly List<KeyValuePair<string, int>> orderedEnemyBreakdownBuffer = new List<KeyValuePair<string, int>>();

	private readonly List<string> enemyBreakdownLineBuffer = new List<string>();

	private readonly List<string> monsterSectionPartsBuffer = new List<string>();

	private readonly List<string> valueSectionPartsBuffer = new List<string>();

	private readonly List<string> teammateSectionPartsBuffer = new List<string>();

	private readonly List<string> evacuatedFundsLineBuffer = new List<string>();

	private readonly List<string> overlayPartsBuffer = new List<string>();

	private readonly List<string> playerColorKeyBuffer = new List<string>();

	private readonly List<object> currentDollarHaulObjectsBuffer = new List<object>();

	private readonly List<object> currentCartObjectsBuffer = new List<object>();

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

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

	private readonly List<PhysGrabCart> activeCartBuffer = new List<PhysGrabCart>();

	private readonly List<CartLabelCandidate> cartLabelCandidateBuffer = new List<CartLabelCandidate>();

	private Enemy[] enemyObjectsFrameCache = Array.Empty<Enemy>();

	private PhysGrabCart[] cartObjectsFrameCache = Array.Empty<PhysGrabCart>();

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

	private List<PlayerAvatar> playerObjectsFrameCache;

	private readonly Dictionary<int, string> enemyDisplayNameCache = new Dictionary<int, string>();

	private readonly Dictionary<int, string> playerNameCache = new Dictionary<int, string>();

	private readonly Dictionary<string, PlayerColorCacheEntry> playerColorCache = new Dictionary<string, PlayerColorCacheEntry>();

	private readonly Dictionary<int, LabelYOffsetCache> playerLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();

	private readonly Dictionary<int, LabelYOffsetCache> enemyLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();

	private readonly Dictionary<int, LabelYOffsetCache> cartLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>();

	private DisplayLanguage cachedEnemyDisplayNameLanguage;

	private bool cachedEnemyNicknameEnabled;

	private bool hasCachedEnemyDisplayNameLanguage;

	private float refreshTimer;

	private float keyNormalizeTimer;

	private float teammateVisibleTimer;

	private float teammateProximityVisibleTimer;

	private float teammateProximityRefreshTimer;

	private float enemyRefreshTimer;

	private float enemyProximityRefreshTimer;

	private float enemyVisibleTimer;

	private float enemyProximityVisibleTimer;

	private float cartRefreshTimer;

	private int enemyObjectsFrameCacheFrame = -1;

	private int cartObjectsFrameCacheFrame = -1;

	private int grabberObjectsFrameCacheFrame = -1;

	private int playerObjectsFrameCacheFrame = -1;

	private int playerNameCacheFrame = -1;

	private bool cartDistanceCacheValid;

	private int cartLabelIndexLevelNumber = -1;

	private int nextLargeCartLabelIndex = 1;

	private int nextSmallCartLabelIndex = 1;

	private int trackedLevelNumber = -1;

	private float previousExtractedValue = -1f;

	private float accumulatedLostValue;

	private bool hasLoggedUpdateError;

	private bool runtimeWasActive;

	private bool levelTransitionLogIndicatesRun;

	private float lastConfirmedRunLevelTime = -999f;

	private int submittedFundsSnapshotLevelNumber = -1;

	private float submittedFundsBaselineTotalHaul = -1f;

	private float submittedFundsSnapshot;

	private int shopRemainingSnapshotLevelNumber = -1;

	private float shopRemainingFundsSnapshot = -1f;

	private readonly Dictionary<int, ValuableSnapshot> valuableSnapshots = new Dictionary<int, ValuableSnapshot>();

	private DisplayLanguage CurrentLanguage
	{
		get
		{
			if (displayLanguage != null)
			{
				return displayLanguage.Value;
			}
			return DisplayLanguage.中文;
		}
	}

	private bool UseEnemyNicknameNames
	{
		get
		{
			if (CurrentLanguage == DisplayLanguage.中文 && enemyNicknameEnabled != null)
			{
				return enemyNicknameEnabled.Value;
			}
			return false;
		}
	}

	private void Awake()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Expected O, but got Unknown
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_032d: Expected O, but got Unknown
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Expected O, but got Unknown
		//IL_044d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: Expected O, but got Unknown
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0502: Expected O, but got Unknown
		//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ae: Expected O, but got Unknown
		//IL_0677: Unknown result type (might be due to invalid IL or missing references)
		//IL_0681: Expected O, but got Unknown
		//IL_0722: Unknown result type (might be due to invalid IL or missing references)
		//IL_072c: Expected O, but got Unknown
		//IL_0824: Unknown result type (might be due to invalid IL or missing references)
		//IL_082e: Expected O, but got Unknown
		//IL_0938: Unknown result type (might be due to invalid IL or missing references)
		//IL_0942: Expected O, but got Unknown
		//IL_096d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0977: Expected O, but got Unknown
		//IL_09ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_09b5: Expected O, but got Unknown
		//IL_09e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ef: Expected O, but got Unknown
		//IL_0a1f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a29: Expected O, but got Unknown
		Instance = this;
		MakePluginHostPersistent();
		Application.logMessageReceived += new LogCallback(OnUnityLogMessageReceived);
		moduleNameInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组名称", "WZC_定制UI", new ConfigDescription("当前模组的中文名称。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 1000,
				CustomDrawer = DrawContactInfo,
				ReadOnly = true
			}
		}));
		moduleNameInfo.Value = "WZC_定制UI";
		moduleVersionInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "模组版本号", "1.1.4", new ConfigDescription("当前模组版本号。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 990,
				CustomDrawer = DrawContactInfo,
				ReadOnly = true
			}
		}));
		moduleVersionInfo.Value = "1.1.4";
		contactInfo = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", "REPO交流QQ群", "824639225", new ConfigDescription("REPO游戏交流、BUG反馈、优化建议、功能请求请加QQ群。此处只是提示,不影响功能。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 980,
				CustomDrawer = DrawContactInfo,
				ReadOnly = true
			}
		}));
		contactInfo.Value = "824639225";
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "模组启用", true, ConfigDescriptionWithOrder("关闭后整个模组所有UI显示功能都不生效,包括右下角显示、队友/敌人距离、购物车距离、怪物统计和价值统计。", 990));
		displayLanguage = ((BaseUnityPlugin)this).Config.Bind<DisplayLanguage>("A.全局设置", "语言/Language", DisplayLanguage.中文, ConfigDescriptionWithOrder("选择游戏内显示文本的语言。默认中文,English 会把怪物名称和右下角字段名切换为英文。", 980));
		enemyNicknameEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "敌人名字优化", true, ConfigDescriptionWithOrder("默认开启。仅在语言为中文时生效,会把直接翻译的敌人名称优化成更顺口、更好辨认的中文名字;语言为 English 时始终显示英文。", 970));
		teammateOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "启用", true, ConfigDescriptionWithOrder("在局内显示好友名字、距离和死亡状态。", 600));
		teammateDeadOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "死亡好友显示", true, ConfigDescriptionWithOrder("开启后,局内显示死亡好友的名字和距离。", 599));
		teammateAliveOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "存活好友显示", true, ConfigDescriptionWithOrder("开启后,局内显示存活好友的名字和距离。", 598));
		teammateFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("好友局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 590));
		teammateFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "远处字体变小/%", 30, new ConfigDescription("好友距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 589
			}
		}));
		teammateLabelHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("B.好友局内显示", "显示高度/米", 0.05f, new ConfigDescription("好友文字距离角色模型顶部额外抬高多少米。默认0.05米,数值越大文字越高。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 585
			}
		}));
		teammateDisplayMode = ((BaseUnityPlugin)this).Config.Bind<TeammateDisplayMode>("B.好友局内显示", "显示方式", TeammateDisplayMode.常显, ConfigDescriptionWithOrder("常显,或按键后显示一段时间。", 580));
		teammateUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("B.好友局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次好友局内信息。", new AcceptableValueRange<float>(0.1f, 5f), 570));
		teammateToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("B.好友局内显示", "显示按键", "f", new ConfigDescription("按键显示模式下,按下后显示好友局内信息。可以填写 f、t、g、f1、mouse3 这类 KeyCode 名称。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 560,
				CustomDrawer = DrawKeyBinding
			}
		}));
		teammateHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "按键显示持续/秒", 5, ConfigDescriptionWithOrder<int>("按下好友显示按键后,好友距离显示持续多少秒。", new AcceptableValueRange<int>(1, 30), 550));
		teammateProximityAutoShowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.好友局内显示", "启用靠近自动显示", true, ConfigDescriptionWithOrder("开启后,只要有好友进入指定距离内,就会临时常显好友信息;好友离开范围后5秒恢复原显示方式。", 540));
		teammateProximityAutoShowDistance = ((BaseUnityPlugin)this).Config.Bind<int>("B.好友局内显示", "靠近自动显示距离/米", 20, new ConfigDescription("好友距离你多少米以内时自动临时常显。默认20米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 530
			}
		}));
		enemyOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("C.敌人局内显示", "启用", true, ConfigDescriptionWithOrder("在局内显示敌人名字和距离,统一使用红色。", 540));
		enemyFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("敌人局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 530));
		enemyFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "远处字体变小/%", 30, new ConfigDescription("敌人距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 525
			}
		}));
		enemyDisplayMode = ((BaseUnityPlugin)this).Config.Bind<TeammateDisplayMode>("C.敌人局内显示", "显示方式", TeammateDisplayMode.按键显示, ConfigDescriptionWithOrder("常显,或按键后显示一段时间。", 520));
		enemyUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("C.敌人局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次敌人局内信息。", new AcceptableValueRange<float>(0.1f, 5f), 510));
		enemyToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("C.敌人局内显示", "显示按键", "f", new ConfigDescription("按键显示模式下,按下后显示敌人局内信息。可以填写 f、t、y、g、f1、mouse3 这类 KeyCode 名称。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 500,
				CustomDrawer = DrawKeyBinding
			}
		}));
		enemyHoldSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "按键显示持续/秒", 5, ConfigDescriptionWithOrder<int>("按下敌人显示按键后,敌人局内信息显示持续多少秒。", new AcceptableValueRange<int>(1, 30), 490));
		enemyProximityAutoShowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("C.敌人局内显示", "启用靠近自动显示", true, ConfigDescriptionWithOrder("开启后,只要有敌人进入指定距离内,就会临时常显敌人信息;敌人离开范围后5秒恢复原显示方式。", 480));
		enemyProximityAutoShowDistance = ((BaseUnityPlugin)this).Config.Bind<int>("C.敌人局内显示", "靠近自动显示距离/米", 20, new ConfigDescription("敌人距离你多少米以内时自动临时常显。默认20米。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 470
			}
		}));
		cartSectionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "启用", true, ConfigDescriptionWithOrder("关闭后购物车局内显示全部不显示。", 530));
		cartOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "显示大购物车", true, ConfigDescriptionWithOrder("在大购物车上显示编号和距离。", 520));
		smallCartOverlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("D.购物车局内显示", "显示小购物车", true, ConfigDescriptionWithOrder("在小购物车上显示编号和距离。", 518));
		cartFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("D.购物车局内显示", "字体大小", 22, ConfigDescriptionWithOrder<int>("购物车局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", new AcceptableValueRange<int>(8, 42), 515));
		cartFarFontShrinkPercent = ((BaseUnityPlugin)this).Config.Bind<int>("D.购物车局内显示", "远处字体变小/%", 30, new ConfigDescription("购物车距离较远时,局内文字最多变小多少百分比。默认30表示最远显示为字体大小的70%。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 75), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = 513
			}
		}));
		cartLabelHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("D.购物车局内显示", "显示高度/米", 0f, ConfigDescriptionWithOrder<float>("购物车文字相对购物车模型底部的上下偏移。默认0米,显示在模型最底部。", new AcceptableValueRange<float>(-0.5f, 0.5f), 510));
		cartUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("D.购物车局内显示", "刷新间隔/秒", 0.5f, ConfigDescriptionWithOrder<float>("每隔多少秒刷新一次购物车位置和距离。数值越小越实时,数值越大越省性能。", new AcceptableValueRange<float>(0.1f, 2f), 508));
		overlayEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("E1.右下角基础设置", "启用", true, "是否在右下角显示额外信息。");
		sectionSpacing = ((BaseUnityPlugin)this).Config.Bind<bool>("E1.右下角基础设置", "不同分区空行", true, "默认开启。开启后不同信息分区之间会插入一行空白。");
		displayMode = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("E1.右下角基础设置", "显示模式", DisplayMode.文字显示, new ConfigDescription("可切换为文字显示或更贴近游戏的原生UI显示。", (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				CustomDrawer = DrawDisplayMode
			}
		}));
		fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "字体大小", 22, new ConfigDescription("显示文字的字体大小。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 36), Array.Empty<object>()));
		updateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("E1.右下角基础设置", "刷新间隔/秒", 1.5f, new ConfigDescription("每隔多少秒刷新一次显示。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
		overlayOffsetX = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "右下角X偏移/像素", 0, new ConfigDescription("右下角信息的水平偏移。正数向左移动,负数向右移动。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), Array.Empty<object>()));
		overlayOffsetY = ((BaseUnityPlugin)this).Config.Bind<int>("E1.右下角基础设置", "右下角Y偏移/像素", 0, new ConfigDescription("右下角信息的垂直偏移。正数向上移动,负数向下移动。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), Array.Empty<object>()));
		showEnemySection = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "启用", true, "关闭后右下角怪物统计分区全部不显示。");
		showBreakdown = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "显示怪物明细", true, "显示每种怪物当前数量。");
		showTotalEnemyCount = ((BaseUnityPlugin)this).Config.Bind<bool>("E2.右下角怪物统计", "显示怪物总数", true, "显示当前存活怪物总数。");
		showValueSection = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "启用", true, ConfigDescriptionWithOrder("关闭后右下角价值统计分区全部不显示。", 770));
		showExplorationProgress = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示探索进度", true, ConfigDescriptionWithOrder("单独显示探索进度。进度按地图初始总价值计算,已放到提取点或购物车的物资也算作已探索。", 760));
		showMapLostValue = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示本局损失资金", true, ConfigDescriptionWithOrder("显示本局中已摔坏或丢失造成的资金损失。", 750));
		showMapTotalValue = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示地图剩余价值", true, ConfigDescriptionWithOrder("显示当前地图剩余价值。已放到提取点的物品会被排除,购物车里和地图上未提取的物品仍会计入。", 740));
		showCurrentRunSubmittedFunds = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示本局提交资金", true, ConfigDescriptionWithOrder("显示本局已经成功带走并结算的资金。仅放进提取点但未提取成功时不会计入。", 730));
		showShopRemainingFunds = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示商店剩余资金", true, ConfigDescriptionWithOrder("显示商店剩余资金。此值只在每局开始读取一次快照,当前关卡提交物品不会让它上涨。", 720));
		showLevelInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("E3.右下角价值统计", "显示关卡信息", true, ConfigDescriptionWithOrder("显示当前关卡编号和名称,位于商店剩余资金下面。", 710));
		showTeammateInfoSection = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "启用", true, ConfigDescriptionWithOrder("关闭后右下角好友信息分区全部不显示。", 670));
		showDeadTeammates = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示死亡好友信息", true, ConfigDescriptionWithOrder("在右下角好友信息分区顶部显示死亡好友图标、名字和距离,距离越近越靠上。", 660));
		showAliveTeammates = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示存活好友信息", true, ConfigDescriptionWithOrder("在右下角好友信息分区显示每个存活好友的名字和距离,距离越近越靠上。", 650));
		showPlayerCounts = ((BaseUnityPlugin)this).Config.Bind<bool>("E4.右下角好友信息", "显示玩家数量", true, ConfigDescriptionWithOrder("在右下角好友信息分区最底部显示死亡、存活和总玩家数量。", 640));
		NormalizeKeyConfigEntries();
		ApplyValuableHaulPatch();
		WzcUiApi.IsLoaded = true;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"wzc_ui loaded.");
	}

	private void Update()
	{
		try
		{
			UpdateCore();
		}
		catch (Exception ex)
		{
			ResetRuntimeDisplayState();
			if (!hasLoggedUpdateError)
			{
				hasLoggedUpdateError = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("wzc_ui update skipped after an error: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}

	private void UpdateCore()
	{
		keyNormalizeTimer += Time.deltaTime;
		if (keyNormalizeTimer >= 0.5f)
		{
			keyNormalizeTimer = 0f;
			NormalizeKeyConfigEntries();
		}
		bool flag = IsRuntimeSessionActive();
		if (!IsModEnabled() || !flag)
		{
			if (runtimeWasActive)
			{
				runtimeWasActive = false;
				ResetLossTracking();
				WzcUiApi.ResetSnapshot();
				ResetRuntimeDisplayState();
			}
			return;
		}
		runtimeWasActive = true;
		refreshTimer += Time.deltaTime;
		UpdateTeammateOverlayState();
		UpdateEnemyOverlayState();
		UpdateCartDistanceCache();
		bool flag2 = overlayEnabled.Value && displayMode.Value == DisplayMode.原生UI显示;
		if (refreshTimer >= ClampRefreshInterval((updateInterval == null) ? 1.5f : updateInterval.Value))
		{
			refreshTimer = 0f;
			string text = BuildOverlayText();
			overlayText = (overlayEnabled.Value ? text : string.Empty);
			if (flag2)
			{
				UpdateNativeOverlay();
			}
		}
		if (flag2)
		{
			SetNativeOverlayVisible(visible: true);
		}
		else
		{
			SetNativeOverlayVisible(visible: false);
		}
	}

	private static float ClampRefreshInterval(float value)
	{
		if (float.IsNaN(value) || float.IsInfinity(value))
		{
			return 0.1f;
		}
		return Mathf.Max(0.1f, value);
	}

	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 void OnUnityLogMessageReceived(string condition, string stackTrace, LogType type)
	{
		if (!string.IsNullOrEmpty(condition))
		{
			int num = condition.IndexOf("Changed level to:", StringComparison.OrdinalIgnoreCase);
			int length = "Changed level to:".Length;
			if (num < 0)
			{
				num = condition.IndexOf("updated level to:", StringComparison.OrdinalIgnoreCase);
				length = "updated level to:".Length;
			}
			if (num >= 0)
			{
				string name = condition.Substring(num + length).Trim();
				levelTransitionLogIndicatesRun = LooksLikePlayableSessionName(name);
			}
		}
	}

	private void ApplyValuableHaulPatch()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		try
		{
			valuableHaulHarmony = new Harmony("local.repo.enemycountoverlay.valuablehaul");
			PatchValuableHaulMethod("AddToDollarHaulList", "ValuableDollarHaulAddPostfix");
			PatchValuableHaulMethod("AddToDollarHaulListRPC", "ValuableDollarHaulAddPostfix");
			PatchValuableHaulMethod("RemoveFromDollarHaulList", "ValuableDollarHaulRemovePostfix");
			PatchValuableHaulMethod("RemoveFromDollarHaulListRPC", "ValuableDollarHaulRemovePostfix");
			PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetLogic", "ValuableDollarValueSetLogicPostfix");
			PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetRPC", "ValuableDollarValueSetRpcPostfix");
			PatchValuableTrackingMethod(typeof(PhysGrabObjectImpactDetector), "BreakRPC", "ValuableBreakPostfix");
			PatchValuableTrackingMethod(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC", "ValuableDestroyPhysGrabObjectPostfix");
			PatchValuableTrackingMethod(typeof(RoundDirector), "ExtractionCompleted", "RoundDirectorExtractionCompletedPostfix");
			PatchValuableTrackingMethod(typeof(LevelGenerator), "StartRoomGeneration", "LevelGeneratorStartRoomGenerationPrefix", prefix: true);
			PatchValuableTrackingMethod(typeof(LevelGenerator), "GenerateDone", "LevelGeneratorGenerateDonePostfix");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Valuable haul tracking patched.");
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to patch valuable haul tracking: {arg}");
		}
	}

	private void PatchValuableHaulMethod(string originalName, string postfixName)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		MethodInfo methodInfo = AccessTools.Method(typeof(ValuableObject), originalName, (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), postfixName, (Type[])null, (Type[])null);
		if (methodInfo == null || methodInfo2 == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable haul method patch target: " + originalName));
		}
		else
		{
			valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}

	private void PatchValuableTrackingMethod(Type originalType, string originalName, string patchName, bool prefix = false)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		MethodInfo methodInfo = AccessTools.Method(originalType, originalName, (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), patchName, (Type[])null, (Type[])null);
		if (methodInfo == null || methodInfo2 == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable tracking patch target: " + originalType?.Name + "." + originalName));
			return;
		}
		HarmonyMethod val = new HarmonyMethod(methodInfo2);
		if (prefix)
		{
			valuableHaulHarmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		else
		{
			valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}

	private static void ValuableDollarHaulAddPostfix(ValuableObject __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			valuablesCurrentlyInDollarHaul.Add(GetValuableKey(__instance));
		}
	}

	private static void ValuableDollarHaulRemovePostfix(ValuableObject __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			valuablesCurrentlyInDollarHaul.Remove(GetValuableKey(__instance));
		}
	}

	private static void ValuableDollarValueSetLogicPostfix(ValuableObject __instance)
	{
		if (IsRunLevelSafe())
		{
			WzcMapValueService.RegisterValueSet(__instance, GetCurrentMapValueLevelNumber());
		}
	}

	private static void ValuableDollarValueSetRpcPostfix(ValuableObject __instance, float value)
	{
		if (IsRunLevelSafe())
		{
			WzcMapValueService.RegisterValueSet(__instance, value, GetCurrentMapValueLevelNumber());
		}
	}

	private static void ValuableBreakPostfix(float valueLost, PhysGrabObjectImpactDetector __instance, bool _loseValue)
	{
		if (_loseValue && IsRunLevelSafe())
		{
			WzcMapValueService.RegisterBreak(((Object)(object)__instance == (Object)null) ? null : ((Component)__instance).GetComponent<ValuableObject>(), valueLost, GetCurrentMapValueLevelNumber());
		}
	}

	private static void ValuableDestroyPhysGrabObjectPostfix(PhysGrabObject __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && IsRunLevelSafe())
		{
			WzcMapValueService.RegisterDestroy(((Component)__instance).GetComponent<ValuableObject>(), GetCurrentMapValueLevelNumber());
		}
	}

	private static void RoundDirectorExtractionCompletedPostfix()
	{
		if (IsRunLevelSafe())
		{
			WzcMapValueService.SyncFromLiveValuables(Object.FindObjectsOfType<ValuableObject>(), GetCurrentMapValueLevelNumber());
		}
	}

	private static void LevelGeneratorStartRoomGenerationPrefix()
	{
		if ((Object)(object)Instance != (Object)null)
		{
			Instance.ResetLossTracking();
			return;
		}
		valuablesCurrentlyInDollarHaul.Clear();
		WzcMapValueService.Reset();
	}

	private static void LevelGeneratorGenerateDonePostfix()
	{
		WzcMapValueService.SyncFromLiveValuables(Object.FindObjectsOfType<ValuableObject>(), GetCurrentMapValueLevelNumber());
	}

	private string BuildOverlayText()
	{
		Enemy[] enemyObjectsCachedForFrame = GetEnemyObjectsCachedForFrame();
		activeEnemyBuffer.Clear();
		if (enemyObjectsCachedForFrame != null)
		{
			Enemy[] array = enemyObjectsCachedForFrame;
			foreach (Enemy val in array)
			{
				if (IsEnemyCountable(val))
				{
					activeEnemyBuffer.Add(val);
				}
			}
		}
		List<WzcUiPlayerDistance> teammateInfos = CreateTeammateDistanceInfos();
		enemyBreakdownBuffer.Clear();
		foreach (Enemy item in activeEnemyBuffer)
		{
			string cachedEnemyDisplayName = GetCachedEnemyDisplayName(item);
			if (!string.IsNullOrWhiteSpace(cachedEnemyDisplayName))
			{
				enemyBreakdownBuffer.TryGetValue(cachedEnemyDisplayName, out var value);
				enemyBreakdownBuffer[cachedEnemyDisplayName] = value + 1;
			}
		}
		orderedEnemyBreakdownBuffer.Clear();
		foreach (KeyValuePair<string, int> item2 in enemyBreakdownBuffer)
		{
			orderedEnemyBreakdownBuffer.Add(item2);
		}
		orderedEnemyBreakdownBuffer.Sort(CompareEnemyBreakdownEntry);
		DisplayLanguage currentLanguage = CurrentLanguage;
		bool flag = showEnemySection == null || showEnemySection.Value;
		bool flag2 = showValueSection == null || showValueSection.Value;
		bool flag3 = showTeammateInfoSection == null || showTeammateInfoSection.Value;
		string text = string.Empty;
		if (flag && showBreakdown.Value && orderedEnemyBreakdownBuffer.Count > 0)
		{
			enemyBreakdownLineBuffer.Clear();
			foreach (KeyValuePair<string, int> item3 in orderedEnemyBreakdownBuffer)
			{
				enemyBreakdownLineBuffer.Add($"{item3.Key}: {item3.Value}");
			}
			text = string.Join("\n", enemyBreakdownLineBuffer);
		}
		string text2 = ((flag && showTotalEnemyCount.Value) ? $"{HudText.EnemyTotal(currentLanguage)}: {activeEnemyBuffer.Count}" : string.Empty);
		string text3 = string.Empty;
		string text4 = string.Empty;
		string text5 = string.Empty;
		string empty = string.Empty;
		float mapValue = 0f;
		float initialMapValue = 0f;
		ValuableObject[] valuables = null;
		int num;
		if (flag2)
		{
			if (!showMapLostValue.Value && !showExplorationProgress.Value)
			{
				num = (showMapTotalValue.Value ? 1 : 0);
				if (num == 0)
				{
					goto IL_02bc;
				}
			}
			else
			{
				num = 1;
			}
			valuables = Object.FindObjectsOfType<ValuableObject>();
		}
		else
		{
			num = 0;
		}
		goto IL_02bc;
		IL_02bc:
		int levelNumber = SemiFunc.RunGetLevelsCompleted() + 1;
		bool flag4 = num != 0 && WzcMapValueService.TryGetValues(valuables, levelNumber, out mapValue, out initialMapValue);
		float num2 = 0f;
		int num3 = 0;
		float unexploredValue = 0f;
		bool hasLiveValuableData = false;
		if (flag2 && flag4)
		{
			bool value2 = showMapLostValue.Value;
			bool value3 = showExplorationProgress.Value;
			bool value4 = showMapTotalValue.Value;
			float num4 = mapValue;
			if (value2 || value3 || value4)
			{
				FillCurrentDollarHaulObjects(currentDollarHaulObjectsBuffer);
				FillReferenceSet(currentDollarHaulObjectsBuffer, haulReferenceSetBuffer);
				if (value4)
				{
					num4 = CalculateRemainingMapValue(mapValue, valuables, haulReferenceSetBuffer);
				}
				if (value2)
				{
					num2 = UpdateAndGetLostMapValue(mapValue, valuables, haulReferenceSetBuffer);
				}
				if (value3)
				{
					FillCurrentCartObjects(currentCartObjectsBuffer);
					FillReferenceSet(currentCartObjectsBuffer, cartReferenceSetBuffer);
					num3 = CalculateExplorationProgress(mapValue, initialMapValue, valuables, haulReferenceSetBuffer, cartReferenceSetBuffer, out unexploredValue, out hasLiveValuableData);
				}
			}
			text3 = (showMapLostValue.Value ? (HudText.MapLostValue(currentLanguage) + ": " + FormatMoney(num2)) : string.Empty);
			text4 = (showExplorationProgress.Value ? BuildExplorationProgressLine(currentLanguage, num3) : string.Empty);
			mapValue = num4;
			text5 = (showMapTotalValue.Value ? BuildMapValueLine(currentLanguage, mapValue) : string.Empty);
		}
		else if (flag2 && (showMapLostValue.Value || showExplorationProgress.Value || showMapTotalValue.Value))
		{
			text4 = (showExplorationProgress.Value ? BuildExplorationProgressLine(currentLanguage, 0) : string.Empty);
			text3 = (showMapLostValue.Value ? (HudText.MapLostValue(currentLanguage) + ": " + FormatMoney(0f)) : string.Empty);
			text5 = (showMapTotalValue.Value ? BuildMapValueLine(currentLanguage, 0f) : string.Empty);
			empty = string.Empty;
		}
		float shopRemainingFunds = (flag2 ? GetShopRemainingFundsSnapshot() : 0f);
		float currentLevelFunds = (flag2 ? GetCurrentLevelSubmittedValue() : 0f);
		evacuatedFundsLineBuffer.Clear();
		if (flag2)
		{
			BuildEvacuatedFundsLines(currentLanguage, shopRemainingFunds, currentLevelFunds, evacuatedFundsLineBuffer);
		}
		string text6 = ((flag2 && showLevelInfo.Value) ? BuildLevelLine() : string.Empty);
		monsterSectionPartsBuffer.Clear();
		valueSectionPartsBuffer.Clear();
		teammateSectionPartsBuffer.Clear();
		if (flag3)
		{
			BuildRightBottomTeammateInfoParts(teammateInfos, teammateSectionPartsBuffer);
		}
		if (!string.IsNullOrWhiteSpace(text))
		{
			monsterSectionPartsBuffer.Add(text);
		}
		if (!string.IsNullOrWhiteSpace(text2))
		{
			monsterSectionPartsBuffer.Add(text2);
		}
		if (!string.IsNullOrWhiteSpace(text4))
		{
			valueSectionPartsBuffer.Add(text4);
		}
		if (!string.IsNullOrWhiteSpace(text5))
		{
			valueSectionPartsBuffer.Add(text5);
		}
		if (!string.IsNullOrWhiteSpace(empty))
		{
			valueSectionPartsBuffer.Add(empty);
		}
		if (!string.IsNullOrWhiteSpace(text3))
		{
			valueSectionPartsBuffer.Add(text3);
		}
		if (evacuatedFundsLineBuffer.Count > 0)
		{
			valueSectionPartsBuffer.AddRange(evacuatedFundsLineBuffer);
		}
		if (!string.IsNullOrWhiteSpace(text6))
		{
			valueSectionPartsBuffer.Add(text6);
		}
		overlayPartsBuffer.Clear();
		AppendSection(overlayPartsBuffer, monsterSectionPartsBuffer);
		AppendSection(overlayPartsBuffer, valueSectionPartsBuffer);
		AppendSection(overlayPartsBuffer, teammateSectionPartsBuffer);
		string text7 = string.Join("\n", overlayPartsBuffer);
		UpdateApiSnapshot(currentLanguage, text7, activeEnemyBuffer.Count, enemyBreakdownBuffer, flag4, mapValue, initialMapValue, unexploredValue, hasLiveValuableData, num3, num2, currentLevelFunds, shopRemainingFunds, teammateInfos, activeEnemyBuffer);
		return text7;
	}

	private static int CompareEnemyBreakdownEntry(KeyValuePair<string, int> left, KeyValuePair<string, int> right)
	{
		int num = right.Value.CompareTo(left.Value);
		if (num == 0)
		{
			return string.Compare(left.Key, right.Key, StringComparison.Ordinal);
		}
		return num;
	}

	private void UpdateApiSnapshot(DisplayLanguage language, string overlayTextValue, int enemyTotalCount, Dictionary<string, int> enemyBreakdown, bool mapValueAvailable, float mapValue, float initialMapValue, float unexploredMapValue, bool hasLiveValuableData, int explorationProgressPercent, float lostValue, float currentLevelFunds, float shopRemainingFunds, List<WzcUiPlayerDistance> teammateInfos, List<Enemy> activeEnemies)
	{
		GetLevelInfo(language, out var levelNumber, out var levelName);
		GetPlayerCountsFromTeammateInfos(teammateInfos, out var totalPlayers, out var alivePlayers, out var deadPlayers);
		int capacity = teammateInfos?.Count ?? 0;
		List<WzcUiPlayerDistance> list = new List<WzcUiPlayerDistance>(capacity);
		List<WzcUiPlayerDistance> list2 = new List<WzcUiPlayerDistance>(capacity);
		if (teammateInfos != null)
		{
			foreach (WzcUiPlayerDistance teammateInfo in teammateInfos)
			{
				if (teammateInfo != null)
				{
					if (teammateInfo.IsDead)
					{
						list2.Add(teammateInfo);
					}
					else
					{
						list.Add(teammateInfo);
					}
				}
			}
		}
		WzcUiApi.UpdateSnapshot(new WzcUiSnapshot
		{
			IsInRun = true,
			Language = language.ToString(),
			DisplayMode = ((displayMode != null) ? displayMode.Value : DisplayMode.文字显示).ToString(),
			OverlayText = (overlayTextValue ?? string.Empty),
			EnemyTotalCount = enemyTotalCount,
			EnemyBreakdown = ((enemyBreakdown == null) ? new Dictionary<string, int>() : new Dictionary<string, int>(enemyBreakdown)),
			MapValueAvailable = mapValueAvailable,
			MapValue = mapValue,
			InitialMapValue = initialMapValue,
			UnexploredMapValue = unexploredMapValue,
			HasLiveValuableData = hasLiveValuableData,
			ExplorationProgressPercent = explorationProgressPercent,
			LostMapValue = lostValue,
			CurrentRunEvacuatedFunds = currentLevelFunds,
			CurrentRunSubmittedFunds = currentLevelFunds,
			WarehouseFunds = shopRemainingFunds,
			ShopRemainingFunds = shopRemainingFunds,
			LevelNumber = levelNumber,
			LevelName = (levelName ?? string.Empty),
			TotalPlayerCount = totalPlayers,
			AlivePlayerCount = alivePlayers,
			DeadPlayerCount = deadPlayers,
			AliveTeammates = list,
			DeadTeammates = list2,
			Enemies = CreateEnemyDistanceInfos(activeEnemies),
			Carts = new List<WzcUiCartDistance>(cartDistanceCache),
			Settings = CreateApiSettings(),
			UpdatedFrame = Time.frameCount,
			UpdatedAtUtc = DateTime.UtcNow
		});
	}

	private void GetPlayerCountsFromTeammateInfos(List<WzcUiPlayerDistance> teammateInfos, out int totalPlayers, out int alivePlayers, out int deadPlayers)
	{
		List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
		PlayerAvatar localPlayer = GetLocalPlayer(playerObjectsCachedForFrame);
		if (playerObjectsCachedForFrame == null || (Object)(object)localPlayer == (Object)null || teammateInfos == null)
		{
			GetPlayerCounts(out totalPlayers, out alivePlayers, out deadPlayers);
			return;
		}
		totalPlayers = playerObjectsCachedForFrame.Count;
		deadPlayers = 0;
		foreach (WzcUiPlayerDistance teammateInfo in teammateInfos)
		{
			if (teammateInfo != null && teammateInfo.IsDead)
			{
				deadPlayers++;
			}
		}
		alivePlayers = Math.Max(0, totalPlayers - deadPlayers);
	}

	private WzcUiDisplaySettings CreateApiSettings()
	{
		return new WzcUiDisplaySettings
		{
			ModEnabled = IsModEnabled(),
			OverlayEnabled = (overlayEnabled != null && overlayEnabled.Value),
			SectionSpacing = (sectionSpacing != null && sectionSpacing.Value),
			Language = CurrentLanguage.ToString(),
			EnemyNicknameNamesEnabled = UseEnemyNicknameNames,
			DisplayMode = ((displayMode != null) ? displayMode.Value : DisplayMode.文字显示).ToString(),
			FontSize = ((fontSize == null) ? 22 : fontSize.Value),
			UpdateIntervalSeconds = ClampRefreshInterval((updateInterval == null) ? 0.5f : updateInterval.Value),
			OverlayOffsetX = ((overlayOffsetX != null) ? overlayOffsetX.Value : 0),
			OverlayOffsetY = ((overlayOffsetY != null) ? overlayOffsetY.Value : 0),
			ShowEnemySection = (showEnemySection == null || showEnemySection.Value),
			ShowEnemyBreakdown = (showBreakdown != null && showBreakdown.Value),
			ShowEnemyTotal = (showTotalEnemyCount != null && showTotalEnemyCount.Value),
			ShowValueSection = (showValueSection == null || showValueSection.Value),
			ShowMapLostValue = (showMapLostValue != null && showMapLostValue.Value),
			ShowExplorationProgress = (showExplorationProgress != null && showExplorationProgress.Value),
			ShowMapTotalValue = (showMapTotalValue != null && showMapTotalValue.Value),
			ShowCurrentRunSubmittedFunds = (showCurrentRunSubmittedFunds != null && showCurrentRunSubmittedFunds.Value),
			ShowShopRemainingFunds = (showShopRemainingFunds != null && showShopRemainingFunds.Value),
			ShowEvacuatedFunds = ((showCurrentRunSubmittedFunds != null && showCurrentRunSubmittedFunds.Value) || (showShopRemainingFunds != null && showShopRemainingFunds.Value)),
			ShowLevelInfo = (showLevelInfo != null && showLevelInfo.Value),
			ShowTeammateInfoSection = (showTeammateInfoSection == null || showTeammateInfoSection.Value),
			ShowDeadTeammates = (showDeadTeammates != null && showDeadTeammates.Value),
			ShowAliveTeammates = (showAliveTeammates != null && showAliveTeammates.Value),
			ShowPlayerCounts = (showPlayerCounts != null && showPlayerCounts.Value),
			TeammateOverlayEnabled = (teammateOverlayEnabled != null && teammateOverlayEnabled.Value),
			TeammateAliveOverlayEnabled = (teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value),
			TeammateDeadOverlayEnabled = (teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value),
			TeammateFontSize = ((teammateFontSize == null) ? 22 : teammateFontSize.Value),
			TeammateLabelHeightOffsetMeters = ((teammateLabelHeightOffset == null) ? 0.05f : teammateLabelHeightOffset.Value),
			TeammateFarFontShrinkPercent = ((teammateFarFontShrinkPercent == null) ? 30 : teammateFarFontShrinkPercent.Value),
			TeammateUpdateIntervalSeconds = ClampRefreshInterval((teammateUpdateInterval == null) ? 0.2f : teammateUpdateInterval.Value),
			TeammateDisplayMode = ((teammateDisplayMode != null) ? teammateDisplayMode.Value : TeammateDisplayMode.常显).ToString(),
			TeammateToggleKey = ((teammateToggleKey == null) ? "f" : SanitizeConfiguredKeyName(teammateToggleKey.Value)),
			TeammateHoldSeconds = ((teammateHoldSeconds == null) ? 5 : teammateHoldSeconds.Value),
			TeammateProximityAutoShowEnabled = (teammateProximityAutoShowEnabled != null && teammateProximityAutoShowEnabled.Value),
			TeammateProximityAutoShowDistanceMeters = ((teammateProximityAutoShowDistance == null) ? 20 : teammateProximityAutoShowDistance.Value),
			EnemyOverlayEnabled = (enemyOverlayEnabled != null && enemyOverlayEnabled.Value),
			EnemyFontSize = ((enemyFontSize == null) ? 22 : enemyFontSize.Value),
			EnemyFarFontShrinkPercent = ((enemyFarFontShrinkPercent == null) ? 30 : enemyFarFontShrinkPercent.Value),
			EnemyUpdateIntervalSeconds = ClampRefreshInterval((enemyUpdateInterval == null) ? 0.2f : enemyUpdateInterval.Value),
			EnemyDisplayMode = ((enemyDisplayMode == null) ? TeammateDisplayMode.按键显示 : enemyDisplayMode.Value).ToString(),
			EnemyToggleKey = ((enemyToggleKey == null) ? "f" : SanitizeConfiguredKeyName(enemyToggleKey.Value)),
			EnemyHoldSeconds = ((enemyHoldSeconds == null) ? 5 : enemyHoldSeconds.Value),
			EnemyProximityAutoShowEnabled = (enemyProximityAutoShowEnabled != null && enemyProximityAutoShowEnabled.Value),
			EnemyProximityAutoShowDistanceMeters = ((enemyProximityAutoShowDistance == null) ? 20 : enemyProximityAutoShowDistance.Value),
			CartSectionEnabled = (cartSectionEnabled == null || cartSectionEnabled.Value),
			CartOverlayEnabled = (cartOverlayEnabled != null && cartOverlayEnabled.Value),
			SmallCartOverlayEnabled = (smallCartOverlayEnabled != null && smallCartOverlayEnabled.Value),
			CartFontSize = ((cartFontSize == null) ? 22 : cartFontSize.Value),
			CartFarFontShrinkPercent = ((cartFarFontShrinkPercent == null) ? 30 : cartFarFontShrinkPercent.Value),
			CartLabelHeightOffsetMeters = ((cartLabelHeightOffset == null) ? 0f : cartLabelHeightOffset.Value),
			CartUpdateIntervalSeconds = ClampRefreshInterval((cartUpdateInterval == null) ? 0.5f : cartUpdateInterval.Value)
		};
	}

	private void BuildRightBottomTeammateInfoParts(List<WzcUiPlayerDistance> teammateInfos, List<string> parts)
	{
		string text = (showPlayerCounts.Value ? BuildPlayerCountLine() : string.Empty);
		if (showDeadTeammates.Value)
		{
			AppendTeammateDistanceLines(teammateInfos, deadOnly: true, parts);
		}
		if (showAliveTeammates.Value)
		{
			AppendTeammateDistanceLines(teammateInfos, deadOnly: false, parts);
		}
		if (!string.IsNullOrWhiteSpace(text))
		{
			parts.Add(text);
		}
	}

	private void UpdateTeammateOverlayState()
	{
		if (!teammateOverlayEnabled.Value)
		{
			teammateVisibleTimer = 0f;
			teammateProximityVisibleTimer = 0f;
			teammateProximityRefreshTimer = 0f;
			return;
		}
		if (teammateDisplayMode.Value == TeammateDisplayMode.按键显示 && IsConfiguredKeyDown(teammateToggleKey.Value))
		{
			teammateVisibleTimer = Mathf.Max(0.1f, (float)teammateHoldSeconds.Value);
		}
		if (teammateDisplayMode.Value == TeammateDisplayMode.按键显示 && teammateVisibleTimer > 0f)
		{
			teammateVisibleTimer -= Time.deltaTime;
		}
		UpdateTeammateProximityAutoShowState();
	}

	private void UpdateEnemyOverlayState()
	{
		if (!enemyOverlayEnabled.Value)
		{
			enemyLabels.Clear();
			ClearEnemyProximityTracking();
			enemyVisibleTimer = 0f;
			enemyProximityVisibleTimer = 0f;
			return;
		}
		if (enemyDisplayMode.Value == TeammateDisplayMode.按键显示 && IsConfiguredKeyDown(enemyToggleKey.Value))
		{
			enemyVisibleTimer = Mathf.Max(0.1f, (float)enemyHoldSeconds.Value);
		}
		if (enemyDisplayMode.Value == TeammateDisplayMode.按键显示 && enemyVisibleTimer > 0f)
		{
			enemyVisibleTimer -= Time.deltaTime;
		}
		bool flag = UpdateEnemyProximityAutoShowState();
		UpdateEnemyProximityPopTimers();
		if (!(enemyDisplayMode.Value == TeammateDisplayMode.常显 || enemyVisibleTimer > 0f || flag))
		{
			enemyLabels.Clear();
			return;
		}
		enemyRefreshTimer += Time.deltaTime;
		if (enemyRefreshTimer >= ClampRefreshInterval((enemyUpdateInterval == null) ? 0.5f : enemyUpdateInterval.Value))
		{
			enemyRefreshTimer = 0f;
			RefreshEnemyLabels();
		}
	}

	private void UpdateTeammateProximityAutoShowState()
	{
		if (teammateProximityAutoShowEnabled == null || !teammateProximityAutoShowEnabled.Value)
		{
			teammateProximityVisibleTimer = 0f;
			teammateProximityRefreshTimer = 0f;
			return;
		}
		bool num = teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value;
		bool flag = teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value;
		if (!num && !flag)
		{
			teammateProximityVisibleTimer = 0f;
			teammateProximityRefreshTimer = 0f;
			return;
		}
		teammateProximityRefreshTimer += Time.deltaTime;
		float num2 = ClampRefreshInterval((teammateUpdateInterval == null) ? 0.5f : teammateUpdateInterval.Value);
		if (teammateProximityRefreshTimer >= num2)
		{
			teammateProximityRefreshTimer = 0f;
			if (HasTeammateWithinDistance(teammateProximityAutoShowDistance.Value))
			{
				teammateProximityVisibleTimer = 5f;
			}
			else if (teammateProximityVisibleTimer > 0f)
			{
				teammateProximityVisibleTimer -= num2;
			}
		}
		else if (teammateProximityVisibleTimer > 0f)
		{
			teammateProximityVisibleTimer -= Time.deltaTime;
		}
	}

	private bool UpdateEnemyProximityAutoShowState()
	{
		if (enemyProximityAutoShowEnabled == null || !enemyProximityAutoShowEnabled.Value)
		{
			enemyProximityVisibleTimer = 0f;
			ClearEnemyProximityTracking();
			return false;
		}
		enemyProximityRefreshTimer += Time.deltaTime;
		float num = ClampRefreshInterval((enemyUpdateInterval == null) ? 0.5f : enemyUpdateInterval.Value);
		bool flag = false;
		bool flag2 = enemiesInsideProximityRange.Count > 0;
		if (enemyProximityRefreshTimer >= num)
		{
			enemyProximityRefreshTimer = 0f;
			flag = true;
			flag2 = UpdateEnemiesWithinProximityDistance(enemyProximityAutoShowDistance.Value);
		}
		if (flag2)
		{
			enemyProximityVisibleTimer = 5f;
		}
		else if (enemyProximityVisibleTimer > 0f && flag)
		{
			enemyProximityVisibleTimer -= num;
		}
		return enemyProximityVisibleTimer > 0f;
	}

	private bool HasTeammateWithinDistance(float distance)
	{
		//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_00a9: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		if (distance <= 0f)
		{
			return false;
		}
		List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
		PlayerAvatar localPlayer = GetLocalPlayer(playerObjectsCachedForFrame);
		if (playerObjectsCachedForFrame == null || (Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		Vector3 playerDistanceOrigin = GetPlayerDistanceOrigin(localPlayer, IsPlayerAlive(localPlayer));
		float num = distance * distance;
		bool flag = teammateAliveOverlayEnabled == null || teammateAliveOverlayEnabled.Value;
		bool flag2 = teammateDeadOverlayEnabled == null || teammateDeadOverlayEnabled.Value;
		foreach (PlayerAvatar item in playerObjectsCachedForFrame)
		{
			if ((Object)(object)item == (Object)null || item == localPlayer)
			{
				continue;
			}
			bool flag3 = IsPlayerAlive(item);
			if ((!flag3 || flag) && (flag3 || flag2))
			{
				Vector3 val = GetPlayerReferencePosition(item, !flag3) - playerDistanceOrigin;
				if (((Vector3)(ref val)).sqrMagnitude <= num)
				{
					return true;
				}
			}
		}
		return false;
	}

	private bool UpdateEnemiesWithinProximityDistance(float distance)
	{
		//IL_006e: 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_0074: 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)
		if (distance <= 0f)
		{
			enemiesInsideProximityRange.Clear();
			return false;
		}
		if (!TryGetEnemyDistanceOrigin(out var origin))
		{
			enemiesInsideProximityRange.Clear();
			return false;
		}
		Enemy[] enemyObjectsCachedForFrame = GetEnemyObjectsCachedForFrame();
		if (enemyObjectsCachedForFrame == null || enemyObjectsCachedForFrame.Length == 0)
		{
			enemiesInsideProximityRange.Clear();
			return false;
		}
		float num = distance * distance;
		currentEnemiesInsideProximityRange.Clear();
		Enemy[] array = enemyObjectsCachedForFrame;
		foreach (Enemy enemy in array)
		{
			if (!IsEnemyCountable(enemy))
			{
				continue;
			}
			Vector3 val = GetEnemyReferencePosition(enemy) - origin;
			if (((Vector3)(ref val)).sqrMagnitude <= num)
			{
				int enemyKey = GetEnemyKey(enemy);
				currentEnemiesInsideProximityRange.Add(enemyKey);
				if (!enemiesInsideProximityRange.Contains(enemyKey))
				{
					enemyProximityPopTimers[enemyKey] = 1.2f;
				}
			}
		}
		enemiesInsideProximityRange.Clear();
		foreach (int item in currentEnemiesInsideProximityRange)
		{
			enemiesInsideProximityRange.Add(item);
		}
		bool result = currentEnemiesInsideProximityRange.Count > 0;
		currentEnemiesInsideProximityRange.Clear();
		return result;
	}

	private void UpdateEnemyProximityPopTimers()
	{
		if (enemyProximityPopTimers.Count == 0)
		{
			return;
		}
		reusableIntKeys.Clear();
		foreach (int key in enemyProximityPopTimers.Keys)
		{
			reusableIntKeys.Add(key);
		}
		foreach (int reusableIntKey in reusableIntKeys)
		{
			float num = enemyProximityPopTimers[reusableIntKey] - Time.deltaTime;
			if (num <= 0f)
			{
				enemyProximityPopTimers.Remove(reusableIntKey);
			}
			else
			{
				enemyProximityPopTimers[reusableIntKey] = num;
			}
		}
	}

	private void ClearEnemyProximityTracking()
	{
		enemyProximityRefreshTimer = 0f;
		enemyProximityPopTimers.Clear();
		enemiesInsideProximityRange.Clear();
		currentEnemiesInsideProximityRange.Clear();
	}

	private void UpdateCartDistanceCache()
	{
		if (!ShouldDrawCartWorldLabels())
		{
			ClearCartDistanceCache();
			return;
		}
		cartRefreshTimer += Time.deltaTime;
		float num = ClampRefreshInterval((cartUpdateInterval == null) ? 0.25f : cartUpdateInterval.Value);
		if (!cartDistanceCacheValid || !(cartRefreshTimer < num))
		{
			cartRefreshTimer = 0f;
			cartDistanceCache.Clear();
			FillCartDistanceInfos(cartDistanceCache);
			cartDistanceCacheValid = true;
		}
	}

	private void ClearCartDistanceCache()
	{
		cartRefreshTimer = 0f;
		cartDistanceCacheValid = false;
		cartDistanceCache.Clear();
	}

	private Enemy[] GetEnemyObjectsCachedForFrame()
	{
		int frameCount = Time.frameCount;
		if (enemyObjectsFrameCacheFrame == frameCount && enemyObjectsFrameCache != null)
		{
			return enemyObjectsFrameCache;
		}
		enemyObjectsFrameCacheFrame = frameCount;
		enemyObjectsFrameCache = Resources.FindObjectsOfTypeAll<Enemy>() ?? Array.Empty<Enemy>();
		return enemyObjectsFrameCache;
	}

	private PhysGrabCart[] GetCartObjectsCachedForFrame()
	{
		int frameCount = Time.frameCount;
		if (cartObjectsFrameCacheFrame == frameCount && cartObjectsFrameCache != null)
		{
			return cartObjectsFrameCache;
		}
		cartObjectsFrameCacheFrame = frameCount;
		cartObjectsFrameCache = Object.FindObjectsOfType<PhysGrabCart>(true) ?? Array.Empty<PhysGrabCart>();
		return cartObjectsFrameCache;
	}

	private PhysGrabber[] GetGrabberObjectsCachedForFrame()
	{
		int frameCount = Time.frameCount;
		if (grabberObjectsFrameCacheFrame == frameCount && grabberObjectsFrameCache != null)
		{
			return grabberObjectsFrameCache;
		}
		grabberObjectsFrameCacheFrame = frameCount;
		grabberObjectsFrameCache = Object.FindObjectsOfType<PhysGrabber>(true) ?? Array.Empty<PhysGrabber>();
		return grabberObjectsFrameCache;
	}

	private List<PlayerAvatar> GetPlayerObjectsCachedForFrame()
	{
		int frameCount = Time.frameCount;
		if (playerObjectsFrameCacheFrame == frameCount)
		{
			return playerObjectsFrameCache;
		}
		playerObjectsFrameCacheFrame = frameCount;
		try
		{
			playerObjectsFrameCache = SemiFunc.PlayerGetAll();
		}
		catch
		{
			playerObjectsFrameCache = null;
		}
		return playerObjectsFrameCache;
	}

	private static int GetEnemyKey(Enemy enemy)
	{
		if (!((Object)(object)enemy == (Object)null))
		{
			return ((Object)enemy).GetInstanceID();
		}
		return 0;
	}

	private bool TryGetEnemyDistanceOrigin(out Vector3 origin)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0046: 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)
		try
		{
			PlayerAvatar localPlayer = GetLocalPlayer(GetPlayerObjectsCachedForFrame());
			if ((Object)(object)localPlayer != (Object)null)
			{
				origin = GetPlayerDistanceOrigin(localPlayer, IsPlayerAlive(localPlayer));
				return true;
			}
		}
		catch
		{
		}
		Camera worldLabelCamera = GetWorldLabelCamera();
		if ((Object)(object)worldLabelCamera != (Object)null)
		{
			origin = ((Component)worldLabelCamera).transform.position;
			return true;
		}
		origin = Vector3.zero;
		return false;
	}

	private void AppendSection(List<string> parts, List<string> sectionItems)
	{
		if (sectionItems != null && sectionItems.Count != 0)
		{
			if (parts.Count > 0 && sectionSpacing.Value)
			{
				parts.Add(string.Empty);
			}
			parts.AddRange(sectionItems);
		}
	}

	private static string ColorOverlayLine(string text, string colorHex)
	{
		if (string.IsNullOrWhiteSpace(text))
		{
			return text;
		}
		string text2 = (string.IsNullOrWhiteSpace(colorHex) ? "ffffff" : colorHex.TrimStart(new char[1] { '#' }));
		return "<color=#" + text2 + ">" + text + "</color>";
	}

	private static int GetDistanceScaledFontSize(int maxFontSize, float shrinkPercent, float distance, float fullShrinkDistance, int hardMaxFontSize)
	{
		int num = Mathf.Clamp(maxFontSize, 8, hardMaxFontSize);
		float num2 = Mathf.Clamp(shrinkPercent, 0f, 75f) / 100f;
		float num3 = (float)num * (1f - num2);
		float num4 = Mathf.Max(1f, fullShrinkDistance);
		float num5 = Mathf.Clamp01(distance / num4);
		return Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp((float)num, num3, num5)), 8, hardMaxFontSize);
	}

	private static Vector2 CalcLabelSize(GUIStyle style, string text)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		ReusableGuiContent.text = text ?? string.Empty;
		return style.CalcSize(ReusableGuiContent);
	}

	private static float CalcLabelHeight(GUIStyle style, string text, float width)
	{
		ReusableGuiContent.text = text ?? string.Empty;
		return style.CalcHeight(ReusableGuiContent, width);
	}

	private GUIStyle GetCenteredLabelStyle(int fontSize, bool shadow)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<int, GUIStyle> dictionary = (shadow ? centeredShadowLabelStyleCache : centeredRichLabelStyleCache);
		int key = Mathf.Clamp(fontSize, 8, 60);
		if (dictionary.TryGetValue(key, out var value))
		{
			return value;
		}
		value = new GUIStyle(GUI.skin.label)
		{
			fontSize = key,
			fontStyle = (FontStyle)1,
			alignment = (TextAnchor)4,
			wordWrap = false,
			richText = !shadow
		};
		value.normal.textColor = (Color)(shadow ? new Color(0f, 0f, 0f, 0.85f) : Color.white);
		dictionary[key] = value;
		return value;
	}

	private GUIStyle GetOverlayLabelStyle(int fontSize, bool shadow)
	{
		//IL_0034: 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_0040: 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_004e: 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_0060: Expected O, but got Unknown
		//IL_0084: 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)
		Dictionary<int, GUIStyle> dictionary = (shadow ? overlayShadowStyleCache : overlayRichStyleCache);
		int key = Mathf.Clamp(fontSize, 10, 28);
		if (dictionary.TryGetValue(key, out var value))
		{
			return value;
		}
		value = new GUIStyle(GUI.skin.label)
		{
			fontSize = key,
			fontStyle = (FontStyle)1,
			alignment = (TextAnchor)8,
			wordWrap = false,
			richText = !shadow
		};
		value.normal.textColor = (Color)(shadow ? new Color(0f, 0f, 0f, 0.85f) : Color.white);
		dictionary[key] = value;
		return value;
	}

	private void UpdateNativeOverlay()
	{
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		if (displayMode.Value != DisplayMode.原生UI显示 || string.IsNullOrWhiteSpace(overlayText))
		{
			return;
		}
		EnsureNativeOverlay();
		if (!((Object)(object)overlayLabel == (Object)null) && !((Object)(object)overlayRect == (Object)null))
		{
			int num = Mathf.Clamp(fontSize.Value, 10, 28);
			if (!string.Equals(lastNativeOverlayText, overlayText, StringComparison.Ordinal) || lastNativeOverlayFontSize != num || lastNativeOverlayOffsetX != overlayOffsetX.Value || lastNativeOverlayOffsetY != overlayOffsetY.Value || lastNativeOverlayShowBreakdown != showBreakdown.Value)
			{
				((TMP_Text)overlayLabel).text = overlayText;
				((TMP_Text)overlayLabel).fontSize = num;
				((Graphic)overlayLabel).color = Color.white;
				((TMP_Text)overlayLabel).enableWordWrapping = false;
				((TMP_Text)overlayLabel).alignment = (TextAlignmentOptions)1028;
				((TMP_Text)overlayLabel).overflowMode = (TextOverflowModes)0;
				((TMP_Text)overlayLabel).horizontalAlignment = (HorizontalAlignmentOptions)4;
				((TMP_Text)overlayLabel).verticalAlignment = (VerticalAlignmentOptions)1024;
				float num2 = (showBreakdown.Value ? 460f : 320f);
				overlayRect.anchorMin = new Vector2(1f, 0f);
				overlayRect.anchorMax = new Vector2(1f, 0f);
				overlayRect.pivot = new Vector2(1f, 0f);
				overlayRect.anchoredPosition = new Vector2(-18f - (float)overlayOffsetX.Value, 18f + (float)overlayOffsetY.Value);
				overlayRect.sizeDelta = new Vector2(num2, 720f);
				lastNativeOverlayText = overlayText;
				lastNativeOverlayFontSize = num;
				lastNativeOverlayOffsetX = overlayOffsetX.Value;
				lastNativeOverlayOffsetY = overlayOffsetY.Value;
				lastNativeOverlayShowBreakdown = showBreakdown.Value;
			}
		}
	}

	private void EnsureNativeOverlay()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Expected O, but got Unknown
		if (!((Object)(object)overlayObject != (Object)null) || !((Object)(object)overlayLabel != (Object)null) || !((Object)(object)overlayRect != (Object)null))
		{
			if ((Object)(object)overlayCanvasObject == (Object)null || (Object)(object)overlayCanvas == (Object)null)
			{
				overlayCanvasObject = new GameObject("wzc_ui.Canvas", new Type[3]
				{
					typeof(Canvas),
					typeof(CanvasScaler),
					typeof(GraphicRaycaster)
				});
				overlayCanvas = overlayCanvasObject.GetComponent<Canvas>();
				overlayCanvas.renderMode = (RenderMode)0;
				overlayCanvas.sortingOrder = 32767;
				overlayCanvas.pixelPerfect = false;
				CanvasScaler component = overlayCanvasObject.GetComponent<CanvasScaler>();
				component.uiScaleMode = (ScaleMode)1;
				component.referenceResolution = new Vector2(1920f, 1080f);
				component.screenMatchMode = (ScreenMatchMode)0;
				component.matchWidthOrHeight = 0.5f;
				Object.DontDestroyOnLoad((Object)(object)overlayCanvasObject);
			}
			overlayObject = new GameObject("wzc_ui.NativeOverlay", new Type[1] { typeof(RectTransform) });
			overlayObject.transform.SetParent(((Component)overlayCanvas).transform, false);
			overlayObject.transform.SetAsLastSibling();
			overlayRect = overlayObject.GetComponent<RectTransform>();
			overlayLabel = overlayObject.AddComponent<TextMeshProUGUI>();
			((Graphic)overlayLabel).raycastTarget = false;
			((TMP_Text)overlayLabel).richText = true;
			((TMP_Text)overlayLabel).enableWordWrapping = false;
			((TMP_Text)overlayLabel).alignment = (TextAlignmentOptions)1028;
			TryCopyGoalUiStyle(overlayLabel);
		}
	}

	private static void TryCopyGoalUiStyle(TextMeshProUGUI target)
	{
		//IL_0027: 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_007d: 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_00c5: 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)
		if ((Object)(object)target == (Object)null)
		{
			return;
		}
		GoalUI val = Object.FindObjectOfType<GoalUI>();
		if ((Object)(object)val == (Object)null || GoalUiTextField == null)
		{
			((Graphic)target).color = Color.white;
			return;
		}
		object? value = GoalUiTextField.GetValue(val);
		TextMeshProUGUI val2 = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
		if ((Object)(object)val2 == (Object)null)
		{
			((Graphic)target).color = Color.white;
			return;
		}
		((TMP_Text)target).font = ((TMP_Text)val2).font;
		((TMP_Text)target).fontSharedMaterial = ((TMP_Text)val2).fontSharedMaterial;
		((Graphic)target).color = Color.white;
		((TMP_Text)target).outlineColor = ((TMP_Text)val2).outlineColor;
		((TMP_Text)target).outlineWidth = ((TMP_Text)val2).outlineWidth;
		((TMP_Text)target).enableVertexGradient = ((TMP_Text)val2).enableVertexGradient;
		((TMP_Text)target).fontStyle = ((TMP_Text)val2).fontStyle;
		((TMP_Text)target).characterSpacing = ((TMP_Text)val2).characterSpacing;
		((TMP_Text)target).lineSpacing = ((TMP_Text)val2).lineSpacing;
		((TMP_Text)target).margin = ((TMP_Text)val2).margin;
	}

	private float UpdateAndGetLostMapValue(float currentMapValue, ValuableObject[] valuables, HashSet<object> haulObjects)
	{
		int num = SemiFunc.RunGetLevelsCompleted() + 1;
		if (trackedLevelNumber != num || previousExtractedValue < 0f)
		{
			trackedLevelNumber = num;
			previousExtractedValue = 0f;
			accumulatedLostValue = 0f;
			valuableSnapshots.Clear();
			UpdateValuableLossSnapshots(extractionJustChanged: false, valuables, haulObjects);
			return accumulatedLostValue;
		}
		UpdateValuableLossSnapshots(extractionJustChanged: false, valuables, haulObjects);
		return accumulatedLostValue;
	}

	private void ResetLossTracking()
	{
		trackedLevelNumber = -1;
		previousExtractedValue = -1f;
		accumulatedLostValue = 0f;
		submittedFundsSnapshotLevelNumber = -1;
		submittedFundsBaselineTotalHaul = -1f;
		submittedFundsSnapshot = 0f;
		shopRemainingSnapshotLevelNumber = -1;
		shopRemainingFundsSnapshot = -1f;
		valuableSnapshots.Clear();
		valuablesCurrentlyInDollarHaul.Clear();
		WzcMapValueService.Reset();
	}

	private void UpdateValuableLossSnapshots(bool extractionJustChanged, ValuableObject[] valuables, HashSet<object> haulObjects)
	{
		valuables = valuables ?? Array.Empty<ValuableObject>();
		haulObjects = haulObjects ?? new HashSet<object>(ReferenceObjectComparer.Instance);
		liveValuableKeys.Clear();
		ValuableObject[] array = valuables;
		foreach (ValuableObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && IsValuableReady(val))
			{
				int valuableKey = GetValuableKey(val);
				float floatField = GetFloatField(ValuableOriginalValueField, val);
				float floatField2 = GetFloatField(ValuableCurrentValueField, val);
				float num = Mathf.Max(0f, floatField - floatField2);
				object physGrabObject = ValuablePhysGrabObjectField?.GetValue(val);
				bool flag = IsValuableMarkedInHaul(valuableKey) || IsValuableInReferenceSet(val, physGrabObject, haulObjects);
				liveValuableKeys.Add(valuableKey);
				if (!valuableSnapshots.TryGetValue(valuableKey, out var value))
				{
					ValuableSnapshot valuableSnapshot = default(ValuableSnapshot);
					valuableSnapshot.CountedLostValue = 0f;
					value = valuableSnapshot;
				}
				value.OriginalValue = floatField;
				value.CurrentValue = floatField2;
				value.CurrentDamage = num;
				value.WasInHaul = flag;
				float num2 = Mathf.Clamp(num, 0f, Mathf.Max(0f, floatField));
				if (!flag && num2 > value.CountedLostValue + 0.01f)
				{
					accumulatedLostValue += num2 - value.CountedLostValue;
					value.CountedLostValue = num2;
				}
				valuableSnapshots[valuableKey] = value;
			}
		}
		reusableSnapshotKeys.Clear();
		foreach (int key in valuableSnapshots.Keys)
		{
			reusableSnapshotKeys.Add(key);
		}
		foreach (int reusableSnapshotKey in reusableSnapshotKeys)
		{
			if (!liveValuableKeys.Contains(reusableSnapshotKey))
			{
				ValuableSnapshot snapshot = valuableSnapshots[reusableSnapshotKey];
				if (!snapshot.WasInHaul && !extractionJustChanged)
				{
					accumulatedLostValue += CalculateRemovedValuableLoss(snapshot);
				}
				valuableSnapshots.Remove(reusableSnapshotKey);
			}
		}
		liveValuableKeys.Clear();
	}

	private static float CalculateRemovedValuableLoss(ValuableSnapshot snapshot)
	{
		float num = Mathf.Max(0f, snapshot.OriginalValue);
		return Mathf.Max(0f, num - snapshot.CountedLostValue);
	}

	private static float GetCurrentExtractedValue()
	{
		try
		{
			return (float)SemiFunc.StatGetRunCurrency() * 1000f;
		}
		catch
		{
			try
			{
				return (float)SemiFunc.StatGetRunTotalHaul() * 1000f;
			}
			catch
			{
				return 0f;
			}
		}
	}

	private static float GetShopRemainingFundsValue()
	{
		try
		{
			return (float)SemiFunc.StatGetRunCurrency() * 1000f;
		}
		catch
		{
			return 0f;
		}
	}

	private float GetShopRemainingFundsSnapshot()
	{
		int num = SemiFunc.RunGetLevelsCompleted() + 1;
		if (shopRemainingSnapshotLevelNumber != num || shopRemainingFundsSnapshot < 0f)
		{
			shopRemainingSnapshotLevelNumber = num;
			shopRemainingFundsSnapshot = GetShopRemainingFundsValue();
		}
		return shopRemainingFundsSnapshot;
	}

	private static float GetRunTotalHaulValue()
	{
		try
		{
			return (float)SemiFunc.StatGetRunTotalHaul() * 1000f;
		}
		catch
		{
			return 0f;
		}
	}

	private float GetCurrentLevelSubmittedValue()
	{
		int submittedFundsLevelKey = GetSubmittedFundsLevelKey();
		if (submittedFundsSnapshotLevelNumber != submittedFundsLevelKey || submittedFundsBaselineTotalHaul < 0f)
		{
			submittedFundsSnapshotLevelNumber = submittedFundsLevelKey;
			submittedFundsBaselineTotalHaul = GetRunTotalHaulValue();
			submittedFundsSnapshot = 0f;
		}
		float num = Mathf.Max(0f, GetRunTotalHaulValue() - submittedFundsBaselineTotalHaul);
		submittedFundsSnapshot = Mathf.Max(submittedFundsSnapshot, num);
		return submittedFundsSnapshot;
	}

	private static int GetSubmittedFundsLevelKey()
	{
		int num = SemiFunc.RunGetLevelsCompleted();
		try
		{
			return SemiFunc.RunIsShop() ? num : (num + 1);
		}
		catch
		{
			return num + 1;
		}
	}

	private static float GetRoundDirectorCurrentHaulValue()
	{
		object obj = RoundDirectorInstanceField?.GetValue(null);
		if (obj != null && RoundDirectorCurrentHaulField != null)
		{
			return Mathf.Max(0f, GetFloatField(RoundDirectorCurrentHaulField, obj));
		}
		return 0f;
	}

	private static bool IsValuableReady(ValuableObject valuable)
	{
		if (ValuableValueSetField == null)
		{
			return true;
		}
		object value = ValuableValueSetField.GetValue(valuable);
		bool flag = default(bool);
		int num;
		if (value is bool)
		{
			flag = (bool)value;
			num = ((1 == 0) ? 1 : 0);
		}
		else
		{
			num = 1;
		}
		return (byte)((uint)num | (flag ? 1u : 0u)) != 0;
	}

	private static int GetValuableKey(ValuableObject valuable)
	{
		object obj = ValuablePhotonViewField?.GetValue(valuable);
		if (obj != null)
		{
			Type type = obj.GetType();
			if (GetCachedPhotonViewIdProperty(type)?.GetValue(obj, null) is int num && num != 0)
			{
				return num;
			}
			if (GetCachedPhotonViewIdField(type)?.GetValue(obj) is int num2 && num2 != 0)
			{
				return num2;
			}
		}
		return ((Object)valuable).GetInstanceID();
	}

	private static PropertyInfo GetCachedPhotonViewIdProperty(Type photonViewType)
	{
		if (photonViewType == null)
		{
			return null;
		}
		if (!PhotonViewIdPropertyCache.TryGetValue(photonViewType, out var value))
		{
			value = photonViewType.GetProperty("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			PhotonViewIdPropertyCache[photonViewType] = value;
		}
		return value;
	}

	private static FieldInfo GetCachedPhotonViewIdField(Type photonViewType)
	{
		if (photonViewType == null)
		{
			return null;
		}
		if (!PhotonViewIdFieldCache.TryGetValue(photonViewType, out var value))
		{
			value = photonViewType.GetField("viewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? photonViewType.GetField("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			PhotonViewIdFieldCache[photonViewType] = value;
		}
		return value;
	}

	private static PropertyInfo GetCachedPhotonViewOwnerProperty(Type photonViewType)
	{
		if (photonViewType == null)
		{
			return null;
		}
		if (!PhotonViewOwnerPropertyCache.TryGetValue(photonViewType, out var value))
		{
			value = photonViewType.GetProperty("Owner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			PhotonViewOwnerPropertyCache[photonViewType] = value;
		}
		return value;
	}

	private static PropertyInfo GetCachedPhotonOwnerNickNameProperty(Type ownerType)
	{
		if (ownerType == null)
		{
			return null;
		}
		if (!PhotonOwnerNickNamePropertyCache.TryGetValue(ownerType, out var value))
		{
			value = ownerType.GetProperty("NickName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			PhotonOwnerNickNamePropertyCache[ownerType] = value;
		}
		return value;
	}

	private static float GetFloatField(FieldInfo field, object instance)
	{
		if (field == null || instance == null)
		{
			return 0f;
		}
		object value = field.GetValue(instance);
		if (value != null)
		{
			return Convert.ToSingle(value, CultureInfo.InvariantCulture);
		}
		return 0f;
	}

	private static void FillCurrentDollarHaulObjects(List<object> result)
	{
		if (result == null)
		{
			return;
		}
		result.Clear();
		object obj = RoundDirectorInstanceField?.GetValue(null);
		if (!(((obj == null) ? null : RoundDirectorDollarHaulListField?.GetValue(obj)) is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			if (item != null)
			{
				result.Add(item);
			}
		}
	}

	private void FillCurrentCartObjects(List<object> result)
	{
		if (result == null)
		{
			return;
		}
		result.Clear();
		PhysGrabCart[] cartObjectsCachedForFrame = GetCartObjectsCachedForFrame();
		if (cartObjectsCachedForFrame == null || cartObjectsCachedForFrame.Length == 0)
		{
			return;
		}
		PhysGrabCart[] array = cartObjectsCachedForFrame;
		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 static void AddEnumerableObjects(List<object> result, object rawList)
	{
		if (!(rawList is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			if (item != null)
			{
				result.Add(item);
			}
		}
	}

	private static void FillReferenceSet(List<object> list, HashSet<object> result)
	{
		if (result == null)
		{
			return;
		}
		result.Clear();
		if (list == null || list.Count == 0)
		{
			return;
		}
		foreach (object item in list)
		{
			if (item != null)
			{
				result.Add(item);
			}
		}
	}

	private static bool IsReferenceInSet(HashSet<object> set, object target)
	{
		if (target != null && set != null)
		{
			return set.Contains(target);
		}
		return false;
	}

	private static bool IsValuableMarkedInHaul(int key)
	{
		if (key != 0)
		{
			return valuablesCurrentlyInDollarHaul.Contains(key);
		}
		return false;
	}

	private static bool IsValuableInReferenceSet(ValuableObject valuable, object physGrabObject, HashSet<object> set)
	{
		if ((Object)(object)valuable == (Object)null || set == null || set.Count == 0)
		{
			return false;
		}
		GameObject gameObject = ((Component)valuable).gameObject;
		GameObject objectGameObject = GetObjectGameObject(physGrabObject);
		foreach (object item in set)
		{
			if (item != null)
			{
				if (item == valuable || item == gameObject || item == physGrabObject || item == objectGameObject)
				{
					return true;
				}
				GameObject objectGameObject2 = GetObjectGameObject(item);
				if ((Object)(object)objectGameObject2 != (Object)null && (objectGameObject2 == gameObject || objectGameObject2 == objectGameObject))
				{
					return true;
				}
			}
		}
		return false;
	}

	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 string BuildLevelLine()
	{
		DisplayLanguage currentLanguage = CurrentLanguage;
		GetLevelInfo(currentLanguage, out var levelNumber, out var levelName);
		return $"{HudText.Level(currentLanguage)}: {levelNumber} - {levelName}";
	}

	private string BuildPlayerCountLine()
	{
		DisplayLanguage currentLanguage = CurrentLanguage;
		GetPlayerCounts(out var totalPlayers, out var alivePlayers, out var deadPlayers);
		return $"{HudText.PlayerCounts(currentLanguage)}: {HudText.Dead(currentLanguage)} {deadPlayers} | {HudText.Alive(currentLanguage)} {alivePlayers} | {HudText.Total(currentLanguage)} {totalPlayers}";
	}

	private static void GetLevelInfo(DisplayLanguage language, out int levelNumber, out string levelName)
	{
		levelNumber = SemiFunc.RunGetLevelsCompleted() + 1;
		levelName = HudText.UnknownLevel(language);
		if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null)
		{
			string narrativeName = RunManager.instance.levelCurrent.NarrativeName;
			if (!string.IsNullOrWhiteSpace(narrativeName))
			{
				levelName = LevelNameLocalizer.Translate(narrativeName.Trim(), language);
			}
		}
	}

	private void GetPlayerCounts(out int totalPlayers, out int alivePlayers, out int deadPlayers)
	{
		List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
		totalPlayers = playerObjectsCachedForFrame?.Count ?? 0;
		alivePlayers = 0;
		if (playerObjectsCachedForFrame != null)
		{
			foreach (PlayerAvatar item in playerObjectsCachedForFrame)
			{
				if (IsPlayerAlive(item))
				{
					alivePlayers++;
				}
			}
		}
		deadPlayers = Math.Max(0, totalPlayers - alivePlayers);
	}

	private static void AppendTeammateDistanceLines(List<WzcUiPlayerDistance> teammates, bool deadOnly, List<string> lines)
	{
		if (teammates == null || teammates.Count == 0)
		{
			return;
		}
		foreach (WzcUiPlayerDistance teammate in teammates)
		{
			if (teammate != null && teammate.IsDead == deadOnly)
			{
				string text = (teammate.IsDead ? $"☠ {teammate.Name} {teammate.DistanceMeters}m" : string.Format("{0} {1} {2}m", "\ud83e\udd16", teammate.Name, teammate.DistanceMeters));
				lines.Add(ColorOverlayLine(text, teammate.ColorHex));
			}
		}
	}

	private List<WzcUiPlayerDistance> CreateTeammateDistanceInfos()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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_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_0087: Unknown result type (might be due to invalid IL or missing references)
		List<PlayerAvatar> playerObjectsCachedForFrame = GetPlayerObjectsCachedForFrame();
		PlayerAvatar localPlayer = GetLocalPlayer(playerObjectsCachedForFrame);
		if (playerObjectsCachedForFrame == null || playerObjectsCachedForFrame.Count == 0 || (Object)(object)localPlayer == (Object)null)
		{
			return new List<WzcUiPlayerDistance>();
		}
		Vector3 playerDistanceOrigin = GetPlayerDistanceOrigin(localPlayer, IsPlayerAlive(localPlayer));
		List<WzcUiPlayerDistance> list = new List<WzcUiPlayerDistance>(playerObjectsCachedForFrame.Count);
		foreach (PlayerAvatar item in playerObjectsCachedForFrame)
		{
			if (!((Object)(object)item == (Object)null))
			{
				bool flag = item == localPlayer;
				bool flag2 = IsPlayerAlive(item);
				if (!(flag && flag2))
				{
					Vector3 playerReferencePosition = GetPlayerReferencePosition(item, !flag2);
					int distanceMeters = Mathf.RoundToInt(Vector3.Distance(playerDistanceOrigin, playerReferencePosition));
					list.Add(new WzcUiPlayerDistance
					{
						Name = GetCachedPlayerName(item),
						DistanceMeters = distanceMeters,
						IsDead = !flag2,
						IsLocalPlayer = flag,
						ColorHex = GetCachedPlayerColorHex(item)
					});
				}
			}
		}
		list.Sort(ComparePlayerDistanceInfo);
		return list;
	}

	private static int ComparePlayerDistanceInfo(WzcUiPlayerDistance left, WzcUiPlayerDista