Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HealthBarViewer v1.0.0
HealthBarViewer.dll
Decompiled 2 years agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.CameraModes; using RoR2.UI; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Local.HealthBar.Viewer { [BepInPlugin("local.healthbar.viewer", "HealthBarViewer", "1.0.0")] public class Plugin : BaseUnityPlugin { private class ConfigValue<T> : ConfigValue<T, T> { public ConfigValue(ConfigEntry<T> entry) : base(entry) { convert = (T _) => _; } public static implicit operator ConfigValue<T>(ConfigEntry<T> entry) { return new ConfigValue<T>(entry); } } private class ConfigValue<T, U> { private readonly ConfigEntry<T> entry; public Func<T, U> convert; public ConfigValue(ConfigEntry<T> entry) { this.entry = entry; base..ctor(); } public static implicit operator ConfigValue<T, U>(ConfigEntry<T> entry) { return new ConfigValue<T, U>(entry); } public static implicit operator U(ConfigValue<T, U> configuration) { return configuration.convert(configuration.entry.Value); } } public const string version = "1.0.0"; public const string identifier = "local.healthbar.viewer"; private static ConfigValue<uint> duration; private static ConfigValue<uint> range; private static ConfigValue<float> threshold; private static ConfigValue<float> alpha; private static ConfigValue<bool> ally; private static ConfigValue<uint, float> delay; private static ConfigValue<uint, float> interval; public void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown duration = ((BaseUnityPlugin)this).Config.Bind<uint>("General", "Minimum Duration", 10u, "After damage is dealt, the target's health bar will remain visible for this many seconds."); threshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Health Threshold", 75f, new ConfigDescription("Enemies at this hit point percentage or below remain visible indefinitely.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); threshold.convert = percent; range = ((BaseUnityPlugin)this).Config.Bind<uint>("General", "Maximum Range", 100u, "Remove health bar regardless of health threshold if distance to target exceeds this value in meters. Set to zero for unlimited range."); ally = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allied Targets", true, "Determines whether allies reveal their target upon dealing damage."); delay = ((BaseUnityPlugin)this).Config.Bind<uint>("Other", "Targeting Delay", 0u, "Aiming directly at an enemy will display their health for this many milliseconds. If target is below the health threshold, minimum duration parameter is used instead."); delay.convert = milliseconds; alpha = ((BaseUnityPlugin)this).Config.Bind<float>("Other", "Alpha Channel", 85f, new ConfigDescription("Use this parameter to adjust transparency/opacity of the health bar interface.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); alpha.convert = percent; interval = ((BaseUnityPlugin)this).Config.Bind<uint>("Other", "Refresh Interval", 500u, "How often to check target health/range, in milliseconds. Note that decreasing this value could negatively affect performance."); interval.convert = milliseconds; ReplaceEventHandler(); Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); static float milliseconds(uint input) { return (float)input / 1000f; } static float percent(float input) { return input / 100f; } } private static void ReplaceEventHandler() { try { Type typeFromHandle = typeof(CombatHealthBarViewer); Type typeFromHandle2 = typeof(GlobalEventManager); string name = "onClientDamageNotified"; RuntimeHelpers.RunClassConstructor(typeFromHandle.TypeHandle); EventInfo @event = typeFromHandle2.GetEvent(name); Delegate[] invocationList = (typeFromHandle2.GetField(name, BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Delegate).GetInvocationList(); foreach (Delegate @delegate in invocationList) { if (typeFromHandle == @delegate.Method.DeclaringType.DeclaringType) { @event.RemoveEventHandler(null, @delegate); return; } } throw new Exception("Unable to locate original health bar event handler."); } catch (Exception value) { Console.WriteLine(value); } finally { GlobalEventManager.onClientDamageNotified += ShowHealthBar; } } [HarmonyPatch(typeof(CombatHealthBarViewer), "Awake")] [HarmonyPostfix] private static void ApplySettings(CombatHealthBarViewer __instance) { __instance.healthBarDuration = (uint)duration; if ((float)alpha != 1f && Object.op_Implicit((Object)(object)((Component)__instance).gameObject)) { ((Component)__instance).gameObject.AddComponent<CanvasGroup>().alpha = alpha; } } [HarmonyPatch(typeof(CombatHealthBarViewer), "CleanUp")] [HarmonyPrefix] private static bool CheckStatus(CombatHealthBarViewer __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) int num = __instance.trackedVictims.Count; while (--num >= 0) { HealthComponent val = __instance.trackedVictims[num]; HealthBarInfo healthBarInfo = __instance.GetHealthBarInfo(val); if (Object.op_Implicit((Object)(object)val) && val.alive && Object.op_Implicit((Object)(object)val.body)) { if (healthBarInfo.endTime > Time.time) { continue; } float num2; if ((uint)range == 0 || !Object.op_Implicit((Object)(object)__instance.viewerBody)) { num2 = (uint)range; } else { Vector3 val2 = __instance.viewerBody.corePosition - val.body.corePosition; num2 = ((Vector3)(ref val2)).magnitude; } float num3 = num2; if (val.combinedHealthFraction <= (float)threshold && num3 <= (float)(uint)range) { healthBarInfo.endTime = Time.time + (float)interval; continue; } } __instance.Remove(num, healthBarInfo); } return false; } private static void ShowHealthBar(DamageDealtMessage message) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) if (message.isSilent || !Object.op_Implicit((Object)(object)message.victim) || !Object.op_Implicit((Object)(object)message.attacker)) { return; } HealthComponent component = message.victim.GetComponent<HealthComponent>(); if (!Object.op_Implicit((Object)(object)component) || component.dontShowHealthbar) { return; } foreach (CombatHealthBarViewer instances in CombatHealthBarViewer.instancesList) { if (Object.op_Implicit((Object)(object)instances.viewerBodyObject)) { object obj = instances.viewerBodyObject; object obj2 = message.attacker; if ((bool)ally) { obj = instances.viewerTeamIndex; obj2 = TeamComponent.GetObjectTeam(message.attacker); } if (obj.Equals(obj2)) { instances.HandleDamage(component, TeamComponent.GetObjectTeam(message.victim)); } } } } [HarmonyPatch(typeof(CameraRigController), "SetCameraState")] [HarmonyPostfix] private static void UpdateCrosshair(CameraRigController __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) CameraModeBase cameraMode = __instance.cameraMode; HurtBox val2 = (__instance.lastCrosshairHurtBox = ((InstanceData)(/*isinst with value type is only supported in some contexts*/?)).lastCrosshairHurtBox); if (Object.op_Implicit((Object)(object)__instance.hud)) { CombatHealthBarViewer combatHealthBarViewer = __instance.hud.combatHealthBarViewer; if (Object.op_Implicit((Object)(object)combatHealthBarViewer)) { combatHealthBarViewer.crosshairTarget = (Object.op_Implicit((Object)(object)val2) ? val2.healthComponent : null); } } } [HarmonyPatch(typeof(CombatHealthBarViewer), "Update")] [HarmonyPrefix] private static bool ShowCrosshairTarget(CombatHealthBarViewer __instance) { if (Object.op_Implicit((Object)(object)__instance.crosshairTarget)) { float num = delay; if (__instance.crosshairTarget.combinedHealthFraction <= (float)threshold) { num = (uint)duration; } if (num > 0f) { HealthBarInfo healthBarInfo = __instance.GetHealthBarInfo(__instance.crosshairTarget); healthBarInfo.endTime = Mathf.Max(healthBarInfo.endTime, Time.time + num); } } __instance.SetDirty(); return false; } } }