using 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.5.0")]
[assembly: AssemblyInformationalVersion("1.2.5+0d472968ff35083749d9e161d7fe412da0901ee2")]
[assembly: AssemblyProduct("DamageLog")]
[assembly: AssemblyTitle("DamageLog")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.5.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();
}
public 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 Cease(CharacterBody _ = null)
{
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 + "."));
}
MethodBase method = new StackTrace().GetFrame(1).GetMethod();
Plugin.Logger.LogDebug((object)$"Untracking {loggingName}. | {method.DeclaringType}::{method.Name}");
}
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;
}
((Component)component.canvas).transform.SetParent(((Component)panel).transform);
((Behaviour)component.canvas).enabled = true;
((Behaviour)component).enabled = false;
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()
{
int num;
if (Plugin.Config.OnlyShowWithScoreboard)
{
LocalUser localUserViewer = hud.localUserViewer;
num = ((((localUserViewer != null) ? localUserViewer.inputPlayer : null) != null && hud.localUserViewer.inputPlayer.GetButton("info")) ? 1 : 0);
}
else
{
num = 1;
}
bool flag = (byte)num != 0;
((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;
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());
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;
}
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.");
Clear(userLogs);
}
internal void ClearBossLogs()
{
Plugin.Logger.LogDebug((object)"Clearing boss damage logs.");
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.Cease();
Plugin.Logger.LogDebug((object)"Replacing existing damage log.");
}
logs[key] = newLog;
}
public static void Clear<TKey>(Dictionary<TKey, DamageLog> logs)
{
foreach (DamageLog value in logs.Values)
{
value.Cease();
}
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)
{
DamageLogUI.MoveToGameEndReportPanel(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameEndReportPanelController), "SetPlayerInfo")]
private static void GameEndReportPanelController_SetPlayerInfo(PlayerInfo playerInfo)
{
DamageLogUI.DisplayPlayerDamageLog(playerInfo?.networkUser);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(BossGroup), "OnMemberDiscovered")]
private static void BossGroup_OnMemberDiscovered(BossGroup __instance, CharacterMaster memberMaster)
{
Plugin.TrackBoss(__instance, memberMaster);
}
}
[BepInPlugin("itsschwer.DamageLog", "DamageLog", "1.2.5")]
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.5";
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));
}
}
}
}