Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RepoDeathCounter v1.4.6
Matsu.RepoDeathCounter.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; 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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Matsu.RepoDeathCounter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.4.6.0")] [assembly: AssemblyInformationalVersion("1.4.6")] [assembly: AssemblyProduct("Matsu.RepoDeathCounter")] [assembly: AssemblyTitle("Matsu.RepoDeathCounter")] [assembly: AssemblyVersion("1.4.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 Matsu.RepoDeathCounter { internal static class DeathCounterCore { internal static bool ShouldCountDeath(bool isShop) { return !isShop; } internal static bool ShouldResetForGameOver(bool isArena) { return isArena; } internal static bool TryRecordDeath(Dictionary<string, int> counts, Dictionary<string, string> names, Dictionary<string, float> lastAcceptedDeathTime, string stableId, string playerName, float now, float duplicateWindowSeconds, out string key, out int newCount) { key = ResolvePlayerKey(stableId, playerName); newCount = 0; if (string.IsNullOrEmpty(key)) { return false; } if (duplicateWindowSeconds < 0f) { duplicateWindowSeconds = 0f; } if (lastAcceptedDeathTime.TryGetValue(key, out var value)) { float num = now - value; if (num >= 0f && num < duplicateWindowSeconds) { counts.TryGetValue(key, out newCount); return false; } } lastAcceptedDeathTime[key] = now; counts.TryGetValue(key, out var value2); if (value2 < 0) { value2 = 0; } newCount = ((value2 == int.MaxValue) ? int.MaxValue : (value2 + 1)); counts[key] = newCount; if (!string.IsNullOrWhiteSpace(playerName)) { names[key] = CleanTsvField(playerName).Trim(); } return true; } internal static string ResolvePlayerKey(string stableId, string playerName) { if (!string.IsNullOrWhiteSpace(stableId)) { return CleanTsvField(stableId).Trim(); } if (!string.IsNullOrWhiteSpace(playerName)) { return "name:" + CleanTsvField(playerName).Trim(); } return ""; } internal static List<KeyValuePair<string, int>> BuildDisplayEntries(Dictionary<string, int> counts, Dictionary<string, string> visiblePlayers) { List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(counts.Count + visiblePlayers.Count); foreach (KeyValuePair<string, int> count in counts) { if (!string.IsNullOrWhiteSpace(count.Key) && count.Value >= 0) { list.Add(count); } } foreach (KeyValuePair<string, string> visiblePlayer in visiblePlayers) { if (!string.IsNullOrWhiteSpace(visiblePlayer.Key) && !counts.ContainsKey(visiblePlayer.Key)) { list.Add(new KeyValuePair<string, int>(visiblePlayer.Key, 0)); } } return list; } internal static string SanitizeFileName(string value, char[] invalidCharacters) { string text = value ?? ""; foreach (char oldChar in invalidCharacters) { text = text.Replace(oldChar, '_'); } if (!string.IsNullOrWhiteSpace(text)) { return text; } return "_"; } internal static void BuildSnapshot(Dictionary<string, int> counts, Dictionary<string, string> names, out string[] ids, out int[] deathCounts, out string[] playerNames) { List<string> list = new List<string>(); foreach (KeyValuePair<string, int> count in counts) { if (!string.IsNullOrWhiteSpace(count.Key) && count.Value >= 0) { list.Add(count.Key); } } list.Sort(StringComparer.Ordinal); ids = new string[list.Count]; deathCounts = new int[list.Count]; playerNames = new string[list.Count]; for (int i = 0; i < list.Count; i++) { string text = list[i]; ids[i] = text; deathCounts[i] = counts[text]; playerNames[i] = (names.TryGetValue(text, out string value) ? value : ""); } } internal static void ApplySnapshot(string[] ids, int[] deathCounts, string[] playerNames, Dictionary<string, int> counts, Dictionary<string, string> names) { counts.Clear(); names.Clear(); int num = Math.Min(ids.Length, deathCounts.Length); for (int i = 0; i < num; i++) { string text = ids[i]; int num2 = deathCounts[i]; if (!string.IsNullOrWhiteSpace(text) && num2 >= 0) { counts[text] = num2; if (i < playerNames.Length && !string.IsNullOrWhiteSpace(playerNames[i])) { names[text] = playerNames[i]; } } } } internal static void CalculateOverlayPage(int itemCount, int rowsPerColumn, int maxColumns, int requestedPage, out int pageIndex, out int pageCount, out int startIndex, out int visibleCount, out int visibleColumns) { itemCount = Math.Max(0, itemCount); rowsPerColumn = Math.Max(1, rowsPerColumn); maxColumns = Math.Max(1, maxColumns); long num = (long)rowsPerColumn * (long)maxColumns; int num2 = (int)((num > int.MaxValue) ? int.MaxValue : num); pageCount = (int)((itemCount == 0) ? 1 : (((long)itemCount + (long)num2 - 1) / num2)); pageIndex = requestedPage % pageCount; if (pageIndex < 0) { pageIndex += pageCount; } long num3 = (long)pageIndex * (long)num2; startIndex = (int)((num3 > int.MaxValue) ? int.MaxValue : num3); visibleCount = Math.Min(num2, Math.Max(0, itemCount - startIndex)); visibleColumns = Math.Max(1, (visibleCount + rowsPerColumn - 1) / rowsPerColumn); } internal static string Serialize(Dictionary<string, int> counts, Dictionary<string, string> names) { List<string> list = new List<string>(counts.Keys); list.Sort(StringComparer.Ordinal); StringBuilder stringBuilder = new StringBuilder(); foreach (string item in list) { if (counts.TryGetValue(item, out var value) && value >= 0) { string value2 = CleanTsvField(item).Trim(); if (!string.IsNullOrEmpty(value2)) { string value4; string value3 = (names.TryGetValue(item, out value4) ? CleanTsvField(value4).Trim() : ""); stringBuilder.Append(value2).Append('\t').Append(value.ToString(CultureInfo.InvariantCulture)) .Append('\t') .Append(value3) .Append('\n'); } } } return stringBuilder.ToString(); } internal static void Deserialize(string contents, Dictionary<string, int> counts, Dictionary<string, string> names) { counts.Clear(); names.Clear(); if (string.IsNullOrEmpty(contents)) { return; } using StringReader stringReader = new StringReader(contents); string text; while ((text = stringReader.ReadLine()) != null) { if (string.IsNullOrWhiteSpace(text)) { continue; } string[] array = text.Split(new char[1] { '\t' }); if (array.Length < 2 || string.IsNullOrWhiteSpace(array[0]) || !int.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0) { continue; } string text2 = CleanTsvField(array[0]).Trim(); if (!string.IsNullOrEmpty(text2)) { counts[text2] = result; if (array.Length >= 3 && !string.IsNullOrWhiteSpace(array[2])) { names[text2] = CleanTsvField(array[2]).Trim(); } } } } private static string CleanTsvField(string? value) { return (value ?? "").Replace('\t', ' ').Replace('\n', ' ').Replace('\r', ' '); } } internal sealed class DeathCounterOverlay : MonoBehaviour { private sealed class RowView { internal GameObject Root; internal Image Background; internal Image SelfBar; internal Image Badge; internal Text Name; internal Text Count; } private const float Margin = 20f; private const float TruckHudSafeTop = 100f; private const float Padding = 12f; private const float ColumnGap = 8f; private const float RowGap = 4f; private const float PageSeconds = 8f; private const int PreferredRowsPerColumn = 10; private const int MaxColumnsPerPage = 2; private readonly List<RowView> rows = new List<RowView>(); private Canvas? canvas; private RectTransform? panel; private Image? panelImage; private Image? headerImage; private Image? accentImage; private Image? totalImage; private Image? emptyImage; private Image? dividerImage; private Text? titleText; private Text? subtitleText; private Text? totalText; private Text? emptyText; private Text? pageText; private Texture2D? pixel; private Sprite? sprite; private Font? font; private float nextPoll; private ulong lastSignature; private bool hasSignature; private static float TopMargin { get { if (Screen.height < 620) { return 20f; } return 100f; } } private void Awake() { CreateUi(); } private void Update() { if (Time.unscaledTime < nextPoll) { return; } nextPoll = Time.unscaledTime + 0.1f; try { bool flag = Plugin.showOverlay.Value && Plugin.IsInTruckLobby(); if ((Object)(object)canvas == (Object)null) { CreateUi(); } if ((Object)(object)canvas == (Object)null) { return; } if (!flag) { ((Behaviour)canvas).enabled = false; hasSignature = false; return; } ((Behaviour)canvas).enabled = true; ulong num = Signature(); if (!hasSignature || num != lastSignature) { Render(); lastSignature = num; hasSignature = true; } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Scoreboard refresh failed: " + ex); if ((Object)(object)canvas != (Object)null) { ((Behaviour)canvas).enabled = false; } hasSignature = false; nextPoll = Time.unscaledTime + 3f; } } private ulong Signature() { ulong hash = 1469598103934665603uL; Add(Screen.width); Add(Screen.height); GetPageCapacity(out var rowsPerColumn, out var maxColumns); Add((Plugin.DeathCountsBySteamId.Count > rowsPerColumn * maxColumns) ? Mathf.FloorToInt(Time.unscaledTime / 8f) : 0); Add((int)Plugin.overlayCorner.Value); Add((int)Plugin.sortMode.Value); Add(Plugin.titleFontSize.Value); Add(Plugin.itemFontSize.Value); Add(Plugin.showTotal.Value ? 1 : 0); Add(Plugin.highlightSelf.Value ? 1 : 0); AddString(Plugin.titleColorHex.Value); AddString(Plugin.itemColorHex.Value); AddString(Plugin.selfColorHex.Value); AddString(Plugin.GetLocalSteamId()); Add(Plugin.DeathCountsBySteamId.Count); foreach (KeyValuePair<string, int> item in Plugin.DeathCountsBySteamId) { AddString(item.Key); Add(item.Value); Plugin.PlayerNamesBySteamId.TryGetValue(item.Key, out string value); AddString(value); } return hash; void Add(int num) { hash = (hash ^ (uint)num) * 1099511628211L; } void AddString(string? text) { if (text == null) { Add(-1); } else { for (int i = 0; i < text.Length; i++) { Add(text[i]); } Add(0); } } } private void CreateUi() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_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_0060: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)canvas != (Object)null)) { font = Resources.GetBuiltinResource<Font>("Arial.ttf"); if ((Object)(object)font == (Object)null) { throw new InvalidOperationException("Unity built-in Arial font unavailable"); } pixel = new Texture2D(1, 1, (TextureFormat)4, false) { name = "DeathCounter shared UI pixel", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; pixel.SetPixel(0, 0, Color.white); pixel.Apply(false, true); sprite = Sprite.Create(pixel, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); ((Object)sprite).name = "DeathCounter shared UI sprite"; GameObject val = new GameObject("DeathCounter Canvas", new Type[2] { typeof(RectTransform), typeof(Canvas) }); val.transform.SetParent(((Component)this).transform, false); canvas = val.GetComponent<Canvas>(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 32000; canvas.pixelPerfect = true; ((Behaviour)canvas).enabled = false; panelImage = MakeImage(val.transform, "Scoreboard panel", new Color(0.025f, 0.03f, 0.04f, 0.94f)); panel = ((Graphic)panelImage).rectTransform; accentImage = MakeImage((Transform)(object)panel, "Red accent", new Color(0.92f, 0.1f, 0.12f, 1f)); headerImage = MakeImage((Transform)(object)panel, "Header", new Color(0.065f, 0.075f, 0.095f, 0.98f)); titleText = MakeText((Transform)(object)panel, "Title", (TextAnchor)3, (FontStyle)1); subtitleText = MakeText((Transform)(object)panel, "Player count", (TextAnchor)3, (FontStyle)0); totalImage = MakeImage((Transform)(object)panel, "Total badge", new Color(0.48f, 0.045f, 0.065f, 0.96f)); totalText = MakeText(((Component)totalImage).transform, "Total text", (TextAnchor)4, (FontStyle)1); emptyImage = MakeImage((Transform)(object)panel, "Empty row", new Color(1f, 1f, 1f, 0.045f)); emptyText = MakeText(((Component)emptyImage).transform, "Empty text", (TextAnchor)4, (FontStyle)0); dividerImage = MakeImage((Transform)(object)panel, "Page divider", new Color(1f, 1f, 1f, 0.14f)); pageText = MakeText((Transform)(object)panel, "Page text", (TextAnchor)4, (FontStyle)0); } } private Image MakeImage(Transform parent, string name, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); component.sprite = sprite; component.type = (Type)0; ((Graphic)component).color = color; ((Graphic)component).raycastTarget = false; return component; } private Text MakeText(Transform parent, string name, TextAnchor alignment, FontStyle style = (FontStyle)0) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }); val.transform.SetParent(parent, false); Text component = val.GetComponent<Text>(); component.font = font; component.fontStyle = style; component.fontSize = 20; component.alignment = alignment; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; component.supportRichText = false; ((Graphic)component).raycastTarget = false; return component; } private RowView MakeRow() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Image val = MakeImage((Transform)(object)panel, "Player row", new Color(1f, 1f, 1f, 0.045f)); Image selfBar = MakeImage(((Component)val).transform, "Self marker", Color.yellow); Image val2 = MakeImage(((Component)val).transform, "Death badge", new Color(0.48f, 0.045f, 0.065f, 0.96f)); return new RowView { Root = ((Component)val).gameObject, Background = val, SelfBar = selfBar, Badge = val2, Name = MakeText(((Component)val).transform, "Player name", (TextAnchor)3, (FontStyle)0), Count = MakeText(((Component)val2).transform, "Death count", (TextAnchor)4, (FontStyle)1) }; } private static void GetPageCapacity(out int rowsPerColumn, out int maxColumns) { int num = Mathf.Clamp(Plugin.titleFontSize.Value, 6, 100); int num2 = Mathf.Clamp(Plugin.itemFontSize.Value, 6, 100); float num3 = Mathf.Max(30f, (float)num2 + 14f); float num4 = Mathf.Max(72f, (float)num + 46f); float num5 = (float)Screen.height - TopMargin - 20f - num4 - 52f; int num6 = Mathf.Max(1, Mathf.FloorToInt((num5 + 4f) / (num3 + 4f))); rowsPerColumn = Mathf.Min(10, num6); float num7 = Mathf.Max(180f, (float)Screen.width - 40f); int num8 = Mathf.Max(1, Mathf.FloorToInt((num7 - 24f + 8f) / 248f)); maxColumns = Mathf.Min(2, num8); } private void Render() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_0280: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0872: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_0726: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Unknown result type (might be due to invalid IL or missing references) //IL_0789: Unknown result type (might be due to invalid IL or missing references) List<(string, string, int)> list = Plugin.BuildSortedLines(); long num = 0L; foreach (var item in list) { num += item.Item3; } int num2 = Mathf.Clamp(Plugin.titleFontSize.Value, 6, 100); int num3 = Mathf.Clamp(Plugin.itemFontSize.Value, 6, 100); Color color = Plugin.ParseColor(Plugin.titleColorHex.Value, Color.red); Color val = Plugin.ParseColor(Plugin.itemColorHex.Value, Color.white); Color val2 = Plugin.ParseColor(Plugin.selfColorHex.Value, val); bool flag = Plugin.overlayCorner.Value == OverlayCorner.TopRight || Plugin.overlayCorner.Value == OverlayCorner.BottomRight; bool num4 = Plugin.overlayCorner.Value == OverlayCorner.BottomLeft || Plugin.overlayCorner.Value == OverlayCorner.BottomRight; float num5 = Mathf.Max(30f, (float)num3 + 14f); float num6 = Mathf.Max(72f, (float)num2 + 46f); float num7 = Mathf.Max(180f, (float)Screen.width - 40f); GetPageCapacity(out var rowsPerColumn, out var maxColumns); DeathCounterCore.CalculateOverlayPage(list.Count, rowsPerColumn, maxColumns, Mathf.FloorToInt(Time.unscaledTime / 8f), out var pageIndex, out var pageCount, out var startIndex, out var visibleCount, out var visibleColumns); float num8 = Mathf.Min(280f, (num7 - 24f - 8f * (float)(visibleColumns - 1)) / (float)visibleColumns); num8 = Mathf.Max(140f, num8); int num9 = ((list.Count == 0) ? 1 : Mathf.Max(1, Mathf.CeilToInt((float)visibleCount / (float)visibleColumns))); float num10 = ((list.Count == 0) ? 52f : ((float)num9 * num5 + (float)(num9 - 1) * 4f)); float num11 = ((pageCount > 1) ? 28f : 0f); float num12 = 24f + (float)visibleColumns * num8 + (float)(visibleColumns - 1) * 8f; float num13 = num6 + 8f + num10 + num11 + 12f; float num14 = (flag ? ((float)Screen.width - num12 - 20f) : 20f); float num15 = (num4 ? ((float)Screen.height - num13 - 20f) : TopMargin); SetRect(panel, Mathf.Max(4f, num14), Mathf.Max(4f, num15), num12, num13); ((Graphic)panelImage).color = new Color(0.025f, 0.03f, 0.04f, 0.94f); SetRect((Graphic)(object)accentImage, 0f, 0f, num12, 3f); SetRect((Graphic)(object)headerImage, 0f, 3f, num12, num6 - 3f); titleText.fontSize = num2; ((Graphic)titleText).color = color; titleText.text = "PLAYER DEATHS"; SetRect((Graphic)(object)titleText, 16f, 8f, num12 - 24f - 8f, (float)num2 + 8f); subtitleText.fontSize = Mathf.Clamp(num3 - 7, 9, 16); ((Graphic)subtitleText).color = new Color(0.75f, 0.78f, 0.83f, 1f); subtitleText.text = ((list.Count == 1) ? "1 PLAYER RECORDED" : (list.Count + " PLAYERS RECORDED")); float num16 = Mathf.Min(104f, num12 * 0.36f); SetRect((Graphic)(object)subtitleText, 16f, num6 - 29f, num12 - 24f - (Plugin.showTotal.Value ? (num16 + 12f) : 0f), 22f); ((Component)totalImage).gameObject.SetActive(Plugin.showTotal.Value); if (Plugin.showTotal.Value) { SetRect((Graphic)(object)totalImage, num12 - 12f - num16, num6 - 34f, num16, 25f); totalText.fontSize = Mathf.Clamp(num3 - 3, 10, 23); ((Graphic)totalText).color = Color.white; totalText.text = "TOTAL " + num; SetRect((Graphic)(object)totalText, 0f, 0f, num16, 25f); } float num17 = num6 + 8f; ((Component)emptyImage).gameObject.SetActive(list.Count == 0); if (list.Count == 0) { SetRect((Graphic)(object)emptyImage, 12f, num17, num8, num10); emptyText.fontSize = Mathf.Clamp(num3 - 2, 10, 28); ((Graphic)emptyText).color = new Color(val.r, val.g, val.b, 0.85f); emptyText.text = "NO DEATHS RECORDED"; SetRect((Graphic)(object)emptyText, 3f, 0f, num8 - 6f, num10); } while (rows.Count < visibleCount) { rows.Add(MakeRow()); } string localSteamId = Plugin.GetLocalSteamId(); for (int i = 0; i < rows.Count; i++) { RowView rowView = rows[i]; rowView.Root.SetActive(i < visibleCount); if (i < visibleCount) { int num18 = startIndex + i; (string, string, int) tuple = list[num18]; int num19 = i / num9; int num20 = i % num9; float x = 12f + (float)num19 * (num8 + 8f); float y = num17 + (float)num20 * (num5 + 4f); SetRect((Graphic)(object)rowView.Background, x, y, num8, num5); bool flag2 = Plugin.highlightSelf.Value && tuple.Item1 == localSteamId; ((Graphic)rowView.Background).color = (flag2 ? new Color(1f, 0.65f, 0.05f, 0.16f) : (((num18 & 1) == 0) ? new Color(1f, 1f, 1f, 0.045f) : new Color(1f, 1f, 1f, 0.075f))); ((Component)rowView.SelfBar).gameObject.SetActive(flag2); if (flag2) { ((Graphic)rowView.SelfBar).color = val2; SetRect((Graphic)(object)rowView.SelfBar, 0f, 0f, 3f, num5); } float num21 = Mathf.Clamp((float)num3 * 2.35f, 42f, 74f); SetRect((Graphic)(object)rowView.Badge, num8 - num21 - 8f, 5f, num21, num5 - 10f); rowView.Name.fontSize = num3; rowView.Name.fontStyle = (FontStyle)(flag2 ? 1 : 0); ((Graphic)rowView.Name).color = (flag2 ? val2 : val); float width = num8 - num21 - 28f; SetRect((Graphic)(object)rowView.Name, 12f, 0f, width, num5); rowView.Name.text = FitName(tuple.Item2, rowView.Name, width); rowView.Count.fontSize = num3; ((Graphic)rowView.Count).color = Color.white; rowView.Count.text = tuple.Item3.ToString(); SetRect((Graphic)(object)rowView.Count, 0f, 0f, num21, num5 - 10f); } } ((Component)dividerImage).gameObject.SetActive(pageCount > 1); ((Component)pageText).gameObject.SetActive(pageCount > 1); if (pageCount > 1) { float num22 = num17 + num10 + 7f; SetRect((Graphic)(object)dividerImage, 12f, num22, num12 - 24f, 1f); pageText.fontSize = Mathf.Clamp(num3 - 7, 9, 16); ((Graphic)pageText).color = new Color(0.75f, 0.78f, 0.83f, 1f); pageText.text = "PAGE " + (pageIndex + 1) + "/" + pageCount + " | PLAYERS " + (startIndex + 1) + "-" + (startIndex + visibleCount) + " OF " + list.Count; SetRect((Graphic)(object)pageText, 12f, num22 + 3f, num12 - 24f, 20f); } } private static string FitName(string name, Text label, float width) { if (string.IsNullOrEmpty(name)) { return "UNKNOWN PLAYER"; } label.text = name; if (label.preferredWidth <= width) { return name; } int num = name.Length; do { num--; label.text = name.Substring(0, num).TrimEnd(Array.Empty<char>()) + "..."; } while (num > 1 && label.preferredWidth > width); return label.text; } private static void SetRect(Graphic graphic, float x, float y, float width, float height) { SetRect(graphic.rectTransform, x, y, width, height); } private static void SetRect(RectTransform rect, float x, float y, float width, float height) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(x, 0f - y); rect.sizeDelta = new Vector2(width, height); } private void OnDestroy() { if ((Object)(object)sprite != (Object)null) { Object.Destroy((Object)(object)sprite); } if ((Object)(object)pixel != (Object)null) { Object.Destroy((Object)(object)pixel); } } } internal sealed class DeathCounterOverlayLite : MonoBehaviour { private const float Margin = 20f; private const float TruckHudSafeTop = 100f; private const float Padding = 12f; private const float ColumnGap = 8f; private const float RowGap = 4f; private const float PageSeconds = 8f; private const int PreferredRowsPerColumn = 10; private const int MaxColumnsPerPage = 2; private readonly Image[] columnBackground = (Image[])(object)new Image[2]; private readonly Image[] countBackground = (Image[])(object)new Image[2]; private readonly Image[] selfHighlight = (Image[])(object)new Image[2]; private readonly Text[] names = (Text[])(object)new Text[2]; private readonly Text[] counts = (Text[])(object)new Text[2]; private readonly Dictionary<(int Size, FontStyle Style), HashSet<char>> requestedGlyphs = new Dictionary<(int, FontStyle), HashSet<char>>(); private Canvas? canvas; private Image? panelImage; private Image? headerImage; private Image? awardImage; private Image? accentImage; private Image? totalImage; private Image? dividerImage; private Text? titleText; private Text? subtitleText; private Text? awardLinesText; private Text? totalText; private Text? pageText; private Font? font; private bool ownsFont; private Font? awardFont; private bool ownsAwardFont; private Font? totalFont; private bool ownsTotalFont; private Texture2D? pixel; private Sprite? sprite; private float nextPoll; private ulong lastSignature; private bool hasSignature; private bool followupRenderPending; private bool hotkeyVisible = true; private int renderedLineCount; private static float TopMargin { get { if (Screen.height < 620) { return 20f; } return 100f; } } private static bool HasAwards { get { if (Plugin.MvpInstalled && !string.IsNullOrEmpty(Plugin.LastLevelAwardName)) { if (string.IsNullOrEmpty(Plugin.LastMvpAward)) { return !string.IsNullOrEmpty(Plugin.LastReverseAward); } return true; } return false; } } private static float AwardHeight { get { if (HasAwards) { if (string.IsNullOrEmpty(Plugin.LastMvpRankings)) { if (string.IsNullOrEmpty(Plugin.LastMvpScoreDetails)) { return 74f; } return 90f; } return 110f; } return 0f; } } private void Awake() { CreateUi(); } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) try { KeyboardShortcut value = Plugin.toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { hotkeyVisible = !hotkeyVisible; hasSignature = false; nextPoll = 0f; } if (Time.unscaledTime < nextPoll) { return; } nextPoll = Time.unscaledTime + 0.5f; bool flag = Plugin.showOverlay.Value && hotkeyVisible && Plugin.IsInTruckLobby(); if ((Object)(object)canvas == (Object)null) { CreateUi(); } if ((Object)(object)canvas == (Object)null) { return; } if (((Behaviour)canvas).enabled != flag) { ((Behaviour)canvas).enabled = flag; } if (!flag) { hasSignature = false; followupRenderPending = false; return; } ulong num = Signature(); bool flag2 = !hasSignature || num != lastSignature; if (flag2 || followupRenderPending) { bool rebindText = followupRenderPending; followupRenderPending = false; Render(rebindText); lastSignature = num; hasSignature = true; if (flag2 && (Object)(object)font != (Object)null && font.dynamic) { followupRenderPending = true; nextPoll = Time.unscaledTime + 0.05f; } } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Compact scoreboard refresh failed: " + ex); if ((Object)(object)canvas != (Object)null) { ((Behaviour)canvas).enabled = false; } hasSignature = false; nextPoll = Time.unscaledTime + 3f; } } private ulong Signature() { ulong hash = 1469598103934665603uL; Add(Screen.width); Add(Screen.height); GetPageCapacity(out var rowsPerColumn, out var maxColumns); Add((renderedLineCount > rowsPerColumn * maxColumns) ? Mathf.FloorToInt(Time.unscaledTime / 8f) : 0); Add((int)Plugin.overlayCorner.Value); Add((int)Plugin.sortMode.Value); Add(Plugin.titleFontSize.Value); Add(Plugin.itemFontSize.Value); Add(Mathf.RoundToInt(Plugin.backgroundOpacity.Value * 1000f)); Add(Plugin.showTotal.Value ? 1 : 0); Add(Plugin.highlightSelf.Value ? 1 : 0); if (Plugin.MvpInstalled) { Add(Plugin.AwardRevision); } Add(Plugin.UiRevision); AddString(Plugin.titleColorHex.Value); AddString(Plugin.itemColorHex.Value); AddString(Plugin.selfColorHex.Value); AddString(Plugin.GetLocalSteamId()); return hash; void Add(int value) { hash = (hash ^ (uint)value) * 1099511628211L; } void AddString(string? value) { if (value == null) { Add(-1); } else { for (int i = 0; i < value.Length; i++) { Add(value[i]); } Add(0); } } } private static void GetPageCapacity(out int rowsPerColumn, out int maxColumns) { int num = Mathf.Clamp(Plugin.titleFontSize.Value, 6, 100); int num2 = Mathf.Clamp(Plugin.itemFontSize.Value, 6, 100); float num3 = Mathf.Max(30f, (float)num2 + 10f); float num4 = Mathf.Max(72f, (float)num + 46f); float awardHeight = AwardHeight; float num5 = (float)Screen.height - TopMargin - 20f - num4 - awardHeight - 74f; int num6 = Mathf.Max(1, Mathf.FloorToInt((num5 + 4f) / (num3 + 4f))); rowsPerColumn = Mathf.Min(10, num6); float num7 = Mathf.Max(180f, (float)Screen.width - 40f); int num8 = Mathf.Max(1, Mathf.FloorToInt((num7 - 24f + 8f) / 248f)); maxColumns = Mathf.Min(2, num8); } private void CreateUi() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)canvas != (Object)null) { return; } font = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial", "Yu Gothic UI", "Meiryo", "Liberation Sans" }, 20); ownsFont = (Object)(object)font != (Object)null; if ((Object)(object)font == (Object)null) { font = Resources.GetBuiltinResource<Font>("Arial.ttf"); } if ((Object)(object)font == (Object)null) { throw new InvalidOperationException("Unity built-in Arial font unavailable"); } pixel = new Texture2D(1, 1, (TextureFormat)4, false) { name = "DeathCounter compact UI pixel", filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; pixel.SetPixel(0, 0, Color.white); pixel.Apply(false, true); sprite = Sprite.Create(pixel, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f)); ((Object)sprite).name = "DeathCounter compact UI sprite"; GameObject val = new GameObject("DeathCounter Compact Canvas", new Type[2] { typeof(RectTransform), typeof(Canvas) }); val.transform.SetParent(((Component)this).transform, false); canvas = val.GetComponent<Canvas>(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 32000; canvas.pixelPerfect = false; ((Behaviour)canvas).enabled = false; panelImage = MakeImage(val.transform, "Scoreboard panel", new Color(0.025f, 0.03f, 0.04f, 0.94f)); accentImage = MakeImage(((Component)panelImage).transform, "Red accent", new Color(0.92f, 0.1f, 0.12f, 1f)); headerImage = MakeImage(((Component)panelImage).transform, "Header", new Color(0.065f, 0.075f, 0.095f, 0.98f)); if (Plugin.MvpInstalled) { awardImage = MakeImage(((Component)panelImage).transform, "Last level awards", new Color(0.12f, 0.11f, 0.085f, 0.98f)); awardLinesText = MakeText(((Component)awardImage).transform, "Last level award lines", (TextAnchor)0, (FontStyle)0); awardFont = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial", "Yu Gothic UI", "Meiryo", "Liberation Sans" }, 20); ownsAwardFont = (Object)(object)awardFont != (Object)null; if ((Object)(object)awardFont == (Object)null) { awardFont = font; } awardLinesText.font = awardFont; awardLinesText.supportRichText = true; } titleText = MakeText(((Component)panelImage).transform, "Title", (TextAnchor)3, (FontStyle)1); subtitleText = MakeText(((Component)panelImage).transform, "Player count", (TextAnchor)3, (FontStyle)0); totalImage = MakeImage(((Component)panelImage).transform, "Total badge", new Color(0.48f, 0.045f, 0.065f, 0.96f)); totalText = MakeText(((Component)totalImage).transform, "Total text", (TextAnchor)4, (FontStyle)1); totalFont = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial", "Yu Gothic UI", "Meiryo", "Liberation Sans" }, 20); ownsTotalFont = (Object)(object)totalFont != (Object)null; if ((Object)(object)totalFont == (Object)null) { totalFont = font; } totalText.font = totalFont; dividerImage = MakeImage(((Component)panelImage).transform, "Page divider", new Color(1f, 1f, 1f, 0.14f)); pageText = MakeText(((Component)panelImage).transform, "Page text", (TextAnchor)4, (FontStyle)0); for (int i = 0; i < 2; i++) { columnBackground[i] = MakeImage(((Component)panelImage).transform, "Player column " + i, new Color(1f, 1f, 1f, 0.055f)); selfHighlight[i] = MakeImage(((Component)columnBackground[i]).transform, "Self highlight " + i, new Color(1f, 0.65f, 0.05f, 0.13f)); countBackground[i] = MakeImage(((Component)columnBackground[i]).transform, "Count strip " + i, new Color(0.48f, 0.045f, 0.065f, 0.85f)); names[i] = MakeText(((Component)columnBackground[i]).transform, "Player names " + i, (TextAnchor)0, (FontStyle)0); counts[i] = MakeText(((Component)countBackground[i]).transform, "Death counts " + i, (TextAnchor)2, (FontStyle)1); names[i].supportRichText = true; counts[i].supportRichText = true; } } private Image MakeImage(Transform parent, string name, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); component.sprite = sprite; ((Graphic)component).color = color; ((Graphic)component).raycastTarget = false; return component; } private Text MakeText(Transform parent, string name, TextAnchor alignment, FontStyle style = (FontStyle)0) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }); val.transform.SetParent(parent, false); Text component = val.GetComponent<Text>(); component.font = font; component.fontStyle = style; component.fontSize = 20; component.alignment = alignment; component.horizontalOverflow = (HorizontalWrapMode)1; component.verticalOverflow = (VerticalWrapMode)0; ((Graphic)component).raycastTarget = false; return component; } private void Render(bool rebindText) { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_06b6: Unknown result type (might be due to invalid IL or missing references) //IL_06bb: Unknown result type (might be due to invalid IL or missing references) //IL_06bf: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_083d: Unknown result type (might be due to invalid IL or missing references) //IL_07a7: Unknown result type (might be due to invalid IL or missing references) //IL_0cbe: Unknown result type (might be due to invalid IL or missing references) //IL_0ad5: Unknown result type (might be due to invalid IL or missing references) //IL_0af4: Unknown result type (might be due to invalid IL or missing references) if (rebindText) { titleText.text = ""; subtitleText.text = ""; totalText.text = ""; pageText.text = ""; if ((Object)(object)awardLinesText != (Object)null) { awardLinesText.text = ""; } for (int i = 0; i < 2; i++) { names[i].text = ""; counts[i].text = ""; } } List<(string, string, int)> list = Plugin.BuildSortedLines(); renderedLineCount = list.Count; long num = 0L; foreach (var item in list) { num += item.Item3; } int num2 = Mathf.Clamp(Plugin.titleFontSize.Value, 6, 100); int num3 = Mathf.Clamp(Plugin.itemFontSize.Value, 6, 100); WarmGlyphs(list, num2, num3); Color color = Plugin.ParseColor(Plugin.titleColorHex.Value, Color.red); Color val = Plugin.ParseColor(Plugin.itemColorHex.Value, Color.white); Color val2 = Plugin.ParseColor(Plugin.selfColorHex.Value, val); bool flag = Plugin.overlayCorner.Value == OverlayCorner.TopRight || Plugin.overlayCorner.Value == OverlayCorner.BottomRight; bool num4 = Plugin.overlayCorner.Value == OverlayCorner.BottomLeft || Plugin.overlayCorner.Value == OverlayCorner.BottomRight; float num5 = Mathf.Max(30f, (float)num3 + 10f); float num6 = num5 + 4f; float num7 = Mathf.Max(72f, (float)num2 + 46f); float awardHeight = AwardHeight; float num8 = Mathf.Max(180f, (float)Screen.width - 40f); GetPageCapacity(out var rowsPerColumn, out var maxColumns); DeathCounterCore.CalculateOverlayPage(list.Count, rowsPerColumn, maxColumns, Mathf.FloorToInt(Time.unscaledTime / 8f), out var pageIndex, out var pageCount, out var startIndex, out var visibleCount, out var visibleColumns); float num9 = Mathf.Min(Plugin.MvpInstalled ? 440f : 280f, (num8 - 24f - 8f * (float)(visibleColumns - 1)) / (float)visibleColumns); num9 = Mathf.Max(140f, num9); int num10 = ((list.Count == 0) ? 1 : Mathf.Max(1, Mathf.CeilToInt((float)visibleCount / (float)visibleColumns))); float num11 = ((list.Count == 0) ? 52f : ((float)num10 * num6 + 18f)); float num12 = ((pageCount > 1) ? 28f : 0f); float num13 = 24f + (float)visibleColumns * num9 + (float)(visibleColumns - 1) * 8f; float num14 = num7 + awardHeight + 8f + num11 + num12 + 12f; float num15 = (flag ? ((float)Screen.width - num13 - 20f) : 20f); float num16 = (num4 ? ((float)Screen.height - num14 - 20f) : TopMargin); SetRect((Graphic)(object)panelImage, Mathf.Max(4f, num15), Mathf.Max(4f, num16), num13, num14); float num17 = Mathf.Clamp(Plugin.backgroundOpacity.Value, 0.55f, 0.95f); ((Graphic)panelImage).color = new Color(0.025f, 0.03f, 0.04f, num17); ((Graphic)headerImage).color = new Color(0.065f, 0.075f, 0.095f, Mathf.Min(0.95f, num17 + 0.06f)); SetRect((Graphic)(object)accentImage, 0f, 0f, num13, 3f); SetRect((Graphic)(object)headerImage, 0f, 3f, num13, num7 - 3f); if ((Object)(object)awardImage != (Object)null) { ((Component)awardImage).gameObject.SetActive(HasAwards); } if (HasAwards && (Object)(object)awardImage != (Object)null && (Object)(object)awardLinesText != (Object)null) { ((Graphic)awardImage).color = new Color(0.12f, 0.11f, 0.085f, Mathf.Min(0.95f, num17 + 0.04f)); SetRect((Graphic)(object)awardImage, 12f, num7 + 4f, num13 - 24f, awardHeight - 8f); float num18 = num13 - 24f - 16f; awardLinesText.fontSize = 14; ((Graphic)awardLinesText).color = Color.white; string text = FitName("LAST LEVEL / " + Plugin.LastLevelAwardName, awardLinesText, num18); string text2 = FitName(Plugin.LastMvpAward, awardLinesText, num18 * 14f / 17f); string text3 = (string.IsNullOrEmpty(Plugin.LastMvpScoreDetails) ? "" : FitName("TOP SCORES " + Plugin.LastMvpScoreDetails, awardLinesText, num18)); string text4 = FitName("NEXT " + Plugin.LastMvpRankings, awardLinesText, num18); string text5 = FitName(Plugin.LastReverseAward, awardLinesText, num18); awardLinesText.text = "<size=12><color=#C7CCD6>" + text + "</color></size>\n<size=17><color=#FFD64C><b>" + text2 + "</b></color></size>" + (string.IsNullOrEmpty(text3) ? "" : ("\n<size=13><color=#CDE0FF>" + text3 + "</color></size>")) + (string.IsNullOrEmpty(Plugin.LastMvpRankings) ? "" : ("\n<size=13><color=#C7CCD6>" + text4 + "</color></size>")) + "\n<size=14>" + text5 + "</size>"; SetRect((Graphic)(object)awardLinesText, 8f, 3f, num18, awardHeight - 15f); } titleText.fontSize = num2; ((Graphic)titleText).color = color; titleText.text = "PLAYER DEATHS"; SetRect((Graphic)(object)titleText, 16f, 8f, num13 - 24f - 8f, (float)num2 + 8f); subtitleText.fontSize = Mathf.Clamp(num3 - 7, 9, 16); ((Graphic)subtitleText).color = new Color(0.75f, 0.78f, 0.83f, 1f); Text? obj = subtitleText; string text6 = list.Count.ToString(); KeyboardShortcut value = Plugin.toggleKey.Value; obj.text = text6 + " PLAYERS | " + ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString().ToUpperInvariant() + " HIDE"; float num19 = Mathf.Min(104f, num13 * 0.36f); SetRect((Graphic)(object)subtitleText, 16f, num7 - 29f, num13 - 24f - (Plugin.showTotal.Value ? (num19 + 12f) : 0f), 22f); ((Component)totalImage).gameObject.SetActive(Plugin.showTotal.Value); if (Plugin.showTotal.Value) { SetRect((Graphic)(object)totalImage, num13 - 12f - num19, num7 - 34f, num19, 25f); totalText.fontSize = Mathf.Clamp(num3 - 3, 10, 23); ((Graphic)totalText).color = Color.white; totalText.text = "TOTAL " + num; SetRect((Graphic)(object)totalText, 0f, 0f, num19, 25f); } float num20 = num7 + awardHeight + 8f; StringBuilder[] array = new StringBuilder[2] { new StringBuilder(), new StringBuilder() }; StringBuilder[] array2 = new StringBuilder[2] { new StringBuilder(), new StringBuilder() }; int[] array3 = new int[2] { -1, -1 }; string localSteamId = Plugin.GetLocalSteamId(); string value2 = ColorUtility.ToHtmlStringRGB(val2); float num21 = Mathf.Clamp((float)num3 * 2.35f, 42f, 74f); float num22 = num9 - num21 - 28f; for (int j = 0; j < 2; j++) { names[j].fontSize = num3; } for (int k = 0; k < visibleCount; k++) { (string, string, int) tuple = list[startIndex + k]; int num23 = k / num10; int num24 = k % num10; if (num24 != 0) { array[num23].Append('\n'); array2[num23].Append('\n'); } bool flag2 = Plugin.highlightSelf.Value && tuple.Item1 == localSteamId; if (flag2) { array3[num23] = num24; } string value3 = FitName(tuple.Item2.Replace('<', '‹').Replace('>', '›'), names[num23], num22 - (flag2 ? 20f : 0f)); if (flag2) { array[num23].Append("<color=#").Append(value2).Append("><b>★ ") .Append(value3) .Append("</b></color>"); array2[num23].Append("<color=#").Append(value2).Append(">") .Append(tuple.Item3) .Append("</color>"); } else { array[num23].Append(value3); array2[num23].Append(tuple.Item3); } } for (int l = 0; l < 2; l++) { bool flag3 = l < visibleColumns; ((Component)columnBackground[l]).gameObject.SetActive(flag3); if (flag3) { float x = 12f + (float)l * (num9 + 8f); SetRect((Graphic)(object)columnBackground[l], x, num20, num9, num11); bool flag4 = list.Count > 0; ((Component)countBackground[l]).gameObject.SetActive(flag4); if (flag4) { SetRect((Graphic)(object)countBackground[l], num9 - num21 - 8f, 4f, num21, num11 - 8f); } bool flag5 = array3[l] >= 0; ((Component)selfHighlight[l]).gameObject.SetActive(flag5); if (flag5) { SetRect((Graphic)(object)selfHighlight[l], 0f, (float)array3[l] * num6, num9, num5); } names[l].fontSize = num3; ((Graphic)names[l]).color = val; counts[l].fontSize = num3; ((Graphic)counts[l]).color = Color.white; float num25 = Mathf.Max(1f, (float)font.lineHeight * (float)num3 / (float)Mathf.Max(1, font.fontSize)); float lineSpacing = num6 / num25; names[l].lineSpacing = lineSpacing; counts[l].lineSpacing = lineSpacing; names[l].text = (flag4 ? array[l].ToString() : "NO PLAYERS YET"); names[l].alignment = (TextAnchor)((!flag4) ? 4 : 0); counts[l].text = (flag4 ? array2[l].ToString() : ""); if (flag4) { SetRect((Graphic)(object)names[l], 12f, 6f, num22, num11 - 8f); SetRect((Graphic)(object)counts[l], 4f, 2f, num21 - 8f, num11 - 8f); } else { SetRect((Graphic)(object)names[l], 4f, 0f, num9 - 8f, num11); } } } ((Component)dividerImage).gameObject.SetActive(pageCount > 1); ((Component)pageText).gameObject.SetActive(pageCount > 1); if (pageCount > 1) { float num26 = num20 + num11 + 7f; SetRect((Graphic)(object)dividerImage, 12f, num26, num13 - 24f, 1f); pageText.fontSize = Mathf.Clamp(num3 - 7, 9, 16); ((Graphic)pageText).color = new Color(0.75f, 0.78f, 0.83f, 1f); pageText.text = "PAGE " + (pageIndex + 1) + "/" + pageCount + " | PLAYERS " + (startIndex + 1) + "-" + (startIndex + visibleCount) + " OF " + list.Count; SetRect((Graphic)(object)pageText, 12f, num26 + 3f, num13 - 24f, 20f); } ((Graphic)titleText).SetAllDirty(); ((Graphic)subtitleText).SetAllDirty(); ((Graphic)totalText).SetAllDirty(); if (HasAwards && (Object)(object)awardLinesText != (Object)null) { ((Graphic)awardLinesText).SetAllDirty(); } for (int m = 0; m < visibleColumns; m++) { ((Graphic)names[m]).SetAllDirty(); ((Graphic)counts[m]).SetAllDirty(); } if (pageCount > 1) { ((Graphic)pageText).SetAllDirty(); } } private static string FitName(string name, Text label, float width) { if (string.IsNullOrEmpty(name)) { return "UNKNOWN PLAYER"; } label.text = name; if (label.preferredWidth <= width) { return name; } int num = name.Length; do { num--; label.text = name.Substring(0, num).TrimEnd(Array.Empty<char>()) + "..."; } while (num > 1 && label.preferredWidth > width); return label.text; } private void WarmGlyphs(List<(string SteamId, string Name, int Deaths)> lines, int titleSize, int itemSize) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)font == (Object)null || !font.dynamic) { return; } StringBuilder stringBuilder = new StringBuilder("★ ... ‹› 0123456789"); foreach (var line in lines) { stringBuilder.Append(' ').Append(line.Name); } string characters = stringBuilder.ToString(); string text = "LAST LEVEL / TOP SCORES NEXT MVP OOPS CHAMP PTS SETBACK " + Plugin.LastLevelAwardName + Plugin.LastMvpAward + Plugin.LastReverseAward + Plugin.LastMvpScoreDetails + Plugin.LastMvpRankings; RequestNewGlyphs(characters, itemSize, (FontStyle)0); RequestNewGlyphs(characters, itemSize, (FontStyle)1); if (HasAwards) { Font? obj = awardFont ?? font; obj.RequestCharactersInTexture(text, 12, (FontStyle)0); obj.RequestCharactersInTexture(text, 13, (FontStyle)0); obj.RequestCharactersInTexture(text, 14, (FontStyle)0); obj.RequestCharactersInTexture(text, 17, (FontStyle)1); } RequestNewGlyphs("PLAYER DEATHS", titleSize, (FontStyle)1); KeyboardShortcut value = Plugin.toggleKey.Value; RequestNewGlyphs("0123456789 PLAYERS | " + ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString().ToUpperInvariant() + " HIDE", Mathf.Clamp(itemSize - 7, 9, 16), (FontStyle)0); (totalFont ?? font).RequestCharactersInTexture("TOTAL 0123456789", Mathf.Clamp(itemSize - 3, 10, 23), (FontStyle)1); } private void RequestNewGlyphs(string characters, int size, FontStyle style) { //IL_001f: 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) if ((Object)(object)font == (Object)null || !font.dynamic) { return; } (int, FontStyle) key = (size, style); if (!requestedGlyphs.TryGetValue(key, out HashSet<char> value)) { value = new HashSet<char>(); requestedGlyphs[key] = value; } StringBuilder stringBuilder = new StringBuilder(); HashSet<char> hashSet = new HashSet<char>(); string text = characters; foreach (char c in text) { if (!value.Contains(c) && hashSet.Add(c)) { stringBuilder.Append(c); } } if (stringBuilder.Length != 0) { string text2 = stringBuilder.ToString(); font.RequestCharactersInTexture(text2, size, style); text = text2; foreach (char item in text) { value.Add(item); } } } private static void SetRect(Graphic graphic, float x, float y, float width, float height) { SetRect(graphic.rectTransform, x, y, width, height); } private static void SetRect(RectTransform rect, float x, float y, float width, float height) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.anchorMax = val; rect.anchorMin = val; rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(x, 0f - y); rect.sizeDelta = new Vector2(width, height); } private void OnDestroy() { if ((Object)(object)sprite != (Object)null) { Object.Destroy((Object)(object)sprite); } if ((Object)(object)pixel != (Object)null) { Object.Destroy((Object)(object)pixel); } if (ownsTotalFont && (Object)(object)totalFont != (Object)null) { Object.Destroy((Object)(object)totalFont); } if (ownsAwardFont && (Object)(object)awardFont != (Object)null) { Object.Destroy((Object)(object)awardFont); } if (ownsFont && (Object)(object)font != (Object)null) { Object.Destroy((Object)(object)font); } } } internal sealed class DeathSyncBehaviour : MonoBehaviour, IInRoomCallbacks, IOnEventCallback { internal const byte DeathSyncEventCode = 77; internal const byte DeathReportEventCode = 78; private const float DuplicateWindowSeconds = 2f; private static MethodInfo? isMasterOrSpMethod; private static bool isMasterResolved; private static FieldInfo? statsInstanceField; private static FieldInfo? saveFileCurrentField; private static bool statsResolved; private static readonly Dictionary<string, float> LastAcceptedDeathTime = new Dictionary<string, float>(); private string? loadedSaveFile; private float pollTimer; private bool callbacksRegistered; private static string SaveDir => Path.Combine(Application.persistentDataPath, "MatsuDeathCounter"); private void OnDestroy() { if (callbacksRegistered) { try { PhotonNetwork.RemoveCallbackTarget((object)this); } catch { } callbacksRegistered = false; } } private void Update() { try { bool flag = false; try { flag = PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode; } catch { } if (flag && !callbacksRegistered) { try { PhotonNetwork.AddCallbackTarget((object)this); callbacksRegistered = true; } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] AddCallbackTarget failed: " + ex.Message); } } else if (!flag && callbacksRegistered) { try { PhotonNetwork.RemoveCallbackTarget((object)this); } catch { } callbacksRegistered = false; } pollTimer += Time.deltaTime; if (pollTimer < 1f) { return; } pollTimer = 0f; Plugin.RefreshVisiblePlayers(); if (!IsHost()) { return; } string saveFileCurrent = GetSaveFileCurrent(); if (!(saveFileCurrent == loadedSaveFile)) { loadedSaveFile = saveFileCurrent; Plugin.DeathCountsBySteamId.Clear(); Plugin.PlayerNamesBySteamId.Clear(); LastAcceptedDeathTime.Clear(); if (!string.IsNullOrEmpty(saveFileCurrent)) { LoadFromDisk(saveFileCurrent); BroadcastDeaths(); } Plugin.MarkUiDirty(); } } catch (Exception ex2) { Plugin.TrackerErr("[DeathCounter] Update error: " + ex2.Message); } } public void OnEvent(EventData photonEvent) { if (photonEvent.Code == 78) { if (IsHost()) { HandleDeathReport(photonEvent); } } else { if (photonEvent.Code != 77 || IsHost()) { return; } try { if (photonEvent.CustomData is object[] array && array.Length >= 3 && array[0] is string[] ids && array[1] is int[] deathCounts && array[2] is string[] playerNames) { DeathCounterCore.ApplySnapshot(ids, deathCounts, playerNames, Plugin.DeathCountsBySteamId, Plugin.PlayerNamesBySteamId); Plugin.MarkUiDirty(); } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Snapshot apply failed: " + ex.Message); } } } private static void HandleDeathReport(EventData photonEvent) { try { if (!(photonEvent.CustomData is int num) || num <= 0) { return; } PhotonView val = PhotonView.Find(num); if ((Object)(object)val == (Object)null || val.Owner == null || val.Owner.ActorNumber != photonEvent.Sender) { Plugin.TrackerErr("[DeathCounter] Rejected a death report whose sender did not own its avatar ViewID."); return; } Component component = ((Component)val).GetComponent("PlayerAvatar"); if ((Object)(object)component == (Object)null || !Plugin.TryGetPlayerIdentity(component, out string steamId, out string playerName, out int _)) { Plugin.TrackerErr("[DeathCounter] Rejected a death report without a resolvable PlayerAvatar identity."); } else { OnHostDeath(steamId, playerName, "player report"); } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Death report failed: " + ex.Message); } } public void OnPlayerEnteredRoom(Player newPlayer) { if (IsHost()) { BroadcastDeaths(); } } public void OnPlayerLeftRoom(Player otherPlayer) { } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } public void OnMasterClientSwitched(Player newMasterClient) { } internal static void ReportLocalDeath(string steamId, string playerName, int photonViewId) { //IL_0048: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown if (!DeathCounterCore.ShouldCountDeath(Plugin.IsInShop())) { return; } if (IsHost()) { OnHostDeath(steamId, playerName, "local host"); return; } try { if (!PhotonNetwork.InRoom || PhotonNetwork.OfflineMode || photonViewId <= 0) { Plugin.TrackerErr("[DeathCounter] Could not report a client death: no joined room or avatar ViewID. The host RPC fallback may still record it."); return; } PhotonNetwork.RaiseEvent((byte)78, (object)photonViewId, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Client death report failed: " + ex.Message); } } internal static void RecordRpcFallback(string steamId, string playerName, int photonViewId) { OnHostDeath(steamId, playerName, "RPC fallback"); } internal static void ResetTallyForGameOver() { Plugin.DeathCountsBySteamId.Clear(); Plugin.PlayerNamesBySteamId.Clear(); LastAcceptedDeathTime.Clear(); Plugin.MarkUiDirty(); if (IsHost()) { SaveToDisk(); BroadcastDeaths(); } } private static void OnHostDeath(string steamId, string playerName, string source) { if (!IsHost() || !DeathCounterCore.ShouldCountDeath(Plugin.IsInShop())) { return; } if (!DeathCounterCore.TryRecordDeath(Plugin.DeathCountsBySteamId, Plugin.PlayerNamesBySteamId, LastAcceptedDeathTime, steamId, playerName, Time.unscaledTime, 2f, out string key, out int newCount)) { if (!string.IsNullOrEmpty(key)) { Plugin.TrackerLog("[DeathCounter] Ignored duplicate death for " + key + " (" + source + ")."); } } else { Plugin.TrackerLog($"[DeathCounter] {(string.IsNullOrWhiteSpace(playerName) ? key : playerName)} died ({source}). Total: {newCount}"); Plugin.MarkUiDirty(); SaveToDisk(); BroadcastDeaths(); } } private static void BroadcastDeaths() { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown try { if (PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode) { PhotonNetwork.RaiseEvent((byte)77, (object)Pack(), new RaiseEventOptions { Receivers = (ReceiverGroup)0 }, SendOptions.SendReliable); } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Broadcast failed: " + ex.Message); } } private static object[] Pack() { DeathCounterCore.BuildSnapshot(Plugin.DeathCountsBySteamId, Plugin.PlayerNamesBySteamId, out string[] ids, out int[] deathCounts, out string[] playerNames); return new object[3] { ids, deathCounts, playerNames }; } private static string SavePathFor(string saveFile) { return Path.Combine(SaveDir, DeathCounterCore.SanitizeFileName(saveFile, Path.GetInvalidFileNameChars()) + ".tsv"); } internal static void SaveToDisk() { string saveFileCurrent = GetSaveFileCurrent(); if (string.IsNullOrEmpty(saveFileCurrent)) { return; } try { Directory.CreateDirectory(SaveDir); File.WriteAllText(SavePathFor(saveFileCurrent), DeathCounterCore.Serialize(Plugin.DeathCountsBySteamId, Plugin.PlayerNamesBySteamId)); } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Save failed: " + ex.Message); } } private static void LoadFromDisk(string saveFile) { try { string path = SavePathFor(saveFile); if (File.Exists(path)) { DeathCounterCore.Deserialize(File.ReadAllText(path), Plugin.DeathCountsBySteamId, Plugin.PlayerNamesBySteamId); } } catch (Exception ex) { Plugin.TrackerErr("[DeathCounter] Load failed: " + ex.Message); } } internal static bool IsHost() { if (!isMasterResolved) { Type type = AccessTools.TypeByName("SemiFunc"); isMasterOrSpMethod = ((type == null) ? null : AccessTools.Method(type, "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null)); isMasterResolved = true; } if (isMasterOrSpMethod != null) { try { return (bool)isMasterOrSpMethod.Invoke(null, null); } catch { } } try { return PhotonNetwork.OfflineMode || !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient; } catch { return true; } } private static string GetSaveFileCurrent() { if (!statsResolved) { Type type = AccessTools.TypeByName("StatsManager"); statsInstanceField = ((type == null) ? null : AccessTools.Field(type, "instance")); saveFileCurrentField = ((type == null) ? null : AccessTools.Field(type, "saveFileCurrent")); statsResolved = true; } try { object obj = statsInstanceField?.GetValue(null); return (saveFileCurrentField?.GetValue(obj) as string) ?? ""; } catch { return ""; } } } public enum OverlayCorner { TopRight, TopLeft, BottomRight, BottomLeft } public enum SortMode { DeathsAscending, DeathsDescending, NameAscending, NameDescending } [BepInPlugin("matsu.repo.deathcounter", "REPO Death Counter", "1.4.6")] public sealed class Plugin : BaseUnityPlugin { private const float OverlayMargin = 20f; private const float ColumnGap = 8f; private const float RowGap = 4f; private const float PanelPadding = 12f; private const float PageSeconds = 8f; private const int PreferredRowsPerColumn = 10; private const int MaximumColumnsPerPage = 4; public const string PluginGuid = "matsu.repo.deathcounter"; public const string PluginName = "REPO Death Counter"; public const string PluginVersion = "1.4.6"; private const string MvpPluginGuid = "matsu.repo.mvp"; internal static string LastLevelAwardName = ""; internal static string LastMvpAward = ""; internal static string LastReverseAward = ""; internal static string LastMvpScoreDetails = ""; internal static string LastMvpRankings = ""; internal static int AwardRevision; internal static int UiRevision; internal static ManualLogSource? Log; public static readonly Dictionary<string, int> DeathCountsBySteamId = new Dictionary<string, int>(); public static readonly Dictionary<string, string> PlayerNamesBySteamId = new Dictionary<string, string>(); internal static readonly Dictionary<string, string> VisiblePlayerNamesBySteamId = new Dictionary<string, string>(); internal static ConfigEntry<bool> showOverlay = null; internal static ConfigEntry<OverlayCorner> overlayCorner = null; internal static ConfigEntry<int> titleFontSize = null; internal static ConfigEntry<int> itemFontSize = null; internal static ConfigEntry<string> titleColorHex = null; internal static ConfigEntry<string> itemColorHex = null; internal static ConfigEntry<SortMode> sortMode = null; internal static ConfigEntry<bool> showTotal = null; internal static ConfigEntry<bool> highlightSelf = null; internal static ConfigEntry<string> selfColorHex = null; internal static ConfigEntry<float> backgroundOpacity = null; internal static ConfigEntry<KeyboardShortcut> toggleKey = null; private static GameObject? runtimeRoot; private static bool gameDirectorReflectionResolved; private static FieldInfo? gameDirectorInstanceField; private static FieldInfo? gameDirectorPlayerListField; private static bool runManagerReflectionResolved; private static FieldInfo? runManagerInstanceField; private static FieldInfo? runManagerLevelCurrentField; private static FieldInfo? runManagerLevelLobbyField; private static FieldInfo? runManagerLevelIsShopField; private static bool playerReflectionResolved; private static FieldInfo? playerAvatarInstanceField; private static FieldInfo? playerIsLocalField; private static FieldInfo? playerSteamIdField; private static FieldInfo? playerNameField; private static FieldInfo? playerPhotonViewField; private static FieldInfo? playerDeadSetField; private static bool shopReflectionResolved; private static MethodInfo? runIsShopMethod; private static bool gameOverReflectionResolved; private static MethodInfo? runIsArenaMethod; private Harmony harmony; private Texture2D? panelTexture; private Texture2D? headerTexture; private Texture2D? rowTexture; private Texture2D? alternateRowTexture; private Texture2D? selfRowTexture; private Texture2D? accentTexture; private Texture2D? countBadgeTexture; private Texture2D? dividerTexture; private Texture2D? solidTexture; internal static bool MvpInstalled { get; private set; } public static void SetLastLevelAwards(string levelName, string mvp, string reverse) { SetLastLevelAwardsDetailed(levelName, mvp, reverse, "", ""); } public static void SetLastLevelAwardsDetailed(string levelName, string mvp, string reverse, string scoreDetails, string rankings) { if (MvpInstalled) { levelName = TrimAward(levelName, 80); mvp = TrimAward(mvp, 160); reverse = TrimAward(reverse, 160); scoreDetails = TrimAward(scoreDetails, 160); rankings = TrimAward(rankings, 160); if (!(levelName == LastLevelAwardName) || !(mvp == LastMvpAward) || !(reverse == LastReverseAward) || !(scoreDetails == LastMvpScoreDetails) || !(rankings == LastMvpRankings)) { LastLevelAwardName = levelName; LastMvpAward = mvp; LastReverseAward = reverse; LastMvpScoreDetails = scoreDetails; LastMvpRankings = rankings; AwardRevision++; MarkUiDirty(); } } } internal static void MarkUiDirty() { UiRevision++; } private static string TrimAward(string? value, int maximum) { value = (value ?? "").Replace('\n', ' ').Replace('\r', ' ').Replace('<', '‹') .Replace('>', '›'); if (value.Length > maximum) { return value.Substring(0, maximum); } return value; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("matsu.repo.deathcounter"); showOverlay = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowOverlay", true, "Show the death-count overlay in the truck lobby."); overlayCorner = ((BaseUnityPlugin)this).Config.Bind<OverlayCorner>("Display", "Corner", OverlayCorner.TopRight, "Which screen corner the overlay is anchored to."); titleFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "TitleFontSize", 24, "Font size of the header."); itemFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "FontSize", 20, "Font size of each player line."); titleColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "TitleColorHex", "FF3333", "Header text color, hex RGB (for example FF3333). '#' is optional."); itemColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "TextColorHex", "FFFFFF", "Player-line text color, hex RGB (for example FFFFFF). '#' is optional."); sortMode = ((BaseUnityPlugin)this).Config.Bind<SortMode>("Display", "SortMode", SortMode.DeathsAscending, "List order. DeathsAscending puts the fewest deaths on top."); showTotal = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowTotal", true, "Show a total-deaths badge in the scoreboard header."); highlightSelf = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "HighlightSelf", true, "Draw your own row in a different color so it is easy to spot."); selfColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "SelfColorHex", "FFD700", "Your own row's text color, hex RGB. Only used when HighlightSelf is on."); backgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "BackgroundOpacity", 0.82f, "Truck scoreboard background opacity, from 0.55 (more transparent) to 0.95."); toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Display", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Press this key to show or hide the truck scoreboard for this session."); TryPatchPlayerMethod("PlayerDeath", "PlayerAvatar_PlayerDeath_Prefix", "primary local death reporter"); TryPatchPlayerMethod("PlayerDeathRPC", "PlayerDeathRpcPrefix", "host RPC fallback"); TryPatchRunManagerMethod("ResetProgress", "RunManager_ResetProgress_Postfix", "game-over tally reset"); SceneManager.sceneLoaded += OnInitialSceneLoaded; Log.LogInfo((object)"REPO Death Counter 1.4.6 loaded. BepInEx is the only required dependency."); } private static void OnInitialSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown SceneManager.sceneLoaded -= OnInitialSceneLoaded; MvpInstalled = Chainloader.PluginInfos.ContainsKey("matsu.repo.mvp"); if ((Object)(object)runtimeRoot == (Object)null) { runtimeRoot = new GameObject("REPO Death Counter Runtime"); Object.DontDestroyOnLoad((Object)(object)runtimeRoot); runtimeRoot.AddComponent<DeathSyncBehaviour>(); runtimeRoot.AddComponent<DeathCounterOverlayLite>(); } } private void TryPatchPlayerMethod(string methodName, string prefixName, string label) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("PlayerAvatar"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, methodName, (Type[])null, (Type[])null)); MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), prefixName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ManualLogSource? log = Log; if (log != null) { log.LogWarning((object)("[DeathCounter] PlayerAvatar." + methodName + " was not found; " + label + " is unavailable.")); } return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource? log2 = Log; if (log2 != null) { log2.LogInfo((object)("[DeathCounter] Patched PlayerAvatar." + methodName + " (" + label + ").")); } } catch (Exception arg) { ManualLogSource? log3 = Log; if (log3 != null) { log3.LogError((object)$"[DeathCounter] Failed to patch PlayerAvatar.{methodName} ({label}): {arg}"); } } } private void TryPatchRunManagerMethod(string methodName, string postfixName, string label) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("RunManager"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, methodName, (Type[])null, (Type[])null)); MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), postfixName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ManualLogSource? log = Log; if (log != null) { log.LogWarning((object)("[DeathCounter] RunManager." + methodName + " was not found; " + label + " is unavailable.")); } return; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource? log2 = Log; if (log2 != null) { log2.LogInfo((object)("[DeathCounter] Patched RunManager." + methodName + " (" + label + ").")); } } catch (Exception arg) { ManualLogSource? log3 = Log; if (log3 != null) { log3.LogError((object)$"[DeathCounter] Failed to patch RunManager.{methodName} ({label}): {arg}"); } } } private void DrawLegacyOverlay() { //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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Expected O, but got Unknown //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_04ef: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bb: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05d0: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Expected O, but got Unknown //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Expected O, but got Unknown //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Unknown result type (might be due to invalid IL or missing references) //IL_0638: Expected O, but got Unknown //IL_063f: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Expected O, but got Unknown //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0683: Unknown result type (might be due to invalid IL or missing references) //IL_0688: Unknown result type (might be due to invalid IL or missing references) //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06b6: Expected O, but got Unknown //IL_06bd: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Unknown result type (might be due to invalid IL or missing references) //IL_06c9: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Unknown result type (might be due to invalid IL or missing references) //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_0937: Unknown result type (might be due to invalid IL or missing references) //IL_0898: Unknown result type (might be due to invalid IL or missing references) //IL_08aa: Unknown result type (might be due to invalid IL or missing references) //IL_08af: Unknown result type (might be due to invalid IL or missing references) //IL_08b8: Expected O, but got Unknown //IL_08e2: Unknown result type (might be due to invalid IL or missing references) //IL_0807: Unknown result type (might be due to invalid IL or missing references) //IL_080c: Unknown result type (might be due to invalid IL or missing references) //IL_082f: Unknown result type (might be due to invalid IL or missing references) //IL_0795: Unknown result type (might be due to invalid IL or missing references) //IL_07a2: Unknown result type (might be due to invalid IL or missing references) //IL_07b4: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Unknown result type (might be due to invalid IL or missing references) if (!showOverlay.Value || !IsInTruckLobby()) { return; } EnsureUiTextures(); int num = Mathf.Clamp(titleFontSize.Value, 6, 100); int num2 = Mathf.Clamp(itemFontSize.Value, 6, 100); Color textColor = ParseColor(titleColorHex.Value, Color.red); Color val = ParseColor(itemColorHex.Value, Color.white); Color val2 = ParseColor(selfColorHex.Value, val); bool flag = overlayCorner.Value == OverlayCorner.TopRight || overlayCorner.Value == OverlayCorner.BottomRight; bool flag2 = overlayCorner.Value == OverlayCorner.BottomLeft || overlayCorner.Value == OverlayCorner.BottomRight; List<(string, string, int)> list = BuildSortedLines(); long num3 = 0L; foreach (var item in list) { num3 += item.Item3; } float num4 = Mathf.Max(30f, (float)num2 + 14f); float num5 = Mathf.Max(62f, (float)num + 36f); float num6 = Mathf.Max(180f, (float)Screen.width - 40f); float num7 = (float)Screen.height - 40f - num5 - 52f; int num8 = Mathf.Max(1, Mathf.FloorToInt((num7 + 4f) / (num4 + 4f))); int rowsPerColumn = Mathf.Min(10, num8); int num9 = Mathf.Max(1, Mathf.FloorToInt((num6 - 24f + 8f) / 248f)); int maxColumns = Mathf.Min(4, num9); int requestedPage = Mathf.FloorToInt(Time.unscaledTime / 8f); DeathCounterCore.CalculateOverlayPage(list.Count, rowsPerColumn, maxColumns, requestedPage, out var pageIndex, out var pageCount, out var startIndex, out var visibleCount, out var visibleColumns); float num10 = Mathf.Min(300f, (num6 - 24f - 8f * (float)(visibleColumns - 1)) / (float)visibleColumns); num10 = Mathf.Max(140f, num10); int num11 = ((list.Count == 0) ? 1 : Mathf.Max(1, Mathf.CeilToInt((float)visibleCount / (float)visibleColumns))); int num12 = ((list.Count == 0) ? 1 : num11); float num13 = ((list.Count == 0) ? 52f : ((float)num12 * num4 + (float)Mathf.Max(0, num12 - 1) * 4f)); float num14 = ((pageCount > 1) ? 28f : 0f); float num15 = 24f + (float)visibleColumns * num10 + (float)(visibleColumns - 1) * 8f; float num16 = num5 + 8f + num13 + num14 + 12f; float num17 = (flag ? ((float)Screen.width - num15 - 20f) : 20f); float num18 = (flag2 ? ((float)Screen.height - num16 - 20f) : 20f); num17 = Mathf.Max(4f, num17); num18 = Mathf.Max(4f, num18); Color color = GUI.color; GUI.color = Color.white; GUI.DrawTexture(new Rect(num17, num18, num15, num16), (Texture)(object)panelTexture); GUI.DrawTexture(new Rect(num17, num18, num15, 3f), (Texture)(object)accentTexture); GUI.DrawTexture(new Rect(num17, num18 + 3f, num15, num5 - 3f), (Texture)(object)headerTexture); GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = num, fontStyle = (FontStyle)1, alignment = (TextAnchor)3, clipping = (TextClipping)1, richText = false }; val3.normal.textColor = textColor; GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = Mathf.Clamp(num2 - 7, 9, 16), fontStyle = (FontStyle)0, alignment = (TextAnchor)3, clipping = (TextClipping)1, richText = false }; val4.normal.textColor = new Color(0.72f, 0.75f, 0.8f, 1f); float num19 = (showTotal.Value ? Mathf.Min(104f, num15 * 0.34f) : 0f); float num20 = num17 + num15 - 12f - num19 - (showTotal.Value ? 10f : 0f); GUI.Label(new Rect(num17 + 12f + 4f, num18 + 8f, num20 - num17 - 12f - 4f, (float)num + 8f), "PLAYER DEATHS", val3); string text = ((list.Count == 1) ? "1 PLAYER RECORDED" : $"{list.Count} PLAYERS RECORDED"); GUI.Label(new Rect(num17 + 12f + 4f, num18 + num5 - 25f, num20 - num17 - 12f - 4f, 18f), text, val4); if (showTotal.Value) { Rect val5 = new Rect(num17 + num15 - 12f - num19, num18 + 13f, num19, num5 - 23f); GUI.DrawTexture(val5, (Texture)(object)countBadgeTexture); GUIStyle val6 = new GUIStyle(GUI.skin.label) { fontSize = Mathf.Clamp(num2 - 2, 10, 28), fontStyle = (FontStyle)1, alignment = (TextAnchor)4, clipping = (TextClipping)1, richText = false }; val6.normal.textColor = Color.white; GUI.Label(val5, $"TOTAL {num3}", val6); } GUIStyle val7 = new GUIStyle(GUI.skin.label) { fontSize = num2, fontStyle = (FontStyle)0, alignment = (TextAnchor)3, clipping = (TextClipping)1, richText = false }; val7.normal.textColor = val; GUIStyle val8 = new GUIStyle(val7) { fontStyle = (FontStyle)1 }; val8.normal.textColor = val2; GUIStyle val9 = new GUIStyle(GUI.skin.label) { fontSize = num2, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, clipping = (TextClipping)1, richText = false }; val9.normal.textColor = Color.white; string text2 = (highlightSelf.Value ? GetLocalSteamId() : null); float num21 = num18 + num5 + 8f; if (list.Count == 0) { Rect val10 = new Rect(num17 + 12f, num21, num10, num13); GUI.DrawTexture(val10, (Texture)(object)rowTexture); GUIStyle val11 = new GUIStyle(val7) { fontSize = Mathf.Clamp(num2 - 2, 10, 28), alignment = (TextAnchor)4 }; val11.normal.textColor = new Color(val.r, val.g, val.b, 0.72f); GUI.Label(val10, "NO DEATHS RECORDED", val11); } else { Rect val12 = default(Rect); for (int i = 0; i < visibleCount; i++) { int num22 = startIndex + i; (string, string, int) tuple = list[num22]; int num23 = i / num11; int num24 = i % num11; float num25 = num17 + 12f + (float)num23 * (num10 + 8f); float num26 = num21 + (float)num24 * (num4 + 4f); ((Rect)(ref val12))..ctor(num25, num26, num10, num4); GUI.DrawTexture(val12, (Texture)(object)(((num22 & 1) == 0) ? rowTexture : alternateRowTexture)); bool flag3 = highlightSelf.Value && !string.IsNullOrEmpty(text2) && tuple.Item1 == text2; if (flag3) { GUI.DrawTexture(val12, (Texture)(object)selfRowTexture); GUI.color = val2; GUI.DrawTexture(new Rect(num25, num26, 3f, num4), (Texture)(object)solidTexture); GUI.color = Color.white; } float num27 = Mathf.Clamp((float)num2 * 2.35f, 42f, 74f); Rect val13 = new Rect(num25 + num10 - num27 - 8f, num26 + 5f, num27, num4 - 10f); GUI.DrawTexture(val13, (Texture)(object)countBadgeTexture); GUI.Label(new Rect(num25 + 12f, num26, num10 - num27 - 28f, num4), tuple.Item2, flag3 ? val8 : val7); GUI.Label(val13, tuple.Item3.ToString(), val9); } } if (pageCount > 1) { float num28 = num21 + num13 + 7f; GUI.DrawTexture(new Rect(num17 + 12f, num28, num15 - 24f, 1f), (Texture)(object)dividerTexture); GUIStyle val14 = new GUIStyle(val4) { alignment = (TextAnchor)4 }; int num29 = startIndex + 1; int num30 = startIndex + visibleCount; GUI.Label(new Rect(num17 + 12f, num28 + 3f, num15 - 24f, 20f), $"PAGE {pageIndex + 1}/{pageCount} | PLAYERS {num29}-{num30} OF {list.Count}", val14); } GUI.color = color; } private void EnsureUiTextures() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)panelTexture != (Object)null)) { panelTexture = CreateUiTexture("DeathCounter Panel", new Color(0.025f, 0.03f, 0.04f, 0.94f)); headerTexture = CreateUiTexture("DeathCounter Header", new Color(0.065f, 0.075f, 0.095f, 0.98f)); rowTexture = CreateUiTexture("DeathCounter Row", new Color(1f, 1f, 1f, 0.045f)); alternateRowTexture = CreateUiTexture("DeathCounter Alternate Row", new Color(1f, 1f, 1f, 0.075f)); selfRowTexture = CreateUiTexture("DeathCounter Self Row", new Color(1f, 0.65f, 0.05f, 0.14f)); accentTexture = CreateUiTexture("DeathCounter Accent", new Color(0.92f, 0.1f, 0.12f, 1f)); countBadgeTexture = CreateUiTexture("DeathCounter Count Badge", new Color(0.48f, 0.045f, 0.065f, 0.96f)); dividerTexture = CreateUiTexture("DeathCounter Divider", new Color(1f, 1f, 1f, 0.14f)); solidTexture = CreateUiTexture("DeathCounter Solid", Color.white); } } private static Texture2D CreateUiTexture(string textureName, Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { name = textureName, hideFlags = (HideFlags)61, filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; val.SetPixel(0, 0, color); val.Apply(false, true); return val; } internal static List<(string SteamId, string Name, int Deaths)> BuildSortedLines() { List<KeyValuePair<string, int>> list = DeathCounterCore.BuildDisplayEntries(DeathCountsBySteamId, VisiblePlayerNamesBySteamId); switch (sortMode.Value) { case SortMode.DeathsAscending: list.Sort(delegate(KeyValuePair<string, int> a, KeyValuePair<string, int> b) { int num = a.Value.CompareTo(b.Value); return (num == 0) ? string.Compare(NameOf(a.Key), NameOf(b.Key), StringComparison.OrdinalIgnoreCase) : num; }); break; case SortMode.DeathsDescending: list.Sort(delegate(KeyValuePair<string, int> a, KeyValuePair<string, int> b) { int num = b.Value.CompareTo(a.Value); return (num == 0) ? string.Compare(NameOf(a.Key), NameOf(b.Key), StringComparison.OrdinalIgnoreCase) : num; }); break; case SortMode.NameAscending: list.Sort(delegate(KeyValuePair<string, int> a, KeyValuePair<string, int> b) { int num = string.Compare(NameOf(a.Key), NameOf(b.Key), StringComparison.OrdinalIgnoreCase); return (num == 0) ? string.Compare(a.Key, b.Key, StringComparison.Ordinal) : num; }); break; case SortMode.NameDescending: list.Sort(delegate(KeyValuePair<string, int> a, KeyValuePair<string, int> b) { int num = string.Compare(NameOf(b.Key), NameOf(a.Key), StringComparison.OrdinalIgnoreCase); return (num == 0) ? string.Compare(a.Key, b.Key, StringComparison.Ordinal) : num; }); break; } List<(string, string, int)> list2 = new List<(string, string, int)>(list.Count); foreach (KeyValuePair<string, int> item in list) { list2.Add((item.Key, NameOf(item.Key), item.Value)); } return list2; } private static string NameOf(string steamId) { if (!VisiblePlayerNamesBySteamId.TryGetValue(steamId, out string value) || string.IsNullOrWhiteSpace(value)) { if (!PlayerNamesBySteamId.TryGetValue(steamId, out string value2) || string.IsNullOrWhiteSpace(value2)) { return steamId; } return value2; } return value; } internal static void RefreshVisiblePlayers() { try { if (!gameDirectorReflectionResolved) { Type type = AccessTools.TypeByName("GameDirector"); gameDirectorInstanceField = ((type == null) ? null : AccessTools.Field(type, "instance")); gameDirectorPlayerListField = ((type == null) ? null : AccessTools.Field(type, "PlayerList")); gameDirectorReflectionResolved = true; } Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); object obj = gameDirectorInstanceField?.GetValue(null); if (obj != null && gameDirectorPlayerListField?.GetValue(obj) is IEnumerable enumerable) { foreach (object item in enumerable) { if (item != null) { Object val = (Object)((item is Object) ? item : null); if ((val == null || Object.op_Implicit(val)) && TryGetPlayerIdentity(item, out string steamId, out string playerName, out int _)) { dictionary[steamId] = (string.IsNullOrWhiteSpace(playerName) ? steamId : playerName); } } } } if (dictionary.Count == VisiblePlayerNamesBySteamId.Count && dictionary.All((KeyValuePair<string, string> entry) => VisiblePlayerNamesBySteamId.TryGetValue(entry.Key, out string value) && value == entry.Value)) { return; } VisiblePlayerNamesBySteamId.Clear(); foreach (KeyValuePair<string, string> item2 in dictionary) { VisiblePlayerNamesBySteamId[item2.Key] = item2.Value; } MarkUiDirty(); } catch (Exception ex) { TrackerErr("[DeathCounter] Player roster refresh failed: " + ex.Message); } } internal static Color ParseColor(string hex, Color fallback) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(hex)) { return fallback; } if (!hex.StartsWith("#")) { hex = "#" + hex; } Color result = default(Color); if (!ColorUtility.TryParseHtmlString(hex, ref result)) { return fallback; } return result; } private static void ResolveRunManagerFields() { if (!runManagerReflectionResolved) { Type type = AccessTools.TypeByName("RunManager"); if (type != null) { runManagerInstanceField = AccessTools.Field(type, "instance"); runManagerLevelCurrentField = AccessTools.Field(type, "levelCurrent"); runManagerLevelLobbyField = AccessTools.Field(type, "levelLobby"); runManagerLevelIsShopField = AccessTools.Field(type, "levelIsShop"); } runManagerReflectionResolved = true; } } internal static bool IsInTruckLobby() { try { ResolveRunManagerFields(); object obj = runManagerInstanceField?.GetValue(null); object obj2 = runManagerLevelCurrentField?.GetValue(obj); object obj3 = runManagerLevelLobbyField?.GetValue(obj);