Decompiled source of MeleeFixes v1.5.1

MeleeFixes.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MeleeFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Fixes buggy collision with the shovel and kitchen knife")]
[assembly: AssemblyFileVersion("1.5.1.0")]
[assembly: AssemblyInformationalVersion("1.5.1+c4f6e144b6789d799d1e427ea72326143cec51ba")]
[assembly: AssemblyProduct("MeleeFixes")]
[assembly: AssemblyTitle("MeleeFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.1.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 MeleeFixes
{
	internal static class LobbyCompatibility
	{
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.meleefixes", Version.Parse("1.5.1"), (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
	[BepInPlugin("butterystancakes.lethalcompany.meleefixes", "Melee Fixes", "1.5.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.meleefixes";

		internal const string PLUGIN_NAME = "Melee Fixes";

		internal const string PLUGIN_VERSION = "1.5.1";

		internal static ManualLogSource Logger;

		private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
				LobbyCompatibility.Init();
			}
			new Harmony("butterystancakes.lethalcompany.meleefixes").PatchAll();
			Logger.LogInfo((object)"Melee Fixes v1.5.1 loaded");
		}
	}
	[HarmonyPatch]
	internal static class MeleeFixesPatches
	{
		private const int TERRAIN = 25;

		private static readonly MethodInfo GAME_OBJECT_LAYER = AccessTools.DeclaredPropertyGetter(typeof(GameObject), "layer");

		private static readonly FieldInfo OBJECTS_HIT_BY_SHOVEL_LIST = AccessTools.Field(typeof(Shovel), "objectsHitByShovelList");

		private static readonly FieldInfo OBJECTS_HIT_BY_KNIFE_LIST = AccessTools.Field(typeof(KnifeItem), "objectsHitByKnifeList");

		private static readonly FieldInfo ENEMY_COLLIDERS = AccessTools.Field(typeof(ShotgunItem), "enemyColliders");

		private static readonly MethodInfo FIND_OBJECT_OF_TYPE_ROUND_MANAGER = AccessTools.Method(typeof(Object), "FindObjectOfType", (Type[])null, new Type[1] { typeof(RoundManager) });

		private static readonly MethodInfo ROUND_MANAGER_INSTANCE = AccessTools.DeclaredPropertyGetter(typeof(RoundManager), "Instance");

		private static readonly MethodInfo MELEE_HELPER_FILTER_TARGETS = AccessTools.Method(typeof(WeaponHelper), "FilterTargets", (Type[])null, (Type[])null);

		private static readonly MethodInfo SHOTGUN_PRE_PROCESS = AccessTools.Method(typeof(WeaponHelper), "ShotgunPreProcess", (Type[])null, (Type[])null);

		[HarmonyPatch(typeof(Shovel), "HitShovel")]
		[HarmonyPriority(800)]
		[HarmonyPatch(typeof(KnifeItem), "HitKnife")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Trans_Hit(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Expected O, but got Unknown
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Expected O, but got Unknown
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			bool flag = false;
			for (int i = 8; i < list.Count - 3; i++)
			{
				if (!flag && list[i].opcode == OpCodes.Stfld)
				{
					FieldInfo fieldInfo = (FieldInfo)list[i].operand;
					if (fieldInfo == OBJECTS_HIT_BY_SHOVEL_LIST || fieldInfo == OBJECTS_HIT_BY_KNIFE_LIST)
					{
						list.InsertRange(i + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
						{
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Ldflda, list[i].operand),
							new CodeInstruction(OpCodes.Call, (object)MELEE_HELPER_FILTER_TARGETS)
						}));
						Plugin.Logger.LogDebug((object)$"Transpiler ({__originalMethod.DeclaringType}.{__originalMethod.Name}): Filter targets by validity");
						flag = true;
						i += 3;
					}
				}
				else if (list[i].opcode == OpCodes.Call && list[i].operand as MethodInfo == FIND_OBJECT_OF_TYPE_ROUND_MANAGER)
				{
					list[i].operand = ROUND_MANAGER_INSTANCE;
					Plugin.Logger.LogDebug((object)$"Transpiler ({__originalMethod.DeclaringType}.{__originalMethod.Name}): Replace FindObjectOfType<RoundManager>() with RoundManager.Instance");
				}
				else if (list[i].opcode == OpCodes.Callvirt && list[i].operand as MethodInfo == GAME_OBJECT_LAYER && list[i + 1].opcode == OpCodes.Ldc_I4_8 && list[i - 7].opcode == OpCodes.Ldfld)
				{
					FieldInfo fieldInfo2 = (FieldInfo)list[i - 7].operand;
					if (fieldInfo2 == OBJECTS_HIT_BY_SHOVEL_LIST || fieldInfo2 == OBJECTS_HIT_BY_KNIFE_LIST)
					{
						list.InsertRange(i + 3, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[11]
						{
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Ldfld, list[i - 7].operand),
							new CodeInstruction(OpCodes.Ldloc_S, list[i - 6].operand),
							new CodeInstruction(OpCodes.Callvirt, list[i - 5].operand),
							new CodeInstruction(OpCodes.Stloc_S, list[i - 4].operand),
							new CodeInstruction(OpCodes.Ldloca_S, list[i - 3].operand),
							new CodeInstruction(OpCodes.Call, list[i - 2].operand),
							new CodeInstruction(OpCodes.Callvirt, list[i - 1].operand),
							new CodeInstruction(OpCodes.Callvirt, (object)GAME_OBJECT_LAYER),
							new CodeInstruction(OpCodes.Ldc_I4_S, (object)(sbyte)25),
							new CodeInstruction(OpCodes.Beq, list[i + 2].operand)
						}));
						Plugin.Logger.LogDebug((object)$"Transpiler ({__originalMethod.DeclaringType}.{__originalMethod.Name}): Bounce off layer 25 (Terrain)");
						i += 11;
					}
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(Shovel), "ItemActivate")]
		[HarmonyPrefix]
		private static void Shovel_Pre_ItemActivate(Shovel __instance)
		{
			__instance.shovelMask |= 0x2000000;
			if (__instance.reelingUp && (Object)(object)__instance.previousPlayerHeldBy != (Object)(object)((GrabbableObject)__instance).playerHeldBy)
			{
				__instance.reelingUp = false;
				Plugin.Logger.LogInfo((object)"Reset broken shovel to allow swinging it again");
			}
		}

		[HarmonyPatch(typeof(ShotgunItem), "ShootGun")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ShotgunItem_Trans_ShootGun(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			bool flag = false;
			for (int i = 2; i < list.Count; i++)
			{
				if (!flag && list[i].opcode == OpCodes.Bge_Un && list[i - 2].opcode == OpCodes.Ldloc_2)
				{
					int num = -1;
					for (int j = i + 1; j < list.Count - 1; j++)
					{
						if (list[j + 1].opcode == OpCodes.Ldloc_2)
						{
							if (num >= 0 && list[j].opcode == OpCodes.Br)
							{
								list.Insert(num, new CodeInstruction(OpCodes.Br, list[j].operand));
								Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Fix ear-ringing severity in extremely close range");
								flag = true;
								break;
							}
							if (num < 0 && list[j].opcode == OpCodes.Stloc_S)
							{
								num = j + 1;
							}
						}
					}
				}
				else if (list[i].opcode == OpCodes.Newarr && (Type)list[i].operand == typeof(RaycastHit) && list[i - 1].opcode == OpCodes.Ldc_I4_S && (sbyte)list[i - 1].operand == 10)
				{
					list[i - 1].operand = 50;
					Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Resize target colliders array");
				}
				else if (list[i].opcode == OpCodes.Call && list[i].operand.ToString().Contains("SphereCastNonAlloc"))
				{
					list.InsertRange(i + 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[5]
					{
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldloca_S, list[i + 1].operand),
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldflda, (object)ENEMY_COLLIDERS),
						new CodeInstruction(OpCodes.Call, (object)SHOTGUN_PRE_PROCESS)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Pre-process shotgun targets");
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(KnifeItem), "EquipItem")]
		[HarmonyPostfix]
		private static void KnifeItem_Post_ItemActivate(KnifeItem __instance)
		{
			__instance.knifeMask |= 0x2000000;
		}
	}
	internal static class WeaponHelper
	{
		internal static void FilterTargets(ref List<RaycastHit> hits)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			HashSet<IHittable> hashSet = new HashSet<IHittable>();
			IHittable val2 = default(IHittable);
			for (int i = 0; i < hits.Count; i++)
			{
				RaycastHit val = hits[i];
				if (!((Component)((RaycastHit)(ref val)).transform).TryGetComponent<IHittable>(ref val2))
				{
					continue;
				}
				if (!hashSet.Add(val2))
				{
					hits.RemoveAt(i--);
					continue;
				}
				EnemyAICollisionDetect val3 = (EnemyAICollisionDetect)(object)((val2 is EnemyAICollisionDetect) ? val2 : null);
				if ((Object)(object)val3 != (Object)null && ((val3.onlyCollideWhenGrounded && !val3.alwaysAllowHitting) || ((Object)(object)val3.mainScript != (Object)null && val3.mainScript.isEnemyDead)))
				{
					hits.RemoveAt(i--);
				}
			}
		}

		internal static void ShotgunPreProcess(Vector3 shotgunPosition, ref int num, ref RaycastHit[] results)
		{
			//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)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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)
			//IL_00c9: 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)
			int num2 = 0;
			HashSet<EnemyAI> hashSet = new HashSet<EnemyAI>();
			List<RaycastHit> list = new List<RaycastHit>();
			RaycastHit[] array = (from hit in results.Take(num)
				orderby Vector3.Distance(shotgunPosition, ((RaycastHit)(ref hit)).point)
				select hit).ToArray();
			EnemyAICollisionDetect val = default(EnemyAICollisionDetect);
			for (int i = 0; i < num; i++)
			{
				if (!((Component)((RaycastHit)(ref array[i])).transform).TryGetComponent<EnemyAICollisionDetect>(ref val) || (val.onlyCollideWhenGrounded && !val.alwaysAllowHitting))
				{
					continue;
				}
				EnemyAI mainScript = val.mainScript;
				if (!hashSet.Add(mainScript))
				{
					continue;
				}
				EnemyType enemyType = mainScript.enemyType;
				if (!enemyType.canDie || ((Object)enemyType).name == "DocileLocustBees")
				{
					list.Add(array[i]);
				}
				else if (!mainScript.isEnemyDead)
				{
					results[num2] = array[i];
					num2++;
					if (num2 == 10)
					{
						num = 10;
						return;
					}
				}
			}
			if (list.Count > 0)
			{
				foreach (RaycastHit item in list.OrderByDescending((RaycastHit invincible) => ((Component)((RaycastHit)(ref invincible)).transform).GetComponent<EnemyAICollisionDetect>().mainScript is BlobAI))
				{
					results[num2] = item;
					num2++;
					if (num2 == 10)
					{
						num = 10;
						return;
					}
				}
			}
			num = num2;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MeleeFixes";

		public const string PLUGIN_NAME = "MeleeFixes";

		public const string PLUGIN_VERSION = "1.5.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}