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 Trans_Hit(IEnumerable 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 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[])(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() 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[])(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 ShotgunItem_Trans_ShootGun(IEnumerable 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 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[])(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 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 hashSet = new HashSet(); IHittable val2 = default(IHittable); for (int i = 0; i < hits.Count; i++) { RaycastHit val = hits[i]; if (!((Component)((RaycastHit)(ref val)).transform).TryGetComponent(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 hashSet = new HashSet(); List list = new List(); 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(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().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 : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { 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.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.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 IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } }