Decompiled source of DamageAnalyzer Restored v2.0.1

BepInEx\plugins\Hikaria.DamageAnalyzer\Hikaria.DamageAnalyzer.dll

Decompiled a day ago
using System;
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 Agents;
using BepInEx;
using Enemies;
using GameData;
using Gear;
using Hikaria.Core;
using Hikaria.Core.SNetworkExt;
using Hikaria.DamageAnalyzer.Features;
using Hikaria.DamageAnalyzer.Handlers;
using Hikaria.DamageAnalyzer.Managers;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Collections.Generic;
using Player;
using SNetwork;
using TMPro;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature;
using TheArchive.Core.Attributes.Feature.Members;
using TheArchive.Core.Attributes.Feature.Patches;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.Localization;
using TheArchive.Core.Models;
using TheArchive.Core.ModulesAPI;
using TheArchive.Interfaces;
using TheArchive.Loader;
using TheArchive.Utilities;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Hikaria.DamageAnalyzer
{
	internal static class DebugTypeScanner
	{
		private static readonly string[] Keywords = new string[12]
		{
			"Damage", "Dam_", "EnemyDamage", "EnemyDamageLimb", "BulletWeapon", "BulletHit", "MeleeDamage", "BulletDamage", "SentryGunInstance", "PUI_Watermark",
			"GuiManager", "Watermark"
		};

		private static bool _hasScanned;

		public static void Scan()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_008d: Expected O, but got Unknown
			if (_hasScanned)
			{
				return;
			}
			_hasScanned = true;
			try
			{
				string text = Path.Combine(Paths.BepInExRootPath, "interop");
				string text2 = Path.Combine(Paths.BepInExRootPath, "core");
				if (!Directory.Exists(text))
				{
					Logs.LogWarning("DebugTypeScanner skipped: interop folder not found at " + text + ".");
					return;
				}
				Logs.LogInfo("DebugTypeScanner scanning " + text + ".");
				DefaultAssemblyResolver val = new DefaultAssemblyResolver();
				((BaseAssemblyResolver)val).AddSearchDirectory(text);
				((BaseAssemblyResolver)val).AddSearchDirectory(text2);
				ReaderParameters readerParameters = new ReaderParameters
				{
					AssemblyResolver = (IAssemblyResolver)(object)val,
					InMemory = true
				};
				foreach (string item in Directory.EnumerateFiles(text, "*.dll"))
				{
					ScanAssembly(item, readerParameters);
				}
			}
			catch (Exception value)
			{
				Logs.LogError($"DebugTypeScanner failed: {value}");
			}
		}

		private static void ScanAssembly(string assemblyPath, ReaderParameters readerParameters)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			AssemblyDefinition val;
			try
			{
				val = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters);
			}
			catch (Exception ex)
			{
				Logs.LogWarning("DebugTypeScanner could not read " + Path.GetFileName(assemblyPath) + ": " + ex.Message);
				return;
			}
			AssemblyDefinition val2 = val;
			try
			{
				Enumerator<ModuleDefinition> enumerator = val.Modules.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						foreach (TypeDefinition item in EnumerateTypes((IEnumerable<TypeDefinition>)enumerator.Current.Types))
						{
							bool num = ContainsKeyword(((MemberReference)item).FullName);
							MethodDefinition[] array = ((IEnumerable<MethodDefinition>)item.Methods).Where((MethodDefinition method) => ContainsKeyword(((MemberReference)method).Name)).ToArray();
							if (num || array.Length != 0)
							{
								Logs.LogInfo($"DebugTypeScanner type {((MemberReference)item).FullName} [{Path.GetFileName(assemblyPath)}]");
								MethodDefinition[] array2 = array;
								foreach (MethodDefinition val3 in array2)
								{
									Logs.LogInfo($"DebugTypeScanner method {((MemberReference)item).FullName}.{((MemberReference)val3).Name}({FormatParameters(val3)}) -> {((MemberReference)((MethodReference)val3).ReturnType).FullName}");
								}
							}
						}
					}
				}
				finally
				{
					((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}

		private static IEnumerable<TypeDefinition> EnumerateTypes(IEnumerable<TypeDefinition> types)
		{
			foreach (TypeDefinition type in types)
			{
				yield return type;
				foreach (TypeDefinition item in EnumerateTypes((IEnumerable<TypeDefinition>)type.NestedTypes))
				{
					yield return item;
				}
			}
		}

		private static bool ContainsKeyword(string value)
		{
			return Keywords.Any((string keyword) => value.Contains(keyword, StringComparison.OrdinalIgnoreCase));
		}

		private static string FormatParameters(MethodDefinition method)
		{
			return string.Join(", ", ((IEnumerable<ParameterDefinition>)((MethodReference)method).Parameters).Select((ParameterDefinition parameter) => ((MemberReference)((ParameterReference)parameter).ParameterType).FullName + " " + ((ParameterReference)parameter).Name));
		}
	}
	[ArchiveDependency(/*Could not decode attribute arguments.*/)]
	[ArchiveModule("Hikaria.DamageAnalyzer", "DamageAnalyzer", "2.0.0")]
	public class EntryPoint : IArchiveModule
	{
		public ILocalizationService LocalizationService { get; set; }

		public IArchiveLogger Logger { get; set; }

		public void Init()
		{
			Logs.Setup(Logger);
		}
	}
	internal static class Logs
	{
		private const string Prefix = "[DamageAnalyzer.Restore]";

		private static IArchiveLogger _logger;

		public static void Setup(IArchiveLogger logger)
		{
			_logger = logger;
		}

		public static void LogDebug(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Debug(Format(data));
			}
		}

		public static void LogError(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Error(Format(data));
			}
		}

		public static void LogInfo(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Info(Format(data));
			}
		}

		public static void LogMessage(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Msg(ConsoleColor.White, Format(data));
			}
		}

		public static void LogWarning(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Warning(Format(data));
			}
		}

		public static void LogNotice(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Notice(Format(data));
			}
		}

		public static void LogSuccess(object data)
		{
			IArchiveLogger logger = _logger;
			if (logger != null)
			{
				logger.Success(Format(data));
			}
		}

		public static void LogException(Exception ex)
		{
			_logger.Exception(ex);
		}

		private static string Format(object data)
		{
			return $"{"[DamageAnalyzer.Restore]"} {data}";
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.DamageAnalyzer";

		public const string NAME = "DamageAnalyzer";

		public const string VERSION = "2.0.0";
	}
}
namespace Hikaria.DamageAnalyzer.Managers
{
	public static class DamageInfoManager
	{
		public struct pDamageInfo
		{
			public pPlayer player;

			public BasicDamageInfo damageInfo;

			public pDamageInfo(SNet_Player player, BasicDamageInfo damageInfo)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				this.player = default(pPlayer);
				((pPlayer)(ref this.player)).SetPlayer(player);
				this.damageInfo = damageInfo;
			}
		}

		public struct BasicDamageInfo
		{
			public pPlayer player;

			public pEnemyAgent enemy;

			public float rawDamage;

			public int limbID;

			public bool allowDirectionalBonus;

			public bool isSleepMulti;

			public float staggerMulti;

			public float precisionMulti;

			public float backstabberMulti;

			public float sleeperMulti;

			public DamageType damageType;

			public DamageSource damageSource;

			public Vector3 position;

			public Vector3 direction;

			public BasicDamageInfo(SNet_Player player, DamageType damageType, DamageSource damageSource, Dam_EnemyDamageLimb limb, Vector3 position, Vector3 direction, float rawDamage, bool allowDirectionalBonus = false, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f, bool isSleepMulti = false)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				this.player = default(pPlayer);
				((pPlayer)(ref this.player)).SetPlayer(player);
				this.damageType = damageType;
				this.damageSource = damageSource;
				enemy = default(pEnemyAgent);
				((pEnemyAgent)(ref enemy)).Set(limb.m_base.Owner);
				limbID = limb.m_limbID;
				this.position = position;
				this.direction = direction;
				this.rawDamage = rawDamage;
				this.allowDirectionalBonus = allowDirectionalBonus;
				this.staggerMulti = staggerMulti;
				this.precisionMulti = precisionMulti;
				this.backstabberMulti = backstabberMulti;
				this.sleeperMulti = sleeperMulti;
				this.isSleepMulti = isSleepMulti;
			}
		}

		public enum DamageType : byte
		{
			Bullet,
			Melee
		}

		public enum DamageSource : byte
		{
			SentryGun,
			Player
		}

		public static bool ShowSentryDamage = true;

		public static uint LocalAgentGlobalID;

		public static bool IsSleepMulti;

		public static bool IsSentryGunFire;

		public static Dictionary<ulong, float> OriginalBulletDamage = new Dictionary<ulong, float>();

		private static SNetExt_AuthorativeAction<pDamageInfo> m_packet;

		public static void Setup()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			VersionRange compatibleVersions = new VersionRange(new Version(2, 0, 0), new Version(3, 0, 0), true, false);
			m_packet = SNetExt_AuthorativeAction<pDamageInfo>.Create(typeof(pDamageInfo).FullName, (Action<SNet_Player, pDamageInfo>)ReceiveDamageInfo, (Action<pDamageInfo>)null, (Func<SNet_Player, bool>)((SNet_Player p) => CoreAPI.IsPlayerInstalledMod(p, "Hikaria.DamageAnalyzer", compatibleVersions)), (SNet_ChannelType)4);
		}

		public static void SendDamageInfo(BasicDamageInfo damageInfo, SNet_Player player)
		{
			m_packet.Ask(new pDamageInfo(player, damageInfo));
		}

		private static void ReceiveDamageInfo(SNet_Player sender, pDamageInfo data)
		{
			SNet_Player val = default(SNet_Player);
			if (((pPlayer)(ref data.player)).TryGetPlayer(ref val) && val.IsLocal && (Object)(object)sender != (Object)null && sender.IsMaster)
			{
				OriginalBulletDamage[val.Lookup] = data.damageInfo.rawDamage;
				ProcessDamageInfo(data.damageInfo);
			}
		}

		public static void ProcessDamageInfo(BasicDamageInfo damageInfo)
		{
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Invalid comparison between Unknown and I4
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)DamageInfoUpdater.Instance == (Object)null)
			{
				Logs.LogWarning("ProcessDamageInfo skipped: DamageInfoUpdater.Instance is null.");
				return;
			}
			SNet_Player player = default(SNet_Player);
			EnemyAgent val = default(EnemyAgent);
			if (!((pPlayer)(ref damageInfo.player)).TryGetPlayer(ref player) || !((pEnemyAgent)(ref damageInfo.enemy)).TryGet(ref val))
			{
				Logs.LogWarning("ProcessDamageInfo skipped: player or enemy lookup failed.");
				return;
			}
			if ((Object)(object)val.Damage == (Object)null || val.Damage.DamageLimbs == null || damageInfo.limbID < 0 || damageInfo.limbID >= ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)val.Damage.DamageLimbs).Length)
			{
				Logs.LogWarning($"ProcessDamageInfo skipped: invalid limb index {damageInfo.limbID}.");
				return;
			}
			Dam_EnemyDamageLimb val2 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)val.Damage.DamageLimbs)[damageInfo.limbID];
			if ((Object)(object)val2 == (Object)null)
			{
				Logs.LogWarning($"ProcessDamageInfo skipped: limb {damageInfo.limbID} is null.");
				return;
			}
			float num = damageInfo.rawDamage;
			bool isCrit = false;
			bool isArmor = false;
			bool isBackMulti = false;
			bool isSleepMulti = damageInfo.isSleepMulti;
			bool isImortal = val.Damage.IsImortal;
			bool allowDirectionalBonus = damageInfo.allowDirectionalBonus;
			float precisionMulti = damageInfo.precisionMulti;
			float sleeperMulti = damageInfo.sleeperMulti;
			float backstabberMulti = damageInfo.backstabberMulti;
			Vector3 direction = damageInfo.direction;
			Vector3 position = damageInfo.position;
			DamageType damageType = damageInfo.damageType;
			DamageSource damageSource = damageInfo.damageSource;
			if ((Object)(object)val2 != (Object)null)
			{
				if ((int)val2.m_type == 1)
				{
					isCrit = true;
				}
				else if ((int)val2.m_type == 2)
				{
					isArmor = true;
				}
			}
			switch (damageType)
			{
			case DamageType.Bullet:
			{
				if (!OriginalBulletDamage.TryGetValue(player.Lookup, out var value))
				{
					Logs.LogWarning($"ProcessDamageInfo skipped: OriginalBulletDamage missing for player {player.Lookup}.");
					return;
				}
				if (damageSource == DamageSource.SentryGun)
				{
					if (!player.IsLocal)
					{
						if (SNet.IsMaster && ((SNetExt_SyncedAction<pDamageInfo>)(object)m_packet).Listeners.Any((SNet_Player p) => p.Lookup == player.Lookup))
						{
							SendDamageInfo(damageInfo, player);
						}
						return;
					}
					if (player.IsLocal && !ShowSentryDamage)
					{
						return;
					}
				}
				num = AgentModifierManager.ApplyModifier((Agent)(object)val, (AgentModifier)7, value);
				break;
			}
			case DamageType.Melee:
				num = AgentModifierManager.ApplyModifier((Agent)(object)val, (AgentModifier)6, num);
				if (isSleepMulti)
				{
					num *= sleeperMulti;
				}
				break;
			}
			num = val2.ApplyWeakspotAndArmorModifiers(num, precisionMulti);
			if (allowDirectionalBonus)
			{
				float num2 = num;
				num = val2.ApplyDamageFromBehindBonus(num, position, direction, backstabberMulti);
				if (num > num2)
				{
					isBackMulti = true;
				}
			}
			if (Hikaria.DamageAnalyzer.Features.DamageAnalyzer.EnableVerboseRestoreLog)
			{
				Logs.LogInfo($"Damage hook triggered: type={damageType}, source={damageSource}, raw={damageInfo.rawDamage:0.00}, real={num:0.00}, limb={damageInfo.limbID}.");
			}
			DamageInfoUpdater.Instance.UpdateBasicDamageInfo(val2, isImortal, isArmor, isCrit, isBackMulti, IsSleepMulti, num);
		}
	}
	internal static class TranslateManager
	{
		public struct EnemyIDName
		{
			public List<uint> IDs;

			public string Name;
		}

		private struct EnemyLimbName
		{
			public string Contain;

			public string Name;
		}

		private static CustomSetting<List<EnemyIDName>> EnemyIDNameSettings = new CustomSetting<List<EnemyIDName>>("EnemyIDNames", new List<EnemyIDName>(), (Action<List<EnemyIDName>>)delegate(List<EnemyIDName> data)
		{
			EnemyID2NameLookup = new Dictionary<uint, string>();
			foreach (EnemyIDName datum in data)
			{
				foreach (uint iD in datum.IDs)
				{
					EnemyID2NameLookup[iD] = datum.Name;
				}
			}
		}, (LoadingTime)1, true);

		private static CustomSetting<List<EnemyLimbName>> EnemyLimbNameSettings = new CustomSetting<List<EnemyLimbName>>("EnemyLimbNames", new List<EnemyLimbName>(), (Action<List<EnemyLimbName>>)delegate(List<EnemyLimbName> data)
		{
			EnemyLimbNamesLookup = data.ToDictionary((EnemyLimbName x) => x.Contain.ToLower(), (EnemyLimbName x) => x.Name);
		}, (LoadingTime)1, true);

		private static Dictionary<string, string> EnemyLimbNamesLookup;

		private static Dictionary<uint, string> EnemyID2NameLookup;

		public static string KILL => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(1u, (string)null);

		public static string IMMORTAL => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(2u, (string)null);

		public static string UNKNOWN => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(3u, (string)null);

		public static string ARMOR => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(4u, (string)null);

		public static string CRIT => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(5u, (string)null);

		public static string BACKMULTI => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(6u, (string)null);

		public static string SLEEPMULTI => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(7u, (string)null);

		public static string HITPOSITION_DESC => Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Localization.GetById(8u, (string)null);

		public static string EnemyName(uint id)
		{
			if (!EnemyID2NameLookup.TryGetValue(id, out var value))
			{
				return $"{((GameDataBlockBase<EnemyDataBlock>)(object)GameDataBlockBase<EnemyDataBlock>.GetBlock(id)).name} [{id}]";
			}
			return value;
		}

		public static string EnemyLimb(string LimbName)
		{
			LimbName = LimbName.ToLower();
			if (EnemyLimbNamesLookup.Any(delegate(KeyValuePair<string, string> x)
			{
				if (LimbName.Contains(x.Key))
				{
					LimbName = x.Value;
					return true;
				}
				return false;
			}))
			{
				return LimbName;
			}
			return UNKNOWN;
		}
	}
}
namespace Hikaria.DamageAnalyzer.Handlers
{
	public class DamageInfoUpdater : MonoBehaviour
	{
		private bool Status;

		private float timer;

		private static StringBuilder sb = new StringBuilder(500);

		private Dam_EnemyDamageBase _dmgBase;

		private float _healthMax;

		private float _health;

		private bool _isImmortal;

		private string _limbName = string.Empty;

		private string _enemyName = string.Empty;

		private bool _isKill;

		private bool _isArmor;

		private bool _isCrit;

		private bool _isBackMulti;

		private bool _isSleepMulti;

		private float _damage;

		public static float LastingTime = 2.5f;

		public static int BarFontSize = 12;

		public static int HintFontSize = 12;

		public static int BarLength = 80;

		public static int OffsetX = 970;

		public static int OffsetY = 790;

		public static bool ShowHints = true;

		public static string BarFillChar_Remaining = "#";

		public static string BarFillChar_Lost = "-";

		public static bool ShowHPBar = true;

		public static bool ShowName = true;

		public static bool ShowLimb = true;

		public static bool ShowDamage = true;

		public static Color TextColor = new Color(1f, 1f, 0.8823f, 0.7059f);

		public static TextMeshPro TextMesh;

		public static DamageInfoUpdater Instance { get; private set; }

		public static TextMeshPro WatermarkTextPrefab => GuiManager.WatermarkLayer.m_watermark.m_watermarkText;

		private void Awake()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			TextMesh = Object.Instantiate<TextMeshPro>(WatermarkTextPrefab);
			((Transform)((TMP_Text)TextMesh).rectTransform).SetParent(((Transform)((TMP_Text)WatermarkTextPrefab).rectTransform).parent);
			((Transform)((TMP_Text)TextMesh).rectTransform).localPosition = new Vector3((float)OffsetX, (float)OffsetY);
			((TMP_Text)TextMesh).rectTransform.sizeDelta = new Vector2(1920f, ((TMP_Text)TextMesh).rectTransform.sizeDelta.y);
			((Graphic)TextMesh).color = TextColor;
			((TMP_Text)TextMesh).alignment = (TextAlignmentOptions)257;
			((TMP_Text)TextMesh).SetText(string.Empty, true);
			((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.zero;
		}

		private void FixedUpdate()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (timer >= LastingTime)
			{
				((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.zero;
				Status = false;
			}
			if (Status)
			{
				timer += Time.fixedDeltaTime;
				UpdateDamageInfo();
			}
		}

		private void RestartTimer()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			timer = 0f;
			Status = true;
			((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.one;
		}

		public void UpdateBasicDamageInfo(Dam_EnemyDamageLimb dam_EnemyDamageLimb, bool isImmortal, bool isArmor, bool isCrit, bool isBackMulti, bool isSleepMulti, float damage)
		{
			_dmgBase = dam_EnemyDamageLimb.m_base;
			_limbName = TranslateManager.EnemyLimb(((Object)dam_EnemyDamageLimb).name);
			_enemyName = TranslateManager.EnemyName(_dmgBase.Owner.EnemyDataID);
			_isImmortal = isImmortal;
			_isArmor = isArmor;
			_isCrit = isCrit;
			_isBackMulti = isBackMulti;
			_isSleepMulti = isSleepMulti;
			_damage = (isImmortal ? 0f : damage);
			RestartTimer();
		}

		private void UpdateDamageInfo()
		{
			bool flag = (Object)(object)_dmgBase != (Object)null;
			if (flag)
			{
				_health = ((Dam_SyncedDamageBase)_dmgBase).Health;
				_healthMax = ((Dam_SyncedDamageBase)_dmgBase).HealthMax;
			}
			else
			{
				_health = 0f;
			}
			_health = Math.Max(_health, 0f);
			_health = (float)Math.Round(_health, 1);
			if (flag)
			{
				_isKill = !flag || ((Dam_SyncedDamageBase)_dmgBase).Health <= 0f;
			}
			else
			{
				_isKill = true;
			}
			StringBuilder stringBuilder = sb;
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
			handler.AppendLiteral("<size=");
			handler.AppendFormatted(HintFontSize);
			handler.AppendLiteral(">");
			stringBuilder2.Append(ref handler);
			if (ShowName)
			{
				sb.Append(_enemyName);
			}
			if (ShowLimb)
			{
				if (ShowName)
				{
					stringBuilder = sb;
					StringBuilder stringBuilder3 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder);
					handler.AppendLiteral(" (");
					handler.AppendFormatted(_limbName);
					handler.AppendLiteral(")");
					stringBuilder3.Append(ref handler);
				}
				else
				{
					stringBuilder = sb;
					StringBuilder stringBuilder4 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder);
					handler.AppendFormatted(TranslateManager.HITPOSITION_DESC);
					handler.AppendLiteral(": ");
					handler.AppendFormatted(_limbName);
					stringBuilder4.Append(ref handler);
				}
			}
			sb.Append("</size>\n");
			if (ShowHPBar)
			{
				stringBuilder = sb;
				StringBuilder stringBuilder5 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(BarFontSize);
				handler.AppendLiteral(">HP: |-");
				stringBuilder5.Append(ref handler);
				int num = (int)(_health / _healthMax * (float)BarLength);
				if (num == 0 && !_isKill)
				{
					num = 1;
				}
				sb.Append(BarFillChar_Remaining[0], num);
				sb.Append(BarFillChar_Lost[0], BarLength - num);
				sb.Append("-| </size>");
			}
			else
			{
				stringBuilder = sb;
				StringBuilder stringBuilder6 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(18, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(BarFontSize);
				handler.AppendLiteral(">HP: </size>");
				stringBuilder6.Append(ref handler);
			}
			stringBuilder = sb;
			StringBuilder stringBuilder7 = stringBuilder;
			handler = new StringBuilder.AppendInterpolatedStringHandler(19, 3, stringBuilder);
			handler.AppendLiteral("<size=");
			handler.AppendFormatted(BarFontSize);
			handler.AppendLiteral(">[");
			handler.AppendFormatted(_health);
			handler.AppendLiteral(" / ");
			handler.AppendFormatted(_healthMax);
			handler.AppendLiteral("]</size>");
			stringBuilder7.AppendLine(ref handler);
			if (ShowHints)
			{
				stringBuilder = sb;
				StringBuilder stringBuilder8 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(HintFontSize);
				handler.AppendLiteral(">");
				stringBuilder8.Append(ref handler);
				if (ShowDamage)
				{
					stringBuilder = sb;
					StringBuilder stringBuilder9 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(4, 1, stringBuilder);
					handler.AppendLiteral("HP -");
					handler.AppendFormatted(_damage.ToString("0.00"));
					stringBuilder9.AppendLine(ref handler);
				}
				if (_isCrit)
				{
					sb.AppendLine(TranslateManager.CRIT);
				}
				if (_isBackMulti)
				{
					sb.AppendLine(TranslateManager.BACKMULTI);
				}
				if (_isSleepMulti)
				{
					sb.AppendLine(TranslateManager.SLEEPMULTI);
				}
				if (_isImmortal)
				{
					sb.AppendLine(TranslateManager.IMMORTAL);
				}
				if (_isArmor)
				{
					sb.AppendLine(TranslateManager.ARMOR);
				}
				if (_isKill)
				{
					sb.AppendLine(TranslateManager.KILL);
				}
				sb.Append("</size>");
			}
			((TMP_Text)TextMesh).SetText(sb.ToString(), true);
			sb.Clear();
		}
	}
}
namespace Hikaria.DamageAnalyzer.Features
{
	[DisallowInGameToggle]
	[EnableFeatureByDefault]
	public class DamageAnalyzer : Feature
	{
		public class DamageAnalyzerSetting
		{
			[FSDisplayName("持续时间")]
			public float LastingTime
			{
				get
				{
					return DamageInfoUpdater.LastingTime;
				}
				set
				{
					DamageInfoUpdater.LastingTime = value;
				}
			}

			[FSDisplayName("生命值条文本大小")]
			public int BarFontSize
			{
				get
				{
					return DamageInfoUpdater.BarFontSize;
				}
				set
				{
					DamageInfoUpdater.BarFontSize = value;
				}
			}

			[FSDisplayName("提示文本大小")]
			public int HintFontSize
			{
				get
				{
					return DamageInfoUpdater.HintFontSize;
				}
				set
				{
					DamageInfoUpdater.HintFontSize = value;
				}
			}

			[FSDisplayName("生命值条文本长度")]
			public int BarLength
			{
				get
				{
					return DamageInfoUpdater.BarLength;
				}
				set
				{
					DamageInfoUpdater.BarLength = value;
				}
			}

			[FSDisplayName("显示位置横向偏移量")]
			public int OffsetX
			{
				get
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoUpdater.TextMesh == (Object)null)
					{
						return DamageInfoUpdater.OffsetX;
					}
					return (int)DamageInfoUpdater.TextMesh.transform.localPosition.x;
				}
				set
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					DamageInfoUpdater.OffsetX = value;
					if (!((Object)(object)DamageInfoUpdater.TextMesh == (Object)null))
					{
						DamageInfoUpdater.TextMesh.transform.localPosition = new Vector3((float)value, (float)OffsetY, 0f);
					}
				}
			}

			[FSDisplayName("显示位置纵向偏移量")]
			public int OffsetY
			{
				get
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoUpdater.TextMesh == (Object)null)
					{
						return DamageInfoUpdater.OffsetY;
					}
					return (int)DamageInfoUpdater.TextMesh.transform.localPosition.y;
				}
				set
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					DamageInfoUpdater.OffsetY = value;
					if (!((Object)(object)DamageInfoUpdater.TextMesh == (Object)null))
					{
						DamageInfoUpdater.TextMesh.transform.localPosition = new Vector3((float)OffsetX, (float)value, 0f);
					}
				}
			}

			[FSDisplayName("显示提示")]
			public bool ShowHints
			{
				get
				{
					return DamageInfoUpdater.ShowHints;
				}
				set
				{
					DamageInfoUpdater.ShowHints = value;
				}
			}

			[FSDisplayName("显示生命值条")]
			public bool ShowHPBar
			{
				get
				{
					return DamageInfoUpdater.ShowHPBar;
				}
				set
				{
					DamageInfoUpdater.ShowHPBar = value;
				}
			}

			[FSDisplayName("显示敌人名称")]
			public bool ShowName
			{
				get
				{
					return DamageInfoUpdater.ShowName;
				}
				set
				{
					DamageInfoUpdater.ShowName = value;
				}
			}

			[FSDisplayName("显示命中部位")]
			public bool ShowLimb
			{
				get
				{
					return DamageInfoUpdater.ShowLimb;
				}
				set
				{
					DamageInfoUpdater.ShowLimb = value;
				}
			}

			[FSDisplayName("显示造成的伤害")]
			public bool ShowDamage
			{
				get
				{
					return DamageInfoUpdater.ShowDamage;
				}
				set
				{
					DamageInfoUpdater.ShowDamage = value;
				}
			}

			[FSDisplayName("显示哨戒炮造成的伤害")]
			[FSDescription("显示哨戒炮的命中信息, 仅当房主也安装了本插件才能显示")]
			public bool ShowSentryDamage
			{
				get
				{
					return DamageInfoManager.ShowSentryDamage;
				}
				set
				{
					DamageInfoManager.ShowSentryDamage = value;
				}
			}

			[FSDisplayName("Enable verbose restore log")]
			public bool EnableVerboseRestoreLog
			{
				get
				{
					return DamageAnalyzer.EnableVerboseRestoreLog;
				}
				set
				{
					DamageAnalyzer.EnableVerboseRestoreLog = value;
				}
			}

			[FSDisplayName("Enable debug scanner")]
			public bool EnableDebugScanner
			{
				get
				{
					return DamageAnalyzer.EnableDebugScanner;
				}
				set
				{
					DamageAnalyzer.EnableDebugScanner = value;
				}
			}

			[FSDisplayName("生命值剩余表示字符")]
			public string BarFillChar_Remaining
			{
				get
				{
					return DamageInfoUpdater.BarFillChar_Remaining;
				}
				set
				{
					DamageInfoUpdater.BarFillChar_Remaining = value;
				}
			}

			[FSDisplayName("生命值失去表示字符")]
			public string BarFillChar_Lost
			{
				get
				{
					return DamageInfoUpdater.BarFillChar_Lost;
				}
				set
				{
					DamageInfoUpdater.BarFillChar_Lost = value;
				}
			}

			[FSDisplayName("文本颜色")]
			public SColor TextColor
			{
				get
				{
					//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_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoUpdater.TextMesh == (Object)null)
					{
						return SColorExtensions.ToSColor(DamageInfoUpdater.TextColor);
					}
					return SColorExtensions.ToSColor(((Graphic)DamageInfoUpdater.TextMesh).color);
				}
				set
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//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_001e: 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)
					DamageInfoUpdater.TextColor = SColorExtensions.ToUnityColor(value);
					if (!((Object)(object)DamageInfoUpdater.TextMesh == (Object)null))
					{
						((Graphic)DamageInfoUpdater.TextMesh).color = SColorExtensions.ToUnityColor(value);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PUI_Watermark__UpdateWatermark__Patch
		{
			private static bool IsSetup;

			private static void Postfix()
			{
				//IL_000c: 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)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				if (!IsSetup)
				{
					GameObject val = new GameObject("DamageAnalyzer");
					val.transform.position = new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f);
					Object.DontDestroyOnLoad((Object)val);
					val.AddComponent<DamageInfoUpdater>();
					IsSetup = true;
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__BulletHit__Patch
		{
			private static void Prefix(WeaponHitData weaponRayData, bool doDamage, float additionalDis)
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				if (EnableVerboseRestoreLog)
				{
					Logs.LogInfo("ENTER BulletWeapon.BulletHit");
				}
				SNet_Player owner = weaponRayData.owner.Owner;
				if (!DamageInfoManager.OriginalBulletDamage.TryAdd(owner.Lookup, weaponRayData.damage))
				{
					DamageInfoManager.OriginalBulletDamage[owner.Lookup] = weaponRayData.damage;
				}
				RaycastHit rayHit = weaponRayData.rayHit;
				float num = ((RaycastHit)(ref rayHit)).distance + additionalDis;
				if (num > weaponRayData.damageFalloff.x)
				{
					DamageInfoManager.OriginalBulletDamage[owner.Lookup] *= Mathf.Max(1f - (num - weaponRayData.damageFalloff.x) / (weaponRayData.damageFalloff.y - weaponRayData.damageFalloff.x), BulletWeapon.s_falloffMin);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageLimb__MeleeDamage__Patch
		{
			private static void Prefix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f)
			{
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Invalid comparison between Unknown and I4
				if (EnableVerboseRestoreLog)
				{
					Logs.LogInfo($"ENTER Dam_EnemyDamageLimb.MeleeDamage Prefix sourceAgent={(Object)(object)sourceAgent != (Object)null} local={DamageInfoManager.LocalAgentGlobalID} source={((sourceAgent != null) ? new ushort?(sourceAgent.GlobalID) : ((ushort?)null))}");
				}
				if (!((Object)(object)sourceAgent == (Object)null) && DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID && !((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>().Owner.IsBot && (int)__instance.m_base.Owner.Locomotion.CurrentStateEnum == 14)
				{
					DamageInfoManager.IsSleepMulti = true;
				}
			}

			private static void Postfix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f)
			{
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				if (EnableVerboseRestoreLog)
				{
					Logs.LogInfo($"ENTER Dam_EnemyDamageLimb.MeleeDamage Postfix sourceAgent={(Object)(object)sourceAgent != (Object)null} local={DamageInfoManager.LocalAgentGlobalID} source={((sourceAgent != null) ? new ushort?(sourceAgent.GlobalID) : ((ushort?)null))}");
				}
				if (!((Object)(object)sourceAgent == (Object)null) && DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID)
				{
					PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
					if (!val.Owner.IsBot)
					{
						DamageInfoManager.ProcessDamageInfo(new DamageInfoManager.BasicDamageInfo(val.Owner, DamageInfoManager.DamageType.Melee, DamageInfoManager.DamageSource.Player, __instance, position, direction, dam, allowDirectionalBonus: true, staggerMulti, precisionMulti, backstabberMulti, sleeperMulti, DamageInfoManager.IsSleepMulti));
						DamageInfoManager.IsSleepMulti = false;
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageLimb__BulletDamage__Patch
		{
			private static void Postfix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, bool allowDirectionalBonus, float staggerMulti = 1f, float precisionMulti = 1f)
			{
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				if (EnableVerboseRestoreLog)
				{
					Logs.LogInfo($"ENTER Dam_EnemyDamageLimb.BulletDamage sourceAgent={(Object)(object)sourceAgent != (Object)null} local={DamageInfoManager.LocalAgentGlobalID} source={((sourceAgent != null) ? new ushort?(sourceAgent.GlobalID) : ((ushort?)null))}");
				}
				if (!((Object)(object)sourceAgent == (Object)null) && (SNet.IsMaster || DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID))
				{
					PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
					if (!val.Owner.IsBot)
					{
						DamageInfoManager.ProcessDamageInfo(new DamageInfoManager.BasicDamageInfo(val.Owner, DamageInfoManager.DamageType.Bullet, (!DamageInfoManager.IsSentryGunFire) ? DamageInfoManager.DamageSource.Player : DamageInfoManager.DamageSource.SentryGun, __instance, position, direction, dam, allowDirectionalBonus, staggerMulti, precisionMulti));
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__FireBullet__Patch
		{
			private static void Prefix()
			{
				DamageInfoManager.IsSentryGunFire = true;
			}

			private static void Postfix()
			{
				DamageInfoManager.IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__UpdateFireShotgunSemi__Patch
		{
			private static void Prefix(SentryGunInstance_Firing_Bullets __instance)
			{
				if (Clock.Time > __instance.m_fireBulletTimer)
				{
					DamageInfoManager.IsSentryGunFire = true;
				}
			}

			private static void Postfix()
			{
				DamageInfoManager.IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class LocalPlayerAgent__Setup__Patch
		{
			private static void Postfix(LocalPlayerAgent __instance)
			{
				Logs.LogInfo($"LocalPlayerAgent.Setup localGlobalID={((Agent)__instance).GlobalID}");
				DamageInfoManager.LocalAgentGlobalID = ((Agent)__instance).GlobalID;
			}
		}

		public static bool EnableVerboseRestoreLog;

		public static bool EnableDebugScanner;

		public override string Name => "Damage Analyzer";

		public override bool InlineSettingsIntoParentMenu => true;

		public static ILocalizationService Localization { get; set; }

		[FeatureConfig]
		public static DamageAnalyzerSetting Settings { get; set; }

		public override void Init()
		{
			Logs.LogInfo("DamageAnalyzer loaded");
			Logs.LogInfo(EnableDebugScanner ? "DebugTypeScanner enabled" : "DebugTypeScanner disabled");
			if (EnableDebugScanner)
			{
				DebugTypeScanner.Scan();
			}
			ClassInjector.RegisterTypeInIl2Cpp<DamageInfoUpdater>(false);
			DamageInfoManager.Setup();
		}
	}
}