Decompiled source of DpsMeter v0.1.0

DpsMeter.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InControl;
using Microsoft.CodeAnalysis;
using NineSolsAPI;
using NineSolsAPI.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
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("DpsMeter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+66408d67671c7d3224d44dca51bf26a7171fc1ad")]
[assembly: AssemblyProduct("DpsMeter")]
[assembly: AssemblyTitle("DpsMeter")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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]
	[Microsoft.CodeAnalysis.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;
		}
	}
	[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 DpsMeter
{
	public class DpsDisplay
	{
		[CompilerGenerated]
		private DpsTracker <tracker>P;

		[CompilerGenerated]
		private ConfigEntry<bool> <configShowDamageNumbers>P;

		[CompilerGenerated]
		private ConfigEntry<bool> <updateOnHits>P;

		[CompilerGenerated]
		private TMP_Text <statsPanel>P;

		private const float MoveAmount = 50f;

		private const float FadeDuration = 2f;

		private const float ScaleFactor = 1.2f;

		private List<TMP_Text> objects;

		public DpsDisplay(DpsTracker tracker, ConfigEntry<bool> configShowDamageNumbers, ConfigEntry<bool> updateOnHits, TMP_Text statsPanel)
		{
			<tracker>P = tracker;
			<configShowDamageNumbers>P = configShowDamageNumbers;
			<updateOnHits>P = updateOnHits;
			<statsPanel>P = statsPanel;
			objects = new List<TMP_Text>();
			base..ctor();
		}

		public IEnumerator OnDamage(EffectHitData data, float value, bool internalDamage)
		{
			if (<configShowDamageNumbers>P.Value)
			{
				Color color = (Color)(internalDamage ? new Color(0.5f, 1f, 1f, 1f) : Color.white);
				yield return SpawnText(data.hitPos, $"{value:0.##}", color);
			}
		}

		public IEnumerator OnInaccurateParry(EffectHitData data, float parryTime, float requiredParryTime, float spamLevel)
		{
			if (<configShowDamageNumbers>P.Value)
			{
				float num = parryTime - requiredParryTime;
				string text = $"Missed by {num * 1000f:F0}ms";
				if (spamLevel > 0f)
				{
					text += $" (Spam {spamLevel})";
				}
				if (requiredParryTime == 0f)
				{
					text = "Parry Spam";
				}
				yield return SpawnText(data.hitPos, text, new Color(1f, 0f, 0.28f, 1f));
			}
		}

		private IEnumerator SpawnText(Vector3 pos, string str, Color color)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text text = CreateDamageText(str, color);
			objects.Add(text);
			yield return AnimateText(text, pos);
			objects.Remove(text);
		}

		public void Update()
		{
			List<HitData> recentHits = <tracker>P.RecentHits;
			if (recentHits.Count == 0)
			{
				<statsPanel>P.text = "";
				return;
			}
			float num = recentHits.Sum((HitData hit) => hit.Value);
			float totalDamage = recentHits.Sum((HitData hit) => hit.Value);
			IEnumerable<string> enumerable = from x in recentHits.GroupBy((HitData hit) => hit.Type, (HitData hit) => hit.Value, delegate(string type, IEnumerable<float> @group)
				{
					float num4 = @group.Sum();
					int item = (int)(num4 / totalDamage * 100f);
					return (type, num4, item);
				})
				orderby x.groupSum descending
				select $"{x.type}: {x.groupSum:0.##} {x.percentage}%";
			<statsPanel>P.text = GeneralExtensions.Join<string>(enumerable, (Func<string, string>)null, "\n");
			float num2 = (<updateOnHits>P.Value ? <tracker>P.RunningTime : ((recentHits.Count <= 0) ? 0f : (ListExtensions.Last<HitData>(recentHits).Time - ListExtensions.First<HitData>(recentHits).Time)));
			if (num2 != 0f)
			{
				float num3 = num / num2;
				TMP_Text obj = <statsPanel>P;
				obj.text += $"\nDPS: {num3:F1}";
			}
		}

		public void OnDestroy()
		{
			foreach (TMP_Text @object in objects)
			{
				Object.Destroy((Object)(object)((Component)@object).gameObject);
			}
		}

		private static Vector2 WorldToCanvas(Vector3 worldPosition)
		{
			//IL_0019: 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)
			//IL_0025: 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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)NineSolsAPICore.FullscreenCanvas).transform;
			Vector3 val = SingletonBehaviour<CameraManager>.Instance.camera2D.GameCamera.WorldToScreenPoint(worldPosition);
			Vector2 result = default(Vector2);
			RectTransformUtility.ScreenPointToLocalPointInRectangle(((Component)transform).GetComponent<RectTransform>(), Vector2.op_Implicit(val), (Camera)null, ref result);
			return result;
		}

		private static TMP_Text CreateDamageText(string str, Color color)
		{
			//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)
			//IL_004a: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)NineSolsAPICore.FullscreenCanvas).transform;
			GameObject val = new GameObject();
			val.transform.SetParent(transform);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).fontSize = 25f;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)1026;
			((TMP_Text)obj).fontWeight = (FontWeight)700;
			((TMP_Text)obj).text = str;
			((Graphic)obj).color = color;
			RectTransform component = ((Component)obj).GetComponent<RectTransform>();
			component.pivot = new Vector2(0.5f, 0f);
			component.sizeDelta = new Vector2(200f, 10f);
			return (TMP_Text)(object)obj;
		}

		private static IEnumerator AnimateText(TMP_Text text, Vector3 worldPosition)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector2 anchoredPosition = WorldToCanvas(worldPosition);
			RectTransform rectTransform = ((Component)text).GetComponent<RectTransform>();
			rectTransform.anchoredPosition = anchoredPosition;
			Vector3 targetPositionWorld = worldPosition + new Vector3(0f, 50f, 0f);
			float elapsedTime = 0f;
			Color originalColor = ((Graphic)text).color;
			float originalScale = ((Transform)rectTransform).localScale.x;
			while (elapsedTime < 2f)
			{
				rectTransform.anchoredPosition = WorldToCanvas(Vector3.Lerp(worldPosition, targetPositionWorld, elapsedTime / 2f));
				Color color = ((Graphic)text).color;
				color.a = Mathf.Lerp(1f, 0f, elapsedTime / 2f);
				((Graphic)text).color = color;
				float num = Mathf.Lerp(originalScale, 1.2f, elapsedTime / 1f);
				if (elapsedTime > 1f)
				{
					num = Mathf.Lerp(1.2f, originalScale, (elapsedTime - 1f) / 1f);
				}
				((Transform)rectTransform).localScale = new Vector3(num, num, num);
				elapsedTime += Time.deltaTime;
				yield return null;
			}
			((Graphic)text).color = new Color(originalColor.r, originalColor.g, originalColor.b, 0f);
			Object.Destroy((Object)(object)((Component)text).gameObject);
		}
	}
	internal static class Extensions
	{
		public static string Name(this EffectType type)
		{
			//IL_0000: 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_000f: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((type & 0x40000) != 0)
			{
				return "Heavy";
			}
			if ((type & 0x20) != 0)
			{
				return "Talisman Attach";
			}
			if ((type & 0x2000000) != 0)
			{
				return "Talisman Explode";
			}
			if ((type & 0x200) != 0)
			{
				return "Tai-Chi";
			}
			return ((object)(EffectType)(ref type)).ToString();
		}
	}
	public enum DpsResetMode
	{
		OnEnemyChange,
		Manual
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("DpsMeter", "DpsMeter", "1.0.0")]
	public class DpsMeterMod : BaseUnityPlugin
	{
		private ConfigEntry<DpsResetMode> configResetMode;

		private ConfigEntry<bool> configUpdateOnHits;

		private ConfigEntry<bool> configShowDamageNumbers;

		private ConfigEntry<KeyboardShortcut> configShortcutPause;

		private ConfigEntry<KeyboardShortcut> configShortcutReset;

		public static DpsMeterMod Instance;

		private Harmony harmony;

		private DpsTracker dpsTracker;

		private DpsDisplay dpsDisplay;

		private GameObject dummy;

		public TMP_Text statsPanel;

		private void Awake()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			RCGLifeCycle.DontDestroyForever(((Component)this).gameObject);
			try
			{
				configResetMode = ((BaseUnityPlugin)this).Config.Bind<DpsResetMode>("General", "Reset Mode", DpsResetMode.OnEnemyChange, (ConfigDescription)null);
				configUpdateOnHits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Only update DPS on hits", false, (ConfigDescription)null);
				configShowDamageNumbers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show damage numbers", true, (ConfigDescription)null);
				configShortcutPause = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Shortcuts", "Pause DPS Tracking", KeyboardShortcut.Empty, (ConfigDescription)null);
				configShortcutReset = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Shortcuts", "Reset DPS Tracking", KeyboardShortcut.Empty, (ConfigDescription)null);
				statsPanel = CreateStatsPanel();
				harmony = Harmony.CreateAndPatchAll(typeof(DpsMeterMod).Assembly, (string)null);
				dpsTracker = new DpsTracker(configResetMode);
				dpsDisplay = new DpsDisplay(dpsTracker, configShowDamageNumbers, configUpdateOnHits, statsPanel);
				KeybindManager.Add((MonoBehaviour)(object)this, (Action)delegate
				{
					dpsTracker.Pause();
				}, (Func<KeyboardShortcut>)(() => configShortcutPause.Value));
				KeybindManager.Add((MonoBehaviour)(object)this, (Action)delegate
				{
					dpsTracker.Reset();
				}, (Func<KeyboardShortcut>)(() => configShortcutReset.Value));
				KeybindManager.Add((MonoBehaviour)(object)this, (Action)delegate
				{
					GameCore instance = SingletonBehaviour<GameCore>.Instance;
					if (instance != null)
					{
						instance.ResetLevel(false);
					}
				}, (KeyCode[])(object)new KeyCode[1] { (KeyCode)116 });
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin DpsMeter is loaded!");
			}
			catch (Exception ex)
			{
				ToastManager.Toast((object)ex);
			}
		}

		private static TMP_Text CreateStatsPanel()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Stats");
			val.transform.SetParent(((Component)NineSolsAPICore.FullscreenCanvas).transform);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).alignment = (TextAlignmentOptions)1028;
			((TMP_Text)obj).fontSize = 20f;
			((Graphic)obj).color = Color.white;
			((TMP_Text)obj).text = "";
			RectTransform component = ((Component)obj).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0.5f);
			component.anchorMax = new Vector2(1f, 0.5f);
			component.pivot = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(-10f, 10f);
			component.sizeDelta = new Vector2((float)Screen.width, 0f);
			return (TMP_Text)(object)obj;
		}

		private void Update()
		{
			dpsTracker.Update();
			dpsDisplay.Update();
		}

		private void SpawnTrainingDummy()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Player i = Player.i;
			if (i != null)
			{
				Object.Instantiate<GameObject>(dummy, ((Component)Instance).gameObject.transform).transform.position = ((Component)i).transform.position;
			}
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
			dpsDisplay.OnDestroy();
			if (Object.op_Implicit((Object)(object)dummy))
			{
				Object.Destroy((Object)(object)dummy);
			}
			if (Object.op_Implicit((Object)(object)statsPanel))
			{
				Object.Destroy((Object)(object)((Component)statsPanel).gameObject);
			}
		}

		public void OnDamage(EffectHitData hitData, float value, bool internalDamage)
		{
			dpsTracker.OnDamage(hitData, value, internalDamage);
			((MonoBehaviour)this).StartCoroutine(dpsDisplay.OnDamage(hitData, value, internalDamage));
		}

		public void OnInaccurateParry(EffectHitData hitData, float parryTime, float requiredParryTime, float spamLevel)
		{
			((MonoBehaviour)this).StartCoroutine(dpsDisplay.OnInaccurateParry(hitData, parryTime, requiredParryTime, spamLevel));
		}

		private static GameObject LoadObjectFromResources(string resourceName, string scenePath, string objectName)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			AssetBundle embeddedAssetBundle = AssemblyUtils.GetEmbeddedAssetBundle(resourceName);
			SceneManager.LoadScene(scenePath, (LoadSceneMode)1);
			Scene sceneByPath = SceneManager.GetSceneByPath(scenePath);
			GameObject[] rootGameObjects = ((Scene)(ref sceneByPath)).GetRootGameObjects();
			foreach (GameObject val2 in rootGameObjects)
			{
				if (((Object)val2).name == objectName)
				{
					val = Object.Instantiate<GameObject>(val2);
					((Object)val).name = "Training Dummy";
					RCGLifeCycle.DontDestroyForever(val);
					break;
				}
				Object.Destroy((Object)(object)val2);
			}
			SceneManager.UnloadSceneAsync(sceneByPath);
			embeddedAssetBundle.Unload(true);
			if (val == null)
			{
				ToastManager.Toast((object)embeddedAssetBundle);
				ToastManager.Toast((object)sceneByPath);
				ToastManager.Toast((object)((Scene)(ref sceneByPath)).GetRootGameObjects().Length);
				throw new Exception(objectName + " not found in " + resourceName + "/" + scenePath);
			}
			return val;
		}
	}
	public record struct HitData(float Time, float Value, string Type, GameObject Owner);
	public class DpsTracker
	{
		[CompilerGenerated]
		private ConfigEntry<DpsResetMode> <resetMode>P;

		public readonly List<HitData> RecentHits;

		public bool Running;

		public float RunningTime;

		private readonly Dictionary<string, string> dealerNames;

		public DpsTracker(ConfigEntry<DpsResetMode> resetMode)
		{
			<resetMode>P = resetMode;
			RecentHits = new List<HitData>();
			Running = true;
			dealerNames = new Dictionary<string, string>
			{
				{ "AttackFront", "Attack" },
				{ "ChargedAttackFront", "Charge Attack" },
				{ "Third Attack", "Heavy" },
				{ "Foo", "Foo Attach" },
				{ "FooExplode", "Foo" },
				{ "JumpSpinKick", "Tai Chi" },
				{ "[Dealer] Internal Damage", "UC" },
				{ "--ReflectNode", "Reflect Projectile" },
				{ "NormalArrow Shoot 穿雲 Lv1(Clone)", "Bow" },
				{ "NormalArrow Shoot 穿雲 Lv2(Clone)", "Bow" },
				{ "NormalArrow Shoot 穿雲 Lv3(Clone)", "Bow" }
			};
			base..ctor();
		}

		public void Pause()
		{
			Running = !Running;
			ToastManager.Toast((object)$"DPS tracking enabled: {Running}");
		}

		public void Reset()
		{
			RecentHits.Clear();
			RunningTime = 0f;
			ToastManager.Toast((object)"DPS tracking reset");
		}

		public void Update()
		{
			if (Running)
			{
				RunningTime += Time.deltaTime;
			}
		}

		public void OnDamage(EffectHitData data, float value, bool internalDamage)
		{
			if (Running)
			{
				GameObject gameObject = data.receiver.OwnerComponent.gameObject;
				if (<resetMode>P.Value == DpsResetMode.OnEnemyChange && RecentHits.Count > 0 && (Object)(object)ListExtensions.Last<HitData>(RecentHits).Owner != (Object)(object)gameObject)
				{
					RecentHits.Clear();
					ToastManager.Toast((object)"New enemy, resetting DPS stats");
				}
				string name = ((Object)data.dealer).name;
				if ((name == "PostureDecrease" || name == "Posture Decrease") ? true : false)
				{
					name = ((Object)((Component)data.dealer).transform.parent).name;
				}
				string value2 = null;
				Transform val = ((Component)data.dealer).transform;
				while (Object.op_Implicit((Object)(object)val) && !dealerNames.TryGetValue(((Object)val).name, out value2))
				{
					val = val.parent;
				}
				if (value2 == null)
				{
					ToastManager.Toast((object)ObjectUtils.ObjectPath(((Component)data.dealer).gameObject));
					value2 = ((Object)data.dealer).name;
				}
				RecentHits.Add(new HitData(Time.time, value, value2, gameObject));
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource logSource;

		internal static void Init(ManualLogSource logSource)
		{
			Log.logSource = logSource;
		}

		internal static void Debug(object data)
		{
			logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			logSource.LogWarning(data);
		}
	}
	[HarmonyPatch]
	public class Patches
	{
		private static FieldRef<PlayerInputCommandQueue, Dictionary<PlayerAction, List<float>>> actionDict = AccessTools.FieldRefAccess<PlayerInputCommandQueue, Dictionary<PlayerAction, List<float>>>("actionDict");

		private static FieldRef<PlayerParryState, float[]> spamDatas = AccessTools.FieldRefAccess<PlayerParryState, float[]>("spamDatas");

		[HarmonyPatch(typeof(PlayerParryState), "Parried")]
		[HarmonyPrefix]
		public static void Parried(ref PlayerParryState __instance, EffectHitData hitData)
		{
			Player i = Player.i;
			List<float> list = actionDict.Invoke(i.inputCommandQueue)[i.playerInput.gameplayActions.Parry];
			float num;
			if (list.Count <= 0)
			{
				num = -1f;
			}
			else
			{
				num = list[list.Count - 1];
			}
			float num2 = num;
			float[] array = spamDatas.Invoke(__instance);
			int spamLevel = __instance.spamLevel;
			float num3 = Time.time - num2;
			if (!__instance.IsAlwaysAccurate && !i.IsInQTETutorial && !(num3 < array[spamLevel]))
			{
				DpsMeterMod.Instance.OnInaccurateParry(hitData, num3, array[spamLevel], spamLevel);
			}
		}

		[HarmonyPatch(typeof(MonsterBase), "HittedByPlayerDecreasePosture")]
		[HarmonyPrefix]
		public static void OnDamage(EffectHitData hitData)
		{
			DpsMeterMod.Instance.OnDamage(hitData, hitData.dealer.FinalValue, internalDamage: false);
		}

		[HarmonyPatch(typeof(MonsterBase), "InternalInjuryVirtual")]
		[HarmonyPrefix]
		public static void OnDamageInternal(EffectHitData data, float scale, float additionalDamage)
		{
			float value = (int)(data.dealer.FinalValue * scale + additionalDamage);
			DpsMeterMod.Instance.OnDamage(data, value, internalDamage: true);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "DpsMeter";

		public const string PLUGIN_NAME = "DpsMeter";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}