Decompiled source of WeaponDamageDisplay v1.3.0

WeaponDamageDisplay.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[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("WeaponDamageDisplay")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WeaponDamageDisplay")]
[assembly: AssemblyTitle("WeaponDamageDisplay")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 WeaponDamageDisplay
{
	[BepInPlugin("com.nadre.weapondamagedisplay", "WeaponDamageDisplay", "1.3.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerControllerB))]
		internal class PlayerControllerBPatch
		{
			private static int lastTooltipIndex = -1;

			private static HUDManager? lastHudInstance = null;

			private static readonly HashSet<string> _ignoredTypeNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
			{
				"FlashlightItem", "PatcherTool", "WalkieTalkie", "BoomboxItem", "KeyItem", "ShoppingCart", "RadarBoosterItem", "NoisemakerProp", "SprayPaintItem", "ExtensionLadderItem",
				"TetraChemicalItem", "JetpackItem", "LungProp"
			};

			private static readonly string[] _damageKeywords = new string[11]
			{
				"hitforce", "shovelhitforce", "hitdamage", "damagevalue", "damage", "force", "power", "attack", "hit", "strike",
				"weapon"
			};

			private static MethodInfo? _lguShovelForceMethod = null;

			private static MethodInfo? _lguKnifeForceMethod = null;

			private static bool _checkedLgu = false;

			private static readonly Dictionary<Type, MemberInfo?> _damageMemberCache = new Dictionary<Type, MemberInfo>();

			public static void ResetTooltipTracker()
			{
				lastTooltipIndex = -1;
				lastHudInstance = null;
			}

			private static void ClearLastTooltip()
			{
				if (lastTooltipIndex != -1 && (Object)(object)lastHudInstance != (Object)null && lastHudInstance.controlTipLines != null && lastTooltipIndex >= 0 && lastTooltipIndex < lastHudInstance.controlTipLines.Length && (Object)(object)lastHudInstance.controlTipLines[lastTooltipIndex] != (Object)null && ((TMP_Text)lastHudInstance.controlTipLines[lastTooltipIndex]).text != "")
				{
					((TMP_Text)lastHudInstance.controlTipLines[lastTooltipIndex]).text = "";
				}
				lastTooltipIndex = -1;
				lastHudInstance = null;
			}

			[HarmonyPatch("Update")]
			[HarmonyPostfix]
			private static void Postfix_Update(PlayerControllerB __instance)
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)__instance != (Object)(object)StartOfRound.Instance.localPlayerController)
				{
					return;
				}
				GrabbableObject val = null;
				if (__instance.ItemSlots != null && __instance.currentItemSlot >= 0 && __instance.currentItemSlot < __instance.ItemSlots.Length)
				{
					val = __instance.ItemSlots[__instance.currentItemSlot];
				}
				if ((Object)(object)val != (Object)null)
				{
					string weaponDamage = GetWeaponDamage(val);
					if (!string.IsNullOrEmpty(weaponDamage) && (Object)(object)HUDManager.Instance != (Object)null && HUDManager.Instance.controlTipLines != null)
					{
						int num = 0;
						if (val.itemProperties?.toolTips != null)
						{
							num = val.itemProperties.toolTips.Length;
						}
						if (num < HUDManager.Instance.controlTipLines.Length)
						{
							if (lastTooltipIndex != -1 && lastTooltipIndex != num)
							{
								ClearLastTooltip();
							}
							if ((Object)(object)HUDManager.Instance.controlTipLines[num] != (Object)null)
							{
								string text = "Dégat : " + weaponDamage;
								if (((TMP_Text)HUDManager.Instance.controlTipLines[num]).text != text)
								{
									((TMP_Text)HUDManager.Instance.controlTipLines[num]).text = text;
								}
								lastTooltipIndex = num;
								lastHudInstance = HUDManager.Instance;
							}
						}
						else
						{
							ClearLastTooltip();
						}
					}
					else
					{
						ClearLastTooltip();
					}
				}
				else
				{
					ClearLastTooltip();
				}
			}

			private static void TryLoadLgu()
			{
				if (_checkedLgu)
				{
					return;
				}
				_checkedLgu = true;
				try
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly in assemblies)
					{
						if (assembly.GetName().Name != "MoreShipUpgrades")
						{
							continue;
						}
						Type type = assembly.GetType("MoreShipUpgrades.UpgradeComponents.TierUpgrades.ProteinPowder");
						if (type != null)
						{
							_lguShovelForceMethod = type.GetMethod("GetShovelHitForce", BindingFlags.Static | BindingFlags.Public);
							if (_lguShovelForceMethod != null)
							{
								LoggerInstance.LogInfo((object)"[LGU] Support Protein Powder (pelle) activé.");
							}
						}
						string[] array = new string[3] { "MoreShipUpgrades.UpgradeComponents.TierUpgrades.ProteinPowder", "MoreShipUpgrades.UpgradeComponents.TierUpgrades.BigBolt", "MoreShipUpgrades.UpgradeComponents.TierUpgrades.MedKit" };
						foreach (string text in array)
						{
							Type type2 = assembly.GetType(text);
							if (!(type2 == null))
							{
								MethodInfo methodInfo = type2.GetMethod("GetKnifeHitForce", BindingFlags.Static | BindingFlags.Public) ?? type2.GetMethod("GetMeleeHitForce", BindingFlags.Static | BindingFlags.Public) ?? type2.GetMethod("GetWeaponHitForce", BindingFlags.Static | BindingFlags.Public);
								if (methodInfo != null)
								{
									_lguKnifeForceMethod = methodInfo;
									LoggerInstance.LogInfo((object)("[LGU] Support bonus couteau/mêlée trouvé dans " + text + "."));
									break;
								}
							}
						}
						break;
					}
				}
				catch (Exception ex)
				{
					LoggerInstance.LogError((object)("[LGU] Erreur détection MoreShipUpgrades : " + ex.Message));
				}
			}

			private static int GetLguShovelForce(int originalForce)
			{
				TryLoadLgu();
				if (_lguShovelForceMethod != null)
				{
					try
					{
						object obj = _lguShovelForceMethod.Invoke(null, new object[1] { originalForce });
						if (obj is int)
						{
							return (int)obj;
						}
					}
					catch
					{
					}
				}
				return originalForce;
			}

			private static int GetLguKnifeForce(int originalForce)
			{
				TryLoadLgu();
				if (_lguKnifeForceMethod != null)
				{
					try
					{
						object obj = _lguKnifeForceMethod.Invoke(null, new object[1] { originalForce });
						if (obj is int)
						{
							return (int)obj;
						}
					}
					catch
					{
					}
				}
				return originalForce;
			}

			private static MemberInfo? FindDamageMember(Type? type)
			{
				if (type == null || type == typeof(MonoBehaviour) || type == typeof(Object))
				{
					return null;
				}
				if (_damageMemberCache.TryGetValue(type, out MemberInfo value))
				{
					return value;
				}
				MemberInfo memberInfo = null;
				Type type2 = type;
				while (type2 != null && type2 != typeof(MonoBehaviour) && type2 != typeof(Object))
				{
					FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					string[] damageKeywords = _damageKeywords;
					foreach (string value2 in damageKeywords)
					{
						FieldInfo[] array = fields;
						foreach (FieldInfo fieldInfo in array)
						{
							if (fieldInfo.Name.ToLower().Contains(value2))
							{
								Type fieldType = fieldInfo.FieldType;
								if (fieldType == typeof(int) || fieldType == typeof(float) || fieldType == typeof(double))
								{
									memberInfo = fieldInfo;
									break;
								}
							}
						}
						if (memberInfo != null)
						{
							break;
						}
					}
					if (memberInfo != null)
					{
						break;
					}
					PropertyInfo[] properties = type2.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					damageKeywords = _damageKeywords;
					foreach (string value3 in damageKeywords)
					{
						PropertyInfo[] array2 = properties;
						foreach (PropertyInfo propertyInfo in array2)
						{
							if (propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.Name.ToLower().Contains(value3))
							{
								Type propertyType = propertyInfo.PropertyType;
								if (propertyType == typeof(int) || propertyType == typeof(float) || propertyType == typeof(double))
								{
									memberInfo = propertyInfo;
									break;
								}
							}
						}
						if (memberInfo != null)
						{
							break;
						}
					}
					if (memberInfo != null)
					{
						break;
					}
					type2 = type2.BaseType;
				}
				_damageMemberCache[type] = memberInfo;
				return memberInfo;
			}

			private static string GetWeaponDamage(GrabbableObject item)
			{
				if ((Object)(object)item == (Object)null)
				{
					return "";
				}
				string name = ((object)item).GetType().Name;
				if (_ignoredTypeNames.Contains(name))
				{
					return "";
				}
				Shovel val = (Shovel)(object)((item is Shovel) ? item : null);
				if (val != null)
				{
					int lguShovelForce = GetLguShovelForce(val.shovelHitForce);
					return $"{lguShovelForce} HP";
				}
				if (name == "ShotgunItem")
				{
					return "1-5 par plomb (max 50)";
				}
				if (name == "KnifeItem")
				{
					int num = 1;
					int lguKnifeForce = GetLguKnifeForce(num);
					if (lguKnifeForce <= num)
					{
						return "1 HP (Rapide)";
					}
					return $"{lguKnifeForce} HP (LGU)";
				}
				try
				{
					MemberInfo memberInfo = FindDamageMember(((object)item).GetType());
					if (memberInfo != null)
					{
						object obj = null;
						if (memberInfo is FieldInfo fieldInfo)
						{
							obj = fieldInfo.GetValue(item);
						}
						else if (memberInfo is PropertyInfo propertyInfo)
						{
							obj = propertyInfo.GetValue(item);
						}
						if (obj != null)
						{
							if (obj is int num2)
							{
								return $"{num2} HP";
							}
							if (obj is float num3)
							{
								return $"{num3:0.#} HP";
							}
							if (obj is double)
							{
								double num4 = (double)obj;
								return $"{num4:0.#} HP";
							}
						}
					}
				}
				catch (Exception ex)
				{
					LoggerInstance.LogError((object)("[WDD] Réflexion échouée sur " + name + " : " + ex.Message));
				}
				if ((Object)(object)item.itemProperties != (Object)null && item.itemProperties.isDefensiveWeapon)
				{
					return "Arme (valeur inconnue)";
				}
				return "";
			}
		}

		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartOfRoundPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void Postfix_Start()
			{
				LoggerInstance.LogInfo((object)"[WDD] StartOfRound.Start : Initialisation terminée.");
				PlayerControllerBPatch.ResetTooltipTracker();
			}
		}

		public const string ModGUID = "com.nadre.weapondamagedisplay";

		public const string ModName = "WeaponDamageDisplay";

		public const string ModVersion = "1.3.0";

		private readonly Harmony harmony = new Harmony("com.nadre.weapondamagedisplay");

		internal static Plugin? Instance;

		internal static ManualLogSource LoggerInstance;

		private void Awake()
		{
			Instance = this;
			LoggerInstance = ((BaseUnityPlugin)this).Logger;
			LoggerInstance.LogInfo((object)"WeaponDamageDisplay v1.3.0 chargé avec succès.");
			harmony.PatchAll();
		}
	}
}