Decompiled source of DadsEZCrafting v1.0.0

DadsEZCrafting.dll

Decompiled a month ago
using 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.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("DadsEZCrafting")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+19e798672f4bf44f0cb043cd0827426dc5b2fc7c")]
[assembly: AssemblyProduct("DadsEZCrafting")]
[assembly: AssemblyTitle("DadsEZCrafting")]
[assembly: AssemblyVersion("1.0.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 DadsEZCrafting
{
	internal static class CraftingPatches
	{
		internal static void Install(Harmony harmony)
		{
			Patch(harmony, AccessTools.Method(typeof(InventoryGui), "Awake", (Type[])null, (Type[])null), "InventoryGuiAwakePostfix", prefix: false);
			Patch(harmony, AccessTools.Method(typeof(InventoryGui), "UpdateRecipeList", new Type[1] { typeof(List<Recipe>) }, (Type[])null), "UpdateRecipeListPrefix", prefix: true);
			Patch(harmony, AccessTools.Method(typeof(InventoryGui), "OnCraftPressed", (Type[])null, (Type[])null), "OnCraftPressedPrefix", prefix: true);
		}

		private static void Patch(Harmony harmony, MethodBase original, string patchName, bool prefix)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if (original == null)
			{
				DadsEZCraftingPlugin.ModLog.LogError((object)("Required Valheim method was not found for " + patchName + "; no invalid Harmony patch was applied."));
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(CraftingPatches), patchName, (Type[])null);
			harmony.Patch(original, prefix ? val : null, prefix ? null : val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void InventoryGuiAwakePostfix(InventoryGui __instance)
		{
			CraftingUiManager.Attach(__instance);
		}

		private static void UpdateRecipeListPrefix(List<Recipe> recipes)
		{
			ConfigEntry<bool> enabled = DadsEZCraftingPlugin.Enabled;
			if (enabled != null && enabled.Value)
			{
				RecipeFilterState.Apply(recipes);
			}
		}

		private static void OnCraftPressedPrefix(InventoryGui __instance)
		{
			CraftingUiManager.PrepareCrafting(__instance);
		}
	}
	internal sealed class CraftingUiManager : MonoBehaviour
	{
		private sealed class DropdownChoice
		{
			internal string Label;

			internal Action Select;
		}

		private const float ToolbarHeight = 92f;

		private const int MaximumCraftQuantity = 9999;

		private static readonly MethodInfo UpdateCraftingPanelMethod = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly FieldInfo SelectedRecipeField = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe");

		private static readonly FieldInfo MultiCraftAmountField = AccessTools.Field(typeof(InventoryGui), "m_multiCraftAmount");

		private static readonly FieldInfo TouchMultiCraftingField = AccessTools.Field(typeof(InventoryGui), "m_touchMultiCrafting");

		private static readonly FieldInfo SelectedRecipeValueField = AccessTools.Field(SelectedRecipeField.FieldType, "<Recipe>k__BackingField");

		private static readonly FieldInfo SelectedItemDataValueField = AccessTools.Field(SelectedRecipeField.FieldType, "<ItemData>k__BackingField");

		private InventoryGui _gui;

		private RectTransform _viewport;

		private Vector2 _originalViewportOffsetMax;

		private RectTransform _toolbar;

		private TMP_InputField _search;

		private Button _categoryButton;

		private Button _tierButton;

		private Button _sortButton;

		private TMP_Text _categoryLabel;

		private TMP_Text _tierLabel;

		private TMP_Text _sortLabel;

		private GameObject _categoryMenu;

		private GameObject _tierMenu;

		private RectTransform _craftControls;

		private TMP_Text _quantityLabel;

		private Button _minusButton;

		private Button _plusButton;

		private Button _maxButton;

		private Recipe _lastSelectedRecipe;

		private ItemData _lastUpgradeItem;

		private int _craftQuantity = 1;

		internal static CraftingUiManager Instance { get; private set; }

		internal static void Attach(InventoryGui gui)
		{
			if (!((Object)(object)gui == (Object)null))
			{
				CraftingUiManager craftingUiManager = ((Component)gui).GetComponent<CraftingUiManager>();
				if ((Object)(object)craftingUiManager == (Object)null)
				{
					craftingUiManager = ((Component)gui).gameObject.AddComponent<CraftingUiManager>();
				}
				craftingUiManager.Initialize(gui);
			}
		}

		internal static void RefreshRecipes()
		{
			if (!((Object)(object)Instance?._gui == (Object)null) && !(UpdateCraftingPanelMethod == null))
			{
				UpdateCraftingPanelMethod.Invoke(Instance._gui, new object[1] { false });
			}
		}

		internal static void PrepareCrafting(InventoryGui gui)
		{
			if (!((Object)(object)Instance == (Object)null) && !((Object)(object)gui != (Object)(object)Instance._gui))
			{
				bool flag = Instance._craftQuantity > 1 && GetSelectedItemData(gui) == null;
				MultiCraftAmountField.SetValue(gui, (!flag) ? 1 : Instance._craftQuantity);
				TouchMultiCraftingField.SetValue(gui, flag);
			}
		}

		private void Initialize(InventoryGui gui)
		{
			if (!((Object)(object)_gui != (Object)null))
			{
				_gui = gui;
				Instance = this;
				BuildToolbar();
				BuildCraftControls();
				RefreshLabels();
			}
		}

		private void BuildToolbar()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00bb: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Expected O, but got Unknown
			RectTransform recipeListRoot = _gui.m_recipeListRoot;
			_viewport = (RectTransform)(((Object)(object)recipeListRoot == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/);
			if ((Object)(object)_viewport == (Object)null || (Object)(object)((Transform)_viewport).parent == (Object)null)
			{
				DadsEZCraftingPlugin.ModLog.LogError((object)"The native recipe-list viewport was not found; filtering remains active without the toolbar.");
				return;
			}
			_originalViewportOffsetMax = _viewport.offsetMax;
			_viewport.offsetMax = new Vector2(_originalViewportOffsetMax.x, _originalViewportOffsetMax.y - 92f - 4f);
			GameObject val = new GameObject("DadsEZCrafting_FilterToolbar", new Type[1] { typeof(RectTransform) });
			_toolbar = val.GetComponent<RectTransform>();
			((Transform)_toolbar).SetParent(((Transform)_viewport).parent, false);
			_toolbar.anchorMin = new Vector2(_viewport.anchorMin.x, _viewport.anchorMax.y);
			_toolbar.anchorMax = new Vector2(_viewport.anchorMax.x, _viewport.anchorMax.y);
			_toolbar.pivot = new Vector2(0.5f, 1f);
			_toolbar.offsetMin = new Vector2(_viewport.offsetMin.x, _originalViewportOffsetMax.y - 92f);
			_toolbar.offsetMax = new Vector2(_viewport.offsetMax.x, _originalViewportOffsetMax.y);
			((Transform)_toolbar).SetAsLastSibling();
			_search = CreateSearchField((Transform)(object)_toolbar);
			SetRow(((Component)_search).GetComponent<RectTransform>(), 0f, 1f, 0f, 28f);
			((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate(string value)
			{
				RecipeFilterState.Search = value ?? string.Empty;
				RefreshRecipes();
			});
			_categoryButton = CreateNativeButton((Transform)(object)_toolbar, "Category", out _categoryLabel);
			SetRow(((Component)_categoryButton).GetComponent<RectTransform>(), 0f, 0.5f, 32f, 28f, 0f, -2f);
			((UnityEvent)_categoryButton.onClick).AddListener((UnityAction)delegate
			{
				ToggleMenu(_categoryMenu, _tierMenu);
			});
			_tierButton = CreateNativeButton((Transform)(object)_toolbar, "Tier", out _tierLabel);
			SetRow(((Component)_tierButton).GetComponent<RectTransform>(), 0.5f, 1f, 32f, 28f, 2f);
			((UnityEvent)_tierButton.onClick).AddListener((UnityAction)delegate
			{
				ToggleMenu(_tierMenu, _categoryMenu);
			});
			_sortButton = CreateNativeButton((Transform)(object)_toolbar, "Sort", out _sortLabel);
			SetRow(((Component)_sortButton).GetComponent<RectTransform>(), 0f, 1f, 64f, 28f);
			((UnityEvent)_sortButton.onClick).AddListener((UnityAction)delegate
			{
				RecipeFilterState.NextSort();
				RefreshLabels();
				RefreshRecipes();
			});
			_categoryMenu = CreateDropdownMenu(_categoryButton, "CategoryMenu", Array.ConvertAll(RecipeFilterState.Categories, (RecipeCategory value) => new DropdownChoice
			{
				Label = CategoryLabel(value),
				Select = delegate
				{
					RecipeFilterState.SetCategory(value);
					CloseMenus();
					RefreshLabels();
					RefreshRecipes();
				}
			}));
			_tierMenu = CreateDropdownMenu(_tierButton, "TierMenu", Array.ConvertAll(RecipeFilterState.Tiers, (ProgressionTier value) => new DropdownChoice
			{
				Label = TierLabel(value),
				Select = delegate
				{
					RecipeFilterState.SetTier(value);
					CloseMenus();
					RefreshLabels();
					RefreshRecipes();
				}
			}));
		}

		private void BuildCraftControls()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			RectTransform val = (((Object)(object)_gui.m_craftButton == (Object)null) ? null : ((Component)_gui.m_craftButton).GetComponent<RectTransform>());
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Transform)val).parent == (Object)null))
			{
				GameObject val2 = new GameObject("DadsEZCrafting_CraftControls", new Type[1] { typeof(RectTransform) });
				_craftControls = val2.GetComponent<RectTransform>();
				((Transform)_craftControls).SetParent(((Transform)val).parent, false);
				((Transform)_craftControls).SetSiblingIndex(((Transform)val).GetSiblingIndex());
				CopyRect(val, _craftControls);
				((Transform)val).SetParent((Transform)(object)_craftControls, false);
				SetSlice(val, 0.48f, 1f, 2f, 0f);
				RectTransform component = new GameObject("QuantitySelector", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)_craftControls, false);
				SetSlice(component, 0f, 0.46f, 0f, -2f);
				_minusButton = CreateNativeButton((Transform)(object)component, "QuantityMinus", out var label);
				label.text = "-";
				SetSlice(((Component)_minusButton).GetComponent<RectTransform>(), 0f, 0.18f, 0f, -1f);
				((UnityEvent)_minusButton.onClick).AddListener((UnityAction)delegate
				{
					ChangeQuantity(-ModifierStep());
				});
				Button obj = CreateNativeButton((Transform)(object)component, "Quantity", out _quantityLabel);
				((Behaviour)obj).enabled = false;
				SetSlice(((Component)obj).GetComponent<RectTransform>(), 0.18f, 0.43f, 1f, -1f);
				_plusButton = CreateNativeButton((Transform)(object)component, "QuantityPlus", out var label2);
				label2.text = "+";
				SetSlice(((Component)_plusButton).GetComponent<RectTransform>(), 0.43f, 0.61f, 1f, -1f);
				((UnityEvent)_plusButton.onClick).AddListener((UnityAction)delegate
				{
					ChangeQuantity(ModifierStep());
				});
				_maxButton = CreateNativeButton((Transform)(object)component, "QuantityMax", out var label3);
				label3.text = "Max";
				SetSlice(((Component)_maxButton).GetComponent<RectTransform>(), 0.61f, 1f, 1f, 0f);
				((UnityEvent)_maxButton.onClick).AddListener(new UnityAction(SetMaximumQuantity));
				_lastSelectedRecipe = GetSelectedRecipe(_gui);
				_lastUpgradeItem = GetSelectedItemData(_gui);
				RefreshQuantityControls();
			}
		}

		private GameObject CreateDropdownMenu(Button owner, string name, IReadOnlyList<DropdownChoice> choices)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			GameObject val = new GameObject("DadsEZCrafting_" + name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent(((Component)owner).transform, false);
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(0.5f, 1f);
			component.offsetMin = new Vector2(0f, -27f * (float)choices.Count);
			component.offsetMax = Vector2.zero;
			Image component2 = val.GetComponent<Image>();
			CopyNativeImage(((Component)_gui.m_craftButton).GetComponent<Image>(), component2);
			((Graphic)component2).color = new Color(0.16f, 0.13f, 0.11f, 1f);
			for (int i = 0; i < choices.Count; i++)
			{
				DropdownChoice choice = choices[i];
				TMP_Text label;
				Button obj = CreateNativeButton((Transform)(object)component, name + "_" + i, out label);
				label.text = choice.Label;
				RectTransform component3 = ((Component)obj).GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0f, 1f);
				component3.anchorMax = new Vector2(1f, 1f);
				component3.pivot = new Vector2(0.5f, 1f);
				component3.offsetMin = new Vector2(2f, -27f * (float)(i + 1) + 1f);
				component3.offsetMax = new Vector2(-2f, -27f * (float)i - 1f);
				((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
				{
					choice.Select();
				});
			}
			val.SetActive(false);
			return val;
		}

		private TMP_InputField CreateSearchField(Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("DadsEZCrafting_Search", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(TMP_InputField)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			CopyNativeImage(((Component)_gui.m_craftButton).GetComponent<Image>(), component);
			((Graphic)component).color = new Color(0.3f, 0.25f, 0.21f, 0.98f);
			GameObject val2 = new GameObject("Text Area", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform val3 = (RectTransform)val2.transform;
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = new Vector2(8f, 2f);
			val3.offsetMax = new Vector2(-8f, -2f);
			TextMeshProUGUI val4 = CreateInputText((Transform)(object)val3, "Placeholder", new Color(0.72f, 0.68f, 0.62f, 0.78f));
			((TMP_Text)val4).text = "Search recipes...";
			((TMP_Text)val4).fontStyle = (FontStyles)2;
			TextMeshProUGUI textComponent = CreateInputText((Transform)(object)val3, "Text", new Color(1f, 0.72f, 0.36f, 1f));
			TMP_InputField component2 = val.GetComponent<TMP_InputField>();
			component2.textViewport = val3;
			component2.textComponent = (TMP_Text)(object)textComponent;
			component2.placeholder = (Graphic)(object)val4;
			((Selectable)component2).targetGraphic = (Graphic)(object)component;
			component2.lineType = (LineType)0;
			component2.characterLimit = 80;
			return component2;
		}

		private TextMeshProUGUI CreateInputText(Transform parent, string name, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0034: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).font = _gui.m_recipeName.font;
			((TMP_Text)obj).fontSize = 15f;
			((Graphic)obj).color = color;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
			((Graphic)obj).raycastTarget = false;
			val.SetActive(true);
			return obj;
		}

		private Button CreateNativeButton(Transform parent, string name, out TMP_Text label)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)_gui.m_craftButton).gameObject, parent, false);
			((Object)val).name = "DadsEZCrafting_" + name;
			val.SetActive(true);
			Button component = val.GetComponent<Button>();
			((UnityEventBase)component.onClick).RemoveAllListeners();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component).navigation = navigation;
			label = val.GetComponentInChildren<TMP_Text>(true);
			label.enableAutoSizing = true;
			label.fontSizeMin = 9f;
			label.fontSizeMax = 14f;
			label.alignment = (TextAlignmentOptions)514;
			label.textWrappingMode = (TextWrappingModes)0;
			label.overflowMode = (TextOverflowModes)1;
			((Graphic)label).raycastTarget = false;
			label.rectTransform.anchorMin = Vector2.zero;
			label.rectTransform.anchorMax = Vector2.one;
			label.rectTransform.offsetMin = new Vector2(4f, 1f);
			label.rectTransform.offsetMax = new Vector2(-4f, -1f);
			return component;
		}

		private void RefreshLabels()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_categoryLabel == (Object)null))
			{
				_categoryLabel.text = "Type: " + RecipeFilterState.CategoryLabel() + "  v";
				_tierLabel.text = "Tier: " + RecipeFilterState.TierLabel() + "  v";
				_sortLabel.text = "Sort: " + RecipeFilterState.SortLabel();
				Color white = Color.white;
				Color val = default(Color);
				((Color)(ref val))..ctor(1f, 0.72f, 0.36f, 1f);
				((Graphic)_categoryLabel).color = ((RecipeFilterState.Category == RecipeCategory.All) ? white : val);
				((Graphic)_tierLabel).color = ((RecipeFilterState.Tier == ProgressionTier.All) ? white : val);
				((Graphic)_sortLabel).color = ((RecipeFilterState.Sort == RecipeSort.Native) ? white : val);
			}
		}

		private void Update()
		{
			if (!((Object)(object)_gui == (Object)null))
			{
				Recipe selectedRecipe = GetSelectedRecipe(_gui);
				ItemData selectedItemData = GetSelectedItemData(_gui);
				if ((Object)(object)selectedRecipe != (Object)(object)_lastSelectedRecipe || selectedItemData != _lastUpgradeItem)
				{
					_lastSelectedRecipe = selectedRecipe;
					_lastUpgradeItem = selectedItemData;
					_craftQuantity = 1;
					RefreshQuantityControls();
				}
				PrepareCrafting(_gui);
				if (Input.GetKeyDown((KeyCode)27))
				{
					CloseMenus();
				}
				if (Input.GetMouseButtonDown(0) && !PointerInside((Component)(object)_categoryButton) && !PointerInside((Component)(object)_tierButton) && !PointerInside((Component)(object)(((Object)(object)_categoryMenu == (Object)null) ? null : _categoryMenu.transform)) && !PointerInside((Component)(object)(((Object)(object)_tierMenu == (Object)null) ? null : _tierMenu.transform)))
				{
					CloseMenus();
				}
			}
		}

		private void ChangeQuantity(int delta)
		{
			if (CanSelectQuantity())
			{
				_craftQuantity = Mathf.Clamp(_craftQuantity + delta, 1, 9999);
				RefreshQuantityControls();
				RefreshRecipes();
			}
		}

		private void SetMaximumQuantity()
		{
			if (!CanSelectQuantity())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			Recipe selectedRecipe = GetSelectedRecipe(_gui);
			int num = 1;
			int num2 = 0;
			int num3 = 1;
			while (num3 < 9999 && localPlayer.HaveRequirements(selectedRecipe, false, num, num3))
			{
				num2 = num3;
				num3 = Math.Min(9999, num3 * 2);
				if (num3 == num2)
				{
					break;
				}
			}
			while (num2 + 1 < num3)
			{
				int num4 = num2 + (num3 - num2) / 2;
				if (localPlayer.HaveRequirements(selectedRecipe, false, num, num4))
				{
					num2 = num4;
				}
				else
				{
					num3 = num4;
				}
			}
			if (num3 == 9999 && localPlayer.HaveRequirements(selectedRecipe, false, num, num3))
			{
				num2 = num3;
			}
			_craftQuantity = Mathf.Max(1, num2);
			RefreshQuantityControls();
			RefreshRecipes();
		}

		private bool CanSelectQuantity()
		{
			if ((Object)(object)_gui != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)GetSelectedRecipe(_gui) != (Object)null)
			{
				return GetSelectedItemData(_gui) == null;
			}
			return false;
		}

		private void RefreshQuantityControls()
		{
			if (!((Object)(object)_quantityLabel == (Object)null))
			{
				bool flag = CanSelectQuantity();
				_quantityLabel.text = _craftQuantity.ToString();
				((Selectable)_minusButton).interactable = flag && _craftQuantity > 1;
				((Selectable)_plusButton).interactable = flag && _craftQuantity < 9999;
				((Selectable)_maxButton).interactable = flag;
			}
		}

		private static int ModifierStep()
		{
			if (!Input.GetKey((KeyCode)306))
			{
				return 1;
			}
			return 10;
		}

		private static object GetSelectedPair(InventoryGui gui)
		{
			if (!((Object)(object)gui == (Object)null))
			{
				return SelectedRecipeField.GetValue(gui);
			}
			return null;
		}

		private static Recipe GetSelectedRecipe(InventoryGui gui)
		{
			object selectedPair = GetSelectedPair(gui);
			if (selectedPair != null)
			{
				object? value = SelectedRecipeValueField.GetValue(selectedPair);
				return (Recipe)((value is Recipe) ? value : null);
			}
			return null;
		}

		private static ItemData GetSelectedItemData(InventoryGui gui)
		{
			object selectedPair = GetSelectedPair(gui);
			if (selectedPair != null)
			{
				object? value = SelectedItemDataValueField.GetValue(selectedPair);
				return (ItemData)((value is ItemData) ? value : null);
			}
			return null;
		}

		private void ToggleMenu(GameObject menu, GameObject other)
		{
			if (!((Object)(object)menu == (Object)null))
			{
				if ((Object)(object)other != (Object)null)
				{
					other.SetActive(false);
				}
				bool flag = !menu.activeSelf;
				menu.SetActive(flag);
				if (flag)
				{
					menu.transform.parent.SetAsLastSibling();
				}
			}
		}

		private void CloseMenus()
		{
			if ((Object)(object)_categoryMenu != (Object)null)
			{
				_categoryMenu.SetActive(false);
			}
			if ((Object)(object)_tierMenu != (Object)null)
			{
				_tierMenu.SetActive(false);
			}
		}

		private static bool PointerInside(Component component)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)component == (Object)null || !component.gameObject.activeInHierarchy)
			{
				return false;
			}
			RectTransform component2 = component.GetComponent<RectTransform>();
			if ((Object)(object)component2 != (Object)null)
			{
				return RectTransformUtility.RectangleContainsScreenPoint(component2, Vector2.op_Implicit(Input.mousePosition));
			}
			return false;
		}

		private static string CategoryLabel(RecipeCategory category)
		{
			if (category != RecipeCategory.Ammunition)
			{
				return category.ToString();
			}
			return "Ammo / Throwables";
		}

		private static string TierLabel(ProgressionTier tier)
		{
			return tier switch
			{
				ProgressionTier.All => "All Tiers", 
				ProgressionTier.BlackForest => "Black Forest", 
				ProgressionTier.DeepNorth => "Deep North", 
				_ => tier.ToString(), 
			};
		}

		private static void CopyNativeImage(Image source, Image target)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
			{
				target.sprite = source.sprite;
				target.overrideSprite = source.overrideSprite;
				((Graphic)target).material = ((Graphic)source).material;
				target.type = source.type;
				target.preserveAspect = source.preserveAspect;
				target.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier;
			}
		}

		private static void SetRow(RectTransform rect, float minX, float maxX, float top, float height, float left = 0f, float right = 0f)
		{
			//IL_0007: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(minX, 1f);
			rect.anchorMax = new Vector2(maxX, 1f);
			rect.pivot = new Vector2(0.5f, 1f);
			rect.offsetMin = new Vector2(left, 0f - top - height);
			rect.offsetMax = new Vector2(right, 0f - top);
		}

		private static void SetSlice(RectTransform rect, float minX, float maxX, float left, float right)
		{
			//IL_0007: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(minX, 0f);
			rect.anchorMax = new Vector2(maxX, 1f);
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = new Vector2(left, 0f);
			rect.offsetMax = new Vector2(right, 0f);
			((Transform)rect).localScale = Vector3.one;
		}

		private static void CopyRect(RectTransform source, RectTransform target)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			target.anchorMin = source.anchorMin;
			target.anchorMax = source.anchorMax;
			target.pivot = source.pivot;
			target.anchoredPosition = source.anchoredPosition;
			target.sizeDelta = source.sizeDelta;
			((Transform)target).localScale = ((Transform)source).localScale;
			((Transform)target).localRotation = ((Transform)source).localRotation;
		}

		private void OnDestroy()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_viewport != (Object)null)
			{
				_viewport.offsetMax = _originalViewportOffsetMax;
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	[BepInPlugin("com.dadisbored.dadsezcrafting", "DadsEZCrafting", "1.0.0")]
	[BepInProcess("valheim.exe")]
	public sealed class DadsEZCraftingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dadisbored.dadsezcrafting";

		public const string PluginName = "DadsEZCrafting";

		public const string PluginVersion = "1.0.0";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> BlackForestHints;

		internal static ConfigEntry<string> SwampHints;

		internal static ConfigEntry<string> MountainHints;

		internal static ConfigEntry<string> PlainsHints;

		internal static ConfigEntry<string> MistlandsHints;

		internal static ConfigEntry<string> AshlandsHints;

		internal static ConfigEntry<string> DeepNorthHints;

		internal static ManualLogSource ModLog;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			ModLog = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable native crafting-menu search, filtering, and sorting.");
			BlackForestHints = BindTier("Black Forest", "Copper,CopperOre,Tin,TinOre,Bronze,BronzeNails,CoreWood,TrollHide,SurtlingCore,AncientSeed");
			SwampHints = BindTier("Swamps", "Iron,IronScrap,IronOre,IronNails,AncientBark,Guck,Root,Bloodbag,Entrails,WitheredBone,Chain,Ooze,Turnip");
			MountainHints = BindTier("Mountain", "Silver,SilverOre,WolfPelt,WolfFang,WolfClaw,WolfHairBundle,FreezeGland,Crystal,Obsidian,DragonTear,Onion,JuteRed,Fenring");
			PlainsHints = BindTier("Plains", "BlackMetal,BlackMetalScrap,LinenThread,Flax,Barley,BarleyFlour,Tar,LoxPelt,LoxMeat,Needle,Cloudberry,GoblinTotem,VileRibcage");
			MistlandsHints = BindTier("Mistlands", "Blackmarble,YggdrasilWood,Sap,Softtissue,Eitr,Carapace,Mandible,ScaleHide,Bilebag,RoyalJelly,Magecap,JotunPuffs,blackcore,GiantBloodSack,JuteBlue,MechanicalSpring,DvergrExtractor,Wisp,SealbreakerFragment");
			AshlandsHints = BindTier("Ashlands", "FlametalNew,FlametalOreNew,Grausten,Ashwood,GemstoneRed,GemstoneBlue,GemstoneGreen,AskHide,AskBladder,AskSinew,BonemawTooth,CelestialFeather,CeramicPlate,CharcoalResin,CharredBone,CharredCogwheel,CharredSkull,Fiddlehead,MoltenCore,MorgenHeart,MorgenSinew,PotShard,ProustitePowder,ScrapBronze,ShieldCore,SmokePuff,Sulfur,Vineberry,BellFragment");
			DeepNorthHints = BindTier("Deep North", "DeepNorth,Frostcore,LuminousLarva,Mould,Timberwood,Bloodgold,PetrifiedTissue,SealPelt,SealBlubber,MooseMeat,MooseHide,MooseSinew,ElakingHair,LongClaw,FrozenBranch,DeadPulp,Lingonberry,Kale,Snowball,FrostFoundry,NordShield,NordGreatshield,IntricateKey,EmberCharge");
			RecipeFilterState.RebuildTierHints();
			ConfigEntry<string>[] array = new ConfigEntry<string>[7] { BlackForestHints, SwampHints, MountainHints, PlainsHints, MistlandsHints, AshlandsHints, DeepNorthHints };
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SettingChanged += OnTierHintsChanged;
			}
			_harmony = new Harmony("com.dadisbored.dadsezcrafting");
			CraftingPatches.Install(_harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsEZCrafting 1.0.0 loaded for Valheim 1.0.12 and BepInEx 5.4.23.5.");
		}

		private ConfigEntry<string> BindTier(string name, string defaults)
		{
			return ((BaseUnityPlugin)this).Config.Bind<string>("2 - Tier Detection", name + " Prefab Hints", defaults, "Comma-separated prefab or recipe-name fragments used to classify this progression tier.");
		}

		private static void OnTierHintsChanged(object sender, EventArgs args)
		{
			RecipeFilterState.RebuildTierHints();
			CraftingUiManager.RefreshRecipes();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal enum RecipeCategory
	{
		All,
		Weapons,
		Armor,
		Shields,
		Ammunition,
		Food,
		Tools,
		Materials,
		Other
	}
	internal enum ProgressionTier
	{
		All,
		Meadows,
		BlackForest,
		Swamps,
		Mountain,
		Plains,
		Mistlands,
		Ashlands,
		DeepNorth
	}
	internal enum RecipeSort
	{
		Native,
		NameAscending,
		NameDescending,
		Health,
		Stamina,
		Eitr
	}
	internal static class RecipeFilterState
	{
		internal static readonly RecipeCategory[] Categories = (RecipeCategory[])Enum.GetValues(typeof(RecipeCategory));

		internal static readonly ProgressionTier[] Tiers = (ProgressionTier[])Enum.GetValues(typeof(ProgressionTier));

		private static readonly Dictionary<ProgressionTier, string[]> TierHints = new Dictionary<ProgressionTier, string[]>();

		internal static RecipeCategory Category { get; private set; } = RecipeCategory.All;

		internal static ProgressionTier Tier { get; private set; } = ProgressionTier.All;

		internal static RecipeSort Sort { get; private set; } = RecipeSort.Native;

		internal static string Search { get; set; } = string.Empty;

		internal static void RebuildTierHints()
		{
			TierHints.Clear();
			TierHints[ProgressionTier.BlackForest] = Split(DadsEZCraftingPlugin.BlackForestHints?.Value);
			TierHints[ProgressionTier.Swamps] = Split(DadsEZCraftingPlugin.SwampHints?.Value);
			TierHints[ProgressionTier.Mountain] = Split(DadsEZCraftingPlugin.MountainHints?.Value);
			TierHints[ProgressionTier.Plains] = Split(DadsEZCraftingPlugin.PlainsHints?.Value);
			TierHints[ProgressionTier.Mistlands] = Split(DadsEZCraftingPlugin.MistlandsHints?.Value);
			TierHints[ProgressionTier.Ashlands] = Split(DadsEZCraftingPlugin.AshlandsHints?.Value);
			TierHints[ProgressionTier.DeepNorth] = Split(DadsEZCraftingPlugin.DeepNorthHints?.Value);
		}

		internal static void NextCategory()
		{
			Category = Categories[(int)(Category + 1) % Categories.Length];
			if (Category != RecipeCategory.Food && Sort >= RecipeSort.Health)
			{
				Sort = RecipeSort.Native;
			}
		}

		internal static void SetCategory(RecipeCategory category)
		{
			Category = category;
			if (Category != RecipeCategory.Food && Sort >= RecipeSort.Health)
			{
				Sort = RecipeSort.Native;
			}
		}

		internal static void NextTier()
		{
			Tier = Tiers[(int)(Tier + 1) % Tiers.Length];
		}

		internal static void SetTier(ProgressionTier tier)
		{
			Tier = tier;
		}

		internal static void NextSort()
		{
			RecipeSort[] array = ((Category == RecipeCategory.Food) ? ((RecipeSort[])Enum.GetValues(typeof(RecipeSort))) : new RecipeSort[3]
			{
				RecipeSort.Native,
				RecipeSort.NameAscending,
				RecipeSort.NameDescending
			});
			int num = Array.IndexOf(array, Sort);
			Sort = array[(num + 1 + array.Length) % array.Length];
		}

		internal static void Apply(List<Recipe> recipes)
		{
			if (recipes != null)
			{
				recipes.RemoveAll((Recipe recipe) => !Matches(recipe));
				Comparison<Recipe> comparison = GetComparison();
				if (comparison != null)
				{
					recipes.Sort(comparison);
				}
			}
		}

		internal static bool Matches(Recipe recipe)
		{
			if (recipe?.m_item?.m_itemData?.m_shared == null)
			{
				return false;
			}
			if (Category != RecipeCategory.All && ClassifyCategory(recipe) != Category)
			{
				return false;
			}
			if (Tier != ProgressionTier.All && ClassifyTier(recipe) != Tier)
			{
				return false;
			}
			string text = (Search ?? string.Empty).Trim();
			if (text.Length == 0)
			{
				return true;
			}
			string haystack = BuildSearchText(recipe);
			return text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries).All((string term) => haystack.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0);
		}

		internal static RecipeCategory ClassifyCategory(Recipe recipe)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			SharedData val = recipe?.m_item?.m_itemData?.m_shared;
			if (val == null)
			{
				return RecipeCategory.Other;
			}
			if ((int)val.m_itemType == 2 && (val.m_food > 0f || val.m_foodStamina > 0f || val.m_foodEitr > 0f || val.m_foodRegen > 0f))
			{
				return RecipeCategory.Food;
			}
			if ((int)val.m_itemType == 5)
			{
				return RecipeCategory.Shields;
			}
			if ((int)val.m_itemType == 6 || (int)val.m_itemType == 7 || (int)val.m_itemType == 11 || (int)val.m_itemType == 17)
			{
				return RecipeCategory.Armor;
			}
			if ((int)val.m_itemType == 9 || (int)val.m_itemType == 23)
			{
				return RecipeCategory.Ammunition;
			}
			if ((int)val.m_itemType == 19)
			{
				return RecipeCategory.Tools;
			}
			if ((int)val.m_itemType == 1)
			{
				return RecipeCategory.Materials;
			}
			if (recipe.m_item.m_itemData.IsWeapon())
			{
				return RecipeCategory.Weapons;
			}
			return RecipeCategory.Other;
		}

		internal static ProgressionTier ClassifyTier(Recipe recipe)
		{
			ProgressionTier current = StationTier(recipe?.m_craftingStation);
			Promote(ref current, Identifier((recipe != null) ? ((Object)recipe).name : null));
			object value;
			if (recipe == null)
			{
				value = null;
			}
			else
			{
				ItemDrop item = recipe.m_item;
				if (item == null)
				{
					value = null;
				}
				else
				{
					GameObject gameObject = ((Component)item).gameObject;
					value = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
			}
			Promote(ref current, Identifier((string)value));
			if (recipe?.m_resources != null)
			{
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					object value2;
					if (val == null)
					{
						value2 = null;
					}
					else
					{
						ItemDrop resItem = val.m_resItem;
						if (resItem == null)
						{
							value2 = null;
						}
						else
						{
							GameObject gameObject2 = ((Component)resItem).gameObject;
							value2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
						}
					}
					Promote(ref current, Identifier((string)value2));
				}
			}
			if (current != ProgressionTier.All)
			{
				return current;
			}
			return ProgressionTier.Meadows;
		}

		internal static string CategoryLabel()
		{
			if (Category == RecipeCategory.Ammunition)
			{
				return "Ammo / Throwables";
			}
			return Category.ToString();
		}

		internal static string TierLabel()
		{
			return Tier switch
			{
				ProgressionTier.All => "All Tiers", 
				ProgressionTier.BlackForest => "Black Forest", 
				ProgressionTier.DeepNorth => "Deep North", 
				_ => Tier.ToString(), 
			};
		}

		internal static string SortLabel()
		{
			return Sort switch
			{
				RecipeSort.NameAscending => "Name A-Z", 
				RecipeSort.NameDescending => "Name Z-A", 
				_ => Sort.ToString(), 
			};
		}

		private static Comparison<Recipe> GetComparison()
		{
			return Sort switch
			{
				RecipeSort.NameAscending => (Recipe left, Recipe right) => CompareNames(left, right), 
				RecipeSort.NameDescending => (Recipe left, Recipe right) => CompareNames(right, left), 
				RecipeSort.Health => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_food), 
				RecipeSort.Stamina => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_foodStamina), 
				RecipeSort.Eitr => (Recipe left, Recipe right) => CompareFoodDescending(left, right, (ItemData item) => item.m_shared.m_foodEitr), 
				_ => null, 
			};
		}

		private static int CompareFoodDescending(Recipe left, Recipe right, Func<ItemData, float> selector)
		{
			float value = ((left?.m_item?.m_itemData == null) ? 0f : selector(left.m_item.m_itemData));
			int num = ((right?.m_item?.m_itemData == null) ? 0f : selector(right.m_item.m_itemData)).CompareTo(value);
			if (num == 0)
			{
				return CompareNames(left, right);
			}
			return num;
		}

		private static int CompareNames(Recipe left, Recipe right)
		{
			return StringComparer.CurrentCultureIgnoreCase.Compare(ItemName(left), ItemName(right));
		}

		private static string ItemName(Recipe recipe)
		{
			string text = recipe?.m_item?.m_itemData?.m_shared?.m_name ?? string.Empty;
			if (Localization.instance != null)
			{
				return Localization.instance.Localize(text);
			}
			return text;
		}

		private static string BuildSearchText(Recipe recipe)
		{
			List<string> obj = new List<string>
			{
				ItemName(recipe),
				((recipe != null) ? ((Object)recipe).name : null) ?? string.Empty
			};
			object obj2;
			if (recipe == null)
			{
				obj2 = null;
			}
			else
			{
				ItemDrop item = recipe.m_item;
				if (item == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject = ((Component)item).gameObject;
					obj2 = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
			}
			if (obj2 == null)
			{
				obj2 = string.Empty;
			}
			obj.Add((string)obj2);
			obj.Add(Localize(recipe?.m_item?.m_itemData?.m_shared?.m_description));
			List<string> list = obj;
			if (recipe?.m_resources != null)
			{
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					object obj3;
					if (val == null)
					{
						obj3 = null;
					}
					else
					{
						ItemDrop resItem = val.m_resItem;
						if (resItem == null)
						{
							obj3 = null;
						}
						else
						{
							GameObject gameObject2 = ((Component)resItem).gameObject;
							obj3 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
						}
					}
					if (obj3 == null)
					{
						obj3 = string.Empty;
					}
					list.Add((string)obj3);
					list.Add(Localize(val?.m_resItem?.m_itemData?.m_shared?.m_name));
				}
			}
			return string.Join(" ", list);
		}

		private static string Localize(string text)
		{
			if (Localization.instance != null)
			{
				return Localization.instance.Localize(text ?? string.Empty);
			}
			return text ?? string.Empty;
		}

		private static ProgressionTier StationTier(CraftingStation station)
		{
			object value;
			if (station == null)
			{
				value = null;
			}
			else
			{
				GameObject gameObject = ((Component)station).gameObject;
				value = ((gameObject != null) ? ((Object)gameObject).name : null);
			}
			string text = Identifier((string)value);
			if (text.Contains("frostfoundry"))
			{
				return ProgressionTier.DeepNorth;
			}
			if (text.Contains("blackforge") || text.Contains("galdrtable"))
			{
				return ProgressionTier.Mistlands;
			}
			if (text.Contains("artisan"))
			{
				return ProgressionTier.Plains;
			}
			if (text.Contains("stonecutter"))
			{
				return ProgressionTier.Swamps;
			}
			if (text.Contains("forge"))
			{
				return ProgressionTier.BlackForest;
			}
			return ProgressionTier.Meadows;
		}

		private static void Promote(ref ProgressionTier current, string identifier)
		{
			if (identifier.Length == 0)
			{
				return;
			}
			for (ProgressionTier progressionTier = ProgressionTier.DeepNorth; progressionTier >= ProgressionTier.BlackForest; progressionTier--)
			{
				if (TierHints.TryGetValue(progressionTier, out var value) && value.Any(identifier.Contains))
				{
					if (progressionTier > current)
					{
						current = progressionTier;
					}
					break;
				}
			}
		}

		private static string Identifier(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
		}

		private static string[] Split(string value)
		{
			return (from item in (value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries).Select(Identifier)
				where item.Length > 0
				select item).Distinct<string>(StringComparer.Ordinal).ToArray();
		}
	}
}