Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of DamageLog v1.2.9
plugins/DamageLog/DamageLog.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DamageLog")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.9.0")] [assembly: AssemblyInformationalVersion("1.2.9+ce18af9320e9a1877c95543caec3dd9812854da2")] [assembly: AssemblyProduct("DamageLog")] [assembly: AssemblyTitle("DamageLog")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.9.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DamageLog { internal sealed class BossDamageLog : DamageLog { public readonly uint targetNetId; public override string displayName => $"<style=cStack>{targetNetId:x8}</style> <style=cIsHealth>{base.displayName}</style>"; public override string loggingName => $"{base.loggingName} <{targetNetId:x8}>"; public BossDamageLog(CharacterBody body) { //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) NetworkInstanceId netId = ((NetworkBehaviour)body).netId; targetNetId = ((NetworkInstanceId)(ref netId)).Value; base..ctor(body, Util.GetBestBodyName(((Component)body).gameObject)); } public override bool IsExpired(float elapsedTime) { return false; } public static bool IsIgnoredBossSubtitle(string subtitleNameToken) { if (string.IsNullOrEmpty(subtitleNameToken)) { return true; } switch (subtitleNameToken) { default: return false; case "NULL_SUBTITLE": case "LUNARWISP_BODY_SUBTITLE": case "LUNARGOLEM_BODY_SUBTITLE": case "LUNAREXPLODER_BODY_SUBTITLE": return true; } } } internal static class Compatibility { internal static string ApplicationVersion => "RoR2v" + Application.version + " (" + Application.buildGUID + ")"; internal static string PluginVersion => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion; internal static bool DamageInfoChanged() { try { DamageInfoChanged_Test(); return false; } catch (MissingFieldException) { Plugin.Logger.LogError((object)("DamageLogv" + PluginVersion + " is not compatible with " + ApplicationVersion + "\nPlease refer to the README on the mod page for guidance.")); return true; } } [MethodImpl(MethodImplOptions.NoInlining)] private static void DamageInfoChanged_Test() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ((object)(DamageTypeCombo)(ref new DamageInfo().damageType)).ToString(); } } internal static class ConfigUtility { public static ConfigEntry<string> BindInputKey(this ConfigFile config, string section, string key, string defaultInputKey, string description) { ConfigEntry<string> val = config.Bind<string>(section, key, defaultInputKey, description + "\nKey names follow the naming conventions outlined at: https://docs.unity3d.com/2019.4/Documentation/Manual/class-InputManager.html#:~:text=Key%20family"); try { Input.GetKeyDown(val.Value); } catch (ArgumentException) { Plugin.Logger.LogWarning((object)("Config> " + section + "." + key + " | '" + val.Value + "' is not a valid input key string, using '" + defaultInputKey + "' instead.")); val.Value = defaultInputKey; } return val; } } internal sealed class Config { private readonly ConfigFile file; private readonly ConfigEntry<bool> trackBosses; private readonly ConfigEntry<float> entryMaxRetainTime; private readonly ConfigEntry<bool> onlyShowWithScoreboard; private readonly ConfigEntry<bool> useSimpleTextMode; private readonly ConfigEntry<bool> hideDamageTimer; private readonly ConfigEntry<int> maximumPortraitCount; private readonly ConfigEntry<bool> showDamageIdentifier; private readonly ConfigEntry<bool> compactLines; private readonly ConfigEntry<bool> showRawDamageInsteadOfPercentage; private readonly ConfigEntry<string> cycleUserKey; private readonly ConfigEntry<string> cycleBossKey; private readonly ConfigEntry<float> canvasOffsetRight; private readonly ConfigEntry<float> canvasOffsetTop; private readonly ConfigEntry<float> canvasWidth; private readonly ConfigEntry<float> textSize; private readonly ConfigEntry<float> portraitSpacing; private readonly ConfigEntry<float> portraitSize; private readonly ConfigEntry<float> eliteIconSize; private readonly ConfigEntry<float> portraitTextSize; private readonly ConfigEntry<float> damageTextSize; public bool TrackBosses => trackBosses.Value; public float EntryMaxRetainTime { get { if (!(entryMaxRetainTime.Value < 1f)) { return entryMaxRetainTime.Value; } return 1f; } } public bool OnlyShowWithScoreboard => onlyShowWithScoreboard.Value; public bool SimpleTextMode => useSimpleTextMode.Value; public bool HideDamageTimer => hideDamageTimer.Value; public int MaximumPortraitCount { get { if (maximumPortraitCount.Value <= 0) { return 1; } return maximumPortraitCount.Value; } } public bool ShowIdentifier => showDamageIdentifier.Value; public bool CompactLines => compactLines.Value; public bool ShowRawDamageInsteadOfPercentage => showRawDamageInsteadOfPercentage.Value; public string CycleUserKey => cycleUserKey.Value; public string CycleBossKey => cycleBossKey.Value; public Vector2 CanvasOffsetTopRight => new Vector2(canvasOffsetRight.Value, canvasOffsetTop.Value); public float CanvasWidth => canvasWidth.Value; public float TextSize => textSize.Value; public float PortraitSpacing => portraitSpacing.Value; public float PortraitSize => portraitSize.Value; public float EliteIconSize => eliteIconSize.Value; public float PortraitTextSize => portraitTextSize.Value; public float DamageTextSize => damageTextSize.Value; internal void Reload() { Plugin.Logger.LogDebug((object)("Reloading " + file.ConfigFilePath.Substring(file.ConfigFilePath.LastIndexOf(Path.DirectorySeparatorChar) + 1))); file.Reload(); } internal Config(ConfigFile config) { file = config; trackBosses = config.Bind<bool>("Bosses", "trackBosses", false, "Generate Damage Logs for bosses. Use cycleBossKey to display these in the UI."); entryMaxRetainTime = config.Bind<float>("Constraints", "entryMaxRetainTime", 10f, "The maximum length of time (seconds) a Damage Log entry will be retained for.\nMinimum is 1."); onlyShowWithScoreboard = config.Bind<bool>("Display", "onlyShowWithScoreboard", false, "Only show the Damage Log when the scoreboard is open."); useSimpleTextMode = config.Bind<bool>("Display", "useSimpleTextMode", false, "Display Damage Log entries as text instead of portraits with tooltips."); hideDamageTimer = config.Bind<bool>("Display", "hideDamageTimer", false, "Hide the timer portion of each Damage Log entry showing how long it has been since the damage was inflicted."); maximumPortraitCount = config.Bind<int>("Display: Portraits Mode", "maximumPortraitCount", 12, "The maximum number of Damage Log entry portraits to show at a time.\nMinimum is 1."); showDamageIdentifier = config.Bind<bool>("Display: Portraits Mode", "showDamageIdentifier", false, "Show the damage identifier in the portrait tooltip. Can show additional information about damage attributed to The Planet."); compactLines = config.Bind<bool>("Display: Simple Text Mode", "compactLines", false, "Remove empty lines used as separators between Damage Log entries."); showRawDamageInsteadOfPercentage = config.Bind<bool>("Display: Simple Text Mode", "showRawDamageInsteadOfPercentage", false, "Show the raw damage value instead of the percentage of full combined health."); cycleUserKey = config.BindInputKey("Controls", "cycleUserKey", "left alt", "The key to use to cycle which user's Damage Log should be shown."); cycleBossKey = config.BindInputKey("Controls", "cycleBossKey", "`", "The key to use to cycle which boss's Damage Log should be shown."); canvasOffsetRight = config.Bind<float>("m_Debug", "canvasOffsetRight", 8f, (ConfigDescription)null); canvasOffsetTop = config.Bind<float>("m_Debug", "canvasOffsetTop", 12f, (ConfigDescription)null); canvasWidth = config.Bind<float>("m_Debug", "canvasWidth", 88f, (ConfigDescription)null); textSize = config.Bind<float>("m_Debug", "textSize", 14f, (ConfigDescription)null); portraitSpacing = config.Bind<float>("m_Debug", "portraitSpacing", 8f, (ConfigDescription)null); portraitSize = config.Bind<float>("m_Debug", "portraitSize", 78f, (ConfigDescription)null); eliteIconSize = config.Bind<float>("m_Debug", "eliteIconSize", 24f, (ConfigDescription)null); portraitTextSize = config.Bind<float>("m_Debug", "portraitTextSize", 18f, (ConfigDescription)null); damageTextSize = config.Bind<float>("m_Debug", "damageTextSize", 20f, (ConfigDescription)null); } } public static class DamageDealtMessageExtension { public static bool IsFallDamage(this DamageDealtMessage e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) return DamageTypeCombo.op_Implicit(e.damageType & DamageTypeCombo.op_Implicit((DamageType)2097152)) != 0; } public static bool IsVoidFogDamage(this DamageDealtMessage e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if ((int)DamageTypeCombo.op_Implicit(e.damageType) == 66 && (int)e.damageColorIndex == 9) { return (Object)(object)e.attacker == (Object)null; } return false; } public static bool IsMeridianLightningDamage(this DamageDealtMessage e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) return DamageTypeCombo.op_Implicit(e.damageType) == DamageTypeCombo.op_Implicit(DamageTypeCombo.Generic | DamageTypeCombo.op_Implicit((DamageType)131072) | DamageTypeCombo.op_Implicit((DamageType)1073741824) | DamageTypeCombo.op_Implicit((DamageTypeExtended)268435456) | DamageTypeCombo.op_Implicit((DamageTypeExtended)536870912)); } public static string GetAttackerName(this DamageDealtMessage e) { string result = Language.GetString("UNIDENTIFIED_KILLER_NAME"); if ((Object)(object)e.attacker != (Object)null) { string bestBodyName = Util.GetBestBodyName(e.attacker); if (!string.IsNullOrEmpty(bestBodyName)) { result = bestBodyName; } } else if (e.IsFallDamage()) { result = "The Ground"; } else if (e.IsVoidFogDamage()) { result = "Void Fog"; } return result; } public static string GenerateIdentifier(this DamageDealtMessage e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) string result = $"?? | {e.damageType} | {e.damageColorIndex} | {e.damage}"; if (e.IsFallDamage()) { result = "fall_damage"; } if (e.IsVoidFogDamage()) { result = "void_fog_damage"; } if ((Object)(object)e.attacker != (Object)null) { result = $"{((Object)e.attacker).GetInstanceID()} | {e.GetAttackerName()}"; } else if (e.IsMeridianLightningDamage()) { result = "meridian_lightning"; } return result; } } public class DamageLog { private readonly CharacterBody targetBody; private readonly string targetName; private readonly Dictionary<string, DamageSource> entries = new Dictionary<string, DamageSource>(); private float timeOfDeath = -1f; public float Time { get { if (!(timeOfDeath > 0f)) { return Time.time; } return timeOfDeath; } } public virtual string displayName => targetName; public virtual string loggingName => targetName; public DamageLog(NetworkUser user, CharacterBody body) : this(body, user.userName) { } protected DamageLog(CharacterBody targetBody, string targetName) { this.targetBody = targetBody; this.targetName = targetName; Track(targetBody); } private DamageLog Track(CharacterBody body) { GlobalEventManager.onClientDamageNotified += Record; body.master.onBodyDestroyed += Cease; Plugin.Logger.LogDebug((object)("Tracking " + loggingName + ".")); return this; } internal void Untrack() { if (timeOfDeath <= 0f) { timeOfDeath = Time.time; } GlobalEventManager.onClientDamageNotified -= Record; CharacterBody obj = targetBody; if ((Object)(object)((obj != null) ? obj.master : null) != (Object)null) { targetBody.master.onBodyDestroyed -= Cease; } else { Plugin.Logger.LogWarning((object)("Could not unsubscribe RoR2.CharacterMaster::onBodyDestroyed for " + loggingName + ".")); } } private void Cease(CharacterBody _) { Untrack(); Plugin.Logger.LogDebug((object)("Untracking " + loggingName + " (body destroyed).")); } private void Record(DamageDealtMessage e) { if (!((Object)(object)targetBody == (Object)null) && !((Object)(object)e.victim != (Object)(object)((Component)targetBody).gameObject)) { string key = e.GenerateIdentifier(); if (entries.TryGetValue(key, out var value) && !IsExpired(Time - value.time)) { value.Add(e); } else { entries.Remove(key); value = new DamageSource(e); entries.Add(key, value); } if (value.remainingHpPercent <= 0f) { timeOfDeath = Time.time; } Decay(); } } private void Decay() { float time = Time; foreach (DamageSource entry in GetEntries()) { if (IsExpired(time - entry.time)) { entries.Remove(entry.identifier); } } } public virtual bool IsExpired(float elapsedTime) { return elapsedTime > Plugin.Config.EntryMaxRetainTime; } public List<DamageSource> GetEntries() { List<DamageSource> list = entries.Values.ToList(); if (list.Count > 1) { list.Sort((DamageSource a, DamageSource b) => Math.Sign(b.time - a.time)); } return list; } } internal sealed class DamageLogUI : MonoBehaviour { private static HUD hud; private int bossIndex; private bool showingBoss; private Canvas canvas; private HGTextMeshProUGUI text; private readonly List<DamageSourceUI> uiEntries = new List<DamageSourceUI>(); public NetworkUser user { get; private set; } public static void Instantiate(HUD hud, ref bool _) { if (!((Object)(object)DamageLogUI.hud != (Object)null)) { Plugin.Logger.LogDebug((object)"Adding to HUD."); ((Component)hud).gameObject.AddComponent<DamageLogUI>(); DamageLogUI.hud = hud; } } internal static void MoveToGameEndReportPanel(GameEndReportPanelController panel) { if ((Object)(object)hud == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to move canvas (no HUD). This can safely be ignored if triggered by viewing Game End Report from Run History."); return; } DamageLogUI component = ((Component)hud).gameObject.GetComponent<DamageLogUI>(); if ((Object)(object)component == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to move canvas (missing)."); return; } Transform val = ((Component)panel).transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name.Contains("Logbook") || ((Object)val).name.Contains("Pause")) { Plugin.Logger.LogWarning((object)"Blocked attempt to move canvas. This can safely be ignored if triggered by viewing Game End Report from Run History mid-run."); return; } val = val.parent; } ((Behaviour)component).enabled = false; if ((Object)(object)component.canvas == (Object)null) { Plugin.Logger.LogWarning((object)"Attempting to move canvas but it has not been created. Attempting to create."); component.CreateUI(hud.mainContainer); } ((Component)component.canvas).transform.SetParent(((Component)panel).transform); ((Behaviour)component.canvas).enabled = true; Plugin.Logger.LogDebug((object)"Moved canvas."); } internal static void DisplayPlayerDamageLog(NetworkUser user) { if ((Object)(object)hud == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to update canvas (no HUD). This can safely be ignored if triggered by viewing Game End Report from Run History."); return; } DamageLogUI component = ((Component)hud).gameObject.GetComponent<DamageLogUI>(); if ((Object)(object)component == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to update canvas (missing)."); return; } if ((Object)(object)user == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to display player damage log (null)."); return; } if (!Plugin.Data.TryGetUserLog(user, out var log)) { Plugin.Logger.LogWarning((object)("Failed to find damage log for " + user.userName + ".")); return; } component.UpdateText(log); component.UpdatePortraits(log); } private void Start() { CreateUI(hud.mainContainer); } private void CreateUI(GameObject parent) { Plugin.Config.Reload(); HUD obj = hud; object obj2; if (obj == null) { obj2 = null; } else { LocalUser localUserViewer = obj.localUserViewer; obj2 = ((localUserViewer != null) ? localUserViewer.currentNetworkUser : null); } user = (NetworkUser)obj2; if ((Object)(object)user == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to get HUD user (null)."); } CreateCanvas(parent); CreateText(); if (!Plugin.Config.SimpleTextMode) { CreatePortraits(); } Plugin.Logger.LogDebug((object)"Created canvas."); } private void CreateCanvas(GameObject parent) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) canvas = new GameObject("DamageLogUI", new Type[2] { typeof(Canvas), typeof(GraphicRaycaster) }).GetComponent<Canvas>(); RectTransform component = ((Component)canvas).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent.transform); ResetRectTransform(component); AnchorStretchRight(component); component.pivot = Vector2.one; ((Transform)component).localPosition = ((Transform)component).localPosition - Vector2.op_Implicit(Plugin.Config.CanvasOffsetTopRight); component.sizeDelta = Vector2.right * Plugin.Config.CanvasWidth - Vector2.up * Plugin.Config.CanvasOffsetTopRight; } private void CreatePortraits() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown VerticalLayoutGroup obj = ((Component)canvas).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).spacing = Plugin.Config.PortraitSpacing; for (int i = 0; i < Plugin.Config.MaximumPortraitCount; i++) { uiEntries.Add(DamageSourceUI.Instantiate((RectTransform)((Component)canvas).transform).Hide()); } } private void CreateText() { //IL_0018: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject("DamageLogText", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(((Component)canvas).transform); ResetRectTransform(component); AnchorTopStretch(component); component.pivot = Vector2.one; component.sizeDelta = (Vector2)(Plugin.Config.SimpleTextMode ? Vector2.zero : new Vector2(((RectTransform)((Component)canvas).transform).sizeDelta.x, 0f)); text = ((Component)component).gameObject.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)text).fontSize = Plugin.Config.TextSize; ((TMP_Text)text).SetText("<style=cDeath>Damage Log <null></style>", true); } private void ListenForRebuild() { if (Input.GetKey((KeyCode)278) && Input.GetKeyDown((KeyCode)279)) { Plugin.Logger.LogWarning((object)"Rebuild input triggered, destroying DamageLogUI."); Object.Destroy((Object)(object)((Component)canvas).gameObject); Object.Destroy((Object)(object)this); hud = null; } } private void Update() { bool flag = !Plugin.Config.OnlyShowWithScoreboard || hud.scoreboardPanel.activeSelf; ((Behaviour)canvas).enabled = flag; if (!flag) { return; } ListenForRebuild(); bool reverse = Input.GetKey("left shift") || Input.GetKey("right shift"); bool keyDown = Input.GetKeyDown(Plugin.Config.CycleUserKey); bool flag2 = Plugin.Config.TrackBosses && Input.GetKeyDown(Plugin.Config.CycleBossKey); if (keyDown) { if (!showingBoss) { user = Plugin.Data.CycleUser(user, reverse); } showingBoss = false; } else if (flag2 && Plugin.Data.HasBossLogs) { if (showingBoss) { bossIndex = Plugin.Data.CycleBossIndex(bossIndex, reverse); } showingBoss = true; } if ((!showingBoss && (Object)(object)user != (Object)null && Plugin.Data.TryGetUserLog(user, out var log)) || (showingBoss && Plugin.Data.TryGetBossLog(bossIndex, out log))) { UpdateText(log); UpdatePortraits(log); } } private void UpdateText(DamageLog log) { //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_0023: 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_0052: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)text).SetText(GenerateTextLog(log), true); Vector2 sizeDelta = ((TMP_Text)text).rectTransform.sizeDelta; if (sizeDelta.y != ((TMP_Text)text).preferredHeight) { ((TMP_Text)text).rectTransform.sizeDelta = new Vector2(sizeDelta.x, ((TMP_Text)text).preferredHeight); } } private void UpdatePortraits(DamageLog log) { if (Plugin.Config.SimpleTextMode) { return; } float time = log.Time; List<DamageSource> entries = log.GetEntries(); for (int i = 0; i < uiEntries.Count; i++) { if (i >= entries.Count) { uiEntries[i].Hide(); continue; } float elapsedTime = time - entries[i].time; if (log.IsExpired(elapsedTime)) { uiEntries[i].Hide(); } else { uiEntries[i].Display(entries[i], elapsedTime); } } } private static string GenerateTextLog(DamageLog log) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("<style=cWorldEvent>Damage Log"); stringBuilder.AppendLine("<" + log.displayName + "></style>"); if (!Plugin.Config.SimpleTextMode) { return stringBuilder.ToString(); } float time = log.Time; foreach (DamageSource entry in log.GetEntries()) { float num = time - entry.time; if (!log.IsExpired(num)) { if (!Plugin.Config.CompactLines) { stringBuilder.AppendLine(); } string text = (entry.isPlayerDamage ? "cDeath" : (entry.isFallDamage ? "cHumanObjective" : (entry.isVoidFogDamage ? "cIsVoid" : ""))); if (string.IsNullOrEmpty(text)) { stringBuilder.Append(entry.attackerName); } else { stringBuilder.Append("<style=" + text + ">" + entry.attackerName + "</style>"); } bool num2 = entry.hits == 1; if (!num2) { stringBuilder.Append($"<style=cStack><nobr>×{entry.hits}</nobr></style>"); } if (Plugin.Config.ShowRawDamageInsteadOfPercentage) { stringBuilder.Append($" · <style=cIsHealth><nobr>{-1f * entry.totalDamage:0.0}</nobr></style>"); } else { stringBuilder.Append($" · <style=cIsDamage><nobr>{-1f * entry.totalDamagePercent:0.0%}</nobr></style>"); } if (num2) { stringBuilder.Append($" <style=cEvent><nobr>({entry.remainingHpPercent:0.0%})</nobr></style>"); } if (!Plugin.Config.HideDamageTimer) { stringBuilder.AppendLine($" · <style=cSub>{num:0.00s}</style>"); } else { stringBuilder.AppendLine(); } } } return stringBuilder.ToString(); } public static RectTransform ResetRectTransform(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) ((Transform)rect).localPosition = Vector3.zero; ((Transform)rect).localScale = Vector3.one; ((Transform)rect).localRotation = Quaternion.identity; ((Component)rect).gameObject.layer = LayerMask.NameToLayer("UI"); return rect; } private static RectTransform AnchorStretchRight(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) rect.anchoredPosition = Vector2.zero; rect.anchorMin = Vector2.right; rect.anchorMax = Vector2.one; return rect; } private static RectTransform AnchorTopStretch(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) rect.anchoredPosition = Vector2.zero; rect.anchorMin = Vector2.up; rect.anchorMax = Vector2.one; return rect; } } public sealed class DamageSource { private static Texture _PlanetPortrait; private static Texture _SotVPortrait; private static Sprite _CollectiveEliteIcon; public readonly string identifier; public readonly string attackerName; public readonly Texture attackerPortrait; public readonly Color attackerPortraitColor; public readonly Sprite eliteIcon; public readonly Color eliteIconColor; public readonly bool isPlayerDamage; public readonly bool isFallDamage; public readonly bool isVoidFogDamage; public readonly float timeStart; private static Texture PlanetPortrait => _PlanetPortrait ?? (_PlanetPortrait = LegacyResourcesAPI.Load<Texture>("Textures/BodyIcons/texUnidentifiedKillerIcon")); private static Texture SotVPortrait => _SotVPortrait ?? (_SotVPortrait = Addressables.LoadAssetAsync<Texture>((object)"RoR2/DLC1/UI/texVoidExpansionIcon.png").WaitForCompletion()); private static Sprite CollectiveEliteIcon => _CollectiveEliteIcon ?? (_CollectiveEliteIcon = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/DLC3/Collective/texEliteCollectiveIcon.png").WaitForCompletion()); public float time { get; private set; } public int hits { get; private set; } public float totalDamage { get; private set; } public float totalDamagePercent { get; private set; } public float remainingHpPercent { get; private set; } public DamageSource(DamageDealtMessage e) { GameObject attacker = e.attacker; CharacterBody val = ((attacker != null) ? attacker.GetComponent<CharacterBody>() : null); isPlayerDamage = val != null && val.isPlayerControlled; isFallDamage = e.IsFallDamage(); isVoidFogDamage = e.IsVoidFogDamage(); identifier = e.GenerateIdentifier(); attackerName = e.GetAttackerName(); GetAttackerPortrait(e, out attackerPortrait, out attackerPortraitColor); GetEliteIcon(val, out eliteIcon, out eliteIconColor); timeStart = Time.time; time = timeStart; hits = 1; totalDamage = e.damage; UpdateHpDamagePercent(e.victim, e.damage); } public DamageSource Add(DamageDealtMessage e) { time = Time.time; hits++; totalDamage += e.damage; UpdateHpDamagePercent(e.victim, e.damage); return this; } private void UpdateHpDamagePercent(GameObject victim, float latestHitDamage) { HealthComponent val = ((victim != null) ? victim.GetComponent<HealthComponent>() : null); if ((Object)(object)val != (Object)null) { remainingHpPercent = (NetworkServer.active ? val.combinedHealthFraction : ((val.combinedHealth - latestHitDamage) / val.fullCombinedHealth)); totalDamagePercent = totalDamage / val.fullCombinedHealth; } else { Plugin.Logger.LogWarning((object)"Could not UpdateHpDamagePercent"); } } private static void GetAttackerPortrait(DamageDealtMessage e, out Texture portrait, out Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) portrait = PlanetPortrait; color = Color.white; if ((Object)(object)e.attacker != (Object)null) { Texture val = e.attacker.GetComponent<CharacterBody>()?.portraitIcon; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)PlanetPortrait) { val = GetAlternativeAttackerPortrait(e.attacker, e.GetAttackerName(), ref color); } if ((Object)(object)val != (Object)null) { portrait = val; } } else if (e.IsFallDamage()) { portrait = (Texture)(object)Artifacts.weakAssKneesArtifactDef.smallIconSelectedSprite.texture; } else if (e.IsVoidFogDamage()) { portrait = (Texture)(object)Buffs.VoidFogMild.iconSprite.texture; color = DamageColor.FindColor((DamageColorIndex)9); } else if (e.IsMeridianLightningDamage()) { portrait = (Texture)(object)Buffs.lunarruin.iconSprite.texture; } } private static Texture GetAlternativeAttackerPortrait(GameObject attacker, string attackerName, ref Color color) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (attackerName == Language.GetString("SHRINE_BLOOD_NAME")) { color = Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)9)); if (attacker == null) { return null; } ShrineBloodBehavior component = attacker.GetComponent<ShrineBloodBehavior>(); if (component == null) { return null; } Transform symbolTransform = component.symbolTransform; if (symbolTransform == null) { return null; } MeshRenderer component2 = ((Component)symbolTransform).GetComponent<MeshRenderer>(); if (component2 == null) { return null; } Material material = ((Renderer)component2).material; if (material == null) { return null; } return material.mainTexture; } if (attackerName == Language.GetString("VOID_CHEST_NAME") || attackerName == Language.GetString("VOID_TRIPLE_NAME")) { return SotVPortrait; } if (attackerName == Language.GetString("ARTIFACTSHELL_BODY_NAME")) { return (Texture)(object)Items.ArtifactKey.pickupIconSprite.texture; } return null; } private static void GetEliteIcon(CharacterBody body, out Sprite icon, out Color color) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) BuffDef eliteBuffDef = GetEliteBuffDef(body); icon = eliteBuffDef?.iconSprite; color = eliteBuffDef?.buffColor ?? Color.white; if ((Object)(object)icon == (Object)null && eliteBuffDef?.eliteDef?.modifierToken == "ELITE_MODIFIER_COLLECTIVE") { icon = CollectiveEliteIcon; } else if (eliteBuffDef?.eliteDef?.modifierToken == "ELITE_MODIFIER_COLLECTIVE") { Plugin.Logger.LogWarning((object)$"collective elite buff has been assigned an icon! '{icon}'"); } } private static BuffDef GetEliteBuffDef(CharacterBody body) { //IL_0022: 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_002c: Unknown result type (might be due to invalid IL or missing references) BuffDef result = null; if ((Object)(object)body == (Object)null || !body.isElite) { return result; } BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices; foreach (BuffIndex val in eliteBuffIndices) { if (body.HasBuff(val)) { result = BuffCatalog.GetBuffDef(val); } } return result; } } internal sealed class DamageSourceUI : MonoBehaviour { private RawImage portrait; private Image elite; private HGTextMeshProUGUI damage; private HGTextMeshProUGUI hits; private HGTextMeshProUGUI time; private TooltipProvider tooltip; public static DamageSourceUI Instantiate(RectTransform parent) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)new GameObject("DamageEntry", new Type[2] { typeof(DamageSourceUI), typeof(RawImage) }).transform; ((Transform)val).SetParent((Transform)(object)parent, false); val.sizeDelta = Vector2.one * ((Plugin.Config.PortraitSize > 0f) ? Plugin.Config.PortraitSize : parent.sizeDelta.x); return ((Component)val).GetComponent<DamageSourceUI>().Build(val); } private DamageSourceUI Build(RectTransform root) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) float x = root.sizeDelta.x; tooltip = ((Component)root).gameObject.AddComponent<TooltipProvider>(); portrait = ((Component)root).GetComponent<RawImage>(); elite = AddChild<Image>(root, "elite"); AnchorTopLeft(((Graphic)elite).rectTransform); ((Graphic)elite).rectTransform.sizeDelta = Vector2.one * Plugin.Config.EliteIconSize; damage = AddChild<HGTextMeshProUGUI>(root, "damage"); AnchorTopRight(((TMP_Text)damage).rectTransform); ((TMP_Text)damage).enableWordWrapping = false; ((TMP_Text)damage).alignment = (TextAlignmentOptions)260; ((TMP_Text)damage).rectTransform.sizeDelta = Vector2.one * (x - Plugin.Config.EliteIconSize); ((TMP_Text)damage).fontSize = Plugin.Config.DamageTextSize; hits = AddChild<HGTextMeshProUGUI>(root, "hits"); AnchorBottomLeft(((TMP_Text)hits).rectTransform); ((TMP_Text)hits).enableWordWrapping = false; ((TMP_Text)hits).alignment = (TextAlignmentOptions)1025; ((TMP_Text)hits).rectTransform.sizeDelta = Vector2.one * (x / 2f); ((TMP_Text)hits).fontSize = Plugin.Config.PortraitTextSize; time = AddChild<HGTextMeshProUGUI>(root, "time"); AnchorBottomRight(((TMP_Text)time).rectTransform); ((TMP_Text)time).enableWordWrapping = false; ((TMP_Text)time).alignment = (TextAlignmentOptions)1028; ((TMP_Text)time).rectTransform.sizeDelta = Vector2.one * (x / 2f); ((TMP_Text)time).fontSize = Plugin.Config.PortraitTextSize; if (Plugin.Config.HideDamageTimer) { ((Component)time).gameObject.SetActive(false); } return this; } private static T AddChild<T>(RectTransform parent, string name) where T : Graphic { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(T) }); val.transform.SetParent((Transform)(object)parent); DamageLogUI.ResetRectTransform((RectTransform)val.transform); T component = val.GetComponent<T>(); ((Graphic)component).raycastTarget = false; return component; } public void Display(DamageSource src, float elapsedTime) { //IL_0034: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_012a: Unknown result type (might be due to invalid IL or missing references) if (src == null) { Hide(); return; } ((Component)portrait).gameObject.SetActive(true); portrait.texture = src.attackerPortrait; ((Graphic)portrait).color = src.attackerPortraitColor; if ((Object)(object)src.eliteIcon != (Object)null) { elite.sprite = src.eliteIcon; ((Graphic)elite).color = src.eliteIconColor; ((Behaviour)elite).enabled = true; } else { ((Behaviour)elite).enabled = false; } ((TMP_Text)damage).SetText($"<style=cIsDamage>{-1f * src.totalDamagePercent:0.0%}</style>", true); if (src.hits == 1) { ((TMP_Text)hits).SetText("", true); } else { ((TMP_Text)hits).SetText($"<style=cStack>×{src.hits}</style>", true); } ((TMP_Text)time).SetText($"<style=cSub>{elapsedTime:0.00s}</style>", true); tooltip.titleColor = Color32.op_Implicit(src.isPlayerDamage ? ColorCatalog.GetColor((ColorIndex)17) : (src.isFallDamage ? ColorCatalog.GetColor((ColorIndex)16) : (src.isVoidFogDamage ? ColorCatalog.GetColor((ColorIndex)25) : ColorCatalog.GetColor((ColorIndex)20)))); tooltip.titleToken = src.attackerName; tooltip.bodyToken = GenerateTooltipString(src); } public DamageSourceUI Hide() { ((Component)portrait).gameObject.SetActive(false); return this; } private static string GenerateTooltipString(DamageSource src) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append($"Dealt <style=cIsHealth>{src.totalDamage:0.0}</style> damage"); if (src.hits == 1) { stringBuilder.Append($" <style=cEvent>({src.remainingHpPercent:0.0%} health remaining)</style>"); } else { stringBuilder.Append($" in <style=cStack>{src.hits} hits</style> over <style=cSub>{src.time - src.timeStart:0.00s}</style>"); } stringBuilder.AppendLine("."); if (Plugin.Config.ShowIdentifier) { stringBuilder.AppendLine(); stringBuilder.AppendLine("<style=cIsDamage>" + src.identifier + "</style>"); } return stringBuilder.ToString(); } private static void AnchorTopLeft(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Anchor(rect, Vector2.up); } private static void AnchorTopRight(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Anchor(rect, Vector2.one); } private static void AnchorBottomLeft(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Anchor(rect, Vector2.zero); } private static void AnchorBottomRight(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Anchor(rect, Vector2.right); } private static void Anchor(RectTransform rect, Vector2 anchor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) Vector2 val2 = (rect.anchorMax = anchor); Vector2 pivot = (rect.anchorMin = val2); rect.pivot = pivot; } } internal sealed class Data { private readonly Dictionary<NetworkUser, DamageLog> userLogs = new Dictionary<NetworkUser, DamageLog>(); private readonly Dictionary<uint, DamageLog> bossLogs = new Dictionary<uint, DamageLog>(); public bool HasBossLogs => bossLogs.Count > 0; internal void AddUserLog(NetworkUser user, DamageLog log) { Add(userLogs, user, log); } internal void AddBossLog(BossDamageLog log) { Add(bossLogs, log.targetNetId, log); } internal bool TryGetUserLog(NetworkUser user, out DamageLog log) { return userLogs.TryGetValue(user, out log); } internal bool TryGetBossLog(int index, out DamageLog log) { return TryGetDamageLog(index, bossLogs, out log); } internal void ClearUserLogs() { Plugin.Logger.LogDebug((object)$"Clearing user damage logs ({userLogs.Count})."); Clear(userLogs); } internal void ClearBossLogs() { if (bossLogs.Count > 0) { Plugin.Logger.LogDebug((object)$"Clearing boss damage logs ({bossLogs.Count})."); Clear(bossLogs); } } internal void ClearAll() { ClearUserLogs(); ClearBossLogs(); } internal NetworkUser CycleUser(NetworkUser current, bool reverse) { if (userLogs.Count <= 0) { return null; } int index = ((!((Object)(object)current == (Object)null)) ? NetworkUser.readOnlyInstancesList.IndexOf(current) : 0); index = CycleCollectionIndex(index, NetworkUser.readOnlyInstancesList, reverse); NetworkUser val = NetworkUser.readOnlyInstancesList[index]; if (userLogs.ContainsKey(val)) { return val; } return CycleUser(val, reverse); } internal int CycleBossIndex(int current, bool reverse) { return CycleCollectionIndex(current, bossLogs, reverse); } internal static int CycleCollectionIndex(int index, ICollection collection, bool reverse) { index = ((!reverse) ? (index + 1) : (index - 1)); if (index < 0) { index = collection.Count - 1; } else if (index >= collection.Count) { index = 0; } return index; } public static void Add<TKey>(Dictionary<TKey, DamageLog> logs, TKey key, DamageLog newLog) { if (logs.TryGetValue(key, out var value)) { value.Untrack(); Plugin.Logger.LogDebug((object)("Untracking " + value.loggingName + " (replacing).")); } logs[key] = newLog; } public static void Clear<TKey>(Dictionary<TKey, DamageLog> logs) { foreach (DamageLog value in logs.Values) { value.Untrack(); Plugin.Logger.LogDebug((object)("Untracking " + value.loggingName + " (clearing).")); } logs.Clear(); } public static bool TryGetDamageLog<TKey>(int index, Dictionary<TKey, DamageLog> dictionary, out DamageLog log) { log = null; if (index < 0) { return false; } if (index >= dictionary.Count) { return false; } log = dictionary.ElementAt(index).Value; return true; } } [HarmonyPatch] internal static class HarmonyPatches { [HarmonyPostfix] [HarmonyPatch(typeof(GameEndReportPanelController), "Awake")] private static void GameEndReportPanelController_Awake(GameEndReportPanelController __instance) { try { DamageLogUI.MoveToGameEndReportPanel(__instance); } catch (Exception ex) { Plugin.Logger.LogError((object)ex); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameEndReportPanelController), "SetPlayerInfo")] private static void GameEndReportPanelController_SetPlayerInfo(PlayerInfo playerInfo) { try { DamageLogUI.DisplayPlayerDamageLog(playerInfo?.networkUser); } catch (Exception ex) { Plugin.Logger.LogError((object)ex); } } [HarmonyPostfix] [HarmonyPatch(typeof(BossGroup), "OnMemberDiscovered")] private static void BossGroup_OnMemberDiscovered(BossGroup __instance, CharacterMaster memberMaster) { try { Plugin.TrackBoss(__instance, memberMaster); } catch (Exception ex) { Plugin.Logger.LogError((object)ex); } } } [BepInPlugin("itsschwer.DamageLog", "DamageLog", "1.2.9")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static ShouldHudDisplayDelegate <0>__Instantiate; public static Action<CharacterBody> <1>__TrackUser; public static Action<Run> <2>__OnRunStartOrDestroy; public static Action<Stage> <3>__OnStageStart; public static Action<CharacterBody> <4>__TrackBoss; } public const string GUID = "itsschwer.DamageLog"; public const string Author = "itsschwer"; public const string Name = "DamageLog"; public const string Version = "1.2.9"; internal static ManualLogSource Logger { get; private set; } internal static Config Config { get; private set; } internal static Data Data { get; private set; } private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Logger.Sources.Remove((ILogSource)(object)((BaseUnityPlugin)this).Logger); Logger = Logger.CreateLogSource("itsschwer.DamageLog"); Config = new Config(((BaseUnityPlugin)this).Config); Data = new Data(); if (Compatibility.DamageInfoChanged()) { Object.DestroyImmediate((Object)(object)this); return; } new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll(); Logger.LogMessage((object)"~awake."); } private void OnEnable() { //IL_0010: 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_001b: Expected O, but got Unknown object obj = <>O.<0>__Instantiate; if (obj == null) { ShouldHudDisplayDelegate val = DamageLogUI.Instantiate; <>O.<0>__Instantiate = val; obj = (object)val; } HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj; CharacterBody.onBodyStartGlobal += TrackUser; Run.onRunStartGlobal += OnRunStartOrDestroy; Run.onRunDestroyGlobal += OnRunStartOrDestroy; Stage.onStageStartGlobal += OnStageStart; Logger.LogMessage((object)"~enabled."); } private void OnDisable() { //IL_0010: 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_001b: Expected O, but got Unknown object obj = <>O.<0>__Instantiate; if (obj == null) { ShouldHudDisplayDelegate val = DamageLogUI.Instantiate; <>O.<0>__Instantiate = val; obj = (object)val; } HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj; CharacterBody.onBodyStartGlobal -= TrackUser; Run.onRunStartGlobal -= OnRunStartOrDestroy; Run.onRunDestroyGlobal -= OnRunStartOrDestroy; Stage.onStageStartGlobal -= OnStageStart; Logger.LogMessage((object)"~disabled."); } private static void OnRunStartOrDestroy(Run _) { Data.ClearAll(); } private static void OnStageStart(Stage _) { Data.ClearBossLogs(); } private static void TrackUser(CharacterBody body) { if (body.isPlayerControlled) { NetworkUser val = Util.LookUpBodyNetworkUser(body); if (!((Object)(object)val == (Object)null)) { DamageLog log = new DamageLog(val, body); Data.AddUserLog(val, log); } } } internal static void TrackBoss(BossGroup boss, CharacterMaster member) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (Config.TrackBosses) { ManualLogSource logger = Logger; object[] obj = new object[4] { "TrackBoss", ((Object)member).name, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)member).netId; obj[2] = ((NetworkInstanceId)(ref netId)).Value; obj[3] = ((Object)boss).name; logger.LogDebug((object)string.Format("{0}> Discovered {1} <{2:x8}> | {3}", obj)); member.onBodyStart += TrackBoss; } } private static void TrackBoss(CharacterBody body) { //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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) body.master.onBodyStart -= TrackBoss; if (!BossDamageLog.IsIgnoredBossSubtitle(body.subtitleNameToken)) { ManualLogSource logger = Logger; object[] obj = new object[5] { "TrackBoss", ((Object)body.master).name, null, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)body.master).netId; obj[2] = ((NetworkInstanceId)(ref netId)).Value; obj[3] = ((Object)body).name; netId = ((NetworkBehaviour)body).netId; obj[4] = ((NetworkInstanceId)(ref netId)).Value; logger.LogDebug((object)string.Format("{0}> Found {1} <{2:x8}> | {3} <{4:x8}>", obj)); Data.AddBossLog(new BossDamageLog(body)); } } } }