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 DeepTip v1.0.0
GC_Valheim_DeepTip.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DeepTip.Core; using DeepTip.UI; using DeepTip.Valheim; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("Gorduan")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4a06e38031db476b3e9b2facb067ab590af8e4a6")] [assembly: AssemblyProduct("DeepTip")] [assembly: AssemblyTitle("GC_Valheim_DeepTip")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 DeepTip { public static class Api { public const string Guid = "gorduan.deeptip"; public const int Version = 1; private static readonly Dictionary<string, Func<string?>> values = new Dictionary<string, Func<string>>(StringComparer.Ordinal); public static string Locale => Glossary.Locale; public static event Action? Changed; public static event Action<string>? Opened; public static event Action<string>? Closed; public static event Action<string>? Pinned; public static bool Register(string owner, string json, string? locale = null) { try { foreach (string item in Glossary.Add(owner, json, locale)) { Plugin.Log.LogWarning((object)(owner + ": " + item)); } return true; } catch (Exception ex) { Plugin.Log.LogError((object)(owner + ": glossary is not valid JSON: " + ex.Message)); return false; } } public static int RegisterFolder(string owner, string folder) { if (!Directory.Exists(folder)) { return 0; } return Directory.GetFiles(folder, "*.json").OrderBy<string, string>((string f) => f, StringComparer.OrdinalIgnoreCase).Count((string f) => Loader.Load(owner, File.ReadAllText(f), Path.GetFileName(f), 20)); } public static void Unregister(string owner) { Glossary.Remove(owner); } public static void Mark(GameObject element, string key, string? sides = null, float delay = -1f) { if (!((Object)(object)element == (Object)null)) { DeepTipAnchor obj = element.GetComponent<DeepTipAnchor>() ?? element.AddComponent<DeepTipAnchor>(); obj.Key = key; obj.Sides = sides ?? ""; obj.Delay = delay; } } public static void Unmark(GameObject element) { DeepTipAnchor deepTipAnchor = (((Object)(object)element != (Object)null) ? element.GetComponent<DeepTipAnchor>() : null); if ((Object)(object)deepTipAnchor != (Object)null) { Object.Destroy((Object)(object)deepTipAnchor); } } public static bool Open(string key, RectTransform anchor, bool pinned = false) { if (!Plugin.HasUi || (Object)(object)anchor == (Object)null) { return false; } return Manager.Open(key, new ElementAnchor(anchor), null, pinned) != null; } public static void CloseAll() { if (Plugin.HasUi) { Manager.CloseAll(); } } public static string Render(string markup) { return Markup.ToTmp(markup, null, Theme.Style); } public static string Link(string tmpText) { return AutoLink.Process(tmpText, Settings.AutoLinkTerms.Value, Theme.Style); } public static void AttachLinks(TMP_Text text) { if (Plugin.HasUi) { Manager.AttachPage(text); } } public static void SetValue(string name, Func<string?> provider) { values[name] = provider; } public static void RemoveValue(string name) { values.Remove(name); } public static void Refresh() { if (Plugin.HasUi) { Manager.RefreshAll(); } } public static bool Has(string key) { return Glossary.Has(key); } public static string? Title(string key) { if (!Glossary.TryGet(key, out Entry entry, out string _)) { return null; } return entry.Title; } public static string? Short(string key) { if (!Glossary.TryGet(key, out Entry entry, out string _)) { return null; } return entry.Short ?? entry.Title; } internal static string? ValueOf(string name, string key) { if (!values.TryGetValue(name, out Func<string> value)) { return null; } try { return value(); } catch (Exception ex) { Manager.WarnOnce("value:" + name, "Live value {" + name + "} failed: " + ex.Message); return null; } } internal static void RaiseChanged() { Api.Changed?.Invoke(); } internal static void RaiseOpened(string key) { Api.Opened?.Invoke(key); } internal static void RaiseClosed(string key) { Api.Closed?.Invoke(key); } internal static void RaisePinned(string key) { Api.Pinned?.Invoke(key); } } public sealed class DeepTipAnchor : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler { public string Key = ""; public string Sides = ""; public float Delay = -1f; internal static DeepTipAnchor? Hovered; public void OnPointerEnter(PointerEventData eventData) { Hovered = this; } public void OnPointerExit(PointerEventData eventData) { if ((Object)(object)Hovered == (Object)(object)this) { Hovered = null; } Manager.Unhush(this); } public void OnPointerDown(PointerEventData eventData) { Manager.Hush(this); } private void OnDisable() { if ((Object)(object)Hovered == (Object)(object)this) { Hovered = null; } } } internal static class Loader { internal static void LoadAll() { int num = 0; Assembly assembly = typeof(Loader).Assembly; foreach (string item in from n in assembly.GetManifestResourceNames() where n.StartsWith("DeepTip.glossary.", StringComparison.Ordinal) && n.EndsWith(".json", StringComparison.Ordinal) select n) { using Stream stream = assembly.GetManifestResourceStream(item); if (stream != null) { using StreamReader streamReader = new StreamReader(stream); string fileName = item.Substring("DeepTip.glossary.".Length); num += (Load("DeepTip", streamReader.ReadToEnd(), fileName, 0) ? 1 : 0); } } int num2 = 0; try { foreach (string item2 in Directory.GetDirectories(Paths.PluginPath, "deeptip", SearchOption.AllDirectories).OrderBy<string, string>((string x) => x, StringComparer.OrdinalIgnoreCase)) { string owner = Owner(item2); int num3 = num; foreach (string item3 in Directory.GetFiles(item2, "*.json").OrderBy<string, string>((string x) => x, StringComparer.OrdinalIgnoreCase)) { num += (Load(owner, File.ReadAllText(item3), Path.GetFileName(item3), 10) ? 1 : 0); } num2 += ((num > num3) ? 1 : 0); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not search the plugin folders for glossaries: " + ex.Message)); } string path = Path.Combine(Paths.ConfigPath, "DeepTip"); if (Directory.Exists(path)) { foreach (string item4 in Directory.GetFiles(path, "*.json").OrderBy<string, string>((string x) => x, StringComparer.OrdinalIgnoreCase)) { num += (Load("config/DeepTip", File.ReadAllText(item4), Path.GetFileName(item4), 30) ? 1 : 0); } } Plugin.Log.LogInfo((object)$"Glossary: {num} files ({num2} mod folders), entries per locale {Glossary.Summary()}."); } private static string Owner(string folder) { string[] array = folder.Substring(Paths.PluginPath.Length).TrimStart('\\', '/').Split('\\', '/'); if (array.Length <= 1) { return "plugins"; } return array[0]; } internal static bool Load(string owner, string json, string fileName, int priority) { try { foreach (string item in Glossary.Add(owner, json, null, priority, fileName)) { Plugin.Log.LogWarning((object)(owner + "/" + fileName + ": " + item)); } return true; } catch (Exception ex) { Plugin.Log.LogError((object)(owner + "/" + fileName + " is not valid JSON and was skipped: " + ex.Message)); return false; } } } internal static class Locale { private static readonly Dictionary<string, string> Codes = new Dictionary<string, string> { ["English"] = "en", ["German"] = "de", ["French"] = "fr", ["Spanish"] = "es", ["Spanish_Latam"] = "es", ["Italian"] = "it", ["Portuguese_European"] = "pt", ["Portuguese_Brazilian"] = "pt-br", ["Russian"] = "ru", ["Polish"] = "pl", ["Czech"] = "cs", ["Slovak"] = "sk", ["Hungarian"] = "hu", ["Romanian"] = "ro", ["Bulgarian"] = "bg", ["Greek"] = "el", ["Turkish"] = "tr", ["Ukrainian"] = "uk", ["Swedish"] = "sv", ["Norwegian"] = "no", ["Danish"] = "da", ["Finnish"] = "fi", ["Icelandic"] = "is", ["Dutch"] = "nl", ["Estonian"] = "et", ["Latvian"] = "lv", ["Lithuanian"] = "lt", ["Croatian"] = "hr", ["Serbian"] = "sr", ["Slovenian"] = "sl", ["Japanese"] = "ja", ["Korean"] = "ko", ["Chinese"] = "zh", ["Chinese_Trad"] = "zh-tw", ["Thai"] = "th", ["Vietnamese"] = "vi", ["Indonesian"] = "id", ["Arabic"] = "ar", ["Hindi"] = "hi" }; private static string? last; private static float nextCheck; internal static string CodeOf(string language) { if (!Codes.TryGetValue(language, out string value)) { return language.ToLowerInvariant(); } return value; } internal static void Update(float now) { if (now < nextCheck) { return; } nextCheck = now + 1f; Localization instance = Localization.instance; string text = ((instance != null) ? instance.GetSelectedLanguage() : null); if (!string.IsNullOrEmpty(text) && !(text == last)) { last = text; string text2 = CodeOf(text); List<string> list = new List<string>(); if (text2.Contains("-")) { list.Add(text2.Split('-')[0]); } list.Add("en"); list.Add("de"); Glossary.SetLocale(text2, list); Plugin.Log.LogInfo((object)("Language " + text + " → glossary chain " + string.Join(", ", Glossary.Chain))); } } } [BepInPlugin("gorduan.deeptip", "DeepTip", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "gorduan.deeptip"; public const string Name = "DeepTip"; public const string Version = "1.0.0"; internal static ManualLogSource Log = Logger.CreateLogSource("DeepTip"); internal static Plugin? Instance; internal static bool HasUi; private readonly HashSet<string> errors = new HashSet<string>(); private void Awake() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown Instance = this; Settings.Bind(((BaseUnityPlugin)this).Config); Loader.LoadAll(); HasUi = !Application.isBatchMode && (int)SystemInfo.graphicsDeviceType != 4; Glossary.Changed += delegate { Api.RaiseChanged(); if (HasUi) { Manager.RefreshAll(); } }; if (!HasUi) { Log.LogInfo((object)"No graphics (dedicated server): glossary loaded, no windows."); return; } Harmony val = new Harmony("gorduan.deeptip"); int num = 0; Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { try { val.CreateClassProcessor(type).Patch(); } catch (Exception ex) { num++; Log.LogError((object)("Patch " + type.Name + " failed, that part of DeepTip is off: " + ex.GetBaseException().Message)); } } Settings.Enabled.SettingChanged += delegate { Manager.CloseAll(); }; Settings.LinkColor.SettingChanged += delegate { Manager.RefreshAll(); }; Log.LogInfo((object)string.Format("DeepTip {0} ready ({1} patch errors).", "1.0.0", num)); } private void Update() { if (!HasUi) { return; } try { Manager.Update(); } catch (Exception ex) { if (errors.Add(ex.GetType().Name + ex.Message)) { Log.LogError((object)$"DeepTip update failed: {ex}"); } } } } internal static class Settings { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> ValheimTooltips; internal static ConfigEntry<bool> AutoLinkTerms; internal static ConfigEntry<float> Delay; internal static ConfigEntry<float> LinkDelay; internal static ConfigEntry<float> CloseDelay; internal static ConfigEntry<float> LockAfter; internal static ConfigEntry<bool> CloseButtons; internal static ConfigEntry<bool> PinButton; internal static ConfigEntry<bool> Hints; internal static ConfigEntry<bool> ClickInsidePins; internal static ConfigEntry<float> MaxWidth; internal static ConfigEntry<float> Opacity; internal static ConfigEntry<string> RootSides; internal static ConfigEntry<string> TooltipSides; internal static ConfigEntry<string> ChildSides; internal static ConfigEntry<KeyboardShortcut> OpenKey; internal static ConfigEntry<KeyboardShortcut> CloseAllKey; internal static ConfigEntry<bool> Lexicon; internal static ConfigEntry<bool> LexiconFirst; internal static ConfigEntry<Color> LinkColor; internal static ConfigEntry<Color> PinnedColor; internal static void Bind(ConfigFile config) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) Enabled = config.Bind<bool>("1 - General", "Enabled", true, "DeepTip windows on. Off: Valheim's tooltips behave as without the mod."); ValheimTooltips = config.Bind<bool>("1 - General", "ValheimTooltips", true, "Valheim's own tooltips (inventory, crafting, skills ...) become DeepTip windows: they open next to the element instead of following the mouse, you can move into them, and highlighted terms open further windows."); AutoLinkTerms = config.Bind<bool>("1 - General", "AutoLink", true, "Highlight known terms in tooltip texts of Valheim and other mods automatically (first occurrence per window)."); Delay = config.Bind<float>("2 - Timing", "Delay", 0.5f, new ConfigDescription("Seconds the mouse rests on an element before its window opens (Valheim: 0.5).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); LinkDelay = config.Bind<float>("2 - Timing", "LinkDelay", 0.08f, new ConfigDescription("Seconds on a highlighted term before its preview opens.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); CloseDelay = config.Bind<float>("2 - Timing", "CloseDelay", 0.3f, new ConfigDescription("Grace in seconds before an unpinned window closes once the mouse left it (longer while the mouse moves towards it).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); LockAfter = config.Bind<float>("2 - Timing", "LockAfter", 0f, new ConfigDescription("Timer lock: seconds resting inside an unpinned window pin it (a bar shows the progress). 0 = off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); CloseButtons = config.Bind<bool>("3 - Windows", "CloseButton", true, "X button in every window."); PinButton = config.Bind<bool>("3 - Windows", "PinButton", true, "Pin button in every window."); Hints = config.Bind<bool>("3 - Windows", "Hints", true, "Hint line \"Click to pin · Esc closes\" in unpinned windows."); ClickInsidePins = config.Bind<bool>("3 - Windows", "ClickInsidePins", true, "A click anywhere inside an unpinned window pins it."); MaxWidth = config.Bind<float>("3 - Windows", "MaxWidth", 420f, new ConfigDescription("Largest window width (GUI units).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(200f, 900f), Array.Empty<object>())); Opacity = config.Bind<float>("3 - Windows", "Opacity", 0.9f, new ConfigDescription("Extra cover behind the text of DeepTip's own windows: 0 = Valheim's see-through tooltip look, 1 = solid. Applies to windows opened afterwards.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); RootSides = config.Bind<string>("3 - Windows", "RootSides", "bottom,top,right,left", "Sides of a marked element where its window may open, in order of preference."); TooltipSides = config.Bind<string>("3 - Windows", "TooltipSides", "right,left,bottom,top", "Sides for Valheim's own tooltips (inventory slots, recipes ...)."); ChildSides = config.Bind<string>("3 - Windows", "ChildSides", "left,right,top,bottom", "Sides of the previous window where a term's window may open (never covering it)."); OpenKey = config.Bind<KeyboardShortcut>("4 - Keys", "Open", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Opens the window of the element under the mouse, pinned."); CloseAllKey = config.Bind<KeyboardShortcut>("4 - Keys", "CloseAll", new KeyboardShortcut((KeyCode)27, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Closes every window (holding Esc does the same). Esc alone closes the newest window."); Lexicon = config.Bind<bool>("5 - Lexicon", "Enabled", true, "A searchable page with every entry in Valheim's Compendium."); LexiconFirst = config.Bind<bool>("5 - Lexicon", "First", true, "The lexicon is the first page of the Compendium (off: the last)."); LinkColor = config.Bind<Color>("6 - Colors", "Link", new Color(0.965f, 0.769f, 0.325f), "Color of highlighted terms."); PinnedColor = config.Bind<Color>("6 - Colors", "Pinned", new Color(0.965f, 0.769f, 0.325f), "Frame color of pinned windows."); } internal static string[] Sides(ConfigEntry<string> entry, string[] fallback) { return Placement.ParseSides(entry.Value, fallback); } } } namespace DeepTip.Valheim { [HarmonyPatch(typeof(ZInput), "GetKeyDown", new Type[] { typeof(KeyCode), typeof(bool) })] internal static class EscapePatch { [HarmonyPriority(800)] private static bool Prefix(KeyCode key, ref bool __result) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (Manager.Reading) { return true; } if (Lexicon.Typing) { __result = false; return false; } if ((int)key != 27 || !Manager.Active || Manager.Windows.Count == 0) { return true; } Manager.Reading = true; bool keyDown; try { keyDown = ZInput.GetKeyDown((KeyCode)27, true); } finally { Manager.Reading = false; } __result = keyDown && !Manager.Escape(); return false; } } [HarmonyPatch] internal static class TypingPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] array = new MethodInfo[5] { AccessTools.Method(typeof(ZInput), "GetKey", new Type[2] { typeof(KeyCode), typeof(bool) }, (Type[])null), AccessTools.Method(typeof(ZInput), "GetKeyUp", new Type[2] { typeof(KeyCode), typeof(bool) }, (Type[])null), AccessTools.Method(typeof(ZInput), "GetButtonDown", new Type[1] { typeof(string) }, (Type[])null), AccessTools.Method(typeof(ZInput), "GetButtonUp", new Type[1] { typeof(string) }, (Type[])null), AccessTools.Method(typeof(ZInput), "GetButton", new Type[1] { typeof(string) }, (Type[])null) }; MethodInfo?[] array2 = array; foreach (MethodInfo methodInfo in array2) { if (methodInfo != null) { yield return methodInfo; } } } private static bool Prefix(ref bool __result) { if (Lexicon.Typing && !Manager.Reading) { __result = false; return false; } return true; } } internal static class Lexicon { internal const string Marker = "\u0001deeptip.lexicon"; private static TMP_InputField? search; private static TextsDialog? dialog; private static string query = ""; internal static bool Typing { get { if ((Object)(object)search != (Object)null) { return search.isFocused; } return false; } } internal static void AddPage(List<TextInfo> texts) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (Settings.Lexicon.Value && Plugin.HasUi && Glossary.All().Count != 0) { TextInfo item = new TextInfo(Glossary.Ui("lexicon"), "\u0001deeptip.lexicon"); if (Settings.LexiconFirst.Value) { texts.Insert(0, item); } else { texts.Add(item); } } } internal static void Shown(TextsDialog d, TextInfo text) { dialog = d; Theme.Ensure(); if (text.m_text == "\u0001deeptip.lexicon") { if (Manager.Active) { Manager.AttachPage(d.m_textArea); } EnsureSearch(d); TMP_InputField? obj = search; if (obj != null) { ((Component)obj).gameObject.SetActive(true); } Render(); } else { if ((Object)(object)search != (Object)null) { ((Component)search).gameObject.SetActive(false); } if (Manager.Active) { Manager.AttachPage(d.m_textArea); d.m_textArea.text = AutoLink.Process(d.m_textArea.text, Settings.AutoLinkTerms.Value, Theme.Style); } } } private static void Render() { TextsDialog val = dialog; if ((Object)(object)val == (Object)null) { return; } Markup.Style style = Theme.Style; string q = query.Trim(); List<Entry> list = Glossary.All(); List<Entry> obj = ((q.Length == 0) ? list : list.Where((Entry e) => Has(e.Title, q) || Has(e.Short, q) || Has(e.Key, q) || e.Aliases.Any((string a) => Has(a, q))).ToList()); StringBuilder stringBuilder = new StringBuilder(); if (obj.Count == 0) { stringBuilder.Append(Markup.Plain(Glossary.Ui("empty"))); } foreach (IGrouping<string, Entry> item in (from g in obj.GroupBy(Group) orderby (g.Key == "deeptip") ? 1 : 0 select g).ThenBy<IGrouping<string, Entry>, string>((IGrouping<string, Entry> g) => g.Key, StringComparer.OrdinalIgnoreCase)) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append("<b>").Append(Markup.Plain(GroupTitle(item.Key))).Append("</b>\n"); foreach (Entry item2 in item) { stringBuilder.Append("• ").Append(Markup.Wrap(item2.Key, Markup.Plain(item2.Title), style)); if (!string.IsNullOrEmpty(item2.Short)) { stringBuilder.Append(" – ").Append(Markup.Plain(item2.Short)); } stringBuilder.Append('\n'); } } string text = stringBuilder.ToString(); val.m_textAreaTopic.text = Glossary.Ui("lexicon"); val.m_textArea.richText = true; val.m_textArea.text = ((text.IndexOf('$') >= 0 && Localization.instance != null) ? Localization.instance.Localize(text) : text); } private static bool Has(string? text, string q) { if (text != null) { return text.IndexOf(q, StringComparison.CurrentCultureIgnoreCase) >= 0; } return false; } private static string Group(Entry e) { int num = e.Key.IndexOf('.'); if (num <= 0) { return e.Key; } return e.Key.Substring(0, num); } private static string GroupTitle(string group) { if (!(group == "valheim")) { if (group == "deeptip") { return "DeepTip"; } return (group.Length <= 3) ? group.ToUpperInvariant() : (char.ToUpperInvariant(group[0]) + group.Substring(1)); } return "Valheim"; } private static void EnsureSearch(TextsDialog d) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)search != (Object)null) { return; } try { GameObject obj = TMP_DefaultControls.CreateInputField(default(Resources)); ((Object)obj).name = "DeepTip Search"; obj.transform.SetParent(d.m_textAreaTopic.transform, false); RectTransform val = (RectTransform)obj.transform; Vector2 anchorMin = (val.anchorMax = new Vector2(1f, 0.5f)); val.anchorMin = anchorMin; val.pivot = new Vector2(1f, 0.5f); val.anchoredPosition = Vector2.zero; val.sizeDelta = new Vector2(260f, 30f); Image component = obj.GetComponent<Image>(); component.sprite = Theme.Background; component.type = (Type)(((Object)(object)Theme.Background != (Object)null) ? ((int)Theme.BackgroundType) : 0); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.6f); search = obj.GetComponent<TMP_InputField>(); TextMeshProUGUI[] componentsInChildren = obj.GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val3 in componentsInChildren) { if ((Object)(object)Theme.Font != (Object)null) { ((TMP_Text)val3).font = Theme.Font; } ((TMP_Text)val3).fontSize = Theme.TextSize; ((Graphic)val3).color = (Color)((((Object)val3).name == "Placeholder") ? new Color(0.6f, 0.6f, 0.6f) : Theme.TextColor); if (((Object)val3).name == "Placeholder") { ((TMP_Text)val3).text = Glossary.Ui("search"); } } ((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate(string value) { query = value ?? ""; Render(); }); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Lexicon search field not created: " + ex.Message)); } } } [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] internal static class CompendiumListPatch { private static void Postfix(TextsDialog __instance) { Lexicon.AddPage(__instance.m_texts); } } [HarmonyPatch(typeof(TextsDialog), "ShowText", new Type[] { typeof(TextInfo) })] internal static class CompendiumShowPatch { private static void Postfix(TextsDialog __instance, TextInfo text) { Lexicon.Shown(__instance, text); } } internal static class TooltipPatches { internal static bool Bypass; internal static bool On { get { if (Manager.Active) { return Settings.ValheimTooltips.Value; } return false; } } } [HarmonyPatch(typeof(UITooltip), "OnHoverStart")] internal static class TooltipHoverStartPatch { [HarmonyPriority(800)] private static bool Prefix(UITooltip __instance, GameObject go) { if (!TooltipPatches.On || TooltipPatches.Bypass) { return true; } if ((__instance.m_text.Length > 0 || __instance.m_topic.Length > 0) && Manager.ShouldDefer(__instance)) { Manager.Deferred = (__instance, go, Time.unscaledTime); return false; } Manager.Deferred = null; Window adopted = Manager.Adopted; if (adopted != null && (Object)(object)adopted.Source != (Object)(object)__instance && !adopted.Pinned) { Manager.DropAdopted(); } return true; } } [HarmonyPatch(typeof(UITooltip), "LateUpdate")] internal static class TooltipLateUpdatePatch { [HarmonyPriority(800)] private static bool Prefix(UITooltip __instance) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0049: Expected O, but got Unknown if (!TooltipPatches.On || (Object)(object)UITooltip.m_current != (Object)(object)__instance) { return true; } GameObject tooltip = UITooltip.m_tooltip; if ((Object)(object)tooltip == (Object)null) { return false; } if (!tooltip.activeSelf) { if (!Geo.Contains((RectTransform)((Component)__instance).transform, Vector2.op_Implicit(ZInput.pointerPosition))) { UITooltip.HideTooltip(); return false; } __instance.m_showTimer += Time.unscaledDeltaTime; if (__instance.m_showTimer >= Settings.Delay.Value) { tooltip.SetActive(true); Manager.Adopt(__instance, tooltip); } } else if (Manager.Adopted == null || (Object)(object)Manager.Adopted.Source != (Object)(object)__instance) { Manager.Adopt(__instance, tooltip); } return false; } } [HarmonyPatch(typeof(UITooltip), "LateUpdate")] [HarmonyAfter(new string[] { "randyknapp.mods.epicloot" })] internal static class TooltipPlacePatch { [HarmonyPriority(0)] private static void Postfix(UITooltip __instance) { if (TooltipPatches.On && (Object)(object)UITooltip.m_current == (Object)(object)__instance) { Manager.KeepAdoptedPlaced(); } } } [HarmonyPatch(typeof(UITooltip), "OnPointerExit")] internal static class TooltipPointerExitPatch { private static bool Prefix() { return !TooltipPatches.On; } } [HarmonyPatch(typeof(UITooltip), "UpdateTextElements")] internal static class TooltipTextPatch { private static void Postfix() { if (TooltipPatches.On && (Object)(object)UITooltip.m_tooltip != (Object)null) { Manager.AdoptedTextChanged(UITooltip.m_tooltip); } } } [HarmonyPatch(typeof(UITooltip), "HideTooltip")] internal static class TooltipHidePatch { private static void Postfix() { if (!Manager.Detaching && Manager.Adopted != null) { Manager.DropAdopted(); } } } } namespace DeepTip.UI { internal sealed class Frame { private const string Name = "DeepTip Frame"; private const float Thickness = 2f; private readonly GameObject root; private readonly Image[] edges; internal Frame(Transform parent) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) Transform val = parent.Find("DeepTip Frame"); if ((Object)(object)val != (Object)null) { root = ((Component)val).gameObject; edges = root.GetComponentsInChildren<Image>(true); return; } root = new GameObject("DeepTip Frame", new Type[1] { typeof(RectTransform) }); root.transform.SetParent(parent, false); root.AddComponent<LayoutElement>().ignoreLayout = true; RectTransform val2 = (RectTransform)root.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; edges = (Image[])(object)new Image[4] { Edge(new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 2f)), Edge(new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 2f)), Edge(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(2f, 0f)), Edge(new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(2f, 0f)) }; root.SetActive(false); } private Image Edge(Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 size) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) GameObject val = new GameObject("Edge", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(root.transform, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = anchorMin; val2.anchorMax = anchorMax; val2.pivot = pivot; val2.sizeDelta = size; val2.anchoredPosition = Vector2.zero; Image obj = val.AddComponent<Image>(); obj.sprite = Theme.Solid; ((Graphic)obj).raycastTarget = false; return obj; } internal void Show(bool on, Color color) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (root.activeSelf != on) { root.SetActive(on); } Image[] array = edges; for (int i = 0; i < array.Length; i++) { ((Graphic)array[i]).color = color; } } internal void ToFront() { root.transform.SetAsLastSibling(); } } internal static class Geo { private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]; internal static Vector2 Pointer => Vector2.op_Implicit(ZInput.pointerPosition); internal static float ScreenH => Screen.height; internal static Camera? Cam(Component c) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = c.GetComponentInParent<Canvas>(); componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null); if (!((Object)(object)componentInParent == (Object)null) && (int)componentInParent.renderMode != 0) { return componentInParent.worldCamera; } return null; } internal static Box ScreenBox(RectTransform rt) { rt.GetWorldCorners(Corners); return FromWorld(Corners, Cam((Component)(object)rt)); } internal static Box FromWorld(Vector3[] corners, Camera? cam) { //IL_0024: 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_002c: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; float num2 = float.MaxValue; float num3 = float.MinValue; float num4 = float.MinValue; foreach (Vector3 val in corners) { Vector2 val2 = RectTransformUtility.WorldToScreenPoint(cam, val); num = Mathf.Min(num, val2.x); num3 = Mathf.Max(num3, val2.x); num2 = Mathf.Min(num2, val2.y); num4 = Mathf.Max(num4, val2.y); } return new Box(num, ScreenH - num4, num3, ScreenH - num2); } internal static bool Contains(RectTransform rt, Vector2 screenPoint) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rt != (Object)null) { return RectTransformUtility.RectangleContainsScreenPoint(rt, screenPoint, Cam((Component)(object)rt)); } return false; } internal static string? LinkAt(TMP_Text text, Vector2 screenPoint, out int index) { //IL_002d: 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) index = -1; if ((Object)(object)text == (Object)null || !((Behaviour)text).isActiveAndEnabled || text.textInfo == null || text.textInfo.linkCount == 0) { return null; } index = TMP_TextUtilities.FindIntersectingLink(text, Vector2.op_Implicit(screenPoint), Cam((Component)(object)text)); if (index < 0 || index >= text.textInfo.linkCount) { index = -1; return null; } string linkID = ((TMP_LinkInfo)(ref text.textInfo.linkInfo[index])).GetLinkID(); if (!linkID.StartsWith("dt:", StringComparison.Ordinal)) { return null; } return linkID.Substring("dt:".Length); } internal static Box LinkBox(TMP_Text text, int index) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_009e: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) TMP_LinkInfo val = text.textInfo.linkInfo[index]; float num = float.MaxValue; float num2 = float.MaxValue; float num3 = float.MinValue; float num4 = float.MinValue; for (int i = val.linkTextfirstCharacterIndex; i < val.linkTextfirstCharacterIndex + val.linkTextLength && i < text.textInfo.characterCount; i++) { TMP_CharacterInfo val2 = text.textInfo.characterInfo[i]; if (val2.isVisible) { num = Mathf.Min(num, val2.bottomLeft.x); num2 = Mathf.Min(num2, val2.descender); num3 = Mathf.Max(num3, val2.topRight.x); num4 = Mathf.Max(num4, val2.ascender); } } if (num > num3) { return ScreenBox(text.rectTransform); } Transform transform = text.transform; Corners[0] = transform.TransformPoint(new Vector3(num, num2)); Corners[1] = transform.TransformPoint(new Vector3(num, num4)); Corners[2] = transform.TransformPoint(new Vector3(num3, num4)); Corners[3] = transform.TransformPoint(new Vector3(num3, num2)); return FromWorld(Corners, Cam((Component)(object)text)); } } internal sealed class GlossaryView : IView { private const float Pad = 10f; private const float IconSize = 18f; private const float Gap = 6f; private const float MinWidth = 180f; private static Canvas? canvas; private static CanvasScaler? scaler; private static GuiScaler? valheimScaler; private readonly Window window; private readonly GameObject root; private readonly RectTransform rect; private readonly Image background; private readonly Frame frame; private readonly RectTransform viewport; private readonly RectTransform content; private readonly TextMeshProUGUI topic; private readonly TextMeshProUGUI badge; private readonly TextMeshProUGUI body; private readonly TextMeshProUGUI see; private readonly TextMeshProUGUI hint; private readonly GameObject pinButton; private readonly Image pinIcon; private readonly GameObject closeButton; private readonly Image lockBar; private float contentHeight; private float headerHeight; private float scroll; private float widthLimit; private float heightLimit; private bool pinned; public GameObject Root => root; public RectTransform Panel => rect; public IEnumerable<TMP_Text> Texts => (IEnumerable<TMP_Text>)(object)new TMP_Text[2] { (TMP_Text)body, (TMP_Text)see }; private static float Scale { get { if (!((Object)(object)scaler != (Object)null)) { return 1f; } return scaler.scaleFactor; } } internal GlossaryView(Window window) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_009b: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_017a: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Expected O, but got Unknown //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) this.window = window; root = new GameObject("DeepTip " + window.Key, new Type[1] { typeof(RectTransform) }); root.transform.SetParent(CanvasRoot(), false); rect = (RectTransform)root.transform; RectTransform obj = rect; RectTransform obj2 = rect; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); obj2.anchorMax = val; obj.anchorMin = val; rect.pivot = new Vector2(0f, 1f); background = root.AddComponent<Image>(); background.sprite = Theme.Background; background.type = (Type)(((Object)(object)Theme.Background != (Object)null) ? ((int)Theme.BackgroundType) : 0); ((Graphic)background).color = (Color)(((Object)(object)Theme.Background != (Object)null) ? Theme.BackgroundColor : new Color(0f, 0f, 0f, 0.88f)); ((Graphic)background).raycastTarget = true; Shade(rect); root.AddComponent<ClickCatcher>().Window = window; topic = Theme.Text((Transform)(object)rect, "Topic", Theme.TopicSize, Theme.TopicColor); badge = Theme.Text((Transform)(object)rect, "Badge", Theme.TextSize * 0.7f, new Color(0.7f, 0.7f, 0.7f)); pinButton = Button((Transform)(object)rect, "Pin", Theme.Pin, (UnityAction)delegate { Manager.TogglePin(window); }, out pinIcon); closeButton = Button((Transform)(object)rect, "Close", Theme.Close, (UnityAction)delegate { Manager.Close(window); }, out Image _); GameObject val2 = new GameObject("Viewport", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)rect, false); viewport = (RectTransform)val2.transform; RectTransform obj3 = viewport; RectTransform obj4 = viewport; ((Vector2)(ref val))..ctor(0f, 1f); obj4.anchorMax = val; obj3.anchorMin = val; viewport.pivot = new Vector2(0f, 1f); val2.AddComponent<RectMask2D>(); GameObject val3 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent((Transform)(object)viewport, false); content = (RectTransform)val3.transform; RectTransform obj5 = content; RectTransform obj6 = content; ((Vector2)(ref val))..ctor(0f, 1f); obj6.anchorMax = val; obj5.anchorMin = val; content.pivot = new Vector2(0f, 1f); body = Theme.Text((Transform)(object)content, "Body", Theme.TextSize, Theme.TextColor); see = Theme.Text((Transform)(object)content, "See", Theme.TextSize * 0.9f, Theme.TextColor); hint = Theme.Text((Transform)(object)content, "Hint", Theme.TextSize * 0.75f, new Color(0.65f, 0.65f, 0.65f)); GameObject val4 = new GameObject("Lock", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent((Transform)(object)rect, false); lockBar = val4.AddComponent<Image>(); ((Graphic)lockBar).color = Settings.PinnedColor.Value; lockBar.type = (Type)3; lockBar.fillMethod = (FillMethod)0; ((Graphic)lockBar).raycastTarget = false; lockBar.sprite = Theme.Solid; RectTransform rectTransform = ((Graphic)lockBar).rectTransform; rectTransform.anchorMin = new Vector2(0f, 0f); rectTransform.anchorMax = new Vector2(1f, 0f); rectTransform.pivot = new Vector2(0f, 0f); rectTransform.sizeDelta = new Vector2(0f, 3f); val4.SetActive(false); frame = new Frame((Transform)(object)rect); Refresh(); } private static void Shade(RectTransform parent) { //IL_0037: 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_0049: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Theme.Background == (Object)null) && !(Settings.Opacity.Value <= 0f)) { GameObject val = new GameObject("Shade", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; Image obj = val.AddComponent<Image>(); obj.sprite = Theme.Background; obj.type = Theme.BackgroundType; Color backgroundColor = Theme.BackgroundColor; ((Graphic)obj).color = new Color(backgroundColor.r, backgroundColor.g, backgroundColor.b, Settings.Opacity.Value); ((Graphic)obj).raycastTarget = false; } } internal static Transform CanvasRoot() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)canvas == (Object)null) { GameObject val = new GameObject("DeepTip"); Object.DontDestroyOnLoad((Object)val); canvas = val.AddComponent<Canvas>(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 30000; scaler = val.AddComponent<CanvasScaler>(); scaler.uiScaleMode = (ScaleMode)0; val.AddComponent<GraphicRaycaster>(); } SyncScale(); return ((Component)canvas).transform; } internal static void SyncScale() { if (!((Object)(object)scaler == (Object)null)) { if ((Object)(object)valheimScaler == (Object)null) { valheimScaler = Object.FindFirstObjectByType<GuiScaler>(); } float num = (((Object)(object)valheimScaler != (Object)null && (Object)(object)valheimScaler.m_canvasScaler != (Object)null) ? valheimScaler.m_canvasScaler.scaleFactor : 1f); if (num > 0.01f && !Mathf.Approximately(scaler.scaleFactor, num)) { scaler.scaleFactor = num; } } } private static GameObject Button(Transform parent, string name, Sprite sprite, UnityAction onClick, out Image icon) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_003c: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); icon = val.AddComponent<Image>(); icon.sprite = sprite; ((Graphic)icon).color = Theme.TextColor; ((Graphic)icon).raycastTarget = true; Button obj = val.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)icon; ColorBlock colors = ((Selectable)obj).colors; ((ColorBlock)(ref colors)).highlightedColor = Settings.LinkColor.Value; ((ColorBlock)(ref colors)).pressedColor = Settings.LinkColor.Value; ((Selectable)obj).colors = colors; ((UnityEvent)obj.onClick).AddListener(onClick); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.sizeDelta = new Vector2(18f, 18f); return val; } public void Refresh() { Markup.Style style = Theme.Style; Entry entry; string fromLocale; bool flag = Glossary.TryGet(window.Key, out entry, out fromLocale); if (!flag) { Manager.WarnOnce(window.Key, "No entry \"" + window.Key + "\""); } ((TMP_Text)topic).text = Localize(Markup.Plain(flag ? entry.Title : window.Key)); ((TMP_Text)badge).text = ((flag && fromLocale != Glossary.Locale) ? fromLocale.ToUpperInvariant() : ""); ((TMP_Text)body).text = Localize(Markup.ToTmp(flag ? (entry.Body ?? entry.Short ?? Glossary.Ui("missing")) : Glossary.Ui("missing"), window.Key, style)); if (flag && entry.See.Length != 0) { ((TMP_Text)see).text = Markup.Plain(Glossary.Ui("seeAlso")) + " " + string.Join(", ", entry.See.Select((string k) => Markup.Link(k, null, window.Key, style))); } else { ((TMP_Text)see).text = ""; } Layout(); } private static string Localize(string text) { if (text.IndexOf('$') < 0 || Localization.instance == null) { return text; } return Localization.instance.Localize(text); } private void Layout() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)hint).text = ((Settings.Hints.Value && !pinned) ? Markup.Plain(Glossary.Ui("hint")) : ""); pinButton.SetActive(Settings.PinButton.Value); closeButton.SetActive(Settings.CloseButtons.Value); float num = Mathf.Max((widthLimit > 0f) ? Mathf.Min(Settings.MaxWidth.Value, widthLimit / Scale) : Settings.MaxWidth.Value, 180f); float num2 = (pinButton.activeSelf ? 22f : 0f) + (closeButton.activeSelf ? 22f : 0f); float num3 = ((((TMP_Text)badge).text.Length > 0) ? (((TMP_Text)badge).GetPreferredValues(((TMP_Text)badge).text).x + 6f) : 0f); float num4 = num - 20f; float num5 = ((TMP_Text)topic).GetPreferredValues(((TMP_Text)topic).text, num4 - num2 - num3, 0f).x + num2 + num3; TextMeshProUGUI[] array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[3] { body, see, hint }; foreach (TextMeshProUGUI val in array) { if (((TMP_Text)val).text.Length > 0) { num5 = Mathf.Max(num5, ((TMP_Text)val).GetPreferredValues(((TMP_Text)val).text, num4, 0f).x); } } float num6 = Mathf.Clamp(Mathf.Ceil(num5) + 2f, 160f, num4); float num7 = num6 + 20f; float num8 = num6 - num2 - num3; float num9 = Mathf.Max(18f, ((TMP_Text)topic).GetPreferredValues(((TMP_Text)topic).text, num8, 0f).y); Set(((TMP_Text)topic).rectTransform, 10f, 10f, num8, num9); Set(((TMP_Text)badge).rectTransform, 10f + Mathf.Min(num8, ((TMP_Text)topic).GetPreferredValues(((TMP_Text)topic).text, num8, 0f).x) + 6f, 12f, num3, num9); float num10 = num7 - 10f; if (closeButton.activeSelf) { num10 -= 18f; Set((RectTransform)closeButton.transform, num10, 10f, 18f, 18f); num10 -= 4f; } if (pinButton.activeSelf) { num10 -= 18f; Set((RectTransform)pinButton.transform, num10, 10f, 18f, 18f); } headerHeight = 10f + num9 + 6f; float num11 = 0f; array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[3] { body, see, hint }; foreach (TextMeshProUGUI val2 in array) { ((Component)val2).gameObject.SetActive(((TMP_Text)val2).text.Length > 0); if (((TMP_Text)val2).text.Length != 0) { if (num11 > 0f) { num11 += 6f; } float y = ((TMP_Text)val2).GetPreferredValues(((TMP_Text)val2).text, num6, 0f).y; Set(((TMP_Text)val2).rectTransform, 0f, num11, num6, y); num11 += y; } } contentHeight = num11; content.sizeDelta = new Vector2(num6, contentHeight); float num12 = ((heightLimit > 0f) ? (heightLimit / Scale - headerHeight - 10f) : float.MaxValue); float num13 = Mathf.Max(20f, Mathf.Min(contentHeight, num12)); Set(viewport, 10f, headerHeight, num6, num13); rect.sizeDelta = new Vector2(num7, headerHeight + num13 + 10f); scroll = Mathf.Clamp(scroll, 0f, Mathf.Max(0f, contentHeight - num13)); content.anchoredPosition = new Vector2(0f, scroll); } private static void Set(RectTransform rt, float x, float y, float w, float h) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) rt.anchoredPosition = new Vector2(x, 0f - y); rt.sizeDelta = new Vector2(w, h); } public Vector2 ScreenSize() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) return rect.sizeDelta * Scale; } public void Place(float x, float y, float maxW, float maxH) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!Mathf.Approximately(maxW, widthLimit) || !Mathf.Approximately(maxH, heightLimit)) { widthLimit = maxW; heightLimit = maxH; Layout(); } rect.anchoredPosition = new Vector2(x / Scale, (0f - y) / Scale); root.transform.SetAsLastSibling(); } public void SetPinned(bool value) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) pinned = value; frame.Show(value, Settings.PinnedColor.Value); pinIcon.sprite = (value ? Theme.PinFilled : Theme.Pin); Layout(); } public void SetLock(float progress) { bool flag = progress > 0f && progress < 1f; if (((Component)lockBar).gameObject.activeSelf != flag) { ((Component)lockBar).gameObject.SetActive(flag); } lockBar.fillAmount = progress; } public void Flash(float strength) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) frame.Show(pinned || strength > 0f, (strength > 0f) ? Color.Lerp(Settings.PinnedColor.Value, Color.white, strength) : Settings.PinnedColor.Value); } public void Scroll(float wheel) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) float y = viewport.sizeDelta.y; if (!(contentHeight <= y)) { scroll = Mathf.Clamp(scroll - wheel * 40f, 0f, contentHeight - y); content.anchoredPosition = new Vector2(0f, scroll); } } public void Destroy() { Object.Destroy((Object)(object)root); } } internal sealed class ClickCatcher : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal Window? Window; public void OnPointerClick(PointerEventData eventData) { //IL_0001: 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) if ((int)eventData.button == 0) { Manager.Click(Window, eventData.position); } } } internal static class Manager { private sealed class Pending { public string Id = ""; public string Key = ""; public Window? Parent; public float Since; public float Delay; public Func<Anchor> Anchor; public string[]? Sides; } private const float TendencyMax = 1.5f; private const float HoldClose = 0.6f; private static readonly List<Window> wins = new List<Window>(); private static readonly List<(Vector2 P, float T)> samples = new List<(Vector2, float)>(); private static readonly HashSet<string> warned = new HashSet<string>(); private static readonly List<TMP_Text> pages = new List<TMP_Text>(); private static int seq; private static Pending? pending; private static DeepTipAnchor? quiet; private static Window? lockWin; private static float lockSince; private static float escHeldSince = -1f; private static bool escHoldDone; private static int escFrame = -1; private static bool escConsumed; internal static bool Reading; internal static Window? Adopted; internal static bool Detaching; internal static (UITooltip Tip, GameObject Go, float Since)? Deferred; internal static bool MouseMode { get { if (ZInput.instance != null && !ZInput.IsExclusiveGamepadActive()) { return !ZInput.IsTouchActive(); } return false; } } internal static bool Active { get { if (Plugin.HasUi && Settings.Enabled.Value) { return MouseMode; } return false; } } internal static IReadOnlyList<Window> Windows => wins; private static string[] RootSides => Settings.Sides(Settings.RootSides, new string[4] { "bottom", "top", "right", "left" }); internal static string[] TooltipSides => Settings.Sides(Settings.TooltipSides, new string[4] { "right", "left", "bottom", "top" }); private static string[] ChildSides => Settings.Sides(Settings.ChildSides, new string[4] { "left", "right", "top", "bottom" }); internal static bool IsOpen(Window w) { return wins.Contains(w); } internal static void WarnOnce(string id, string message) { if (warned.Add(id)) { Plugin.Log.LogWarning((object)message); } } internal static void AttachPage(TMP_Text text) { if (!((Object)(object)text == (Object)null) && !pages.Contains(text)) { pages.Add(text); ((Graphic)text).raycastTarget = true; (((Component)text).GetComponent<ClickCatcher>() ?? ((Component)text).gameObject.AddComponent<ClickCatcher>()).Window = null; } } internal static void Update() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Expected O, but got Unknown //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_063f: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; Locale.Update(unscaledTime); if (!Active) { if (wins.Count > 0) { CloseAll(); } Manager.pending = null; return; } GlossaryView.SyncScale(); Vector2 pointer = Geo.Pointer; Sample(pointer, unscaledTime); Window[] array = wins.ToArray(); foreach (Window window in array) { if (IsOpen(window) && ((Object)(object)window.View.Root == (Object)null || !window.Anchor.Alive)) { Close(window); } } pages.RemoveAll((TMP_Text t) => (Object)(object)t == (Object)null); Window window2 = WindowAt(pointer); TMP_Text val = null; string text = null; int index = -1; IEnumerable<TMP_Text> enumerable2; if (window2 == null) { IEnumerable<TMP_Text> enumerable = pages; enumerable2 = enumerable; } else { enumerable2 = window2.View.Texts; } foreach (TMP_Text item in enumerable2) { if (!((Object)(object)item == (Object)null) && ((Behaviour)item).isActiveAndEnabled && (window2 != null || Geo.Contains(item.rectTransform, pointer))) { text = Geo.LinkAt(item, pointer, out index); if (text != null) { val = item; break; } } } HashSet<Window> hashSet = new HashSet<Window>(); for (Window window3 = window2; window3 != null; window3 = window3.Parent) { hashSet.Add(window3); } foreach (Window win in wins) { Anchor anchor = win.Anchor; if ((anchor is ElementAnchor elementAnchor) ? (window2 == null && elementAnchor.Hovered(pointer)) : (anchor is TermAnchor termAnchor && (Object)(object)val != (Object)null && (Object)(object)termAnchor.Text == (Object)(object)val && termAnchor.Key == text)) { for (Window window4 = win; window4 != null; window4 = window4.Parent) { hashSet.Add(window4); } } } array = wins.ToArray(); foreach (Window window5 in array) { if (!IsOpen(window5) || window5.Pinned) { continue; } if (hashSet.Contains(window5)) { window5.LeaveSince = -1f; continue; } if (window5.LeaveSince < 0f) { window5.LeaveSince = unscaledTime; } float num = unscaledTime - window5.LeaveSince; if (!(num < Settings.CloseDelay.Value) && (!(num < Settings.CloseDelay.Value + 1.5f) || !Heading(window5))) { Close(window5); } } UpdateDeferred(pointer, unscaledTime, window2); if (text != null && (Object)(object)val != (Object)null) { Window parent = window2; TMP_Text text2 = val; string key = text; int index2 = index; Arm("t" + ((parent != null) ? ("w" + parent.Id) : ("p" + ((Object)text2).GetInstanceID())) + ":" + key, key, parent, Settings.LinkDelay.Value, () => new TermAnchor(parent, text2, key, Geo.LinkBox(text2, index2)), null, unscaledTime); } else { if (window2 == null) { DeepTipAnchor hovered = DeepTipAnchor.Hovered; if (hovered != null && (Object)(object)hovered != (Object)(object)quiet && ((Behaviour)hovered).isActiveAndEnabled && hovered.Key.Length > 0 && !HasValheimTooltip(hovered)) { RectTransform rt = (RectTransform)((Component)hovered).transform; string[] sides = ((hovered.Sides.Length > 0) ? Placement.ParseSides(hovered.Sides, RootSides) : null); Arm("e" + ((Object)rt).GetInstanceID(), hovered.Key, null, (hovered.Delay >= 0f) ? hovered.Delay : Settings.Delay.Value, () => new ElementAnchor(rt), sides, unscaledTime); goto IL_0499; } } Manager.pending = null; } goto IL_0499; IL_0499: if (Manager.pending != null && unscaledTime - Manager.pending.Since >= Manager.pending.Delay && (!(unscaledTime - Manager.pending.Since < Manager.pending.Delay + 1.5f) || !HeadingAway(Manager.pending.Parent))) { Pending pending = Manager.pending; Manager.pending = null; Open(pending.Key, pending.Anchor(), pending.Parent, pinned: false, pending.Sides); } UpdateLock(window2, unscaledTime); foreach (Window win2 in wins) { if (win2.FlashUntil > 0f) { float num2 = win2.FlashUntil - unscaledTime; if (num2 <= 0f) { win2.FlashUntil = 0f; win2.View.Flash(0f); } else { win2.View.Flash(Mathf.PingPong(num2 * 4f, 1f)); } } } if (window2 != null) { Reading = true; float mouseScrollWheel = ZInput.GetMouseScrollWheel(); Reading = false; if (Mathf.Abs(mouseScrollWheel) > 0.0001f) { window2.View.Scroll(Mathf.Sign(mouseScrollWheel)); } } Keys(pointer, unscaledTime, window2, val, text, index); array = wins.ToArray(); foreach (Window window6 in array) { if (IsOpen(window6) && window6.View is GlossaryView) { Vector2 val2 = window6.View.ScreenSize() - window6.PlacedSize; if (((Vector2)(ref val2)).sqrMagnitude > 4f) { Place(window6); } } } } private static void Sample(Vector2 p, float now) { //IL_0034: 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_0027: Unknown result type (might be due to invalid IL or missing references) if (samples.Count == 0 || samples[samples.Count - 1].P != p) { samples.Add((p, now)); } while (samples.Count > 2 && now - samples[0].T > 0.12f) { samples.RemoveAt(0); } } private static Window? WindowAt(Vector2 p) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) for (int num = wins.Count - 1; num >= 0; num--) { Window window = wins[num]; if ((Object)(object)window.View.Root != (Object)null && window.View.Root.activeInHierarchy && Geo.Contains(window.View.Panel, p)) { return window; } } return null; } private static bool HasValheimTooltip(DeepTipAnchor a) { UITooltip component = ((Component)a).GetComponent<UITooltip>(); if (component != null) { if (component.m_text.Length <= 0) { return component.m_topic.Length > 0; } return true; } return false; } private static void Arm(string id, string key, Window? parent, float delay, Func<Anchor> anchor, string[]? sides, float now) { if (pending == null || !(pending.Id == id)) { if (wins.Exists((Window w) => w.Anchor.Id == id)) { pending = null; return; } pending = new Pending { Id = id, Key = key, Parent = parent, Since = now, Delay = Mathf.Max(0f, delay), Anchor = anchor, Sides = sides }; } } internal static void Hush(DeepTipAnchor a) { quiet = a; if (pending != null && pending.Id == "e" + ((Object)((Component)a).transform).GetInstanceID()) { pending = null; } } internal static void Unhush(DeepTipAnchor a) { if ((Object)(object)quiet == (Object)(object)a) { quiet = null; } } private static bool Heading(Window w) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (samples.Count < 2 || (Object)(object)w.View.Root == (Object)null) { return false; } (Vector2, float) tuple = samples[0]; (Vector2, float) tuple2 = samples[samples.Count - 1]; if (Time.unscaledTime - tuple2.Item2 > 0.08f) { return false; } Vector2 val = tuple2.Item1 - tuple.Item1; if (((Vector2)(ref val)).magnitude < 3f) { return false; } Box box = w.ScreenBox(); float t = 0f; float t2 = float.MaxValue; if (Axis(tuple2.Item1.x, val.x, box.Left - 12f, box.Right + 12f, ref t, ref t2)) { return Axis(Geo.ScreenH - tuple2.Item1.y, 0f - val.y, box.Top - 12f, box.Bottom + 12f, ref t, ref t2); } return false; } private static bool Axis(float p, float v, float lo, float hi, ref float t0, ref float t1) { if (Mathf.Abs(v) < 1E-06f) { if (p >= lo) { return p <= hi; } return false; } float num = (lo - p) / v; float num2 = (hi - p) / v; if (num > num2) { float num3 = num2; num2 = num; num = num3; } t0 = Mathf.Max(t0, num); t1 = Mathf.Min(t1, num2); return t0 <= t1; } private static bool HeadingAway(Window? parent) { return wins.Exists((Window w) => !w.Pinned && !InChain(parent, w) && Heading(w)); } private static bool InChain(Window? x, Window w) { while (x != null) { if (x == w) { return true; } x = x.Parent; } return false; } internal static bool ShouldDefer(UITooltip tip) { Window adopted = Adopted; if (adopted != null && IsOpen(adopted) && !adopted.Pinned && (Object)(object)adopted.Source != (Object)(object)tip) { return Heading(adopted); } return false; } private static void UpdateDeferred(Vector2 p, float now, Window? hoverWin) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown (UITooltip, GameObject, float)? deferred = Deferred; if (!deferred.HasValue) { return; } (UITooltip, GameObject, float) valueOrDefault = deferred.GetValueOrDefault(); if ((Object)(object)valueOrDefault.Item1 == (Object)null || !((Behaviour)valueOrDefault.Item1).isActiveAndEnabled) { Deferred = null; return; } Window adopted = Adopted; if (adopted != null && hoverWin != null && InChain(hoverWin, adopted)) { Deferred = null; } else { if (adopted != null && IsOpen(adopted) && !adopted.Pinned && now - valueOrDefault.Item3 < 1.5f && Heading(adopted)) { return; } Deferred = null; if (Geo.Contains((RectTransform)((Component)valueOrDefault.Item1).transform, p)) { if (adopted != null && IsOpen(adopted) && !adopted.Pinned) { Close(adopted); } TooltipPatches.Bypass = true; try { valueOrDefault.Item1.OnHoverStart(valueOrDefault.Item2); } finally { TooltipPatches.Bypass = false; } } } } internal static Window? Open(string key, Anchor anchor, Window? parent, bool pinned, string[]? sides = null) { Theme.Ensure(); if (parent != null && !IsOpen(parent)) { return null; } Window window = wins.Find((Window w) => w.Anchor.Id == anchor.Id); if (window != null) { if (pinned) { Pin(window); } return window; } for (Window window2 = parent; window2 != null; window2 = window2.Parent) { if (window2.Key == key) { window2.FlashUntil = Time.unscaledTime + 0.6f; return window2; } } foreach (Window item in wins.Where((Window w) => w.Parent == parent && !w.Pinned).ToList()) { Close(item); } Window window3 = new Window { Id = ++seq, Key = key, Parent = parent, Anchor = anchor, Sides = (sides ?? ((parent != null) ? ChildSides : RootSides)) }; window3.View = new GlossaryView(window3); wins.Add(window3); parent?.Children.Add(window3); if (pinned) { Pin(window3); } else { window3.View.SetPinned(pinned: false); } Place(window3); Api.RaiseOpened(key); return window3; } internal static void Close(Window w) { if (!IsOpen(w)) { return; } Window[] array = w.Children.ToArray(); for (int i = 0; i < array.Length; i++) { Close(array[i]); } wins.Remove(w); w.Parent?.Children.Remove(w); if (lockWin == w) { lockWin = null; } if (w.Adopted) { if (Adopted == w) { Adopted = null; } Detaching = true; try { UITooltip.HideTooltip(); } finally { Detaching = false; } } else if ((Object)(object)w.View.Root != (Object)null) { w.View.Destroy(); } if (w.Key.Length > 0) { Api.RaiseClosed(w.Key); } } internal static void CloseAll() { foreach (Window item in wins.Where((Window x) => x.Parent == null).ToList()) { Close(item); } pending = null; } internal static void Pin(Window w) { Window window = w; while (window != null && !window.Pinned) { if (window.Adopted) { Detach(window); } window.Pinned = true; window.LeaveSince = -1f; window.View.SetPinned(pinned: true); if (window.Key.Length > 0) { Api.RaisePinned(window.Key); } window = window.Parent; } if (lockWin != null && lockWin.Pinned) { lockWin.View.SetLock(0f); lockWin = null; } } internal static void Unpin(Window w) { w.Pinned = false; w.LeaveSince = -1f; w.View.SetPinned(pinned: false); foreach (Window child in w.Children) { Unpin(child); } } internal static void TogglePin(Window w) { if (IsOpen(w)) { if (w.Pinned) { Unpin(w); } else { Pin(w); } } } private static void Place(Window w) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Vector2 val = w.View.ScreenSize(); Box a = ((w.Parent != null) ? w.Parent.ScreenBox() : w.Anchor.Box()); Placed placed = Placement.Compute(val.x, val.y, a, w.Sides, Screen.width, Screen.height); w.View.Place(placed.X, placed.Y, placed.MaxW, placed.MaxH); w.PlacedSize = w.View.ScreenSize(); w.PlacedX = placed.X; w.PlacedY = placed.Y; } internal static void Adopt(UITooltip source, GameObject tooltip) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown Theme.Ensure(); if (Adopted != null) { if ((Object)(object)Adopted.View.Root == (Object)(object)tooltip && (Object)(object)Adopted.Source == (Object)(object)source) { return; } DropAdopted(); } foreach (Window item in wins.Where((Window x) => x.Parent == null && !x.Pinned).ToList()) { Close(item); } Window window = new Window { Id = ++seq, Key = "", Anchor = new ElementAnchor((RectTransform)((Component)source).transform), Adopted = true, Source = source, Sides = TooltipSides }; window.View = new TooltipView(window, tooltip); window.View.SetPinned(pinned: false); wins.Add(window); Adopted = window; TooltipView.LinkTexts(tooltip); Place(window); } internal static void DropAdopted() { Window adopted = Adopted; if (adopted != null) { Adopted = null; Window[] array = adopted.Children.ToArray(); for (int i = 0; i < array.Length; i++) { Close(array[i]); } wins.Remove(adopted); if (lockWin == adopted) { lockWin = null; } } } internal static void KeepAdoptedPlaced() { //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_003e: 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_0045: 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) Window adopted = Adopted; if (adopted == null || !IsOpen(adopted) || (Object)(object)adopted.View.Root == (Object)null) { return; } Vector2 val = adopted.View.ScreenSize(); if (!float.IsNaN(adopted.PlacedX)) { Vector2 val2 = val - adopted.PlacedSize; if (!(((Vector2)(ref val2)).sqrMagnitude > 4f)) { adopted.View.Place(adopted.PlacedX, adopted.PlacedY, 0f, 0f); return; } } Place(adopted); } internal static void AdoptedTextChanged(GameObject tooltip) { if (Adopted != null && (Object)(object)Adopted.View.Root == (Object)(object)tooltip) { foreach (Window item in Adopted.Children.Where((Window c) => !c.Pinned).ToList()) { Close(item); } } TooltipView.LinkTexts(tooltip); } private static void Detach(Window w) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) GameObject root = w.View.Root; GameObject val = Object.Instantiate<GameObject>(root, root.transform.parent); ((Object)val).name = "DeepTip pinned tooltip"; val.transform.position = root.transform.position; val.SetActive(true); w.View = new TooltipView(w, val); w.Adopted = false; w.Source = null; if (Adopted == w) { Adopted = null; } Detaching = true; try { UITooltip.HideTooltip(); } finally { Detaching = false; } } internal static void Click(Window? w, Vector2 position) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } IEnumerable<TMP_Text> enumerable; if (w == null) { enumerable = pages.Where((TMP_Text t) => (Object)(object)t != (Object)null && ((Behaviour)t).isActiveAndEnabled); } else { IEnumerable<TMP_Text> texts = w.View.Texts; enumerable = texts; } foreach (TMP_Text item in enumerable) { int index; string text = Geo.LinkAt(item, position, out index); if (text != null) { Window window = ((w != null && IsOpen(w)) ? w : null); Open(text, new TermAnchor(window, item, text, Geo.LinkBox(item, index)), window, pinned: true); pending = null; return; } } if (w != null && IsOpen(w) && !w.Pinned && Settings.ClickInsidePins.Value) { Pin(w); } } private static void UpdateLock(Window? hoverWin, float now) { float value = Settings.LockAfter.Value; Window window = ((value > 0f && hoverWin != null && !hoverWin.Pinned) ? hoverWin : null); if (window != lockWin) { lockWin?.View.SetLock(0f); lockWin = window; lockSince = now; } if (lockWin != null) { float num = (now - lockSince) / value; if (num >= 1f) { Window? window2 = lockWin; window2.View.SetLock(0f); lockWin = null; Pin(window2); } else { lockWin.View.SetLock(num); } } } private static void Keys(Vector2 p, float now, Window? hoverWin, TMP_Text? linkText, string? linkKey, int linkIndex) { //IL_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references) Reading = true; try { if (Down(Settings.OpenKey.Value)) { OpenHere(p, hoverWin, linkText, linkKey, linkIndex); } if (Down(Settings.CloseAllKey.Value) && wins.Count > 0) { CloseAll(); escFrame = Time.frameCount; escConsumed = true; } if (!ZInput.GetKey((KeyCode)27, true)) { escHeldSince = -1f; escHoldDone = false; } else if (escHeldSince < 0f) { escHeldSince = now; } else if (!escHoldDone && now - escHeldSince >= 0.6f && wins.Count > 0) { escHoldDone = true; CloseAll(); } } finally { Reading = false; } } private static bool Down(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, true)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!ZInput.GetKey(modifier, true)) { return false; } } return true; } internal static bool Escape() { int frameCount = Time.frameCount; if (escFrame == frameCount) { return escConsumed; } escFrame = frameCount; escConsumed = false; if (!Active || wins.Count == 0) { return false; } bool num = wins.Exists((Window w) => w.Pinned); Close(wins[wins.Count - 1]); escConsumed = num; return escConsumed; } private static void OpenHere(Vector2 p, Window? hoverWin, TMP_Text? linkText, string? linkKey, int linkIndex) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown if (linkKey != null && (Object)(object)linkText != (Object)null) { Open(linkKey, new TermAnchor(hoverWin, linkText, linkKey, Geo.LinkBox(linkText, linkIndex)), hoverWin, pinned: true); pending = null; return; } if (hoverWin != null) { Pin(hoverWin); return; } UITooltip current = UITooltip.m_current; GameObject tooltip = UITooltip.m_tooltip; if ((Object)(object)current != (Object)null && (Object)(object)tooltip != (Object)null && Geo.Contains((RectTransform)((Component)current).transform, p)) { if (!tooltip.activeSelf) { tooltip.SetActive(true); } Adopt(current, tooltip); if (Adopted != null) { Pin(Adopted); } } else { DeepTipAnchor hovered = DeepTipAnchor.Hovered; if (hovered != null && ((Behaviour)hovered).isActiveAndEnabled && hovered.Key.Length > 0) { RectTransform rect = (RectTransform)((Component)hovered).transform; Open(hovered.Key, new ElementAnchor(rect), null, pinned: true, (hovered.Sides.Length > 0) ? Placement.ParseSides(hovered.Sides, RootSides) : null); pending = null; } } } internal static void RefreshAll() { Window[] array = wins.ToArray(); foreach (Window window in array) { if (IsOpen(window) && (Object)(object)window.View.Root != (Object)null) { window.View.Refresh(); } } } } internal static class Theme { internal static Sprite? Background; internal static Type BackgroundType = (Type)1; internal static Color BackgroundColor = new Color(0f, 0f, 0f, 0.85f); internal static TMP_FontAsset? Font; internal static Material? FontMaterial; internal static float TextSize = 16f; internal static float TopicSize = 19f; internal static Color TextColor = new Color(0.92f, 0.92f, 0.92f); internal static Color TopicColor = new Color(1f, 0.74f, 0.36f); internal static GameObject? TooltipPrefab; internal static Sprite Pin = null; internal static Sprite PinFilled = null; internal static Sprite Close = null; internal static Sprite Solid = null; private static bool ready; internal static Markup.Style Style => new Markup.Style { Link = "#" + ColorUtility.ToHtmlStringRGB((Color)((Settings.LinkColor != null) ? Settings.LinkColor.Value : new Color(0.965f, 0.769f, 0.325f))), Value = Api.ValueOf }; internal static bool Ensure() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) if (ready) { return true; } if ((Object)(object)Pin == (Object)null) { Pin = Icons.Pin(filled: false); PinFilled = Icons.Pin(filled: true); Close = Icons.Cross(); Solid = Icons.Solid(); } UITooltip[] array = Resources.FindObjectsOfTypeAll<UITooltip>(); foreach (UITooltip val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.m_tooltipPrefab != (Object)null) { TooltipPrefab = val.m_tooltipPrefab; break; } } if ((Object)(object)TooltipPrefab == (Object)null) { return false; } Transform val2 = TooltipPrefab.transform.Find("Bkg"); Image val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Image>() : TooltipPrefab.GetComponentInChildren<Image>(true)); if ((Object)(object)val3 != (Object)null) { Background = val3.sprite; BackgroundType = val3.type; BackgroundColor = ((Graphic)val3).color; } TMP_Text val4 = Find(TooltipPrefab.transform, "Text"); if ((Object)(object)val4 != (Object)null) { Font = val4.font; FontMaterial = val4.fontSharedMaterial; TextSize = ((val4.fontSize > 1f) ? val4.fontSize : TextSize); TextColor = ((Graphic)val4).color; } TMP_Text val5 = Find(TooltipPrefab.transform, "Topic"); if ((Object)(object)val5 != (Object)null) { if (Font == null) { Font = val5.font; } TopicSize = ((val5.fontSize > 1f) ? val5.fontSize : TopicSize); TopicColor = ((Graphic)val5).color; } ready = true; Plugin.Log.LogInfo((object)string.Format("Look taken from Valheim's tooltip: font {0}, size {1}.", ((Object)(object)Font != (Object)null) ? ((Object)Font).name : "default", TextSize)); return true; } internal static TMP_Text? Find(Transform root, string name) { Transform val = Utils.FindChild(root, name, (IterativeSearchType)0); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<TMP_Text>(); } internal static TextMeshProUGUI Text(Transform parent, string name, float size, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)Font != (Object)null) { ((TMP_Text)val2).font = Font; } if ((Object)(object)FontMaterial != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = FontMaterial; } ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).richText = true; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; RectTransform rectTransform = ((TMP_Text)val2).rectTransform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); rectTransform.anchorMax = val3; rectTransform.anchorMin = val3; rectTransform.pivot = new Vector2(0f, 1f); return val2; } } internal static class Icons { private const int Size = 32; internal static Sprite Pin(bool filled) { return Draw(delegate(float x, float y) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) float num = Vector2.Distance(new Vector2(x, y), new Vector2(16f, 21f)) - 7f; float num2 = (filled ? num : (Mathf.Abs(num + 1.25f) - 1.25f)); float num3 = Segment(new Vector2(x, y), new Vector2(16f, 14f), new Vector2(16f, 3f)) - 1.4f; return Mathf.Min(num2, num3); }); } internal static Sprite Solid() { return Draw((float x, float y) => -1f); } internal static Sprite Cross() { return Draw((float x, float y) => Mathf.Min(Segment(new Vector2(x, y), new Vector2(8f, 8f), new Vector2(24f, 24f)), Segment(new Vector2(x, y), new Vector2(8f, 24f), new Vector2(24f, 8f))) - 1.8f); } private static float Segment(Vector2 p, Vector2 a, Vector2 b) { //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_0008: 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_000a: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invali