Decompiled source of ToDoList v0.3.0

ValheimModToDo.dll

Decompiled a day ago
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Xml.Serialization;
using BepInEx;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.GUI;
using Jotunn.Managers;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Xunit;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValheimModToDo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimModToDo")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
namespace ValheimModToDo
{
	internal class ToDoCraftController
	{
		public static GameObject goAddCraftToDo;

		public static Button btnAddCraftToDo;

		public static TMP_Text txtAddCraftToDo;

		public static void CreateAddCraftToDoButton(UnityAction onClickAddCraftItemButton)
		{
			//IL_00b0: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				Button craftButton = instance.m_craftButton;
				obj = ((craftButton != null) ? ((Component)craftButton).gameObject : null);
			}
			GameObject val = (GameObject)obj;
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError((object)"craftButton not found");
				return;
			}
			if ((Object)(object)goAddCraftToDo != (Object)null)
			{
				Logger.LogDebug((object)"craftAddCraftToDoButton already exists. destroy it.");
				Object.Destroy((Object)(object)goAddCraftToDo);
			}
			Logger.LogDebug((object)"Instantiate");
			goAddCraftToDo = Object.Instantiate<GameObject>(val);
			Logger.LogDebug((object)"SetParent");
			goAddCraftToDo.transform.SetParent(val.transform.parent, false);
			Logger.LogDebug((object)"SetName");
			((Object)goAddCraftToDo).name = "craftAddToDoButton";
			Vector3 position = goAddCraftToDo.transform.position;
			position.x += 0f;
			position.y += -60f;
			goAddCraftToDo.transform.position = position;
			RectTransform component = goAddCraftToDo.GetComponent<RectTransform>();
			Vector2 sizeDelta = component.sizeDelta;
			sizeDelta.x += -150f;
			sizeDelta.y += -20f;
			component.sizeDelta = sizeDelta;
			btnAddCraftToDo = goAddCraftToDo.GetComponentInChildren<Button>();
			((Selectable)btnAddCraftToDo).interactable = true;
			((UnityEvent)btnAddCraftToDo.onClick).AddListener(onClickAddCraftItemButton);
			txtAddCraftToDo = goAddCraftToDo.GetComponentInChildren<TMP_Text>();
			if ((Object)(object)txtAddCraftToDo != (Object)null)
			{
				txtAddCraftToDo.text = "Add to To-Do";
				txtAddCraftToDo.autoSizeTextContainer = false;
				txtAddCraftToDo.fontSize = 16f;
			}
			Logger.LogDebug((object)"set tooltip");
			goAddCraftToDo.GetComponent<UITooltip>().m_text = "";
		}
	}
	internal class ToDoPanelController
	{
		public GameObject ToDoPanel;

		public GameObject ToDoTextView;

		public GameObject CleanAllButton;

		public GameObject CreatePanel(UnityAction onClearAllCraftingRecipes)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)"Make new To-Do panel");
			if (GUIManager.Instance == null)
			{
				Logger.LogError((object)"GUIManager instance is null");
				return null;
			}
			if (!Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				Logger.LogError((object)"GUIManager CustomGUI is null");
				return null;
			}
			float num = 250f;
			float num2 = 600f;
			float num3 = 10f;
			float num4 = 50f;
			GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(0f - num, 0f), num, num2, true);
			val.SetActive(false);
			DragWindowCntrl.ApplyDragWindowCntrl(val);
			GUIManager.Instance.CreateText("To-Do", val.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f - num4), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 100f, num4, false);
			float num5 = 400f;
			ToDoTextView = GUIManager.Instance.CreateText("Resources", val.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f - (num5 + 2f * num4 + 4f * num3) * 0.5f), GUIManager.Instance.AveriaSerifBold, 16, GUIManager.Instance.ValheimOrange, true, Color.black, num - 2f * num3, num5, false);
			CleanAllButton = GUIManager.Instance.CreateButton("Clear All", val.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 40f), 150f, 40f);
			CleanAllButton.SetActive(false);
			Button component = CleanAllButton.GetComponent<Button>();
			((UnityEvent)component.onClick).AddListener(onClearAllCraftingRecipes);
			ToDoPanel = val;
			return val;
		}

		public void SetActive(bool active)
		{
			GameObject toDoPanel = ToDoPanel;
			if (toDoPanel != null)
			{
				toDoPanel.SetActive(active);
			}
			GameObject cleanAllButton = CleanAllButton;
			if (cleanAllButton != null)
			{
				cleanAllButton.SetActive(active);
			}
		}

		public void UpdateResources(ToDoResources todo, Inventory inventory)
		{
			if ((Object)(object)ToDoTextView != (Object)null)
			{
				Text component = ToDoTextView.GetComponent<Text>();
				if ((Object)(object)component != (Object)null)
				{
					component.text = GetResourcesText(todo, inventory);
				}
				else
				{
					Logger.LogError((object)"UpdateResourcesText: No text component");
				}
			}
			else
			{
				Logger.LogWarning((object)"UpdateResourcesText: No text view");
			}
		}

		public string GetResourcesText(ToDoResources todo, Inventory inventory)
		{
			Logger.LogInfo((object)"ToDoPanelController.GetResourcesText");
			StringBuilder stringBuilder = new StringBuilder("", 2048);
			if (todo.recipes.Count() > 0 || todo.resources.Count() > 0)
			{
				stringBuilder.AppendLine(Localization.instance.Localize("$menu_resources:"));
				foreach (KeyValuePair<string, int> resource in todo.resources)
				{
					string text = "$item_" + resource.Key.ToLower();
					string arg = Localization.instance.Localize(text);
					int num = inventory.CountItems(text, -1, true);
					string text2 = ((num >= resource.Value) ? $"  {arg}\t[{resource.Value}]" : $"  {arg}\t[{num} / {resource.Value}]");
					Logger.LogInfo((object)text2);
					stringBuilder.AppendLine(text2);
				}
				stringBuilder.AppendLine("\n\n");
				stringBuilder.AppendLine(Localization.instance.Localize("$inventory_recipes:"));
				foreach (KeyValuePair<string, List<ToDoRecipe>> recipe in todo.recipes)
				{
					if (recipe.Value.Count() > 0)
					{
						stringBuilder.AppendLine($"  {recipe.Value[0].name}\t[{recipe.Value.Count()}]");
					}
				}
			}
			string text3 = stringBuilder.ToString();
			Logger.LogInfo((object)("To-Do List:\n" + text3));
			return text3;
		}
	}
	public class ToDoResource
	{
		public string id = "";

		public string name = "";

		public int amount = 1;

		public ToDoResource(string id, string name, int amount)
		{
			this.id = id;
			this.name = name ?? id;
			this.amount = amount;
		}

		public ToDoResource(Requirement req, int quality)
		{
			id = ((Object)req.m_resItem).name;
			name = Localization.instance.Localize(id);
			amount = req.GetAmount(quality);
		}
	}
	public class ToDoRecipe
	{
		public string id = "";

		public string name = "";

		public int quality = 1;

		public List<ToDoResource> resources = new List<ToDoResource>();

		public ToDoRecipe(string id, string name = null, int quality = 1)
		{
			this.id = id;
			this.name = name ?? id;
			this.quality = quality;
		}

		public ToDoRecipe(Piece piece)
		{
			id = ((Object)piece).name;
			name = Localization.instance.Localize(piece.m_name);
			quality = 1;
			Requirement[] array = piece.m_resources;
			foreach (Requirement req in array)
			{
				resources.Add(new ToDoResource(req, quality));
			}
		}

		public ToDoRecipe(Recipe recipe)
		{
			id = GetRecipeId(recipe);
			name = Localization.instance.Localize(recipe.m_item.m_itemData.m_shared.m_name);
			if ((Object)(object)recipe.m_item != (Object)null && recipe.m_item.m_itemData != null)
			{
				quality = recipe.m_item.m_itemData.m_quality;
			}
			else
			{
				quality = 1;
			}
			if ((Object)(object)recipe.m_item != (Object)null && (Object)(object)recipe.m_item.m_piece != (Object)null)
			{
				Requirement[] array = recipe.m_item.m_piece.m_resources;
				foreach (Requirement req in array)
				{
					resources.Add(new ToDoResource(req, quality));
				}
			}
			else
			{
				Requirement[] array2 = recipe.m_resources;
				foreach (Requirement req2 in array2)
				{
					resources.Add(new ToDoResource(req2, quality));
				}
			}
		}

		public static string GetRecipeId(Recipe recipe)
		{
			return ((Object)recipe).name;
		}
	}
	public class ToDoResources
	{
		public Dictionary<string, List<ToDoRecipe>> recipes = new Dictionary<string, List<ToDoRecipe>>();

		public Dictionary<string, int> resources = new Dictionary<string, int>();

		private readonly object _recipeLock = new object();

		private bool hasRecipeListChanged;

		public Dictionary<string, ToDoRecipe> fakeRecipeDb;

		public bool HasRecipeListChanged()
		{
			bool result = hasRecipeListChanged;
			hasRecipeListChanged = false;
			return result;
		}

		public void ClearRecipes()
		{
			lock (_recipeLock)
			{
				recipes.Clear();
				resources.Clear();
			}
		}

		public void AddRecipe(Recipe recipe)
		{
			AddRecipe(new ToDoRecipe(recipe));
		}

		public void AddRecipe(Piece piece)
		{
			AddRecipe(new ToDoRecipe(piece));
		}

		public void AddRecipe(ToDoRecipe recipe)
		{
			Logger.LogInfo((object)("ToDoResources: AddRecipe(" + recipe.name + ")"));
			lock (_recipeLock)
			{
				if (recipes.TryGetValue(recipe.id, out var value))
				{
					value.Add(recipe);
					Logger.LogInfo((object)("ToDoResources: Added Recipe " + recipe.name));
				}
				else
				{
					recipes.Add(recipe.id, new List<ToDoRecipe> { recipe });
				}
				foreach (ToDoResource resource in recipe.resources)
				{
					if (resource.amount > 0)
					{
						if (resources.TryGetValue(resource.id, out var value2))
						{
							resources[resource.id] = value2 + resource.amount;
						}
						else
						{
							resources[resource.id] = resource.amount;
						}
						Logger.LogInfo((object)$"ToDoResources: Added Resource {resource.id} amount {value2} now need {resources[resource.id]}");
					}
				}
				hasRecipeListChanged = true;
			}
		}

		public void RemoveRecipe(Recipe recipe)
		{
			RemoveRecipe(ToDoRecipe.GetRecipeId(recipe));
		}

		public void RemoveRecipe(string id)
		{
			Logger.LogInfo((object)("ToDoResources: RemoveRecipe(" + id + ")"));
			lock (_recipeLock)
			{
				if (!recipes.TryGetValue(id, out var value))
				{
					return;
				}
				ToDoRecipe toDoRecipe = value.First();
				foreach (ToDoResource resource in toDoRecipe.resources)
				{
					if (resources.TryGetValue(resource.id, out var value2))
					{
						int num = value2 - resource.amount;
						if (num > 0)
						{
							resources[resource.id] = num;
						}
						else
						{
							resources.Remove(resource.id);
						}
						Logger.LogInfo((object)$"ToDoResources: Removed Resource {resource.id} amount {value2} - left {num}");
					}
				}
				value.RemoveAt(0);
				if (value.Count == 0)
				{
					recipes.Remove(id);
				}
				hasRecipeListChanged = true;
			}
		}

		public bool IsUnitTesting()
		{
			return fakeRecipeDb != null;
		}

		public Recipe FindRecipe(string id)
		{
			List<Recipe> list = ObjectDB.instance.m_recipes;
			foreach (Recipe item in list)
			{
				string recipeId = ToDoRecipe.GetRecipeId(item);
				if (id == recipeId)
				{
					return item;
				}
			}
			return null;
		}

		public Piece FindPiece(string id)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				foreach (List<Piece> availablePiece in Player.m_localPlayer.m_buildPieces.m_availablePieces)
				{
					foreach (Piece item in availablePiece)
					{
						if (((Object)item).name == id)
						{
							return item;
						}
					}
				}
			}
			return null;
		}

		public void LoadFromFile()
		{
			string saveFileName = GetSaveFileName();
			Logger.LogInfo((object)("ToDoResources: LoadFromFile(" + saveFileName + ")"));
			if (!File.Exists(saveFileName))
			{
				return;
			}
			string text = File.ReadAllText(saveFileName);
			if (text == null)
			{
				return;
			}
			ClearRecipes();
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(RecipesList));
			FileStream fileStream = new FileStream(saveFileName, FileMode.Open);
			RecipesList recipesList = (RecipesList)xmlSerializer.Deserialize(fileStream);
			foreach (recipe recipe in recipesList.recipes)
			{
				if (IsUnitTesting())
				{
					AddSavedRecipeInUnitTest(recipe.id);
				}
				else
				{
					AddSavedRecipeInValheim(recipe.id);
				}
			}
			fileStream.Close();
		}

		public void AddSavedRecipeInUnitTest(string id)
		{
			fakeRecipeDb.TryGetValue(id, out var value);
			if (value != null)
			{
				AddRecipe(value);
			}
		}

		public void AddSavedRecipeInValheim(string id)
		{
			Recipe val = FindRecipe(id);
			if ((Object)(object)val != (Object)null)
			{
				AddRecipe(val);
				return;
			}
			Piece val2 = FindPiece(id);
			if ((Object)(object)val2 != (Object)null)
			{
				AddRecipe(val2);
			}
			else
			{
				Logger.LogWarning((object)("Loading saved to-do-list: Unable to find recipe or piece [" + id + "]"));
			}
		}

		public void SaveToFile()
		{
			string saveFileName = GetSaveFileName();
			Logger.LogInfo((object)("ToDoResources: SaveToFile(" + saveFileName + ")"));
			RecipesList recipesList = new RecipesList();
			foreach (KeyValuePair<string, List<ToDoRecipe>> recipe in recipes)
			{
				foreach (ToDoRecipe item2 in recipe.Value)
				{
					recipe item = new recipe
					{
						id = item2.id,
						quality = item2.quality
					};
					recipesList.recipes.Add(item);
				}
			}
			XmlSerializer xmlSerializer = new XmlSerializer(typeof(RecipesList));
			TextWriter textWriter = new StreamWriter(saveFileName);
			xmlSerializer.Serialize(textWriter, recipesList);
			textWriter.Close();
		}

		public string GetSaveFileName()
		{
			if (IsUnitTesting())
			{
				return GetSaveFileNameInUnitTest();
			}
			return GetSaveFileNameInValheim();
		}

		public string GetSaveFileNameInUnitTest()
		{
			string text = "test";
			string text2 = "map";
			return "todo-list-for-" + text + "-in-" + text2 + "-v1.xml";
		}

		public string GetSaveFileNameInValheim()
		{
			string playerName = Player.m_localPlayer.GetPlayerName();
			string text = "map";
			string path = "todo-list-for-" + playerName + "-in-" + text + "-v1.xml";
			return Path.Combine(Application.persistentDataPath, path);
		}
	}
	[XmlRoot("todolist")]
	public class RecipesList
	{
		[XmlAttribute]
		public string version = "1";

		public List<recipe> recipes = new List<recipe>();
	}
	public class recipe
	{
		[XmlAttribute]
		public string id = "";

		[XmlAttribute]
		public int quality = 1;
	}
	public class ToDoResoucesTest
	{
		private static readonly string test_recipe_id_1 = "Recipe_1";

		private static readonly string test_recipe_id_2 = "Recipe_2";

		private static readonly string test_resource_id_1 = "$item_1";

		private static readonly string test_resource_id_2 = "$item_2";

		private static readonly string test_resource_id_3 = "$item_3";

		private static ToDoRecipe test_recipe_1;

		private static ToDoRecipe test_recipe_2;

		public ToDoResoucesTest()
		{
			test_recipe_1 = new ToDoRecipe(test_recipe_id_1, "Recipe One");
			test_recipe_1.resources.Add(new ToDoResource(test_resource_id_1, "Resource One", 1));
			test_recipe_1.resources.Add(new ToDoResource(test_resource_id_2, "Resource Two", 5));
			test_recipe_2 = new ToDoRecipe(test_recipe_id_2, "Recipe Two");
			test_recipe_2.resources.Add(new ToDoResource(test_resource_id_2, "Resource Two", 3));
			test_recipe_2.resources.Add(new ToDoResource(test_resource_id_3, "Resource Three", 9));
		}

		[Fact]
		public void AddSingleRecipeTest()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.AddRecipe(test_recipe_1);
			Assert.Equal<int>(toDoResources.resources.Count, 2);
			Assert.Equal<int>(toDoResources.recipes.Count, 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 5);
		}

		[Fact]
		public void AddDuplicateRecipeTest()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_1);
			Assert.Equal<int>(toDoResources.resources.Count, 2);
			Assert.Equal<int>(toDoResources.recipes.Count, 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 10);
		}

		[Fact]
		public void AddMultipleRecipesTest()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_2);
			Assert.Equal<int>(toDoResources.resources.Count, 3);
			Assert.Equal<int>(toDoResources.recipes.Count, 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 13);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_3], 9);
		}

		[Fact]
		public void RemoveRecipesTest()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_2);
			toDoResources.RemoveRecipe(test_recipe_1.id);
			Assert.Equal<int>(toDoResources.resources.Count, 3);
			Assert.Equal<int>(toDoResources.recipes.Count, 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 8);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_3], 9);
			toDoResources.RemoveRecipe(test_recipe_2.id);
			Assert.Equal<int>(toDoResources.resources.Count, 2);
			Assert.Equal<int>(toDoResources.recipes.Count, 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 1);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 5);
			toDoResources.RemoveRecipe(test_recipe_1.id);
			Assert.Equal<int>(toDoResources.resources.Count, 0);
			Assert.Equal<int>(toDoResources.recipes.Count, 0);
		}

		[Fact]
		public void RemoveUnknownRecipe()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.RemoveRecipe("unknown-recipe");
			Assert.Equal<int>(toDoResources.resources.Count, 0);
			Assert.Equal<int>(toDoResources.recipes.Count, 0);
		}

		[Fact]
		public void WriteAndReadFile()
		{
			ToDoResources toDoResources = new ToDoResources();
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_1);
			toDoResources.AddRecipe(test_recipe_2);
			toDoResources.fakeRecipeDb = new Dictionary<string, ToDoRecipe>
			{
				{ test_recipe_1.id, test_recipe_1 },
				{ test_recipe_2.id, test_recipe_2 }
			};
			Assert.Equal<int>(toDoResources.resources.Count, 3);
			Assert.Equal<int>(toDoResources.recipes.Count, 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 13);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_3], 9);
			toDoResources.SaveToFile();
			toDoResources.ClearRecipes();
			toDoResources.LoadFromFile();
			Assert.Equal<int>(toDoResources.resources.Count, 3);
			Assert.Equal<int>(toDoResources.recipes.Count, 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_1], 2);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_2], 13);
			Assert.Equal<int>(toDoResources.resources[test_resource_id_3], 9);
		}
	}
	[BepInPlugin("com.jotunn.ValheimModToDo", "ValheimModToDo", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class ValheimModToDo : BaseUnityPlugin
	{
		public const string PluginGUID = "com.jotunn.ValheimModToDo";

		public const string PluginName = "ValheimModToDo";

		public const string PluginVersion = "0.3.0";

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		private static ValheimModToDo _instance;

		private ToDoResources todoResources = new ToDoResources();

		private ToDoPanelController todoPanel = new ToDoPanelController();

		private ButtonConfig ShowGUIButton;

		private ButtonConfig AddCraftToDoButton;

		private ButtonConfig ClearAllCraftToDoButton;

		private GameObject ToDoPanel;

		private void Awake()
		{
			_instance = this;
			Logger.LogInfo((object)"To-Do List Mod Awake");
			AddInputs();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "tloimu.mods.todo");
		}

		private void OnDestroy()
		{
			_instance = null;
		}

		private void AddInputs()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009f: Expected O, but got Unknown
			ShowGUIButton = new ButtonConfig
			{
				Name = "Open To-Do Panel",
				Key = (KeyCode)278,
				ActiveInCustomGUI = true
			};
			InputManager.Instance.AddButton("com.jotunn.ValheimModToDo", ShowGUIButton);
			AddCraftToDoButton = new ButtonConfig
			{
				Name = "Add Crafting to To-Do list",
				Key = (KeyCode)277,
				ActiveInCustomGUI = true
			};
			InputManager.Instance.AddButton("com.jotunn.ValheimModToDo", AddCraftToDoButton);
			ClearAllCraftToDoButton = new ButtonConfig
			{
				Name = "Clear Crafting To-Do list",
				Key = (KeyCode)127,
				ActiveInCustomGUI = true
			};
			InputManager.Instance.AddButton("com.jotunn.ValheimModToDo", ClearAllCraftToDoButton);
		}

		private void Update()
		{
			if (ZInput.instance != null)
			{
				if (ZInput.GetButtonDown(ShowGUIButton.Name))
				{
					TogglePanel();
				}
				if (ZInput.GetButtonDown(AddCraftToDoButton.Name))
				{
					AddCurrentSelectionToDoList();
				}
				if (ZInput.GetButtonDown(ClearAllCraftToDoButton.Name))
				{
					OnClearAllCraftingRecipes();
				}
			}
		}

		private void AddCurrentSelectionToDoList()
		{
			Logger.LogInfo((object)"Add Current Craft Item to To-Do list");
			Piece val = default(Piece);
			Vector2Int val2 = default(Vector2Int);
			int num = default(int);
			PieceCategory val3 = default(PieceCategory);
			PieceTable val4 = default(PieceTable);
			Player.m_localPlayer.GetBuildSelection(ref val, ref val2, ref num, ref val3, ref val4);
			if ((Object)(object)val != (Object)null)
			{
				Logger.LogInfo((object)$"AddCurrentCraftItemToDoList: {((Object)val).name}, total {num}");
				todoResources.AddRecipe(val);
				UpdateToDoPanel();
			}
		}

		private void TogglePanel()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			Logger.LogInfo((object)"Toggle To-Do panel");
			if (!Object.op_Implicit((Object)(object)ToDoPanel))
			{
				todoResources.LoadFromFile();
				ToDoPanel = todoPanel.CreatePanel(new UnityAction(OnClearAllCraftingRecipes));
			}
			bool flag = !ToDoPanel.activeSelf;
			if (flag)
			{
				UpdateToDoPanel();
			}
			todoPanel.SetActive(flag);
		}

		public void UpdateToDoPanel()
		{
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			todoPanel.UpdateResources(todoResources, inventory);
			if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.IsContainerOpen())
			{
				Container currentContainer = InventoryGui.instance.m_currentContainer;
				if ((Object)(object)currentContainer != (Object)null)
				{
					Inventory inventory2 = currentContainer.GetInventory();
					if (inventory2 != null)
					{
						Logger.LogInfo((object)$"Container: {((Object)currentContainer).name} [{currentContainer.m_name}] id [{((Object)currentContainer).GetInstanceID()}]");
						foreach (ItemData item in inventory2.m_inventory)
						{
							Logger.LogInfo((object)$"  {item.m_shared.m_name} stack {item.m_stack} quality {item.m_quality}");
						}
					}
				}
			}
			if (todoResources.HasRecipeListChanged())
			{
				todoResources.SaveToFile();
			}
		}

		public static void OnClickAddCraftItemButton()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Logger.LogInfo((object)"OnClickAddCraftItemButton");
			InventoryGui instance = InventoryGui.instance;
			RecipeDataPair selectedRecipe = instance.m_selectedRecipe;
			int selectedVariant = instance.m_selectedVariant;
			Logger.LogInfo((object)$"m_selectedRecipe={((RecipeDataPair)(ref selectedRecipe)).Recipe}");
			Logger.LogInfo((object)$"m_selectedVariant={selectedVariant}");
			Logger.LogInfo((object)$"m_craftRecipe.m_craftingStation={((RecipeDataPair)(ref selectedRecipe)).Recipe?.m_craftingStation}");
			Recipe val = ((RecipeDataPair)(ref selectedRecipe)).Recipe;
			if ((Object)(object)val.m_item != (Object)null && (Object)(object)val.m_item.m_piece != (Object)null)
			{
				Logger.LogInfo((object)("m_piece=" + val.m_item.m_piece.m_name));
				Requirement[] resources = val.m_item.m_piece.m_resources;
				Requirement[] array = resources;
				foreach (Requirement val2 in array)
				{
					Logger.LogInfo((object)$"  - {((Object)val2.m_resItem).name} [{val2.m_amount}]");
				}
			}
			if ((Object)(object)_instance != (Object)null)
			{
				_instance.AddCraftToDo(val);
			}
		}

		public static void OnRemoveCraftToDo(string name)
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance.RemoveCraftToDo(name);
			}
		}

		public static void OnInventoryChanged()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance.UpdateToDoPanel();
			}
		}

		private void OnClearAllCraftingRecipes()
		{
			todoResources.ClearRecipes();
			UpdateToDoPanel();
		}

		private void AddCraftToDo(Recipe recipe)
		{
			Logger.LogInfo((object)$"Add Craft To-Do: {((Object)recipe).name} amount {recipe.m_amount} item {((Object)recipe.m_item).name}");
			Requirement[] resources = recipe.m_resources;
			Requirement[] array = resources;
			foreach (Requirement val in array)
			{
				Logger.LogInfo((object)$"  - {((Object)val.m_resItem).name} [{val.m_amount}]");
			}
			todoResources.AddRecipe(recipe);
			UpdateToDoPanel();
		}

		private void RemoveCraftToDo(string name)
		{
			Logger.LogInfo((object)("Remove Craft To-Do: " + name));
			todoResources.RemoveRecipe(name);
			UpdateToDoPanel();
		}
	}
}
namespace ValheimModToDo.Properties
{
	[CompilerGenerated]
	[GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
	internal sealed class Settings : ApplicationSettingsBase
	{
		private static Settings defaultInstance = (Settings)(object)SettingsBase.Synchronized((SettingsBase)(object)new Settings());

		public static Settings Default => defaultInstance;
	}
}
namespace ValheimModToDo.Patches
{
	[HarmonyPatch(typeof(InventoryGui), "Awake")]
	public static class InventoryGui_Awake_Patch
	{
		public static void Postfix(InventoryGui __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ToDoCraftController.CreateAddCraftToDoButton(new UnityAction(ValheimModToDo.OnClickAddCraftItemButton));
		}
	}
	[HarmonyPatch(typeof(Inventory), "Changed")]
	public static class Inventory_Changed_Patch
	{
		public static void Postfix(Inventory __instance)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null && !Player.m_localPlayer.m_isLoading)
			{
				Logger.LogInfo((object)("Inventory.Changed: name " + __instance.m_name));
				if (((Humanoid)Player.m_localPlayer).m_inventory == __instance)
				{
					ValheimModToDo.OnInventoryChanged();
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	public static class InventoryGui_DoCrafting_Patch
	{
		public static void Postfix(InventoryGui __instance, Player player)
		{
			Logger.LogInfo((object)"InventoryGui.DoCrafting()");
			if ((Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Recipe recipe = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe;
			ItemData craftUpgradeItem = __instance.m_craftUpgradeItem;
			int num = ((craftUpgradeItem == null) ? 1 : (craftUpgradeItem.m_quality + 1));
			if (Object.op_Implicit((Object)(object)recipe))
			{
				Logger.LogInfo((object)$"InventoryGui.DoCrafting {((Object)recipe).name} quality {num}");
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					Logger.LogInfo((object)$"  - {((Object)val.m_resItem).name} [{val.m_amount}]");
				}
				ValheimModToDo.OnRemoveCraftToDo(((Object)recipe).name);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "PlacePiece")]
	public static class Player_PlacePiece_Patch
	{
		public static void Postfix(Player __instance, Piece piece, Vector3 pos, Quaternion rot, bool doAttack)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				Logger.LogInfo((object)("Player.PlacePiece: " + ((Object)piece).name));
				ValheimModToDo.OnRemoveCraftToDo(((Object)piece).name);
			}
		}
	}
}