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 ItemHoverInfo v1.1.2
ItemHoverInfo.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using RoR2; 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("ItemHoverInfo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ItemHoverInfo")] [assembly: AssemblyTitle("ItemHoverInfo")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ItemHoverInfo { [BepInPlugin("com.example.itemhoverinfo", "ItemHoverInfo", "1.1.2")] public class ItemHoverInfoPlugin : BaseUnityPlugin { public const string PluginGUID = "com.example.itemhoverinfo"; public const string PluginName = "ItemHoverInfo"; public const string PluginVersion = "1.1.2"; private ConfigEntry<float> hoverDelay; private ConfigEntry<float> maxDistance; private ConfigEntry<float> castRadius; private ConfigEntry<bool> showFullDescription; private ConfigEntry<bool> showChestContents; private ConfigEntry<bool> showCommandCubes; private ConfigEntry<int> maxListedChoices; private ConfigEntry<int> panelWidth; private ConfigEntry<bool> debugLogging; private Component target; private float hoverStartTime; private bool panelVisible; private Vector3 panelWorldPos; private string panelText = ""; private Camera panelCamera; private Component warnedTarget; private readonly Dictionary<string, string> textCache = new Dictionary<string, string>(); private GUIStyle labelStyle; private Texture2D backgroundTexture; private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly Dictionary<string, string> StyleColors = new Dictionary<string, string> { { "cIsDamage", "#FF6A3D" }, { "cIsHealing", "#86E15C" }, { "cIsHealth", "#E05353" }, { "cIsUtility", "#8097E6" }, { "cIsVoid", "#CC66FF" }, { "cStack", "#BFBFBF" }, { "cSub", "#AAAAAA" }, { "cDeath", "#D43B3B" }, { "cEvent", "#E8B04A" }, { "cShrine", "#E0C170" } }; private static readonly Regex StyleOpenTag = new Regex("<style=([A-Za-z]+)>", RegexOptions.Compiled); private void Awake() { hoverDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Hover Delay", 0.3f, "Seconds the crosshair must stay on something before its info is shown."); maxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Max Distance", 40f, "Maximum distance (meters) at which things can be inspected."); castRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Aim Tolerance", 0.35f, "Radius (meters) of the aim check. Larger = easier to target small items."); showFullDescription = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Full Description", true, "If false, only the short pickup text is shown."); showChestContents = ((BaseUnityPlugin)this).Config.Bind<bool>("Targets", "Show Chest Contents", true, "Show what a closed chest will drop. Set to false to keep chests a surprise."); showCommandCubes = ((BaseUnityPlugin)this).Config.Bind<bool>("Targets", "Show Command Cube Choices", true, "Show the choices offered by Command cubes and similar item pickers."); maxListedChoices = ((BaseUnityPlugin)this).Config.Bind<int>("Targets", "Max Listed Choices", 6, "Pickers with more choices than this only show a summary instead of listing every item."); panelWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "Panel Width", 380, "Width of the info panel in pixels."); debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Debug Logging", false, "Log what the crosshair is pointing at to the BepInEx console/log file."); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)backgroundTexture)) { Object.Destroy((Object)(object)backgroundTexture); } } private void Update() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) panelVisible = false; if (PauseManager.isPaused) { ResetTarget(); return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CameraRigController val = ((firstLocalUser != null) ? firstLocalUser.cameraRigController : null); if ((Object)(object)val == (Object)null || (Object)(object)val.sceneCam == (Object)null) { ResetTarget(); return; } panelCamera = val.sceneCam; Ray aimRay = default(Ray); ((Ray)(ref aimRay))..ctor(((Component)panelCamera).transform.position, ((Component)panelCamera).transform.forward); CharacterBody cachedBody = firstLocalUser.cachedBody; if ((Object)(object)cachedBody != (Object)null && (Object)(object)cachedBody.inputBank != (Object)null) { aimRay = cachedBody.inputBank.GetAimRay(); } Component val2 = FindHoveredTarget(aimRay); if ((Object)(object)val2 != (Object)(object)target) { target = val2; hoverStartTime = Time.unscaledTime; if (debugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(((Object)(object)target != (Object)null) ? ("Crosshair on " + ((object)target).GetType().Name + " (" + ((Object)target).name + ")") : "Crosshair left target")); } } if ((Object)(object)target != (Object)null && Time.unscaledTime - hoverStartTime >= hoverDelay.Value) { string value = GetPanelText(target); if (string.IsNullOrEmpty(value) && (Object)(object)warnedTarget != (Object)(object)target) { warnedTarget = target; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Hovered a " + ((object)target).GetType().Name + " (" + ((Object)target).name + ") but could not read its item. Members: " + DescribeMembers(target))); } if (!string.IsNullOrEmpty(value)) { panelText = value; panelWorldPos = target.transform.position + Vector3.up * HeightOffsetFor(target); panelVisible = true; } } } private void ResetTarget() { target = null; panelVisible = false; } private static float HeightOffsetFor(Component c) { if (c is ShopTerminalBehavior) { return 2f; } if (c is ChestBehavior) { return 1.5f; } if (c is PickupPickerController) { return 1.5f; } return 0.8f; } private Component ResolveTarget(Collider col) { GenericPickupController componentInParent = ((Component)col).GetComponentInParent<GenericPickupController>(); if (Object.op_Implicit((Object)(object)componentInParent)) { return (Component)(object)componentInParent; } ShopTerminalBehavior componentInParent2 = ((Component)col).GetComponentInParent<ShopTerminalBehavior>(); if (Object.op_Implicit((Object)(object)componentInParent2)) { return (Component)(object)componentInParent2; } if (showChestContents.Value) { ChestBehavior componentInParent3 = ((Component)col).GetComponentInParent<ChestBehavior>(); if (Object.op_Implicit((Object)(object)componentInParent3)) { return (Component)(object)componentInParent3; } } if (showCommandCubes.Value) { PickupPickerController componentInParent4 = ((Component)col).GetComponentInParent<PickupPickerController>(); if (Object.op_Implicit((Object)(object)componentInParent4)) { return (Component)(object)componentInParent4; } } return null; } private Component FindHoveredTarget(Ray ray) { //IL_0000: 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_004f: 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) RaycastHit[] array = Physics.SphereCastAll(ray, castRadius.Value, maxDistance.Value, -1, (QueryTriggerInteraction)2); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; Collider collider = ((RaycastHit)(ref val)).collider; if (Object.op_Implicit((Object)(object)collider)) { Component val2 = ResolveTarget(collider); if (!((Object)(object)val2 == (Object)null) && !IsOccluded(((Ray)(ref ray)).origin, val2, collider)) { return val2; } } } return null; } private bool IsOccluded(Vector3 origin, Component candidate, Collider candidateCollider) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //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_0014: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = candidateCollider.bounds; Vector3 val = ((Bounds)(ref bounds)).center - origin; float magnitude = ((Vector3)(ref val)).magnitude; float num = magnitude - (castRadius.Value + 0.5f); if (num <= 0.1f) { return false; } RaycastHit[] array = Physics.RaycastAll(origin, val / magnitude, num, -1, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; Collider collider = ((RaycastHit)(ref val2)).collider; if (Object.op_Implicit((Object)(object)collider) && !((Component)collider).transform.IsChildOf(candidate.transform) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<CharacterBody>()) && !((Object)(object)ResolveTarget(collider) != (Object)null)) { return true; } } return false; } private string GetPanelText(Component c) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) PickupPickerController val = (PickupPickerController)(object)((c is PickupPickerController) ? c : null); if ((Object)(object)val != (Object)null) { return GetPickerText(val); } if (!TryGetPickupIndex(c, out var index)) { return null; } bool flag = c is ChestBehavior; string key = "p:" + index.value + (flag ? ":c" : ""); if (textCache.TryGetValue(key, out var value)) { return value; } string text = BuildPickupBlock(index, includeFullDescription: true); if (text == null) { return null; } if (flag) { text = "<color=#AAAAAA>Contains:</color>\n" + text; } textCache[key] = text; return text; } private string BuildPickupBlock(PickupIndex index, bool includeFullDescription) { //IL_0000: 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) PickupDef pickupDef = PickupCatalog.GetPickupDef(index); if (pickupDef == null) { return null; } string shortToken = null; string longToken = null; GetDescriptionTokens(pickupDef, out shortToken, out longToken); string value = ColorUtility.ToHtmlStringRGB(pickupDef.baseColor); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<b><size=18><color=#").Append(value).Append(">") .Append(Language.GetString(pickupDef.nameToken)) .Append("</color></size></b>"); if (!string.IsNullOrEmpty(shortToken)) { stringBuilder.Append("\n<color=#D8D8D8><i>").Append(ConvertRichText(Language.GetString(shortToken))).Append("</i></color>"); } if (includeFullDescription && showFullDescription.Value && !string.IsNullOrEmpty(longToken)) { stringBuilder.Append("\n\n").Append(ConvertRichText(Language.GetString(longToken))); } return stringBuilder.ToString(); } private static void GetDescriptionTokens(PickupDef def, out string shortToken, out string longToken) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_0010: 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) shortToken = null; longToken = null; if ((int)def.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(def.itemIndex); if ((Object)(object)itemDef != (Object)null) { shortToken = itemDef.pickupToken; longToken = itemDef.descriptionToken; } } else if ((int)def.equipmentIndex != -1) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(def.equipmentIndex); if ((Object)(object)equipmentDef != (Object)null) { shortToken = equipmentDef.pickupToken; longToken = equipmentDef.descriptionToken; } } } private string GetPickerText(PickupPickerController picker) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if (!(GetMemberValue(picker, "options") is Array { Length: not 0 } array)) { return null; } List<PickupIndex> list = new List<PickupIndex>(); foreach (object item in array) { if (item != null) { object memberValue = GetMemberValue(item, "available"); if ((!(memberValue is bool) || (bool)memberValue) && ReadPickupIndex(item, out var index, "pickupIndex", "pickup")) { list.Add(index); } } } if (list.Count == 0) { return null; } StringBuilder stringBuilder = new StringBuilder("pick:"); foreach (PickupIndex item2 in list) { stringBuilder.Append(item2.value).Append(','); } string key = stringBuilder.ToString(); if (textCache.TryGetValue(key, out var value)) { return value; } StringBuilder stringBuilder2 = new StringBuilder(); if (list.Count <= maxListedChoices.Value) { stringBuilder2.Append("<color=#AAAAAA>Choose one:</color>"); foreach (PickupIndex item3 in list) { string text = BuildPickupBlock(item3, showFullDescription.Value); if (text != null) { stringBuilder2.Append("\n\n").Append(text); } } } else { PickupDef pickupDef = PickupCatalog.GetPickupDef(list[0]); string value2 = ((pickupDef != null) ? ColorUtility.ToHtmlStringRGB(pickupDef.baseColor) : "FFFFFF"); stringBuilder2.Append("<b><size=18><color=#").Append(value2).Append(">Choice of ") .Append(list.Count) .Append(" items</color></size></b>"); stringBuilder2.Append("\n<color=#D8D8D8><i>Interact to pick any one of them.</i></color>"); } string text2 = stringBuilder2.ToString(); textCache[key] = text2; return text2; } private static string ConvertRichText(string s) { if (string.IsNullOrEmpty(s)) { return s; } s = StyleOpenTag.Replace(s, (Match m) => "<color=" + (StyleColors.TryGetValue(m.Groups[1].Value, out var value) ? value : "#FFFFFF") + ">"); return s.Replace("</style>", "</color>"); } private static bool TryGetPickupIndex(Component c, out PickupIndex index) { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) index = PickupIndex.none; ShopTerminalBehavior val = (ShopTerminalBehavior)(object)((c is ShopTerminalBehavior) ? c : null); if ((Object)(object)val != (Object)null) { object memberValue = GetMemberValue(val, "hidden"); if (memberValue is bool && (bool)memberValue) { return false; } MethodInfo method = typeof(ShopTerminalBehavior).GetMethod("CurrentPickupIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { object obj = method.Invoke(val, null); if (obj is PickupIndex) { index = (PickupIndex)obj; return ((PickupIndex)(ref index)).isValid; } } return ReadPickupIndex(val, out index, "pickupIndex", "pickupState", "pickup"); } if (c is ChestBehavior) { return ReadPickupIndex(c, out index, "dropPickup", "dropPickupState", "pickupState"); } return ReadPickupIndex(c, out index, "pickupIndex", "pickupState", "pickup"); } private static bool ReadPickupIndex(object holder, out PickupIndex index, params string[] memberNames) { //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_002a: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) index = PickupIndex.none; foreach (string name in memberNames) { object memberValue = GetMemberValue(holder, name); if (memberValue == null) { continue; } if (memberValue is PickupIndex) { index = (PickupIndex)memberValue; if (((PickupIndex)(ref index)).isValid) { return true; } continue; } object memberValue2 = GetMemberValue(memberValue, "pickupIndex"); if (memberValue2 is PickupIndex) { index = (PickupIndex)memberValue2; if (((PickupIndex)(ref index)).isValid) { return true; } } } return false; } private static string DescribeMembers(Component c) { StringBuilder stringBuilder = new StringBuilder(); FieldInfo[] fields = ((object)c).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { stringBuilder.Append(fieldInfo.Name).Append(':').Append(fieldInfo.FieldType.Name) .Append(' '); } PropertyInfo[] properties = ((object)c).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { stringBuilder.Append(propertyInfo.Name).Append(':').Append(propertyInfo.PropertyType.Name) .Append(' '); } return stringBuilder.ToString(); } private static object GetMemberValue(object obj, string name) { if (obj == null) { return null; } Type type = obj.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(obj); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(obj, null); } return null; } private void OnGUI() { //IL_001e: 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_0028: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (panelVisible && !((Object)(object)panelCamera == (Object)null)) { Vector3 val = panelCamera.WorldToScreenPoint(panelWorldPos); if (!(val.z <= 0f)) { EnsureStyles(); float num = panelWidth.Value; float num2 = num - 20f; GUIContent val2 = new GUIContent(panelText); float num3 = labelStyle.CalcHeight(val2, num2) + 20f; float num4 = val.x - num / 2f; float num5 = (float)Screen.height - val.y - num3; num4 = Mathf.Clamp(num4, 8f, (float)Screen.width - num - 8f); num5 = Mathf.Clamp(num5, 8f, (float)Screen.height - num3 - 8f); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num4, num5, num, num3); GUI.DrawTexture(val3, (Texture)(object)backgroundTexture); GUI.Label(new Rect(((Rect)(ref val3)).x + 10f, ((Rect)(ref val3)).y + 10f, num2, num3 - 20f), val2, labelStyle); } } } private void EnsureStyles() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0032: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (labelStyle == null) { backgroundTexture = new Texture2D(1, 1); backgroundTexture.SetPixel(0, 0, new Color(0.05f, 0.05f, 0.07f, 0.88f)); backgroundTexture.Apply(); ((Object)backgroundTexture).hideFlags = (HideFlags)61; labelStyle = new GUIStyle(GUI.skin.label) { richText = true, wordWrap = true, fontSize = 15, alignment = (TextAnchor)0 }; labelStyle.normal.textColor = Color.white; } } } }