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 Auto Feeder v0.9.3
AutoFeed.dll
Decompiled 2 days agousing 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 BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCompany("vanbushi")] [assembly: AssemblyTitle("Auto Feed")] [assembly: AssemblyDescription("Auto Feed for Valheim 1.0.x. Maintained by vanbushi; originally created by aedenthorn (https://www.nexusmods.com/valheim/mods/985).")] [assembly: AssemblyFileVersion("0.9.3.0")] [assembly: AssemblyInformationalVersion("0.9.3")] [assembly: AssemblyVersion("0.9.3.0")] public class AedenthornUtils { public static bool IgnoreKeyPresses(bool extra = false) { if (!extra) { int result; if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance = Chat.instance; result = ((instance != null && instance.HasFocus()) ? 1 : 0); } else { result = 1; } return (byte)result != 0; } int result2; if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance2 = Chat.instance; if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible()) { TextViewer instance3 = TextViewer.instance; result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0); goto IL_00d2; } } result2 = 1; goto IL_00d2; IL_00d2: return (byte)result2 != 0; } public static bool CheckKeyDown(string value) { try { return Input.GetKeyDown(value.ToLower()); } catch { return false; } } public static bool CheckKeyHeld(string value, bool req = true) { try { return Input.GetKey(value.ToLower()); } catch { return !req; } } } namespace AutoFeed; [BepInPlugin("vanbushi.AutoFeed", "Auto Feed", "0.9.3")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")] public static class UpdateConsumeItem_Patch { public static void Postfix(MonsterAI __instance, ZNetView ___m_nview, Character ___m_character, Tameable ___m_tamable, List<ItemDrop> ___m_consumeItems, float dt, bool __result) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0214: 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_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) string prefabName = GetPrefabName(((Object)((Component)__instance).gameObject).name); if (!modEnabled.Value || !isOn.Value || __result || !Object.op_Implicit((Object)(object)___m_character) || !Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsOwner() || (Object)(object)___m_tamable == (Object)null || !___m_character.IsTamed() || !___m_tamable.IsHungry() || ___m_consumeItems == null || ___m_consumeItems.Count == 0 || TrimAll(animalDisallowTypes.Value.Split(new char[1] { ',' })).Contains(prefabName)) { return; } Vector3 position = ((Component)__instance).gameObject.transform.position; Traverse val = Traverse.Create((object)__instance); val.Field("m_pathAgentType").SetValue((object)(AgentType)1); Container val2 = null; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(0f, 0f, 0f); float num = containerRange.Value + 1f; Collider[] array = Physics.OverlapSphere(position, Mathf.Max(containerRange.Value, 0f), LayerMask.GetMask(new string[1] { "piece" })); foreach (Collider val4 in array) { Transform parent = ((Component)val4).transform.parent; object obj; if (parent == null) { obj = null; } else { Transform parent2 = parent.parent; if (parent2 == null) { obj = null; } else { GameObject gameObject = ((Component)parent2).gameObject; obj = ((gameObject != null) ? gameObject.GetComponent<Container>() : null); } } Container val5 = (Container)obj; if (val5 == null) { continue; } ZNetView component = ((Component)val5).GetComponent<ZNetView>(); if (((component != null) ? new bool?(component.IsValid()) : ((bool?)null)) != true) { continue; } string[] array2 = TrimAll(containerNameStartsWith.Value.Split(new char[1] { ',' })); foreach (string value in array2) { if (!((Object)val5).name.StartsWith(value) || val5.GetInventory() == null) { continue; } Vector3 position2 = ((Component)val5).transform.position; float num2 = Vector3.Distance(position2, position); if (!(num2 < moveProximity.Value) && !val.Method("HavePath", new object[1] { position2 }).GetValue<bool>()) { continue; } bool flag = true; bool flag2 = false; foreach (ItemData item in val5.GetInventory().GetAllItems()) { if (__instance.m_consumeItems.Exists((ItemDrop val6) => val6.m_itemData.m_shared.m_name == item.m_shared.m_name) && !TrimAll(feedDisallowTypes.Value.Split(new char[1] { ',' })).Contains(((Object)item.m_dropPrefab).name)) { flag2 = true; if (!requireOnlyFood.Value) { break; } } else if (requireOnlyFood.Value) { flag = false; break; } } if (flag && flag2 && num > num2) { val2 = val5; num = num2; val3 = position2; } } } if ((Object)(object)val2 != (Object)null) { Dbgl($"{((Object)((Component)__instance).gameObject).name} found container: {val3}", pref: false, (LogLevel)32); if (requireMove.Value) { Dbgl($"{((Object)((Component)__instance).gameObject).name} {position} trying to move to {val3} {Utils.DistanceXZ(position, val3)}", pref: false, (LogLevel)32); val.Field("m_lastFindPathTime").SetValue((object)0); if (!val.Method("MoveTo", new object[4] { 0.05f, val3, moveProximity.Value, false }).GetValue<bool>()) { return; } val.Method("LookAt", new object[1] { val3 }).GetValue(); if (!val.Method("IsLookingAt", new object[3] { val3, 20f, false }).GetValue<bool>()) { return; } } using List<ItemDrop>.Enumerator enumerator2 = __instance.m_consumeItems.GetEnumerator(); while (enumerator2.MoveNext()) { ItemData item2 = val2.GetInventory().GetItem(enumerator2.Current.m_itemData.m_shared.m_name, -1, false); if (item2 != null && !TrimAll(feedDisallowTypes.Value.Split(new char[1] { ',' })).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"{((Object)((Component)__instance).gameObject).name} {position} consuming {((Object)item2.m_dropPrefab).name} at {val3}, distance {Utils.DistanceXZ(position, val3)}", pref: false, (LogLevel)32); ConsumeItem(item2, __instance, ___m_character); val2.GetInventory().RemoveItem(item2.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(val2, new object[0]); break; } } return; } Dbgl(((Object)((Component)__instance).gameObject).name + " could not find container", pref: false, (LogLevel)32); } } [HarmonyPatch(typeof(Terminal), "InputText")] public static class InputText_Patch { public static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue(); return false; } return true; } } public static ConfigEntry<bool> isDebug; public static ConfigEntry<float> containerRange; public static ConfigEntry<float> moveProximity; public static ConfigEntry<string> feedDisallowTypes; public static ConfigEntry<string> animalDisallowTypes; public static ConfigEntry<string> containerNameStartsWith; public static ConfigEntry<string> toggleKey; public static ConfigEntry<string> toggleString; public static ConfigEntry<bool> isOn; public static ConfigEntry<bool> requireMove; public static ConfigEntry<bool> requireOnlyFood; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<int> nexusID; private static BepInExPlugin context; public static void Dbgl(string str = "", bool pref = false, LogLevel logLevel = (LogLevel)32) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (isDebug.Value) { ((BaseUnityPlugin)context).Logger.Log(logLevel, (object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } public void Awake() { context = this; containerRange = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "ContainerRange", 10f, "Container range in metres."); feedDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "FeedDisallowTypes", "", "Types of item to disallow as feed, comma-separated."); animalDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "AnimalDisallowTypes", "", "Types of creature to disallow to feed, comma-separated."); requireMove = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "RequireMove", true, "Require animals to move to container to feed."); requireOnlyFood = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "RequireOnlyFood", false, "Don't allow feeding from containers that have items that the animal will not eat as well."); moveProximity = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "MoveProximity", 2f, "How close to move towards the container if RequireMove is true."); containerNameStartsWith = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "ContainerNameFilter", "piece_chest,Container", "Only feed from containers which's name start like this, comma-separated."); toggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ToggleKey", "", "Key to toggle behaviour. Leave blank to disable the toggle key. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html"); toggleString = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ToggleString", "Auto Feed: {0}", "Text to show on toggle. {0} is replaced with true/false"); modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", false, "Show debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 985, "Nexus mod ID for updates"); isOn = ((BaseUnityPlugin)this).Config.Bind<bool>("ZAuto", "IsOn", true, "Behaviour is currently on or not"); if (modEnabled.Value) { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } } public void Update() { if (AedenthornUtils.CheckKeyDown(toggleKey.Value) && !AedenthornUtils.IgnoreKeyPresses(extra: true)) { isOn.Value = !isOn.Value; ((BaseUnityPlugin)this).Config.Save(); ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format(toggleString.Value, isOn.Value), 0, (Sprite)null, false); } } public static string GetPrefabName(string name) { char[] anyOf = new char[2] { '(', ' ' }; int num = name.IndexOfAny(anyOf); if (num >= 0) { return name.Substring(0, num); } return name; } public static void ConsumeItem(ItemData item, MonsterAI monsterAI, Character character) { //IL_0025: 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_003a: 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) monsterAI.m_onConsumedItem?.Invoke(null); ((Humanoid)((character is Humanoid) ? character : null)).m_consumeItemEffects.Create(((Component)character).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); Traverse.Create((object)monsterAI).Field("m_animator").GetValue<ZSyncAnimation>() .SetTrigger("consume"); } public static string[] TrimAll(string[] a) { for (int i = 0; i < a.Length; i++) { a[i] = a[i].Trim(); } return a; } }