Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ToDoList v0.6.1
ValheimModToDo.dll
Decompiled 9 months agousing System; 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.Managers; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [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.6.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.6.1.0")] namespace ValheimModToDo { internal class ToDoCraftController { public static GameObject goAddCraftToDo; public static Button btnAddCraftToDo; public static TMP_Text txtAddCraftToDo; public static RectTransform InventoryPanelPos; public static void CreateAddCraftToDoButton(UnityAction onClickAddCraftItemButton) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) 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); } InventoryGui instance2 = InventoryGui.instance; object inventoryPanelPos; if (instance2 == null) { inventoryPanelPos = null; } else { GameObject gameObject = ((Component)instance2).gameObject; inventoryPanelPos = ((gameObject != null) ? gameObject.GetComponent<RectTransform>() : null); } InventoryPanelPos = (RectTransform)inventoryPanelPos; goAddCraftToDo = Object.Instantiate<GameObject>(val); goAddCraftToDo.transform.SetParent(val.transform.parent, false); ((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; } goAddCraftToDo.GetComponent<UITooltip>().m_text = ""; } } public class ToDoListEdit { public ToDoResources todoList; private GameObject scrollView; private Transform contentPanel; private float nameWidth = 50f; private float width = 100f; private readonly float rowHeight = 16f; public bool viewOnly; private float buttonWidth = 16f; public UnityEvent onListChanged = new UnityEvent(); public void SetActive(bool active) { scrollView.SetActive(active); } public void AddEditMode(GameObject parent, float width, float height, float nameWidth) { viewOnly = false; width += 2f * buttonWidth; SetUp(parent, width, height, nameWidth); } public void AddViewMode(GameObject parent, float width, float height, float nameWidth) { viewOnly = true; SetUp(parent, width, height, nameWidth); } public void SetUp(GameObject parent, float width, float height, float nameWidth) { //IL_0053: 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) Logger.LogDebug((object)"ToDoListEdit.SetUp"); if ((Object)(object)scrollView == (Object)null) { this.width = width; this.nameWidth = nameWidth; scrollView = GUIManager.Instance.CreateScrollView(parent.transform, false, !viewOnly, 8f, 50f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, new Color(0.1568628f, 0.1019608f, 0.0627451f, 1f), width, height); contentPanel = scrollView.transform.Find("Scroll View/Viewport/Content"); Logger.LogDebug((object)"ToDoListEdit.SetUp: Scroll view created"); } } public void Clear() { if ((Object)(object)contentPanel != (Object)null) { contentPanel.DetachChildren(); } } public void AddRow(string name, string amounts = null, string modifyItemKey = null) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown GameObject val = new GameObject("Row", new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(contentPanel, false); HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 1f; ((LayoutGroup)val2).childAlignment = (TextAnchor)3; ((LayoutGroup)val2).padding = new RectOffset(0, 0, 0, 1); ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; Color val3 = (viewOnly ? GUIManager.Instance.ValheimBeige : GUIManager.Instance.ValheimOrange); GUIManager.Instance.CreateText(name, ((Component)val2).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerifBold, 16, val3, true, Color.black, nameWidth, rowHeight, false); float num = width - nameWidth - (float)((LayoutGroup)val2).padding.left - (float)((LayoutGroup)val2).padding.right; if (modifyItemKey != null) { num -= 3f * buttonWidth + ((HorizontalOrVerticalLayoutGroup)val2).spacing + (float)((LayoutGroup)val2).padding.left + (float)((LayoutGroup)val2).padding.right; } GUIManager.Instance.CreateText(amounts, ((Component)val2).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerifBold, 16, val3, true, Color.black, num, rowHeight, false); if (modifyItemKey != null) { GameObject val4 = GUIManager.Instance.CreateButton("+", ((Component)val2).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f), buttonWidth, rowHeight); GameObject val5 = GUIManager.Instance.CreateButton("-", ((Component)val2).transform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 0f), buttonWidth, rowHeight); ((UnityEvent)val4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { IncrementAmount(modifyItemKey); }); ((UnityEvent)val5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { DecrementAmount(modifyItemKey); }); val4.SetActive(true); val5.SetActive(true); } } public void AddLabelRow(string label) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_008c: 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_0091: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Row", new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(contentPanel, false); HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val2).spacing = 10f; ((LayoutGroup)val2).childAlignment = (TextAnchor)4; ((LayoutGroup)val2).padding = new RectOffset(0, 0, 1, 1); ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; Color val3 = (viewOnly ? GUIManager.Instance.ValheimBeige : GUIManager.Instance.ValheimOrange); GUIManager.Instance.CreateText(label, ((Component)val2).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerifBold, 16, val3, true, Color.black, nameWidth, rowHeight, false); } public void IncrementAmount(string modifyItemKey) { Logger.LogDebug((object)("ToDoListEdit.IncrementAmount(" + modifyItemKey + ")")); if (todoList != null) { todoList.AddExistingRecipe(modifyItemKey); UnityEvent obj = onListChanged; if (obj != null) { obj.Invoke(); } } } public void DecrementAmount(string modifyItemKey) { Logger.LogDebug((object)("ToDoListEdit.DecrementAmount(" + modifyItemKey + ")")); if (todoList != null) { todoList.RemoveRecipe(modifyItemKey); UnityEvent obj = onListChanged; if (obj != null) { obj.Invoke(); } } } } internal class ToDoPanelController { public GameObject ToDoEditPanel; public GameObject ToDoViewPanel; public GameObject ToDoTextNotes; public GameObject ClearAllButton; public ToDoListEdit ListEditor = new ToDoListEdit(); public ToDoListEdit ListViewer = new ToDoListEdit(); public bool ToDoEditPanelParentSet; private readonly float width = 282f; private readonly float buttonWidth = 16f; private readonly float nameWidth = 190f; private readonly float height = 600f; private readonly float margin = 10f; private readonly float notesHeight = 60f; private readonly float headerHeight = 50f; private readonly float listHeight = 300f; public ToDoResources todo = new ToDoResources(); public bool gLogVerbose; private bool isEditingNotes; private bool SaveFileLoaded; public bool Visible; public bool InventoryGuiOpen; public ToDoPanelController() { Logger.LogInfo((object)"Constructor ToDoPanelController"); } private bool IsGuiManagerReady() { if (GUIManager.Instance == null) { Logger.LogError((object)"GUIManager instance is null"); return false; } if (!Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { Logger.LogError((object)"GUIManager CustomGUIFront is null"); return false; } if (!Object.op_Implicit((Object)(object)GUIManager.CustomGUIBack)) { Logger.LogError((object)"GUIManager CustomGUIBack is null"); return false; } return true; } public void LogWorldName() { ZNet instance = ZNet.instance; Logger.LogInfo((object)("WorldName [" + ((instance != null) ? instance.GetWorldName() : null) + "]")); } public void SetupUi() { Logger.LogInfo((object)"Make new To-Do panel"); if (IsGuiManagerReady()) { ZNet instance = ZNet.instance; if (((instance != null) ? instance.GetWorldName() : null) == null) { Logger.LogDebug((object)"World not ready yet"); } CreateViewModePanel(); CreateEditModePanel(); SaveFileLoaded = false; } } public void CreateViewModePanel() { //IL_0017: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ToDoViewPanel == (Object)null) { ToDoViewPanel = DefaultControls.CreatePanel(GUIManager.Instance.ValheimControlResources); ToDoViewPanel.transform.SetParent(GUIManager.CustomGUIBack.transform, false); ToDoViewPanel.GetComponent<Image>().pixelsPerUnitMultiplier = 1f; ((Graphic)ToDoViewPanel.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0f); RectTransform val = (RectTransform)ToDoViewPanel.transform; val.anchoredPosition = new Vector2((0f - width) / 2f, 0f); val.anchorMin = new Vector2(1f, 0.5f); val.anchorMax = new Vector2(1f, 0.5f); val.SetSizeWithCurrentAnchors((Axis)0, width); val.SetSizeWithCurrentAnchors((Axis)1, height); ToDoViewPanel.SetActive(false); ListViewer.todoList = todo; ListViewer.AddViewMode(ToDoViewPanel, width, height, nameWidth); Logger.LogDebug((object)"ToDoPanelController: View Panel Created"); } } public void CreateEditModePanel() { //IL_002b: 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_0050: 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_00b3: 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_00da: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown if ((Object)(object)ToDoEditPanel == (Object)null) { ToDoEditPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(width / 2f, 0f), width + 2f * buttonWidth, height, false); ToDoEditPanel.SetActive(false); GUIManager.Instance.CreateText("To-Do", ToDoEditPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 0f - headerHeight), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 100f, headerHeight, false); ToDoTextNotes = GUIManager.Instance.CreateInputField(ToDoEditPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, (0f - (notesHeight + 2f * headerHeight + 4f * margin)) * 0.5f), (ContentType)0, (string)null, 16, width - 2f * margin, notesHeight); InputField component = ToDoTextNotes.GetComponent<InputField>(); component.lineType = (LineType)2; component.shouldActivateOnSelect = true; ((UnityEvent<string>)(object)component.onEndEdit).AddListener((UnityAction<string>)delegate { GUIManager.BlockInput(false); }); ListEditor.todoList = todo; ListEditor.AddEditMode(ToDoEditPanel, width - 2f * margin, listHeight, nameWidth); ListEditor.onListChanged.AddListener(new UnityAction(UpdateToDoPanel)); ClearAllButton = GUIManager.Instance.CreateButton("Clear All", ToDoEditPanel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 40f), 150f, 40f); ClearAllButton.SetActive(true); Button component2 = ClearAllButton.GetComponent<Button>(); if (component2 != null) { ((UnityEvent)component2.onClick).AddListener(new UnityAction(OnClearAllCraftingRecipes)); } Logger.LogDebug((object)"ToDoPanelController: Edit Panel Created"); } } public void CheckTextInput() { if ((Object)(object)ToDoTextNotes == (Object)null) { return; } InputField component = ToDoTextNotes.GetComponent<InputField>(); if (isEditingNotes) { if (!component.isFocused) { isEditingNotes = false; GUIManager.BlockInput(false); } } else if (component.isFocused) { isEditingNotes = true; GUIManager.BlockInput(true); } } public void EnsureFileLoaded() { if (!SaveFileLoaded) { SaveFileLoaded = true; todo.LoadFromFile(); SetToDoNotesToUi(); } } public void ToggleVisibility() { Visible = !Visible; UpdateViewModes(); } public void SetVisible(bool visible = true) { if (Visible != visible) { Visible = visible; UpdateViewModes(); } } public void UpdateViewModes() { if ((Object)(object)ToDoEditPanel == (Object)null || (Object)(object)ToDoViewPanel == (Object)null) { SetupUi(); } else if (Visible) { UpdateToDoPanel(); ToDoEditPanel.SetActive(InventoryGuiOpen); ToDoViewPanel.SetActive(!InventoryGuiOpen); ReparentEditPanelBehindCraftingUI(); } else { ToDoEditPanel.SetActive(false); ToDoViewPanel.SetActive(false); } } public void ReparentEditPanelBehindCraftingUI() { if (!ToDoEditPanelParentSet) { RectTransform val = InventoryGui.instance?.m_crafting; if ((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent != (Object)null) { Logger.LogInfo((object)("ToDoPanelController: Move to behind " + ((Object)val).name + " panel")); ToDoEditPanel.transform.SetParent(((Transform)val).parent, true); ToDoEditPanel.transform.SetSiblingIndex(((Transform)val).GetSiblingIndex()); ToDoEditPanelParentSet = true; } else { Logger.LogWarning((object)"ToDoPanelController: No crafting panel was found - game has changed and todo list may render incorrectly"); } } } public void PrintGUIHierarchy(Transform transform, int level = 0) { Logger.LogInfo((object)$"[{level}] - {((Object)transform).name} ({transform.GetSiblingIndex()})"); for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); Logger.LogInfo((object)$"[{level}] - child {((Object)child).name} ({child.GetSiblingIndex()})"); } if ((Object)(object)transform.parent != (Object)null) { PrintGUIHierarchy(transform.parent, level + 1); } } public void UpdateToDoPanel() { Logger.LogInfo((object)"UpdateToDoPanel"); Player localPlayer = Player.m_localPlayer; Inventory val = ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null); if (val != null) { if ((Object)(object)ToDoViewPanel == (Object)null || (Object)(object)ToDoEditPanel == (Object)null) { SetupUi(); } EnsureFileLoaded(); UpdateResources(val); if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.IsContainerOpen()) { Container currentContainer = InventoryGui.instance.m_currentContainer; if ((Object)(object)currentContainer != (Object)null) { Inventory inventory = currentContainer.GetInventory(); if (inventory != null) { Logger.LogInfo((object)$"Container: {((Object)currentContainer).name} [{currentContainer.m_name}] id [{((Object)currentContainer).GetInstanceID()}]"); foreach (ItemData item in inventory.m_inventory) { Logger.LogInfo((object)$" {item.m_shared.m_name} stack {item.m_stack} quality {item.m_quality}"); } } } } if (todo.WasChangedSince()) { todo.SaveToFile(); } } else { Logger.LogWarning((object)"UpdateToDoPanel: No inventory"); } } public void UpdateResources(Inventory inventory) { Logger.LogInfo((object)"UpdateResources"); if (ListEditor != null) { UpdateListView(inventory, ListEditor); } else { Logger.LogInfo((object)"UpdateResources: ListEditor NULL"); } if (ListViewer != null) { UpdateListView(inventory, ListViewer); } else { Logger.LogInfo((object)"UpdateResources: ListViewer NULL"); } } public string GetResourcesText(Inventory inventory, bool includeNotes = true) { Logger.LogInfo((object)"ToDoPanelController.GetResourcesText"); StringBuilder stringBuilder = new StringBuilder("", 2048); if (includeNotes && todo.notes != null && todo.notes.Length > 0) { stringBuilder.AppendLine(todo.notes); stringBuilder.AppendLine(); } if (todo.recipes.Count() > 0 || todo.resources.Count() > 0) { stringBuilder.AppendLine(Localization.instance.Localize("$menu_resources:")); foreach (KeyValuePair<string, ToDoResources.ResourceRequirement> resource in todo.resources) { if (resource.Value.count > 0) { string name = resource.Value.item.name; int num = inventory.CountItems(resource.Value.item.id, -1, true); string text = ((num >= resource.Value.count) ? $" {name}\t[{resource.Value.count}]" : $" {name}\t[{num} / {resource.Value.count}]"); if (gLogVerbose) { Logger.LogInfo((object)(text + " from key [" + resource.Key + "] id [" + resource.Value.item.id + "] name [" + resource.Value.item.name + "]")); } stringBuilder.AppendLine(text); } } stringBuilder.AppendLine(); stringBuilder.AppendLine(Localization.instance.Localize("$inventory_recipes:")); foreach (KeyValuePair<string, List<ToDoRecipe>> recipe in todo.recipes) { if (recipe.Value.Count() > 0) { ToDoRecipe toDoRecipe = recipe.Value[0]; string arg = ""; if (toDoRecipe.quality > 1) { arg = $" ⇧{toDoRecipe.quality}"; } stringBuilder.AppendLine($" {toDoRecipe.name}{arg}\t[{recipe.Value.Count()}]"); } } } string text2 = stringBuilder.ToString(); if (gLogVerbose) { Logger.LogInfo((object)("To-Do List:\n" + text2)); Logger.LogInfo((object)"Inventory:"); foreach (ItemData item in inventory.m_inventory) { Logger.LogInfo((object)(" - [" + item.m_shared.m_name + "]")); } } return text2; } public void UpdateListView(Inventory inventory, ToDoListEdit listView) { Logger.LogInfo((object)"ToDoPanelController.UpdateListView"); listView.Clear(); if (listView.viewOnly) { listView.AddLabelRow(todo.notes); listView.AddLabelRow(""); } if (todo.resources.Count > 0) { listView.AddLabelRow(Localization.instance.Localize("$menu_resources:")); foreach (KeyValuePair<string, ToDoResources.ResourceRequirement> resource in todo.resources) { if (resource.Value.count > 0) { string name = resource.Value.item.name; int num = inventory.CountItems(resource.Value.item.id, -1, true); listView.AddRow(amounts: (num >= resource.Value.count) ? $"[{resource.Value.count}]" : $"[{num} / {resource.Value.count}]", name: " " + name); } } } if (todo.recipes.Count <= 0) { return; } listView.AddLabelRow(""); listView.AddLabelRow(Localization.instance.Localize("$inventory_recipes:")); foreach (KeyValuePair<string, List<ToDoRecipe>> recipe in todo.recipes) { if (recipe.Value.Count() > 0) { ToDoRecipe toDoRecipe = recipe.Value[0]; string text = ""; if (toDoRecipe.quality > 1) { text = $" ⇧{toDoRecipe.quality}"; } if (listView.viewOnly) { listView.AddRow(" " + toDoRecipe.name + text, $"[{recipe.Value.Count()}]"); } else { listView.AddRow(" " + toDoRecipe.name + text, $"[{recipe.Value.Count()}]", toDoRecipe.id); } } } } private void OnClearAllCraftingRecipes() { todo.ClearRecipes(); UpdateToDoPanel(); } public void OnShowInventoryGui() { if (!InventoryGuiOpen) { InventoryGuiOpen = true; UpdateViewModes(); } } public void OnHideInventoryGui() { if (InventoryGuiOpen) { InventoryGuiOpen = false; GetToDoNotesFromUi(); UpdateViewModes(); } } public void GetToDoNotesFromUi() { if (!((Object)(object)ToDoTextNotes != (Object)null)) { return; } InputField component = ToDoTextNotes.GetComponent<InputField>(); if ((Object)(object)component != (Object)null) { Text textComponent = component.textComponent; if (textComponent != null) { todo.SetNotes(component.text); return; } } Logger.LogError((object)"GetToDoNotesFromUi: No ToDoTextNotes text component"); } public void SetToDoNotesToUi() { if (!((Object)(object)ToDoTextNotes != (Object)null)) { return; } InputField component = ToDoTextNotes.GetComponent<InputField>(); if ((Object)(object)component != (Object)null) { Text textComponent = component.textComponent; if (textComponent != null) { component.text = todo.notes; return; } } Logger.LogError((object)"SetToDoNotesToUi: No ToDoTextNotes text component"); } } 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 = req.m_resItem?.m_itemData?.m_shared?.m_name; name = TranslateRequiredItem(req); amount = req.GetAmount(quality); } public static string TranslateRequiredItem(Requirement req) { string text = ((Object)req.m_resItem).name; string text2; if (req.m_resItem?.m_itemData?.m_shared?.m_name != null) { text2 = Localization.instance.Localize(req.m_resItem.m_itemData.m_shared.m_name); } else { text = "item_" + ((Object)req.m_resItem).name.ToLower(); string text3 = "$" + text; Logger.LogWarning((object)("Suspicious resource name: [" + ((Object)req.m_resItem).name + "] trying [" + text3 + "]")); text2 = Localization.instance.Localize(text3); } if (text2.Contains("_") || text2.Equals(text)) { if (req.m_resItem?.m_itemData?.m_shared?.m_name != null) { Logger.LogWarning((object)("Suspicious resource name: [" + text + "] m_item shared name [" + req.m_resItem.m_itemData.m_shared.m_name + "]")); text2 = Localization.instance.Localize(req.m_resItem.m_itemData.m_shared.m_name); } else { Logger.LogWarning((object)("Suspicious resource name: [" + text + "]")); } } return text2; } } 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, int quality) { id = ((Object)recipe).name; this.quality = quality; name = Localization.instance.Localize(recipe.m_item.m_itemData.m_shared.m_name); if (name.Contains("_")) { Logger.LogWarning((object)("Suspicious item name: [" + recipe.m_item.m_itemData.m_shared.m_name + "] setName [" + recipe.m_item.m_itemData.m_shared.m_setName + "] m_item.name [" + ((Object)recipe.m_item).name + "]")); } 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 GetRecipeKey(Recipe recipe, int quality) { return GetRecipeKey(((Object)recipe).name, quality); } public static string GetRecipeKey(ToDoRecipe recipe) { return GetRecipeKey(recipe.id, recipe.quality); } public static string GetRecipeKey(string name, int quality) { if (quality == 1) { return name; } return $"{name}/{quality}"; } } public class ToDoResources { public class ResourceRequirement { public ToDoResource item; public int count; public ResourceRequirement(ToDoResource resource, int count) { item = resource; this.count = count; } } public Dictionary<string, List<ToDoRecipe>> recipes = new Dictionary<string, List<ToDoRecipe>>(); public Dictionary<string, ResourceRequirement> resources = new Dictionary<string, ResourceRequirement>(); public string notes = ""; private readonly object _recipeLock = new object(); private bool wasChangedSince; public Dictionary<string, ToDoRecipe> fakeRecipeDb; public void SetNotes(string notes) { if (notes == null) { notes = ""; } if (!this.notes.Equals(notes)) { this.notes = notes; wasChangedSince = true; } } public bool WasChangedSince() { bool result = wasChangedSince; wasChangedSince = false; return result; } public void ClearRecipes() { lock (_recipeLock) { recipes.Clear(); resources.Clear(); } } public void AddRecipe(Recipe recipe, int quality) { AddRecipe(new ToDoRecipe(recipe, quality)); } public void AddRecipe(Piece piece) { AddRecipe(new ToDoRecipe(piece)); } public void AddRecipe(ToDoRecipe recipe) { string recipeKey = ToDoRecipe.GetRecipeKey(recipe); Logger.LogInfo((object)("ToDoResources: AddRecipe(" + recipeKey + ")")); lock (_recipeLock) { if (recipes.TryGetValue(recipeKey, out var value)) { value.Add(recipe); Logger.LogInfo((object)("ToDoResources: Added Recipe " + recipeKey)); } else { recipes.Add(recipeKey, new List<ToDoRecipe> { recipe }); } foreach (ToDoResource resource in recipe.resources) { if (resource.amount > 0) { if (resources.TryGetValue(resource.id, out var value2)) { value2.count += resource.amount; } else { resources[resource.id] = new ResourceRequirement(resource, resource.amount); } Logger.LogInfo((object)$"ToDoResources: Added Resource {resource.id} amount {resource.amount} now need {resources[resource.id].count}"); } } wasChangedSince = true; } } public void AddExistingRecipe(string recipeKey) { Logger.LogInfo((object)("ToDoResources: AddExistingRecipe(" + recipeKey + ")")); lock (_recipeLock) { if (recipes.TryGetValue(recipeKey, out var value)) { ToDoRecipe toDoRecipe = value.First(); AddRecipe(toDoRecipe); } } } public void RemoveRecipe(Recipe recipe, int quality) { RemoveRecipe(ToDoRecipe.GetRecipeKey(recipe, quality)); } public void RemoveRecipe(string name, int quality) { RemoveRecipe(ToDoRecipe.GetRecipeKey(name, quality)); } public void RemoveRecipe(string recipeKey) { Logger.LogInfo((object)("ToDoResources: RemoveRecipe(" + recipeKey + ")")); lock (_recipeLock) { if (!recipes.TryGetValue(recipeKey, 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.count - resource.amount; if (num > 0) { value2.count = num; } else { resources.Remove(resource.id); } Logger.LogInfo((object)$"ToDoResources: Removed Resource {resource.id} amount {resource.amount} - left {num}"); } } value.RemoveAt(0); if (value.Count == 0) { recipes.Remove(recipeKey); } wasChangedSince = true; } } public bool IsUnitTesting() { return fakeRecipeDb != null; } public Recipe FindRecipe(string name) { List<Recipe> list = ObjectDB.instance.m_recipes; foreach (Recipe item in list) { if (name == ((Object)item).name) { return item; } } return null; } public Piece FindPiece(string name) { Logger.LogInfo((object)("FindPiece: " + name)); if (Player.m_localPlayer?.m_buildPieces?.m_availablePieces != null) { foreach (List<Piece> availablePiece in Player.m_localPlayer.m_buildPieces.m_availablePieces) { foreach (Piece item in availablePiece) { Logger.LogInfo((object)(" - is it [" + ((Object)item).name + "]?")); if (((Object)item).name == name) { return item; } } } } else { Logger.LogError((object)"FindPiece: No Available Pieces"); } return null; } public bool LoadFromFile() { string saveFileName = GetSaveFileName(); Logger.LogInfo((object)("ToDoResources: LoadFromFile(" + saveFileName + ")")); if (saveFileName == null) { return false; } if (File.Exists(saveFileName)) { ClearRecipes(); try { string text = File.ReadAllText(saveFileName); if (text != null) { 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, recipe.quality); } else { AddSavedRecipeInValheim(recipe.id, recipe.quality); } } notes = recipesList.notes; fileStream.Close(); } } catch (IOException ex) { Logger.LogError((object)("ToDoResources: LoadFromFile(" + saveFileName + ") exception:" + ex.Message)); return false; } } return true; } public void AddSavedRecipeInUnitTest(string name, int quality) { fakeRecipeDb.TryGetValue(name, out var value); if (value != null) { value.quality = quality; AddRecipe(value); } } public void AddSavedRecipeInValheim(string name, int quality) { Recipe val = FindRecipe(name); if ((Object)(object)val != (Object)null) { AddRecipe(val, quality); return; } Piece val2 = FindPiece(name); if ((Object)(object)val2 != (Object)null) { AddRecipe(val2); } else { Logger.LogWarning((object)("Loading saved to-do-list: Unable to find recipe or piece [" + name + "]")); } } 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); } } recipesList.notes = notes; 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() { ZNet instance = ZNet.instance; string text = ((instance != null) ? instance.GetWorldName() : null); Player localPlayer = Player.m_localPlayer; string text2 = ((localPlayer != null) ? localPlayer.GetPlayerName() : null); Logger.LogInfo((object)("ToDoResources: GetFileName for [" + text2 + "] in [" + text + "])")); if (text2 == null) { return null; } string path = "todo-list-for-" + text2 + "-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 string notes; } public class recipe { [XmlAttribute] public string id = ""; [XmlAttribute] public int quality = 1; } [BepInPlugin("com.jotunn.ValheimModToDo", "ValheimModToDo", "0.6.1")] [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.6.1"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private static ValheimModToDo _instance; private readonly ToDoPanelController todoPanel = new ToDoPanelController(); private ButtonConfig ToggleVisibilityButton; private ButtonConfig AddCraftToDoButton; private void Awake() { _instance = this; Logger.LogInfo((object)"To-Do List Mod Awake"); AddInputs(); GUIManager.OnCustomGUIAvailable += OnRebuildUi; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "tloimu.mods.todo"); } public void OnRebuildUi() { Logger.LogInfo((object)"OnRebuildUi"); todoPanel.SetupUi(); } private void OnDestroy() { Logger.LogInfo((object)"To-Do List Mod OnDestroy"); GUIManager.OnCustomGUIAvailable -= OnRebuildUi; _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 ToggleVisibilityButton = new ButtonConfig { Name = "Open To-Do Panel", Key = (KeyCode)278, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jotunn.ValheimModToDo", ToggleVisibilityButton); AddCraftToDoButton = new ButtonConfig { Name = "Add Crafting to To-Do list", Key = (KeyCode)277, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jotunn.ValheimModToDo", AddCraftToDoButton); } private void Update() { if (ZInput.instance != null) { if (ZInput.GetButtonDown(ToggleVisibilityButton.Name)) { todoPanel.ToggleVisibility(); } if (ZInput.GetButtonDown(AddCraftToDoButton.Name)) { AddCurrentSelectionToDoList(); } if (todoPanel != null) { todoPanel.CheckTextInput(); } } } 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 && !(((Object)val).name == "piece_repair")) { Logger.LogInfo((object)$"AddCurrentCraftItemToDoList: {((Object)val).name}, total {num}"); todoPanel.todo.AddRecipe(val); todoPanel.SetVisible(); UpdateToDoPanel(); } } public void UpdateToDoPanel() { todoPanel.UpdateToDoPanel(); } 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; int num = 1; bool flag = false; if (instance.InUpradeTab()) { ItemData itemData = ((RecipeDataPair)(ref selectedRecipe)).ItemData; num = ((itemData == null) ? 1 : (itemData.m_quality + 1)); } else { flag = instance.m_craftUpgradeItem == null && (ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyLStick")); } 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}"); Logger.LogInfo((object)$"qualityLevel={num}"); int count = ((!flag) ? 1 : instance.m_multiCraftAmount); if ((Object)(object)_instance != (Object)null) { _instance.AddCraftToDo(((RecipeDataPair)(ref selectedRecipe)).Recipe, num, count); } } public static void OnRemoveCraftToDo(Recipe recipe, int quality = 1, int count = 1) { if ((Object)(object)_instance != (Object)null) { _instance.RemoveCraftToDo(recipe, quality, count); } } public static void OnRemoveCraftToDo(Piece piece, int quality = 1) { if ((Object)(object)_instance != (Object)null) { _instance.RemoveCraftToDo(piece, quality); } } public static void OnInventoryChanged() { if ((Object)(object)_instance != (Object)null) { _instance.UpdateToDoPanel(); } } public static void OnShowInventory() { if ((Object)(object)_instance != (Object)null && _instance.todoPanel != null) { _instance.todoPanel.OnShowInventoryGui(); } } public static void OnHideInventory() { if ((Object)(object)_instance != (Object)null && _instance.todoPanel != null) { _instance.todoPanel.OnHideInventoryGui(); } } private void AddCraftToDo(Recipe recipe, int quality, int count = 1) { Logger.LogInfo((object)$"Add Craft To-Do: {((Object)recipe).name} amount {recipe.m_amount} quality {quality}"); for (int i = 0; i < count; i++) { todoPanel.todo.AddRecipe(recipe, quality); } todoPanel.SetVisible(); UpdateToDoPanel(); } private void RemoveCraftToDo(Recipe recipe, int quality, int count = 1) { Logger.LogInfo((object)$"Remove Craft To-Do: {((Object)recipe).name} quality {quality}"); for (int i = 0; i < count; i++) { todoPanel.todo.RemoveRecipe(recipe, quality); } UpdateToDoPanel(); } private void RemoveCraftToDo(Piece piece, int quality) { Logger.LogInfo((object)$"Remove Build To-Do: {((Object)piece).name} quality {quality}"); todoPanel.todo.RemoveRecipe(((Object)piece).name, quality); 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 && ((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) { if (!((Object)(object)player != (Object)(object)Player.m_localPlayer)) { Recipe recipe = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe; ItemData craftUpgradeItem = __instance.m_craftUpgradeItem; int quality = ((craftUpgradeItem == null) ? 1 : (craftUpgradeItem.m_quality + 1)); if (Object.op_Implicit((Object)(object)recipe)) { int num = ((!__instance.m_multiCrafting) ? 1 : __instance.m_multiCraftAmount); Logger.LogInfo((object)$"InventoryGui.DoCrafting({((Object)recipe).name}) x {num}"); ValheimModToDo.OnRemoveCraftToDo(recipe, quality, num); } } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGui_Show_Patch { public static void Postfix(InventoryGui __instance, Container container, int activeGroup) { ValheimModToDo.OnShowInventory(); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryGui_Hide_Patch { public static void Postfix(InventoryGui __instance) { ValheimModToDo.OnHideInventory(); } } [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(piece); } } } [HarmonyPatch(typeof(Player), "OnRespawn")] public static class Player_OnRespawn_Patch { public static void Postfix(Player __instance) { Logger.LogInfo((object)("Player.OnRespawn [" + ((Object)__instance).name + "]")); if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ValheimModToDo.OnInventoryChanged(); } } } }