Decompiled source of NutcrackerFixes v1.2.2

BepInEx/plugins/NutcrackerFixes.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using NutcrackerFixes.Patches;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NutcrackerFixes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NutcrackerFixes")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d01d5a17-8806-47da-aff3-70fb6669aff2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NutcrackerFixes
{
	[BepInPlugin("Zaggy1024.NutcrackerFixes", "NutcrackerFixes", "1.2.2")]
	public class Plugin : BaseUnityPlugin
	{
		private const string MOD_NAME = "NutcrackerFixes";

		private const string MOD_UNIQUE_NAME = "Zaggy1024.NutcrackerFixes";

		private const string MOD_VERSION = "1.2.2";

		private readonly Harmony harmony = new Harmony("Zaggy1024.NutcrackerFixes");

		public static ConfigEntry<bool> Shotgun_SynchronizeShellsAndSafety;

		public static Plugin Instance { get; private set; }

		public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			Instance = this;
			Shotgun_SynchronizeShellsAndSafety = ((BaseUnityPlugin)this).Config.Bind<bool>("Shotgun", "SynchronizeShellsAndSafety", true, "Synchronize the shotgun shell count and safety setting upon picking up the shotgun. This feature must be installed and enabled for everyone, or the safety will not function as expected. Fixes an issue where too many items on the ship would cause the number of loaded shells as well as the safety to be desynced between the server and clients.");
			harmony.PatchAll(typeof(PatchNutcrackerEnemyAI));
			harmony.PatchAll(typeof(PatchShotgunItem));
			harmony.PatchAll(typeof(PatchBlobAI));
			harmony.PatchAll(typeof(PatchSandSpiderAI));
		}
	}
}
namespace NutcrackerFixes.Patches
{
	public class SequenceMatch
	{
		public int Start;

		public int End;

		public int Size => End - Start;

		public SequenceMatch(int start, int end)
		{
			Start = start;
			End = end;
		}
	}
	public static class Common
	{
		public static readonly MethodInfo m_Debug_Log = typeof(Debug).GetMethod("Log", new Type[1] { typeof(object) });

		public static MethodInfo GetGenericMethod(Type type, string name, Type[] parameters, Type[] genericArguments)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo[] methods = type.GetMethods();
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != name)
				{
					continue;
				}
				MethodInfo methodInfo2 = methodInfo;
				if (genericArguments.Length != 0)
				{
					try
					{
						methodInfo2 = methodInfo2.MakeGenericMethod(genericArguments);
					}
					catch
					{
					}
				}
				ParameterInfo[] parameters2 = methodInfo2.GetParameters();
				if (parameters2.Length != parameters.Length)
				{
					continue;
				}
				for (int j = 0; j < parameters.Length; j++)
				{
					if (parameters2[j].ParameterType != parameters[j])
					{
						methodInfo2 = null;
						break;
					}
				}
				if (methodInfo2 != null)
				{
					return methodInfo2;
				}
			}
			throw new MemberNotFoundException("Could not find method " + type.Name + "::" + name);
		}

		public static SequenceMatch FindIndexOfSequence<T>(this List<T> list, int startIndex, int count, IEnumerable<Predicate<T>> predicates)
		{
			int num;
			for (num = startIndex; num < list.Count(); num++)
			{
				IEnumerator<Predicate<T>> enumerator = predicates.GetEnumerator();
				if (!enumerator.MoveNext())
				{
					return null;
				}
				num = list.FindIndex(num, enumerator.Current);
				if (num < 0)
				{
					break;
				}
				bool flag = true;
				int num2 = 1;
				while (enumerator.MoveNext())
				{
					if (num2 >= list.Count() - num || !enumerator.Current(list[num + num2]))
					{
						flag = false;
						break;
					}
					num2++;
				}
				if (flag)
				{
					return new SequenceMatch(num, num + predicates.Count());
				}
			}
			return null;
		}

		public static SequenceMatch FindIndexOfSequence<T>(this List<T> list, int startIndex, IEnumerable<Predicate<T>> predicates)
		{
			return list.FindIndexOfSequence(startIndex, -1, predicates);
		}

		public static SequenceMatch FindIndexOfSequence<T>(this List<T> list, IEnumerable<Predicate<T>> predicates)
		{
			return list.FindIndexOfSequence(0, -1, predicates);
		}
	}
	[HarmonyPatch(typeof(BlobAI))]
	internal class PatchBlobAI
	{
		private static readonly MethodInfo m_Component_get_transform = AccessTools.Method(typeof(Component), "get_transform", new Type[0], (Type[])null);

		private static readonly MethodInfo m_Transform_get_position = AccessTools.Method(typeof(Transform), "get_position", new Type[0], (Type[])null);

		private static readonly MethodInfo m_Transform_set_position = AccessTools.Method(typeof(Transform), "set_position", new Type[1] { typeof(Vector3) }, (Type[])null);

		private static readonly FieldInfo f_PlayerControllerB_gameplayCamera = typeof(PlayerControllerB).GetField("gameplayCamera");

		[HarmonyTranspiler]
		[HarmonyPatch("HitEnemy")]
		private static IEnumerable<CodeInstruction> DoHitEnemyTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			SequenceMatch sequenceMatch = list.FindIndexOfSequence(new Predicate<CodeInstruction>[2]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)2),
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsField(insn, f_PlayerControllerB_gameplayCamera, false)
			});
			CodeInstruction val = list[sequenceMatch.Start];
			Label label = generator.DefineLabel();
			list[sequenceMatch.Start].labels.Add(label);
			Label label2 = generator.DefineLabel();
			int index = list.FindIndex(sequenceMatch.End, (CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_Transform_set_position));
			list[index].labels.Add(label2);
			list.InsertRange(sequenceMatch.Start, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[6]
			{
				new CodeInstruction(val.opcode, val.operand),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)m_Component_get_transform),
				new CodeInstruction(OpCodes.Call, (object)m_Transform_get_position),
				new CodeInstruction(OpCodes.Br, (object)label2)
			});
			return list;
		}
	}
	[HarmonyPatch(typeof(NutcrackerEnemyAI))]
	internal class PatchNutcrackerEnemyAI
	{
		[HarmonyTranspiler]
		[HarmonyPatch("TurnTorsoToTargetDegrees")]
		private static IEnumerable<CodeInstruction> TurnTorsoToTargetDegreesTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, Common.m_Debug_Log))
				{
					yield return new CodeInstruction(OpCodes.Pop, (object)null);
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI))]
	internal class PatchSandSpiderAI
	{
		private static readonly MethodInfo m_NetworkBehavior_get_IsOwner = typeof(NetworkBehaviour).GetMethod("get_IsOwner");

		private static readonly MethodInfo m_SandSpiderAI_TriggerChaseWithPlayer = typeof(SandSpiderAI).GetMethod("TriggerChaseWithPlayer");

		[HarmonyTranspiler]
		[HarmonyPatch("HitEnemy")]
		private static IEnumerable<CodeInstruction> DoHitEnemyTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			Label? label2 = default(Label?);
			SequenceMatch sequenceMatch = list.FindIndexOfSequence(new Predicate<CodeInstruction>[6]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)0),
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_NetworkBehavior_get_IsOwner),
				(CodeInstruction insn) => CodeInstructionExtensions.Branches(insn, ref label2),
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)0),
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)null),
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_SandSpiderAI_TriggerChaseWithPlayer)
			});
			Label label = (Label)list[sequenceMatch.Start + 2].operand;
			list.InsertRange(sequenceMatch.Start + 3, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
			{
				new CodeInstruction(list[sequenceMatch.End - 2]),
				new CodeInstruction(OpCodes.Brfalse_S, (object)label)
			});
			return list;
		}
	}
	[HarmonyPatch(typeof(ShotgunItem))]
	internal class PatchShotgunItem
	{
		private static readonly MethodInfo m_PatchShotgunItem_SetSafetyServerRpc = typeof(PatchShotgunItem).GetMethod("SetSafetyServerRpc", new Type[2]
		{
			typeof(ShotgunItem),
			typeof(bool)
		});

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

		private static readonly FieldInfo f_ShotgunItem_safetyOn = typeof(ShotgunItem).GetField("safetyOn");

		private static readonly MethodInfo m_ShotgunItem_SetSafetyControlTip = AccessTools.Method(typeof(ShotgunItem), "SetSafetyControlTip", new Type[0], (Type[])null);

		private static readonly MethodInfo m_Physics_SphereCastNonAlloc = AccessTools.Method(typeof(Physics), "SphereCastNonAlloc", new Type[6]
		{
			typeof(Ray),
			typeof(float),
			typeof(RaycastHit[]),
			typeof(float),
			typeof(int),
			typeof(QueryTriggerInteraction)
		}, (Type[])null);

		private static readonly ConstructorInfo m_HashSet_EnemyAI_Constructor = typeof(HashSet<EnemyAI>).GetConstructor(new Type[0]);

		private static readonly MethodInfo m_HashSet_EnemyAI_Contains = typeof(HashSet<EnemyAI>).GetMethod("Contains", new Type[1] { typeof(EnemyAI) });

		private static readonly MethodInfo m_HashSet_EnemyAI_Add = typeof(HashSet<EnemyAI>).GetMethod("Add", new Type[1] { typeof(EnemyAI) });

		private static readonly MethodInfo m_Component_GetComponent_EnemyAICollisionDetect = Common.GetGenericMethod(typeof(Component), "GetComponent", new Type[0], new Type[1] { typeof(EnemyAICollisionDetect) });

		private static readonly MethodInfo m_Component_TryGetComponent_IHittable = Common.GetGenericMethod(typeof(Component), "TryGetComponent", new Type[1] { typeof(IHittable).MakeByRefType() }, new Type[1] { typeof(IHittable) });

		private static readonly MethodInfo m_UnityEngine_Object_op_Implicit = typeof(Object).GetMethod("op_Implicit", new Type[1] { typeof(Object) });

		private static readonly FieldInfo f_EnemyAICollisionDetect_onlyCollideWhenGrounded = typeof(EnemyAICollisionDetect).GetField("onlyCollideWhenGrounded");

		private static readonly FieldInfo f_EnemyAICollisionDetect_mainScript = typeof(EnemyAICollisionDetect).GetField("mainScript");

		private static readonly MethodInfo m_RaycastHit_get_transform = AccessTools.Method(typeof(RaycastHit), "get_transform", new Type[0], (Type[])null);

		private const uint SET_SAFETY_SERVER_RPC = 391u;

		private const uint SET_SAFETY_CLIENT_RPC = 392u;

		private const uint SYNCHRONIZE_CLIENT_RPC = 393u;

		private const uint SYNCHRONIZE_SERVER_RPC = 394u;

		[HarmonyTranspiler]
		[HarmonyPatch("ShootGun")]
		private static IEnumerable<CodeInstruction> ShootGunTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Expected O, but got Unknown
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Expected O, but got Unknown
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Expected O, but got Unknown
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Expected O, but got Unknown
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Expected O, but got Unknown
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Expected O, but got Unknown
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Expected O, but got Unknown
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Expected O, but got Unknown
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Expected O, but got Unknown
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Expected O, but got Unknown
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Expected O, but got Unknown
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Expected O, but got Unknown
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Expected O, but got Unknown
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Expected O, but got Unknown
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Expected O, but got Unknown
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Expected O, but got Unknown
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Expected O, but got Unknown
			//IL_067a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Expected O, but got Unknown
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_068e: Expected O, but got Unknown
			//IL_0777: Unknown result type (might be due to invalid IL or missing references)
			//IL_0781: Expected O, but got Unknown
			//IL_07cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d7: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = list.FindIndex((CodeInstruction insn) => insn.opcode == OpCodes.Newarr && insn.operand as Type == typeof(RaycastHit));
			list[num - 1].operand = 50;
			SequenceMatch sequenceMatch = list.FindIndexOfSequence(new Predicate<CodeInstruction>[2]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_Physics_SphereCastNonAlloc),
				(CodeInstruction insn) => CodeInstructionExtensions.IsStloc(insn, (LocalBuilder)null)
			});
			LocalBuilder localBuilder = generator.DeclareLocal(typeof(HashSet<EnemyAI>));
			CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Newobj, (object)m_HashSet_EnemyAI_Constructor),
				new CodeInstruction(OpCodes.Stloc, (object)localBuilder)
			};
			list.InsertRange(sequenceMatch.End, array);
			sequenceMatch.End += array.Length;
			Label? label4 = default(Label?);
			SequenceMatch sequenceMatch2 = list.FindIndexOfSequence(sequenceMatch.End, new Predicate<CodeInstruction>[3]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsConstant(insn, 0L),
				(CodeInstruction insn) => CodeInstructionExtensions.IsStloc(insn, (LocalBuilder)null),
				(CodeInstruction insn) => CodeInstructionExtensions.Branches(insn, ref label4)
			});
			LocalBuilder hitEnemyIndexVar = (LocalBuilder)list[sequenceMatch2.Start + 1].operand;
			Label label = generator.DefineLabel();
			Predicate<CodeInstruction>[] first = new Predicate<CodeInstruction>[6]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)0),
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsField(insn, f_ShotgunItem_enemyColliders, false),
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdloc(insn, hitEnemyIndexVar),
				(CodeInstruction insn) => insn.opcode == OpCodes.Ldelema,
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_RaycastHit_get_transform),
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_Component_GetComponent_EnemyAICollisionDetect)
			};
			Label? label3 = default(Label?);
			SequenceMatch sequenceMatch3 = list.FindIndexOfSequence(sequenceMatch2.End, first.Concat(new Predicate<CodeInstruction>[3]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_UnityEngine_Object_op_Implicit),
				(CodeInstruction insn) => CodeInstructionExtensions.Branches(insn, ref label3),
				(CodeInstruction insn) => insn.opcode == OpCodes.Ret
			}));
			list.RemoveRange(sequenceMatch3.Start, sequenceMatch3.Size);
			sequenceMatch3.End -= sequenceMatch3.Size;
			LocalBuilder localBuilder2 = generator.DeclareLocal(typeof(EnemyAICollisionDetect));
			CodeInstruction[] array2 = (CodeInstruction[])(object)new CodeInstruction[13]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)f_ShotgunItem_enemyColliders),
				new CodeInstruction(OpCodes.Ldloc, (object)hitEnemyIndexVar),
				new CodeInstruction(OpCodes.Ldelema, (object)typeof(RaycastHit)),
				new CodeInstruction(OpCodes.Call, (object)m_RaycastHit_get_transform),
				new CodeInstruction(OpCodes.Call, (object)m_Component_GetComponent_EnemyAICollisionDetect),
				new CodeInstruction(OpCodes.Stloc, (object)localBuilder2),
				new CodeInstruction(OpCodes.Ldloc, (object)localBuilder2),
				new CodeInstruction(OpCodes.Call, (object)m_UnityEngine_Object_op_Implicit),
				new CodeInstruction(OpCodes.Brfalse_S, (object)label),
				new CodeInstruction(OpCodes.Ldloc, (object)localBuilder2),
				new CodeInstruction(OpCodes.Ldfld, (object)f_EnemyAICollisionDetect_onlyCollideWhenGrounded),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label)
			};
			list.InsertRange(sequenceMatch3.Start, array2);
			SequenceMatch sequenceMatch4 = list.FindIndexOfSequence(sequenceMatch3.Start + array2.Length, first.Concat(new Predicate<CodeInstruction>[2]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsField(insn, f_EnemyAICollisionDetect_mainScript, false),
				(CodeInstruction insn) => CodeInstructionExtensions.IsStloc(insn, (LocalBuilder)null)
			}));
			LocalBuilder localBuilder3 = (LocalBuilder)list[sequenceMatch4.End - 1].operand;
			list.RemoveRange(sequenceMatch4.Start, sequenceMatch4.Size);
			list.InsertRange(sequenceMatch4.Start, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldloc, (object)localBuilder2),
				new CodeInstruction(OpCodes.Ldfld, (object)f_EnemyAICollisionDetect_mainScript),
				new CodeInstruction(OpCodes.Stloc, (object)localBuilder3)
			});
			Label? label2 = default(Label?);
			SequenceMatch sequenceMatch5 = list.FindIndexOfSequence(sequenceMatch2.End, new Predicate<CodeInstruction>[8]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)0),
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsField(insn, f_ShotgunItem_enemyColliders, false),
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdloc(insn, hitEnemyIndexVar),
				(CodeInstruction insn) => insn.opcode == OpCodes.Ldelema,
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_RaycastHit_get_transform),
				(CodeInstruction insn) => insn.opcode == OpCodes.Ldloca_S,
				(CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, m_Component_TryGetComponent_IHittable),
				(CodeInstruction insn) => CodeInstructionExtensions.Branches(insn, ref label2)
			});
			list.InsertRange(sequenceMatch5.End, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[8]
			{
				new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder),
				new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder3),
				new CodeInstruction(OpCodes.Call, (object)m_HashSet_EnemyAI_Contains),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label),
				new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder),
				new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder3),
				new CodeInstruction(OpCodes.Call, (object)m_HashSet_EnemyAI_Add),
				new CodeInstruction(OpCodes.Pop, (object)null)
			});
			SequenceMatch sequenceMatch6 = list.FindIndexOfSequence(sequenceMatch2.End, new Predicate<CodeInstruction>[3]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdloc(insn, (LocalBuilder)null),
				(CodeInstruction insn) => CodeInstructionExtensions.LoadsConstant(insn, 1L),
				(CodeInstruction insn) => insn.opcode == OpCodes.Add
			});
			list[sequenceMatch6.Start].labels.Add(label);
			int num2 = sequenceMatch2.End;
			while (true)
			{
				num2 = list.FindIndex(num2, sequenceMatch6.Start - num2, (CodeInstruction insn) => insn.opcode == OpCodes.Ret);
				if (num2 < 0)
				{
					break;
				}
				list[num2] = new CodeInstruction(OpCodes.Br_S, (object)label);
			}
			num2 = sequenceMatch2.End;
			while (true)
			{
				num2 = list.FindIndex(num2, sequenceMatch6.Start - num2, (CodeInstruction insn) => CodeInstructionExtensions.Calls(insn, Common.m_Debug_Log));
				if (num2 < 0)
				{
					break;
				}
				list[num2] = new CodeInstruction(OpCodes.Pop, (object)null);
			}
			return list;
		}

		[HarmonyPostfix]
		[HarmonyPatch("EquipItem")]
		private static void EquipItemPostfix(ShotgunItem __instance)
		{
			if (Plugin.Shotgun_SynchronizeShellsAndSafety.Value)
			{
				SynchronizeServerRpc(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LoadItemSaveData")]
		private static void LoadItemSaveDataPostfix(ShotgunItem __instance)
		{
			if (Plugin.Shotgun_SynchronizeShellsAndSafety.Value)
			{
				SetSafetyServerRpc(__instance, __instance.safetyOn);
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch("ItemInteractLeftRight")]
		private static IEnumerable<CodeInstruction> ItemInteractLeftRightTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			SequenceMatch sequenceMatch = list.FindIndexOfSequence(new Predicate<CodeInstruction>[2]
			{
				(CodeInstruction insn) => CodeInstructionExtensions.IsLdarg(insn, (int?)1),
				(CodeInstruction insn) => insn.opcode == OpCodes.Brtrue || insn.opcode == OpCodes.Brtrue_S
			});
			Label isLeftInteractEndLabel = (Label)list[sequenceMatch.End - 1].operand;
			int num = list.FindIndex((CodeInstruction insn) => insn.labels.Contains(isLeftInteractEndLabel));
			Label label = generator.DefineLabel();
			list[sequenceMatch.End].labels.Add(label);
			CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)Reflection.m_NetworkBehaviour_get_IsOwner),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label),
				new CodeInstruction(OpCodes.Ret, (object)null)
			};
			list.InsertRange(sequenceMatch.End, array);
			CodeInstruction[] collection = (CodeInstruction[])(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)f_ShotgunItem_safetyOn),
				new CodeInstruction(OpCodes.Call, (object)m_PatchShotgunItem_SetSafetyServerRpc)
			};
			list.InsertRange(num - 1 + array.Length, collection);
			return list;
		}

		public static void SetSafetyServerRpc(ShotgunItem shotgun, bool safetyOn)
		{
			//IL_004e: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)shotgun).IsOwner && !((NetworkBehaviour)shotgun).IsHost && !((NetworkBehaviour)shotgun).IsServer)
			{
				return;
			}
			NetworkManager networkManager = ((NetworkBehaviour)shotgun).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if (((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer)
				{
					SetSafetyClientRpc(shotgun, safetyOn);
				}
				else if (((NetworkBehaviour)shotgun).IsClient)
				{
					ServerRpcParams rpcParams = default(ServerRpcParams);
					FastBufferWriter buffer = Reflection.BeginSendServerRPC((NetworkBehaviour)(object)shotgun, 391u, rpcParams, (RpcDelivery)0);
					((FastBufferWriter)(ref buffer)).WriteValueSafe<bool>(ref safetyOn, default(ForPrimitives));
					Reflection.EndSendServerRPC((NetworkBehaviour)(object)shotgun, ref buffer, 391u, rpcParams, (RpcDelivery)0);
				}
			}
		}

		public static void SetSafetyClientRpc(ShotgunItem shotgun, bool safetyOn)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)shotgun).IsOwner || ((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer)
			{
				NetworkManager networkManager = ((NetworkBehaviour)shotgun).NetworkManager;
				if (networkManager != null && networkManager.IsListening && (((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer))
				{
					ClientRpcParams rpcParams = default(ClientRpcParams);
					FastBufferWriter buffer = Reflection.BeginSendClientRPC((NetworkBehaviour)(object)shotgun, 392u, rpcParams, (RpcDelivery)0);
					((FastBufferWriter)(ref buffer)).WriteValueSafe<bool>(ref safetyOn, default(ForPrimitives));
					Reflection.EndSendClientRPC((NetworkBehaviour)(object)shotgun, ref buffer, 392u, rpcParams, (RpcDelivery)0);
				}
			}
		}

		private static void RPCHandlerSetSafetyServer(NetworkBehaviour target, FastBufferReader reader, __RpcParams parameters)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool safetyOn = default(bool);
				((FastBufferReader)(ref reader)).ReadValue<bool>(ref safetyOn, default(ForPrimitives));
				SetSafetyClientRpc((ShotgunItem)target, safetyOn);
			}
		}

		private static void RPCHandlerSetSafetyClient(NetworkBehaviour target, FastBufferReader reader, __RpcParams parameters)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool safetyOn = default(bool);
				((FastBufferReader)(ref reader)).ReadValue<bool>(ref safetyOn, default(ForPrimitives));
				SetSafety((ShotgunItem)target, safetyOn);
			}
		}

		private static void SetSafety(ShotgunItem shotgun, bool safetyOn)
		{
			shotgun.safetyOn = safetyOn;
			m_ShotgunItem_SetSafetyControlTip.Invoke(shotgun, new object[0]);
		}

		public static void SynchronizeServerRpc(ShotgunItem shotgun)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)shotgun).IsOwner || ((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer)
			{
				return;
			}
			NetworkManager networkManager = ((NetworkBehaviour)shotgun).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if (((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer)
				{
					SynchronizeClientRpc(shotgun);
				}
				else if (((NetworkBehaviour)shotgun).IsClient)
				{
					ServerRpcParams rpcParams = default(ServerRpcParams);
					FastBufferWriter buffer = Reflection.BeginSendServerRPC((NetworkBehaviour)(object)shotgun, 394u, rpcParams, (RpcDelivery)0);
					Reflection.EndSendServerRPC((NetworkBehaviour)(object)shotgun, ref buffer, 394u, rpcParams, (RpcDelivery)0);
				}
			}
		}

		public static void SynchronizeClientRpc(ShotgunItem shotgun)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer)
			{
				NetworkManager networkManager = ((NetworkBehaviour)shotgun).NetworkManager;
				if (networkManager != null && networkManager.IsListening && (((NetworkBehaviour)shotgun).IsHost || ((NetworkBehaviour)shotgun).IsServer))
				{
					ClientRpcParams rpcParams = default(ClientRpcParams);
					FastBufferWriter buffer = Reflection.BeginSendClientRPC((NetworkBehaviour)(object)shotgun, 393u, rpcParams, (RpcDelivery)0);
					((FastBufferWriter)(ref buffer)).WriteValueSafe<int>(ref shotgun.shellsLoaded, default(ForPrimitives));
					((FastBufferWriter)(ref buffer)).WriteValueSafe<bool>(ref shotgun.safetyOn, default(ForPrimitives));
					Reflection.EndSendClientRPC((NetworkBehaviour)(object)shotgun, ref buffer, 393u, rpcParams, (RpcDelivery)0);
				}
			}
		}

		private static void RPCHandlerSynchronizeServer(NetworkBehaviour target, FastBufferReader reader, __RpcParams parameters)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				SynchronizeClientRpc((ShotgunItem)target);
			}
		}

		private static void RPCHandlerSynchronizeClient(NetworkBehaviour target, FastBufferReader reader, __RpcParams parameters)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int shellsLoaded = default(int);
				((FastBufferReader)(ref reader)).ReadValue<int>(ref shellsLoaded, default(ForPrimitives));
				bool safetyOn = default(bool);
				((FastBufferReader)(ref reader)).ReadValue<bool>(ref safetyOn, default(ForPrimitives));
				Synchronize((ShotgunItem)target, shellsLoaded, safetyOn);
			}
		}

		private static void Synchronize(ShotgunItem shotgun, int shellsLoaded, bool safetyOn)
		{
			shotgun.shellsLoaded = shellsLoaded;
			((Renderer)shotgun.shotgunShellLeft).enabled = shellsLoaded >= 1;
			((Renderer)shotgun.shotgunShellRight).enabled = shellsLoaded >= 2;
			shotgun.safetyOn = safetyOn;
			m_ShotgunItem_SetSafetyControlTip.Invoke(shotgun, new object[0]);
		}

		[HarmonyPostfix]
		[HarmonyPatch("InitializeRPCS_ShotgunItem")]
		private static void InitializeRPCS_ShotgunItemPostfix()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(391u, new RpcReceiveHandler(RPCHandlerSetSafetyServer));
			NetworkManager.__rpc_func_table.Add(392u, new RpcReceiveHandler(RPCHandlerSetSafetyClient));
			NetworkManager.__rpc_func_table.Add(394u, new RpcReceiveHandler(RPCHandlerSynchronizeServer));
			NetworkManager.__rpc_func_table.Add(393u, new RpcReceiveHandler(RPCHandlerSynchronizeClient));
		}
	}
	public static class Reflection
	{
		public static readonly MethodInfo m_Debug_Log = typeof(Debug).GetMethod("Log", new Type[1] { typeof(object) });

		public static readonly MethodInfo m_NetworkBehaviour_get_IsOwner = typeof(NetworkBehaviour).GetMethod("get_IsOwner", new Type[0]);

		public static readonly MethodInfo m_NetworkBehaviour_beginSendServerRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendServerRpc", new Type[3]
		{
			typeof(uint),
			typeof(ServerRpcParams),
			typeof(RpcDelivery)
		}, (Type[])null);

		public static readonly MethodInfo m_NetworkBehaviour_endSendServerRpc = AccessTools.Method(typeof(NetworkBehaviour), "__endSendServerRpc", new Type[4]
		{
			typeof(FastBufferWriter).MakeByRefType(),
			typeof(uint),
			typeof(ServerRpcParams),
			typeof(RpcDelivery)
		}, (Type[])null);

		public static readonly MethodInfo m_NetworkBehaviour_beginSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendClientRpc", new Type[3]
		{
			typeof(uint),
			typeof(ClientRpcParams),
			typeof(RpcDelivery)
		}, (Type[])null);

		public static readonly MethodInfo m_NetworkBehaviour_endSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__endSendClientRpc", new Type[4]
		{
			typeof(FastBufferWriter).MakeByRefType(),
			typeof(uint),
			typeof(ClientRpcParams),
			typeof(RpcDelivery)
		}, (Type[])null);

		public static FastBufferWriter BeginSendServerRPC(NetworkBehaviour behaviour, uint rpcID, ServerRpcParams rpcParams, RpcDelivery delivery)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			return (FastBufferWriter)m_NetworkBehaviour_beginSendServerRpc.Invoke(behaviour, new object[3] { rpcID, rpcParams, delivery });
		}

		public static void EndSendServerRPC(NetworkBehaviour behaviour, ref FastBufferWriter buffer, uint rpcID, ServerRpcParams rpcParams, RpcDelivery delivery)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			object[] array = new object[4] { buffer, rpcID, rpcParams, delivery };
			m_NetworkBehaviour_endSendServerRpc.Invoke(behaviour, array);
			buffer = (FastBufferWriter)array[0];
		}

		public static FastBufferWriter BeginSendClientRPC(NetworkBehaviour behaviour, uint rpcID, ClientRpcParams rpcParams, RpcDelivery delivery)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			return (FastBufferWriter)m_NetworkBehaviour_beginSendClientRpc.Invoke(behaviour, new object[3] { rpcID, rpcParams, delivery });
		}

		public static void EndSendClientRPC(NetworkBehaviour behaviour, ref FastBufferWriter buffer, uint rpcID, ClientRpcParams rpcParams, RpcDelivery delivery)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			object[] array = new object[4] { buffer, rpcID, rpcParams, delivery };
			m_NetworkBehaviour_endSendClientRpc.Invoke(behaviour, array);
			buffer = (FastBufferWriter)array[0];
		}
	}
}