using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TakeAllCooked")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TakeAllCooked")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("98f7bdb2-540a-4bcb-8ec9-144aeba4e630")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace TakeAllCooked { [BepInPlugin("petri.valheim.takeallcooked", "Take All Cooked", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "petri.valheim.takeallcooked"; public const string ModName = "Take All Cooked"; public const string ModVersion = "1.0.0"; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry EnableMod; internal static ConfigEntry DebugLogging; internal static ConfigEntry TakeAllShortcut; internal static ConfigEntry HoverText; private void Awake() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; EnableMod = ((BaseUnityPlugin)this).Config.Bind("General", "EnableMod", true, "Enable or disable the mod."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("General", "DebugLogging", false, "Enable debug logging."); TakeAllShortcut = ((BaseUnityPlugin)this).Config.Bind("Controls", "TakeAllShortcut", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Shortcut used to take all cooked food from the cooking station."); HoverText = ((BaseUnityPlugin)this).Config.Bind("UI", "HoverText", "Take all cooked", "Text shown in the cooking station hover prompt."); _harmony = new Harmony("petri.valheim.takeallcooked"); _harmony.PatchAll(); Log.LogInfo((object)"Take All Cooked 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static void DebugLog(string message) { ConfigEntry debugLogging = DebugLogging; if (debugLogging != null && debugLogging.Value) { Log.LogInfo((object)message); } } } } namespace TakeAllCooked.Patches { [HarmonyPatch(typeof(CookingStation), "GetHoverText")] public static class CookingStationHoverTextPatch { private static void Postfix(CookingStation __instance, ref string __result) { if (Plugin.EnableMod.Value && !string.IsNullOrEmpty(__result) && HasAnyDoneItem(__instance)) { string shortcutDisplayText = GetShortcutDisplayText(); __result = __result + "\n[" + shortcutDisplayText + "] " + Plugin.HoverText.Value; } } private static bool HasAnyDoneItem(CookingStation station) { return CookingStationInteractPatch.CountDoneSlots(station) > 0; } private static string GetShortcutDisplayText() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Plugin.TakeAllShortcut.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0) { return "Unbound"; } KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; string text = ((object)(KeyCode)(ref mainKey)).ToString(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { text = $"{modifier}+{text}"; } return text.Replace("LeftShift", "LShift").Replace("RightShift", "RShift").Replace("LeftControl", "LCtrl") .Replace("RightControl", "RCtrl") .Replace("LeftAlt", "LAlt") .Replace("RightAlt", "RAlt"); } } [HarmonyPatch(typeof(CookingStation), "Interact")] public static class CookingStationInteractPatch { private sealed class SlotData { public string ItemName; public float CookedTime; public object Status; } private static readonly FieldInfo NViewField = typeof(CookingStation).GetField("m_nview", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo GetSlotMethod = typeof(CookingStation).GetMethod("GetSlot", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly MethodInfo IsItemDoneMethod = typeof(CookingStation).GetMethod("IsItemDone", BindingFlags.Instance | BindingFlags.NonPublic); private static bool Prefix(CookingStation __instance, Humanoid user, bool hold, bool alt, ref bool __result) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.EnableMod.Value) { return true; } if (hold || (Object)(object)user == (Object)null) { return true; } KeyboardShortcut value = Plugin.TakeAllShortcut.Value; if (!((KeyboardShortcut)(ref value)).IsPressed()) { return true; } int num = CountDoneSlots(__instance); if (num <= 0) { Plugin.DebugLog("TakeAllCooked: no cooked items found, allowing vanilla interaction."); return true; } int num2 = TakeAllDoneItems(__instance, user, num); Plugin.DebugLog($"TakeAllCooked: removed {num2} cooked slot(s)."); __result = num2 > 0; return false; } internal static int CountDoneSlots(CookingStation station) { if (station?.m_slots == null || GetSlotMethod == null || IsItemDoneMethod == null) { return 0; } int num = 0; for (int i = 0; i < station.m_slots.Length; i++) { SlotData slot = GetSlot(station, i); if (!string.IsNullOrEmpty(slot.ItemName) && IsItemDone(station, slot.ItemName)) { num++; } } return num; } internal static int TakeAllDoneItems(CookingStation station, Humanoid user, int readySlots) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) object? obj = NViewField?.GetValue(station); ZNetView val = (ZNetView)((obj is ZNetView) ? obj : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { Plugin.DebugLog("TakeAllCooked: missing or invalid ZNetView."); return 0; } int num = 0; for (int i = 0; i < readySlots; i++) { int pickupAmount = GetPickupAmount(station); val.InvokeRPC("RPC_RemoveDoneItem", new object[2] { ((Component)user).transform.position, pickupAmount }); num++; } return num; } private static int GetPickupAmount(CookingStation station) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_00ad: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 1; } ((Character)localPlayer).RaiseSkill((SkillType)105, 0.6f); int num = 1; if ((Object)(object)InventoryGui.instance == (Object)null) { return num; } float num2 = ((Character)localPlayer).GetSkillFactor((SkillType)105) * InventoryGui.instance.m_craftBonusChance; if (Random.value < num2) { num += InventoryGui.instance.m_craftBonusAmount; DamageText instance = DamageText.instance; if (instance != null) { instance.ShowText((TextType)7, ((Component)station).transform.position + Vector3.up, "+" + InventoryGui.instance.m_craftBonusAmount, true); } InventoryGui.instance.m_craftBonusEffect.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1); Plugin.DebugLog("TakeAllCooked: bonus food cooking station!"); } return num; } private static SlotData GetSlot(CookingStation station, int slot) { object[] array = new object[4] { slot, null, 0f, null }; GetSlotMethod.Invoke(station, array); return new SlotData { ItemName = ((array[1] as string) ?? string.Empty), CookedTime = ((array[2] is float num) ? num : 0f), Status = array[3] }; } private static bool IsItemDone(CookingStation station, string itemName) { object obj = IsItemDoneMethod.Invoke(station, new object[1] { itemName }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static bool IsBurntItem(CookingStation station, string itemName) { ItemDrop overCookedItem = station.m_overCookedItem; if ((Object)(object)overCookedItem != (Object)null) { return itemName == ((Object)overCookedItem).name; } return false; } } }