Decompiled source of CraftTracker v1.0.1

CraftTracker.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
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("CraftTracker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+0f0d523791a500ca0b0597e99db8332ce33340fa")]
[assembly: AssemblyProduct("CraftTracker")]
[assembly: AssemblyTitle("CraftTracker")]
[assembly: AssemblyVersion("1.0.1.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 CraftTracker
{
	internal static class CraftedItems
	{
		public static bool IsCrafted(Recipe recipe)
		{
			PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null);
			if (val == null)
			{
				return false;
			}
			if (val.m_playerStats[0].m_itemCraftStats.TryGetValue(NameOf(recipe), out var value))
			{
				return value > 0f;
			}
			return false;
		}

		public static string NameOf(Recipe recipe)
		{
			return recipe.m_item.m_itemData.m_shared.m_name;
		}

		public static int CountUndiscovered(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || player.NoCostCheat() || ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)28)))
			{
				return 0;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				bool flag = (Object)(object)player.CurrentSeason != (Object)null && player.CurrentSeason.Recipes.Contains(recipe);
				if ((recipe.m_enabled || flag) && Object.op_Implicit((Object)(object)recipe.m_item) && !recipe.m_noCraftOnlyUpgrade)
				{
					string text = NameOf(recipe);
					string dlc = recipe.m_item.m_itemData.m_shared.m_dlc;
					if ((string.IsNullOrEmpty(dlc) || DLCMan.instance.IsDLCInstalled(dlc)) && !player.IsRecipeKnown(text) && player.RequiredCraftingStation(recipe, 1, false))
					{
						hashSet.Add(text);
					}
				}
			}
			return hashSet.Count;
		}
	}
	[HarmonyPatch(typeof(InventoryGui))]
	internal static class CraftingPatches
	{
		private static readonly MethodInfo UpdateCraftingPanelMethod = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null);

		private static readonly MethodInfo SetActiveGroupMethod = AccessTools.Method(typeof(InventoryGui), "SetActiveGroup", new Type[2]
		{
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private const int CraftingGroup = 3;

		private static Button s_tab;

		private static StatusOverlay s_overlay;

		private static bool s_active;

		private static bool s_refreshPending;

		private static bool s_manualLayout;

		private static Vector2 s_slotAfterUpgrade;

		private static Vector2 s_slotUpgrade;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(InventoryGui __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0099: 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_00a8: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			s_active = false;
			s_refreshPending = false;
			RectTransform val = (RectTransform)((Component)__instance.m_tabCraft).transform;
			RectTransform val2 = (RectTransform)((Component)__instance.m_tabUpgrade).transform;
			RectTransform val3 = Object.Instantiate<RectTransform>(val2, ((Transform)val2).parent);
			((Object)val3).name = "CraftTracker_NotCraftedTab";
			((Transform)val3).SetSiblingIndex(((Transform)val2).GetSiblingIndex() + 1);
			s_manualLayout = (Object)(object)((Component)((Transform)val2).parent).GetComponent<LayoutGroup>() == (Object)null;
			s_slotUpgrade = val2.anchoredPosition;
			s_slotAfterUpgrade = val2.anchoredPosition + (val2.anchoredPosition - val.anchoredPosition);
			if (s_manualLayout)
			{
				val3.anchoredPosition = s_slotAfterUpgrade;
			}
			TMP_Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<TMP_Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].text = CraftTrackerPlugin.TabName.Value.ToUpperInvariant();
			}
			s_tab = ((Component)val3).GetComponent<Button>();
			s_tab.onClick = new ButtonClickedEvent();
			((UnityEvent)s_tab.onClick).AddListener((UnityAction)delegate
			{
				OnNotCraftedPressed(__instance);
			});
			((Selectable)s_tab).interactable = true;
			s_overlay = new StatusOverlay((RectTransform)((Transform)__instance.m_recipeListRoot).parent, ((Component)__instance.m_tabCraft).GetComponentInChildren<TMP_Text>(true));
		}

		private static void OnNotCraftedPressed(InventoryGui gui)
		{
			s_active = true;
			if (gui.m_uiGroups.Length > 3)
			{
				SetActiveGroupMethod?.Invoke(gui, new object[2] { 3, true });
			}
			UpdateCraftingPanel(gui);
		}

		private static void UpdateCraftingPanel(InventoryGui gui)
		{
			UpdateCraftingPanelMethod.Invoke(gui, new object[1] { false });
		}

		private static bool IsActive(InventoryGui gui)
		{
			if (s_active)
			{
				return ((Component)gui.m_tabCraft).gameObject.activeSelf;
			}
			return false;
		}

		[HarmonyPatch("OnTabCraftPressed")]
		[HarmonyPrefix]
		private static void OnTabCraftPressed_Prefix()
		{
			s_active = false;
		}

		[HarmonyPatch("OnTabUpgradePressed")]
		[HarmonyPrefix]
		private static void OnTabUpgradePressed_Prefix()
		{
			s_active = false;
		}

		[HarmonyPatch("InCraftTab")]
		[HarmonyPostfix]
		private static void InCraftTab_Postfix(InventoryGui __instance, ref bool __result)
		{
			if (IsActive(__instance))
			{
				__result = true;
			}
		}

		[HarmonyPatch("UpdateCraftingPanel")]
		[HarmonyPostfix]
		private static void UpdateCraftingPanel_Postfix(InventoryGui __instance)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			if (!((Object)(object)s_tab == (Object)null))
			{
				bool activeSelf = ((Component)__instance.m_tabCraft).gameObject.activeSelf;
				((Component)s_tab).gameObject.SetActive(activeSelf);
				if (!activeSelf)
				{
					s_active = false;
				}
				if (s_manualLayout)
				{
					((RectTransform)((Component)s_tab).transform).anchoredPosition = (((Component)__instance.m_tabUpgrade).gameObject.activeSelf ? s_slotAfterUpgrade : s_slotUpgrade);
				}
				if (s_active)
				{
					((Selectable)__instance.m_tabCraft).interactable = true;
					((Selectable)__instance.m_tabUpgrade).interactable = true;
				}
				((Selectable)s_tab).interactable = !s_active;
			}
		}

		[HarmonyPatch("UpdateRecipeList")]
		[HarmonyPrefix]
		private static void UpdateRecipeList_Prefix(InventoryGui __instance, List<Recipe> recipes)
		{
			if (IsActive(__instance))
			{
				recipes.RemoveAll((Recipe r) => r.m_noCraftOnlyUpgrade || CraftedItems.IsCrafted(r));
			}
		}

		[HarmonyPatch("UpdateRecipeList")]
		[HarmonyPostfix]
		private static void UpdateRecipeList_Postfix(InventoryGui __instance, List<Recipe> recipes)
		{
			//IL_0099: 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)
			if (s_overlay == null)
			{
				return;
			}
			if (!IsActive(__instance))
			{
				s_overlay.Hide();
				return;
			}
			int num = CraftedItems.CountUndiscovered(Player.m_localPlayer);
			s_overlay.ShowUndiscovered(CraftTrackerPlugin.ShowUndiscovered.Value ? num : 0);
			s_overlay.ShowCongrats((recipes.Count > 0) ? null : ((num == 0) ? CraftTrackerPlugin.CongratsText.Value : CraftTrackerPlugin.CongratsSoFarText.Value));
			if (s_overlay.BarVisible)
			{
				RectTransform recipeListRoot = __instance.m_recipeListRoot;
				float num2 = (float)recipes.Count * __instance.m_recipeListSpace + 30f;
				Rect rect = recipeListRoot.rect;
				if (num2 > ((Rect)(ref rect)).height)
				{
					recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, num2);
				}
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void Update_Postfix(InventoryGui __instance)
		{
			if (s_refreshPending)
			{
				s_refreshPending = false;
				if (IsActive(__instance) && InventoryGui.IsVisible())
				{
					UpdateCraftingPanel(__instance);
				}
			}
		}

		internal static void RequestRefresh()
		{
			s_refreshPending = true;
		}
	}
	[HarmonyPatch(typeof(PlayerProfile), "IncrementStatItemCraft")]
	internal static class ItemCraftedPatch
	{
		private static void Postfix()
		{
			CraftingPatches.RequestRefresh();
		}
	}
	[BepInPlugin("com.koendertjh.crafttracker", "CraftTracker", "1.0.1")]
	public class CraftTrackerPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.koendertjh.crafttracker";

		public const string ModName = "CraftTracker";

		public const string ModVersion = "1.0.1";

		internal static ConfigEntry<string> TabName;

		internal static ConfigEntry<bool> ShowUndiscovered;

		internal static ConfigEntry<string> UndiscoveredText;

		internal static ConfigEntry<string> CongratsText;

		internal static ConfigEntry<string> CongratsSoFarText;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			TabName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TabName", "Not crafted", "Label of the crafting tab. Takes effect after restarting the game.");
			ShowUndiscovered = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowUndiscovered", true, "Show how many recipes of this station 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 recipes.");
			CongratsText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CongratsText", "Congrats! You have crafted every item of it!", "Shown in the tab when every recipe of the station has been crafted.");
			CongratsSoFarText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CongratsSoFarText", "Congrats! You have crafted every item you have discovered so far. There are still more items to craft that you have not discovered yet!", "Shown in the tab when every discovered recipe has been crafted, but some are still undiscovered.");
			_harmony = new Harmony("com.koendertjh.crafttracker");
			_harmony.PatchAll(typeof(CraftTrackerPlugin).Assembly);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal sealed class StatusOverlay
	{
		public const float BarHeight = 30f;

		private readonly GameObject _bar;

		private readonly TMP_Text _barText;

		private readonly TMP_Text _congrats;

		public bool BarVisible => _bar.activeSelf;

		public StatusOverlay(RectTransform parent, 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			_bar = new GameObject("CraftTracker_Undiscovered", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val = (RectTransform)_bar.transform;
			((Transform)val).SetParent((Transform)(object)parent, 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 = _bar.GetComponent<Image>();
			((Graphic)component).color = new Color(0f, 0f, 0f, 0.45f);
			((Graphic)component).raycastTarget = false;
			_barText = CreateText(val, "Text", styleSource, 18f, new Color(0.85f, 0.85f, 0.85f, 1f));
			_barText.fontStyle = (FontStyles)2;
			RectTransform val2 = (RectTransform)_barText.transform;
			val2.offsetMin = new Vector2(10f, 0f);
			val2.offsetMax = new Vector2(-10f, 0f);
			_congrats = CreateText(parent, "CraftTracker_Congrats", styleSource, 24f, new Color(1f, 0.83f, 0.35f, 1f));
			RectTransform val3 = (RectTransform)_congrats.transform;
			val3.offsetMin = new Vector2(20f, 30f);
			val3.offsetMax = new Vector2(-20f, 0f);
			_congrats.textWrappingMode = (TextWrappingModes)1;
			_bar.SetActive(false);
			((Component)_congrats).gameObject.SetActive(false);
		}

		public void ShowUndiscovered(int count)
		{
			if (count > 0)
			{
				_barText.text = Format(count);
			}
			_bar.SetActive(count > 0);
			_bar.transform.SetAsLastSibling();
		}

		public void ShowCongrats(string message)
		{
			if (message != null)
			{
				_congrats.text = message;
			}
			((Component)_congrats).gameObject.SetActive(message != null);
			_congrats.transform.SetAsLastSibling();
		}

		public void Hide()
		{
			ShowUndiscovered(0);
			ShowCongrats(null);
		}

		private static TMP_Text CreateText(RectTransform parent, string name, TMP_Text styleSource, float size, Color color)
		{
			//IL_0021: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_003a: 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_0045: 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_0050: 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)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)parent, false);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			TMP_Text component = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)styleSource != (Object)null)
			{
				component.font = styleSource.font;
				component.fontSharedMaterial = styleSource.fontSharedMaterial;
			}
			component.fontSize = size;
			((Graphic)component).color = color;
			component.alignment = (TextAlignmentOptions)514;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private static string Format(int count)
		{
			try
			{
				return string.Format(CraftTrackerPlugin.UndiscoveredText.Value, count);
			}
			catch (FormatException)
			{
				return count + " not discovered yet";
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Version = "1.0.1";
	}
}