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 TakeAllCooked v1.1.0
TakeAllCooked.dll
Decompiled 4 days agousing System.Collections.Generic; 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [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.1.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "petri.valheim.takeallcooked"; public const string ModName = "Take All Cooked"; public const string ModVersion = "1.1.0"; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<bool> EnableMod; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<KeyboardShortcut> TakeAllShortcut; internal static ConfigEntry<string> HoverText; internal static ConfigEntry<bool> EnableNearbyStations; internal static ConfigEntry<float> NearbyStationRadius; internal static ConfigEntry<int> MaxNearbyStations; private void Awake() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the mod."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Enable debug logging."); TakeAllShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "TakeAllShortcut", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Shortcut used to take all finished outputs from cooking stations."); HoverText = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "HoverText", "Take all cooked", "Text shown in the cooking station hover prompt."); EnableNearbyStations = ((BaseUnityPlugin)this).Config.Bind<bool>("Nearby Stations", "EnableNearbyStations", true, "If enabled, the shortcut also collects finished outputs from nearby cooking stations."); NearbyStationRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Nearby Stations", "NearbyStationRadius", 4f, "Radius in meters used to find nearby cooking stations."); MaxNearbyStations = ((BaseUnityPlugin)this).Config.Bind<int>("Nearby Stations", "MaxNearbyStations", 5, "Maximum number of cooking stations processed per shortcut press, including the hovered station."); _harmony = new Harmony("petri.valheim.takeallcooked"); _harmony.PatchAll(); Log.LogInfo((object)"Take All Cooked 1.1.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static void DebugLog(string message) { ConfigEntry<bool> 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[<color=yellow><b>" + shortcutDisplayText + "</b></color>] " + Plugin.HoverText.Value; } } private static bool HasAnyDoneItem(CookingStation station) { return CookingStationInteractPatch.CountDoneSlots(station) > 0; } private static string GetShortcutDisplayText() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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"; } string text = ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).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 sealed class CookingStationDistance { public CookingStation Station; public float Distance; } 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_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) 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; } List<CookingStation> targetStations = GetTargetStations(__instance); int num = 0; foreach (CookingStation item in targetStations) { num += CountDoneSlots(item); } if (num <= 0) { Plugin.DebugLog("TakeAllCooked: no finished outputs found, allowing vanilla interaction."); return true; } int num2 = 0; int num3 = 0; foreach (CookingStation item2 in targetStations) { int num4 = CountDoneSlots(item2); if (num4 > 0) { num3++; int num5 = TakeAllDoneItems(item2, user, num4); num2 += num5; Plugin.DebugLog($"TakeAllCooked: removed {num5} finished output(s) from station {((Object)item2).name}."); } } Plugin.DebugLog($"TakeAllCooked: removed {num2} finished output(s) from {num3} station(s) with ready output(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_0066: 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_008e: 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_0098: 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) //IL_00d2: 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 skillFactor = ((Character)localPlayer).GetSkillFactor((SkillType)105); float num2 = skillFactor * 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); SlotData slotData = new SlotData(); slotData.ItemName = (array[1] as string) ?? string.Empty; slotData.CookedTime = ((array[2] is float num) ? num : 0f); slotData.Status = array[3]; return slotData; } 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 List<CookingStation> GetTargetStations(CookingStation origin) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) List<CookingStation> list = new List<CookingStation>(); if ((Object)(object)origin == (Object)null) { return list; } list.Add(origin); ConfigEntry<bool> enableNearbyStations = Plugin.EnableNearbyStations; if (enableNearbyStations == null || !enableNearbyStations.Value) { return list; } float num = Mathf.Max(0f, Plugin.NearbyStationRadius.Value); int num2 = Mathf.Max(1, Plugin.MaxNearbyStations.Value); if (num <= 0f || num2 <= 1) { return list; } CookingStation[] array = Object.FindObjectsByType<CookingStation>((FindObjectsSortMode)0); List<CookingStationDistance> list2 = new List<CookingStationDistance>(); CookingStation[] array2 = array; foreach (CookingStation val in array2) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)origin)) { float num3 = Vector3.Distance(((Component)origin).transform.position, ((Component)val).transform.position); if (!(num3 > num)) { list2.Add(new CookingStationDistance { Station = val, Distance = num3 }); } } } list2.Sort((CookingStationDistance a, CookingStationDistance b) => a.Distance.CompareTo(b.Distance)); foreach (CookingStationDistance item in list2) { if (list.Count >= num2) { break; } list.Add(item.Station); } Plugin.DebugLog($"TakeAllCooked: found {list.Count} target cooking station(s)."); return list; } } }