Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CraftMeOnce v1.1.0
CraftMeOnce.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CraftMeOnce")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CraftMeOnce")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7055ccb8-ebe8-49ab-ad51-d72bad2a5c42")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace CraftMeOnce; public static class Caching { public static readonly Dictionary<string, string> itemDropTranslatedKeys = new Dictionary<string, string>(); public static bool findTranslatedKey(TextMeshProUGUI translatedText, out string recipeKey) { if (itemDropTranslatedKeys.TryGetValue(((TMP_Text)translatedText).text, out recipeKey)) { return true; } string text = RemoveAmountSuffix(((TMP_Text)translatedText).text, " x"); Logger.Log("translated quantity check: " + text); if (itemDropTranslatedKeys.TryGetValue(text, out recipeKey)) { return true; } string text2 = CleanItemName(((TMP_Text)translatedText).text); Logger.Log("translated other mods check: " + text2); return itemDropTranslatedKeys.TryGetValue(text2, out recipeKey); } private static string RemoveAmountSuffix(string text, string indicator) { if (string.IsNullOrWhiteSpace(text)) { return text; } int num = text.LastIndexOf(indicator); if (num > 0 && num + 2 < text.Length) { string s = text.Substring(num + 2); if (int.TryParse(s, out var _)) { return text.Substring(0, num).Trim(); } } return text; } private static string CleanItemName(string raw) { if (string.IsNullOrEmpty(raw)) { return raw; } string input = raw; input = Regex.Replace(input, "<size=.*?</size>", "", RegexOptions.IgnoreCase); input = Regex.Replace(input, "<.*?>", "", RegexOptions.IgnoreCase); input = Regex.Replace(input, "\\s+#\\d+$", "", RegexOptions.IgnoreCase); return input.Trim(); } public static void AddItemDrops() { itemDropTranslatedKeys.Clear(); Recipe[] array = Resources.FindObjectsOfTypeAll<Recipe>(); foreach (Recipe val in array) { if ((Object)(object)val.m_item != (Object)null && val.m_item.m_itemData != null && val.m_item.m_itemData.m_shared != null) { string key = Localization.instance.Localize(val.m_item.m_itemData.m_shared.m_name); if (!itemDropTranslatedKeys.ContainsKey(key)) { itemDropTranslatedKeys.Add(key, val.m_item.m_itemData.m_shared.m_name); } } } Trader[] array2 = Resources.FindObjectsOfTypeAll<Trader>(); foreach (Trader val2 in array2) { List<TradeItem> list = val2.m_items ?? new List<TradeItem>(); foreach (TradeItem item in list) { if (item.m_prefab?.m_itemData?.m_shared != null) { string key2 = Localization.instance.Localize(item.m_prefab.m_itemData.m_shared.m_name); if (!itemDropTranslatedKeys.ContainsKey(key2)) { itemDropTranslatedKeys.Add(key2, item.m_prefab.m_itemData.m_shared.m_name); } } } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned { private static void Postfix(bool spawnValkyrie) { Logger.Log("Player_OnSpawned"); Caching.AddItemDrops(); } } [HarmonyPatch(typeof(Localization), "SetLanguage")] public class Localization_SetLanguage_Patch { private static void Postfix(string language) { Logger.Log("Language changed to: " + language); Caching.AddItemDrops(); } } internal class ConfigurationFile { public enum Toggle { Off, On } public enum HintMode { Off, On, Always } public static ConfigEntry<Toggle> modEnabled; public static ConfigEntry<Toggle> debug; public static ConfigEntry<HintMode> hintMode; public static ConfigEntry<HintMode> vendorHintMode; public static ConfigEntry<KeyCode> btnGamepadKey; public static ConfigEntry<Vector2> btnPosition; public static ConfigEntry<Vector2> btnSize; public static ConfigEntry<string> characterForNotCraftedItems; public static ConfigEntry<Toggle> repairAll; public static ConfigEntry<string> repairAllItemsText; public static ConfigEntry<KeyCode> vendorBtnGamepadKey; public static ConfigEntry<Vector2> vendorBtnPosition; public static ConfigEntry<Vector2> vendorBtnSize; public static ConfigEntry<string> vendorCharacterForNotObtainedItems; public static ConfigEntry<string> vendorHiddenElementsText; public static ConfigFile configFile; private static readonly string ConfigFileName = "Turbero.CraftMeOnce.cfg"; private static readonly string ConfigFileFullPath; internal static void LoadConfig(BaseUnityPlugin plugin) { //IL_00c5: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) configFile = plugin.Config; modEnabled = configFile.Bind<Toggle>("1 - General", "Mod Enabled", Toggle.On, "Enabling/Disabling this mod (default = On)"); debug = configFile.Bind<Toggle>("1 - General", "Debug Mode", Toggle.Off, "Enabling/Disabling the debugging in the console (default = Off)"); hintMode = configFile.Bind<HintMode>("1 - General", "Hint Mode - Workstations", HintMode.On, "Turn on/off the hint mark in the recipe names or show it always without the toggle button (default = On)"); vendorHintMode = configFile.Bind<HintMode>("1 - General", "Hint Mode - Vendors", HintMode.On, "Turn on/off the hint mark in the trader item names or show it always without the toggle button (default = On)"); btnGamepadKey = configFile.Bind<KeyCode>("2 - Config Workstations", "Button Gamepad Key", (KeyCode)330, "Gamepad key to link the button (default: JoystickButton0 - A"); btnPosition = configFile.Bind<Vector2>("2 - Config Workstations", "Button Position", new Vector2(-268f, 566f), "Left corner position for the hint button (default: x=-268, y=566)"); btnSize = configFile.Bind<Vector2>("2 - Config Workstations", "Button Size", new Vector2(29f, 29f), "Width/Height of the hint button (default: x=29, y=29)"); characterForNotCraftedItems = configFile.Bind<string>("2 - Config Workstations", "Character for Not Crafted Items", "!", "Character to show the item has never been crafted (default = '!')"); repairAll = configFile.Bind<Toggle>("2 - Config Workstations", "Repair All", Toggle.On, "Enable/disable repairing all items in one click (default = true)"); repairAllItemsText = configFile.Bind<string>("2 - Config Workstations", "Repair All Text", "Repair all items", "Repair all text for repair button tooltip"); vendorBtnGamepadKey = configFile.Bind<KeyCode>("3 - Config Vendors", "Button Gamepad Key", (KeyCode)330, "Gamepad key to link the button (default: JoystickButton0 - A"); vendorBtnPosition = configFile.Bind<Vector2>("3 - Config Vendors", "Button Position", new Vector2(-90f, 573f), "Left corner position for the hint button (default: x=-90, y=573)"); vendorBtnSize = configFile.Bind<Vector2>("3 - Config Vendors", "Button Size", new Vector2(29f, 29f), "Width/Height of the hint button (default: x=29, y=29)"); vendorCharacterForNotObtainedItems = configFile.Bind<string>("3 - Config Vendors", "Character for Not Obtained Items", "!", "Character to show the item has never been obtained (default = '!')"); vendorHiddenElementsText = configFile.Bind<string>("3 - Config Vendors", "Hidden elements translate text", "Hidden\nelements", "Translation for hidden elements count text in the vendor window"); SetupWatcher(); } private static void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private static void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { Logger.Log("Attempting to reload configuration..."); configFile.Reload(); SettingsChanged(null, null); } catch { Logger.LogError("There was an issue loading " + ConfigFileName); } } private static void SettingsChanged(object sender, EventArgs e) { if ((Object)(object)HintButtonPatch.hintButton != (Object)null) { HintButtonPatch.updateHintButton(InventoryGui.instance); } if (InventoryGui.IsVisible()) { GameManager.CallPrivateMethod(InventoryGui.instance, "SetupCrafting"); } if ((Object)(object)StoreGuiShowPatch.vendorHintButton != (Object)null) { StoreGuiShowPatch.updateVendorHintButton(); } if (StoreGui.IsVisible()) { GameManager.CallPrivateMethod(StoreGui.instance, "FillList"); } } static ConfigurationFile() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; } } [BepInPlugin("Turbero.CraftMeOnce", "Craft Me Once", "1.1.0")] public class CraftMeOnce : BaseUnityPlugin { public const string GUID = "Turbero.CraftMeOnce"; public const string NAME = "Craft Me Once"; public const string VERSION = "1.1.0"; private readonly Harmony harmony = new Harmony("Turbero.CraftMeOnce"); private void Awake() { ConfigurationFile.LoadConfig((BaseUnityPlugin)(object)this); harmony.PatchAll(); } private void onDestroy() { harmony.UnpatchSelf(); } } [HarmonyPatch] public class NoWarnings { [HarmonyPatch(typeof(Debug), "LogWarning", new Type[] { typeof(object), typeof(Object) })] [HarmonyPrefix] private static bool LogWarning(object message, Object context) { if (message.ToString().Contains("The LiberationSans SDF Font Asset was not found") || message.ToString().Contains("The character used for Ellipsis is not available in font asset") || message.ToString().Contains("lacks a proper counterpart in the GamepadButton enum")) { return false; } return true; } } public class GameManager { private static readonly Dictionary<string, TMP_FontAsset> cachedFonts = new Dictionary<string, TMP_FontAsset>(); public static object GetPrivateValue(object obj, string name, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic) { return obj.GetType().GetField(name, bindingAttr)?.GetValue(obj); } public static void SetPrivateValue(object obj, string name, object value, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic) { obj.GetType().GetField(name, bindingAttr)?.SetValue(obj, value); } public static object GetPrivateMethod(object obj, string name, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic, object[] args = null) { return obj.GetType().GetMethod(name, bindingAttr)?.Invoke(obj, args); } public static void CallPrivateMethod(object obj, string name, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic, object[] args = null) { obj.GetType().GetMethod(name, bindingAttr)?.Invoke(obj, args); } public static void BindGamePad(Transform buttonGo, KeyCode gamepadKeyCode, Vector2 hintAnchoredPosition, InventoryGui inventoryGui = null) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00b4: Unknown result type (might be due to invalid IL or missing references) UIGamePad val = null; if (((Component)buttonGo).TryGetComponent<UIGamePad>(ref val)) { string text = KeyCodeToString(gamepadKeyCode); if (ZInput.instance != null) { ((TMP_Text)val.m_hint.GetComponentInChildren<TextMeshProUGUI>(true)).text = ZInput.instance.GetBoundKeyString(text, true); } else { ZInput.Initialize(); TextMeshProUGUI componentInChildren = val.m_hint.GetComponentInChildren<TextMeshProUGUI>(true); ZInput instance = ZInput.instance; ((TMP_Text)componentInChildren).text = ((instance != null) ? instance.GetBoundKeyString(text, true) : null); } RectTransform component = val.m_hint.GetComponent<RectTransform>(); if (hintAnchoredPosition != Vector2.zero || component.anchoredPosition != Vector2.zero) { val.m_hint.GetComponent<RectTransform>().anchoredPosition = hintAnchoredPosition; } val.m_zinputKey = text; val.m_keyCode = gamepadKeyCode; UIGroupHandler value = default(UIGroupHandler); if ((Object)(object)inventoryGui != (Object)null && ((Component)inventoryGui.m_crafting).TryGetComponent<UIGroupHandler>(ref value)) { SetPrivateValue(val, "m_group", value); } } } public static string KeyCodeToString(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected I4, but got Unknown int num = keyCode - 330; if (1 == 0) { } string result = num switch { 1 => "JoyButtonB", 2 => "JoyButtonX", 3 => "JoyButtonY", 4 => "JoyLBumper", 5 => "JoyRBumper", 6 => "JoyBack", 7 => "JoyStart", 8 => "JoyLStick", 9 => "JoyRStick", 10 => "JoyDPadLeft", 11 => "JoyDPadRight", 12 => "JoyDPadUp", 13 => "JoyDPadDown", 14 => "JoyLTrigger", 15 => "JoyRTrigger", 16 => "JoyButtonA", 17 => "JoyButtonB", 18 => "JoyButtonX", 19 => "JoyButtonY", _ => "JoyButtonA", }; if (1 == 0) { } return result; } public static TMP_FontAsset getFontAsset(string name) { if (!cachedFonts.ContainsKey(name)) { Logger.Log("Finding " + name + " font..."); TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset val in array) { if (((Object)val).name == name) { Logger.Log(name + " font found."); cachedFonts.Add(name, val); return val; } } Logger.Log(name + " font NOT found."); return null; } return GeneralExtensions.GetValueSafe<string, TMP_FontAsset>(cachedFonts, name); } } public static class Logger { private static readonly ManualLogSource logger = Logger.CreateLogSource("Craft Me Once"); internal static void Log(object s) { if (ConfigurationFile.debug.Value != ConfigurationFile.Toggle.Off) { logger.LogInfo((object)s?.ToString()); } } internal static void LogInfo(object s) { logger.LogInfo((object)s?.ToString()); } internal static void LogWarning(object s) { string text = "Craft Me Once 1.1.0: " + ((s != null) ? s.ToString() : "null"); Debug.LogWarning((object)text); } internal static void LogError(object s) { string text = "Craft Me Once 1.1.0: " + ((s != null) ? s.ToString() : "null"); Debug.LogError((object)text); } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] public static class UpdateCraftingPanelPatch { private static void Postfix(InventoryGui __instance, List<Recipe> recipes) { Logger.Log("UpdateCraftingPanelPatch - Postfix"); if (ConfigurationFile.modEnabled.Value == ConfigurationFile.Toggle.Off) { if ((Object)(object)HintButtonPatch.hintButton != (Object)null) { ((Component)HintButtonPatch.hintButton).gameObject.SetActive(false); } } else { if ((Object)(object)HintButtonPatch.hintButton == (Object)null) { return; } HintButtonPatch.updateHintButton(__instance); if (ConfigurationFile.hintMode.Value == ConfigurationFile.HintMode.Off || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Player.m_localPlayer.GetCurrentCraftingStation() == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Transform val = ((Component)__instance).transform.Find("root/Crafting/RecipeList/Recipes/ListRoot"); int childCount = val.childCount; for (int i = 0; i < childCount; i++) { TextMeshProUGUI component = ((Component)val.GetChild(i).Find("name")).GetComponent<TextMeshProUGUI>(); if ((Object)(object)component == (Object)null) { continue; } Logger.Log("Workstation | translatedText " + ((TMP_Text)component).text); if (Caching.findTranslatedKey(component, out var recipeKey)) { bool flag = localPlayer.IsKnownMaterial(recipeKey); Logger.Log("found itemRecipeKeyValue: " + ((object)component)?.ToString() + " - " + recipeKey + " - IsKnownMaterial: " + flag); if (!flag && ConfigurationFile.hintMode.Value != ConfigurationFile.HintMode.Off) { ((TMP_Text)component).text = "<color=yellow>" + ConfigurationFile.characterForNotCraftedItems.Value + "</color> " + Localization.instance.Localize(((TMP_Text)component).text); } else { ((TMP_Text)component).text = Localization.instance.Localize(((TMP_Text)component).text); } } } } } } [HarmonyPatch(typeof(InventoryGui), "SetupCrafting")] public static class HintButtonPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__3_0; internal void <Prefix>b__3_0() { ConfigurationFile.hintMode.Value = ((ConfigurationFile.hintMode.Value == ConfigurationFile.HintMode.Off) ? ConfigurationFile.HintMode.On : ConfigurationFile.HintMode.Off); } } private static GameObject hintButtonGo; public static Button hintButton; private static TextMeshProUGUI buttonText; private static void Prefix(InventoryGui __instance) { //IL_0095: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown if ((Object)(object)hintButtonGo == (Object)null || (Object)(object)hintButton == (Object)null || (Object)(object)buttonText == (Object)null) { Transform val = ((Component)__instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton"); Transform transform = ((Component)__instance.m_crafting).transform; hintButtonGo = Object.Instantiate<GameObject>(((Component)val).gameObject, transform); ((Object)hintButtonGo).name = "HintButton"; hintButtonGo.transform.SetParent(transform, false); GameManager.BindGamePad(hintButtonGo.transform, ConfigurationFile.btnGamepadKey.Value, new Vector2(-30f, 0f), __instance); RectTransform component = hintButtonGo.GetComponent<RectTransform>(); component.anchoredPosition = ConfigurationFile.btnPosition.Value; component.sizeDelta = ConfigurationFile.btnSize.Value; buttonText = hintButtonGo.GetComponentInChildren<TextMeshProUGUI>(); ((TMP_Text)buttonText).font = GameManager.getFontAsset("Valheim-AveriaSerifLibre"); ((TMP_Text)buttonText).fontStyle = (FontStyles)0; ((TMP_Text)buttonText).alignment = (TextAlignmentOptions)514; hintButton = hintButtonGo.GetComponent<Button>(); hintButton.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = hintButton.onClick; object obj = <>c.<>9__3_0; if (obj == null) { UnityAction val2 = delegate { ConfigurationFile.hintMode.Value = ((ConfigurationFile.hintMode.Value == ConfigurationFile.HintMode.Off) ? ConfigurationFile.HintMode.On : ConfigurationFile.HintMode.Off); }; <>c.<>9__3_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } ((TMP_Text)buttonText).text = ConfigurationFile.characterForNotCraftedItems.Value; ((Graphic)buttonText).color = ((ConfigurationFile.hintMode.Value != ConfigurationFile.HintMode.Off) ? Color.yellow : Color.gray); } public static void updateHintButton(InventoryGui inventoryGui) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) ((Component)hintButton).gameObject.SetActive(ConfigurationFile.modEnabled.Value == ConfigurationFile.Toggle.On && ConfigurationFile.hintMode.Value != ConfigurationFile.HintMode.Always && ((Component)((Transform)inventoryGui.m_crafting).Find("TabsButtons/Craft")).gameObject.activeSelf); ((Component)hintButton).GetComponent<RectTransform>().anchoredPosition = ConfigurationFile.btnPosition.Value; ((Component)hintButton).GetComponent<RectTransform>().sizeDelta = ConfigurationFile.btnSize.Value; GameManager.BindGamePad(((Component)hintButton).gameObject.transform, ConfigurationFile.btnGamepadKey.Value, new Vector2(ConfigurationFile.btnSize.Value.x - 1f, 0f), InventoryGui.instance); } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGuiRepairAllItemsText { [HarmonyPostfix] public static void Postfix(InventoryGui __instance) { ((Component)((Component)InventoryGui.instance).transform.Find("root/Crafting/RepairButton")).GetComponent<UITooltip>().m_text = ((ConfigurationFile.repairAll.Value == ConfigurationFile.Toggle.On) ? ConfigurationFile.repairAllItemsText.Value : "$inventory_repairbutton"); } } [HarmonyPatch(typeof(InventoryGui), "OnRepairPressed")] public static class InventoryGuiRepairAllItemsClick { [HarmonyPostfix] public static void Postfix(InventoryGui __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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: Unknown result type (might be due to invalid IL or missing references) if (ConfigurationFile.repairAll.Value == ConfigurationFile.Toggle.Off) { return; } CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation(); if ((Object)(object)currentCraftingStation != (Object)null) { int num = 0; while ((bool)GameManager.GetPrivateMethod(__instance, "HaveRepairableItems")) { GameManager.CallPrivateMethod(__instance, "RepairOneItem"); num++; } if (num > 0) { currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } } } [HarmonyPatch(typeof(StoreGui), "Show")] public class StoreGuiShowPatch { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__7_0; internal void <createVendorHintButton>b__7_0() { ConfigurationFile.vendorHintMode.Value = ((ConfigurationFile.vendorHintMode.Value == ConfigurationFile.HintMode.Off) ? ConfigurationFile.HintMode.On : ConfigurationFile.HintMode.Off); } } private static GameObject vendorHintButtonGo; public static Button vendorHintButton; private static TextMeshProUGUI vendorButtonText; private static TextMeshProUGUI hiddenItemsText; private static GameObject hiddenItemsGO; public static void Postfix(StoreGui __instance, Trader trader) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)trader == (Object)null)) { Logger.Log("Trader.m_name: " + ((Object)trader).name); if ((Object)(object)vendorHintButtonGo == (Object)null || (Object)(object)vendorHintButton == (Object)null || (Object)(object)vendorButtonText == (Object)null) { createVendorHintButton(); } if ((Object)(object)hiddenItemsGO == (Object)null) { hiddenItemsGO = new GameObject("HiddenItems", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); hiddenItemsGO.transform.SetParent(((Component)__instance).transform.Find("Store"), false); hiddenItemsGO.GetComponent<RectTransform>().anchoredPosition = new Vector2(80f, -265f); hiddenItemsText = hiddenItemsGO.GetComponent<TextMeshProUGUI>(); ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).font = GameManager.getFontAsset("Valheim-AveriaSerifLibre"); ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).fontStyle = (FontStyles)1; ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).fontSize = 16f; ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).fontSizeMax = 16f; ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).fontSizeMin = 8f; ((TMP_Text)((Component)hiddenItemsText).GetComponent<TextMeshProUGUI>()).alignment = (TextAlignmentOptions)514; } updateVendorHintButton(); updateVendorHintFlags(__instance); } } public static void updateVendorHintFlags(StoreGui storeGui) { //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown List<GameObject> list = (List<GameObject>)GameManager.GetPrivateValue(storeGui, "m_itemList"); foreach (GameObject item in list) { Transform obj = Utils.FindChild(item.transform, "name", (IterativeSearchType)0); GameObject val = ((obj != null) ? ((Component)obj).gameObject : null); if (!((Object)(object)val != (Object)null)) { continue; } TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>(); if ((Object)(object)component == (Object)null) { continue; } Logger.Log("Vendor | translatedText " + ((TMP_Text)component).text); if (Caching.findTranslatedKey(component, out var recipeKey)) { bool flag = Player.m_localPlayer.IsKnownMaterial(recipeKey); Logger.Log("found itemRecipeKeyValue: " + ((object)component)?.ToString() + " - " + recipeKey + " - IsKnownMaterial: " + flag); if (!flag && ConfigurationFile.vendorHintMode.Value != ConfigurationFile.HintMode.Off) { ((TMP_Text)component).text = "<color=yellow>" + ConfigurationFile.vendorCharacterForNotObtainedItems.Value + "</color> " + Localization.instance.Localize(((TMP_Text)component).text); } else { ((TMP_Text)component).text = Localization.instance.Localize(((TMP_Text)component).text); } } } if ((Object)(object)hiddenItemsGO == (Object)null) { return; } Trader val2 = (Trader)GameManager.GetPrivateValue(storeGui, "m_trader"); int num = val2.m_items.Count - list.Count; foreach (TradeItem item2 in val2.m_items) { if (!string.IsNullOrEmpty(item2.m_buyKey) && ((Humanoid)Player.m_localPlayer).HaveUniqueKey(item2.m_buyKey)) { num--; } } string text = ((num == 0) ? "" : (ConfigurationFile.vendorHiddenElementsText.Value + ": " + num)); ((TMP_Text)hiddenItemsGO.GetComponent<TextMeshProUGUI>()).text = text; } private static void createVendorHintButton() { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown Transform val = ((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton"); Transform val2 = ((Component)StoreGui.instance).transform.Find("Store"); vendorHintButtonGo = Object.Instantiate<GameObject>(((Component)val).gameObject, val2); ((Object)vendorHintButtonGo).name = "VendorHintButton"; vendorHintButtonGo.transform.SetParent(val2, false); vendorButtonText = vendorHintButtonGo.GetComponentInChildren<TextMeshProUGUI>(); ((TMP_Text)vendorButtonText).font = GameManager.getFontAsset("Valheim-AveriaSerifLibre"); ((TMP_Text)vendorButtonText).fontStyle = (FontStyles)0; ((TMP_Text)vendorButtonText).alignment = (TextAlignmentOptions)514; vendorHintButton = vendorHintButtonGo.GetComponent<Button>(); vendorHintButton.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = vendorHintButton.onClick; object obj = <>c.<>9__7_0; if (obj == null) { UnityAction val3 = delegate { ConfigurationFile.vendorHintMode.Value = ((ConfigurationFile.vendorHintMode.Value == ConfigurationFile.HintMode.Off) ? ConfigurationFile.HintMode.On : ConfigurationFile.HintMode.Off); }; <>c.<>9__7_0 = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } public static void updateVendorHintButton() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) //IL_0081: 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_00a0: Unknown result type (might be due to invalid IL or missing references) ((Component)vendorHintButton).GetComponent<RectTransform>().anchoredPosition = ConfigurationFile.vendorBtnPosition.Value; ((Component)vendorHintButton).GetComponent<RectTransform>().sizeDelta = ConfigurationFile.vendorBtnSize.Value; ((TMP_Text)vendorButtonText).text = ConfigurationFile.vendorCharacterForNotObtainedItems.Value; ((Graphic)vendorButtonText).color = ((ConfigurationFile.vendorHintMode.Value != ConfigurationFile.HintMode.Off) ? Color.yellow : Color.gray); GameManager.BindGamePad(((Component)vendorHintButton).gameObject.transform, ConfigurationFile.vendorBtnGamepadKey.Value, new Vector2(ConfigurationFile.vendorBtnSize.Value.x - 1f, 0f)); ((Component)vendorHintButton).gameObject.SetActive(ConfigurationFile.modEnabled.Value == ConfigurationFile.Toggle.On && ConfigurationFile.vendorHintMode.Value != ConfigurationFile.HintMode.Always); } } [HarmonyPatch(typeof(StoreGui), "FillList")] public class StoreGuiFillListPatch { public static void Postfix(StoreGui __instance) { StoreGuiShowPatch.updateVendorHintFlags(__instance); } }