Decompiled source of AutoShield v1.0.0

plugins/AutoShield/AutoShield.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("AutoShield")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AutoShield")]
[assembly: AssemblyTitle("AutoShield")]
[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;
		}
	}
}
namespace AutoShield
{
	[BepInPlugin("ua.bohdan.autoshield", "Auto Shield", "1.0.0")]
	public sealed class AutoShieldPlugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		private static class EquipItemPatch
		{
			private static MethodBase TargetMethod()
			{
				return (from m in AccessTools.TypeByName("Humanoid")?.GetMethods(AccessTools.all)
					where m.Name == "EquipItem" && m.ReturnType == typeof(bool)
					where m.GetParameters().Length >= 1
					orderby m.GetParameters().Length
					select m).FirstOrDefault();
			}

			[HarmonyPostfix]
			private static void Postfix(object __instance, bool __result, object[] __args)
			{
				AfterEquipItem(__instance, __result, __args);
			}
		}

		public const string PluginGuid = "ua.bohdan.autoshield";

		public const string PluginName = "Auto Shield";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		private static bool _equippingShield;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			try
			{
				_harmony = new Harmony("ua.bohdan.autoshield");
				_harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Auto Shield 1.0.0 loaded.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to initialize Auto Shield: " + ex));
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void AfterEquipItem(object __instance, bool __result, object[] __args)
		{
			if (_equippingShield || !__result || __instance == null || __args == null || __args.Length == 0)
			{
				return;
			}
			object obj = __args[0];
			if (obj == null || !IsLocalPlayer(__instance) || !IsOneHandedSword(obj))
			{
				return;
			}
			object fieldValue = GetFieldValue(__instance, "m_leftItem");
			if ((fieldValue != null && IsShield(fieldValue)) || !(InvokeNoArgs(InvokeNoArgs(__instance, "GetInventory"), "GetAllItems") is IEnumerable enumerable))
			{
				return;
			}
			object obj2 = null;
			float num = float.MinValue;
			foreach (object item in enumerable)
			{
				if (item != null && IsShield(item))
				{
					float baseBlockPower = GetBaseBlockPower(item);
					if (obj2 == null || baseBlockPower > num)
					{
						obj2 = item;
						num = baseBlockPower;
					}
				}
			}
			if (obj2 == null)
			{
				return;
			}
			MethodInfo methodInfo = (from m in __instance.GetType().GetMethods(AccessTools.all)
				where m.Name == "EquipItem" && m.ReturnType == typeof(bool)
				where m.GetParameters().Length >= 1
				orderby m.GetParameters().Length
				select m).FirstOrDefault();
			if (methodInfo == null)
			{
				return;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			object[] array = new object[parameters.Length];
			array[0] = obj2;
			for (int num2 = 1; num2 < parameters.Length; num2++)
			{
				array[num2] = (parameters[num2].HasDefaultValue ? parameters[num2].DefaultValue : GetDefault(parameters[num2].ParameterType));
			}
			try
			{
				_equippingShield = true;
				methodInfo.Invoke(__instance, array);
			}
			finally
			{
				_equippingShield = false;
			}
		}

		private static bool IsLocalPlayer(object humanoid)
		{
			Type type = AccessTools.TypeByName("Player");
			object obj = ((type == null) ? null : AccessTools.Field(type, "m_localPlayer"))?.GetValue(null);
			if (obj != null)
			{
				return humanoid == obj;
			}
			return false;
		}

		private static bool IsOneHandedSword(object item)
		{
			object fieldValue = GetFieldValue(item, "m_shared");
			if (fieldValue == null)
			{
				return false;
			}
			string a = GetFieldValue(fieldValue, "m_itemType")?.ToString();
			string a2 = GetFieldValue(fieldValue, "m_skillType")?.ToString();
			if (string.Equals(a, "OneHandedWeapon", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(a2, "Swords", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool IsShield(object item)
		{
			return string.Equals(GetFieldValue(GetFieldValue(item, "m_shared"), "m_itemType")?.ToString(), "Shield", StringComparison.OrdinalIgnoreCase);
		}

		private static float GetBaseBlockPower(object item)
		{
			object fieldValue = GetFieldValue(item, "m_shared");
			object obj = GetFieldValue(fieldValue, "m_blockPower") ?? GetFieldValue(fieldValue, "m_blockArmor");
			try
			{
				return (obj == null) ? 0f : Convert.ToSingle(obj);
			}
			catch
			{
				return 0f;
			}
		}

		private static object GetFieldValue(object instance, string fieldName)
		{
			if (instance == null)
			{
				return null;
			}
			return AccessTools.Field(instance.GetType(), fieldName)?.GetValue(instance);
		}

		private static object InvokeNoArgs(object instance, string methodName)
		{
			if (instance == null)
			{
				return null;
			}
			return AccessTools.Method(instance.GetType(), methodName, Type.EmptyTypes, (Type[])null)?.Invoke(instance, null);
		}

		private static object GetDefault(Type type)
		{
			if (!type.IsValueType)
			{
				return null;
			}
			return Activator.CreateInstance(type);
		}
	}
}