Decompiled source of EnemyRespawnHUD v0.1.3

BepInEx/plugins/EnemyRespawnHUD/EnemyRespawnHUD.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using RepoSteamNetworking.API;
using RepoSteamNetworking.Networking;
using RepoSteamNetworking.Networking.Serialization;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("EnemyRespawnHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3")]
[assembly: AssemblyProduct("EnemyRespawnHUD")]
[assembly: AssemblyTitle("EnemyRespawnHUD")]
[assembly: AssemblyVersion("0.1.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnemyRespawnHUD
{
	[BepInPlugin("com.codex.enemyresphud", "Enemy Respawn HUD", "0.1.3")]
	[BepInProcess("REPO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class EnemyRespawnHudPlugin : BaseUnityPlugin
	{
		private readonly struct DisplayRow
		{
			public readonly EnemySnapshotEntry Entry;

			public readonly float RemainingSeconds;

			public readonly bool IsActive;

			public DisplayRow(EnemySnapshotEntry entry, float remainingSeconds, bool isActive)
			{
				Entry = entry;
				RemainingSeconds = remainingSeconds;
				IsActive = isActive;
			}
		}

		private sealed class HudLabel
		{
			public readonly TMP_Text Text;

			public readonly RectTransform Rect;

			public HudLabel(TMP_Text text)
			{
				Text = text;
				Rect = text.rectTransform;
			}
		}

		private sealed class EnemyRowView
		{
			public readonly HudLabel Name;

			public readonly HudLabel Timer;

			public EnemyRowView(HudLabel name, HudLabel timer)
			{
				Name = name;
				Timer = timer;
			}
		}

		public const string PluginGuid = "com.codex.enemyresphud";

		public const string PluginName = "Enemy Respawn HUD";

		public const string PluginVersion = "0.1.3";

		private const int MaxSnapshotEntries = 256;

		private const float SnapshotTimeout = 3f;

		private const float SyncIntervalSeconds = 0.5f;

		private const float SpawnWarningSeconds = 5f;

		private const string HudRootPath = "UI/HUD/HUD Canvas/HUD/Game Hud";

		private const float MaxScreenHeightFraction = 0.68f;

		private const float MaxScreenWidthFraction = 0.36f;

		private const float RowGap = 2f;

		private const float ColumnGap = 9f;

		private readonly string _sessionId = Guid.NewGuid().ToString("N");

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

		private List<EnemySnapshotEntry> _currentEntries = new List<EnemySnapshotEntry>();

		private readonly List<EnemyRowView> _rowViews = new List<EnemyRowView>();

		private GameObject _hudObject;

		private RectTransform _hudRect;

		private Canvas _hudCanvas;

		private TMP_FontAsset _hudFont;

		private Material _hudFontMaterial;

		private HudLabel _headerLabel;

		private HudLabel _overflowLabel;

		private string _remoteSessionId = string.Empty;

		private long _sequence;

		private long _lastRemoteSequence = -1L;

		private float _lastCaptureTime = -100f;

		private float _snapshotReceivedAt;

		private float _nextHudLookupTime;

		private float _nextHudRefreshAt;

		private bool _hasSnapshot;

		private void Awake()
		{
			RepoSteamNetwork.RegisterPacket<EnemySnapshotPacket>();
			RepoSteamNetwork.AddCallback<EnemySnapshotPacket>((Action<EnemySnapshotPacket>)OnSnapshotReceived);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Enemy Respawn HUD 0.1.3 loaded (automatic HUD layout).");
		}

		private void OnDestroy()
		{
			RepoSteamNetwork.RemoveCallback<EnemySnapshotPacket>((Action<EnemySnapshotPacket>)OnSnapshotReceived);
			if ((Object)(object)_hudObject != (Object)null)
			{
				Object.Destroy((Object)(object)_hudObject);
			}
		}

		private void Update()
		{
			if (!SemiFunc.RunIsLevel() || SemiFunc.RunIsShop() || SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu())
			{
				_hasSnapshot = false;
				_currentEntries.Clear();
				_lastCaptureTime = -100f;
				_lastRemoteSequence = -1L;
				_remoteSessionId = string.Empty;
				_nextHudRefreshAt = 0f;
			}
			else
			{
				if (!RepoSteamNetwork.HasHostAuthority)
				{
					return;
				}
				float num = 0.5f;
				if (Time.unscaledTime - _lastCaptureTime < num)
				{
					return;
				}
				_lastCaptureTime = Time.unscaledTime;
				if (TryCaptureSnapshot(out var entries))
				{
					_currentEntries = entries;
					_snapshotReceivedAt = Time.unscaledTime;
					_hasSnapshot = true;
					if (RepoSteamNetwork.IsServer)
					{
						RepoSteamNetwork.SendPacket<EnemySnapshotPacket>(new EnemySnapshotPacket
						{
							SessionId = _sessionId,
							Sequence = ++_sequence,
							Entries = entries
						}, (NetworkDestination)1);
					}
				}
			}
		}

		private bool TryCaptureSnapshot(out List<EnemySnapshotEntry> entries)
		{
			entries = new List<EnemySnapshotEntry>();
			EnemyDirector instance = EnemyDirector.instance;
			if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null)
			{
				return false;
			}
			_seenViewIds.Clear();
			foreach (EnemyParent item in instance.enemiesSpawned)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null)
				{
					continue;
				}
				try
				{
					int num = ((Object)item).GetInstanceID() & 0x7FFFFFFF;
					if (num == 0)
					{
						num = int.MaxValue;
					}
					if (_seenViewIds.Add(num))
					{
						string text = (string.IsNullOrWhiteSpace(item.enemyName) ? ((Object)((Component)item).gameObject).name : item.enemyName.Trim());
						if (string.IsNullOrWhiteSpace(text))
						{
							text = "Unknown enemy";
						}
						if (text.Length > 40)
						{
							text = text.Substring(0, 37) + "...";
						}
						float num2 = item.DespawnedTimer;
						if (float.IsNaN(num2) || float.IsInfinity(num2))
						{
							num2 = 0f;
						}
						num2 = Mathf.Clamp(num2, 0f, 86400f);
						entries.Add(new EnemySnapshotEntry(num, text, num2));
						if (entries.Count >= 256)
						{
							break;
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to track an enemy: " + ex.Message));
				}
			}
			entries.Sort(EnemySnapshotEntry.Compare);
			return true;
		}

		private void OnSnapshotReceived(EnemySnapshotPacket packet)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (RepoSteamNetwork.HasHostAuthority || !packet.IsValid || !SemiFunc.RunIsLevel() || SemiFunc.RunIsShop())
			{
				return;
			}
			try
			{
				Lobby currentLobby = RepoSteamNetwork.GetCurrentLobby();
				SteamId id = ((Lobby)(ref currentLobby)).Owner.Id;
				if (!((SteamId)(ref id)).IsValid || SteamId.op_Implicit(((NetworkPacket)packet).Header.Sender) != SteamId.op_Implicit(id))
				{
					return;
				}
			}
			catch (Exception)
			{
				return;
			}
			if (!string.Equals(packet.SessionId, _remoteSessionId, StringComparison.Ordinal))
			{
				_remoteSessionId = packet.SessionId;
				_lastRemoteSequence = -1L;
			}
			if (packet.Sequence > _lastRemoteSequence)
			{
				_lastRemoteSequence = packet.Sequence;
				_currentEntries = new List<EnemySnapshotEntry>(packet.Entries);
				_snapshotReceivedAt = Time.unscaledTime;
				_hasSnapshot = true;
			}
		}

		private void LateUpdate()
		{
			if (!SemiFunc.RunIsLevel() || SemiFunc.RunIsShop() || SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu())
			{
				SetHudVisible(visible: false);
				return;
			}
			List<DisplayRow> displayRows = GetDisplayRows();
			string emptyMessage = null;
			if (displayRows.Count == 0)
			{
				emptyMessage = ((!_hasSnapshot || !(Time.unscaledTime - _snapshotReceivedAt <= 3f)) ? "WAITING FOR ENEMY DATA..." : "NO ENEMIES TRACKED");
			}
			if ((Object)(object)_hudObject == (Object)null)
			{
				if (Time.unscaledTime < _nextHudLookupTime)
				{
					return;
				}
				_nextHudLookupTime = Time.unscaledTime + 1f;
				if (!TryCreateHud())
				{
					return;
				}
			}
			SetHudVisible(visible: true);
			if (!(Time.unscaledTime < _nextHudRefreshAt))
			{
				_nextHudRefreshAt = Time.unscaledTime + 0.1f;
				UpdateHud(displayRows, emptyMessage);
			}
		}

		private void SetHudVisible(bool visible)
		{
			if ((Object)(object)_hudObject != (Object)null && _hudObject.activeSelf != visible)
			{
				_hudObject.SetActive(visible);
			}
		}

		private bool TryCreateHud()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud");
			TMP_Text val2 = (((Object)(object)val != (Object)null) ? FindHudFontSource(val.transform) : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.font == (Object)null)
			{
				TMP_Text[] array = Object.FindObjectsOfType<TMP_Text>();
				foreach (TMP_Text val3 in array)
				{
					if ((Object)(object)val3 != (Object)null && (Object)(object)val3.font != (Object)null && ((Component)val3).gameObject.activeInHierarchy)
					{
						val2 = val3;
						break;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.font == (Object)null)
			{
				return false;
			}
			_hudFont = val2.font;
			_hudFontMaterial = val2.fontSharedMaterial;
			_hudObject = new GameObject("EnemyRespawnHUD_Canvas", new Type[3]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler)
			});
			Object.DontDestroyOnLoad((Object)(object)_hudObject);
			_hudCanvas = _hudObject.GetComponent<Canvas>();
			_hudCanvas.renderMode = (RenderMode)0;
			_hudCanvas.overrideSorting = true;
			_hudCanvas.sortingOrder = 450;
			CanvasScaler component = _hudObject.GetComponent<CanvasScaler>();
			component.uiScaleMode = (ScaleMode)1;
			component.referenceResolution = new Vector2(1920f, 1080f);
			component.screenMatchMode = (ScreenMatchMode)0;
			component.matchWidthOrHeight = 0.5f;
			GameObject val4 = new GameObject("EnemyRespawnHUD_Panel", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val4.transform.SetParent(_hudObject.transform, false);
			_hudRect = (RectTransform)val4.transform;
			Image component2 = val4.GetComponent<Image>();
			((Graphic)component2).color = new Color(0.015f, 0.019f, 0.029f, 0.31f);
			((Graphic)component2).raycastTarget = false;
			_rowViews.Clear();
			_headerLabel = CreateLabel("Header", (Transform)(object)_hudRect, (FontStyles)1, new Color(0.96f, 0.97f, 1f), (TextAlignmentOptions)4097);
			_overflowLabel = CreateLabel("Overflow", (Transform)(object)_hudRect, (FontStyles)0, new Color(0.68f, 0.73f, 0.8f), (TextAlignmentOptions)4097);
			return true;
		}

		private static TMP_Text FindHudFontSource(Transform gameHud)
		{
			TMP_Text val = FindComponentText<HealthUI>(gameHud);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = FindComponentText<CurrencyUI>(gameHud);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			TMP_Text[] componentsInChildren = ((Component)gameHud).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.font != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static TMP_Text FindComponentText<T>(Transform root) where T : Component
		{
			T[] componentsInChildren = ((Component)root).GetComponentsInChildren<T>(true);
			foreach (T val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					TMP_Text component = ((Component)val).GetComponent<TMP_Text>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.font != (Object)null)
					{
						return component;
					}
				}
			}
			return null;
		}

		private HudLabel CreateLabel(string objectName, Transform parent, FontStyles fontStyle, Color color, TextAlignmentOptions alignment)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName, new Type[2]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer)
			});
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = _hudFont;
			if ((Object)(object)_hudFontMaterial != (Object)null)
			{
				((TMP_Text)val2).fontSharedMaterial = _hudFontMaterial;
			}
			((TMP_Text)val2).fontStyle = fontStyle;
			((TMP_Text)val2).alignment = alignment;
			((Graphic)val2).color = color;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)1;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.9f));
			((TMP_Text)val2).outlineWidth = 0.14f;
			return new HudLabel((TMP_Text)(object)val2);
		}

		private void UpdateHud(List<DisplayRow> rows, string emptyMessage)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			if (rows.Count == 0)
			{
				UpdateEmptyHud(emptyMessage ?? "WAITING FOR ENEMY DATA...");
				return;
			}
			RectTransform val = (RectTransform)((Component)_hudCanvas).transform;
			Rect rect = val.rect;
			float num = Mathf.Max(320f, ((Rect)(ref rect)).width);
			rect = val.rect;
			float num2 = Mathf.Max(240f, ((Rect)(ref rect)).height);
			float num3 = Mathf.Clamp(num2 * 0.01f, 8f, 13f);
			float num4 = Mathf.Clamp(num2 * 0.023f, 19f, 26f);
			float num5 = num4 * 0.88f;
			float num6 = num4 * 1.05f;
			float num7 = Mathf.Ceil(num4 + 12f);
			float num8 = Mathf.Ceil(num6 + 14f);
			float num9 = Mathf.Ceil(num4 * 0.86f + 6f);
			int num10 = Mathf.Clamp(Mathf.FloorToInt((num2 * 0.68f - num8 - num3 * 2f - num9) / (num7 + 2f)), 1, 24);
			int num11 = Mathf.Min(rows.Count, num10);
			bool flag = num11 < rows.Count;
			float height = num3 * 2f + num8 + (float)num11 * (num7 + 2f) + (flag ? num9 : 0f);
			EnsureRowViews(num11);
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			foreach (DisplayRow row2 in rows)
			{
				string key = row2.Entry.Name ?? "Unknown enemy";
				dictionary[key] = ((!dictionary.TryGetValue(key, out var value)) ? 1 : (value + 1));
			}
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			float num12 = 0f;
			float num13 = 0f;
			for (int i = 0; i < num11; i++)
			{
				DisplayRow row = rows[i];
				EnemyRowView enemyRowView = _rowViews[i];
				string text = row.Entry.Name ?? "Unknown enemy";
				if (dictionary[text] > 1)
				{
					text = text + "  #" + (dictionary2[text] = ((!dictionary2.TryGetValue(text, out var value2)) ? 1 : (value2 + 1)));
				}
				string text2 = StatusText(row);
				SetTextIfChanged(enemyRowView.Name.Text, text);
				SetFontSizeIfChanged(enemyRowView.Name.Text, num4);
				SetTextIfChanged(enemyRowView.Timer.Text, text2);
				SetFontSizeIfChanged(enemyRowView.Timer.Text, num5);
				float x = enemyRowView.Name.Text.GetPreferredValues(text).x;
				float x2 = enemyRowView.Timer.Text.GetPreferredValues(text2).x;
				num12 = Mathf.Max(num12, x);
				num13 = Mathf.Max(num13, x2);
			}
			string text3 = $"ENEMIES ({rows.Count})";
			SetTextIfChanged(_headerLabel.Text, text3);
			SetFontSizeIfChanged(_headerLabel.Text, num6);
			float x3 = _headerLabel.Text.GetPreferredValues(text3).x;
			float num15 = Mathf.Max(num13 + 5f, num5 * 3.5f);
			float num16 = Mathf.Max(x3, num12 + 9f + num15) + num3 * 2f;
			float num17 = Mathf.Min(Mathf.Max(175f, Mathf.Min(440f, num * 0.36f)), Mathf.Max(195f, num16));
			num15 = Mathf.Min(num15, num17 * 0.43f);
			float width = Mathf.Max(35f, num17 - num3 * 2f - num15 - 9f);
			ConfigurePanelRect(num17, height);
			SetLabelVisible(_headerLabel, visible: true);
			SetLabelRect(_headerLabel, num3, num3, num17 - num3 * 2f, num8, alignRight: false);
			SetColorIfChanged(_headerLabel.Text, new Color(0.97f, 0.97f, 1f));
			for (int j = 0; j < num11; j++)
			{
				DisplayRow displayRow = rows[j];
				EnemyRowView enemyRowView2 = _rowViews[j];
				SetLabelVisible(enemyRowView2.Name, visible: true);
				SetLabelVisible(enemyRowView2.Timer, visible: true);
				float y = num3 + num8 + (float)j * (num7 + 2f);
				SetLabelRect(enemyRowView2.Name, num3, y, width, num7, alignRight: false);
				SetColorIfChanged(enemyRowView2.Name.Text, displayRow.IsActive ? new Color(0.86f, 0.88f, 0.94f) : new Color(1f, 0.97f, 0.93f));
				SetLabelRect(enemyRowView2.Timer, num3, y, num15, num7, alignRight: true);
				SetColorIfChanged(color: displayRow.IsActive ? new Color(0.48f, 1f, 0.57f) : ((displayRow.RemainingSeconds <= 5f) ? new Color(1f, 0.42f, 0.29f) : new Color(1f, 0.78f, 0.38f)), text: enemyRowView2.Timer.Text);
			}
			for (int k = num11; k < _rowViews.Count; k++)
			{
				SetLabelVisible(_rowViews[k].Name, visible: false);
				SetLabelVisible(_rowViews[k].Timer, visible: false);
			}
			SetLabelVisible(_overflowLabel, flag);
			if (flag)
			{
				float y2 = num3 + num8 + (float)num11 * (num7 + 2f);
				SetLabelRect(_overflowLabel, num3, y2, num17 - num3 * 2f, num9, alignRight: false);
				SetTextIfChanged(_overflowLabel.Text, $"+{rows.Count - num11} MORE");
				SetFontSizeIfChanged(_overflowLabel.Text, num4 * 0.78f);
			}
		}

		private static string StatusText(DisplayRow row)
		{
			if (row.IsActive)
			{
				return "ACTIVE";
			}
			if (row.RemainingSeconds <= 5f)
			{
				int num = Mathf.CeilToInt(row.RemainingSeconds);
				if (num > 1)
				{
					return num + "s";
				}
				return "SOON";
			}
			return FormatTime(row.RemainingSeconds);
		}

		private void UpdateEmptyHud(string message)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)_hudCanvas).transform;
			Rect rect = val.rect;
			float num = Mathf.Max(320f, ((Rect)(ref rect)).width);
			rect = val.rect;
			float num2 = Mathf.Max(240f, ((Rect)(ref rect)).height);
			float num3 = Mathf.Clamp(num2 * 0.023f, 19f, 26f);
			float num4 = Mathf.Clamp(num2 * 0.01f, 8f, 13f);
			SetTextIfChanged(_headerLabel.Text, message);
			SetFontSizeIfChanged(_headerLabel.Text, num3);
			float num5 = _headerLabel.Text.GetPreferredValues(message).x + num4 * 2f + 8f;
			float num6 = Mathf.Min(Mathf.Max(175f, Mathf.Min(440f, num * 0.36f)), Mathf.Max(195f, num5));
			float num7 = num3 + 18f + num4 * 2f;
			ConfigurePanelRect(num6, num7);
			SetLabelVisible(_headerLabel, visible: true);
			SetLabelRect(_headerLabel, num4, num4, num6 - num4 * 2f, num7 - num4 * 2f, alignRight: false);
			SetColorIfChanged(_headerLabel.Text, new Color(0.87f, 0.9f, 0.96f));
			SetLabelVisible(_overflowLabel, visible: false);
			foreach (EnemyRowView rowView in _rowViews)
			{
				SetLabelVisible(rowView.Name, visible: false);
				SetLabelVisible(rowView.Timer, visible: false);
			}
		}

		private static void SetTextIfChanged(TMP_Text text, string value)
		{
			if (!string.Equals(text.text, value, StringComparison.Ordinal))
			{
				text.text = value;
			}
		}

		private static void SetFontSizeIfChanged(TMP_Text text, float size)
		{
			if (!Mathf.Approximately(text.fontSize, size))
			{
				text.fontSize = size;
			}
		}

		private static void SetColorIfChanged(TMP_Text text, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (((Graphic)text).color != color)
			{
				((Graphic)text).color = color;
			}
		}

		private static void SetLabelVisible(HudLabel label, bool visible)
		{
			if (((Component)label.Text).gameObject.activeSelf != visible)
			{
				((Component)label.Text).gameObject.SetActive(visible);
			}
		}

		private void EnsureRowViews(int count)
		{
			//IL_003a: 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)
			while (_rowViews.Count < count)
			{
				int num = _rowViews.Count + 1;
				HudLabel name = CreateLabel($"EnemyName_{num}", (Transform)(object)_hudRect, (FontStyles)0, new Color(0.91f, 0.94f, 0.98f), (TextAlignmentOptions)4097);
				HudLabel timer = CreateLabel($"EnemyTimer_{num}", (Transform)(object)_hudRect, (FontStyles)1, new Color(1f, 0.73f, 0.31f), (TextAlignmentOptions)4100);
				_rowViews.Add(new EnemyRowView(name, timer));
			}
		}

		private void ConfigurePanelRect(float width, float height)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)_hudCanvas).transform;
			Rect rect = val.rect;
			float num = Mathf.Clamp(Mathf.Max(320f, ((Rect)(ref rect)).width) * 0.018f, 18f, 42f);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0.5f);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f - num, 0f);
			if (_hudRect.anchorMin != val2)
			{
				_hudRect.anchorMin = val2;
			}
			if (_hudRect.anchorMax != val2)
			{
				_hudRect.anchorMax = val2;
			}
			if (_hudRect.pivot != val2)
			{
				_hudRect.pivot = val2;
			}
			if (_hudRect.anchoredPosition != val3)
			{
				_hudRect.anchoredPosition = val3;
			}
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(width, height);
			if (_hudRect.sizeDelta != val4)
			{
				_hudRect.sizeDelta = val4;
			}
			if (((Transform)_hudRect).localScale != Vector3.one)
			{
				((Transform)_hudRect).localScale = Vector3.one;
			}
		}

		private static void SetLabelRect(HudLabel label, float x, float y, float width, float height, bool alignRight)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rect = label.Rect;
			Vector2 val = (alignRight ? new Vector2(1f, 1f) : new Vector2(0f, 1f));
			if (rect.anchorMin != val)
			{
				rect.anchorMin = val;
			}
			if (rect.anchorMax != val)
			{
				rect.anchorMax = val;
			}
			if (rect.pivot != val)
			{
				rect.pivot = val;
			}
			Vector2 val2 = (alignRight ? new Vector2(0f - x, 0f - y) : new Vector2(x, 0f - y));
			if (rect.anchoredPosition != val2)
			{
				rect.anchoredPosition = val2;
			}
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(width, height);
			if (rect.sizeDelta != val3)
			{
				rect.sizeDelta = val3;
			}
		}

		private List<DisplayRow> GetDisplayRows()
		{
			List<DisplayRow> list = new List<DisplayRow>();
			if (!_hasSnapshot || Time.unscaledTime - _snapshotReceivedAt > 3f)
			{
				return list;
			}
			float num = Mathf.Max(0f, Time.unscaledTime - _snapshotReceivedAt);
			foreach (EnemySnapshotEntry currentEntry in _currentEntries)
			{
				float num2 = Mathf.Max(0f, currentEntry.RemainingSeconds - num);
				bool isActive = num2 <= 0f;
				list.Add(new DisplayRow(currentEntry, num2, isActive));
			}
			list.Sort(delegate(DisplayRow left, DisplayRow right)
			{
				int num3 = left.IsActive.CompareTo(right.IsActive);
				if (num3 != 0)
				{
					return num3;
				}
				if (!left.IsActive)
				{
					int num4 = left.RemainingSeconds.CompareTo(right.RemainingSeconds);
					if (num4 != 0)
					{
						return num4;
					}
				}
				return EnemySnapshotEntry.Compare(left.Entry, right.Entry);
			});
			return list;
		}

		private static string FormatTime(float seconds)
		{
			int num = Mathf.Max(0, Mathf.CeilToInt(seconds));
			int num2 = num / 60;
			int num3 = num % 60;
			if (num2 < 60)
			{
				return $"{num2:00}:{num3:00}";
			}
			return $"{num2 / 60}:{num2 % 60:00}:{num3:00}";
		}
	}
	public sealed class EnemySnapshotEntry
	{
		public int ViewId;

		public string Name;

		public float RemainingSeconds;

		public EnemySnapshotEntry()
		{
			Name = string.Empty;
		}

		public EnemySnapshotEntry(int viewId, string name, float remainingSeconds)
		{
			ViewId = viewId;
			Name = name;
			RemainingSeconds = remainingSeconds;
		}

		public static int Compare(EnemySnapshotEntry left, EnemySnapshotEntry right)
		{
			int num = string.Compare(left.Name, right.Name, StringComparison.OrdinalIgnoreCase);
			if (num == 0)
			{
				return left.ViewId.CompareTo(right.ViewId);
			}
			return num;
		}
	}
	public sealed class EnemySnapshotPacket : NetworkPacket<EnemySnapshotPacket>
	{
		private const int MaxEntries = 256;

		public string SessionId = string.Empty;

		public long Sequence;

		public List<EnemySnapshotEntry> Entries = new List<EnemySnapshotEntry>();

		public bool IsValid { get; private set; } = true;

		protected override void WriteData(SocketMessage socketMessage)
		{
			int num = Math.Min(Entries?.Count ?? 0, 256);
			socketMessage.Write<string>(SessionId ?? string.Empty);
			socketMessage.Write<long>(Sequence);
			socketMessage.Write<int>(num);
			for (int i = 0; i < num; i++)
			{
				EnemySnapshotEntry enemySnapshotEntry = Entries[i];
				socketMessage.Write<int>(enemySnapshotEntry.ViewId);
				socketMessage.Write<string>(enemySnapshotEntry.Name ?? "Unknown enemy");
				socketMessage.Write<float>(enemySnapshotEntry.RemainingSeconds);
			}
		}

		protected override void ReadData(SocketMessage socketMessage)
		{
			IsValid = false;
			SessionId = socketMessage.Read<string>() ?? string.Empty;
			Sequence = socketMessage.Read<long>();
			int num = socketMessage.Read<int>();
			if (string.IsNullOrWhiteSpace(SessionId) || num < 0 || num > 256)
			{
				Entries = new List<EnemySnapshotEntry>();
				return;
			}
			List<EnemySnapshotEntry> list = new List<EnemySnapshotEntry>(num);
			for (int i = 0; i < num; i++)
			{
				int num2 = socketMessage.Read<int>();
				string text = socketMessage.Read<string>() ?? "Unknown enemy";
				float num3 = socketMessage.Read<float>();
				if (num2 <= 0 || float.IsNaN(num3) || float.IsInfinity(num3))
				{
					Entries = new List<EnemySnapshotEntry>();
					return;
				}
				if (text.Length > 40)
				{
					text = text.Substring(0, 37) + "...";
				}
				list.Add(new EnemySnapshotEntry(num2, text, Mathf.Clamp(num3, 0f, 86400f)));
			}
			Entries = list;
			IsValid = true;
		}
	}
}