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 BuildTracker v1.1.0
BuildTracker.dll
Decompiled 10 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BuildTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+319c0bf891e120234819c7c59614e418ebc7feb8")] [assembly: AssemblyProduct("BuildTracker")] [assembly: AssemblyTitle("BuildTracker")] [assembly: AssemblyVersion("1.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 BuildTracker { [HarmonyPatch(typeof(BuildUi))] internal static class BuildUiPatches { private static readonly FieldRef<BuildUi, RectTransform> TabContainerRef = AccessTools.FieldRefAccess<BuildUi, RectTransform>("m_tabContainer"); private static readonly FieldRef<BuildUi, TabHandler> TabHandlerRef = AccessTools.FieldRefAccess<BuildUi, TabHandler>("m_tabHandler"); private static readonly FieldRef<BuildUi, List<IPieceList>> PieceListsRef = AccessTools.FieldRefAccess<BuildUi, List<IPieceList>>("m_pieceLists"); private static readonly FieldRef<BuildUi, int> AvailablePieceCountRef = AccessTools.FieldRefAccess<BuildUi, int>("m_availablePieceCount"); private static readonly FieldRef<BuildUi, int> CurrentPieceListRef = AccessTools.FieldRefAccess<BuildUi, int>("m_currentPieceList"); private static readonly FieldRef<BuildUi, int> CurrentTagIdRef = AccessTools.FieldRefAccess<BuildUi, int>("m_currentTagId"); private static readonly FieldRef<BuildUi, PieceTable> CurrentBuildToolRef = AccessTools.FieldRefAccess<BuildUi, PieceTable>("m_currentBuildTool"); private static readonly FieldRef<BuildUi, RectTransform> PieceViewRef = AccessTools.FieldRefAccess<BuildUi, RectTransform>("m_pieceView"); private static readonly FieldRef<BuildUi, ScrollRect> PieceScrollRectRef = AccessTools.FieldRefAccess<BuildUi, ScrollRect>("m_pieceScrollRect"); private static UndiscoveredLabel s_undiscoveredLabel; [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Awake_Prefix(BuildUi __instance, out bool __state) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_010f: Expected O, but got Unknown //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_0127: Expected O, but got Unknown __state = false; RectTransform val = TabContainerRef.Invoke(__instance); TabHandler val2 = TabHandlerRef.Invoke(__instance); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || ((Transform)val).childCount < 2 || val2.m_tabs.Count != ((Transform)val).childCount) { BuildTrackerPlugin.Log.LogWarning((object)"Build menu tabs have an unexpected layout; the Not built tab is disabled."); return; } RectTransform val3 = (RectTransform)((Transform)val).GetChild(((Transform)val).childCount - 1); RectTransform val4 = (RectTransform)((Transform)val).GetChild(((Transform)val).childCount - 2); RectTransform val5 = Object.Instantiate<RectTransform>(val3, (Transform)(object)val); ((Object)val5).name = "BuildTracker_NotBuiltTab"; if ((Object)(object)((Component)val).GetComponent<LayoutGroup>() == (Object)null) { val5.anchoredPosition = val3.anchoredPosition + (val3.anchoredPosition - val4.anchoredPosition); } TMP_Text[] componentsInChildren = ((Component)val5).GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = BuildTrackerPlugin.TabName.Value; } Button component = ((Component)val5).GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); val2.m_tabs.Add(new Tab { m_button = component }); __state = true; } [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake_Postfix(BuildUi __instance, bool __state) { s_undiscoveredLabel = null; if (__state) { PieceListsRef.Invoke(__instance).Add((IPieceList)(object)new UnbuiltPieceList(BuildTrackerPlugin.TabName.Value)); RectTransform val = PieceViewRef.Invoke(__instance); if ((Object)(object)val != (Object)null) { s_undiscoveredLabel = new UndiscoveredLabel(val, PieceScrollRectRef.Invoke(__instance), ((Component)TabContainerRef.Invoke(__instance)).GetComponentInChildren<TMP_Text>(true)); } } } [HarmonyPatch("UpdatePieceButtons")] [HarmonyPostfix] private static void UpdatePieceButtons_Postfix(BuildUi __instance) { if (s_undiscoveredLabel == null) { return; } List<IPieceList> list = PieceListsRef.Invoke(__instance); int num = CurrentPieceListRef.Invoke(__instance); PieceTable val = CurrentBuildToolRef.Invoke(__instance); if ((Object)(object)val != (Object)null && !val.m_hideAdvancedMenu && num >= 0 && num < list.Count && list[num] is UnbuiltPieceList unbuiltPieceList) { s_undiscoveredLabel.Show(BuildTrackerPlugin.ShowUndiscovered.Value ? unbuiltPieceList.CountUndiscovered(val, CurrentTagIdRef.Invoke(__instance)) : 0); string message = null; if (unbuiltPieceList.AllDiscoveredBuilt(val)) { message = ((unbuiltPieceList.CountUndiscovered(val, -1) == 0) ? BuildTrackerPlugin.CongratsText.Value : BuildTrackerPlugin.CongratsSoFarText.Value); } s_undiscoveredLabel.ShowCongrats(message); } else { s_undiscoveredLabel.Hide(); } } internal static void Refresh() { BuildUi val = (((Object)(object)Hud.instance != (Object)null) ? Hud.instance.m_buildUi : null); if ((Object)(object)val != (Object)null) { AvailablePieceCountRef.Invoke(val) = -1; } } } [HarmonyPatch(typeof(PlayerProfile), "IncrementStatBuildPiecePlaced")] internal static class PiecePlacedPatch { private static void Postfix() { BuildUiPatches.Refresh(); } } [BepInPlugin("com.koendertjh.buildtracker", "BuildTracker", "1.1.0")] public class BuildTrackerPlugin : BaseUnityPlugin { public const string ModGuid = "com.koendertjh.buildtracker"; public const string ModName = "BuildTracker"; public const string ModVersion = "1.1.0"; internal static ManualLogSource Log; internal static ConfigEntry<string> TabName; internal static ConfigEntry<bool> ShowCategories; internal static ConfigEntry<bool> ShowUndiscovered; internal static ConfigEntry<string> UndiscoveredText; internal static ConfigEntry<string> CongratsText; internal static ConfigEntry<string> CongratsSoFarText; internal static ConfigEntry<bool> SeasonalPieces; internal static ConfigEntry<bool> SeasonalRecipes; private Harmony _harmony; private void Awake() { //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; TabName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TabName", "Not built", "Label of the build menu tab. Takes effect after restarting the game."); ShowCategories = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCategories", true, "Show the category list (Building, Furniture, ...) on the left of the tab, only with categories that still have unbuilt pieces."); ShowUndiscovered = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowUndiscovered", true, "Show how many pieces of the tool (or selected category) you have not discovered yet."); UndiscoveredText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "UndiscoveredText", "{0} not discovered yet", "Text of the undiscovered indicator; {0} is the number of pieces."); CongratsText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CongratsText", "Congrats! You have built every piece of it!", "Shown in the tab when every piece of the tool has been built."); CongratsSoFarText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CongratsSoFarText", "Congrats! You have built every piece you have discovered so far. There are still more pieces to build that you have not discovered yet!", "Shown in the tab when every discovered piece has been built, but some are still undiscovered."); SeasonalPieces = ((BaseUnityPlugin)this).Config.Bind<bool>("Seasonal", "SeasonalPieces", false, "Seasonal build pieces (Yule, Midsummer, Halloween ...) can be built all year, not only during their event. They then also count in the Not built tab."); SeasonalRecipes = ((BaseUnityPlugin)this).Config.Bind<bool>("Seasonal", "SeasonalRecipes", false, "Seasonal recipes (like the Yule hat and the Midsummer crown) can be crafted all year."); SeasonalPieces.SettingChanged += delegate { Seasons.Apply(); }; SeasonalRecipes.SettingChanged += delegate { Seasons.Apply(); }; _harmony = new Harmony("com.koendertjh.buildtracker"); _harmony.PatchAll(typeof(BuildTrackerPlugin).Assembly); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Seasons.Restore(); } } [HarmonyPatch] internal static class Seasons { private static readonly FieldRef<Player, List<SeasonalItemGroup>> GroupsRef = AccessTools.FieldRefAccess<Player, List<SeasonalItemGroup>>("m_seasonalItemGroups"); private static readonly Dictionary<Recipe, bool> RecipeDefaults = new Dictionary<Recipe, bool>(); private static readonly Dictionary<Piece, bool> PieceDefaults = new Dictionary<Piece, bool>(); [HarmonyPatch(typeof(Player), "Awake")] [HarmonyPostfix] private static void Player_Awake(Player __instance) { List<SeasonalItemGroup> list = GroupsRef.Invoke(__instance); if (list == null) { return; } bool flag = false; foreach (SeasonalItemGroup item in list) { if ((Object)(object)item == (Object)null) { continue; } foreach (Recipe recipe in item.Recipes) { if (!((Object)(object)recipe == (Object)null) && !RecipeDefaults.ContainsKey(recipe)) { RecipeDefaults[recipe] = recipe.m_enabled; flag = true; } } foreach (GameObject piece in item.Pieces) { Piece val = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null); if (!((Object)(object)val == (Object)null) && !PieceDefaults.ContainsKey(val)) { PieceDefaults[val] = val.m_enabled; flag = true; } } } if (flag) { BuildTrackerPlugin.Log.LogInfo((object)$"Seasonal events: {list.Count}, recipes: {RecipeDefaults.Count}, build pieces: {PieceDefaults.Count}"); } Apply(); } public static void Apply() { foreach (KeyValuePair<Recipe, bool> recipeDefault in RecipeDefaults) { if ((Object)(object)recipeDefault.Key != (Object)null) { recipeDefault.Key.m_enabled = recipeDefault.Value || BuildTrackerPlugin.SeasonalRecipes.Value; } } foreach (KeyValuePair<Piece, bool> pieceDefault in PieceDefaults) { if ((Object)(object)pieceDefault.Key != (Object)null) { pieceDefault.Key.m_enabled = pieceDefault.Value || BuildTrackerPlugin.SeasonalPieces.Value; } } } public static void Restore() { foreach (KeyValuePair<Recipe, bool> recipeDefault in RecipeDefaults) { if ((Object)(object)recipeDefault.Key != (Object)null) { recipeDefault.Key.m_enabled = recipeDefault.Value; } } foreach (KeyValuePair<Piece, bool> pieceDefault in PieceDefaults) { if ((Object)(object)pieceDefault.Key != (Object)null) { pieceDefault.Key.m_enabled = pieceDefault.Value; } } } } internal sealed class UnbuiltPieceList : IPieceList { private readonly UsageTagFlags[] _usageTags = (UsageTagFlags[])Enum.GetValues(typeof(UsageTagFlags)); private readonly string[] _usageTagDisplayNames; private readonly List<int> _availableTags = new List<int>(); public string DisplayName { get; } public bool ShowTags => BuildTrackerPlugin.ShowCategories.Value; public bool CanCustomizeTags => false; public int TagCount => _availableTags.Count; public int TagSeparatorIndex => -1; public UnbuiltPieceList(string displayName) { DisplayName = displayName; _usageTagDisplayNames = _usageTags.Select(GetDisplayName).ToArray(); } public string GetTagDisplayName(int index) { return _usageTagDisplayNames[_availableTags[index]]; } public int GetTagIdByIndex(int index) { return _availableTags[index]; } public void UpdateAvailableTags(PieceTable pieceTable) { //IL_0001: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) UsageTagFlags val = (UsageTagFlags)0; foreach (Piece availablePiece in pieceTable.m_availablePieces) { if (!IsSpecial(availablePiece) && !BuiltPieces.IsBuilt(availablePiece)) { val |= availablePiece.m_usage; } } _availableTags.Clear(); for (int i = 0; i < _usageTags.Length; i++) { if (((Enum)val).HasFlag((Enum)(object)_usageTags[i])) { _availableTags.Add(i); } } } public void GetAvailablePiecesWithTag(int tagId, PieceTable pieceTable, IList<Piece> resultOut) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) foreach (Piece availablePiece in pieceTable.m_availablePieces) { if (IsSpecial(availablePiece)) { resultOut.Add(availablePiece); } else if (!BuiltPieces.IsBuilt(availablePiece) && (tagId == -1 || ((Enum)availablePiece.m_usage).HasFlag((Enum)(object)_usageTags[tagId]))) { resultOut.Add(availablePiece); } } } public bool AllDiscoveredBuilt(PieceTable pieceTable) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } foreach (Piece enabledPiece in pieceTable.m_enabledPieces) { bool flag = pieceTable.m_availablePieces.Contains(enabledPiece) || localPlayer.IsRecipeKnown(enabledPiece.m_name); if (!IsSpecial(enabledPiece) && flag && !BuiltPieces.IsBuilt(enabledPiece)) { return false; } } return true; } public int CountUndiscovered(PieceTable pieceTable, int tagId) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0; } HashSet<string> hashSet = new HashSet<string>(); foreach (Piece enabledPiece in pieceTable.m_enabledPieces) { if (!IsSpecial(enabledPiece) && !pieceTable.m_availablePieces.Contains(enabledPiece) && !localPlayer.IsRecipeKnown(enabledPiece.m_name) && (tagId == -1 || ((Enum)enabledPiece.m_usage).HasFlag((Enum)(object)_usageTags[tagId]))) { hashSet.Add(enabledPiece.m_name); } } return hashSet.Count; } private static bool IsSpecial(Piece piece) { if (!piece.m_repairPiece) { return piece.m_removePiece; } return true; } private unsafe static string GetDisplayName(UsageTagFlags flag) { object obj = typeof(UsageTagFlags).GetField(((object)(*(UsageTagFlags*)(&flag))/*cast due to .constrained prefix*/).ToString())?.GetCustomAttributes(inherit: false).FirstOrDefault((object a) => a.GetType().Name == "DisplayNameAttribute"); return (obj?.GetType().GetProperty("DisplayName")?.GetValue(obj) as string) ?? ((object)(*(UsageTagFlags*)(&flag))/*cast due to .constrained prefix*/).ToString(); } } internal static class BuiltPieces { public static bool IsBuilt(Piece piece) { PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (val == null) { return false; } if (val.m_playerStats[0].m_piecesPlacedStats.TryGetValue(piece.m_name, out var value)) { return value > 0f; } return false; } } internal sealed class UndiscoveredLabel { private const float Height = 30f; private readonly GameObject _root; private readonly TMP_Text _text; private readonly TMP_Text _congrats; private readonly RectTransform _viewport; private readonly float _viewportBottom; public UndiscoveredLabel(RectTransform pieceView, ScrollRect scrollRect, TMP_Text styleSource) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_010f: 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_011c: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("BuildTracker_Undiscovered", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val = (RectTransform)_root.transform; ((Transform)val).SetParent((Transform)(object)pieceView, false); val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(1f, 0f); val.pivot = new Vector2(0.5f, 0f); val.sizeDelta = new Vector2(0f, 30f); val.anchoredPosition = Vector2.zero; Image component = _root.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.45f); ((Graphic)component).raycastTarget = false; GameObject val2 = new GameObject("Text", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent((Transform)(object)val, false); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = new Vector2(10f, 0f); val3.offsetMax = new Vector2(-10f, 0f); _text = (TMP_Text)(object)val2.GetComponent<TextMeshProUGUI>(); if ((Object)(object)styleSource != (Object)null) { _text.font = styleSource.font; _text.fontSharedMaterial = styleSource.fontSharedMaterial; } _text.fontSize = 18f; _text.fontStyle = (FontStyles)2; ((Graphic)_text).color = new Color(0.85f, 0.85f, 0.85f, 1f); _text.alignment = (TextAlignmentOptions)514; ((Graphic)_text).raycastTarget = false; GameObject val4 = new GameObject("BuildTracker_Congrats", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); RectTransform val5 = (RectTransform)val4.transform; ((Transform)val5).SetParent((Transform)(object)pieceView, false); val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(20f, 30f); val5.offsetMax = new Vector2(-20f, 0f); _congrats = (TMP_Text)(object)val4.GetComponent<TextMeshProUGUI>(); if ((Object)(object)styleSource != (Object)null) { _congrats.font = styleSource.font; _congrats.fontSharedMaterial = styleSource.fontSharedMaterial; } _congrats.fontSize = 26f; ((Graphic)_congrats).color = new Color(1f, 0.83f, 0.35f, 1f); _congrats.alignment = (TextAlignmentOptions)514; _congrats.textWrappingMode = (TextWrappingModes)1; ((Graphic)_congrats).raycastTarget = false; val4.SetActive(false); RectTransform val6 = (RectTransform)(((Object)(object)scrollRect != (Object)null) ? (((object)scrollRect.viewport) ?? ((object)(RectTransform)((Component)scrollRect).transform)) : null); if ((Object)(object)val6 != (Object)null && (Object)(object)val6 != (Object)(object)pieceView && ((Transform)val6).IsChildOf((Transform)(object)pieceView)) { _viewport = val6; _viewportBottom = val6.offsetMin.y; } _root.SetActive(false); } public void Show(int count) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) bool flag = count > 0; if (flag) { _text.text = Format(count); } _root.SetActive(flag); _root.transform.SetAsLastSibling(); if ((Object)(object)_viewport != (Object)null) { _viewport.offsetMin = new Vector2(_viewport.offsetMin.x, _viewportBottom + (flag ? 30f : 0f)); } } public void ShowCongrats(string message) { if (message != null) { _congrats.text = message; } ((Component)_congrats).gameObject.SetActive(message != null); _congrats.transform.SetAsLastSibling(); } public void Hide() { Show(0); ShowCongrats(null); } private static string Format(int count) { try { return string.Format(BuildTrackerPlugin.UndiscoveredText.Value, count); } catch (FormatException) { return count + " not discovered yet"; } } } internal static class PluginInfo { public const string Version = "1.1.0"; } }