using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DamageMeter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1a4b418a85a702d93fc8d0d1426b9cb61c3f9c6d")]
[assembly: AssemblyProduct("DamageMeter")]
[assembly: AssemblyTitle("DamageMeter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace DamageMeter
{
public class Overlay : MonoBehaviour
{
private const float Width = 330f;
private GameObject canvasGo;
private GameObject panel;
private GameObject tab;
private TextMeshProUGUI spellsLabel;
private static UnityAction hideAct;
private static UnityAction showAct;
private static UnityAction spellsAct;
private RectTransform panelRt;
private RectTransform textRt;
private TextMeshProUGUI text;
private float nextRefresh;
private float nextErrorLog;
private string lastText = "";
private static readonly Dictionary<string, string> nameCache = new Dictionary<string, string>();
private static readonly Dictionary<ulong, string> playerNames = new Dictionary<ulong, string>();
private static readonly Dictionary<ulong, Color> playerColors = new Dictionary<ulong, Color>();
private static float nextNameScan;
private static PauseMenuManager pauseMenu;
private static float nextPauseLookup;
private const float HeaderHeight = 22f;
public Overlay(IntPtr ptr)
: base(ptr)
{
}
private static Color PlayerColor(ulong id, Color fallback)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (!playerColors.TryGetValue(id, out var value))
{
return fallback;
}
return value;
}
private void Update()
{
//IL_030b: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Expected O, but got Unknown
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
try
{
if (Pressed(Plugin.ToggleKey.Value))
{
Plugin.Visible.Value = !Plugin.Visible.Value;
}
if (Pressed(Plugin.DetailKey.Value))
{
Plugin.Detailed.Value = !Plugin.Detailed.Value;
}
if (Pressed(Plugin.ResetKey.Value))
{
Tracker.Reset();
}
if (Time.unscaledTime < nextRefresh)
{
return;
}
nextRefresh = Time.unscaledTime + 0.25f;
Tracker.HostTick();
bool flag = Plugin.Enabled.Value && (Tracker.Playing || (!Tracker.InRun && Tracker.HaveData && Plugin.KeepAfterRun.Value));
if (flag && !Plugin.ShowWhenSolo.Value && IsSolo())
{
flag = false;
}
if (flag && PauseMenuOpen())
{
flag = false;
}
bool flag2 = flag && Plugin.Visible.Value;
bool flag3 = flag && !Plugin.Visible.Value && Plugin.ShowTab.Value;
if (!flag2 && !flag3)
{
if ((Object)(object)panel != (Object)null && !((Il2CppObjectBase)panel).WasCollected && panel.activeSelf)
{
panel.SetActive(false);
}
if ((Object)(object)tab != (Object)null && !((Il2CppObjectBase)tab).WasCollected && tab.activeSelf)
{
tab.SetActive(false);
}
}
else
{
if (!Build())
{
return;
}
Place();
if (tab.activeSelf != flag3)
{
tab.SetActive(flag3);
}
if (!flag2)
{
if (panel.activeSelf)
{
panel.SetActive(false);
}
return;
}
((TMP_Text)spellsLabel).text = (Plugin.Detailed.Value ? "Spells: on" : "Spells: off");
string text = Compose();
if (text != lastText)
{
lastText = text;
((TMP_Text)this.text).text = text;
float num = 0f;
try
{
num = ((TMP_Text)this.text).GetPreferredValues(text, 310f, 0f).y;
}
catch
{
}
if (num <= 0f)
{
num = (float)text.Split('\n').Length * 18f;
}
panelRt.sizeDelta = new Vector2(330f, num + 16f + 22f);
textRt.sizeDelta = new Vector2(310f, num + 4f);
textRt.anchoredPosition = new Vector2(0f, -11f);
}
if (!panel.activeSelf)
{
panel.SetActive(true);
}
}
}
catch (Exception ex)
{
if (!(Time.unscaledTime < nextErrorLog))
{
nextErrorLog = Time.unscaledTime + 10f;
ManualLogSource log = Plugin.Log;
bool flag4 = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(9, 1, ref flag4);
if (flag4)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Overlay: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
}
}
private static bool PauseMenuOpen()
{
try
{
if (pauseMenu == null || ((Il2CppObjectBase)pauseMenu).WasCollected || (Object)(object)pauseMenu == (Object)null)
{
if (Time.unscaledTime < nextPauseLookup)
{
return false;
}
nextPauseLookup = Time.unscaledTime + 2f;
pauseMenu = Object.FindObjectOfType<PauseMenuManager>();
if ((Object)(object)pauseMenu == (Object)null)
{
return false;
}
}
GameObject pauseMenuPanel = pauseMenu.pauseMenuPanel;
return (Object)(object)pauseMenuPanel != (Object)null && pauseMenuPanel.activeInHierarchy;
}
catch
{
return false;
}
}
private static bool IsSolo()
{
try
{
NetworkManager singleton = NetworkManager.Singleton;
return (Object)(object)singleton == (Object)null || !singleton.IsListening || (singleton.IsServer && Tracker.ClientCount(singleton) <= 1);
}
catch
{
return true;
}
}
private static bool Pressed(string keyName)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
Keyboard current = Keyboard.current;
if (current == null || string.IsNullOrEmpty(keyName))
{
return false;
}
if (!Enum.TryParse<Key>(keyName, ignoreCase: true, out Key result) || (int)result == 0)
{
return false;
}
KeyControl val = current[result];
if (val != null)
{
return ((ButtonControl)val).wasPressedThisFrame;
}
return false;
}
private bool Build()
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Expected O, but got Unknown
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Expected O, but got Unknown
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
//IL_031a: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0353: 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_038b: Unknown result type (might be due to invalid IL or missing references)
//IL_0395: Expected O, but got Unknown
//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0423: Unknown result type (might be due to invalid IL or missing references)
//IL_044b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)panel != (Object)null && !((Il2CppObjectBase)panel).WasCollected && (Object)(object)panel != (Object)null)
{
return true;
}
TMP_FontAsset val = null;
try
{
TextMeshProUGUI val2 = Object.FindObjectOfType<TextMeshProUGUI>();
if ((Object)(object)val2 != (Object)null)
{
val = ((TMP_Text)val2).font;
}
if ((Object)(object)val == (Object)null)
{
val = TMP_Settings.defaultFontAsset;
}
}
catch
{
}
if ((Object)(object)val == (Object)null)
{
return false;
}
canvasGo = new GameObject("DamageMeter_Canvas");
Object.DontDestroyOnLoad((Object)(object)canvasGo);
Canvas obj2 = canvasGo.AddComponent<Canvas>();
obj2.renderMode = (RenderMode)0;
obj2.sortingOrder = 400;
CanvasScaler obj3 = canvasGo.AddComponent<CanvasScaler>();
obj3.uiScaleMode = (ScaleMode)1;
obj3.referenceResolution = new Vector2(1920f, 1080f);
obj3.matchWidthOrHeight = 0.5f;
canvasGo.AddComponent<GraphicRaycaster>();
if (hideAct == null)
{
hideAct = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
{
Plugin.Visible.Value = false;
});
}
if (showAct == null)
{
showAct = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
{
Plugin.Visible.Value = true;
});
}
if (spellsAct == null)
{
spellsAct = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
{
Plugin.Detailed.Value = !Plugin.Detailed.Value;
});
}
panel = new GameObject("Panel");
panelRt = panel.AddComponent<RectTransform>();
panel.transform.SetParent(canvasGo.transform, false);
Image obj4 = panel.AddComponent<Image>();
((Graphic)obj4).color = new Color(0.06f, 0.04f, 0.12f, Mathf.Clamp01(Plugin.BackgroundOpacity.Value));
((Graphic)obj4).raycastTarget = false;
GameObject val3 = new GameObject("Text");
textRt = val3.AddComponent<RectTransform>();
val3.transform.SetParent(panel.transform, false);
text = val3.AddComponent<TextMeshProUGUI>();
((TMP_Text)text).font = val;
((TMP_Text)text).fontSize = 15f;
((TMP_Text)text).alignment = (TextAlignmentOptions)257;
((TMP_Text)text).textWrappingMode = (TextWrappingModes)0;
((TMP_Text)text).overflowMode = (TextOverflowModes)0;
((TMP_Text)text).richText = true;
((Graphic)text).raycastTarget = false;
((Graphic)text).color = Color.white;
RectTransform obj5 = textRt;
RectTransform obj6 = textRt;
RectTransform obj7 = textRt;
Vector2 val4 = default(Vector2);
((Vector2)(ref val4))..ctor(0.5f, 0.5f);
obj7.pivot = val4;
Vector2 anchorMin = (obj6.anchorMax = val4);
obj5.anchorMin = anchorMin;
textRt.anchoredPosition = Vector2.zero;
spellsLabel = MakeButton(panel.transform, val, "Spells: on", new Vector2(-40f, -4f), new Vector2(92f, 20f), spellsAct, new Color(0.3f, 0.22f, 0.5f, 0.9f));
((TMP_Text)MakeButton(panel.transform, val, "Hide", new Vector2(-6f, -4f), new Vector2(30f, 20f), hideAct, new Color(0.5f, 0.2f, 0.25f, 0.9f))).text = "X";
tab = new GameObject("Tab");
RectTransform val6 = tab.AddComponent<RectTransform>();
tab.transform.SetParent(canvasGo.transform, false);
val6.sizeDelta = new Vector2(110f, 26f);
Image val7 = tab.AddComponent<Image>();
((Graphic)val7).color = new Color(0.06f, 0.04f, 0.12f, 0.85f);
Button obj8 = tab.AddComponent<Button>();
((Selectable)obj8).targetGraphic = (Graphic)(object)val7;
((UnityEvent)obj8.onClick).AddListener(showAct);
TextMeshProUGUI obj9 = new GameObject("Label").AddComponent<TextMeshProUGUI>();
((Transform)((TMP_Text)obj9).rectTransform).SetParent(tab.transform, false);
((TMP_Text)obj9).rectTransform.sizeDelta = val6.sizeDelta;
((TMP_Text)obj9).font = val;
((TMP_Text)obj9).fontSize = 14f;
((TMP_Text)obj9).alignment = (TextAlignmentOptions)514;
((Graphic)obj9).raycastTarget = false;
((TMP_Text)obj9).text = "<b>DAMAGE</b> show";
tab.SetActive(false);
lastText = "";
return true;
}
private static TextMeshProUGUI MakeButton(Transform parent, TMP_FontAsset font, string label, Vector2 pos, Vector2 size, UnityAction act, Color color)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: 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)
GameObject val = new GameObject("Button");
RectTransform obj = val.AddComponent<RectTransform>();
val.transform.SetParent(parent, false);
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(1f, 1f);
obj.pivot = val2;
Vector2 anchorMin = (obj.anchorMax = val2);
obj.anchorMin = anchorMin;
obj.anchoredPosition = pos;
obj.sizeDelta = size;
Image val4 = val.AddComponent<Image>();
((Graphic)val4).color = color;
Button obj2 = val.AddComponent<Button>();
((Selectable)obj2).targetGraphic = (Graphic)(object)val4;
((UnityEvent)obj2.onClick).AddListener(act);
TextMeshProUGUI obj3 = new GameObject("Label").AddComponent<TextMeshProUGUI>();
((Transform)((TMP_Text)obj3).rectTransform).SetParent(val.transform, false);
((TMP_Text)obj3).rectTransform.sizeDelta = size;
((TMP_Text)obj3).font = font;
((TMP_Text)obj3).fontSize = 12f;
((TMP_Text)obj3).alignment = (TextAlignmentOptions)514;
((Graphic)obj3).raycastTarget = false;
((TMP_Text)obj3).text = label;
return obj3;
}
private void Place()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Clamp(Plugin.Scale.Value, 0.5f, 2.5f);
((Transform)panelRt).localScale = new Vector3(num, num, 1f);
Vector2 val = (Vector2)(Plugin.Anchor.Value switch
{
"TopLeft" => new Vector2(0f, 1f),
"TopRight" => new Vector2(1f, 1f),
"Right" => new Vector2(1f, 0.5f),
"BottomLeft" => new Vector2(0f, 0f),
"BottomRight" => new Vector2(1f, 0f),
_ => new Vector2(0f, 0.5f),
});
RectTransform obj = panelRt;
RectTransform obj2 = panelRt;
Vector2 val2 = (panelRt.pivot = val);
Vector2 anchorMin = (obj2.anchorMax = val2);
obj.anchorMin = anchorMin;
float num2 = ((val.x < 0.5f) ? Plugin.OffsetX.Value : (0f - Plugin.OffsetX.Value));
float num3 = ((val.y > 0.5f) ? (0f - Plugin.OffsetY.Value) : ((val.y < 0.5f) ? Plugin.OffsetY.Value : Plugin.OffsetY.Value));
panelRt.anchoredPosition = new Vector2(num2, num3);
RectTransform component = tab.GetComponent<RectTransform>();
((Transform)component).localScale = ((Transform)panelRt).localScale;
val2 = (component.pivot = val);
anchorMin = (component.anchorMax = val2);
component.anchorMin = anchorMin;
component.anchoredPosition = new Vector2(num2, num3);
}
private string Compose()
{
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
List<Row> rows = Tracker.Rows;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("<b>DAMAGE</b><size=80%><color=#B8B0D0> ");
stringBuilder.Append(TimeText((Tracker.GameRunSeconds > 0f) ? Tracker.GameRunSeconds : Tracker.RunSeconds)).Append("</color></size>");
stringBuilder.Append("<pos=50%><size=80%><color=#B8B0D0>DPS<pos=70%>TOTAL<pos=89%>%</color></size>");
if (rows.Count == 0)
{
bool flag = false;
try
{
NetworkManager singleton = NetworkManager.Singleton;
flag = (Object)(object)singleton != (Object)null && singleton.IsListening && !singleton.IsServer;
}
catch
{
}
stringBuilder.Append("\n<size=85%><color=#B8B0D0>");
stringBuilder.Append((flag && Time.unscaledTime - Tracker.RunStartedUnscaled > 15f) ? "No numbers from the host yet. The host needs DamageMeter too." : "No damage yet.");
stringBuilder.Append("</color></size>");
return stringBuilder.ToString();
}
double num = 0.0;
foreach (Row item in rows)
{
num += item.Total;
}
bool value = Plugin.Detailed.Value;
int num2 = Mathf.Clamp(Plugin.MaxSpellsPerPlayer.Value, 1, 20);
foreach (Row item2 in rows)
{
string value2 = ColorUtility.ToHtmlStringRGB(Brighten(PlayerColor(item2.Id, item2.Color)));
stringBuilder.Append('\n');
stringBuilder.Append("<color=#").Append(value2).Append('>')
.Append(Trim(PlayerName(item2.Id), 16))
.Append("</color>");
stringBuilder.Append("<pos=50%>").Append(Short(item2.Dps));
stringBuilder.Append("<pos=70%>").Append(Short(item2.Total));
stringBuilder.Append("<pos=89%>").Append((num > 0.0) ? Math.Round(100.0 * item2.Total / num).ToString(CultureInfo.InvariantCulture) : "0");
if (!value)
{
continue;
}
int num3 = 0;
double num4 = 0.0;
foreach (KeyValuePair<int, double> source in item2.Sources)
{
if (num3 >= num2)
{
num4 += source.Value;
continue;
}
num3++;
stringBuilder.Append("\n<size=82%><color=#D8D2EA> ").Append(Trim(SourceName(source.Key), 20)).Append("</color>");
stringBuilder.Append("<pos=70%>").Append(Short(source.Value));
stringBuilder.Append("<pos=89%>").Append((item2.Total > 0.0) ? Math.Round(100.0 * source.Value / item2.Total).ToString(CultureInfo.InvariantCulture) : "0");
stringBuilder.Append("</size>");
}
if (num4 > 0.0)
{
stringBuilder.Append("\n<size=82%><color=#B8B0D0> other<pos=70%>").Append(Short(num4)).Append("</color></size>");
}
}
return stringBuilder.ToString();
}
private static Color Brighten(Color c)
{
//IL_0000: 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)
float num = default(float);
float num2 = default(float);
float num3 = default(float);
Color.RGBToHSV(c, ref num, ref num2, ref num3);
return Color.HSVToRGB(num, Mathf.Min(num2, 0.75f), Mathf.Max(num3, 0.85f));
}
private static string Trim(string s, int max)
{
if (s.Length > max)
{
return s.Substring(0, max - 1) + "…";
}
return s;
}
private static string TimeText(float seconds)
{
int num = Mathf.Max(0, Mathf.RoundToInt(seconds));
return $"{num / 60}:{num % 60:00}";
}
internal static string Short(double v)
{
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
if (v < 1000.0)
{
return Math.Round(v).ToString(invariantCulture);
}
if (v < 10000.0)
{
return (v / 1000.0).ToString("0.0", invariantCulture) + "k";
}
if (v < 1000000.0)
{
return Math.Round(v / 1000.0).ToString(invariantCulture) + "k";
}
if (v < 10000000.0)
{
return (v / 1000000.0).ToString("0.00", invariantCulture) + "M";
}
if (v < 1000000000.0)
{
return (v / 1000000.0).ToString("0.0", invariantCulture) + "M";
}
return (v / 1000000000.0).ToString("0.00", invariantCulture) + "B";
}
private static string PlayerName(ulong id)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: 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)
if (Time.unscaledTime >= nextNameScan || !playerNames.ContainsKey(id))
{
nextNameScan = Time.unscaledTime + 5f;
try
{
foreach (GameplayPlayerIdentity item in Object.FindObjectsOfType<GameplayPlayerIdentity>())
{
if ((Object)(object)item == (Object)null || !((NetworkBehaviour)item).IsSpawned)
{
continue;
}
string value = null;
try
{
value = item.GetDisplayName();
}
catch
{
}
if (!string.IsNullOrWhiteSpace(value))
{
playerNames[((NetworkBehaviour)item).OwnerClientId] = value;
}
try
{
Color playerColor = item.PlayerColor;
if (playerColor.a > 0.01f)
{
playerColors[((NetworkBehaviour)item).OwnerClientId] = playerColor;
}
}
catch
{
}
}
}
catch
{
}
}
if (!playerNames.TryGetValue(id, out var value2))
{
return $"Player {id + 1}";
}
return value2;
}
private static string SourceName(int key)
{
return key switch
{
-1 => "Infused tornado",
-2 => "Explosions",
-3 => "Other",
_ => SpellName(key),
};
}
private static string SpellName(int spell)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
string text;
try
{
text = ((object)(SpellType)spell/*cast due to .constrained prefix*/).ToString();
}
catch
{
text = spell.ToString(CultureInfo.InvariantCulture);
}
string text2 = "SpellName_" + text;
if (nameCache.TryGetValue(text2, out var value))
{
return value;
}
string text3 = null;
try
{
LocalizedStringDatabase stringDatabase = LocalizationSettings.StringDatabase;
if (stringDatabase != null)
{
text3 = stringDatabase.GetLocalizedString(TableEntryReference.op_Implicit(text2), (Locale)null, (FallbackBehavior)0, (Il2CppReferenceArray<Object>)null);
}
}
catch
{
}
if (!string.IsNullOrWhiteSpace(text3) && text3 != text2 && !text3.Contains("No translation found"))
{
nameCache[text2] = text3;
return text3;
}
return Pretty(text);
}
private static string Pretty(string id)
{
if (id == "Smg")
{
return "SMG";
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < id.Length; i++)
{
if (i > 0 && char.IsUpper(id[i]) && !char.IsUpper(id[i - 1]))
{
stringBuilder.Append(' ');
}
stringBuilder.Append(id[i]);
}
return stringBuilder.ToString();
}
}
[BepInPlugin("girthy_mods.DamageMeter", "DamageMeter", "1.1.1")]
public class Plugin : BasePlugin
{
public const string Guid = "girthy_mods.DamageMeter";
public const string Name = "DamageMeter";
public const string Version = "1.1.1";
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<bool> Visible;
internal static ConfigEntry<bool> ShowTab;
internal static ConfigEntry<bool> Detailed;
internal static ConfigEntry<bool> ShowWhenSolo;
internal static ConfigEntry<bool> KeepAfterRun;
internal static ConfigEntry<int> DpsWindowSeconds;
internal static ConfigEntry<int> MaxSpellsPerPlayer;
internal static ConfigEntry<string> ToggleKey;
internal static ConfigEntry<string> DetailKey;
internal static ConfigEntry<string> ResetKey;
internal static ConfigEntry<string> Anchor;
internal static ConfigEntry<float> OffsetX;
internal static ConfigEntry<float> OffsetY;
internal static ConfigEntry<float> Scale;
internal static ConfigEntry<float> BackgroundOpacity;
public override void Load()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Expected O, but got Unknown
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Expected O, but got Unknown
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Expected O, but got Unknown
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: Expected O, but got Unknown
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
//IL_02f6: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Count damage and show the meter.");
DpsWindowSeconds = ((BasePlugin)this).Config.Bind<int>("General", "DpsWindowSeconds", 10, new ConfigDescription("DPS is the damage of the last this-many seconds (game time, so shops and pauses don't count).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
Visible = ((BasePlugin)this).Config.Bind<bool>("Display", "Visible", true, "Show the meter (the toggle key flips this).");
ShowTab = ((BasePlugin)this).Config.Bind<bool>("Display", "ShowTabWhenHidden", true, "When the meter is hidden, leave a small DAMAGE tab you can click to bring it back.");
Detailed = ((BasePlugin)this).Config.Bind<bool>("Display", "ShowSpells", true, "Show each player's damage per spell (the detail key flips this).");
ShowWhenSolo = ((BasePlugin)this).Config.Bind<bool>("Display", "ShowWhenSolo", true, "Show the meter in single player too.");
KeepAfterRun = ((BasePlugin)this).Config.Bind<bool>("Display", "KeepAfterRun", true, "Keep showing the last run's numbers after it ends, until the next run starts.");
MaxSpellsPerPlayer = ((BasePlugin)this).Config.Bind<int>("Display", "MaxSpellsPerPlayer", 8, new ConfigDescription("Spell lines per player in the detailed view; the rest are summed as \"other\".", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
Anchor = ((BasePlugin)this).Config.Bind<string>("Display", "Position", "Left", new ConfigDescription("Screen edge or corner for the meter.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[6] { "Left", "Right", "TopLeft", "TopRight", "BottomLeft", "BottomRight" }), Array.Empty<object>()));
OffsetX = ((BasePlugin)this).Config.Bind<float>("Display", "OffsetX", 20f, "Distance from the left/right edge (at 1080p).");
OffsetY = ((BasePlugin)this).Config.Bind<float>("Display", "OffsetY", 60f, "Distance from the top/bottom edge, or up from the middle for Left/Right (at 1080p).");
Scale = ((BasePlugin)this).Config.Bind<float>("Display", "Scale", 1f, new ConfigDescription("Size of the meter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>()));
BackgroundOpacity = ((BasePlugin)this).Config.Bind<float>("Display", "BackgroundOpacity", 0.7f, new ConfigDescription("0 = no background.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
ToggleKey = ((BasePlugin)this).Config.Bind<string>("Keys", "ToggleKey", "F3", "Show or hide the meter (Unity Input System key name).");
DetailKey = ((BasePlugin)this).Config.Bind<string>("Keys", "SpellsKey", "F4", "Switch the per-spell lines on or off.");
ResetKey = ((BasePlugin)this).Config.Bind<string>("Keys", "ResetKey", "", "Optional key to reset the numbers mid-run (host). Empty = no key.");
new Harmony("girthy_mods.DamageMeter").PatchAll(typeof(Tracker));
((BasePlugin)this).AddComponent<Overlay>();
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DamageMeter");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.1.1");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ready.");
}
log.LogInfo(val);
}
}
internal sealed class Row
{
public ulong Id;
public Color Color = Color.white;
public double Total;
public double Dps;
public readonly List<KeyValuePair<int, double>> Sources = new List<KeyValuePair<int, double>>();
}
internal static class Sources
{
internal const int InfusedTornado = -1;
internal const int Explosions = -2;
internal const int Other = -3;
}
[HarmonyPatch]
internal static class Tracker
{
private sealed class Acc
{
public double Total;
public readonly float[] Buckets = new float[64];
public readonly int[] BucketSecond = new int[64];
public readonly Dictionary<int, double> BySource = new Dictionary<int, double>();
public Color Color = Color.white;
public bool HasColor;
}
private enum Kind : byte
{
None,
Player,
Spell,
Explosion,
Tornado
}
private const string MessageName = "girthy_mods.DamageMeter.Snapshot";
private static readonly Dictionary<ulong, Acc> acc = new Dictionary<ulong, Acc>();
private static float runStart = -1f;
private static float nextSend;
internal static List<Row> Rows = new List<Row>();
internal static float RunSeconds;
internal static bool HaveData;
internal static bool InRun;
internal static float RunStartedUnscaled;
private static HandleNamedMessageDelegate handler;
private static RunManager run;
private static readonly Dictionary<IntPtr, Kind> kinds = new Dictionary<IntPtr, Kind>();
private static int offClientId = -1;
private static int offSpell = -1;
private static int offOwner = -1;
private static int offTornado = -1;
private static float nextErrorLog;
internal static bool Playing
{
get
{
if (!InRun)
{
return false;
}
if (HaveData)
{
return true;
}
try
{
if (run == null || ((Il2CppObjectBase)run).WasCollected || (Object)(object)run == (Object)null)
{
run = Object.FindObjectOfType<RunManager>();
}
return (Object)(object)run != (Object)null && (run.runHasStarted || run.currentRunTimeInSeconds > 0f);
}
catch
{
return false;
}
}
}
internal static float GameRunSeconds
{
get
{
try
{
if (run != null && !((Il2CppObjectBase)run).WasCollected && (Object)(object)run != (Object)null)
{
return run.currentRunTimeInSeconds;
}
}
catch
{
}
return 0f;
}
}
[HarmonyPatch(typeof(RunManager), "OnNetworkSpawn")]
[HarmonyPostfix]
private static void RunSpawned()
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected O, but got Unknown
acc.Clear();
Rows = new List<Row>();
HaveData = false;
InRun = true;
runStart = Time.time;
RunSeconds = 0f;
RunStartedUnscaled = Time.unscaledTime;
try
{
NetworkManager singleton = NetworkManager.Singleton;
if ((Object)(object)singleton != (Object)null && !singleton.IsServer && singleton.CustomMessagingManager != null)
{
if (handler == null)
{
handler = DelegateSupport.ConvertDelegate<HandleNamedMessageDelegate>((Delegate)new Action<ulong, FastBufferReader>(OnSnapshot));
}
singleton.CustomMessagingManager.RegisterNamedMessageHandler("girthy_mods.DamageMeter.Snapshot", handler);
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(8, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Listen: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
}
[HarmonyPatch(typeof(RunManager), "OnDestroy")]
[HarmonyPostfix]
private static void RunDestroyed()
{
InRun = false;
run = null;
}
[HarmonyPatch(typeof(RunManager), "StartRunOnServerRpc")]
[HarmonyPrefix]
private static void StartRun_Prefix(RunManager __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
try
{
if ((int)((NetworkBehaviour)__instance).__rpc_exec_stage == 1)
{
Reset();
InRun = true;
RunStartedUnscaled = Time.unscaledTime;
}
}
catch
{
}
}
[HarmonyPatch(typeof(EnemyHealthContainer), "RecordDamageDealtToEnemy")]
[HarmonyPostfix]
private unsafe static void Record_Postfix(float amount, DamageInfo damageSource)
{
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Expected O, but got Unknown
try
{
if (!Plugin.Enabled.Value || amount <= 0f || float.IsNaN(amount) || float.IsInfinity(amount) || damageSource == null)
{
return;
}
IntPtr pointer = ((Il2CppObjectBase)damageSource).Pointer;
if (pointer == IntPtr.Zero)
{
return;
}
IntPtr intPtr = IL2CPP.il2cpp_object_get_class(pointer);
if (!kinds.TryGetValue(intPtr, out var value))
{
value = Classify(intPtr);
kinds[intPtr] = value;
}
if (value != Kind.None)
{
byte* ptr = (byte*)(void*)pointer;
ulong key;
int key2;
switch (value)
{
default:
return;
case Kind.Spell:
key = *(ulong*)(ptr + offClientId);
key2 = *(int*)(ptr + offSpell);
break;
case Kind.Player:
key = *(ulong*)(ptr + offClientId);
key2 = -3;
break;
case Kind.Explosion:
key = *(ulong*)(ptr + offOwner);
key2 = -2;
break;
case Kind.Tornado:
key = *(ulong*)(ptr + offTornado);
key2 = -1;
break;
}
if (!acc.TryGetValue(key, out var value2))
{
value2 = new Acc();
acc[key] = value2;
}
value2.Total += amount;
value2.BySource.TryGetValue(key2, out var value3);
value2.BySource[key2] = value3 + (double)amount;
int num = Mathf.FloorToInt(Time.time);
int num2 = num & 0x3F;
if (value2.BucketSecond[num2] != num)
{
value2.BucketSecond[num2] = num;
value2.Buckets[num2] = 0f;
}
value2.Buckets[num2] += amount;
}
}
catch (Exception ex)
{
if (!(Time.unscaledTime < nextErrorLog))
{
nextErrorLog = Time.unscaledTime + 10f;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Counting damage: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
}
}
private static Kind Classify(IntPtr klass)
{
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Expected O, but got Unknown
try
{
if (Is(klass, Il2CppClassPointerStore<PlayerSpellDamageInfo>.NativeClassPtr))
{
offClientId = ((offClientId >= 0) ? offClientId : Offset(klass, "<OwnerClientId>k__BackingField"));
offSpell = ((offSpell >= 0) ? offSpell : Offset(klass, "<Spell>k__BackingField"));
return (offClientId > 0 && offSpell > 0) ? Kind.Spell : Kind.None;
}
if (Is(klass, Il2CppClassPointerStore<PlayerDamageInfo>.NativeClassPtr))
{
offClientId = ((offClientId >= 0) ? offClientId : Offset(klass, "<OwnerClientId>k__BackingField"));
return (offClientId > 0) ? Kind.Player : Kind.None;
}
if (Is(klass, Il2CppClassPointerStore<PlayerExplosionDamageInfo>.NativeClassPtr))
{
offOwner = ((offOwner >= 0) ? offOwner : Offset(klass, "<OwnerClientId>k__BackingField"));
return (offOwner > 0) ? Kind.Explosion : Kind.None;
}
if (Is(klass, Il2CppClassPointerStore<InfusedTornadoDamageInfo>.NativeClassPtr))
{
offTornado = ((offTornado >= 0) ? offTornado : Offset(klass, "InfusedByPlayerId"));
return (offTornado > 0) ? Kind.Tornado : Kind.None;
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(19, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Damage type check: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
return Kind.None;
}
private static bool Is(IntPtr klass, IntPtr target)
{
if (target != IntPtr.Zero)
{
if (!(klass == target))
{
return IL2CPP.il2cpp_class_is_subclass_of(klass, target, false);
}
return true;
}
return false;
}
private static int Offset(IntPtr klass, string field)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
IntPtr intPtr = klass;
while (intPtr != IntPtr.Zero)
{
IntPtr intPtr2 = IL2CPP.il2cpp_class_get_field_from_name(intPtr, field);
if (intPtr2 != IntPtr.Zero)
{
return (int)IL2CPP.il2cpp_field_get_offset(intPtr2);
}
intPtr = IL2CPP.il2cpp_class_get_parent(intPtr);
}
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Field ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(field);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found; that kind of damage won't be counted.");
}
log.LogWarning(val);
return -1;
}
internal static void HostTick()
{
//IL_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_0290: Expected O, but got Unknown
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
NetworkManager singleton = NetworkManager.Singleton;
if (!((Object)(object)singleton != (Object)null) || !singleton.IsListening || !singleton.IsServer || !InRun)
{
return;
}
float time = Time.time;
RunSeconds = Mathf.Max(0f, time - runStart);
int num = Mathf.FloorToInt(time);
int num2 = Mathf.Clamp(Plugin.DpsWindowSeconds.Value, 1, 60);
float num3 = Mathf.Clamp(time - runStart, 0.5f, (float)num2);
List<Row> list = new List<Row>();
foreach (KeyValuePair<ulong, Acc> item in acc)
{
Acc value = item.Value;
double num4 = 0.0;
for (int i = 0; i < 64; i++)
{
if (value.BucketSecond[i] > num - num2 && value.BucketSecond[i] <= num)
{
num4 += (double)value.Buckets[i];
}
}
Row row = new Row
{
Id = item.Key,
Color = value.Color,
Total = value.Total,
Dps = num4 / (double)num3
};
foreach (KeyValuePair<int, double> item2 in value.BySource)
{
row.Sources.Add(new KeyValuePair<int, double>(item2.Key, item2.Value));
}
row.Sources.Sort((KeyValuePair<int, double> x, KeyValuePair<int, double> y) => y.Value.CompareTo(x.Value));
list.Add(row);
}
list.Sort((Row x, Row y) => y.Total.CompareTo(x.Total));
Rows = list;
HaveData = list.Count > 0;
if (Time.unscaledTime < nextSend)
{
return;
}
nextSend = Time.unscaledTime + 1f;
try
{
if (singleton.CustomMessagingManager == null || ClientCount(singleton) <= 1)
{
return;
}
string text = Serialize(list, RunSeconds);
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(text.Length * 2 + 64, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
singleton.CustomMessagingManager.SendNamedMessageToAll("girthy_mods.DamageMeter.Snapshot", val, (NetworkDelivery)4);
}
finally
{
((FastBufferWriter)(ref val)).Dispose();
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Sending damage: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log.LogError(val2);
}
}
private static string Serialize(List<Row> rows, float runSeconds)
{
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("1|").Append(Mathf.RoundToInt(runSeconds).ToString(invariantCulture));
foreach (Row row in rows)
{
stringBuilder.Append('|').Append(row.Id.ToString(invariantCulture)).Append(',')
.Append(ColorUtility.ToHtmlStringRGB(row.Color))
.Append(',')
.Append(Math.Round(row.Total).ToString(invariantCulture))
.Append(',')
.Append(Math.Round(row.Dps).ToString(invariantCulture))
.Append(',');
for (int i = 0; i < row.Sources.Count; i++)
{
if (i > 0)
{
stringBuilder.Append('/');
}
stringBuilder.Append(row.Sources[i].Key.ToString(invariantCulture)).Append(':').Append(Math.Round(row.Sources[i].Value).ToString(invariantCulture));
}
}
return stringBuilder.ToString();
}
private static void OnSnapshot(ulong sender, FastBufferReader reader)
{
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Expected O, but got Unknown
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
try
{
string text = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
string[] array = text.Split('|');
if (array.Length < 2 || array[0] != "1")
{
return;
}
RunSeconds = float.Parse(array[1], invariantCulture);
List<Row> list = new List<Row>();
for (int i = 2; i < array.Length; i++)
{
string[] array2 = array[i].Split(',');
if (array2.Length < 5)
{
continue;
}
Row row = new Row
{
Id = ulong.Parse(array2[0], invariantCulture),
Total = double.Parse(array2[2], invariantCulture),
Dps = double.Parse(array2[3], invariantCulture)
};
row.Color = ParseHex(array2[1]);
if (array2[4].Length > 0)
{
string[] array3 = array2[4].Split('/');
foreach (string text2 in array3)
{
int num = text2.IndexOf(':');
if (num > 0)
{
row.Sources.Add(new KeyValuePair<int, double>(int.Parse(text2.Substring(0, num), invariantCulture), double.Parse(text2.Substring(num + 1), invariantCulture)));
}
}
}
list.Add(row);
}
Rows = list;
HaveData = true;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Reading damage snapshot: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
private static Color ParseHex(string s)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
try
{
if (s == null || s.Length < 6)
{
return Color.white;
}
return new Color(H(0), H(2), H(4), 1f);
}
catch
{
return Color.white;
}
float H(int i)
{
return (float)int.Parse(s.Substring(i, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture) / 255f;
}
}
internal static int ClientCount(NetworkManager nm)
{
try
{
IReadOnlyList<ulong> connectedClientsIds = nm.ConnectedClientsIds;
List<ulong> val = ((connectedClientsIds != null) ? ((Il2CppObjectBase)connectedClientsIds).TryCast<List<ulong>>() : null);
if (val != null)
{
return val.Count;
}
}
catch
{
}
return 2;
}
internal static void Reset()
{
acc.Clear();
Rows = new List<Row>();
HaveData = false;
runStart = Time.time;
}
}
}