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 AchievementTracker v0.1.0
plugins/AchievementTracker.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; 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: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AchievementTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+481c8b8578f5d75163cf0921886db388efdaba08")] [assembly: AssemblyProduct("AchievementTracker")] [assembly: AssemblyTitle("AchievementTracker")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AchievementTracker { internal class Requirement { public string Category; public string Key; public string Label; public float Current; public float Needed; public RequirementOperator Op; public bool Met; public float Fraction { get { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!Met) { if ((int)Op != 0 || !(Needed > 0f)) { return 0f; } return Math.Min(Current / Needed, 1f); } return 1f; } } } internal class AchievementEntry { public Achievement Source; public string Name; public string Description; public string Difficulty; public int Tier; public int Order; public bool Secret; public bool Done; public bool? SteamDone; public float Progress; public int Met; public readonly List<Requirement> Requirements = new List<Requirement>(); public bool Hidden { get { if (Secret && !Done && SteamDone != true) { return !Plugin.RevealSecrets.Value; } return false; } } public bool Started { get { if (!Done) { return Progress > 0f; } return true; } } } internal static class AchievementData { private static readonly Dictionary<string, string> LabelCache = new Dictionary<string, string>(); public static bool CanEarn; public static string CurrentDifficulty; public unsafe static List<AchievementEntry> Build() { //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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 List<AchievementEntry> list = new List<AchievementEntry>(); Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if (val == null || (Object)(object)Achievements.m_instance == (Object)null) { return list; } CanEarn = Achievements.CanGetAchievements(false); DifficultyRequirement currentAchievementDifficulty = Achievements.GetCurrentAchievementDifficulty(); CurrentDifficulty = (((int)currentAchievementDifficulty == 1) ? null : ((object)(*(DifficultyRequirement*)(¤tAchievementDifficulty))/*cast due to .constrained prefix*/).ToString()); int num = 0; foreach (AchievementList achievementList in Achievements.m_instance.m_achievementLists) { foreach (Achievement achievement in achievementList.m_achievements) { if (!((Object)(object)achievement == (Object)null)) { list.Add(BuildEntry(achievement, val, num++)); } } } QuerySteam(list); return list; } private unsafe static AchievementEntry BuildEntry(Achievement ach, PlayerProfile profile, int order) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected I4, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected I4, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) AchievementEntry achievementEntry = new AchievementEntry { Source = ach, Name = Localize(ach.m_name), Description = Localize(ach.m_description), Secret = ach.m_isSecret, Order = order, Tier = 99 }; if ((Object)(object)ach.m_iconLocked != (Object)null && ((Object)ach.m_iconLocked).name.Length >= 2 && int.TryParse(((Object)ach.m_iconLocked).name.Substring(0, 2), out var result)) { achievementEntry.Tier = result; } DifficultyRequirement difficultyRequirement = ach.m_difficultyRequirement; if ((int)difficultyRequirement != 1 && (int)difficultyRequirement != 0) { achievementEntry.Difficulty = ((object)(*(DifficultyRequirement*)(&difficultyRequirement))/*cast due to .constrained prefix*/).ToString(); } int num = (int)difficultyRequirement; PlayerStats val = ((num >= 0 && num < profile.m_playerStats.Length) ? profile.m_playerStats[num] : null); if (val != null) { foreach (PlayerStatRequirement item in ach.m_statTrigger) { float value; bool flag = val.m_stats.TryGetValue(item.m_stat, out value); achievementEntry.Requirements.Add(new Requirement { Category = "Stat", Label = StatLabel(item.m_stat), Current = value, Needed = item.m_amountAboveEquals, Op = (RequirementOperator)0, Met = (flag && value >= item.m_amountAboveEquals) }); } foreach (EnemyStatRequirement enemyStatsTrigger in ach.m_enemyStatsTriggers) { int num2 = (int)enemyStatsTrigger.m_modifier; Dictionary<string, float> dict = ((num2 >= 0 && num2 < val.m_enemyStats.Length) ? val.m_enemyStats[num2] : null); AddDictRequirement(achievementEntry, KillCategory(enemyStatsTrigger.m_modifier), dict, enemyStatsTrigger.m_stat, enemyStatsTrigger.m_amount, enemyStatsTrigger.m_operator); } AddDict(achievementEntry, "Eat", val.m_foodEatenStats, ach.m_foodEatenTriggers); AddDict(achievementEntry, "Craft", val.m_itemCraftStats, ach.m_itemCraftTriggers); AddDict(achievementEntry, "Pick up", val.m_itemPickupStats, ach.m_itemPickupTriggers); AddDict(achievementEntry, "Harvest", val.m_pickableStats, ach.m_pickableTriggers); AddDict(achievementEntry, "Build", val.m_piecesPlacedStats, ach.m_piecePlacedTriggers); AddDict(achievementEntry, "Command", val.m_knownCommands, ach.m_knownCommandsTriggers); AddDict(achievementEntry, "World", val.m_knownWorlds, ach.m_knownWorldTriggers); AddDict(achievementEntry, "World key", val.m_knownWorldKeys, ach.m_knownWorldKeysTriggers); } foreach (Achievement otherAchievementTrigger in ach.m_otherAchievementTriggers) { if (!((Object)(object)otherAchievementTrigger == (Object)null)) { achievementEntry.Requirements.Add(new Requirement { Category = "Achievement", Label = Localize(otherAchievementTrigger.m_name), Current = (otherAchievementTrigger.m_unlocked ? 1f : 0f), Needed = 1f, Op = (RequirementOperator)0, Met = otherAchievementTrigger.m_unlocked }); } } float num3 = 0f; foreach (Requirement requirement in achievementEntry.Requirements) { num3 += requirement.Fraction; if (requirement.Met) { achievementEntry.Met++; } } int count = achievementEntry.Requirements.Count; achievementEntry.Done = ach.m_unlocked || (count > 0 && achievementEntry.Met == count); achievementEntry.Progress = (achievementEntry.Done ? 1f : ((count > 0) ? (num3 / (float)count) : 0f)); achievementEntry.Requirements.Sort((Requirement a, Requirement b) => (a.Met == b.Met) ? b.Fraction.CompareTo(a.Fraction) : a.Met.CompareTo(b.Met)); return achievementEntry; } private static void AddDict(AchievementEntry e, string category, Dictionary<string, float> dict, List<DictStatRequirement> triggers) { //IL_000b: 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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) foreach (DictStatRequirement trigger in triggers) { AddDictRequirement(e, category, dict, trigger.m_stat, trigger.m_amount, trigger.m_operator); } } private static void AddDictRequirement(AchievementEntry e, string category, Dictionary<string, float> dict, string stat, float amount, RequirementOperator op) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected I4, but got Unknown float value = 0f; bool num = dict != null && stat != null && dict.TryGetValue(stat, out value); bool met = false; if (num) { switch ((int)op) { case 0: met = value >= amount; break; case 1: met = value <= amount; break; case 2: met = value == amount; break; case 3: met = value != amount; break; } } e.Requirements.Add(new Requirement { Category = category, Key = stat, Label = Localize(stat), Current = value, Needed = amount, Op = op, Met = met }); } private static void QuerySteam(List<AchievementEntry> list) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown IDistributionPlatform distributionPlatform; IAchievementManager val; try { distributionPlatform = PlatformManager.DistributionPlatform; val = ((distributionPlatform != null) ? distributionPlatform.AchievementManager : null); } catch (Exception ex) { Plugin.Log.LogDebug((object)("No platform achievements: " + ex.Message)); return; } if (val == null || !val.IsInitialized) { return; } foreach (AchievementEntry item in list) { AchievementEntry entry = item; try { val.IsUnlocked(PlatformId(entry.Source, distributionPlatform), (AsyncOperationCompletedHandler)delegate(bool unlocked) { entry.SteamDone = unlocked; }); } catch (Exception ex2) { Plugin.Log.LogDebug((object)("Steam lookup failed for " + entry.Source.m_id + ": " + ex2.Message)); } } } private static string PlatformId(Achievement ach, IDistributionPlatform platform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) foreach (DictAchievementPlatformInternalId platformInternalId in ach.m_platformInternalIds) { Platform platform2 = platform.Platform; if (((Platform)(ref platform2)).Equals(platformInternalId.m_platform)) { return platformInternalId.m_internalPlatformId; } } return ach.m_id; } private static string KillCategory(KillModifiers modifier) { //IL_0000: 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_0018: Expected I4, but got Unknown return (modifier - 1) switch { 0 => "Kill (unarmed)", 1 => "Kill (magic)", 2 => "Kill (ranged)", 3 => "Kill (melee)", _ => "Kill", }; } private unsafe static string StatLabel(PlayerStatType stat) { string text = "$stat_" + ((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString(); string text2 = Localize(text); if (!(text2 == text)) { return text2; } return Pretty(((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString()); } internal static string Localize(string key) { if (string.IsNullOrEmpty(key)) { return ""; } if (LabelCache.TryGetValue(key, out var value)) { return value; } string text = key; try { if (key.IndexOf('$') >= 0 && Localization.instance != null) { text = Localization.instance.Localize(key); } } catch (Exception) { } if (string.IsNullOrEmpty(text) || text.StartsWith("[")) { text = Pretty(key); } LabelCache[key] = text; return text; } private static string Pretty(string key) { string text = key.TrimStart(new char[1] { '$' }); int num = text.IndexOf('_'); if (key.StartsWith("$") && num >= 0) { text = text.Substring(num + 1); } StringBuilder stringBuilder = new StringBuilder(text.Length + 8); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '_') { stringBuilder.Append(' '); continue; } if (i > 0 && char.IsUpper(c) && char.IsLower(text[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append((stringBuilder.Length == 0) ? char.ToUpperInvariant(c) : ((i > 0) ? char.ToLowerInvariant(c) : c)); } return stringBuilder.ToString(); } } internal class NativeWindow { private enum Filter { All, Active, Done } internal class Panel { public GameObject Root; public RectTransform Frame; public RectTransform ListContainer; public RectTransform ListRoot; public ScrollRect Scroll; public Scrollbar Scrollbar; public RectTransform TooltipAnchor; public GameObject ElementPrefab; public GameObject TooltipPrefab; public TMP_Text Title; public TMP_Text TextTemplate; public Button Close; public Button Backdrop; public float Spacing; public float BaseListHeight; public readonly List<Row> Rows = new List<Row>(); public float ListWidth { get { //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) Rect rect = ListContainer.rect; return ((Rect)(ref rect)).width; } } public static Panel Clone(SkillsDialog template, Transform parent, string name, bool keepBackdrop) { //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = name; val.SetActive(false); SkillsDialog component = val.GetComponent<SkillsDialog>(); Panel panel = new Panel { Root = val, ListRoot = component.m_listRoot, TooltipAnchor = component.m_tooltipAnchor, ElementPrefab = component.m_elementPrefab, TextTemplate = component.m_totalSkillText, Spacing = component.m_spacing, Scroll = (ScrollRect)/*isinst with value type is only supported in some contexts*/, Scrollbar = (Scrollbar)/*isinst with value type is only supported in some contexts*/, Frame = (RectTransform)/*isinst with value type is only supported in some contexts*/ }; Object.DestroyImmediate((Object)(object)component); UIGroupHandler[] componentsInChildren = val.GetComponentsInChildren<UIGroupHandler>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } CanvasGroup component2 = val.GetComponent<CanvasGroup>(); if ((Object)(object)component2 != (Object)null) { component2.alpha = 1f; component2.interactable = true; component2.blocksRaycasts = true; } if ((Object)(object)panel.Frame == (Object)null || (Object)(object)panel.Scroll == (Object)null || (Object)(object)panel.ListRoot == (Object)null || (Object)(object)panel.ElementPrefab == (Object)null) { Object.Destroy((Object)(object)val); return null; } ref RectTransform listContainer = ref panel.ListContainer; Transform parent2 = ((Component)panel.Scroll).transform.parent; listContainer = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null); Transform obj = ((Transform)panel.Frame).Find("Closebutton"); panel.Close = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null); if ((Object)(object)panel.ListContainer == (Object)null || (Object)(object)panel.Close == (Object)null) { Object.Destroy((Object)(object)val); return null; } Transform obj2 = ((Transform)panel.Frame).Find("topic"); panel.Title = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null); Transform val2 = val.transform.Find("Closebutton"); Transform val3 = val.transform.Find("darken"); Transform val4 = val.transform.Find("blur"); if (keepBackdrop) { panel.Backdrop = ((val2 != null) ? ((Component)val2).GetComponent<Button>() : null); } else { if (val2 != null) { ((Component)val2).gameObject.SetActive(false); } if (val3 != null) { ((Component)val3).gameObject.SetActive(false); } if (val4 != null) { ((Component)val4).gameObject.SetActive(false); } } Transform obj3 = ((Transform)panel.Frame).Find("totalskills_topic"); if (obj3 != null) { ((Component)obj3).gameObject.SetActive(false); } TMP_Text textTemplate = panel.TextTemplate; if (textTemplate != null) { ((Component)textTemplate).gameObject.SetActive(false); } List<GameObject> list = new List<GameObject>(); foreach (Transform item in (Transform)panel.ListRoot) { Transform val5 = item; if ((Object)(object)val5 != (Object)(object)panel.TooltipAnchor) { list.Add(((Component)val5).gameObject); } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } Rect rect = panel.ListRoot.rect; panel.BaseListHeight = ((Rect)(ref rect)).height; if ((Object)(object)panel.Title != (Object)null) { panel.Title.enableAutoSizing = true; panel.Title.fontSizeMin = 14f; panel.Title.fontSizeMax = panel.Title.fontSize; } return panel; } public float ReserveTop(float height) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0049: Unknown result type (might be due to invalid IL or missing references) float result = 0f - ListContainer.anchoredPosition.y; RectTransform listContainer = ListContainer; listContainer.anchoredPosition -= new Vector2(0f, height); RectTransform listContainer2 = ListContainer; listContainer2.sizeDelta -= new Vector2(0f, height); BaseListHeight = Mathf.Max(0f, BaseListHeight - height); return result; } public TMP_Text NewText(string name, float x, float top, float width, float height, float size, TextAlignmentOptions align) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_008e: 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_00b8: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = ButtonLabel(Close); GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)Frame, false); TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); if ((Object)(object)val != (Object)null) { ((TMP_Text)val3).font = val.font; ((TMP_Text)val3).fontSharedMaterial = val.fontSharedMaterial; ((Graphic)val3).color = ((Graphic)val).color; } ((TMP_Text)val3).fontSize = size; ((TMP_Text)val3).enableAutoSizing = true; ((TMP_Text)val3).fontSizeMin = 10f; ((TMP_Text)val3).fontSizeMax = size; ((TMP_Text)val3).alignment = align; ((TMP_Text)val3).textWrappingMode = (TextWrappingModes)0; ((Graphic)val3).raycastTarget = false; Place((RectTransform)val2.transform, x, top, width, height); return (TMP_Text)(object)val3; } public static void Place(RectTransform rt, float x, float top, float width, float height) { //IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0.5f, 0.5f); rt.sizeDelta = new Vector2(width, height); rt.anchoredPosition = new Vector2(x, 0f - (top + height / 2f)); ((Transform)rt).localScale = Vector3.one; } public void SetTitle(string text) { if ((Object)(object)Title != (Object)null) { Title.text = text; } } public void SetRowCount(int count) { while (Rows.Count < count) { Rows.Add(Row.Create(this, Rows.Count)); } for (int i = 0; i < Rows.Count; i++) { bool flag = i < count; if (Rows[i].Go.activeSelf != flag) { Rows[i].Go.SetActive(flag); } } ListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(BaseListHeight, (float)count * Spacing)); } public void UpdateScrollbar() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Scrollbar == (Object)null) && !((Object)(object)Scroll == (Object)null)) { Rect rect = ListRoot.rect; float height = ((Rect)(ref rect)).height; if (height > 0f) { Scrollbar scrollbar = Scrollbar; rect = ((RectTransform)((Component)Scroll).transform).rect; scrollbar.size = Mathf.Clamp01(((Rect)(ref rect)).height / height); } } } } internal class Row { public static readonly Color DoneColor = new Color(0.56f, 0.86f, 0.45f); public GameObject Go; public string Id; public Action OnClick; private Image _icon; private TMP_Text _name; private TMP_Text _level; private GuiBar _bar; private GuiBar _barTotal; private UITooltip _tooltip; private Color _nameColor; private Selectable _selectable; public static Row Create(Panel panel, int index) { //IL_0129: 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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(panel.ElementPrefab, (Transform)(object)panel.ListRoot, false); ((Object)val).name = "Row"; val.SetActive(true); Row obj = new Row { Go = val }; Transform obj2 = Find(val, "icon"); obj._icon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); Transform obj3 = Find(val, "name"); obj._name = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null); Transform obj4 = Find(val, "leveltext"); obj._level = ((obj4 != null) ? ((Component)obj4).GetComponent<TMP_Text>() : null); Transform obj5 = Find(val, "levelbar"); obj._bar = ((obj5 != null) ? ((Component)obj5).GetComponent<GuiBar>() : null); Transform obj6 = Find(val, "levelbar_total"); obj._barTotal = ((obj6 != null) ? ((Component)obj6).GetComponent<GuiBar>() : null); obj._tooltip = val.GetComponentInChildren<UITooltip>(true); obj._selectable = val.GetComponent<Selectable>(); Row row = obj; Transform obj7 = Find(val, "currentlevel"); if (obj7 != null) { ((Component)obj7).gameObject.SetActive(false); } Transform obj8 = Find(val, "bonustext"); if (obj8 != null) { ((Component)obj8).gameObject.SetActive(false); } if ((Object)(object)row._name != (Object)null) { row._nameColor = ((Graphic)row._name).color; row._name.enableAutoSizing = true; row._name.fontSizeMin = 11f; row._name.fontSizeMax = row._name.fontSize; } if ((Object)(object)row._level != (Object)null) { row._level.enableAutoSizing = true; row._level.fontSizeMin = 10f; row._level.fontSizeMax = row._level.fontSize; } Button[] componentsInChildren = val.GetComponentsInChildren<Button>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].onClick = new ButtonClickedEvent(); } if ((Object)(object)row._tooltip != (Object)null && (Object)(object)panel.TooltipPrefab != (Object)null) { row._tooltip.m_tooltipPrefab = panel.TooltipPrefab; } val.AddComponent<RowClick>().Row = row; ((RectTransform)val.transform).anchoredPosition = new Vector2(0f, (float)(-index) * panel.Spacing); return row; } public void SetIcon(Sprite sprite, float alpha) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_icon == (Object)null)) { _icon.sprite = sprite; ((Behaviour)_icon).enabled = (Object)(object)sprite != (Object)null; ((Graphic)_icon).color = new Color(1f, 1f, 1f, alpha); } } public void SetName(string text, Color? color) { //IL_0036: 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) if (!((Object)(object)_name == (Object)null)) { _name.text = text; ((Graphic)_name).color = (Color)(((??)color) ?? _nameColor); } } public void SetLevel(string text) { if ((Object)(object)_level != (Object)null) { _level.text = text; } } public void SetBar(float value) { GuiBar bar = _bar; if (bar != null) { bar.SetValue(value); } GuiBar barTotal = _barTotal; if (barTotal != null) { barTotal.SetValue(value); } } public void SetTooltip(string topic, string text) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) UITooltip tooltip = _tooltip; if (tooltip != null) { tooltip.Set(topic, text, (RectTransform)null, default(Vector2)); } } public void SetSelected(bool selected) { EventSystem current = EventSystem.current; if (selected && !((Object)(object)_selectable == (Object)null) && !((Object)(object)current == (Object)null)) { GameObject currentSelectedGameObject = current.currentSelectedGameObject; if (!((Object)(object)currentSelectedGameObject == (Object)(object)Go) && (!((Object)(object)currentSelectedGameObject != (Object)null) || !((Object)(object)currentSelectedGameObject.GetComponent<TMP_InputField>() != (Object)null))) { current.SetSelectedGameObject(Go); } } } private static Transform Find(GameObject go, string name) { Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return val; } } return null; } } internal class RowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { public Row Row; public void OnPointerClick(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0 && Row?.OnClick != null) { Row.OnClick(); } } } private const float FrameGap = 12f; private const float RefreshSeconds = 2f; private const float SearchHeaderHeight = 36f; private const float DetailHeaderHeight = 64f; private static readonly Color Orange = new Color(1f, 0.65f, 0.1f); private Panel _main; private Panel _detail; private readonly List<Button> _filterButtons = new List<Button>(); private Button _toggleDoneButton; private TMP_InputField _search; private TMP_Text _summary; private TMP_Text _description; private Color _labelColor = Color.white; private List<AchievementEntry> _entries = new List<AchievementEntry>(); private readonly List<AchievementEntry> _visible = new List<AchievementEntry>(); private readonly List<Requirement> _visibleReqs = new List<Requirement>(); private string _selectedId; private Filter _filter; private bool _showDone; private float _refreshTimer; private readonly Dictionary<string, Sprite> _icons = new Dictionary<string, Sprite>(); public bool Exists { get { if ((Object)(object)_main?.Root != (Object)null) { return (Object)(object)_detail?.Root != (Object)null; } return false; } } public bool Show() { if (!Exists && !Build()) { return false; } _main.Root.SetActive(true); _detail.Root.SetActive(true); _main.Root.transform.SetAsLastSibling(); _detail.Root.transform.SetAsLastSibling(); Refresh(); _main.Scroll.verticalNormalizedPosition = 1f; return true; } public void Hide() { UITooltip.HideTooltip(); if ((Object)(object)_search != (Object)null) { _search.DeactivateInputField(false); } if ((Object)(object)_main?.Root != (Object)null) { _main.Root.SetActive(false); } if ((Object)(object)_detail?.Root != (Object)null) { _detail.Root.SetActive(false); } } public void Tick() { if (Exists) { _refreshTimer += Time.unscaledDeltaTime; if (_refreshTimer >= 2f) { Refresh(); } _main.UpdateScrollbar(); _detail.UpdateScrollbar(); } } private bool Build() { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) SkillsDialog val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_skillsDialog : null); Canvas val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Canvas>(true) : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"Skills dialog not found; can't build the tracker window yet."); return false; } Transform transform = ((Component)val2.rootCanvas).transform; _main = Panel.Clone(val, transform, "AchievementTracker_List", keepBackdrop: true); _detail = Panel.Clone(val, transform, "AchievementTracker_Detail", keepBackdrop: false); if (_main == null || _detail == null) { Plugin.Log.LogError((object)"The Skills dialog layout changed; can't build the tracker window."); Object.Destroy((Object)(object)_main?.Root); Object.Destroy((Object)(object)_detail?.Root); _main = (_detail = null); return false; } Rect rect = _main.Frame.rect; float num = ((Rect)(ref rect)).width / 2f + 6f; _main.Frame.anchoredPosition = new Vector2(0f - num, 0f); _detail.Frame.anchoredPosition = new Vector2(num, 0f); if ((Object)(object)_main.Backdrop != (Object)null) { Rebind(_main.Backdrop, Plugin.RequestClose); } _main.SetTitle("Achievements"); TMP_Text obj = ButtonLabel(_main.Close); _labelColor = ((obj != null) ? ((Graphic)obj).color : Color.white); BuildFilterButtons(); BuildSearchHeader(); BuildDetailHeader(); _toggleDoneButton = _detail.Close; Rebind(_toggleDoneButton, delegate { _showDone = !_showDone; RefreshDetail(); }); InventoryGrid playerGrid = InventoryGui.instance.m_playerGrid; object obj2; if (playerGrid == null) { obj2 = null; } else { GameObject elementPrefab = playerGrid.m_elementPrefab; obj2 = ((elementPrefab == null) ? null : elementPrefab.GetComponentInChildren<UITooltip>(true)?.m_tooltipPrefab); } GameObject tooltipPrefab = (GameObject)obj2; _main.TooltipPrefab = (_detail.TooltipPrefab = tooltipPrefab); HideInputHints(_main.Root); HideInputHints(_detail.Root); BuildIconLookup(); return true; } private static void HideInputHints(GameObject root) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "UIInputHint") { val.gameObject.SetActive(false); } } } private void BuildFilterButtons() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_00a3: 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_00ca: Unknown result type (might be due to invalid IL or missing references) Button close = _main.Close; RectTransform val = (RectTransform)((Component)close).transform; string[] array = new string[4] { "All", "Active", "Done", "Close" }; float num = (_main.ListWidth - 6f * (float)(array.Length - 1)) / (float)array.Length; Vector2 anchoredPosition = val.anchoredPosition; for (int i = 0; i < array.Length; i++) { Button val2 = ((i == array.Length - 1) ? close : Object.Instantiate<GameObject>(((Component)close).gameObject, ((Component)close).transform.parent, false).GetComponent<Button>()); RectTransform val3 = (RectTransform)((Component)val2).transform; val3.SetSizeWithCurrentAnchors((Axis)0, num); val3.anchoredPosition = new Vector2(((float)i - (float)(array.Length - 1) / 2f) * (num + 6f), anchoredPosition.y); TMP_Text val4 = ButtonLabel(val2); if ((Object)(object)val4 != (Object)null) { val4.text = array[i]; val4.enableAutoSizing = true; val4.fontSizeMin = 12f; val4.fontSizeMax = val4.fontSize; } if (i == array.Length - 1) { Rebind(val2, Plugin.RequestClose); continue; } Filter f = (Filter)i; Rebind(val2, delegate { _filter = f; RefreshMain(); }); _filterButtons.Add(val2); } } private void BuildSearchHeader() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown float top = _main.ReserveTop(36f); float listWidth = _main.ListWidth; _summary = _main.NewText("Summary", (0f - listWidth) / 2f + (listWidth - 150f) + 75f, top, 150f, 36f, 16f, (TextAlignmentOptions)4100); Component val = (Component)(((Object)(object)Hud.instance != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = Object.Instantiate<GameObject>(val.gameObject, (Transform)(object)_main.Frame, false); ((Object)val2).name = "Search"; val2.SetActive(true); _search = val2.GetComponent<TMP_InputField>(); if ((Object)(object)_search == (Object)null) { Object.Destroy((Object)(object)val2); return; } float num = listWidth - 150f - 8f; Panel.Place((RectTransform)val2.transform, (0f - listWidth) / 2f + num / 2f, top, num, 32f); _search.text = ""; Graphic placeholder = _search.placeholder; TMP_Text val3 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null); if (val3 != null) { val3.text = "Search..."; } _search.onValueChanged = new OnChangeEvent(); _search.onSelect = new SelectionEvent(); _search.onDeselect = new SelectionEvent(); _search.onEndEdit = new SubmitEvent(); _search.onSubmit = new SubmitEvent(); ((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate { RefreshMain(); }); } private void BuildDetailHeader() { float top = _detail.ReserveTop(64f); _description = _detail.NewText("Description", 0f, top, _detail.ListWidth, 64f, 16f, (TextAlignmentOptions)257); _description.textWrappingMode = (TextWrappingModes)1; } private void BuildIconLookup() { _icons.Clear(); if ((Object)(object)ObjectDB.instance == (Object)null) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { SharedData val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared; if (val != null && !string.IsNullOrEmpty(val.m_name) && val.m_icons != null && val.m_icons.Length != 0 && !_icons.ContainsKey(val.m_name)) { _icons[val.m_name] = val.m_icons[0]; } } try { foreach (Piece allBuildPiece in ObjectDB.instance.GetAllBuildPieces(true)) { if ((Object)(object)allBuildPiece != (Object)null && (Object)(object)allBuildPiece.m_icon != (Object)null && !string.IsNullOrEmpty(allBuildPiece.m_name) && !_icons.ContainsKey(allBuildPiece.m_name)) { _icons[allBuildPiece.m_name] = allBuildPiece.m_icon; } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Piece icons unavailable: " + ex.Message)); } } private void Refresh() { _refreshTimer = 0f; _entries = AchievementData.Build(); RefreshMain(); } private void RefreshMain() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) string text = (((Object)(object)_search != (Object)null) ? _search.text.Trim() : ""); _visible.Clear(); foreach (AchievementEntry entry in _entries) { if ((_filter != Filter.Active || !entry.Done) && (_filter != Filter.Done || entry.Done) && (text.Length <= 0 || Matches(entry, text))) { _visible.Add(entry); } } if (_filter == Filter.Active) { _visible.Sort((AchievementEntry a, AchievementEntry b) => (b.Progress == a.Progress) ? a.Order.CompareTo(b.Order) : b.Progress.CompareTo(a.Progress)); } else { _visible.Sort((AchievementEntry a, AchievementEntry b) => (a.Tier == b.Tier) ? a.Order.CompareTo(b.Order) : a.Tier.CompareTo(b.Tier)); } for (int num = 0; num < _filterButtons.Count; num++) { TMP_Text val = ButtonLabel(_filterButtons[num]); if ((Object)(object)val != (Object)null) { ((Graphic)val).color = ((num == (int)_filter) ? Orange : _labelColor); } } int num2 = 0; int num3 = 0; bool flag = false; foreach (AchievementEntry entry2 in _entries) { if (entry2.Done) { num2++; } if (entry2.SteamDone.HasValue) { flag = true; if (entry2.SteamDone.Value) { num3++; } } } if ((Object)(object)_summary != (Object)null) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(AchievementData.CanEarn ? $"<color=orange>{num2}</color> / {_entries.Count}" : "<color=#ff7040>Not recording</color>"); if (flag) { stringBuilder.Append($"\n<size=75%>Steam <color=#8cc0ff>{num3}</color> / {_entries.Count}</size>"); } _summary.text = stringBuilder.ToString(); } _main.SetRowCount(_visible.Count); for (int num4 = 0; num4 < _visible.Count; num4++) { FillAchievementRow(_main.Rows[num4], _visible[num4]); } if (_selectedId == null || _entries.Find((AchievementEntry e) => e.Source.m_id == _selectedId) == null) { _selectedId = ((_visible.Count > 0) ? _visible[0].Source.m_id : null); } RefreshDetail(); } private void FillAchievementRow(Row row, AchievementEntry e) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) bool hidden = e.Hidden; string text = ((e.SteamDone == true && !e.Done) ? " <size=70%><color=#8cc0ff>Steam</color></size>" : ""); row.SetIcon((e.Done || e.SteamDone == true) ? e.Source.m_icon : e.Source.m_iconLocked, 1f); row.SetName((hidden ? "???" : e.Name) + text, e.Done ? new Color?(Row.DoneColor) : ((Color?)null)); row.SetLevel(e.Done ? "Done" : $"{Mathf.FloorToInt(e.Progress * 100f)}%"); row.SetBar(e.Progress); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(hidden ? "Secret achievement. Keep playing to discover it." : e.Description); if (!hidden && e.Requirements.Count > 0) { stringBuilder.Append($"\n\n{e.Met} / {e.Requirements.Count} requirements met"); } if (e.Difficulty != null) { stringBuilder.Append("\nCounts on " + e.Difficulty + " difficulty worlds"); } if (e.SteamDone == true) { stringBuilder.Append("\n<color=#8cc0ff>Unlocked on your Steam account</color>"); } row.SetTooltip(hidden ? "???" : e.Name, stringBuilder.ToString()); string id = e.Source.m_id; row.Id = id; row.OnClick = delegate { _selectedId = id; _showDone = false; RefreshDetail(); _detail.Scroll.verticalNormalizedPosition = 1f; }; } private void RefreshDetail() { //IL_0324: Unknown result type (might be due to invalid IL or missing references) AchievementEntry achievementEntry = ((_selectedId != null) ? _entries.Find((AchievementEntry x) => x.Source.m_id == _selectedId) : null); foreach (Row row2 in _main.Rows) { row2.SetSelected(row2.Go.activeSelf && _selectedId != null && row2.Id == _selectedId); } if (achievementEntry == null || achievementEntry.Hidden) { _detail.SetTitle((achievementEntry == null) ? "Details" : "???"); if ((Object)(object)_description != (Object)null) { _description.text = ((achievementEntry == null) ? "Select an achievement." : "Secret achievement."); } _detail.SetRowCount(0); ((Component)_toggleDoneButton).gameObject.SetActive(false); return; } _detail.SetTitle(achievementEntry.Name); string text = (achievementEntry.Done ? "<color=#8fdc72>Complete</color>" : ((achievementEntry.Requirements.Count > 0) ? $"<color=orange>{achievementEntry.Met}</color> / {achievementEntry.Requirements.Count} done" : "Special condition")); if (achievementEntry.Difficulty != null) { text = text + " <color=#a89f8c>(" + achievementEntry.Difficulty + " difficulty)</color>"; } if ((Object)(object)_description != (Object)null) { _description.text = achievementEntry.Description + "\n<size=85%>" + text + "</size>"; } _visibleReqs.Clear(); int num = 0; foreach (Requirement requirement2 in achievementEntry.Requirements) { if (requirement2.Met) { num++; if (!_showDone) { continue; } } _visibleReqs.Add(requirement2); } ((Component)_toggleDoneButton).gameObject.SetActive(num > 0); TMP_Text val = ButtonLabel(_toggleDoneButton); if ((Object)(object)val != (Object)null) { val.text = (_showDone ? "Hide done" : $"Show done ({num})"); } Sprite val2 = (achievementEntry.Done ? achievementEntry.Source.m_icon : achievementEntry.Source.m_iconLocked); _detail.SetRowCount(_visibleReqs.Count); for (int num2 = 0; num2 < _visibleReqs.Count; num2++) { Requirement requirement = _visibleReqs[num2]; Row row = _detail.Rows[num2]; Sprite value; bool flag = _icons.TryGetValue(requirement.Key ?? "", out value); row.SetIcon(flag ? value : val2, flag ? 1f : 0.35f); row.SetName("<size=70%><color=#a89f8c>" + requirement.Category + "</color></size> " + requirement.Label, requirement.Met ? new Color?(Row.DoneColor) : ((Color?)null)); row.SetLevel(LevelText(requirement)); row.SetBar(requirement.Fraction); row.SetTooltip(requirement.Label, requirement.Category + ": " + requirement.Label + "\n" + LevelText(requirement)); row.OnClick = null; row.Id = null; } } private static string LevelText(Requirement r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected I4, but got Unknown RequirementOperator op = r.Op; return (int)op switch { 0 => Num(Mathf.Min(r.Current, r.Needed)) + "/" + Num(r.Needed), 1 => "<=" + Num(r.Needed), 2 => "=" + Num(r.Needed), _ => "!=" + Num(r.Needed), }; } private static string Num(float v) { return v.ToString((v % 1f == 0f) ? "0" : "0.#"); } private static bool Matches(AchievementEntry e, string q) { if (e.Hidden) { return false; } if (Contains(e.Name, q) || Contains(e.Description, q)) { return true; } foreach (Requirement requirement in e.Requirements) { if (Contains(requirement.Label, q)) { return true; } } return false; } private static bool Contains(string s, string q) { if (s != null) { return s.IndexOf(q, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static void Rebind(Button b, Action action) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown b.onClick = new ButtonClickedEvent(); ((UnityEvent)b.onClick).AddListener((UnityAction)delegate { action(); }); } private static TMP_Text ButtonLabel(Button b) { object obj2; if (!((Object)(object)b == (Object)null)) { Transform obj = ((Component)b).transform.Find("Text"); obj2 = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null); if (obj2 == null) { return ((Component)b).GetComponentInChildren<TMP_Text>(true); } } else { obj2 = null; } return (TMP_Text)obj2; } } [BepInPlugin("Dirtsnack.AchievementTracker", "Achievement Tracker", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "Dirtsnack.AchievementTracker"; public const string ModName = "Achievement Tracker"; public const string ModVersion = "0.1.0"; internal static ManualLogSource Log; internal static ConfigEntry<KeyboardShortcut> ToggleKey; internal static ConfigEntry<bool> RevealSecrets; internal static bool IsOpen; private readonly NativeWindow _window = new NativeWindow(); private static bool _closeRequested; private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) Log = ((BaseUnityPlugin)this).Logger; ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Opens and closes the tracker."); RevealSecrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RevealSecrets", false, "Show the names and requirements of secret achievements before you unlock them."); new Harmony("Dirtsnack.AchievementTracker").PatchAll(); Log.LogInfo((object)string.Format("{0} {1} loaded. Press {2} in game.", "Achievement Tracker", "0.1.0", ToggleKey.Value)); } private void Update() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Achievements.m_instance == (Object)null) { if (IsOpen) { Close(); } return; } if (IsOpen && ZInput.GetKeyDown((KeyCode)27, false)) { _closeRequested = true; } else if (IsShortcutDown(ToggleKey.Value) && (IsOpen || !IsTyping())) { if (IsOpen) { _closeRequested = true; } else { Open(); } } if (IsOpen) { _window.Tick(); } } private void LateUpdate() { if (_closeRequested) { _closeRequested = false; Close(); } } internal static void RequestClose() { _closeRequested = true; } private void Open() { IsOpen = _window.Show(); } private void Close() { IsOpen = false; _window.Hide(); } private static bool IsTyping() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.InTextInput()) { if ((Object)(object)Hud.instance != (Object)null) { return Hud.instance.m_buildUi.SearchFieldFocused; } return false; } return true; } private static bool IsShortcutDown(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, false)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!ZInput.GetKey(modifier, false)) { return false; } } return true; } } [HarmonyPatch(typeof(TextInput), "IsVisible")] internal static class TextInput_IsVisible_Patch { private static void Postfix(ref bool __result) { __result |= Plugin.IsOpen; } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] internal static class ZInput_GetMouseScrollWheel_Patch { private static void Postfix(ref float __result) { if (Plugin.IsOpen) { __result = 0f; } } } }