Decompiled source of DramaMask v2.1.3
DramaMask.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
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(); }