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 AutoOven v1.0.7
AutoOven.dll
Decompiled 8 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ConditionalConfigSync; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MrGay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AutoOven")] [assembly: AssemblyTitle("AutoOven")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AutoOven { [BepInPlugin("mrgay.autoven", "Auto Oven", "1.0.7")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class AutoOvenPlugin : BaseUnityPlugin { private sealed class OvenSlots { public static bool HasFreeSlot(CookingStation oven) { return FindFreeSlot(oven) >= 0; } public static int FindFreeSlot(CookingStation oven) { for (int i = 0; i < oven.m_slots.Length; i++) { if (!TryGetSlot(oven, i, out string _, out object _)) { return i; } } return -1; } public static bool SlotContainsItem(CookingStation oven, int slot, string itemName) { if (TryGetSlot(oven, slot, out string itemName2, out object _)) { return itemName2 == itemName; } return false; } public static bool TryTakeFinished(CookingStation oven, out ItemData? item, out int slot) { item = null; slot = -1; for (int i = 0; i < oven.m_slots.Length; i++) { if (TryGetSlot(oven, i, out string itemName, out object status) && !(status?.ToString() != "Done")) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemName); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { item = val.m_itemData.Clone(); item.m_stack = 1; slot = i; return true; } } } return false; } public static bool RemoveFinished(CookingStation oven, int slot) { ZNetView component = ((Component)oven).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } component.ClaimOwnership(); MethodInfo method = ((object)oven).GetType().GetMethod("SetSlot", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { return false; } object obj = Enum.Parse(method.GetParameters()[3].ParameterType, "NotDone"); method.Invoke(oven, new object[5] { slot, "", 0f, obj, false }); ((object)oven).GetType().GetMethod("RPC_SetSlotVisual", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(oven, new object[3] { 0L, slot, "" }); return true; } public static bool ContainsItem(CookingStation oven, string itemName) { for (int i = 0; i < oven.m_slots.Length; i++) { if (TryGetSlot(oven, i, out string itemName2, out object _) && itemName2 == itemName) { return true; } } return false; } private static bool TryGetSlot(CookingStation oven, int slot, out string itemName, out object? status) { itemName = ""; status = null; MethodInfo method = ((object)oven).GetType().GetMethod("GetSlot", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { return false; } object[] array = new object[5] { slot, null, 0f, null, false }; method.Invoke(oven, array); itemName = (array[1] as string) ?? ""; status = array[3]; return itemName.Length > 0; } } public const string PluginGuid = "mrgay.autoven"; public const string PluginName = "Auto Oven"; public const string PluginVersion = "1.0.7"; private readonly List<CookingStation> ovens = new List<CookingStation>(); private ConfigEntry<float> scanDistance; private ConfigEntry<float> scanInterval; private ConfigEntry<bool> enforceServerConfigSync; private ConfigEntry<bool> logScanSummary; private ConfigEntry<bool> enableAutoFueling; private ConfigSync configSync; private float nextScan; private bool adapterWarningLogged; private int scanCount; private void Awake() { //IL_00b3: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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) //IL_00e5: Expected O, but got Unknown scanDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Automation", "distance", 10f, "Maximum distance in meters between an oven and a chest used for input or output."); scanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Automation", "interval", 3f, "Seconds between server-side oven scans."); enforceServerConfigSync = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enforce_Server_Config_Sync", true, "When enabled, the server controls the automation settings for connected clients."); logScanSummary = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Log_Scan_Summary", false, "When enabled, periodically log the number of active ovens found by Auto Oven."); enableAutoFueling = ((BaseUnityPlugin)this).Config.Bind<bool>("Automation", "Enable_Auto_Fueling", false, "When enabled, nearby chests supply the oven's configured fuel item automatically."); configSync = new ConfigSync("mrgay.autoven") { DisplayName = "Auto Oven", CurrentVersion = "1.0.7", MinimumRequiredVersion = "1.0.7", ModRequired = true }; ((ConditionalConfigSync)configSync).AllowClientConfigUpdatesWhenUnlocked = true; ((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(enforceServerConfigSync); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(logScanSummary, (ConfigSyncMode)0); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(enableAutoFueling, (ConfigSyncMode)0); ((ConditionalConfigSync)configSync).AddConfigEntry<float>(scanDistance, (ConfigSyncMode)1, true); ((ConditionalConfigSync)configSync).AddConfigEntry<float>(scanInterval, (ConfigSyncMode)1, true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Auto Oven 1.0.7 loaded. Automation runs on the server only."); } private void Update() { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && !(Time.time < nextScan)) { nextScan = Time.time + Mathf.Max(0.25f, scanInterval.Value); ScanOvens(); } } private void ScanOvens() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) scanCount++; ovens.Clear(); ovens.AddRange(Object.FindObjectsOfType<CookingStation>()); foreach (CookingStation oven in ovens) { if (!((Object)(object)oven == (Object)null) && ((Behaviour)oven).isActiveAndEnabled) { List<Container> chests = FindNearbyChests(((Component)oven).transform.position); UnloadFinishedItems(oven, chests); if (enableAutoFueling.Value) { FuelOven(oven, chests); } LoadBakeableItems(oven, chests); } } if (logScanSummary.Value && scanCount % 20 == 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Scan {scanCount}: found {ovens.Count} active ovens."); } UnloadFinishedPersistedOvens(); } private void UnloadFinishedPersistedOvens() { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { CookingStation component = prefab.GetComponent<CookingStation>(); if ((Object)(object)component == (Object)null) { continue; } List<ZDO> list = new List<ZDO>(); int num = 0; while (ZDOMan.instance.GetAllZDOsWithPrefabIterative(((Object)prefab).name, list, ref num)) { } foreach (ZDO item in list) { if (ZNetScene.instance.HaveInstance(item)) { continue; } for (int i = 0; i < component.m_slots.Length; i++) { string text = item.GetString("slot" + i, ""); if (text.Length != 0 && item.GetInt("slotstatus" + i, 0) == 1) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null) { ItemDrop.DropItem(val.m_itemData.Clone(), 1, item.GetPosition() + Vector3.up, Quaternion.identity); } item.Set("slot" + i, ""); item.Set("slot" + i, 0f); item.Set("slotstatus" + i, 0); ZDOMan.instance.SetDirtySector(item); } } } } } private List<Container> FindNearbyChests(Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from container in Object.FindObjectsOfType<Container>() where (Object)(object)container != (Object)null && ((Behaviour)container).isActiveAndEnabled select new { Container = container, Distance = Vector3.Distance(position, ((Component)container).transform.position) } into entry where entry.Distance <= Mathf.Max(0f, scanDistance.Value) orderby entry.Distance select entry.Container).ToList(); } private void LoadBakeableItems(CookingStation oven, List<Container> chests) { bool flag; do { flag = false; foreach (Container chest in chests) { if (!OvenSlots.HasFreeSlot(oven)) { return; } foreach (ItemData item in chest.GetInventory().GetAllItems().ToList()) { if (!OvenSlots.HasFreeSlot(oven)) { return; } if (TryAddToOven(oven, chest, item)) { flag = true; } } } } while (flag); } private void FuelOven(CookingStation oven, List<Container> chests) { ItemDrop fuelItem = oven.m_fuelItem; if ((Object)(object)fuelItem == (Object)null || oven.m_maxFuel <= 0) { return; } MethodInfo method = ((object)oven).GetType().GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo method2 = ((object)oven).GetType().GetMethod("RPC_AddFuel", BindingFlags.Instance | BindingFlags.NonPublic); ZNetView component = ((Component)oven).GetComponent<ZNetView>(); if (method == null || method2 == null || (Object)(object)component == (Object)null || !component.IsValid()) { LogAdapterWarning("CookingStation fuel API or ZNetView was not found."); return; } string name = fuelItem.m_itemData.m_shared.m_name; while (Convert.ToSingle(method.Invoke(oven, null)) < (float)oven.m_maxFuel) { bool flag = false; foreach (Container chest in chests) { Inventory inventory = chest.GetInventory(); ItemData item = inventory.GetItem(name, -1, false); if (item != null && ClaimContainerOwnership(chest)) { component.ClaimOwnership(); float num = Convert.ToSingle(method.Invoke(oven, null)); method2.Invoke(oven, new object[1] { 0L }); if (!(Convert.ToSingle(method.Invoke(oven, null)) <= num)) { inventory.RemoveItem(item, 1); flag = true; break; } } } if (!flag) { break; } } } private void UnloadFinishedItems(CookingStation oven, List<Container> chests) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) int slot; do { if (OvenSlots.TryTakeFinished(oven, out ItemData item, out slot)) { Container val = ((IEnumerable<Container>)chests).FirstOrDefault((Func<Container, bool>)((Container chest) => chest.GetInventory().HaveItem(item.m_shared.m_name, true))); if (val == null) { val = chests.FirstOrDefault(); } if (!((Object)(object)val != (Object)null) || !ClaimContainerOwnership(val) || !val.GetInventory().AddItem(item)) { ItemDrop.DropItem(item, item.m_stack, ((Component)oven).transform.position + Vector3.up, Quaternion.identity); } continue; } break; } while (OvenSlots.RemoveFinished(oven, slot)); } private bool TryAddToOven(CookingStation oven, Container chest, ItemData item) { try { Inventory inventory = chest.GetInventory(); ZNetView component = ((Component)oven).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { LogAdapterWarning("CookingStation has no valid ZNetView."); return false; } string itemName = ((Object)item.m_dropPrefab).name; if (!oven.m_conversion.Any((ItemConversion conversion) => (Object)(object)conversion.m_from != (Object)null && ((Object)((Component)conversion.m_from).gameObject).name == itemName)) { return false; } int num = OvenSlots.FindFreeSlot(oven); if (num < 0) { return false; } if (!ClaimContainerOwnership(chest)) { return false; } component.ClaimOwnership(); MethodInfo method = typeof(CookingStation).GetMethod("RPC_AddItem", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { LogAdapterWarning("CookingStation.RPC_AddItem was not found."); return false; } method.Invoke(oven, new object[3] { 0L, itemName, item.m_cheated }); if (!OvenSlots.SlotContainsItem(oven, num, itemName)) { return false; } component.InvokeRPC(ZNetView.Everybody, "RPC_SetSlotVisual", new object[2] { num, itemName }); inventory.RemoveItem(item, 1); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not load " + item.m_shared.m_name + " into an oven: " + ex.GetBaseException().Message)); return false; } } private static bool ClaimContainerOwnership(Container container) { ZNetView val = ((Component)container).GetComponent<ZNetView>() ?? ((Component)container).GetComponentInParent<ZNetView>(); if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } val.ClaimOwnership(); return val.IsOwner(); } private void LogAdapterWarning(string message) { if (!adapterWarningLogged) { adapterWarningLogged = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)(message + " Finished-item automation is disabled for this Valheim build.")); } } } }