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 AutoEquipShield v1.0.4
BepInEx/plugins/RambosAutoEquipShield.dll
Decompiled a day agousing System; using System.Collections; 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 HarmonyLib; 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("RambosAutoEquipShield")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RambosAutoEquipShield")] [assembly: AssemblyTitle("RambosAutoEquipShield")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("rambos.valheim.autoequipshield", "Rambo's Auto Equip Shield", "1.0.4")] public class AutoEquipShield : BaseUnityPlugin { public const string PluginGuid = "rambos.valheim.autoequipshield"; public const string PluginName = "Rambo's Auto Equip Shield"; public const string PluginVersion = "1.0.4"; private static AutoEquipShield _instance; private static Harmony _harmony; private ConfigEntry<bool> _enabled; private ConfigEntry<KeyboardShortcut> _toggleKey; private ConfigEntry<bool> _debug; private static bool _equippingShield; private static Type _humanoidType; private static Type _itemDataType; private static MethodInfo _equipItemMethod; private static FieldInfo _localPlayerField; private static FieldInfo _leftItemField; private static FieldInfo _rightItemField; private static FieldInfo _inventoryField; private static MethodInfo _getInventoryMethod; private static MethodInfo _getAllItemsMethod; private static MethodInfo _getBlockPowerMethod; private static FieldInfo _sharedField; private static FieldInfo _itemTypeField; private static FieldInfo _blockPowerField; private static FieldInfo _blockPowerPerLevelField; private static FieldInfo _qualityField; private static FieldInfo _equippedField; private static Type _messageHudType; private static MethodInfo _showMessageMethod; private static Type _messageTypeEnum; private static string _popupText; private static float _popupUntil; private GUIStyle _popupStyle; private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown _instance = this; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Automatically equip the strongest shield when you equip a one-handed weapon."); _toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKeyF7", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Press F7 to enable/disable automatic shield equipping."); _debug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Write diagnostic information to the BepInEx log."); ResolveValheimTypes(); _harmony = new Harmony("rambos.valheim.autoequipshield"); try { MethodInfo methodInfo = FindEquipItemMethod(); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find Humanoid.EquipItem(ItemData, bool). Auto Equip Shield is disabled."); } else { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(AutoEquipShield), "EquipItemPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched Humanoid.EquipItem successfully. Auto Equip Shield is ready."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to patch Humanoid.EquipItem: " + ex)); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rambo's Auto Equip Shield 1.0.4 loaded. Press F7 to enable/disable."); ((MonoBehaviour)this).StartCoroutine(ShowStartupPopup()); } private IEnumerator ShowStartupPopup() { yield return null; yield return (object)new WaitForSeconds(1f); ShowPopup("Auto Equip Shield: " + (_enabled.Value ? "ENABLED" : "DISABLED") + " | F7 to toggle"); } private void Update() { //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) KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _enabled.Value = !_enabled.Value; string text = (_enabled.Value ? "ENABLED" : "DISABLED"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Auto Equip Shield " + text)); ShowPopup("Auto Equip Shield: " + text); } } private static void ResolveValheimTypes() { _humanoidType = FindType("Humanoid"); _itemDataType = FindType("ItemDrop+ItemData"); if (_humanoidType == null || _itemDataType == null) { ((BaseUnityPlugin)_instance).Logger.LogError((object)"Could not resolve Valheim Humanoid or ItemDrop.ItemData types."); return; } _localPlayerField = FindField(FindType("Player"), "m_localPlayer"); _leftItemField = FindField(_humanoidType, "m_leftItem"); _rightItemField = FindField(_humanoidType, "m_rightItem"); _inventoryField = FindField(_humanoidType, "m_inventory"); _getInventoryMethod = FindMethod(_humanoidType, "GetInventory", 0); _sharedField = FindField(_itemDataType, "m_shared"); _qualityField = FindField(_itemDataType, "m_quality"); _equippedField = FindField(_itemDataType, "m_equipped") ?? FindField(_itemDataType, "m_equiped"); _messageHudType = FindType("MessageHud"); if (_messageHudType != null) { _messageTypeEnum = FindNestedType(_messageHudType, "MessageType"); _showMessageMethod = _messageHudType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "ShowMessage" && m.GetParameters().Length == 2); } Type type = _sharedField?.FieldType; _itemTypeField = FindField(type, "m_itemType"); _blockPowerField = FindField(type, "m_blockPower"); _blockPowerPerLevelField = FindField(type, "m_blockPowerPerLevel"); _getAllItemsMethod = FindMethodByNameContains(_inventoryField?.FieldType, "GetAllItems", 0); _getBlockPowerMethod = FindMethodByNameContains(_itemDataType, "GetBlockPower", 1) ?? FindMethodByNameContains(_itemDataType, "GetBaseBlockPower", 1); } private static MethodInfo FindEquipItemMethod() { if (_humanoidType == null || _itemDataType == null) { return null; } List<MethodInfo> source = (from m in _humanoidType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "EquipItem" select m).ToList(); MethodInfo methodInfo = source.FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return parameters.Length == 2 && parameters[0].ParameterType == _itemDataType && parameters[1].ParameterType == typeof(bool) && m.ReturnType == typeof(bool); }); if (methodInfo != null) { return _equipItemMethod = methodInfo; } return _equipItemMethod = source.FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return parameters.Length >= 1 && parameters[0].ParameterType == _itemDataType; }); } private static void EquipItemPostfix(object __instance, object item, bool __result) { if ((Object)(object)_instance == (Object)null || _equippingShield || !_instance._enabled.Value || !__result || __instance == null || item == null) { return; } try { object obj = _localPlayerField?.GetValue(null); if (obj == null || obj != __instance || !IsItemType(item, "OneHandedWeapon")) { return; } object obj2 = _leftItemField?.GetValue(__instance); if (obj2 != null && IsItemType(obj2, "Shield")) { if (_instance._debug.Value) { ((BaseUnityPlugin)_instance).Logger.LogInfo((object)"One-handed weapon equipped; shield already equipped, leaving it alone."); } } else { TryEquipBestShield(__instance); } } catch (Exception ex) { ((BaseUnityPlugin)_instance).Logger.LogError((object)("Auto shield error: " + ex)); } } private static void TryEquipBestShield(object player) { object obj = _inventoryField?.GetValue(player) ?? _getInventoryMethod?.Invoke(player, null); if (obj == null || !(_getAllItemsMethod?.Invoke(obj, null) is IEnumerable enumerable)) { return; } object obj2 = null; float num = float.MinValue; foreach (object item in enumerable) { if (item != null && IsItemType(item, "Shield") && !IsEquipped(item)) { float blockPower = GetBlockPower(item); if (obj2 == null || blockPower > num) { obj2 = item; num = blockPower; } } } if (obj2 == null) { return; } MethodInfo equipItemMethod = _equipItemMethod; if (equipItemMethod == null) { return; } ParameterInfo[] parameters = equipItemMethod.GetParameters(); _equippingShield = true; try { if (parameters.Length == 2 && parameters[1].ParameterType == typeof(bool)) { equipItemMethod.Invoke(player, new object[2] { obj2, false }); } else { equipItemMethod.Invoke(player, new object[1] { obj2 }); } string itemName = GetItemName(obj2); ((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Auto-equipped shield: " + itemName + " (block " + num.ToString("0.0") + ").")); ShowPopup("Auto Shield: " + itemName); } finally { _equippingShield = false; } } private static string GetItemName(object item) { try { object obj = _sharedField?.GetValue(item); string text = FindField(obj?.GetType(), "m_name")?.GetValue(obj)?.ToString(); if (!string.IsNullOrEmpty(text)) { return text; } } catch { } return "shield"; } private static void ShowPopup(string text) { _popupText = text; _popupUntil = Time.unscaledTime + 3f; try { if ((Object)(object)_instance != (Object)null) { ((BaseUnityPlugin)_instance).Logger.LogInfo((object)("POPUP: " + text)); } } catch { } } private void OnGUI() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if (!string.IsNullOrEmpty(_popupText) && !(Time.unscaledTime >= _popupUntil)) { if (_popupStyle == null) { _popupStyle = new GUIStyle(GUI.skin.box); _popupStyle.fontSize = 24; _popupStyle.alignment = (TextAnchor)4; _popupStyle.normal.textColor = Color.white; _popupStyle.padding = new RectOffset(24, 24, 14, 14); } GUI.Box(new Rect(((float)Screen.width - 560f) * 0.5f, (float)Screen.height * 0.16f, 560f, 72f), _popupText, _popupStyle); } } private static bool IsItemType(object item, string wanted) { object obj = _sharedField?.GetValue(item); object obj2 = _itemTypeField?.GetValue(obj); if (obj2 != null) { return string.Equals(obj2.ToString(), wanted, StringComparison.OrdinalIgnoreCase); } return false; } private static bool IsEquipped(object item) { if (_equippedField == null) { return false; } try { return Convert.ToBoolean(_equippedField.GetValue(item)); } catch { return false; } } private static float GetBlockPower(object item) { try { if (_getBlockPowerMethod != null) { ParameterInfo[] parameters = _getBlockPowerMethod.GetParameters(); int num = ((_qualityField == null) ? 1 : Convert.ToInt32(_qualityField.GetValue(item))); if (parameters.Length == 1) { return Convert.ToSingle(_getBlockPowerMethod.Invoke(item, new object[1] { num })); } } object obj = _sharedField?.GetValue(item); float num2 = ((_blockPowerField == null) ? 0f : Convert.ToSingle(_blockPowerField.GetValue(obj))); float num3 = ((_blockPowerPerLevelField == null) ? 0f : Convert.ToSingle(_blockPowerPerLevelField.GetValue(obj))); int num4 = ((_qualityField == null) ? 1 : Convert.ToInt32(_qualityField.GetValue(item))); return num2 + (float)Math.Max(0, num4 - 1) * num3; } catch { return 0f; } } private static Type FindNestedType(Type parent, string name) { if (parent == null) { return null; } return parent.GetNestedType(name, BindingFlags.Public | BindingFlags.NonPublic); } private static Type FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(fullName, throwOnError: false); if (type != null) { return type; } } catch { } } return null; } private static FieldInfo FindField(Type type, string name) { if (type == null) { return null; } Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type2 = type2.BaseType; } return null; } private static MethodInfo FindMethod(Type type, string name, int parameterCount) { if (type == null) { return null; } return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == name && m.GetParameters().Length == parameterCount); } private static MethodInfo FindMethodByNameContains(Type type, string name, int parameterCount) { if (type == null) { return null; } return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0 && m.GetParameters().Length == parameterCount); } }