Decompiled source of DramaMask v2.1.3

DramaMask.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using DramaMask.Config;
using DramaMask.Constants;
using DramaMask.Extensions;
using DramaMask.Models.Network;
using DramaMask.NetcodePatcher;
using DramaMask.Network;
using DramaMask.Patches.LethalHandsPatch;
using DramaMask.UI;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalHands;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DramaMask")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Enables masks to be worn to hide from enemies by blending in with the Masked and adds a safe mask, Drama!")]
[assembly: AssemblyFileVersion("2.1.3.0")]
[assembly: AssemblyInformationalVersion("2.1.3+4d30284f2d4aeb9df4a9c96cfdd06f71b8a99560")]
[assembly: AssemblyProduct("Stealthy Masks")]
[assembly: AssemblyTitle("DramaMask")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[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 DramaMask
{
	[BepInDependency("evaisa.lethallib", "0.15.1")]
	[BepInDependency("com.sigurd.csync", "5.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("DramaMask", "Stealthy Masks", "2.1.3")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource Logger;

		internal static ConfigValues Config;

		private static readonly Harmony Harmony = new Harmony("DramaMask");

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin DramaMask (2.1.3) is loading...");
			Config = new ConfigValues(((BaseUnityPlugin)this).Config);
			try
			{
				InputUtilsCompat.Init();
			}
			catch
			{
				Logger.LogInfo((object)"Soft dependency on InputUtils could not be loaded.");
			}
			NetcodePatcher();
			Logger.LogInfo((object)"Loading assets...");
			LoadAssets();
			Logger.LogInfo((object)"Loading assets complete!");
			Logger.LogInfo((object)"Patching...");
			Type typeFromHandle = typeof(LethalHandsPatch);
			Harmony.PatchExcept(new Type[1] { typeFromHandle });
			try
			{
				Harmony.PatchAll(typeFromHandle);
			}
			catch
			{
			}
			Logger.LogInfo((object)"Patching complete!");
			Logger.LogInfo((object)"Plugin DramaMask (2.1.3) is loaded!");
		}

		private static void NetcodePatcher()
		{
			Type[] array;
			try
			{
				array = Assembly.GetExecutingAssembly().GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				array = ex.Types.Where((Type t) => t != null).ToArray();
			}
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array3 = methods;
				foreach (MethodInfo methodInfo in array3)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		private void LoadAssets()
		{
			AssetBundle val = LoadBundle("DramaMask", "dramamask");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Item val2 = val.SafeLoadAsset<Item>("assets/drama/dramamask.asset");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Utilities.FixMixerGroups(val2.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val2.spawnPrefab);
			Items.RegisterScrap(val2, Config.DramaSpawnMapVanilla, Config.DramaSpawnMapModded);
			Logger.LogDebug((object)"Loaded asset: dramaMask");
			AssetBundle val3 = LoadBundle("DramaMask", "maskview");
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			Mesh val4 = val3.SafeLoadAsset<Mesh>("assets/maskview/maskoutline.001.mesh");
			if (!((Object)(object)val4 == (Object)null))
			{
				HauntedMaskItemExtensions.OutlineMesh = val4;
				Logger.LogDebug((object)"Loaded asset: maskOutline");
				Material val5 = val3.SafeLoadAsset<Material>("assets/maskview/transmaskmat.mat");
				if (!((Object)(object)val5 == (Object)null))
				{
					HauntedMaskItemExtensions.TransparentMat = val5;
					Logger.LogDebug((object)"Loaded asset: transMaskMat");
				}
			}
		}

		private AssetBundle LoadBundle(string guid, string bundleName)
		{
			AssetBundle val = null;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			string text = manifestResourceNames.FirstOrDefault((string n) => n.StartsWith(guid + ".Assets." + bundleName));
			if (text == null)
			{
				Logger.LogError((object)("Embedded resource for [" + guid + "] not found!\nAvailable: [" + string.Join(", ", manifestResourceNames) + "]"));
				return val;
			}
			try
			{
				Logger.LogDebug((object)("Loading embedded resource data [" + text + "]..."));
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				val = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			}
			catch (Exception arg)
			{
				Logger.LogError((object)("Bundle [" + text + "] failed to load!\nAvailable: [" + string.Join(", ", val.GetAllAssetNames()) + "]" + $"\n{arg}"));
				return val;
			}
			Logger.LogDebug((object)("Bundle [" + text + "] accessible!"));
			return val;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "DramaMask";

		public const string PLUGIN_NAME = "Stealthy Masks";

		public const string PLUGIN_VERSION = "2.1.3";
	}
}
namespace DramaMask.UI
{
	public class StealthMeter : MonoBehaviour
	{
		private const float AccurateMinValue = 0.2978f;

		private const float AccurateMaxValue = 0.9101f;

		private const float AccurateValueRange = 0.6123f;

		private static Vector3 _initWeightPosition;

		private static Vector3 _initStatusPosition;

		public static bool Initialised;

		private GameObject _sprintMeter;

		private GameObject _stealthMeter;

		private Image uiElement;

		private TextMeshProUGUI uiEladsText;

		private static bool IsOxygenInstalled => Chainloader.PluginInfos.ContainsKey("consequential.Oxygen");

		private static bool IsEladsHudInstalled => Chainloader.PluginInfos.ContainsKey("me.eladnlg.customhud");

		private static bool IsShyHudInstalled => Chainloader.PluginInfos.ContainsKey("ShyHUD");

		private static bool IsLcVrInstalled => false;

		private static GameObject WeightUi => GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/TopLeftCorner/WeightUI");

		private static GameObject StatusEffectContainer => GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/TopLeftCorner/StatusEffects");

		public static StealthMeter Instance { get; private set; }

		public bool Visible
		{
			get
			{
				if ((Object)(object)uiElement == (Object)null)
				{
					return false;
				}
				return ((Behaviour)uiElement).enabled;
			}
			set
			{
				if (!((Object)(object)uiElement == (Object)null))
				{
					((Behaviour)uiElement).enabled = value;
					if ((Object)(object)uiEladsText != (Object)null)
					{
						((Behaviour)uiEladsText).enabled = value;
					}
				}
			}
		}

		public float Percent
		{
			get
			{
				if ((Object)(object)uiElement == (Object)null)
				{
					return 0f;
				}
				return IsEladsHudInstalled ? uiElement.fillAmount : InvAdjustFillAmount(uiElement.fillAmount);
			}
			set
			{
				if ((Object)(object)uiElement == (Object)null)
				{
					return;
				}
				float num = (IsEladsHudInstalled ? value : AdjustFillAmount(value));
				if (uiElement.fillAmount != num)
				{
					uiElement.fillAmount = num;
					if ((Object)(object)uiEladsText != (Object)null)
					{
						float num2 = (float)Math.Round(Percent, 2);
						int num3 = (int)(num2 * 100f);
						((TMP_Text)uiEladsText).text = $"{num3}<size=75%><voffset=1>%</voffset></size>";
					}
					if (IsShyHudInstalled)
					{
						bool flag = value >= 0.75f;
						((Graphic)uiElement).CrossFadeAlpha(flag ? 0f : 1f, flag ? 5f : 0.5f, false);
					}
				}
			}
		}

		public Color Colour
		{
			get
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)uiElement == (Object)null)
				{
					return Color.white;
				}
				return ((Graphic)uiElement).color;
			}
			set
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)uiElement == (Object)null))
				{
					((Graphic)uiElement).color = value;
					if ((Object)(object)uiEladsText != (Object)null)
					{
						((Graphic)uiEladsText).color = value;
					}
				}
			}
		}

		private GameObject SprintMeter
		{
			get
			{
				if ((Object)(object)_sprintMeter == (Object)null)
				{
					_sprintMeter = (IsEladsHudInstalled ? GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/PlayerInfo(Clone)/Stamina") : ((Component)GameNetworkManager.Instance.localPlayerController.sprintMeterUI).gameObject);
					if ((Object)(object)_sprintMeter == (Object)null)
					{
						Plugin.Logger.LogError((object)"SprintMeter is null");
					}
				}
				return _sprintMeter;
			}
		}

		private static float AdjustFillAmount(float value)
		{
			return Plugin.Config.AccurateMeter ? (value * 0.6123f + 0.2978f) : value;
		}

		private static float InvAdjustFillAmount(float value)
		{
			return Plugin.Config.AccurateMeter ? ((value - 0.2978f) / 0.6123f) : value;
		}

		public static void Init()
		{
			if (Initialised)
			{
				Plugin.Logger.LogDebug((object)"StealthMeter already initialized");
				return;
			}
			Instance = new StealthMeter();
			Initialised = true;
		}

		private static void SetInitPositions()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			_initWeightPosition = (Vector3)(((Object)(object)WeightUi == (Object)null) ? default(Vector3) : WeightUi.transform.localPosition);
			_initStatusPosition = (Vector3)(((Object)(object)StatusEffectContainer == (Object)null) ? default(Vector3) : StatusEffectContainer.transform.localPosition);
		}

		private StealthMeter()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)SprintMeter.transform.parent).gameObject;
			_stealthMeter = Object.Instantiate<GameObject>(SprintMeter, gameObject.transform);
			((Object)_stealthMeter).name = "StealthMeter";
			if (IsLcVrInstalled)
			{
				CoroutineHelper.Start(InitVr());
				return;
			}
			SetInitPositions();
			if (IsEladsHudInstalled)
			{
				InitEladsHud();
			}
			else
			{
				InitVanilla();
			}
			Colour = Plugin.Config.MeterColour;
			Percent = 1f;
		}

		private void InitVanilla()
		{
			uiElement = ((Component)_stealthMeter.transform).GetComponent<Image>();
			ApplyMeterOffsets();
			Plugin.Logger.LogInfo((object)"StealthMeter initialised (Vanilla)");
		}

		public void ApplyMeterOffsets()
		{
			if (IsLcVrInstalled)
			{
				ApplyVrMeterOffsets();
			}
			else
			{
				ApplyMeterOffsetsCommon();
			}
		}

		private void ApplyMeterOffsetsCommon()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_stealthMeter == (Object)null)
			{
				Plugin.Logger.LogError((object)"StealthMeter was uninitialised while applying offsets");
				return;
			}
			RectTransform component = SprintMeter.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Logger.LogError((object)"SprintRectTransform not found while applying offsets");
				return;
			}
			int num = 1;
			Vector3 val = (Vector3)(IsLcVrInstalled ? (new Vector3(0f, -5f, 3f) / (float)num) : new Vector3(3f, -5f, 0f));
			Vector3 val2 = (IsLcVrInstalled ? new Vector3(0f, 0.4f, 0.3f) : new Vector3(0.3f, 0.4f, 0f));
			_stealthMeter.transform.localPosition = ((Transform)component).localPosition + Plugin.Config.MeterOffset * val;
			_stealthMeter.transform.localScale = ((Transform)component).localScale + Plugin.Config.MeterOffset * val2;
			_stealthMeter.transform.rotation = ((Transform)component).rotation;
			if ((Object)(object)StatusEffectContainer != (Object)null)
			{
				int num2 = ((IsOxygenInstalled && !IsLcVrInstalled) ? 1 : 0);
				StatusEffectContainer.transform.localPosition = _initStatusPosition + new Vector3(Math.Max(num2, Plugin.Config.MeterOffset) * 20f, 0f, 0f);
				Plugin.Logger.LogInfo((object)"StatusEffectHUD adjusted");
			}
			if ((Object)(object)WeightUi != (Object)null)
			{
				WeightUi.transform.localPosition = _initWeightPosition + new Vector3(Math.Max(0f, Plugin.Config.MeterOffset * 20f), 0f, 0f);
				Plugin.Logger.LogInfo((object)"WeightUI adjusted");
			}
		}

		private void InitEladsHud()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			uiElement = ((Component)_stealthMeter.transform.Find("Bar/StaminaBar")).GetComponent<Image>();
			uiEladsText = ((Component)_stealthMeter.transform.Find("StaminaInfo")).GetComponent<TextMeshProUGUI>();
			((TMP_Text)uiEladsText).horizontalAlignment = (HorizontalAlignmentOptions)4;
			Object.DestroyImmediate((Object)(object)((Component)_stealthMeter.transform.Find("CarryInfo")).gameObject);
			Object.DestroyImmediate((Object)(object)((Component)_stealthMeter.transform.Find("Bar/Stamina Change FG")).gameObject);
			_stealthMeter.transform.localPosition = SprintMeter.transform.localPosition + new Vector3(0f, 60f, 0f);
			Plugin.Logger.LogInfo((object)"StealthMeter initialised (EladsHUD)");
		}

		private IEnumerator InitVr()
		{
			yield break;
		}

		private void ApplyVrMeterOffsets()
		{
			if ((Object)(object)_stealthMeter == (Object)null)
			{
				Plugin.Logger.LogError((object)"StealthMeter was uninitialised while applying offsets");
				return;
			}
			Transform transform = SprintMeter.transform;
			_stealthMeter.transform.SetParent(transform.parent, false);
			ApplyMeterOffsets();
			_stealthMeter.transform.SetParent(transform, true);
		}
	}
}
namespace DramaMask.Patches.StartOfRoundPatch
{
	[HarmonyPatch(typeof(StartOfRound), "EndPlayersFiredSequenceClientRpc")]
	public class EndPlayersFiredSequencePatch
	{
		[HarmonyPostfix]
		public static void Postfix(StartOfRound __instance)
		{
			bool isMaskAttached = NetworkHandler.Instance.MyPretend.IsMaskAttached;
			NetworkHandler.Instance.MyPretend.IsMaskAttached = false;
			if (isMaskAttached)
			{
				int currentItemSlot = __instance.localPlayerController.currentItemSlot;
				((Behaviour)HUDManager.Instance.itemSlotIcons[currentItemSlot]).enabled = false;
			}
			NetworkHandler.Instance.MyPretend.Reset();
			NetworkHandler.Instance.MyStealth.Reset();
			if (!NetworkHandler.IsHostOrServer())
			{
				return;
			}
			foreach (KeyValuePair<ulong, StealthData> item in NetworkHandler.Instance.StealthMap)
			{
				item.Value.Reset();
			}
			foreach (KeyValuePair<ulong, PretendData> item2 in NetworkHandler.Instance.PretendMap)
			{
				item2.Value.Reset();
			}
		}
	}
}
namespace DramaMask.Patches.LethalHandsPatch
{
	[HarmonyPatch(typeof(LethalHands))]
	public class LethalHandsPatch
	{
		[HarmonyPatch("SquareUp")]
		[HarmonyPrefix]
		public static void Prefix(LethalHands __instance)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (localPlayerController.IsLocal() && NetworkHandler.Instance.MyPretend.IsMaskAttached)
			{
				NetworkHandler.Instance.MyPretend.IsMaskAttached = false;
				if ((int)SyncedInstance<NetworkConfig>.Instance.itemDropMode == 0)
				{
					localPlayerController.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
				}
			}
		}
	}
}
namespace DramaMask.Patches.HudManagerPatch
{
	[HarmonyPatch(typeof(HUDManager), "Start")]
	public class StartPatch
	{
		[HarmonyPostfix]
		public static void Postfix(HUDManager __instance)
		{
			CoroutineHelper.Start(CreateStealthMeter());
		}

		private static IEnumerator CreateStealthMeter()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)GameNetworkManager.Instance.localPlayerController?.sprintMeterUI != (Object)null));
			if (Plugin.Config.UseStealthMeter.Value && Plugin.Config.StealthMeterVisibility.LocalValue != 0)
			{
				StealthMeter.Init();
				StealthMeter.Instance.Visible = Plugin.Config.StealthMeterVisibility.LocalValue == MeterVisibility.Always;
			}
		}
	}
}
namespace DramaMask.Patches.HauntedMaskItemPatch
{
	[HarmonyPatch(typeof(HauntedMaskItem), "BeginAttachment")]
	public class BeginAttachmentPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(HauntedMaskItem __instance)
		{
			return !NetworkHandler.Instance.MyPretend.IsMaskAttached || Plugin.Config.AttachedCanPossess.Value;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "DiscardItem")]
	public class DiscardItemPatch
	{
		[HarmonyPrefix]
		public static void Prefix(HauntedMaskItem __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				((GrabbableObject)__instance).playerHeldBy.equippedUsableItemQE = false;
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "EquipItem")]
	public class EquipItemPatch
	{
		[HarmonyPostfix]
		public static void Postfix(HauntedMaskItem __instance)
		{
			((GrabbableObject)__instance).playerHeldBy.equippedUsableItemQE = true;
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "MaskClampToHeadAnimationEvent")]
	public class MaskClampPatch
	{
		[HarmonyPrefix]
		public static void Prefix(HauntedMaskItem __instance, bool ___attaching, PlayerControllerB ___previousPlayerHeldBy)
		{
			if (___attaching && !((Object)(object)___previousPlayerHeldBy == (Object)null) && !((Object)(object)__instance.currentHeadMask == (Object)null))
			{
				Object.Destroy((Object)(object)((Component)__instance.currentHeadMask).gameObject);
				__instance.currentHeadMask = null;
			}
		}
	}
	[HarmonyPatch(typeof(HauntedMaskItem), "PocketItem")]
	public class PocketItemPatch
	{
		[HarmonyPrefix]
		public static void Prefix(HauntedMaskItem __instance)
		{
			if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null))
			{
				((GrabbableObject)__instance).playerHeldBy.equippedUsableItemQE = false;
			}
		}
	}
}
namespace DramaMask.Patches.GrabbableObjectItemPatch
{
	[HarmonyPatch(typeof(GrabbableObject), "SetControlTipsForItem")]
	public class ControlTipsPatch
	{
		private static List<string> _defaultTooltips;

		[HarmonyPostfix]
		public static void Postfix(GrabbableObject __instance)
		{
			HauntedMaskItem val = (HauntedMaskItem)(object)((__instance is HauntedMaskItem) ? __instance : null);
			if (val != null && !((Object)(object)((GrabbableObject)val).playerHeldBy == (Object)null) && ((NetworkBehaviour)val).IsOwner && !((Object)(object)((GrabbableObject)val).itemProperties == (Object)null) && ((GrabbableObject)val).itemProperties.toolTips != null && val.CanHide())
			{
				if (_defaultTooltips == null)
				{
					_defaultTooltips = ((GrabbableObject)val).itemProperties.toolTips.ToList();
				}
				List<string> list = _defaultTooltips.ToList();
				if (NetworkHandler.Instance.MyPretend.IsMaskAttached)
				{
					list.AddRange(new <>z__ReadOnlyArray<string>(new string[2]
					{
						"Detach mask: [Q]",
						(!NetworkHandler.Instance.MyPretend.IsMaskEyesOn) ? "Activate eyes: [E]" : "Deactivate eyes: [E]"
					}));
				}
				else
				{
					list.AddRange(new <>z__ReadOnlyArray<string>(new string[2] { "Attach mask: [Q]", "" }));
				}
				((GrabbableObject)val).itemProperties.toolTips = list.ToArray();
				HUDManager.Instance.ChangeControlTipMultiple(((GrabbableObject)val).itemProperties.toolTips, true, ((GrabbableObject)val).itemProperties);
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject), "InteractLeftRightServerRpc")]
	public class InteractLeftRightPatch
	{
		private static bool _useInputFlipFlop;

		[HarmonyPostfix]
		public static void Postfix(GrabbableObject __instance, bool right)
		{
			HauntedMaskItem val = (HauntedMaskItem)(object)((__instance is HauntedMaskItem) ? __instance : null);
			if (val == null || !val.CanHide() || (Object)(object)((GrabbableObject)val).playerHeldBy == (Object)null || (!NetworkHandler.IsHostOrServer() && !((GrabbableObject)val).playerHeldBy.IsLocal()))
			{
				return;
			}
			ulong id = ((GrabbableObject)val).playerHeldBy.GetId();
			if (NetworkHandler.IsHostOrServer() && ((GrabbableObject)val).playerHeldBy.IsLocal())
			{
				_useInputFlipFlop = !_useInputFlipFlop;
				if (_useInputFlipFlop)
				{
					return;
				}
			}
			StealthData stealth = NetworkHandler.Instance.GetStealth(((GrabbableObject)val).playerHeldBy.IsLocal(), id);
			if (stealth == null)
			{
				return;
			}
			PretendData pretend = NetworkHandler.Instance.GetPretend(((GrabbableObject)val).playerHeldBy.IsLocal(), id);
			if (pretend == null)
			{
				return;
			}
			if (pretend.IsMaskAttached)
			{
				if (!right)
				{
					pretend.IsMaskAttached = false;
					if (Plugin.Config.ChangeClientViewInstantly)
					{
						val.SetMaskAttached(isAttaching: false);
					}
					if (stealth.IsHoldingMask)
					{
						((GrabbableObject)val).playerHeldBy.playerBodyAnimator.SetBool("HoldMask", true);
						((GrabbableObject)val).playerHeldBy.playerBodyAnimator.Play("HoldingItemsRightHand.HoldMaskToFace", 2, 1f);
					}
					else
					{
						Traverse.Create((object)val).Field("maskOn").SetValue((object)false);
					}
					return;
				}
				bool flag = !StartOfRound.Instance.localPlayerUsingController;
				if (!Plugin.Config.IgnoreCustomKeybinds)
				{
					try
					{
						flag = InputUtilsCompat.IsMaskEyeInteractClash();
					}
					catch (TypeLoadException)
					{
					}
				}
				if (((GrabbableObject)val).playerHeldBy.IsLocal() && (!flag || (Object)(object)((GrabbableObject)val).playerHeldBy.hoveringOverTrigger == (Object)null))
				{
					pretend.IsMaskEyesOn = !pretend.IsMaskEyesOn;
					if (Plugin.Config.ChangeClientViewInstantly)
					{
						val.SetMaskEyes(pretend.IsMaskEyesOn);
					}
					NetworkHandler.Instance.SetPlayerMaskEyesValueServerRpc(id, pretend.IsMaskEyesOn);
				}
			}
			else if (!right)
			{
				pretend.IsMaskAttached = true;
				if (Plugin.Config.ChangeClientViewInstantly)
				{
					val.SetMaskAttached(isAttaching: true);
				}
				Traverse.Create((object)val).Field("maskOn").SetValue((object)true);
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject), "ActivateItemServerRpc")]
	public class ItemActivatePatch
	{
		private static bool _useInputFlipFlop;

		[HarmonyPostfix]
		public static void Postfix(GrabbableObject __instance, bool onOff, bool buttonDown)
		{
			HauntedMaskItem val = (HauntedMaskItem)(object)((__instance is HauntedMaskItem) ? __instance : null);
			if (val == null || (Object)(object)((GrabbableObject)val).playerHeldBy == (Object)null || (!NetworkHandler.IsHostOrServer() && !((GrabbableObject)val).playerHeldBy.IsLocal()))
			{
				return;
			}
			ulong id = ((GrabbableObject)val).playerHeldBy.GetId();
			if (NetworkHandler.IsHostOrServer() && ((GrabbableObject)val).playerHeldBy.IsLocal())
			{
				_useInputFlipFlop = !_useInputFlipFlop;
				if (_useInputFlipFlop)
				{
					return;
				}
			}
			StealthData stealth = NetworkHandler.Instance.GetStealth(((GrabbableObject)val).playerHeldBy.IsLocal(), id);
			if (stealth == null)
			{
				return;
			}
			PretendData pretend = NetworkHandler.Instance.GetPretend(((GrabbableObject)val).playerHeldBy.IsLocal(), id);
			if (pretend != null)
			{
				stealth.IsHoldingMask = buttonDown && val.CanHide();
				if (!pretend.IsMaskAttached)
				{
					Traverse.Create((object)val).Field("maskOn").SetValue((object)buttonDown);
				}
				if (((GrabbableObject)val).playerHeldBy.IsLocal())
				{
					val.SetMaskView(buttonDown ? new int?((int)Plugin.Config.HeldMaskView.LocalValue) : null);
				}
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject), "Start")]
	public class StartPatch
	{
		[HarmonyPostfix]
		public static void Postfix(GrabbableObject __instance)
		{
			if (__instance is HauntedMaskItem)
			{
				__instance.itemProperties.syncUseFunction = true;
				__instance.itemProperties.syncInteractLRFunction = true;
			}
		}
	}
}
namespace DramaMask.Patches.PlayerControllerBPatch
{
	[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
	public class DisconnectPatch
	{
		[HarmonyPostfix]
		public static void Postfix(GameNetworkManager __instance)
		{
			if (StealthMeter.Initialised)
			{
				StealthMeter.Initialised = false;
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "SaveItemsInShip")]
	public class SaveItemsInShipPatch
	{
		[HarmonyPrefix]
		public static void Prefix(GameNetworkManager __instance)
		{
			HauntedMaskItem[] array = Object.FindObjectsByType<HauntedMaskItem>((FindObjectsSortMode)0);
			HauntedMaskItem[] array2 = array;
			foreach (HauntedMaskItem val in array2)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.currentHeadMask == (Object)null)
				{
					continue;
				}
				HauntedMaskItem component = ((Component)val.currentHeadMask).gameObject.GetComponent<HauntedMaskItem>();
				if (!((Object)(object)component == (Object)null))
				{
					if (!__instance.isDisconnecting)
					{
						break;
					}
					((GrabbableObject)component).deactivated = true;
					Object.Destroy((Object)(object)((Component)val.currentHeadMask).gameObject);
					val.currentHeadMask = null;
				}
			}
		}
	}
	public class BaseEndSpecialAnimationPatch
	{
		public static void HideMaskVisibilityOnAnimationEnd(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player.currentlyHeldObjectServer == (Object)null))
			{
				GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
				HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
				if (val != null && !((Object)(object)val.currentHeadMask == (Object)null))
				{
					val.SetVisibility(isVisible: false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(InteractTrigger), "StopSpecialAnimation")]
	public class StopSpecialAnimationPatch : BaseEndSpecialAnimationPatch
	{
		[HarmonyPrefix]
		public static void Prefix(InteractTrigger __instance, Transform ___lockedPlayer, out Transform __state)
		{
			__state = ___lockedPlayer;
		}

		[HarmonyPostfix]
		public static void Postfix(InteractTrigger __instance, Transform __state)
		{
			if (!((Object)(object)__state == (Object)null))
			{
				BaseEndSpecialAnimationPatch.HideMaskVisibilityOnAnimationEnd(((Component)__state).GetComponent<PlayerControllerB>());
			}
		}
	}
	[HarmonyPatch(typeof(InteractTrigger), "SetInteractTriggerNotInAnimation")]
	public class SetInteractTriggerNotInAnimationPatch : BaseEndSpecialAnimationPatch
	{
		[HarmonyPostfix]
		public static void Postfix(InteractTrigger __instance, int playerUsing)
		{
			if (StartOfRound.Instance.allPlayerScripts.Length > playerUsing)
			{
				BaseEndSpecialAnimationPatch.HideMaskVisibilityOnAnimationEnd(StartOfRound.Instance.allPlayerScripts[playerUsing]);
			}
		}
	}
	public abstract class BaseChangeItemPatch
	{
		protected static bool ShouldInvoke(PlayerControllerB __instance)
		{
			if (!__instance.isPlayerControlled)
			{
				return true;
			}
			if (!__instance.IsLocal())
			{
				return true;
			}
			if (!NetworkHandler.Instance.MyPretend.IsMaskAttached)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Discard_performed")]
	public class DiscardPatch : BaseChangeItemPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			return BaseChangeItemPatch.ShouldInvoke(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItems")]
	public class DropAllHeldItemsPatch
	{
		private static readonly List<CodeInstruction> _isMaskAttached = new List<CodeInstruction>(2)
		{
			new CodeInstruction(OpCodes.Ldarg_0, (object)null),
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropAllHeldItemsPatch), "IsMaskAttached", (Type[])null, (Type[])null))
		};

		private static readonly List<CodeInstruction> _isPlayerValid = new List<CodeInstruction>(3)
		{
			new CodeInstruction(OpCodes.Ldarg_0, (object)null),
			new CodeInstruction(OpCodes.Ldarg_2, (object)null),
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropAllHeldItemsPatch), "IsPlayerValid", (Type[])null, (Type[])null))
		};

		private static readonly List<CodeInstruction> _currentItemIsHeld = new List<CodeInstruction>(4)
		{
			new CodeInstruction(OpCodes.Ldloc_0, (object)null),
			new CodeInstruction(OpCodes.Ldarg_0, (object)null),
			new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "currentlyHeldObjectServer")),
			new CodeInstruction(OpCodes.Ceq, (object)null)
		};

		private static bool IsMaskAttached(PlayerControllerB player)
		{
			GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
			HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
			return (Object)(object)val != (Object)null && (Object)(object)val.currentHeadMask != (Object)null;
		}

		private static bool IsPlayerValid(PlayerControllerB player, bool disconnecting)
		{
			return !player.isPlayerDead && !disconnecting;
		}

		[HarmonyPrefix]
		public static void Prefix(PlayerControllerB __instance, bool itemsFall = true, bool disconnecting = false)
		{
			if (!IsPlayerValid(__instance, disconnecting))
			{
				GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
				HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
				if (__instance.IsLocal())
				{
					NetworkHandler.Instance.MyPretend.IsMaskAttached = false;
				}
				else if (NetworkHandler.IsHostOrServer())
				{
					NetworkHandler.Instance.PretendMap[__instance.GetId()].IsMaskAttached = false;
				}
				if (__instance.isPlayerDead && (Object)(object)val != (Object)null && (Object)(object)val.currentHeadMask != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val.currentHeadMask).gameObject);
					val.currentHeadMask = null;
				}
			}
		}

		[HarmonyPostfix]
		public static void Postfix(PlayerControllerB __instance, bool itemsFall = true, bool disconnecting = false)
		{
			if (IsPlayerValid(__instance, disconnecting) && IsMaskAttached(__instance))
			{
				__instance.carryWeight = __instance.currentlyHeldObjectServer.itemProperties.weight;
			}
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> IgnoreDroppingAttachedMask(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Expected O, but got Unknown
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: 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_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stloc_1, (object)null, (string)null)
			});
			Label label = generator.DefineLabel();
			val.AddLabelsAt(val.Pos, (IEnumerable<Label>)new <>z__ReadOnlyArray<Label>(new Label[1] { label }));
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ret, (object)null, (string)null)
			});
			Label label2 = generator.DefineLabel();
			val.AddLabelsAt(val.Pos, (IEnumerable<Label>)new <>z__ReadOnlyArray<Label>(new Label[1] { label2 }));
			val.Start();
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "ItemSlots"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null)
			});
			val.Advance(1);
			val.InsertAndAdvance(_isPlayerValid.Union(_isMaskAttached).Union(_currentItemIsHeld).Union(new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.And, (object)null),
				new CodeInstruction(OpCodes.And, (object)null),
				new CodeInstruction(OpCodes.Brtrue, (object)label)
			})));
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Property(typeof(NetworkBehaviour), "IsOwner").GetMethod, (string)null)
			});
			val.Advance(1);
			val.InsertAndAdvance(_isPlayerValid.Union(_isMaskAttached).Union(new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.And, (object)null),
				new CodeInstruction(OpCodes.Not, (object)null),
				new CodeInstruction(OpCodes.And, (object)null)
			})));
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "isHoldingObject"), (string)null)
			});
			val.Advance(2);
			val.InsertAndAdvance(_isPlayerValid.Union(_isMaskAttached).Union(new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.And, (object)null),
				new CodeInstruction(OpCodes.Brtrue, (object)label2)
			})));
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
	public class GrabObjectPatch : BaseChangeItemPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			return BaseChangeItemPatch.ShouldInvoke(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class KillPlayerPatch
	{
		[HarmonyPatch("KillPlayerClientRpc")]
		[HarmonyPrefix]
		public static void Prefix(int playerId, bool spawnBody, Vector3 bodyVelocity, int causeOfDeath, int deathAnimation)
		{
			PlayerControllerB component = StartOfRound.Instance.allPlayerObjects[playerId].GetComponent<PlayerControllerB>();
			component.isPlayerDead = true;
		}

		[HarmonyPatch("KillPlayer")]
		[HarmonyPostfix]
		public static void Postfix(PlayerControllerB __instance, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation)
		{
			ulong id = __instance.GetId();
			if (__instance.IsLocal())
			{
				NetworkHandler.Instance.MyStealth.Reset();
				NetworkHandler.Instance.MyPretend.Reset();
			}
			if (NetworkHandler.IsHostOrServer())
			{
				NetworkHandler.Instance.StealthMap[id].Reset();
				NetworkHandler.Instance.PretendMap[id].Reset();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
	public class LateUpdatePatch
	{
		[HarmonyPostfix]
		public static void Postfix(PlayerControllerB __instance)
		{
			HandleStealthMeter(__instance);
			HandleAttachedMask(__instance);
		}

		private static void HandleStealthMeter(PlayerControllerB __instance)
		{
			if (Plugin.Config.UseStealthMeter.Value && Plugin.Config.StealthMeterVisibility.LocalValue != 0 && StealthMeter.Initialised && __instance.isPlayerControlled && __instance.IsLocal() && !__instance.isPlayerDead)
			{
				bool flag = ShouldBarBeVisible(__instance.currentlyHeldObjectServer);
				StealthMeter.Instance.Visible = flag;
				if (flag)
				{
					float percent = Math.Max(0f, NetworkHandler.Instance.MyStealth.StealthValue) / Plugin.Config.MaxHiddenTime.Value;
					StealthMeter.Instance.Percent = percent;
				}
			}
		}

		private static bool ShouldBarBeVisible(GrabbableObject heldItem)
		{
			return Plugin.Config.StealthMeterVisibility.LocalValue == MeterVisibility.Always || (((HauntedMaskItem)(object)((heldItem is HauntedMaskItem) ? heldItem : null))?.CanHide() ?? false);
		}

		private static void HandleAttachedMask(PlayerControllerB __instance)
		{
			if (__instance.isPlayerControlled && !((Object)(object)__instance.currentlyHeldObjectServer == (Object)null))
			{
				GrabbableObject currentlyHeldObjectServer = __instance.currentlyHeldObjectServer;
				HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
				if (val != null && !((Object)(object)val.currentHeadMask == (Object)null))
				{
					AccessTools.Method(typeof(HauntedMaskItem), "PositionHeadMaskWithOffset", (Type[])null, (Type[])null).Invoke(val, null);
				}
			}
		}
	}
	public class QeInputPatchBase
	{
		public static bool ShouldProcessInput(PlayerControllerB __instance, ref bool isCustomInput, bool right)
		{
			if (!InputUtilsCompat.Enabled)
			{
				return true;
			}
			if ((!right && InputUtilsCompat.IsMaskAttachDefaultClash()) || (right && InputUtilsCompat.IsMaskEyeDefaultClash()))
			{
				return true;
			}
			bool flag = (Object)(object)__instance != (Object)null && __instance.currentlyHeldObjectServer is HauntedMaskItem;
			PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
			bool flag2 = (Object)(object)localPlayerController != (Object)null && localPlayerController.currentlyHeldObjectServer is HauntedMaskItem;
			bool flag3 = false;
			if (flag == flag2)
			{
				flag3 = isCustomInput;
				isCustomInput = false;
			}
			return flag3 ^ !flag;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
	public class SwitchSlotsPatch : BaseChangeItemPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			if (__instance.inTerminalMenu)
			{
				return true;
			}
			return BaseChangeItemPatch.ShouldInvoke(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ItemSecondaryUse_performed")]
	public class SecondaryUsePatch : QeInputPatchBase
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			return QeInputPatchBase.ShouldProcessInput(__instance, ref InputUtilsCompat.HandleAttachMask, right: false);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
	public class SwitchToItemSlotPatch : BaseChangeItemPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			return BaseChangeItemPatch.ShouldInvoke(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "ItemTertiaryUse_performed")]
	public class TertiaryUsePatch : QeInputPatchBase
	{
		[HarmonyPrefix]
		public static bool Prefix(PlayerControllerB __instance)
		{
			return QeInputPatchBase.ShouldProcessInput(__instance, ref InputUtilsCompat.HandleMaskEyes, right: true);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	public class UpdatePatch
	{
		[HarmonyPostfix]
		public static void Postfix(PlayerControllerB __instance)
		{
			if (!Plugin.Config.UseStealthMeter.Value || !__instance.isPlayerControlled || (!NetworkHandler.IsHostOrServer() && !__instance.IsLocal()))
			{
				return;
			}
			ulong id = __instance.GetId();
			PretendData pretend = NetworkHandler.Instance.GetPretend(__instance.IsLocal(), id);
			if (pretend == null)
			{
				return;
			}
			StealthData stealth = NetworkHandler.Instance.GetStealth(__instance.IsLocal(), id);
			if (stealth == null)
			{
				return;
			}
			bool flag = stealth.IsAttemptingStealth();
			if (flag)
			{
				if (stealth.StealthValue > 0f)
				{
					stealth.StealthValue = Math.Max(0f, stealth.StealthValue - Time.deltaTime * (pretend.IsMaskAttached ? Plugin.Config.AttachedStealthMultiplier.Value : 1f));
				}
				else if (Plugin.Config.RemoveOnDepletion.Value)
				{
					pretend.IsMaskAttached = false;
				}
			}
			else if (!flag && stealth.StealthValue < Plugin.Config.MaxHiddenTime.Value && (!stealth.LastStoppedStealth.HasValue || DateTime.UtcNow.Subtract(stealth.LastStoppedStealth.Value).TotalSeconds > (double)Plugin.Config.RechargeDelay.Value))
			{
				stealth.StealthValue = Math.Min(Plugin.Config.MaxHiddenTime.Value, stealth.StealthValue + Time.deltaTime);
				if (stealth.LastStoppedStealth.HasValue)
				{
					stealth.LastStoppedStealth = null;
				}
				if (stealth.AddExhaustionPenalty)
				{
					stealth.AddExhaustionPenalty = false;
				}
			}
		}
	}
}
namespace DramaMask.Patches.Enemies
{
	public abstract class ModifyPlayerArrayPatchBase
	{
		private static PlayerControllerB[] allPlayerScriptsOriginal;

		protected static void AddOobCheckToLoopPredicate(CodeMatcher matcher, ILGenerator generator, CodeInstruction index)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			int pos = matcher.Pos;
			Label? label = default(Label?);
			if (!CodeInstructionExtensions.Branches(matcher.Instruction, ref label))
			{
				Plugin.Logger.LogWarning((object)"Couldn't apply OOB check to loop predicate: Loop entry target not accessible");
				return;
			}
			Label enterLoopTarget = label.Value;
			matcher.Advance(1);
			Label label2;
			if ((label2 = matcher.Instruction.labels.FirstOrDefault()) == default(Label))
			{
				label2 = generator.DefineLabel();
				matcher.AddLabelsAt(matcher.Pos, (IEnumerable<Label>)new <>z__ReadOnlyArray<Label>(new Label[1] { label2 }));
			}
			matcher.Start();
			matcher.SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.labels.Contains(enterLoopTarget)));
			List<CodeInstruction> list = new List<CodeInstruction>(3);
			list.Add(index);
			list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ModifyPlayerArrayPatchBase), "IsWithinPlayerBounds", (Type[])null, (Type[])null)));
			list.Add(new CodeInstruction(OpCodes.Brfalse, (object)label2));
			List<CodeInstruction> list2 = list;
			CodeInstruction instruction2 = matcher.Instruction;
			matcher.Insert((IEnumerable<CodeInstruction>)list2);
			CodeInstructionExtensions.MoveLabelsFrom(matcher.Instruction, instruction2);
			matcher.Start();
			matcher.Advance(pos + list2.Count);
		}

		protected static bool IsWithinPlayerBounds(int index)
		{
			return index < StartOfRound.Instance.allPlayerScripts.Length;
		}

		protected static ulong GetTrueIndex(int index)
		{
			return StartOfRound.Instance.allPlayerScripts[index].playerClientId;
		}

		protected static void SaveAndModifyPlayerArray(EnemyAI __instance)
		{
			if (EnemyTargetHandler.ShouldHideFromEnemy(__instance))
			{
				allPlayerScriptsOriginal = StartOfRound.Instance.allPlayerScripts;
				StartOfRound.Instance.allPlayerScripts = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB player) => (Object)(object)player == (Object)null || !player.isPlayerControlled || !player.IsHidden()).ToArray();
			}
		}

		protected static void LoadOriginalPlayerArray(EnemyAI __instance)
		{
			if (EnemyTargetHandler.ShouldHideFromEnemy(__instance))
			{
				StartOfRound.Instance.allPlayerScripts = allPlayerScriptsOriginal;
			}
		}
	}
	public abstract class OnCollideWithPlayerPatchBase
	{
		protected static void AddNoCollideCheck(CodeMatcher matcher, ILGenerator generator, CodeInstruction player, string enemyName)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			matcher.Advance(1);
			Label label = generator.DefineLabel();
			matcher.AddLabelsAt(matcher.Pos, (IEnumerable<Label>)new <>z__ReadOnlyArray<Label>(new Label[1] { label }));
			matcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[9]
			{
				player,
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerControllerBExtensions), "IsHidden", (Type[])null, (Type[])null)),
				player,
				new CodeInstruction(OpCodes.Ldstr, (object)enemyName),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyTargetHandler), "ShouldCollideWithEnemy", new Type[2]
				{
					typeof(PlayerControllerB),
					typeof(string)
				}, (Type[])null)),
				new CodeInstruction(OpCodes.Not, (object)null),
				new CodeInstruction(OpCodes.And, (object)null),
				new CodeInstruction(OpCodes.Brfalse, (object)label),
				new CodeInstruction(OpCodes.Ret, (object)null)
			});
		}
	}
}
namespace DramaMask.Patches.Enemies.TurretPatch
{
	[HarmonyPatch(typeof(Turret), "CheckForPlayersInLineOfSight")]
	public class CheckForPlayersInLineOfSightPatch
	{
		private static readonly List<CodeInstruction> _isPlayerHidden = new List<CodeInstruction>(2)
		{
			new CodeInstruction(OpCodes.Ldloc_3, (object)null),
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerControllerBExtensions), "IsHidden", (Type[])null, (Type[])null))
		};

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromRaycast(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"Player", (string)null)
			});
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null)
			});
			val.Advance(-1);
			object operand = val.Instruction.operand;
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Stloc_3, (object)null, (string)null)
			});
			val.Advance(1);
			val.InsertAndAdvance(_isPlayerHidden.Union(new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Brtrue, operand)
			})));
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.SandWormAIPatch
{
	[HarmonyPatch(typeof(SandWormAI), "OnCollideWithPlayer")]
	public class OnCollideWithPlayerPatch : OnCollideWithPlayerPatchBase
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CheckIfNoCollide(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null)
			});
			OnCollideWithPlayerPatchBase.AddNoCollideCheck(val, generator, new CodeInstruction(OpCodes.Ldloc_0, (object)null), "SandWormAI");
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.SandSpiderAIPatch
{
	[HarmonyPatch(typeof(SandSpiderAI), "DoAIInterval")]
	public class DoAIIntervalPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(SandSpiderAI __instance)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray((EnemyAI)(object)__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_1, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(SandSpiderAI __instance)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray((EnemyAI)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI), "TriggerChaseWithPlayer")]
	public class TriggerChaseWithPlayerPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(SandSpiderAI __instance, PlayerControllerB playerScript)
		{
			if (!EnemyTargetHandler.ShouldHideFromEnemy("SandSpiderAI"))
			{
				return true;
			}
			return !playerScript.IsHidden();
		}
	}
}
namespace DramaMask.Patches.Enemies.RedLocustBeesPatch
{
	[HarmonyPatch(typeof(RedLocustBees), "DoAIInterval")]
	public class DoAIIntervalPatch
	{
		private static bool IsPlayerHidden()
		{
			return EnemyTargetHandler.ShouldHideFromEnemy("RedLocustBees") && StartOfRound.Instance.localPlayerController.IsHidden();
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromCollider(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null)
			});
			val.Advance(7);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DoAIIntervalPatch), "IsPlayerHidden", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Not, (object)null),
				new CodeInstruction(OpCodes.And, (object)null)
			});
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.RadMechAIPatch
{
	[HarmonyPatch(typeof(RadMechAI), "CheckSightForThreat")]
	public class CheckSightForThreatPatch
	{
		private static bool IsThreatHiddenPlayer(Collider collider)
		{
			IVisibleThreat val = default(IVisibleThreat);
			int result;
			if (EnemyTargetHandler.ShouldHideFromEnemy("RadMechAI") && ((Component)((Component)collider).transform).TryGetComponent<IVisibleThreat>(ref val))
			{
				PlayerControllerB val2 = (PlayerControllerB)(object)((val is PlayerControllerB) ? val : null);
				if (val2 != null)
				{
					result = (val2.IsHidden() ? 1 : 0);
					goto IL_002f;
				}
			}
			result = 0;
			goto IL_002f;
			IL_002f:
			return (byte)result != 0;
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromCollider(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Br, (object)null, (string)null)
			});
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, (string)null)
			});
			object operand = val.Instruction.operand;
			val.Advance(1);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[6]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(RoundManager), "Instance").GetMethod),
				new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(RoundManager), "tempColliderResults")),
				new CodeInstruction(OpCodes.Ldloc_S, (object)5),
				new CodeInstruction(OpCodes.Ldelem_Ref, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CheckSightForThreatPatch), "IsThreatHiddenPlayer", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Brtrue, operand)
			});
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch(typeof(RadMechAI), "LookForPlayersInFlight")]
	public class LookForPlayersInFlightPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(RadMechAI __instance)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray((EnemyAI)(object)__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_0, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(RadMechAI __instance)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray((EnemyAI)(object)__instance);
		}
	}
}
namespace DramaMask.Patches.Enemies.NutcrackerEnemyAIPatch
{
	[HarmonyPatch(typeof(NutcrackerEnemyAI), "CheckLineOfSightForLocalPlayer")]
	public class CheckLineOfSightForLocalPlayerPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(NutcrackerEnemyAI __instance, ref bool __result, float width = 45f, int range = 60, int proximityAwareness = -1)
		{
			if (!GameNetworkManager.Instance.localPlayerController.IsHidden())
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
}
namespace DramaMask.Patches.Enemies.JesterAIPatch
{
	[HarmonyPatch(typeof(JesterAI), "Update")]
	public class UpdatePatch
	{
		private static readonly List<CodeInstruction> _isPlayerHidden = new List<CodeInstruction>(5)
		{
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(StartOfRound), "Instance").GetMethod),
			new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(StartOfRound), "allPlayerScripts")),
			new CodeInstruction(OpCodes.Ldloc_2, (object)null),
			new CodeInstruction(OpCodes.Ldelem_Ref, (object)null),
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerControllerBExtensions), "IsHidden", (Type[])null, (Type[])null))
		};

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromPopCheck(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "isInsideFactory"), (string)null)
			});
			val.Advance(1);
			object operand = val.Instruction.operand;
			val.Advance(1);
			val.InsertAndAdvance(_isPlayerHidden.Union(new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Brtrue, operand)
			})));
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.ForestGiantAIPatch
{
	[HarmonyPatch(typeof(ForestGiantAI), "OnCollideWithPlayer")]
	public class OnCollideWithPlayerPatch : OnCollideWithPlayerPatchBase
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CheckIfNoCollide(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null)
			});
			OnCollideWithPlayerPatchBase.AddNoCollideCheck(val, generator, new CodeInstruction(OpCodes.Ldloc_0, (object)null), "ForestGiantAI");
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.EnemyAIPatch
{
	[HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForClosestPlayer")]
	public class CheckLineOfSightForClosestPlayerPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(EnemyAI __instance, float width = 45f, int range = 60, int proximityAwareness = -1, float bufferDistance = 0f)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray(__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_S, (object)4));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(EnemyAI __instance, ref PlayerControllerB __result, float width = 45f, int range = 60, int proximityAwareness = -1, float bufferDistance = 0f)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForPlayer")]
	public class CheckLineOfSightForPlayerPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(EnemyAI __instance, float width = 45f, int range = 60, int proximityAwareness = -1)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray(__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_1, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(EnemyAI __instance, ref PlayerControllerB __result, float width = 45f, int range = 60, int proximityAwareness = -1)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "GetAllPlayersInLineOfSight")]
	public class GetAllPlayersInLineOfSightPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(EnemyAI __instance, float width = 45f, int range = 60, Transform eyeObject = null, float proximityCheck = -1f, int layerMask = -1)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray(__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_2, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(EnemyAI __instance, ref PlayerControllerB[] __result, float width = 45f, int range = 60, Transform eyeObject = null, float proximityCheck = -1f, int layerMask = -1)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "GetClosestPlayer")]
	public class GetClosestPlayerPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(EnemyAI __instance, bool requireLineOfSight = false, bool cannotBeInShip = false, bool cannotBeNearShip = false)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray(__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_1, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(EnemyAI __instance, ref PlayerControllerB __result, bool requireLineOfSight = false, bool cannotBeInShip = false, bool cannotBeNearShip = false)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "PlayerIsTargetable")]
	public class PlayerIsTargetablePatch
	{
		[HarmonyPrefix]
		public static bool Prefix(EnemyAI __instance, ref bool __result, PlayerControllerB playerScript, bool cannotBeInShip = false, bool overrideInsideFactoryCheck = false)
		{
			if (playerScript.IsHidden() && !EnemyTargetHandler.ShouldCollideWithEnemy(playerScript, __instance))
			{
				__result = false;
				return false;
			}
			if (!Plugin.Config.IncreaseCustomEnemyCompatibility.Value)
			{
				return true;
			}
			string name = new StackFrame(1).GetMethod().Name;
			if ("MeetsStandardPlayerCollisionConditions" == name)
			{
				return true;
			}
			if (!playerScript.IsHidden())
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI), "TargetClosestPlayer")]
	public class TargetClosestPlayerPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(EnemyAI __instance, float bufferDistance = 1.5f, bool requireLineOfSight = false, float viewWidth = 70f)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray(__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_1, (object)null));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(EnemyAI __instance, ref bool __result, float bufferDistance = 1.5f, bool requireLineOfSight = false, float viewWidth = 70f)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray(__instance);
		}
	}
}
namespace DramaMask.Patches.Enemies.DressGirlAIPatch
{
	[HarmonyPatch(typeof(DressGirlAI), "ChoosePlayerToHaunt")]
	public class ChoosePlayerToHauntPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(DressGirlAI __instance)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray((EnemyAI)(object)__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_S, (object)5));
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_S, (object)6));
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(DressGirlAI __instance)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray((EnemyAI)(object)__instance);
		}
	}
}
namespace DramaMask.Patches.Enemies.CrawlerAIPatch
{
	[HarmonyPatch(typeof(CrawlerAI), "CheckForVeryClosePlayer")]
	public class CheckForVeryClosePlayerPatch
	{
		private static readonly List<CodeInstruction> _getVisiblePlayerCollider = new List<CodeInstruction>(2)
		{
			new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(CrawlerAI), "nearPlayerColliders")),
			new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CheckForVeryClosePlayerPatch), "GetVisiblePlayerCollider", (Type[])null, (Type[])null))
		};

		private static PlayerControllerB GetVisiblePlayerCollider(Collider[] nearPlayerColliders)
		{
			foreach (Collider val in nearPlayerColliders)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null))
				{
					PlayerControllerB component = ((Component)((Component)val).transform).GetComponent<PlayerControllerB>();
					if (!((Object)(object)component == (Object)null) && !component.IsHidden())
					{
						return component;
					}
				}
			}
			return null;
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromCollider(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ret, (object)null, (string)null)
			});
			val.Advance(2);
			val.RemoveInstructions(5);
			val.InsertAndAdvance((IEnumerable<CodeInstruction>)_getVisiblePlayerCollider);
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.ClaySurgeonAIPatch
{
	[HarmonyPatch(typeof(ClaySurgeonAI), "DoAIInterval")]
	public class DoAIIntervalPatch
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HandleNonTargetablePlayer(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
			});
			object operand = val.Instruction.operand;
			val.Advance(1);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[6]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(EnemyAI), "PlayerIsTargetable", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Brfalse, operand)
			});
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Patches.Enemies.CentipedeAIPatch
{
	[HarmonyPatch(typeof(CentipedeAI), "TriggerCentipedeFallServerRpc")]
	public class TriggerCentipedeFallPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(CentipedeAI __instance, ref bool ___triggeredFall, ulong clientId)
		{
			if (!GameNetworkManager.Instance.localPlayerController.IsHidden())
			{
				return true;
			}
			___triggeredFall = false;
			return false;
		}
	}
}
namespace DramaMask.Patches.Enemies.ButlerEnemyAIPatch
{
	[HarmonyPatch(typeof(ButlerEnemyAI), "CheckLOS")]
	public class CheckLOSPatch : ModifyPlayerArrayPatchBase
	{
		[HarmonyPrefix]
		public static void Prefix(ButlerEnemyAI __instance)
		{
			ModifyPlayerArrayPatchBase.SaveAndModifyPlayerArray((EnemyAI)(object)__instance);
		}

		[HarmonyAfter(new string[] { "notnotnotswipez-MoreCompany-1.8.1", "bizzlemip-BiggerLobby-2.6.0", "PotatoePet-AdvancedCompany-1.0.150" })]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StopOutOfBounds(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.End();
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Blt, (object)null, (string)null)
			});
			ModifyPlayerArrayPatchBase.AddOobCheckToLoopPredicate(val, generator, new CodeInstruction(OpCodes.Ldloc_S, (object)4));
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Clt, (object)null, (string)null)
			});
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null)
			});
			val.Advance(-1);
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null)
			});
			val.Advance(-1);
			while (true)
			{
				val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null)
				});
				if (val.Pos == -1)
				{
					break;
				}
				val.Advance(1);
				if (val.Instruction.opcode == OpCodes.Stloc_3 || val.Instruction.opcode == OpCodes.Stloc_S)
				{
					val.Advance(-2);
					continue;
				}
				val.Advance(-2);
				if (!CodeInstructionExtensions.Is(val.Instruction, OpCodes.Ldfld, (MemberInfo)AccessTools.Field(typeof(StartOfRound), "allPlayerScripts")))
				{
					val.Advance(2);
					val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ModifyPlayerArrayPatchBase), "GetTrueIndex", (Type[])null, (Type[])null))
					});
					val.Advance(-3);
				}
			}
			return val.InstructionEnumeration();
		}

		[HarmonyPostfix]
		public static void Postfix(ButlerEnemyAI __instance)
		{
			ModifyPlayerArrayPatchBase.LoadOriginalPlayerArray((EnemyAI)(object)__instance);
		}
	}
}
namespace DramaMask.Patches.Enemies.BaboonBirdAIPatch
{
	[HarmonyPatch(typeof(BaboonBirdAI), "DoLOSCheck")]
	public class DoLOSCheckPatch
	{
		private static bool IsThreatHiddenPlayer(IVisibleThreat threat)
		{
			int result;
			if (EnemyTargetHandler.ShouldHideFromEnemy("BaboonBirdAI"))
			{
				PlayerControllerB val = (PlayerControllerB)(object)((threat is PlayerControllerB) ? threat : null);
				if (val != null)
				{
					result = (val.IsHidden() ? 1 : 0);
					goto IL_0020;
				}
			}
			result = 0;
			goto IL_0020;
			IL_0020:
			return (byte)result != 0;
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> HidePlayerFromCollider(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null)
			});
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null)
			});
			val.Advance(-1);
			object operand = val.Instruction.operand;
			val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null)
			});
			val.Advance(3);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldloc_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DoLOSCheckPatch), "IsThreatHiddenPlayer", (Type[])null, (Type[])null)),
				new CodeInstruction(OpCodes.Brtrue, operand)
			});
			return val.InstructionEnumeration();
		}
	}
}
namespace DramaMask.Network
{
	public class NetworkHandler : NetworkBehaviour
	{
		public NetworkList<ulong> VisiblePlayers;

		public static NetworkHandler Instance { get; private set; }

		public Dictionary<ulong, StealthData> StealthMap { get; private set; }

		public StealthData MyStealth { get; private set; }

		public Dictionary<ulong, PretendData> PretendMap { get; private set; }

		public PretendData MyPretend { get; private set; }

		public StealthData GetStealth(bool isLocal, ulong id)
		{
			return StealthMap.GetNetworkData(MyStealth, isLocal, id);
		}

		public PretendData GetPretend(bool isLocal, ulong id)
		{
			return PretendMap.GetNetworkData(MyPretend, isLocal, id);
		}

		public static bool IsHostOrServer()
		{
			return NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer;
		}

		private void Awake()
		{
			VisiblePlayers = new NetworkList<ulong>();
			((NetworkVariableBase)VisiblePlayers).Initialize((NetworkBehaviour)(object)this);
		}

		public override void OnNetworkSpawn()
		{
			NetworkHandler instance = Instance;
			Instance = this;
			MyStealth = new StealthData();
			MyPretend = new PretendData();
			if (IsHostOrServer())
			{
				StealthMap = new Dictionary<ulong, StealthData>();
				PretendMap = new Dictionary<ulong, PretendData>();
				VisiblePlayers.Clear();
				RegisterPlayer(0uL);
				((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback += NetworkManager_OnClientConnectedCallback;
				((NetworkBehaviour)this).NetworkManager.OnClientDisconnectCallback += NetworkManager_OnClientDisconnectedCallback;
			}
			VisiblePlayers.OnListChanged += OnVisiblePlayersChanged;
			((NetworkBehaviour)this).OnNetworkSpawn();
		}

		public override void OnNetworkDespawn()
		{
			if (IsHostOrServer())
			{
				((NetworkBehaviour)this).NetworkManager.OnClientConnectedCallback -= NetworkManager_OnClientConnectedCallback;
				((NetworkBehaviour)this).NetworkManager.OnClientDisconnectCallback -= NetworkManager_OnClientDisconnectedCallback;
			}
			VisiblePlayers.OnListChanged -= OnVisiblePlayersChanged;
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		private void NetworkManager_OnClientConnectedCallback(ulong obj)
		{
			if (obj != 0)
			{
				RegisterPlayer(obj);
			}
		}

		private void RegisterPlayer(ulong id)
		{
			if (!StealthMap.ContainsKey(id))
			{
				StealthMap.Add(id, new StealthData(id));
			}
			if (!PretendMap.ContainsKey(id))
			{
				PretendMap.Add(id, new PretendData(id));
			}
			if (!VisiblePlayers.Contains(id))
			{
				VisiblePlayers.Add(id);
			}
		}

		private void NetworkManager_OnClientDisconnectedCallback(ulong obj)
		{
			if (obj != 0)
			{
				UnregisterPlayer(obj);
			}
		}

		private void UnregisterPlayer(ulong id)
		{
			if (StealthMap.ContainsKey(id))
			{
				StealthMap.Remove(id);
			}
			if (!PretendMap.ContainsKey(id))
			{
				PretendMap.Remove(id);
			}
			if (VisiblePlayers == null)
			{
				Plugin.Logger.LogWarning((object)"Visible player list could not unregister player: This is fine on host disconnection");
			}
			else if (VisiblePlayers.Contains(id))
			{
				VisiblePlayers.Remove(id);
			}
		}

		private void OnVisiblePlayersChanged(NetworkListEvent<ulong> changeEvent)
		{
			Plugin.Logger.LogInfo((object)("Visible players: [" + VisiblePlayers.AsString<ulong>() + "]"));
			if (!IsHostOrServer())
			{
			}
		}

		public void SetPlayerHiddenServer(ulong playerId, bool isHidden)
		{
			if (isHidden && VisiblePlayers.Contains(playerId))
			{
				VisiblePlayers.Remove(playerId);
			}
			else if (!isHidden && !VisiblePlayers.Contains(playerId))
			{
				VisiblePlayers.Add(playerId);
			}
		}

		public void SetPlayerMaskAttachedServer(ulong playerId, bool isAttaching)
		{
			SetPlayerMaskAttachedClientRpc(playerId, isAttaching);
		}

		[ClientRpc]
		public void SetPlayerMaskAttachedClientRpc(ulong playerId, bool isAttaching)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4253758658u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerId);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isAttaching, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4253758658u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				PlayerControllerB player = StartOfRound.Instance.GetPlayer(playerId);
				Plugin.Logger.LogDebug((object)$"AttachMaskClientRPC {playerId} -> {player}: {isAttaching}");
				if (!IsMaskActionValid(player, out var mask, out var reasonInvalid))
				{
					Plugin.Logger.LogDebug((object)("AttachMaskClientRPC invalid call: " + reasonInvalid));
				}
				else
				{
					mask.SetMaskAttached(isAttaching);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetPlayerMaskEyesValueServerRpc(ulong playerId, bool isActivating)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3585587505u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isActivating, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3585587505u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					PretendMap[playerId].IsMaskEyesOn = isActivating;
				}
			}
		}

		public void SetPlayerMaskEyesServer(ulong playerId, bool isActivating)
		{
			SetPlayerMaskEyesClientRpc(playerId, isActivating);
		}

		[ClientRpc]
		public void SetPlayerMaskEyesClientRpc(ulong playerId, bool isActivating)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3711124253u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerId);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isActivating, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3711124253u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				PlayerControllerB player = StartOfRound.Instance.GetPlayer(playerId);
				Plugin.Logger.LogDebug((object)$"MaskEyesClientRPC {playerId} -> {player}: {isActivating}");
				if (!IsMaskActionValid(player, out var mask, out var reasonInvalid))
				{
					Plugin.Logger.LogDebug((object)("MaskEyesClientRPC invalid call: " + reasonInvalid));
				}
				else
				{
					mask.SetMaskEyes(isActivating);
				}
			}
		}

		private bool IsMaskActionValid(PlayerControllerB player, out HauntedMaskItem mask, out string reasonInvalid)
		{
			reasonInvalid = null;
			mask = null;
			if ((Object)(object)player == (Object)null)
			{
				reasonInvalid = "Player is null";
				return false;
			}
			GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
			if ((Object)(object)currentlyHeldObjectServer == (Object)null)
			{
				reasonInvalid = "CurrentlyHeldObjectServer is null";
				return false;
			}
			HauntedMaskItem val = (HauntedMaskItem)(object)((currentlyHeldObjectServer is HauntedMaskItem) ? currentlyHeldObjectServer : null);
			if (val == null)
			{
				reasonInvalid = "CurrentlyHeldObjectServer is not a HauntedMaskItem";
				return false;
			}
			mask = val;
			return true;
		}

		protected override void __initializeVariables()
		{
			if (VisiblePlayers == null)
			{
				throw new Exception("NetworkHandler.VisiblePlayers cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)VisiblePlayers).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)VisiblePlayers, "VisiblePlayers");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)VisiblePlayers);
			((NetworkBehaviour)this).__initializeVariables();
		}