using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; 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("LineOfSightNametags")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+81548efc41f42e65d00100d77fe1bd8c91d71f15")] [assembly: AssemblyProduct("LineOfSightNametags")] [assembly: AssemblyTitle("LineOfSightNametags")] [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 LineOfSightNametags { [BepInPlugin("com.lineofsightnametags", "Line Of Sight Nametags", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.lineofsightnametags"; public const string PluginName = "Line Of Sight Nametags"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry EnableMod; internal static ConfigEntry RequireDirectLineOfSight; internal static ConfigEntry NametagMaxDistance; internal static ConfigEntry NametagMinFontSize; internal static ConfigEntry NametagMaxFontSize; internal static ConfigEntry NametagShrinkPerMeter; internal static ConfigEntry NametagFadeSpeed; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; BindConfig(); new Harmony("com.lineofsightnametags").PatchAll(typeof(PlayerNametagVisibilityPatch)); Log.LogInfo((object)"Line Of Sight Nametags v1.0.0 loaded"); } private void BindConfig() { EnableMod = ((BaseUnityPlugin)this).Config.Bind("General", "EnableMod", true, "Enable client-side living player nametag visibility adjustments."); RequireDirectLineOfSight = ((BaseUnityPlugin)this).Config.Bind("General", "RequireDirectLineOfSight", true, "Hide the nametag when a wall or another solid object blocks the direct view."); NametagMaxDistance = ((BaseUnityPlugin)this).Config.Bind("Display", "MaxDistance", 120f, "Maximum distance in meters at which a living player nametag can stay visible."); NametagMinFontSize = ((BaseUnityPlugin)this).Config.Bind("Display", "MinFontSize", 7f, "Minimum font size used for very distant nametags."); NametagMaxFontSize = ((BaseUnityPlugin)this).Config.Bind("Display", "MaxFontSize", 18f, "Maximum font size used for nearby nametags."); NametagShrinkPerMeter = ((BaseUnityPlugin)this).Config.Bind("Display", "ShrinkPerMeter", 0.08f, "How quickly the nametag shrinks as distance increases."); NametagFadeSpeed = ((BaseUnityPlugin)this).Config.Bind("Display", "FadeSpeed", 7f, "How quickly the nametag fades in and out."); } } [HarmonyPatch(typeof(WorldSpaceUIPlayerName), "Update")] internal static class PlayerNametagVisibilityPatch { private const float HiddenAlpha = 0f; private const float VisibleAlpha = 1f; private static readonly FieldRef PlayerAvatarRef = AccessTools.FieldRefAccess("playerAvatar"); private static readonly FieldRef IsLocalRef = AccessTools.FieldRefAccess("isLocal"); private static readonly FieldRef IsDisabledRef = AccessTools.FieldRefAccess("isDisabled"); private static readonly FieldRef ColliderRef = AccessTools.FieldRefAccess("collider"); private static Camera mainCamera; [HarmonyPostfix] private static void Postfix(WorldSpaceUIPlayerName __instance) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008a: 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_008c: 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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.EnableMod.Value || (Object)(object)__instance == (Object)null || (Object)(object)__instance.text == (Object)null) { return; } PlayerAvatar val = PlayerAvatarRef.Invoke(__instance); if ((Object)(object)val == (Object)null || IsLocalRef.Invoke(val) || IsDisabledRef.Invoke(val)) { FadeNameTag((Graphic)(object)__instance.text, 0f); return; } Camera val2 = GetMainCamera(); if (!((Object)(object)val2 == (Object)null)) { Vector3 position = ((Component)val2).transform.position; Vector3 targetPoint = GetTargetPoint(val); float num = Vector3.Distance(position, targetPoint); bool num2 = num <= Plugin.NametagMaxDistance.Value; bool flag = !Plugin.RequireDirectLineOfSight.Value || HasDirectLineOfSight(position, targetPoint, val); bool flag2 = num2 && flag; if (flag2) { __instance.Show(); ApplyReadableScale(__instance.text, num); } FadeNameTag((Graphic)(object)__instance.text, flag2 ? 1f : 0f); } } private static Camera GetMainCamera() { if ((Object)(object)mainCamera == (Object)null || !((Behaviour)mainCamera).isActiveAndEnabled) { mainCamera = Camera.main; } return mainCamera; } private static Vector3 GetTargetPoint(PlayerAvatar targetAvatar) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0030: 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) if ((Object)(object)targetAvatar.lowPassRaycastPoint != (Object)null) { return targetAvatar.lowPassRaycastPoint.position; } Collider targetCollider = GetTargetCollider(targetAvatar); if ((Object)(object)targetCollider != (Object)null) { Bounds bounds = targetCollider.bounds; return ((Bounds)(ref bounds)).center; } return ((Component)targetAvatar).transform.position + Vector3.up * 0.75f; } private static Collider GetTargetCollider(PlayerAvatar targetAvatar) { try { return ColliderRef.Invoke(targetAvatar); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Failed to read player collider for nametag visibility: " + ex.Message)); return null; } } private static bool HasDirectLineOfSight(Vector3 observerPoint, Vector3 targetPoint, PlayerAvatar targetAvatar) { //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_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) //IL_001a: 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_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) Vector3 val = targetPoint - observerPoint; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= 0.01f) { return true; } Vector3 val2 = val / magnitude; Vector3 val3 = observerPoint + val2 * 0.05f; float num = Mathf.Max(0f, magnitude - 0.05f); RaycastHit[] array = Physics.RaycastAll(val3, val2, num, -5, (QueryTriggerInteraction)1); if (array.Length == 0) { return true; } Array.Sort(array, CompareRaycastHitDistance); Transform val4 = (((Object)(object)PlayerAvatar.instance != (Object)null) ? ((Component)PlayerAvatar.instance).transform.root : null); Transform root = ((Component)targetAvatar).transform.root; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val5 = array2[i]; Collider collider = ((RaycastHit)(ref val5)).collider; if ((Object)(object)collider == (Object)null) { continue; } Transform root2 = ((Component)collider).transform.root; if (!((Object)(object)val4 != (Object)null) || !((Object)(object)root2 == (Object)(object)val4)) { if ((Object)(object)root2 == (Object)(object)root) { return true; } return false; } } return true; } private static int CompareRaycastHitDistance(RaycastHit left, RaycastHit right) { return ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance); } private static void ApplyReadableScale(TextMeshProUGUI text, float distance) { float value = Plugin.NametagMinFontSize.Value; float value2 = Plugin.NametagMaxFontSize.Value; float value3 = Plugin.NametagShrinkPerMeter.Value; float num = Mathf.Clamp(value2 - distance * value3, value, value2); if (!Mathf.Approximately(((TMP_Text)text).fontSize, num)) { ((TMP_Text)text).fontSize = num; } } private static void FadeNameTag(Graphic text, float targetAlpha) { //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_0022: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Color color = text.color; float num = Mathf.Max(0.01f, Plugin.NametagFadeSpeed.Value) * Time.deltaTime; float num2 = Mathf.MoveTowards(color.a, targetAlpha, num); if (!Mathf.Approximately(color.a, num2)) { text.color = new Color(color.r, color.g, color.b, num2); } } } }