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 ComfyAutoPicker v1.6.0
ComfyAutoPicker.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ComfyAutoPicker")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ComfyAutoPicker")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c912b20f-2bfa-439d-ab23-9a07f0f9ee70")] [assembly: AssemblyFileVersion("1.6.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ComfyLib { public sealed class ComfyArgs { public static readonly Regex CommandRegex = new Regex("^(?<command>\\w[\\w-]*)(?:\\s+--(?:(?<arg>\\w[\\w-]*)=(?:\"(?<value>[^\"]*?)\"|(?<value>\\S+))|no(?<argfalse>\\w[\\w-]*)|(?<argtrue>\\w[\\w-]*)))*"); public static readonly char[] CommaSeparator = new char[1] { ',' }; public readonly Dictionary<string, string> ArgsValueByName = new Dictionary<string, string>(); public ConsoleEventArgs Args { get; } public string Command { get; private set; } public ComfyArgs(ConsoleEventArgs args) { Args = args; ParseArgs(Args); } private void ParseArgs(ConsoleEventArgs args) { Match match = CommandRegex.Match(args.FullLine); Command = match.Groups["command"].Value; foreach (Capture capture3 in match.Groups["argtrue"].Captures) { ArgsValueByName[capture3.Value] = "true"; } foreach (Capture capture4 in match.Groups["argfalse"].Captures) { ArgsValueByName[capture4.Value] = "false"; } CaptureCollection captures = match.Groups["arg"].Captures; CaptureCollection captures2 = match.Groups["value"].Captures; for (int i = 0; i < captures.Count; i++) { ArgsValueByName[captures[i].Value] = ((i < captures2.Count) ? captures2[i].Value : string.Empty); } } public bool TryGetValue(string argName, out string argValue) { return ArgsValueByName.TryGetValue(argName, out argValue); } public bool TryGetValue(string argName, string argShortName, out string argValue) { if (!ArgsValueByName.TryGetValue(argName, out argValue)) { return ArgsValueByName.TryGetValue(argShortName, out argValue); } return true; } public bool TryGetValue<T>(string argName, out T argValue) { argValue = default(T); if (TryGetValue(argName, out var argValue2)) { return TryConvertValue<T>(argValue2, out argValue); } return false; } public bool TryGetValue<T>(string argName, string argShortName, out T argValue) { argValue = default(T); if (TryGetValue(argName, argShortName, out var argValue2)) { return TryConvertValue<T>(argValue2, out argValue); } return false; } public bool TryGetListValue<T>(string argName, string argShortName, out List<T> argListValue) { if (!TryGetValue(argName, argShortName, out var argValue)) { argListValue = null; return false; } string[] array = argValue.Split(CommaSeparator, StringSplitOptions.RemoveEmptyEntries); argListValue = new List<T>(array.Length); for (int i = 0; i < array.Length; i++) { if (!TryConvertValue<T>(array[i], out var argValue2)) { return false; } argListValue.Add(argValue2); } return true; } public static bool TryConvertValue<T>(string argStringValue, out T argValue) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) try { Vector2 value; Vector3 value2; ZDOID value3; if (typeof(T) == typeof(string)) { argValue = (T)(object)argStringValue; } else if (typeof(T) == typeof(Vector2) && argStringValue.TryParseVector2(out value)) { argValue = (T)(object)value; } else if (typeof(T) == typeof(Vector3) && argStringValue.TryParseVector3(out value2)) { argValue = (T)(object)value2; } else if (typeof(T) == typeof(ZDOID) && argStringValue.TryParseZDOID(out value3)) { argValue = (T)(object)value3; } else { argValue = (T)Convert.ChangeType(argStringValue, typeof(T)); } return true; } catch (Exception arg) { Debug.LogError((object)$"Failed to convert value '{argStringValue}' to type {typeof(T)}: {arg}"); } argValue = default(T); return false; } } [AttributeUsage(AttributeTargets.Method)] public sealed class ComfyCommand : Attribute { } public static class ComfyCommandUtils { [CompilerGenerated] private sealed class <RegisterCommands>d__5 : IEnumerable<ConsoleCommand>, IEnumerable, IEnumerator<ConsoleCommand>, IDisposable, IEnumerator { private int <>1__state; private ConsoleCommand <>2__current; private int <>l__initialThreadId; private MethodInfo method; public MethodInfo <>3__method; private IEnumerator<ConsoleCommand> <>7__wrap1; ConsoleCommand IEnumerator<ConsoleCommand>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RegisterCommands>d__5(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (IsRegisterCommandMethod(method)) { <>2__current = (ConsoleCommand)method.Invoke(null, null); <>1__state = 1; return true; } if (!IsRegisterCommandsMethod(method)) { break; } <>7__wrap1 = ((IEnumerable<ConsoleCommand>)method.Invoke(null, null)).GetEnumerator(); <>1__state = -3; goto IL_00bd; case 1: <>1__state = -1; break; case 2: { <>1__state = -3; goto IL_00bd; } IL_00bd: if (<>7__wrap1.MoveNext()) { ConsoleCommand current = <>7__wrap1.Current; <>2__current = current; <>1__state = 2; return true; } <>m__Finally1(); <>7__wrap1 = null; break; } return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<ConsoleCommand> IEnumerable<ConsoleCommand>.GetEnumerator() { <RegisterCommands>d__5 <RegisterCommands>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <RegisterCommands>d__ = this; } else { <RegisterCommands>d__ = new <RegisterCommands>d__5(0); } <RegisterCommands>d__.method = <>3__method; return <RegisterCommands>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<ConsoleCommand>)this).GetEnumerator(); } } private static readonly List<ConsoleCommand> _commands = new List<ConsoleCommand>(); public static void ToggleCommands(bool toggleOn) { DeregisterCommands(_commands); _commands.Clear(); if (toggleOn) { _commands.AddRange(RegisterCommands(Assembly.GetExecutingAssembly())); } UpdateCommandLists(); } private static void UpdateCommandLists() { Terminal[] array = Object.FindObjectsOfType<Terminal>(true); for (int i = 0; i < array.Length; i++) { array[i].updateCommandList(); } } private static void DeregisterCommands(List<ConsoleCommand> commands) { foreach (ConsoleCommand command in commands) { if (Terminal.commands[command.Command] == command) { Terminal.commands.Remove(command.Command); } } } private static IEnumerable<ConsoleCommand> RegisterCommands(Assembly assembly) { return (from method in assembly.GetTypes().SelectMany((Type type) => type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) where method.GetCustomAttributes(typeof(ComfyCommand), inherit: false).Length != 0 select method).SelectMany(RegisterCommands); } [IteratorStateMachine(typeof(<RegisterCommands>d__5))] private static IEnumerable<ConsoleCommand> RegisterCommands(MethodInfo method) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RegisterCommands>d__5(-2) { <>3__method = method }; } private static bool IsRegisterCommandMethod(MethodInfo method) { if (method.GetParameters().Length == 0) { return typeof(ConsoleCommand).IsAssignableFrom(method.ReturnType); } return false; } private static bool IsRegisterCommandsMethod(MethodInfo method) { if (method.GetParameters().Length == 0) { return typeof(IEnumerable<ConsoleCommand>).IsAssignableFrom(method.ReturnType); } return false; } } public static class ConfigFileExtensions { internal sealed class ConfigurationManagerAttributes { public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public bool? HideDefaultButton; public int? Order; } private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>(); public static readonly char[] CommaSeparator = new char[1] { ',' }; private static int GetSettingOrder(string section) { if (!_sectionToSettingOrder.TryGetValue(section, out var value)) { value = 0; } _sectionToSettingOrder[section] = value - 1; return value; } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { new ConfigurationManagerAttributes { Order = GetSettingOrder(section) } })); } public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = browsable, CustomDrawer = customDrawer, HideDefaultButton = hideDefaultButton, Order = GetSettingOrder(section) } })); } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler) { configEntry.SettingChanged += delegate { settingChangedHandler(); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler) { configEntry.SettingChanged += delegate(object _, EventArgs eventArgs) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) settingChangedHandler((ConfigEntry<T>)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue); }; } public static string[] StringValues(this ConfigEntry<string> configEntry) { return configEntry.Value.Split(CommaSeparator, StringSplitOptions.RemoveEmptyEntries); } } public static class StringExtensions { public static readonly char[] CommaSeparator = new char[1] { ',' }; public static readonly char[] ColonSeparator = new char[1] { ':' }; public static bool TryParseVector2(this string text, out Vector2 value) { //IL_0050: 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) //IL_0048: Unknown result type (might be due to invalid IL or missing references) string[] array = text.Split(CommaSeparator, 2, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 2 && float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { value = new Vector2(result, result2); return true; } value = default(Vector2); return false; } public static bool TryParseVector3(this string text, out Vector3 value) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) string[] array = text.Split(CommaSeparator, 3, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 3 && float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { value = new Vector3(result, result2, result3); return true; } value = default(Vector3); return false; } public static bool TryParseZDOID(this string text, out ZDOID value) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) string[] array = text.Split(ColonSeparator, 2, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 2 && long.TryParse(array[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && uint.TryParse(array[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { value = new ZDOID(result, result2); return true; } value = default(ZDOID); return false; } } public static class ChatExtensions { public static void AddMessage(this Chat chat, object obj) { if (Object.op_Implicit((Object)(object)chat)) { ((Terminal)chat).AddString($"{obj}"); chat.m_hideTimer = 0f; } } } public static class ComponentExtensions { public static T GetOrAddComponent<T>(this Component component) where T : Component { T result = default(T); if (!component.TryGetComponent<T>(ref result)) { return component.gameObject.AddComponent<T>(); } return result; } public static T GetOrAddComponent<T>(this Component component, out T otherComponent) where T : Component { if (!component.TryGetComponent<T>(ref otherComponent)) { otherComponent = component.gameObject.AddComponent<T>(); } return otherComponent; } } public static class UnityExtensions { public static T Ref<T>(this T unityObject) where T : Object { if (!Object.op_Implicit((Object)(object)unityObject)) { return default(T); } return unityObject; } public static T SetName<T>(this T component, string name) where T : Component { ((Object)(object)component).name = name; return component; } } } namespace ComfyAutoPicker { [BepInPlugin("EardwulfDoesMods.valheim.ComfyAutoPicker", "ComfyAutoPicker", "1.6.0")] public class Mod : BaseUnityPlugin { public const string PluginGuid = "EardwulfDoesMods.valheim.ComfyAutoPicker"; public const string PluginName = "ComfyAutoPicker"; public const string PluginVersion = "1.6.0"; public static readonly HashSet<int> PlantsToAutoPick = new HashSet<int> { StringExtensionMethods.GetStableHashCode("CloudberryBush"), StringExtensionMethods.GetStableHashCode("Pickable_Barley"), StringExtensionMethods.GetStableHashCode("Pickable_Barley_Wild"), StringExtensionMethods.GetStableHashCode("Pickable_Flax"), StringExtensionMethods.GetStableHashCode("Pickable_Flax_Wild"), StringExtensionMethods.GetStableHashCode("Pickable_Carrot"), StringExtensionMethods.GetStableHashCode("Pickable_SeedCarrot"), StringExtensionMethods.GetStableHashCode("Pickable_Turnip"), StringExtensionMethods.GetStableHashCode("Pickable_SeedTurnip"), StringExtensionMethods.GetStableHashCode("Pickable_Onion"), StringExtensionMethods.GetStableHashCode("Pickable_SeedOnion"), StringExtensionMethods.GetStableHashCode("Pickable_Mushroom_JotunPuffs"), StringExtensionMethods.GetStableHashCode("Pickable_Mushroom_Magecap"), "VineAsh".GetHashCode(), StringExtensionMethods.GetStableHashCode("Pickable_Thistle"), StringExtensionMethods.GetStableHashCode("LuredWisp"), StringExtensionMethods.GetStableHashCode("Pickable_Fiddlehead") }; private void Awake() { PluginConfig.BindConfig(((BaseUnityPlugin)this).Config); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "EardwulfDoesMods.valheim.ComfyAutoPicker"); } } public sealed class AutoPicker : MonoBehaviour { private Pickable _pickable; private void Awake() { _pickable = ((Component)this).GetComponent<Pickable>(); if (PluginConfig.IsModEnabled.Value) { ((MonoBehaviour)this).InvokeRepeating("CheckAndPick", 1f, 0.425f); } } private int GetPlantsPerSwing(float skillLevel) { if (!(skillLevel < 25f)) { if (skillLevel >= 25f) { if (!(skillLevel < 50f)) { if (!(skillLevel < 75f)) { if (skillLevel < 100f) { return 16; } return 20; } return 13; } return 10; } return 7; } return 7; } private float GetStaminaModifier(float skillLevel) { if (!(skillLevel >= 100f)) { if (!(skillLevel >= 75f)) { if (!(skillLevel >= 50f)) { if (skillLevel >= 25f) { return 0.92f; } return 1f; } return 0.83f; } return 0.75f; } return 0.67f; } private float GetDurabilityPenalty(float skillLevel) { if (!(skillLevel < 25f)) { if (skillLevel >= 25f) { if (!(skillLevel < 50f)) { if (!(skillLevel < 75f)) { if (skillLevel < 100f) { return 1.05f; } return 1.07f; } return 1.03f; } return 1.01f; } return 1f; } return 1f; } public void CheckAndPick() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (!PluginConfig.IsModEnabled.Value || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } Player localPlayer = Player.m_localPlayer; ItemData rightItem = ((Humanoid)localPlayer).m_rightItem; bool flag = ((rightItem != null) ? ((Object)rightItem.m_dropPrefab).name : null) == "Scythe"; ItemData rightItem2 = ((Humanoid)localPlayer).m_rightItem; bool flag2 = ((rightItem2 != null) ? ((Object)rightItem2.m_dropPrefab).name : null) == "Cultivator"; if (!flag && Vector3.Distance(((Component)this).transform.position, ((Component)localPlayer).transform.position) > PluginConfig.AutoPickRadius.Value) { return; } if (flag) { float harvestRadius = ((Humanoid)Player.m_localPlayer).m_rightItem.m_shared.m_attack.m_harvestRadius; float harvestRadiusMaxLevel = ((Humanoid)Player.m_localPlayer).m_rightItem.m_shared.m_attack.m_harvestRadiusMaxLevel; float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)106); float num = Mathf.Lerp(harvestRadius, harvestRadiusMaxLevel, skillFactor); if (Vector3.Distance(((Component)this).transform.position, ((Component)localPlayer).transform.position) > num) { return; } } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false) || flag2) { return; } if (flag) { float level = localPlayer.m_skills.GetSkill((SkillType)106).m_level; int plantsPerSwing = GetPlantsPerSwing(level); ItemData rightItem3 = ((Humanoid)localPlayer).m_rightItem; bool flag3 = false; float num2 = 0f; float num3 = 0f; if (plantsPerSwing > 0) { num2 = rightItem3.m_shared.m_attack.m_attackStamina * GetStaminaModifier(level) / (float)plantsPerSwing; flag3 = ((Character)localPlayer).HaveStamina(num2); num3 = GetDurabilityPenalty(level); } if (!(rightItem3.m_durability <= 0f) && plantsPerSwing > 0 && flag3 && _pickable.Interact((Humanoid)(object)Player.m_localPlayer, false, false)) { float num4 = rightItem3.m_shared.m_useDurabilityDrain / (float)plantsPerSwing * 1.05f * num3; rightItem3.m_durability -= num4; ((Character)localPlayer).UseStamina(num2); } } else { _pickable.Interact((Humanoid)(object)Player.m_localPlayer, false, false); } } } [HarmonyPatch(typeof(Pickable))] internal static class PickablePatch { [HarmonyPostfix] [HarmonyPatch("Awake")] private static void AwakePostfix(Pickable __instance) { if (PluginConfig.IsModEnabled.Value && Mod.PlantsToAutoPick.Contains(__instance.m_nview.m_zdo.m_prefab) && !__instance.m_picked) { ((Component)__instance).gameObject.AddComponent<AutoPicker>(); } } } public static class PluginConfig { public static ConfigEntry<bool> IsModEnabled { get; private set; } public static ConfigEntry<float> AutoPickRadius { get; private set; } public static void BindConfig(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown IsModEnabled = config.Bind<bool>("_Global", "IsModEnabled", true, "Globally enable or disable this mod"); AutoPickRadius = config.Bind<float>("AutoPickerProperties", "AutoPickRadius", 0.875f, new ConfigDescription("Adjust Auto-Picker Radius", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.875f), Array.Empty<object>())); } } }