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 DpsMeter v0.6.0
plugins\DpsMeter\DpsMeter.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Collections.ObjectModel; 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.Configuration; using BepInEx.Logging; using DpsMeter.Net; using DpsMeter.Reporting; using DpsMeter.Tracking; using DpsMeter.Ui; using RoR2; using RoR2.Projectile; using RoR2.Skills; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DpsMeter")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("DpsMeter")] [assembly: AssemblyTitle("DpsMeter")] [assembly: AssemblyVersion("1.0.0.0")] namespace DpsMeter { [BepInPlugin("noctilucentgames.dpsmeter", "DPS Meter", "0.6.0")] public sealed class DpsMeterPlugin : BaseUnityPlugin { public const string Guid = "noctilucentgames.dpsmeter"; public const string Name = "DPS Meter"; public const string Version = "0.6.0"; internal static ManualLogSource Log; internal static readonly DamageTracker Tracker = new DamageTracker(); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; PluginConfig.Init(((BaseUnityPlugin)this).Config); ScopeStats.WindowSeconds = PluginConfig.WindowSeconds.Value; RoR2Application.isModded = true; GlobalEventManager.onServerDamageDealt += OnServerDamageDealt; Run.onRunStartGlobal += OnRunStart; BossGroup.onBossGroupStartServer += OnBossGroupStart; BossGroup.onBossGroupDefeatedServer += OnBossGroupEnd; Stage.onServerStageBegin += OnStageBegin; Run.onRunDestroyGlobal += OnRunEnd; SessionReport.Init(Log); InventoryWatcher.Subscribe(); InflictorMap.Load(); ((Component)this).gameObject.AddComponent<MeterNetwork>(); ((Component)this).gameObject.AddComponent<DpsPanel>(); ((Component)this).gameObject.AddComponent<DetailScreen>(); Log.LogInfo((object)$"inflictor map: {InflictorMap.Count} prefabs"); Log.LogInfo((object)"hooked onServerDamageDealt | F8 show/hide, F7 scope, F6 detail, F11 full screen, F9/F10 log dump"); } private void OnDestroy() { GlobalEventManager.onServerDamageDealt -= OnServerDamageDealt; Run.onRunStartGlobal -= OnRunStart; BossGroup.onBossGroupStartServer -= OnBossGroupStart; BossGroup.onBossGroupDefeatedServer -= OnBossGroupEnd; Stage.onServerStageBegin -= OnStageBegin; Run.onRunDestroyGlobal -= OnRunEnd; InventoryWatcher.Unsubscribe(); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(PluginConfig.DumpMobsKey.Value)) { Dump(DamageScope.Mobs); } else if (Input.GetKeyDown(PluginConfig.DumpBossKey.Value)) { Dump(DamageScope.TeleporterBoss); } } private static void OnBossGroupStart(BossGroup group) { bool flag = Tracker.IsEncounterContinuation(); Tracker.RegisterBossGroup(group); if (PluginConfig.ResetBossOnEncounter.Value && !flag) { Tracker.ResetScope(DamageScope.TeleporterBoss); } else if (flag) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)"boss group started as a continuation; keeping the numbers"); } } } private static void OnBossGroupEnd(BossGroup group) { Tracker.UnregisterBossGroup(group); if (PluginConfig.AutoReport.Value) { SessionReport.Write(Tracker, "Boss defeated on stage " + StageLabel()); } } private static void OnRunEnd(Run run) { if (PluginConfig.AutoReport.Value) { SessionReport.Write(Tracker, "Run ended on stage " + StageLabel()); } } private static void OnStageBegin(Stage stage) { if (PluginConfig.AutoReport.Value) { SessionReport.Write(Tracker, "Stage " + StageLabel() + " - entering next stage"); } if (PluginConfig.ResetMobsOnStage.Value) { Tracker.ResetScope(DamageScope.Mobs); } } private static string StageLabel() { Run instance = Run.instance; string text = (((Object)(object)instance != (Object)null) ? (instance.stageClearCount + 1).ToString() : "?"); Stage instance2 = Stage.instance; string text2 = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.sceneDef != (Object)null) ? instance2.sceneDef.cachedName : null); return string.IsNullOrEmpty(text2) ? text : (text + " (" + text2 + ")"); } private static void OnRunStart(Run run) { Tracker.Clear(); MeterNetwork.ResetForNewRun(); InventoryWatcher.Clear(); SessionReport.BeginRun(); } private static void OnServerDamageDealt(DamageReport report) { if (NetworkServer.active) { Tracker.Record(report); } } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CcDps(ConCommandArgs args) { DamageScope scope = ((((ConCommandArgs)(ref args)).Count > 0 && ((ConCommandArgs)(ref args))[0].StartsWith("boss", StringComparison.OrdinalIgnoreCase)) ? DamageScope.TeleporterBoss : DamageScope.Mobs); Dump(scope); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CcDpsReset(ConCommandArgs args) { Tracker.ResetAll(); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"reset"); } } internal static void Dump(DamageScope scope) { StringBuilder stringBuilder = new StringBuilder(); ReportBuilder.AppendScope(stringBuilder, Tracker, scope); ReportBuilder.AppendUnresolved(stringBuilder, Tracker); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)stringBuilder.ToString()); } } } public static class PluginConfig { public static ConfigEntry<KeyCode> ToggleKey; public static ConfigEntry<KeyCode> ScopeKey; public static ConfigEntry<KeyCode> DetailKey; public static ConfigEntry<KeyCode> ScreenKey; public static ConfigEntry<KeyCode> DumpMobsKey; public static ConfigEntry<KeyCode> DumpBossKey; public static ConfigEntry<bool> VisibleByDefault; public static ConfigEntry<bool> HideWithHud; public static ConfigEntry<bool> AutoScope; public static ConfigEntry<bool> ColorByMagnitude; public static ConfigEntry<bool> AvoidHudElements; public static ConfigEntry<int> NetMessageId; public static ConfigEntry<float> NetSendRate; public static ConfigEntry<bool> AutoReport; public static ConfigEntry<bool> ResetMobsOnStage; public static ConfigEntry<bool> ResetBossOnEncounter; public static ConfigEntry<float> WindowSeconds; public static ConfigEntry<float> PanelWidth; public static ConfigEntry<float> PanelMargin; public static ConfigEntry<int> MaxDetailRows; public static ConfigEntry<bool> AnchorRight; public static void Init(ConfigFile cfg) { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Expected O, but got Unknown ToggleKey = cfg.Bind<KeyCode>("Keys", "Toggle", (KeyCode)289, "Show or hide the meter."); ScopeKey = cfg.Bind<KeyCode>("Keys", "Scope", (KeyCode)288, "Switch between mobs and boss damage."); DetailKey = cfg.Bind<KeyCode>("Keys", "Detail", (KeyCode)287, "Expand or collapse the per-source breakdown."); ScreenKey = cfg.Bind<KeyCode>("Keys", "DetailScreen", (KeyCode)292, "Open the full-screen breakdown. While it is open the scope and detail keys switch mobs/boss and dealt/taken."); DumpMobsKey = cfg.Bind<KeyCode>("Keys", "DumpMobs", (KeyCode)290, "Write the mob breakdown to the log."); DumpBossKey = cfg.Bind<KeyCode>("Keys", "DumpBoss", (KeyCode)291, "Write the boss breakdown to the log."); VisibleByDefault = cfg.Bind<bool>("Display", "VisibleByDefault", true, "Show the meter as soon as a run starts."); AutoScope = cfg.Bind<bool>("Display", "AutoScope", true, "Switch to boss damage when a boss encounter starts, and back to mobs on a new stage. You can still switch manually at any time; the next transition takes over again."); ColorByMagnitude = cfg.Bind<bool>("Display", "ColorByMagnitude", true, "Tint numbers by magnitude - k green, M blue, B purple, T and beyond pink - so the scale registers before the text is read. Percentages are never tinted, since they are not magnitudes."); HideWithHud = cfg.Bind<bool>("Display", "HideWithHud", true, "Hide the meter whenever the game hides its own HUD - cutscenes, cinematics and stage transitions. Turn off to keep it on screen at all times."); AvoidHudElements = cfg.Bind<bool>("Display", "AvoidHudElements", true, "Sit below the run timer and objective strip instead of overlapping them. Measured each refresh, so it follows the objective panel as it grows and shrinks. Turn off to use PanelMargin as a fixed offset."); PanelWidth = cfg.Bind<float>("Display", "PanelWidth", 440f, new ConfigDescription("Panel width in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(220f, 900f), Array.Empty<object>())); PanelMargin = cfg.Bind<float>("Display", "PanelMargin", 12f, new ConfigDescription("Gap from the screen edge in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 400f), Array.Empty<object>())); AnchorRight = cfg.Bind<bool>("Display", "AnchorRight", true, "Anchor to the right edge of the screen. False anchors left."); MaxDetailRows = cfg.Bind<int>("Display", "MaxDetailRows", 8, new ConfigDescription("Sources shown per player when expanded.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); WindowSeconds = cfg.Bind<float>("Tracking", "WindowSeconds", 5f, new ConfigDescription("Length of the trailing window for the live DPS figure. Shorter reacts faster and reads spikier; longer is steadier but lags burst damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); NetMessageId = cfg.Bind<int>("Networking", "MessageId", 1495, new ConfigDescription("UNet message id used to broadcast the meter to clients. Ids are a flat shared space, so change this if it ever clashes with the game or another mod. Every player must use the same value.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(200, 32000), Array.Empty<object>())); NetSendRate = cfg.Bind<float>("Networking", "SendRate", 3f, new ConfigDescription("Snapshots per second sent to clients. Higher is smoother and costs more bandwidth; the meter only refreshes a few times a second anyway.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); AutoReport = cfg.Bind<bool>("Tracking", "AutoReport", true, "Write a breakdown to BepInEx/DpsMeter/report-*.log before each stage and boss reset, so attribution problems can be reviewed after the fact."); ResetMobsOnStage = cfg.Bind<bool>("Tracking", "ResetMobsOnStage", true, "Clear mob damage when a new stage begins, so totals mean 'this stage'. False accumulates across the whole run."); ResetBossOnEncounter = cfg.Bind<bool>("Tracking", "ResetBossOnEncounter", true, "Clear boss damage when a boss encounter starts, so totals mean 'this fight'. False accumulates across every boss in the run."); } } } namespace DpsMeter.Ui { public sealed class DetailScreen : MonoBehaviour { private struct Row { public RectTransform Root; public HGTextMeshProUGUI[] Cells; public int CacheStyle; } private const int MaxRows = 34; private const float RowHeight = 24f; private const float HeaderHeight = 40f; private const float TabHeight = 26f; private const float ColHeadHeight = 22f; private const float FooterHeight = 26f; private const float ContentWidth = 1120f; private const float Pad = 18f; private static readonly Color Backdrop = new Color(0f, 0f, 0f, 0.74f); private static readonly Color Dim = new Color(0.48f, 0.53f, 0.6f); private static readonly Color Head = new Color(0.72f, 0.78f, 0.86f); private static readonly float[] ColFrac = new float[6] { 0f, 0.42f, 0.55f, 0.66f, 0.77f, 0.89f }; private bool _built; private ViewMode _mode = ViewMode.Mobs; private int _scroll; private Canvas _canvas; private RectTransform _content; private Image _contentImg; private HGTextMeshProUGUI _title; private HGTextMeshProUGUI _tabs; private HGTextMeshProUGUI _footer; private HGTextMeshProUGUI[] _colHeads; private Row[] _rows; private int _activeRows; private float _nextRefresh; public static bool IsOpen { get; private set; } private void Update() { //IL_0006: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(PluginConfig.ScreenKey.Value)) { Toggle(); } if (!IsOpen) { return; } if ((Object)(object)Run.instance == (Object)null) { Close(); return; } if (Input.GetKeyDown(PluginConfig.ScopeKey.Value)) { _mode = DamageScopeNames.Next(_mode); _scroll = 0; _nextRefresh = 0f; } float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.01f) { _scroll = Mathf.Max(0, _scroll - Mathf.RoundToInt(y) * 3); _nextRefresh = 0f; } if (!(Time.unscaledTime < _nextRefresh)) { _nextRefresh = Time.unscaledTime + 0.25f; Refresh(); } } private void Toggle() { if (IsOpen) { Close(); } else if (!((Object)(object)Run.instance == (Object)null)) { if (!_built) { Build(); } IsOpen = true; ((Behaviour)_canvas).enabled = true; _nextRefresh = 0f; Refresh(); } } private void Close() { IsOpen = false; if ((Object)(object)_canvas != (Object)null) { ((Behaviour)_canvas).enabled = false; } } private void Build() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00bc: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00e3: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_039c: 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_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) _built = true; GameObject val = new GameObject("DpsDetailCanvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 55; CanvasScaler val2 = val.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 1f; GameObject val3 = new GameObject("Backdrop", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; Vector2 val5 = (val4.offsetMin = (val4.offsetMax = Vector2.zero)); Image val7 = val3.AddComponent<Image>(); ((Graphic)val7).color = Backdrop; ((Graphic)val7).raycastTarget = false; GameObject val8 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); val8.transform.SetParent(val.transform, false); _content = (RectTransform)val8.transform; RectTransform content = _content; RectTransform content2 = _content; ((Vector2)(ref val5))..ctor(0.5f, 0.5f); content2.anchorMax = val5; content.anchorMin = val5; _content.pivot = new Vector2(0.5f, 0.5f); _content.sizeDelta = new Vector2(1120f, 400f); _contentImg = val8.AddComponent<Image>(); Image contentImg = _contentImg; ((Graphic)contentImg).color = ModePalette.ScreenBackground(ViewMode.Mobs); ((Graphic)contentImg).raycastTarget = false; _title = Text((Transform)(object)_content, "Title", 26f, ModePalette.Accent(ViewMode.Mobs), (TextAlignmentOptions)4097); Place(((TMP_Text)_title).rectTransform, 18f, -6f, 1084f, 40f); _tabs = Text((Transform)(object)_content, "Tabs", 15f, Dim, (TextAlignmentOptions)4097); Place(((TMP_Text)_tabs).rectTransform, 18f, -40f, 1084f, 26f); string[] array = new string[6] { "SOURCE", "DAMAGE", "SHARE", "HITS", "CRIT", "AVG HIT" }; _colHeads = (HGTextMeshProUGUI[])(object)new HGTextMeshProUGUI[array.Length]; for (int i = 0; i < array.Length; i++) { _colHeads[i] = Text((Transform)(object)_content, "H" + i, 12f, Dim, (TextAlignmentOptions)((i == 0) ? 4097 : 4100)); ((TMP_Text)_colHeads[i]).text = array[i]; PlaceCell(((TMP_Text)_colHeads[i]).rectTransform, i, -66f, 22f, 0f); } _rows = new Row[34]; for (int j = 0; j < 34; j++) { _rows[j] = MakeRow(j); } _footer = Text((Transform)(object)_content, "Footer", 13f, Dim, (TextAlignmentOptions)4100); RectTransform rectTransform = ((TMP_Text)_footer).rectTransform; ((Vector2)(ref val5))..ctor(1f, 0f); rectTransform.anchorMax = val5; rectTransform.anchorMin = val5; rectTransform.pivot = new Vector2(1f, 0f); rectTransform.anchoredPosition = new Vector2(-18f, 4f); rectTransform.sizeDelta = new Vector2(1084f, 26f); ((Behaviour)_canvas).enabled = false; } private Row MakeRow(int index) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_005d: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("R" + index, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_content, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(1120f, 24f); val.SetActive(false); HGTextMeshProUGUI[] array = (HGTextMeshProUGUI[])(object)new HGTextMeshProUGUI[6]; for (int i = 0; i < 6; i++) { array[i] = Text((Transform)(object)val2, "C" + i, 15f, Head, (TextAlignmentOptions)((i == 0) ? 4097 : 4100)); PlaceCell(((TMP_Text)array[i]).rectTransform, i, 0f, 24f, 0f); } return new Row { Root = val2, Cells = array, CacheStyle = -1 }; } private static void PlaceCell(RectTransform rt, int col, float y, float h, float indent) { float x = 18f + indent + ColFrac[col] * 1084f; float num = ((col == 0) ? (ColFrac[1] * 1084f - indent - 12f) : (((col == ColFrac.Length - 1) ? (1f - ColFrac[col]) : (ColFrac[col + 1] - ColFrac[col])) * 1084f - 10f)); Place(rt, x, y, Mathf.Max(30f, num), h); } private static HGTextMeshProUGUI Text(Transform parent, string name, float size, Color color, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); HGTextMeshProUGUI val2 = val.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = align; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)1; ((Graphic)val2).raycastTarget = false; if ((Object)(object)HGTextMeshProUGUI.defaultLanguageFont != (Object)null) { ((TMP_Text)val2).font = HGTextMeshProUGUI.defaultLanguageFont; } return val2; } private static void Place(RectTransform rt, float x, float y, float w, float h) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, y); rt.sizeDelta = new Vector2(w, h); } private void Refresh() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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) bool flag = _mode == ViewMode.Taken; Color val = ModePalette.Accent(_mode); ((Graphic)_title).color = val; ((Graphic)_contentImg).color = ModePalette.ScreenBackground(_mode); ((TMP_Text)_tabs).text = Tabs(_mode); ((TMP_Text)_footer).text = "F7 mobs / boss / taken · wheel scrolls · " + ((object)PluginConfig.ScreenKey.Value/*cast due to .constrained prefix*/).ToString() + " close"; SetHeads(flag); int num = (flag ? RefreshTaken(val) : RefreshDealt(val)); for (int i = num; i < _activeRows; i++) { ((Component)_rows[i].Root).gameObject.SetActive(false); } _activeRows = num; float num2 = 88f + (float)num * 24f + 26f + 8f; _content.sizeDelta = new Vector2(1120f, Mathf.Min(num2, 960f)); } private static string Tabs(ViewMode m) { string text = ((m == ViewMode.Mobs) ? "<b>[ Mobs ]</b>" : "Mobs"); string text2 = ((m == ViewMode.Boss) ? "<b>[ Boss ]</b>" : "Boss"); string text3 = ((m == ViewMode.Taken) ? "<b>[ Taken ]</b>" : "Taken"); return text + " " + text2 + " " + text3; } private void SetHeads(bool taken) { string[] array = ((!taken) ? new string[6] { "SOURCE", "DAMAGE", "SHARE", "HITS", "CRIT", "AVG HIT" } : new string[6] { "SOURCE", "DAMAGE", "", "COUNT", "CRIT", "WHEN" }); for (int i = 0; i < _colHeads.Length; i++) { ((TMP_Text)_colHeads[i]).text = array[i]; } } private int RefreshDealt(Color accent) { //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) int scopeIdx = (int)DamageScopeNames.ToScope(_mode); IReadOnlyList<MeterView.PlayerView> players = MeterNetwork.View.Players; int num = 0; float num2 = 0f; for (int i = 0; i < players.Count; i++) { MeterView.ScopeView scopeView = players[i].Scopes[scopeIdx]; num2 += scopeView.Total; if (scopeView.Total > 0f && scopeView.StageIndex > num) { num = scopeView.StageIndex; } } string text = "DAMAGE DEALT · " + DamageScopeNames.Display(_mode).ToUpperInvariant(); if (num > 0) { text = text + " [S" + num + "]"; } ((TMP_Text)_title).text = text; List<MeterView.PlayerView> list = new List<MeterView.PlayerView>(players.Count); for (int j = 0; j < players.Count; j++) { if (players[j].Scopes[scopeIdx].Total > 0f) { list.Add(players[j]); } } list.Sort((MeterView.PlayerView a, MeterView.PlayerView b) => b.Scopes[scopeIdx].Total.CompareTo(a.Scopes[scopeIdx].Total)); int num3 = 0; foreach (MeterView.PlayerView item in list) { if (num3 >= 34) { break; } MeterView.ScopeView scopeView2 = item.Scopes[scopeIdx]; int num4 = 0; int num5 = 0; for (int num6 = 0; num6 < scopeView2.Sources.Count; num6++) { num4 += scopeView2.Sources[num6].Hits; num5 += scopeView2.Sources[num6].Crits; } double v = ((num2 > 0f) ? ((double)(scopeView2.Total / num2) * 100.0) : 0.0); SetRow(ref _rows[num3], num3, 0, accent, PlayerName(item), Fmt.Compact(scopeView2.Total), Fmt.Percent(v, 0), Fmt.Num(num4), (num4 > 0) ? Fmt.Percent((double)num5 / (double)num4 * 100.0, 0) : "-", (num4 > 0) ? Fmt.Compact(scopeView2.Total / (float)num4) : "-"); num3++; CharacterBody body = PlayerLookup.FindBodyByNetId(item.NetId); foreach (SourceRow source in scopeView2.Sources) { if (num3 >= 34) { break; } double v2 = ((scopeView2.Total > 0f) ? ((double)(source.Damage / scopeView2.Total) * 100.0) : 0.0); SetRow(ref _rows[num3], num3, 1, Head, SourceNames.Label(source.Key, body), Fmt.Compact(source.Damage), Fmt.Percent(v2), Fmt.Num(source.Hits), (source.Hits > 0) ? Fmt.Percent(source.CritRate, 0) : "-", (source.Hits > 0) ? Fmt.Compact(source.AverageHit) : "-"); num3++; } if (num3 < 34) { SetRow(ref _rows[num3], num3, 2, Dim, "", "", "", "", "", ""); num3++; } } if (num3 == 0) { SetRow(ref _rows[num3], num3, 1, Dim, "no damage recorded yet", "", "", "", "", ""); num3++; } return num3; } private int RefreshTaken(Color accent) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList<MeterView.PlayerView> players = MeterNetwork.View.Players; MeterView.PlayerView playerView = null; for (int i = 0; i < players.Count; i++) { if (players[i].Taken.Count != 0) { if (playerView == null) { playerView = players[i]; } if (IsLocal(players[i].NetId)) { playerView = players[i]; break; } } } if (playerView == null) { ((TMP_Text)_title).text = "DAMAGE TAKEN"; SetRow(ref _rows[0], 0, 1, Dim, "nothing has hit you yet", "", "", "", "", ""); return 1; } ((TMP_Text)_title).text = "DAMAGE TAKEN · " + PlayerName(playerView).ToUpperInvariant(); List<IncomingEvent> taken = playerView.Taken; int num = Mathf.Max(0, taken.Count - 34); if (_scroll > num) { _scroll = num; } float num2 = (((Object)(object)Run.instance != (Object)null) ? Run.instance.GetRunStopwatch() : Time.time); int num3 = 0; int num4 = _scroll; while (num4 < taken.Count && num3 < 34) { IncomingEvent incomingEvent = taken[num4]; string text = SourceNames.Label(SourceKey.Pack(SourceKind.Attacker, incomingEvent.AttackerBody), null); string text2 = SourceNames.Label(incomingEvent.SourceKey, null); string c = ((text2 == text) ? text : (text + " · " + text2)); SetRow(ref _rows[num3], num3, 1, (num3 == 0 && _scroll == 0) ? accent : Head, c, Fmt.Compact(incomingEvent.Damage), "", (incomingEvent.Count > 1) ? ("×" + incomingEvent.Count) : "", incomingEvent.Crit ? "crit" : "", Ago(num2 - incomingEvent.Time)); num4++; num3++; } if (num3 == 0) { SetRow(ref _rows[0], 0, 1, Dim, "nothing has hit you yet", "", "", "", "", ""); num3 = 1; } return num3; } private static bool IsLocal(uint netId) { NetworkUser val = PlayerLookup.FindNetworkUser(netId); return (Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer; } private static string PlayerName(MeterView.PlayerView pv) { NetworkUser val = PlayerLookup.FindNetworkUser(pv.NetId); string text = (((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.userName)) ? val.userName : pv.Name); return string.IsNullOrEmpty(text) ? "Player" : text; } private static string Ago(float seconds) { if (seconds < 0f) { seconds = 0f; } if (seconds < 60f) { return Mathf.FloorToInt(seconds) + "s"; } int num = Mathf.FloorToInt(seconds / 60f); return num + "m" + Mathf.FloorToInt(seconds - (float)num * 60f).ToString("00") + "s"; } private void SetRow(ref Row row, int index, int style, Color color, string c0, string c1, string c2, string c3, string c4, string c5) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if (!((Component)row.Root).gameObject.activeSelf) { ((Component)row.Root).gameObject.SetActive(true); } row.Root.anchoredPosition = new Vector2(0f, 0f - (88f + (float)index * 24f)); if (row.CacheStyle != style) { row.CacheStyle = style; bool flag = style == 1; float fontSize = (flag ? 14f : 16f); float num = (flag ? 22f : 0f); for (int i = 0; i < 6; i++) { ((TMP_Text)row.Cells[i]).fontSize = fontSize; PlaceCell(((TMP_Text)row.Cells[i]).rectTransform, i, 0f, 24f, (i == 0) ? num : 0f); } } string[] array = new string[6] { c0, c1, c2, c3, c4, c5 }; for (int j = 0; j < 6; j++) { Color val = ((j == 0) ? color : ((style == 1) ? Head : color)); if (((Graphic)row.Cells[j]).color != val) { ((Graphic)row.Cells[j]).color = val; } if (((TMP_Text)row.Cells[j]).text != array[j]) { ((TMP_Text)row.Cells[j]).text = array[j]; } } } } public sealed class DpsPanel : MonoBehaviour { private struct Row { public RectTransform Root; public HGTextMeshProUGUI Left; public HGTextMeshProUGUI C1; public HGTextMeshProUGUI C2; public HGTextMeshProUGUI C3; public string CacheL; public string Cache1; public string Cache2; public string Cache3; public int CacheStyle; public Color CacheNameColor; public Color Cache1Color; public Color Cache2Color; public Color Cache3Color; } private const float RefreshInterval = 0.2f; private const int MaxRows = 40; private const float RowHeight = 22f; private const float HeaderHeight = 30f; private const float LabelRowHeight = 15f; private const float TopHeight = 45f; private const float FooterHeight = 18f; private const float Pad = 10f; private static Color AccentColor = ModePalette.Accent(ViewMode.Mobs); private static readonly Color[] TierColors = (Color[])(object)new Color[7] { new Color(0.9f, 0.92f, 0.95f), new Color(0.48f, 0.88f, 0.52f), new Color(0.42f, 0.72f, 1f), new Color(0.76f, 0.56f, 1f), new Color(1f, 0.48f, 0.8f), new Color(1f, 0.48f, 0.8f), new Color(1f, 0.48f, 0.8f) }; private static readonly Color NameColor = new Color(0.96f, 0.96f, 0.96f); private static readonly Color DetailColor = new Color(0.66f, 0.71f, 0.78f); private static readonly Color HintColor = new Color(0.45f, 0.5f, 0.58f); private bool _visible; private bool _expanded; private ViewMode _mode = ViewMode.Mobs; private float _nextRefresh; private int _lastStageId = int.MinValue; private int _lastClearCount = int.MinValue; private bool _switchedForEncounter; private int _styledScope = -1; private Canvas _canvas; private RectTransform _panel; private Image _bg; private Image _accentBar; private HGTextMeshProUGUI _header; private HGTextMeshProUGUI _hint; private HGTextMeshProUGUI _totalLabel; private HGTextMeshProUGUI _lab1; private HGTextMeshProUGUI _lab2; private HGTextMeshProUGUI _lab3; private Row[] _rows; private int _activeRows; private void Awake() { _visible = PluginConfig.VisibleByDefault.Value; Build(); ApplyVisibility(); } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(PluginConfig.ToggleKey.Value)) { _visible = !_visible; ApplyVisibility(); } if (Input.GetKeyDown(PluginConfig.ScopeKey.Value)) { _mode = DamageScopeNames.Next(_mode); } if (Input.GetKeyDown(PluginConfig.DetailKey.Value)) { _expanded = !_expanded; } bool flag = ShouldShow(); if ((Object)(object)_canvas != (Object)null && ((Behaviour)_canvas).enabled != flag) { ((Behaviour)_canvas).enabled = flag; } if (flag && !(Time.unscaledTime < _nextRefresh)) { _nextRefresh = Time.unscaledTime + 0.2f; Refresh(); } } private bool ShouldShow() { if (!_visible || (Object)(object)Run.instance == (Object)null) { return false; } if (DetailScreen.IsOpen) { return false; } if (PluginConfig.HideWithHud.Value && !HudVisibility.IsVisible()) { return false; } return true; } private void ApplyVisibility() { if ((Object)(object)_canvas != (Object)null) { ((Behaviour)_canvas).enabled = ShouldShow(); } } private void Build() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: 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_0315: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0361: 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_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DpsMeterCanvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 50; CanvasScaler val2 = val.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 1f; float value = PluginConfig.PanelWidth.Value; float value2 = PluginConfig.PanelMargin.Value; bool value3 = PluginConfig.AnchorRight.Value; GameObject val3 = new GameObject("Panel", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val.transform, false); _panel = (RectTransform)val3.transform; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(value3 ? 1f : 0f, 1f); Vector2 val5 = (_panel.anchorMin = (_panel.anchorMax = val4)); _panel.pivot = val4; _panel.anchoredPosition = new Vector2(value3 ? (0f - value2) : value2, 0f - value2); _panel.sizeDelta = new Vector2(value, 30f); _bg = val3.AddComponent<Image>(); ((Graphic)_bg).color = ModePalette.Background(ViewMode.Mobs); ((Graphic)_bg).raycastTarget = false; GameObject val8 = new GameObject("AccentBar", new Type[1] { typeof(RectTransform) }); val8.transform.SetParent((Transform)(object)_panel, false); RectTransform val9 = (RectTransform)val8.transform; val9.anchorMin = new Vector2(0f, 0f); val9.anchorMax = new Vector2(0f, 1f); val9.pivot = new Vector2(0f, 0.5f); val9.offsetMin = new Vector2(0f, 0f); val9.offsetMax = new Vector2(4f, 0f); _accentBar = val8.AddComponent<Image>(); ((Graphic)_accentBar).color = ModePalette.Accent(ViewMode.Mobs); ((Graphic)_accentBar).raycastTarget = false; _header = MakeText((Transform)(object)_panel, "Header", 19f, AccentColor, (TextAlignmentOptions)4097); SetRect(((TMP_Text)_header).rectTransform, 10f, -4f, value - 20f, 30f); _hint = MakeText((Transform)(object)_panel, "Hint", 12f, HintColor, (TextAlignmentOptions)4100); RectTransform rectTransform = ((TMP_Text)_hint).rectTransform; ((Vector2)(ref val5))..ctor(1f, 0f); rectTransform.anchorMax = val5; rectTransform.anchorMin = val5; rectTransform.pivot = new Vector2(1f, 0f); rectTransform.anchoredPosition = new Vector2(-10f, 2f); rectTransform.sizeDelta = new Vector2(value - 20f, 18f); _totalLabel = MakeText((Transform)(object)_panel, "Total", 12f, HintColor, (TextAlignmentOptions)4097); SetRect(((TMP_Text)_totalLabel).rectTransform, 14f, -30f, value * 0.4f, 15f); _lab1 = MakeText((Transform)(object)_panel, "Lab1", 11f, HintColor, (TextAlignmentOptions)4100); _lab2 = MakeText((Transform)(object)_panel, "Lab2", 11f, HintColor, (TextAlignmentOptions)4100); _lab3 = MakeText((Transform)(object)_panel, "Lab3", 11f, HintColor, (TextAlignmentOptions)4100); ((TMP_Text)_lab1).text = "CUR"; ((TMP_Text)_lab2).text = "PEAK"; ((TMP_Text)_lab3).text = "AVG"; LayoutColumns(((TMP_Text)_lab1).rectTransform, ((TMP_Text)_lab2).rectTransform, ((TMP_Text)_lab3).rectTransform, value, -30f, 15f); _rows = new Row[40]; for (int i = 0; i < 40; i++) { _rows[i] = MakeRow(i); } } private Row MakeRow(int index) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_005d: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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) GameObject val = new GameObject("Row" + index, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_panel, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(PluginConfig.PanelWidth.Value, 22f); val.SetActive(false); return new Row { Root = val2, Left = MakeText((Transform)(object)val2, "L", 16f, NameColor, (TextAlignmentOptions)4097), C1 = MakeText((Transform)(object)val2, "C1", 16f, NameColor, (TextAlignmentOptions)4100), C2 = MakeText((Transform)(object)val2, "C2", 16f, NameColor, (TextAlignmentOptions)4100), C3 = MakeText((Transform)(object)val2, "C3", 16f, AccentColor, (TextAlignmentOptions)4100), CacheStyle = -1 }; } private static HGTextMeshProUGUI MakeText(Transform parent, string name, float size, Color color, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); HGTextMeshProUGUI val2 = val.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = align; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)1; ((Graphic)val2).raycastTarget = false; if ((Object)(object)HGTextMeshProUGUI.defaultLanguageFont != (Object)null) { ((TMP_Text)val2).font = HGTextMeshProUGUI.defaultLanguageFont; } return val2; } private static void LayoutColumns(RectTransform c1, RectTransform c2, RectTransform c3, float width, float y, float h) { float num = (width - 20f) * 0.2f; float num2 = width - 10f; SetRect(c3, num2 - num, y, num, h); SetRect(c2, num2 - num * 2f - 4f, y, num, h); SetRect(c1, num2 - num * 3f - 8f, y, num, h); } private static float NameColumnWidth(float width, float indent) { float num = (width - 20f) * 0.2f; return Mathf.Max(40f, width - num * 3f - 12f - indent - 10f); } private static void SetRect(RectTransform rt, float x, float y, float w, float h) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, y); rt.sizeDelta = new Vector2(w, h); } private void Refresh() { //IL_00b6: 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) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_0691: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Unknown result type (might be due to invalid IL or missing references) //IL_0560: 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) float value = PluginConfig.PanelWidth.Value; float runStopwatch = Run.instance.GetRunStopwatch(); UpdateAutoScope(); ApplyScopeStyle(); IReadOnlyList<MeterView.PlayerView> players = MeterNetwork.View.Players; if (_mode == ViewMode.Taken) { int num = RefreshTaken(value); for (int i = num; i < _activeRows; i++) { ((Component)_rows[i].Root).gameObject.SetActive(false); } _activeRows = num; _panel.sizeDelta = new Vector2(value, 45f + (float)num * 22f + 18f + 4f); UpdateVerticalPosition(); return; } int scopeIdx = (int)DamageScopeNames.ToScope(_mode); float num2 = 0f; float num3 = 0f; for (int j = 0; j < players.Count; j++) { num2 += players[j].Scopes[scopeIdx].Total; if (players[j].Scopes[scopeIdx].Duration > num3) { num3 = players[j].Scopes[scopeIdx].Duration; } } int num4 = 0; for (int k = 0; k < players.Count; k++) { MeterView.ScopeView scopeView = players[k].Scopes[scopeIdx]; if (scopeView.Total > 0f && scopeView.StageIndex > num4) { num4 = scopeView.StageIndex; } } string text = "DPS · " + DamageScopeNames.Display(_mode).ToUpperInvariant(); if (num4 > 0) { text = text + " [S" + num4 + "]"; } if (_mode == ViewMode.Boss && num3 > 0f) { text = text + " " + FormatClock(num3); } ((TMP_Text)_header).text = text; ((TMP_Text)_hint).text = (_expanded ? "F6 collapse" : "F6 expand") + " · F7 view · F8 hide · " + ((object)PluginConfig.ScreenKey.Value/*cast due to .constrained prefix*/).ToString() + " detail"; if (num2 > 0f) { ((TMP_Text)_totalLabel).text = "Σ " + CompactTinted(num2, detail: false, out var color); ((Graphic)_totalLabel).color = color; } else { ((TMP_Text)_totalLabel).text = ""; } ((TMP_Text)_lab1).text = "CUR"; ((TMP_Text)_lab2).text = "PEAK"; ((TMP_Text)_lab3).text = "AVG"; int num5 = 0; IOrderedEnumerable<MeterView.PlayerView> orderedEnumerable = from p in players where p.Scopes[scopeIdx].Total > 0f orderby p.Scopes[scopeIdx].Total descending select p; foreach (MeterView.PlayerView item in orderedEnumerable) { if (num5 >= 40) { break; } MeterView.ScopeView scopeView2 = item.Scopes[scopeIdx]; NetworkUser val = PlayerLookup.FindNetworkUser(item.NetId); string text2 = (((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.userName)) ? val.userName : item.Name); if (string.IsNullOrEmpty(text2)) { text2 = "Player"; } if (num2 > 0f && players.Count > 1) { text2 = text2 + " " + Fmt.Percent((double)(scopeView2.Total / num2) * 100.0, 0); } Color color2; string c = CompactTinted(scopeView2.Dps, detail: false, out color2); Color color3; string c2 = CompactTinted(scopeView2.PeakDps, detail: false, out color3); Color color4; string c3 = CompactTinted(scopeView2.AvgDps, detail: false, out color4); SetRow(ref _rows[num5], num5, 0, value, PlayerColor(item.NetId), text2, c, c2, c3, color2, color3, color4); num5++; if (!_expanded) { continue; } CharacterBody body = PlayerLookup.FindBodyByNetId(item.NetId); int num6 = 0; foreach (SourceRow source in scopeView2.Sources) { if (num5 >= 40 || num6 >= PluginConfig.MaxDetailRows.Value) { break; } double v = ((scopeView2.Total > 0f) ? ((double)(source.Damage / scopeView2.Total) * 100.0) : 0.0); Color color5; string c4 = CompactTinted(source.Damage, detail: true, out color5); SetRow(ref _rows[num5], num5, 1, value, DetailColor, SourceNames.Label(source.Key, body), "", Fmt.Percent(v), c4, DetailColor, DetailColor, color5); num5++; num6++; } } if (num5 == 0) { string left = (MeterNetwork.VersionMismatch ? "host has a different mod version" : ((MeterNetwork.IsRemote && !MeterNetwork.HasRemoteData) ? "waiting for host (needs the mod)" : "no damage recorded yet")); SetRow(ref _rows[num5], num5, 1, value, DetailColor, left, "", "", "", DetailColor, DetailColor, DetailColor); num5++; } for (int num7 = num5; num7 < _activeRows; num7++) { ((Component)_rows[num7].Root).gameObject.SetActive(false); } _activeRows = num5; _panel.sizeDelta = new Vector2(value, 45f + (float)num5 * 22f + 18f + 4f); UpdateVerticalPosition(); } private void UpdateAutoScope() { if (!PluginConfig.AutoScope.Value) { return; } int num = (((Object)(object)Stage.instance != (Object)null) ? ((Object)Stage.instance).GetInstanceID() : 0); int num2 = (((Object)(object)Run.instance != (Object)null) ? Run.instance.stageClearCount : (-1)); if (num != _lastStageId || num2 != _lastClearCount) { _lastStageId = num; _lastClearCount = num2; _mode = ViewMode.Mobs; _switchedForEncounter = false; ManualLogSource log = DpsMeterPlugin.Log; if (log != null) { log.LogDebug((object)"auto-scope: new stage, showing Mobs"); } } else { if (_mode == ViewMode.Taken) { return; } bool flag = IsBossEncounterActive(); if (flag && !_switchedForEncounter) { _mode = ViewMode.Boss; _switchedForEncounter = true; ManualLogSource log2 = DpsMeterPlugin.Log; if (log2 != null) { log2.LogDebug((object)("auto-scope: boss encounter, showing Boss " + $"(hostFlag={MeterNetwork.View.BossEncounterActive}, " + $"charging={TeleporterCharging()})")); } } else if (!flag && _switchedForEncounter) { _switchedForEncounter = false; ManualLogSource log3 = DpsMeterPlugin.Log; if (log3 != null) { log3.LogDebug((object)"auto-scope: boss encounter ended"); } } } } private static bool IsBossEncounterActive() { return MeterNetwork.View.BossEncounterActive || TeleporterCharging(); } private static bool TeleporterCharging() { TeleporterInteraction instance = TeleporterInteraction.instance; return (Object)(object)instance != (Object)null && instance.isCharging; } private void ApplyScopeStyle() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (_styledScope != (int)_mode) { _styledScope = (int)_mode; AccentColor = ModePalette.Accent(_mode); ((Graphic)_header).color = AccentColor; ((Graphic)_accentBar).color = AccentColor; ((Graphic)_bg).color = ModePalette.Background(_mode); for (int i = 0; i < _rows.Length; i++) { _rows[i].CacheStyle = -1; } } } private void UpdateVerticalPosition() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) float value = PluginConfig.PanelMargin.Value; float num = value; if (PluginConfig.AvoidHudElements.Value) { num = HudLayout.TopOffset(HudVisibility.Current, _canvas, value, 8f); } bool value2 = PluginConfig.AnchorRight.Value; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(value2 ? (0f - value) : value, 0f - num); if (_panel.anchoredPosition != val) { _panel.anchoredPosition = val; } } private int RefreshTaken(float width) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)_header).text = "DPS · TAKEN"; ((TMP_Text)_hint).text = "F7 view · F8 hide · " + ((object)PluginConfig.ScreenKey.Value/*cast due to .constrained prefix*/).ToString() + " detail"; ((TMP_Text)_totalLabel).text = ""; ((TMP_Text)_lab1).text = ""; ((TMP_Text)_lab2).text = ""; ((TMP_Text)_lab3).text = ""; IReadOnlyList<MeterView.PlayerView> players = MeterNetwork.View.Players; List<IncomingEvent> list = null; for (int i = 0; i < players.Count; i++) { if (players[i].Taken.Count != 0) { if (list == null) { list = players[i].Taken; } NetworkUser val = PlayerLookup.FindNetworkUser(players[i].NetId); if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer) { list = players[i].Taken; break; } } } if (list == null || list.Count == 0) { SetRow(ref _rows[0], 0, 1, width, DetailColor, "nothing has hit you yet", "", "", "", DetailColor, DetailColor, DetailColor); return 1; } int num = Mathf.Min(PluginConfig.MaxDetailRows.Value + 2, 40); int num2 = 0; int num3 = 0; while (num3 < list.Count && num2 < num) { IncomingEvent incomingEvent = list[num3]; string text = SourceNames.Label(SourceKey.Pack(SourceKind.Attacker, incomingEvent.AttackerBody), null); string text2 = SourceNames.Label(incomingEvent.SourceKey, null); string left = ((text2 == text) ? text : (text + " · " + text2)); Color color; string c = CompactTinted(incomingEvent.Damage, num2 != 0, out color); SetRow(ref _rows[num2], num2, (num2 != 0) ? 1 : 0, width, (num2 == 0) ? NameColor : DetailColor, left, "", (incomingEvent.Count > 1) ? ("×" + incomingEvent.Count) : "", c, DetailColor, DetailColor, color); num3++; num2++; } return num2; } private void SetRow(ref Row row, int index, int style, float width, Color nameColor, string left, string c1, string c2, string c3, Color col1, Color col2, Color col3) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) if (!((Component)row.Root).gameObject.activeSelf) { ((Component)row.Root).gameObject.SetActive(true); } row.Root.anchoredPosition = new Vector2(0f, 0f - (45f + (float)index * 22f)); if (row.CacheStyle != style) { row.CacheStyle = style; bool flag = style == 1; float fontSize = (flag ? 14f : 16f); float num = (flag ? 24f : 10f); ((TMP_Text)row.C1).fontSize = fontSize; ((TMP_Text)row.C2).fontSize = fontSize; ((TMP_Text)row.C3).fontSize = fontSize; ((TMP_Text)row.Left).fontSize = fontSize; SetRect(((TMP_Text)row.Left).rectTransform, num, 0f, NameColumnWidth(width, num), 22f); LayoutColumns(((TMP_Text)row.C1).rectTransform, ((TMP_Text)row.C2).rectTransform, ((TMP_Text)row.C3).rectTransform, width, 0f, 22f); Color val = default(Color); ((Color)(ref val))..ctor(-1f, -1f, -1f, -1f); row.CacheNameColor = val; row.Cache1Color = val; row.Cache2Color = val; row.Cache3Color = val; } if (row.CacheNameColor != nameColor) { row.CacheNameColor = nameColor; ((Graphic)row.Left).color = nameColor; } if (row.Cache1Color != col1) { row.Cache1Color = col1; ((Graphic)row.C1).color = col1; } if (row.Cache2Color != col2) { row.Cache2Color = col2; ((Graphic)row.C2).color = col2; } if (row.Cache3Color != col3) { row.Cache3Color = col3; ((Graphic)row.C3).color = col3; } if (row.CacheL != left) { row.CacheL = left; ((TMP_Text)row.Left).text = left; } if (row.Cache1 != c1) { row.Cache1 = c1; ((TMP_Text)row.C1).text = c1; } if (row.Cache2 != c2) { row.Cache2 = c2; ((TMP_Text)row.C2).text = c2; } if (row.Cache3 != c3) { row.Cache3 = c3; ((TMP_Text)row.C3).text = c3; } } private static Color PlayerColor(uint netId) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) CharacterBody val = PlayerLookup.FindBodyByNetId(netId); if ((Object)(object)val == (Object)null) { return NameColor; } Color val2 = val.bodyColor; float num = 0.2126f * val2.r + 0.7152f * val2.g + 0.0722f * val2.b; if (num < 0.45f) { val2 = Color.Lerp(val2, Color.white, (0.45f - num) / 0.45f * 0.8f); } val2.a = 1f; return val2; } private static Color MagnitudeColor(int tier, bool detail) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!PluginConfig.ColorByMagnitude.Value) { return detail ? DetailColor : NameColor; } if (tier < 0) { tier = 0; } if (tier >= TierColors.Length) { tier = TierColors.Length - 1; } Color val = TierColors[tier]; return detail ? Color.Lerp(val, DetailColor, 0.45f) : val; } private static string CompactTinted(double v, bool detail, out Color color) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) int tier; string result = Fmt.Compact(v, out tier); color = MagnitudeColor(tier, detail); return result; } private static string FormatClock(float seconds) { if (seconds < 0f) { seconds = 0f; } int num = Mathf.FloorToInt(seconds); return num / 60 + ":" + (num % 60).ToString("00"); } private void OnDestroy() { if ((Object)(object)_canvas != (Object)null) { Object.Destroy((Object)(object)((Component)_canvas).gameObject); } } } internal static class HudLayout { private static ObjectivePanelController _objectives; private static RunTimerUIController _timer; private const float MaxOffsetFraction = 0.4f; public static float TopOffset(HUD hud, Canvas canvas, float fallback, float gap) { if ((Object)(object)hud == (Object)null || (Object)(object)canvas == (Object)null) { return fallback; } Resolve(hud); float num = float.MaxValue; bool flag = false; if (Measure((RectTransform)(((Object)(object)_objectives != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null), out var bottomScreenY)) { num = Mathf.Min(num, bottomScreenY); flag = true; } if (Measure((RectTransform)(((Object)(object)_timer != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null), out var bottomScreenY2)) { num = Mathf.Min(num, bottomScreenY2); flag = true; } if (!flag) { return fallback; } float scaleFactor = canvas.scaleFactor; if (scaleFactor <= 0f) { return fallback; } float num2 = ((float)Screen.height - num) / scaleFactor + gap; float num3 = (float)Screen.height * 0.4f / scaleFactor; if (float.IsNaN(num2) || num2 < fallback) { return fallback; } return Mathf.Min(num2, num3); } private static bool Measure(RectTransform rt, out float bottomScreenY) { bottomScreenY = 0f; if ((Object)(object)rt == (Object)null || !((Component)rt).gameObject.activeInHierarchy) { return false; } Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); bottomScreenY = array[0].y; return bottomScreenY > 0f && bottomScreenY <= (float)Screen.height; } private static void Resolve(HUD hud) { if ((Object)(object)_objectives == (Object)null) { _objectives = ((Component)hud).GetComponentInChildren<ObjectivePanelController>(true); } if ((Object)(object)_timer == (Object)null) { _timer = ((Component)hud).GetComponentInChildren<RunTimerUIController>(true); } } } internal static class HudVisibility { private static HUD _cached; public static HUD Current => Resolve(); public static bool IsVisible() { HUD val = Resolve(); if ((Object)(object)val == (Object)null) { return false; } if (!((Behaviour)val).isActiveAndEnabled) { return false; } Canvas mainContainerCanvas = val.mainContainerCanvas; if ((Object)(object)mainContainerCanvas != (Object)null && !((Behaviour)mainContainerCanvas).enabled) { return false; } GameObject mainContainer = val.mainContainer; if ((Object)(object)mainContainer != (Object)null && !mainContainer.activeInHierarchy) { return false; } return true; } private static HUD Resolve() { if ((Object)(object)_cached != (Object)null) { return _cached; } ReadOnlyCollection<HUD> readOnlyInstanceList = HUD.readOnlyInstanceList; if (readOnlyInstanceList == null) { return null; } for (int i = 0; i < readOnlyInstanceList.Count; i++) { HUD val = readOnlyInstanceList[i]; if (!((Object)(object)val == (Object)null) && val.localUserViewer != null) { _cached = val; return val; } } return null; } } internal static class ModePalette { private static readonly Color MobsAccent = new Color(0.42f, 0.72f, 1f); private static readonly Color BossAccent = new Color(1f, 0.42f, 0.38f); private static readonly Color TakenAccent = new Color(1f, 0.78f, 0.32f); private static readonly Color MobsBg = new Color(0.04f, 0.05f, 0.07f, 0.85f); private static readonly Color BossBg = new Color(0.1f, 0.04f, 0.05f, 0.88f); private static readonly Color TakenBg = new Color(0.09f, 0.07f, 0.03f, 0.88f); public static Color Accent(ViewMode m) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return (Color)(m switch { ViewMode.Boss => BossAccent, ViewMode.Mobs => MobsAccent, _ => TakenAccent, }); } public static Color Background(ViewMode m) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return (Color)(m switch { ViewMode.Boss => BossBg, ViewMode.Mobs => MobsBg, _ => TakenBg, }); } public static Color ScreenBackground(ViewMode m) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) Color result = Background(m); result.a = 0.97f; return result; } } } namespace DpsMeter.Tracking { public enum DamageScope { Mobs, TeleporterBoss } public enum ViewMode { Mobs, Boss, Taken } public static class DamageScopeNames { public static string Display(DamageScope s) { return (s == DamageScope.Mobs) ? "Mobs" : "Boss"; } public static string Display(ViewMode m) { return m switch { ViewMode.Boss => "Boss", ViewMode.Mobs => "Mobs", _ => "Taken", }; } public static ViewMode Next(ViewMode m) { return (ViewMode)((int)(m + 1) % 3); } public static DamageScope ToScope(ViewMode m) { return (m == ViewMode.Boss) ? DamageScope.TeleporterBoss : DamageScope.Mobs; } } public struct SourceAgg { public double Damage; public int Hits; public int Crits; public double AverageHit => (Hits > 0) ? (Damage / (double)Hits) : 0.0; public double CritRate => (Hits > 0) ? ((double)Crits / (double)Hits * 100.0) : 0.0; } public sealed class ScopeStats { public double Total; public double Peak; public int StageIndex; public float FirstHitTime = -1f; public float LastHitTime; public readonly Dictionary<int, SourceAgg> BySource = new Dictionary<int, SourceAgg>(32); public readonly RollingWindow Window = new RollingWindow(WindowSeconds); public static float WindowSeconds = 5f; public double ActiveDuration => (FirstHitTime < 0f) ? 0.0 : ((double)(LastHitTime - FirstHitTime)); public double AverageDps { get { if (FirstHitTime < 0f) { return 0.0; } double num = LastHitTime - FirstHitTime; return (num > 0.25) ? (Total / num) : 0.0; } } public void Add(int key, float amount, float now, int stage, bool crit) { if (FirstHitTime < 0f) { StageIndex = stage; } Total += amount; BySource.TryGetValue(key, out var value); value.Damage += amount; value.Hits++; if (crit) { value.Crits++; } BySource[key] = value; Window.Add(now, amount); if (FirstHitTime < 0f) { FirstHitTime = now; } LastHitTime = now; } public void SamplePeak(float now) { double num = Window.PerSecond(now); if (num > Peak) { Peak = num; } } public void Reset() { Total = 0.0; Peak = 0.0; StageIndex = 0; FirstHitTime = -1f; LastHitTime = 0f; BySource.Clear(); Window.Reset(); } } public sealed class PlayerStats { public string DisplayName; public uint NetId; public readonly ScopeStats[] Scopes = new ScopeStats[2] { new ScopeStats(), new ScopeStats() }; public ScopeStats this[DamageScope s] => Scopes[(int)s]; public void ResetAll() { ScopeStats[] scopes = Scopes; foreach (ScopeStats scopeStats in scopes) { scopeStats.Reset(); } } } public sealed class DamageTracker { private readonly Dictionary<int, PlayerStats> _players = new Dictionary<int, PlayerStats>(8); private readonly Dictionary<int, IncomingLog> _taken = new Dictionary<int, IncomingLog>(8); public readonly Dictionary<string, double> UnresolvedByInflictor = new Dictionary<string, double>(16); private readonly List<BossGroup> _activeBossGroups = new List<BossGroup>(4); public IReadOnlyDictionary<int, PlayerStats> Players => _players; public IReadOnlyDictionary<int, IncomingLog> Taken => _taken; public double TrackedTotal { get; private set; } public double UnattributedTotal { get; private set; } public bool HasActiveBossGroups => _activeBossGroups.Count > 0; public void RegisterBossGroup(BossGroup group) { if (!((Object)(object)group == (Object)null) && !_activeBossGroups.Contains(group)) { _activeBossGroups.Add(group); } } public void UnregisterBossGroup(BossGroup group) { if ((Object)(object)group != (Object)null) { _activeBossGroups.Remove(group); } } public bool IsEncounterContinuation() { if (HasActiveBossGroups) { return true; } int num = CurrentStage(); foreach (KeyValuePair<int, PlayerStats> player in _players) { ScopeStats scopeStats = player.Value[DamageScope.TeleporterBoss]; if (scopeStats.Total > 0.0 && scopeStats.StageIndex == num) { return true; } } return false; } public void Record(DamageReport report) { if (report != null) { RecordDealt(report); RecordTaken(report); } } private void RecordTaken(DamageReport report) { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected I4, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected I4, but got Unknown CharacterMaster victimMaster = report.victimMaster; if ((Object)(object)victimMaster == (Object)null || (Object)(object)victimMaster.playerCharacterMasterController == (Object)null || report.victimTeamIndex == report.attackerTeamIndex) { return; } float damageDealt = report.damageDealt; if (damageDealt <= 0f) { return; } DamageInfo damageInfo = report.damageInfo; int num = (int)report.attackerBodyIndex; int sourceKey; if ((int)report.dotType != -1 && (int)report.dotType >= 0) { sourceKey = SourceKey.Pack(SourceKind.Dot, (int)report.dotType); } else { int num2 = -1; if (damageInfo != null && (Object)(object)damageInfo.inflictor != (Object)null) { ProjectileController component = damageInfo.inflictor.GetComponent<ProjectileController>(); if ((Object)(object)component != (Object)null) { num2 = component.catalogIndex; } } sourceKey = ((num2 >= 0) ? SourceKey.Pack(SourceKind.Projectile, num2) : SourceKey.Pack(SourceKind.Attacker, num)); } int instanceID = ((Object)victimMaster).GetInstanceID(); if (!_taken.TryGetValue(instanceID, out var value)) { value = new IncomingLog(); _taken[instanceID] = value; } value.Add(num, sourceKey, damageDealt, Now(), damageInfo?.crit ?? false); } private void RecordDealt(DamageReport report) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected I4, but got Unknown CharacterMaster val = report.attackerOwnerMaster ?? report.attackerMaster; if ((Object)(object)val == (Object)null) { return; } PlayerCharacterMasterController playerCharacterMasterController = val.playerCharacterMasterController; if ((Object)(object)playerCharacterMasterController == (Object)null || report.victimTeamIndex == report.attackerTeamIndex) { return; } float damageDealt = report.damageDealt; if (!(damageDealt <= 0f)) { int key = SourceResolver.Resolve(report); if ((Object)(object)report.attackerOwnerMaster != (Object)null && (Object)(object)report.attackerOwnerMaster != (Object)(object)report.attackerMaster) { key = SourceKey.Pack(SourceKind.Minion, (int)report.attackerBodyIndex); } DamageScope s = ClassifyScope(report); float now = Now(); PlayerStats orCreateIn = GetOrCreateIn(_players, val, playerCharacterMasterController); orCreateIn[s].Add(key, damageDealt, now, CurrentStage(), report.damageInfo != null && report.damageInfo.crit); TrackedTotal += damageDealt; SourceKind sourceKind = SourceKey.KindOf(key); if (sourceKind == SourceKind.Unattributed || sourceKind == SourceKind.GenericItem) { UnattributedTotal += damageDealt; RecordUnresolved(report, damageDealt); } } } private void RecordUnresolved(DamageReport report, float amount) { GameObject val = ((report.damageInfo != null) ? report.damageInfo.inflictor : null); string text = (((Object)(object)val != (Object)null) ? ((Object)val).name : "<null inflictor>"); int num = text.IndexOf("(Clone)", StringComparison.Ordinal); if (num > 0) { text = text.Substring(0, num); } string key; if ((Object)(object)val == (Object)null) { DamageInfo damageInfo = report.damageInfo; key = "<null> [" + ((object)Unsafe.As<DamageColorIndex, DamageColorIndex>(ref damageInfo.damageColorIndex)/*cast due to .constrained prefix*/).ToString() + "]" + " dt=" + ((object)Unsafe.As<DamageType, DamageType>(ref damageInfo.damageType.damageType)/*cast due to .constrained prefix*/).ToString() + " src=" + ((object)Unsafe.As<DamageSource, DamageSource>(ref damageInfo.damageType.damageSource)/*cast due to .constrained prefix*/).ToString() + " proc=" + damageInfo.procCoefficient.ToString("0.##", CultureInfo.InvariantCulture) + " mask=" + damageInfo.procChainMask.mask.ToString(CultureInfo.InvariantCulture) + " ext=" + ((object)Unsafe.As<DamageTypeExtended, DamageTypeExtended>(ref damageInfo.damageType.damageTypeExtended)/*cast due to .constrained prefix*/).ToString() + (damageInfo.crit ? " crit" : ""); } else { key = text + " [" + ((object)Unsafe.As<DamageColorIndex, DamageColorIndex>(ref report.damageInfo.damageColorIndex)/*cast due to .constrained prefix*/).ToString() + "]"; } UnresolvedByInflictor.TryGetValue(key, out var value); UnresolvedByInflictor[key] = value + (double)amount; } private static PlayerStats GetOrCreateIn(Dictionary<int, PlayerStats> map, CharacterMaster owner, PlayerCharacterMasterController pcmc) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)owner).GetInstanceID(); if (!map.TryGetValue(instanceID, out var value)) { value = (map[instanceID] = new PlayerStats { DisplayName = ResolveName(pcmc) }); } else if (string.IsNullOrEmpty(value.DisplayName)) { value.DisplayName = ResolveName(pcmc); } if (value.NetId == 0) { NetworkUser networkUser = pcmc.networkUser; if ((Object)(object)networkUser != (Object)null) { PlayerStats playerStats2 = value; NetworkInstanceId netId = ((NetworkBehaviour)networkUser).netId; playerStats2.NetId = ((NetworkInstanceId)(ref netId)).Value; } } return value; } private static string ResolveName(PlayerCharacterMasterController pcmc) { NetworkUser val = (((Object)(object)pcmc != (Object)null) ? pcmc.networkUser : null); return ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.userName)) ? val.userName : "Player"; } private DamageScope ClassifyIncomingScope(DamageReport report) { CharacterMaster attackerMaster = report.attackerMaster; if ((Object)(object)attackerMaster == (Object)null || _activeBossGroups.Count == 0) { return DamageScope.Mobs; } for (int num = _activeBossGroups.Count - 1; num >= 0; num--) { BossGroup val = _activeBossGroups[num]; if ((Object)(object)val == (Object)null) { _activeBossGroups.RemoveAt(num); } else { CombatSquad combatSquad = val.combatSquad; if ((Object)(object)combatSquad != (Object)null && combatSquad.ContainsMember(attackerMaster)) { return DamageScope.TeleporterBoss; } } } return DamageScope.Mobs; } private DamageScope ClassifyScope(DamageReport report) { CharacterMaster victimMaster = report.victimMaster; if ((Object)(object)victimMaster == (Object)null || _activeBossGroups.Count == 0) { return DamageScope.Mobs; } for (int num = _activeBossGroups.Count - 1; num >= 0; num--) { BossGroup val = _activeBossGroups[num]; if ((Object)(object)val == (Object)null) { _activeBossGroups.RemoveAt(num); } else { CombatSquad combatSquad = val.combatSquad; if ((Object)(object)combatSquad != (Object)null && combatSquad.ContainsMember(victimMaster)) { return DamageScope.TeleporterBoss; } } } return DamageScope.Mobs; } public static int CurrentStage() { Run instance = Run.instance; return ((Object)(object)instance != (Object)null) ? (instance.stageClearCount + 1) : 0; } private static float Now() { Run instance = Run.instance; return ((Object)(object)instance != (Object)null) ? instance.GetRunStopwatch() : Time.time; } public void ResetScope(DamageScope scope) { foreach (KeyValuePair<int, PlayerStats> player in _players) { player.Value[scope].Reset(); } } public void ResetAll() { foreach (KeyValuePair<int, PlayerStats> player in _players) { player.Value.ResetAll(); } foreach (KeyValuePair<int, IncomingLog> item in _taken) { item.Value.Clear(); } ResetDiagnostics(); } public void Clear() { _players.Clear(); _taken.Clear(); _activeBossGroups.Clear(); ResetDiagnostics(); } private void ResetDiagnostics() { TrackedTotal = 0.0; UnattributedTotal = 0.0; UnresolvedByInflictor.Clear(); } } public static class Fmt { private static readonly CultureInfo Inv = CultureInfo.InvariantCulture; private static readonly string[] Suffixes = new string[6] { "", "k", "M", "B", "T", "Q" }; public static string Compact(double v) { int tier; return Compact(v, out tier); } public static string Compact(double v, out int tier) { tier = 0; if (double.IsNaN(v) || double.IsInfinity(v)) { return "-"; } if (v < 0.0) { return "-" + Compact(0.0 - v, out tier); } if (v < 1000.0) { return v.ToString("#,0", Inv); } double num = v; while (num >= 1000.0 && tier < Suffixes.Length - 1) { num /= 1000.0; tier++; } if (num >= 1000.0) { tier = Suffixes.Length; return v.ToString("0.###e+0", Inv); } int num2 = DecimalsFor(num); double num3 = Math.Round(num, num2, MidpointRounding.AwayFromZero); if (num3 >= 1000.0 && tier < Suffixes.Length - 1) { tier++; num = num3 / 1000.0; num2 = 2; } else { num = num3; int num4 = DecimalsFor(num); if (num4 != num2) { num2 = num4; num = Math.Round(num, num2, MidpointRounding.AwayFromZero); } } return num.ToString("0." + new string('0', num2), Inv) + Suffixes[tier]; } private static int DecimalsFor(double mantissa) { return (!(mantissa >= 100.0)) ? ((mantissa >= 10.0) ? 1 : 2) : 0; } public static string Num(double v, int decimals = 0) { if (double.IsNaN(v) || double.IsInfinity(v)) { return "-"; } return v.ToString("N" + decimals.ToString(Inv), Inv); } public static string Percent(double v, int decimals = 1) { if (double.IsNaN(v) || double.IsInfinity(v)) { return "-"; } return Num(v, decimals) + "%"; } } public struct IncomingEvent { public uint Id; public float Time; public int AttackerBody; public int SourceKey; public float Damage; public int Count; public bool Crit; } public sealed class IncomingLog { private const float CoalesceWindow = 4f; public const int Capacity = 128; private readonly IncomingEvent[] _events = new IncomingEvent[128]; private int _count; private int _head; private uint _nextId = 1u; public int Count => _count; public uint LatestId => _nextId - 1; public IncomingEvent GetNewest(int offset) { int num = (_head - 1 - offset + 256) % 128; return _events[num]; } public void Add(int attackerBody, int sourceKey, float damage, float now, bool crit) { if (_count > 0) { int num = (_head - 1 + 128) % 128; ref IncomingEvent reference = ref _events[num]; if (reference.AttackerBody == attackerBody && reference.SourceKey == sourceKey && now - reference.Time <= 4f) { reference.Damage += damage; reference.Count++; reference.Time = now; reference.Crit |= crit; return; } } _events[_head] = new IncomingEvent { Id = _nextId++, Time = now, AttackerBody = attackerBody, SourceKey = sourceKey, Damage = damage, Count = 1, Crit = crit }; _head = (_head + 1) % 128; if (_count < 128) { _count++; } } public void CopyNewest(List<IncomingEvent> into, int max) { into.Clear(); int num = ((_count < max) ? _count : max); for (int i = 0; i < num; i++) { into.Add(GetNewest(i)); } } public void Merge(IncomingEvent e) { for (int i = 0; i < _count; i++) { int num = (_head - 1 - i + 256) % 128; if (_events[num].Id == e.Id) { _events[num] = e; return; } if (_events[num].Id < e.Id) { break; } } _events[_head] = e; _head = (_head + 1) % 128; if (_count < 128) { _count++; } if (e.Id >= _nextId) { _nextId = e.Id + 1; } } public void Clear() { _count = 0; _head = 0; _nextId = 1u; } } public static class InflictorMap { private static Dictionary<string, string> _prefabToOwner; private static readonly Dictionary<int, int> _byProjectile = new Dictionary<int, int>(128); private static readonly Dictionary<string, int> _byName = new Dictionary<string, int>(128); private const int Unresolved = int.MinValue; public static int Count => _prefabToOwner?.Count ?? 0; public static void Load() { if (_prefabToOwner != null) { return; } _prefabToOwner = new Dictionary<string, string>(2048, StringComparer.Ordinal); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith("inflictors.txt", StringComparison.Ordinal)) { text = text2; break; } } if (text == null) { return; } using Stream stream = executingAssembly.GetManifestResourceStream(text); using StreamReader streamReader = new StreamReader(stream); string text3; while ((text3 = streamReader.ReadLine()) != null) { int num = text3.IndexOf('='); if (num > 0 && num != text3.Length - 1) { _prefabToOwner[text3.Substring(0, num)] = text3.Substring(num + 1); } } } public static bool TryResolve(GameObject inflictor, GameObject attacker, out int key) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected I4, but got Unknown key = 0; if ((Object)(object)inflictor == (Object)null) { return false; } if (inflictor != attacker) { CharacterBody component = inflictor.GetComponent<CharacterBody>(); if ((Object)(object)component != (Object)null && (int)component.bodyIndex >= 0) { key = SourceKey.Pack(SourceKind.Minion, (int)component.bodyIndex); return true; } } if (_prefabToOwner == null) { return false; } ProjectileController component2 = inflictor.GetComponent<ProjectileController>(); if ((Object)(object)component2 != (Object)null) { int catalogIndex = component2.catalogIndex; if (_byProjectile.TryGetValue(catalogIndex, out var value)) { key = value; return value != int.MinValue; } int num = ResolveByName(((Object)inflictor).name); _byProjectile[catalogIndex] = num; key = num; return num != int.MinValue; } string text = StripClone(((Object)inflictor).name); if (_byName.TryGetValue(text, out var value2)) { key = value2; return value2 != int.MinValue; } int num2 = ResolveOwner(text); _byName[text] = num2; key = num2; return num2 != int.MinValue; } private static int ResolveByName(string rawName) { return ResolveOwner(StripClone(rawName)); } private static int ResolveOwner(string prefabName) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_003e: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected I4, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected I4, but got Unknown if (!_prefabToOwner.TryGetValue(prefabName, out var value)) { return int.MinValue; } ItemIndex val = ItemCatalog.FindItemIndex(value); if ((int)val != -1) { return SourceKey.Pack(SourceKind.Item, (int)val); } EquipmentIndex val2 = EquipmentCatalog.FindEquipmentIndex(value); if ((int)val2 != -1) { return SourceKey.Pack(SourceKind.Equipment, (int)val2); } return int.MinValue; } private static string StripClone(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } int num = name.IndexOf("(Clone)", StringComparison.Ordinal); return (num > 0) ? name.Substring(0, num) : name; } } public static class InventoryWatcher { private static readonly Dictionary<int, int[]> _lastStacks = new Dictionary<int, int[]>(8); private static readonly Dictionary<int, EquipmentIndex> _lastEquipment = new Dictionary<int, EquipmentIndex>(8); private static readonly StringBuilder Sb = new StringBuilder(128); public static void Subscribe() { Inventory.onInventoryChangedGlobal += OnChanged; } public static void Unsubscribe() { Inventory.onInventoryChangedGlobal -= OnChanged; } public static void Clear() { _lastStacks.Clear(); _lastEquipment.Clear(); } private static void OnChanged(Inventory inventory) { //IL_01bc: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: 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_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Invalid comparison between Unknown and I4 //IL_0218: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)inventory == (Object)null) { return; } CharacterMaster component = ((Component)inventory).GetComponent<CharacterMaster>(); if ((Object)(object)component == (Object)null || (Object)(object)component.playerCharacterMasterController == (Object)null) { return; } int instanceID = ((Object)inventory).GetInstanceID(); int itemCount = ItemCatalog.itemCount; if (!_lastStacks.TryGetValue(instanceID, out var value) || value.Length != itemCount) { value = new int[itemCount]; for (int i = 0; i < itemCount; i++) { value[i] = inventory.GetItemCount((ItemIndex)i); } _lastStacks[instanceID] = value; _lastEquipment[instanceID] = inventory.currentEquipmentIndex; return; } string text = NameOf(component); for (int j = 0; j < itemCount; j++) { int itemCount2 = inventory.GetItemCount((ItemIndex)j); int num = value[j]; if (itemCount2 == num) { continue; } value[j] = itemCount2; string text2 = ItemName((ItemIndex)j); if (itemCount2 > num) { ManualLogSource log = DpsMeterPlugin.Log; if (log != null) { log.LogInfo((object)$"[items] {text} +{itemCount2 - num} {text2} (now {itemCount2}) stage {DamageTracker.CurrentStage()}"); } } else { ManualLogSource log2 = DpsMeterPlugin.Log; if (log2 != null) { log2.LogInfo((object)$"[items] {text} -{num - itemCount2} {text2} (now {itemCount2}) stage {DamageTracker.CurrentStage()}"); } } } EquipmentIndex currentEquipmentIndex = inventory.currentEquipmentIndex; if (_lastEquipment.TryGetValue(instanceID, out var value2) && value2 == currentEquipmentIndex) { return; } _lastEquipment[instanceID] = currentEquipmentIndex; if ((int)currentEquipmentIndex != -1) { ManualLogSource log3 = DpsMeterPlugin.Log; if (log3 != null) { log3.LogInfo((object)("[items] " + text + " equipped " + EquipmentName(currentEquipmentIndex))); } } } public static void AppendInventories(StringBuilder sb) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Invalid comparison between Unknown and I4 //IL_0162: Unknown result type (might be due to invalid IL or missing references) ReadOnlyCollection<PlayerCharacterMasterController> instances = PlayerCharacterMasterController.instances; if (instances == null) { return; } foreach (PlayerCharacterMasterController item in instances) { CharacterMaster val = (((Object)(object)item != (Object)null) ? item.master : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null); if ((Object)(object)val2 == (Object)null) { continue; } Sb.Length = 0; int itemCount = ItemCatalog.itemCount; int num = 0; for (int i = 0; i < itemCount; i++) { int itemCount2 = val2.GetItemCount((ItemIndex)i); if (itemCount2 > 0) { if (num++ > 0) { Sb.Append(", "); } Sb.Append(ItemName((ItemIndex)i)); if (itemCount2 > 1) { Sb.Append(" x").Append(itemCount2); } } } EquipmentIndex currentEquipmentIndex = val2.currentEquipmentIndex; sb.AppendLine("[items] " + NameOf(val) + ": " + ((num == 0) ? "(none)" : Sb.ToString())); if ((int)currentEquipmentIndex != -1) { sb.AppendLine("[items] " + NameOf(val) + " equipment: " + EquipmentName(currentEquipmentIndex)); } } } private static string NameOf(CharacterMaster master) { PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; NetworkUser val = (((Object)(object)playerCharacterMasterController != (Object)null) ? playerCharacterMasterController.networkUser : null); return ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.userName)) ? val.userName : "Player"; } private unsafe static string ItemName(ItemIndex index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ItemDef itemDef = ItemCatalog.GetItemDef(index); if ((Object)(object)itemDef == (Object)null) { return ((object)(*(ItemIndex*)(&index))/*cast due to .constrained prefix*/).ToString(); } string text = Language.GetString(itemDef.nameToken); string name = ((Object)itemDef).name; if (string.IsNullOrEmpty(text) || text == itemDef.nameToken) { return string.IsNullOrEmpty(name) ? ((object)(*(ItemIndex*)(&index))/*cast due to .constrained prefix*/).ToString() : name; } return (string.IsNullOrEmpty(name) || name == text) ? text : (text + " (" + name + ")"); } private unsafe static string EquipmentName(EquipmentIndex index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(index); if ((Object)(object)equipmentDef == (Object)null) { return ((object)(*(EquipmentIndex*)(&index))/*cast due to .constrained prefix*/).ToString(); } string text = Language.GetString(equipmentDef.nameToken); return (string.IsNullOrEmpty(text) || text == equipmentDef.nameToken) ? ((Object)equipmentDef).name : text; } } public static class PlayerLookup { public static CharacterBody FindBody(int masterInstanceId) { foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { CharacterMaster val = (((Object)(object)instance != (Object)null) ? instance.master : null); if ((Object)(object)val != (Object)null && ((Object)val).GetInstanceID() == masterInstanceId) { return val.GetBody(); }