using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using EpicLoot; using EpicLoot.Crafting; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("EnhancedTooltip")] [assembly: AssemblyDescription("Enhanced tooltip system for Valheim mods - EpicLoot, VES, RTDLegends")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EnhancedTooltip")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("A1B2C3D4-E5F6-7890-ABCD-EF1234567890")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace EnhancedTooltip; [HarmonyPatch(typeof(CraftSuccessDialog), "Show")] public static class CraftSuccessDialogFixPatch { [HarmonyPostfix] public static void Postfix(CraftSuccessDialog __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { bool flag = false; if ((Object)(object)__instance.Icon != (Object)null && !((Behaviour)__instance.Icon).enabled) { ((Behaviour)__instance.Icon).enabled = true; flag = true; } if ((Object)(object)__instance.Description != (Object)null && !((Behaviour)__instance.Description).enabled) { ((Behaviour)__instance.Description).enabled = true; flag = true; } if ((Object)(object)__instance.NameText != (Object)null && !((Behaviour)__instance.NameText).enabled) { ((Behaviour)__instance.NameText).enabled = true; flag = true; } if ((Object)(object)__instance.MagicBG != (Object)null && !((Behaviour)__instance.MagicBG).enabled) { ((Behaviour)__instance.MagicBG).enabled = true; flag = true; } if (EnhancedTooltipPlugin.EnableDialogLogging.Value) { string[] obj = new string[6] { "[EnhancedTooltip][CraftSuccessDialog] NameText='", null, null, null, null, null }; int num = 1; TMP_Text nameText = __instance.NameText; obj[num] = (((Object)(object)nameText != (Object)null) ? nameText.text : null) ?? "null"; obj[2] = "' "; int num2 = 3; string format = "DescLen={0} "; TMP_Text description = __instance.Description; int? num3 = ((!((Object)(object)description == (Object)null)) ? description.text?.Length : ((int?)null)); int? num4 = num3; obj[num2] = string.Format(format, num4.GetValueOrDefault()); int num5 = 4; string format2 = "IconEnabled={0} "; Image icon = __instance.Icon; obj[num5] = string.Format(format2, ((Object)(object)icon != (Object)null) ? new bool?(((Behaviour)icon).enabled) : ((bool?)null)); obj[5] = $"Fixed={flag}"; Debug.LogWarning((object)string.Concat(obj)); } } catch (Exception ex) { Debug.LogError((object)("[EnhancedTooltip] CraftSuccessDialog fix error: " + ex.Message)); } } } [BepInPlugin("enhancedtooltip.valheim.rizumi", "Enhanced Tooltip", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EnhancedTooltipPlugin : BaseUnityPlugin { private static EnhancedTooltipPlugin _instance; public static ConfigEntry EnableLogging; public static ConfigEntry EnableEpicLootIntegration; public static ConfigEntry EnableVESIntegration; public static ConfigEntry EnableRTDIntegration; public static ConfigEntry EnableSetBonusSection; public static ConfigEntry EnableDialogLogging; public static ConfigEntry EnableCompactMode; public static ConfigEntry SetBonusHeaderColor; public static ConfigEntry VESHeaderColor; public static ConfigEntry EpicLootHeaderColor; private Harmony _harmony; public static EnhancedTooltipPlugin Instance => _instance; public static bool HasVES { get; private set; } public static bool HasRTD { get; private set; } public static bool HasEpicLoot { get; private set; } private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown _instance = this; _harmony = new Harmony("enhancedtooltip.valheim.rizumi"); CreateConfigs(); DetectMods(); ApplyPatches(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Enhanced Tooltip v1.0.0 loaded. VES={HasVES}, RTD={HasRTD}, EpicLoot={HasEpicLoot}"); } private void CreateConfigs() { EnableLogging = ((BaseUnityPlugin)this).Config.Bind("General", "EnableLogging", false, "Enable debug logging for tooltips."); EnableDialogLogging = ((BaseUnityPlugin)this).Config.Bind("General", "EnableDialogLogging", false, "Enable logging of CraftSuccessDialog state in enchanting table."); EnableEpicLootIntegration = ((BaseUnityPlugin)this).Config.Bind("Integration", "EnableEpicLoot", true, "Integrate EpicLoot magic effects."); EnableVESIntegration = ((BaseUnityPlugin)this).Config.Bind("Integration", "EnableVES", true, "Integrate VES enchantments."); EnableRTDIntegration = ((BaseUnityPlugin)this).Config.Bind("Integration", "EnableRTD", true, "Integrate RTDLegends set bonuses."); EnableSetBonusSection = ((BaseUnityPlugin)this).Config.Bind("Display", "EnableSetBonusSection", true, "Show set bonus block."); EnableCompactMode = ((BaseUnityPlugin)this).Config.Bind("Display", "CompactMode", false, "Compact spacing."); SetBonusHeaderColor = ((BaseUnityPlugin)this).Config.Bind("Colors", "SetBonusHeader", "#FFD700", "Set bonus header color."); VESHeaderColor = ((BaseUnityPlugin)this).Config.Bind("Colors", "VESHeader", "#00FF88", "VES header color."); EpicLootHeaderColor = ((BaseUnityPlugin)this).Config.Bind("Colors", "EpicLootHeader", "#ADD8E6", "EpicLoot header color."); } private void DetectMods() { HasVES = Chainloader.PluginInfos.ContainsKey("kg.ValheimEnchantmentSystem"); HasRTD = Chainloader.PluginInfos.ContainsKey("Soloredis.RtDLegends"); HasEpicLoot = Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"); } private void ApplyPatches() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_0143: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown _harmony.PatchAll(typeof(EnhancedTooltipPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"EnhancedTooltip: Applied all Harmony patches via PatchAll"); Type type = AccessTools.TypeByName("EpicLoot.MagicTooltip"); if (type != null) { MethodInfo methodInfo = AccessTools.Method(type, "GetTooltip", (Type[])null, (Type[])null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(TooltipEnhancer), "MagicTooltipPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched MagicTooltip.GetTooltip (postfix)"); } } MethodInfo methodInfo2 = AccessTools.Method(typeof(ItemData), "GetTooltip", new Type[5] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) }, (Type[])null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(TooltipEnhancer), "Prefix_SaveOriginalTooltip", (Type[])null) { priority = 1000 }, new HarmonyMethod(typeof(TooltipEnhancer), "FinalizeTooltipPostfix", (Type[])null) { priority = int.MinValue }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched ItemDrop.ItemData.GetTooltip with prefix+postfix."); } Type type2 = AccessTools.TypeByName("EpicLoot.MagicTooltipPatches"); if (type2 != null) { Type type3 = AccessTools.Inner(type2, "MagicItemTooltip_ItemDrop_Patch"); if (type3 != null) { MethodInfo methodInfo3 = AccessTools.Method(type3, "Postfix", (Type[])null, (Type[])null); if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(EpicLootTooltipPatch), "Prefix_BlockEpicLootPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Blocked EpicLoot non-magic tooltip postfix (VES fix)."); } } } Type type4 = AccessTools.TypeByName("EpicLoot.ItemDataExtensions"); if (type4 != null) { MethodInfo methodInfo4 = AccessTools.Method(type4, "GetSetTooltip", new Type[1] { typeof(ItemData) }, (Type[])null); if (methodInfo4 != null) { _harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(EpicLootTooltipPatch), "Prefix_GetSetTooltip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched EpicLoot.ItemDataExtensions.GetSetTooltip to return empty string."); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"EnhancedTooltip patches applied."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPriority(300)] public static class EpicLootTooltipPatch { private static Type _magicItemType; private static Type _magicTooltipType; private static Type _itemDataExtensionsType; private static MethodInfo _getMagicItemMethod; private static MethodInfo _getSetTooltipMethod; private static MethodInfo _isSetItemMethod; private static MethodInfo _isMagicMethod; private static bool _reflectionInitialized; private static bool _reflectionFailed; [ThreadStatic] private static bool _allowOriginalGetSetTooltip; private static void InitializeReflection() { if (_reflectionInitialized || _reflectionFailed) { return; } try { Assembly assembly = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { if (assembly2.GetName().Name == "EpicLoot") { assembly = assembly2; break; } } if (assembly == null) { _reflectionFailed = true; return; } _magicItemType = assembly.GetType("EpicLoot.MagicItem"); _magicTooltipType = assembly.GetType("EpicLoot.MagicTooltip"); _itemDataExtensionsType = assembly.GetType("EpicLoot.ItemDataExtensions"); if (_itemDataExtensionsType != null) { _getMagicItemMethod = _itemDataExtensionsType.GetMethod("GetMagicItem", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); _getSetTooltipMethod = _itemDataExtensionsType.GetMethod("GetSetTooltip", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); _isSetItemMethod = _itemDataExtensionsType.GetMethod("IsSetItem", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); _isMagicMethod = _itemDataExtensionsType.GetMethod("IsMagic", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(ItemData) }, null); } _reflectionInitialized = true; } catch (Exception ex) { Debug.LogWarning((object)("[EnhancedTooltip] EpicLoot reflection init failed: " + ex.Message)); _reflectionFailed = true; } } public static object GetMagicItem(ItemData item) { if (item == null || _reflectionFailed) { return null; } InitializeReflection(); if (!_reflectionInitialized || _getMagicItemMethod == null) { return null; } object result; try { result = _getMagicItemMethod.Invoke(null, new object[1] { item }); } catch { result = null; } return result; } public static bool IsSetItem(ItemData item) { if (item == null || _reflectionFailed) { return false; } InitializeReflection(); if (!_reflectionInitialized || _isSetItemMethod == null) { return false; } bool result; try { result = (bool)_isSetItemMethod.Invoke(null, new object[1] { item }); } catch { result = false; } return result; } public static string GetSetTooltip(ItemData item) { if (item == null || _reflectionFailed) { return string.Empty; } InitializeReflection(); if (!_reflectionInitialized || _getSetTooltipMethod == null) { return string.Empty; } string result; try { _allowOriginalGetSetTooltip = true; result = (_getSetTooltipMethod.Invoke(null, new object[1] { item }) as string) ?? string.Empty; } catch { result = string.Empty; } finally { _allowOriginalGetSetTooltip = false; } return result; } public static bool IsMagicItem(ItemData item) { if (item == null || _reflectionFailed) { return false; } InitializeReflection(); if (!_reflectionInitialized || _isMagicMethod == null) { return false; } bool result; try { result = (bool)_isMagicMethod.Invoke(null, new object[1] { item }); } catch { result = false; } return result; } public static void Postfix_ItemTooltip_RemoveSetBonus(ref string __result, ItemData item) { if (item != null && !string.IsNullOrEmpty(__result) && !IsMagicItem(item)) { string pattern = "\\n\\n[^\\n]*(?:Комплект|Set|Бонус комплекта|Set Bonus|套装|セット|\\$mod_epicloot_set)[^\\n]*(?:(?!\\n\\n)[\\s\\S])*?(?=\\n\\n|$)"; __result = Regex.Replace(__result, pattern, "", RegexOptions.IgnoreCase | RegexOptions.Multiline); __result = Regex.Replace(__result, "\\n{3,}", "\n\n"); __result = __result.TrimEnd(Array.Empty()); } } public static ItemData GetItemFromMagicTooltip(object magicTooltipInstance) { if (magicTooltipInstance == null) { return null; } InitializeReflection(); if (_magicTooltipType == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(_magicTooltipType, "P"); if (fieldInfo == null) { return null; } object? value = fieldInfo.GetValue(magicTooltipInstance); return (ItemData)((value is ItemData) ? value : null); } public static object GetMagicItemFromMagicTooltip(object magicTooltipInstance) { if (magicTooltipInstance == null) { return null; } InitializeReflection(); if (_magicTooltipType == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(_magicTooltipType, "P"); if (fieldInfo == null) { return null; } return fieldInfo.GetValue(magicTooltipInstance); } public static int GetQualityLevelFromMagicTooltip(object magicTooltipInstance) { if (magicTooltipInstance == null) { return 1; } InitializeReflection(); if (_magicTooltipType == null) { return 1; } FieldInfo fieldInfo = AccessTools.Field(_magicTooltipType, "P"); if (fieldInfo == null) { return 1; } return (int)fieldInfo.GetValue(magicTooltipInstance); } public static bool Prefix_GetSetTooltip(ItemData item, ref string __result) { if (_allowOriginalGetSetTooltip) { return true; } __result = ""; return false; } public static bool Prefix_BlockEpicLootPostfix(ItemData item) { if (item == null) { return true; } return IsMagicItem(item); } } public static class RTDSetFormatter { private const string ColorGold = "#FF9800"; private const string ColorInactive = "#808080"; public static string BuildSetBonusBlock(ItemData item) { if (item == null) { return string.Empty; } if (!EnhancedTooltipPlugin.EnableSetBonusSection.Value) { return string.Empty; } string empty; try { StatusEffect setStatusEffect = item.m_shared.m_setStatusEffect; string setName = item.m_shared.m_setName; int num = item.m_shared.m_setSize; if ((Object)(object)setStatusEffect != (Object)null && !string.IsNullOrEmpty(setStatusEffect.m_name)) { if (num <= 0) { int num2 = CountEquippedWithStatusEffect(setStatusEffect); num = ((num2 > 0) ? num2 : 3); } if (num > 0) { int num3 = CountEquippedWithStatusEffect(setStatusEffect); string color = ((num3 >= num) ? "#FF9800" : "#808080"); return BuildBlock(GetLocalizedName(setStatusEffect.m_name), num3, num, color, setStatusEffect); } } if (!string.IsNullOrEmpty(setName)) { if (num <= 0) { int num4 = CountEquippedWithSetName(setName); num = ((num4 > 0) ? num4 : 3); } if (num > 0) { int num5 = CountEquippedWithSetName(setName); string color2 = ((num5 >= num) ? "#FF9800" : "#808080"); return BuildBlock(GetLocalizedName(setName), num5, num, color2, null); } } empty = string.Empty; } catch (Exception ex) { Debug.LogWarning((object)("[EnhancedTooltip] Set block error: " + ex.Message)); empty = string.Empty; } return empty; } private static string BuildBlock(string displayName, int equipped, int setSize, string color, StatusEffect effect) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("\n---\n"); stringBuilder.Append($"+ Бонус комплекта [{displayName}] ({equipped}/{setSize}):"); if ((Object)(object)effect != (Object)null) { string setStatusEffectTooltip = GetSetStatusEffectTooltip(effect); if (!string.IsNullOrEmpty(setStatusEffectTooltip)) { string[] array = setStatusEffectTooltip.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { stringBuilder.Append($"\n > {text}"); } } } } stringBuilder.Append("\n\n"); return stringBuilder.ToString(); } private static int CountEquippedWithStatusEffect(StatusEffect effect) { if ((Object)(object)effect == (Object)null) { return 0; } Player localPlayer = Player.m_localPlayer; if ((((Object)(object)localPlayer != (Object)null) ? ((Humanoid)localPlayer).m_inventory : null) == null) { return 0; } int num = 0; foreach (ItemData item in ((Humanoid)localPlayer).m_inventory.m_inventory) { if (item != null && item.m_equipped && (Object)(object)item.m_shared.m_setStatusEffect == (Object)(object)effect) { num++; } } return num; } private static int CountEquippedWithSetName(string setName) { if (string.IsNullOrEmpty(setName)) { return 0; } Player localPlayer = Player.m_localPlayer; if ((((Object)(object)localPlayer != (Object)null) ? ((Humanoid)localPlayer).m_inventory : null) == null) { return 0; } int num = 0; foreach (ItemData item in ((Humanoid)localPlayer).m_inventory.m_inventory) { if (item != null && item.m_equipped && item.m_shared.m_setName == setName) { num++; } } return num; } private static string GetLocalizedName(string key) { if (string.IsNullOrEmpty(key)) { return key; } string text = Localization.instance.Localize(key); if (!string.IsNullOrEmpty(text)) { return text; } return key; } private static string GetSetStatusEffectTooltip(StatusEffect statusEffect) { if ((Object)(object)statusEffect == (Object)null) { return string.Empty; } try { string tooltipString = statusEffect.GetTooltipString(); if (!string.IsNullOrEmpty(tooltipString)) { return Localization.instance.Localize(tooltipString); } if (!string.IsNullOrEmpty(statusEffect.m_name)) { string text = Localization.instance.Localize(statusEffect.m_name); if (!string.IsNullOrEmpty(statusEffect.m_startMessage)) { return text + ": " + Localization.instance.Localize(statusEffect.m_startMessage); } return text; } } catch { } return string.Empty; } } public static class TooltipEnhancer { public static int FindInsertPositionAfterStats(string text) { if (string.IsNullOrEmpty(text)) { return -1; } string[] obj = new string[5] { "$item_weight", "$item_armor", "$item_durability", "$item_quality", "$item_repairlevel" }; int num = -1; string[] array = obj; foreach (string text2 in array) { int startIndex = 0; while (true) { int num2 = text.IndexOf(text2, startIndex, StringComparison.OrdinalIgnoreCase); if (num2 < 0) { break; } text.LastIndexOf('\n', num2); _ = 0; int num3 = text.IndexOf('\n', num2); num3 = ((num3 >= 0) ? (num3 + 1) : text.Length); if (num3 > num) { num = num3; } startIndex = num2 + text2.Length; } } if (num < 0) { return -1; } return num; } public static string Cleanup(string s) { return s.Replace("\n\n\n\n\n", "\n\n").Replace("\n\n\n\n", "\n\n").Replace("\n\n\n", "\n\n") .TrimEnd(Array.Empty()); } public static string ClearExistingSetBlocks(string text) { if (string.IsNullOrEmpty(text)) { return text; } text = Regex.Replace(text, "---\\s*(?:]+>.*?\\s*)*", "", RegexOptions.IgnoreCase | RegexOptions.Singleline); text = Regex.Replace(text, "\\$item_seteffect.*?(?=\\n\\n|\\n• \\$enchantment_canbeenchantedwith:|$)", "", RegexOptions.IgnoreCase | RegexOptions.Singleline); text = Regex.Replace(text, "(?:\\n{1,2}|\\A)(?:[^\\n]*(?:Комплект|Set Bonus|Бонус комплекта|Set[^a-zA-Z])[^\\n]*)\\n(?:[^\\n]*\\n)*(?=\\n{2,}|• \\$enchantment_canbeenchantedwith:|$)", "", RegexOptions.IgnoreCase | RegexOptions.Singleline); text = Regex.Replace(text, "\\n{3,}", "\n\n"); return text.TrimEnd(Array.Empty()); } public static void MagicTooltipPostfix(ref string __result, MagicTooltip __instance) { if (string.IsNullOrEmpty(__result) || __instance == null) { return; } try { ItemData itemFromMagicTooltip = EpicLootTooltipPatch.GetItemFromMagicTooltip(__instance); if (itemFromMagicTooltip == null || !EpicLootTooltipPatch.IsMagicItem(itemFromMagicTooltip) || !EpicLootTooltipPatch.IsSetItem(itemFromMagicTooltip) || !EnhancedTooltipPlugin.EnableSetBonusSection.Value) { return; } string text = RTDSetFormatter.BuildSetBonusBlock(itemFromMagicTooltip); if (string.IsNullOrEmpty(text)) { return; } TooltipLogger.Log("MAGIC_BEFORE_CLEAR", __result); string text2 = ClearExistingSetBlocks(__result); TooltipLogger.Log("MAGIC_AFTER_CLEAR", text2); string text3 = text.TrimStart(Array.Empty()); int num = text2.IndexOf("---", StringComparison.OrdinalIgnoreCase); int num2; string value; if (num >= 0) { num2 = num + "---".Length; value = "\n" + text3; } else { int num3 = text2.IndexOf("• $enchantment_canbeenchantedwith:", StringComparison.OrdinalIgnoreCase); if (num3 >= 0) { num2 = num3; value = text3 + "\n\n"; } else { num2 = FindInsertPositionAfterStats(text2); value = "\n\n" + text3; } } if (num2 >= 0) { __result = text2.Insert(num2, value); } else { __result = text3 + "\n\n" + text2; } __result = Cleanup(__result); TooltipLogger.Log("MAGIC_FINAL", __result); } catch (Exception ex) { Debug.LogError((object)("[EnhancedTooltip] MagicTooltipPostfix error: " + ex.Message + "\n" + ex.StackTrace)); } } public static void Prefix_SaveOriginalTooltip(ItemData item) { } public static void FinalizeTooltipPostfix(ItemData item, int qualityLevel, bool crafting, float worldLevel, int stackOverride, ref string __result) { if (string.IsNullOrEmpty(__result) || item == null) { return; } try { if (!EnhancedTooltipPlugin.EnableSetBonusSection.Value || (EnhancedTooltipPlugin.HasEpicLoot && EpicLootTooltipPatch.IsMagicItem(item))) { return; } string text = RTDSetFormatter.BuildSetBonusBlock(item); if (string.IsNullOrEmpty(text)) { return; } TooltipLogger.Log("NON_MAGIC_BEFORE_CLEAR", __result); int num = __result.IndexOf("$item_seteffect", StringComparison.OrdinalIgnoreCase); string text2; if (num >= 0) { int num2 = __result.IndexOf("\n()); int num3 = FindInsertPositionAfterStats(text2); if (num3 < 0) { num3 = text2.Length; } string value = "\n\n" + text3; if (num3 >= 0) { __result = text2.Insert(num3, value); } else { __result = text3 + "\n\n" + text2; } __result = Cleanup(__result); TooltipLogger.Log("NON_MAGIC_FINAL", __result); } catch (Exception ex) { Debug.LogError((object)("[EnhancedTooltip] FinalizeTooltipPostfix error: " + ex.Message + "\n" + ex.StackTrace)); } } } internal static class TooltipLogger { public static void Log(string prefix, string text) { if (EnhancedTooltipPlugin.EnableLogging.Value) { if (string.IsNullOrEmpty(text)) { Debug.LogWarning((object)("[EnhancedTooltip][" + prefix + "] (null or empty)")); return; } string text2 = ((text.Length > 2000) ? (text.Substring(0, 2000) + "...[TRUNCATED]") : text); Debug.LogWarning((object)("[EnhancedTooltip][" + prefix + "]\n" + text2)); } } }