using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using Enemies;
using ExteriorRendering;
using GTFO.API;
using GTFO.API.Extensions;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using Player;
using PlayerCoverage;
using SNetwork;
using SnatcherBugFix.Utils;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SnatcherBugFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d894ee67490884eb05a33b1b0c72a99a25b24984")]
[assembly: AssemblyProduct("SnatcherBugFix")]
[assembly: AssemblyTitle("SnatcherBugFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace SnatcherBugFix
{
[BepInPlugin("Amor.SnatcherBugFix", "SnatcherBugFix", "0.5.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal sealed class EntryPoint : BasePlugin
{
public override void Load()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
ClassInjector.RegisterTypeInIl2Cpp<SnatcherHandler>();
SnatcherNativePatches.Init();
new Harmony("Amor.SnatcherBugFix").PatchAll();
Logger.Info("SnatcherBugFix is done loading!");
}
}
internal static class Logger
{
private static readonly ManualLogSource MLS;
static Logger()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
MLS = new ManualLogSource("SnatcherBugFix");
Logger.Sources.Add((ILogSource)(object)MLS);
}
public static void Info(BepInExInfoLogInterpolatedStringHandler handler)
{
MLS.LogInfo(handler);
}
public static void Info(string str)
{
MLS.LogMessage((object)str);
}
public static void Debug(BepInExDebugLogInterpolatedStringHandler handler)
{
MLS.LogDebug(handler);
}
public static void Debug(string str)
{
MLS.LogDebug((object)str);
}
public static void Error(BepInExErrorLogInterpolatedStringHandler handler)
{
MLS.LogError(handler);
}
public static void Error(string str)
{
MLS.LogError((object)str);
}
public static void Warn(BepInExWarningLogInterpolatedStringHandler handler)
{
MLS.LogWarning(handler);
}
public static void Warn(string str)
{
MLS.LogWarning((object)str);
}
}
public class SnatcherHandler : MonoBehaviour
{
public PlayerAgent Player;
public EnemyAgent? Captor;
public AIG_CourseNode? LastNode;
public eDimensionIndex LastDimension;
public Vector3 LastPosition;
private float _warpTime;
private const float DeadBuffer = 0.5f;
public AIG_CourseNode? GoodNode
{
get
{
EnemyAgent? captor = Captor;
return ((captor != null) ? ((Agent)captor).CourseNode : null) ?? LastNode;
}
}
public eDimensionIndex GoodDimension
{
get
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
EnemyAgent? captor = Captor;
if (captor == null)
{
return LastDimension;
}
return ((Agent)captor).DimensionIndex;
}
}
public Vector3 GoodPosition
{
get
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
EnemyAgent? captor = Captor;
if (captor == null)
{
return LastPosition;
}
return captor.Position;
}
}
public bool IsInArenaDim
{
get
{
PlayerAgent player = Player;
bool? obj;
if (player == null)
{
obj = null;
}
else
{
Dimension dimension = ((Agent)player).Dimension;
obj = ((dimension != null) ? new bool?(dimension.IsArenaDimension) : null);
}
bool? flag = obj;
return flag.GetValueOrDefault();
}
}
public void Awake()
{
Player = ((Component)this).GetComponent<PlayerAgent>();
if (!ListExtensions.ToManaged<Dimension>(Builder.CurrentFloor.m_dimensions).Any((Dimension dim) => dim.IsArenaDimension))
{
Logger.Error("No arena dimension present in level");
((Behaviour)this).enabled = false;
}
else
{
Logger.Debug("SnatcherHandler is setup and enabled");
}
}
public void Update()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if ((int)GameStateManager.CurrentStateName != 10 || (Object)(object)Player == (Object)null)
{
return;
}
bool isInArenaDim = IsInArenaDim;
if (_warpTime > 0f && Clock.Time > _warpTime)
{
if (isInArenaDim)
{
Player.RequestWarpToSync(GoodDimension, GoodPosition, Player.FPSCamera.CameraRayDir, (WarpOptions)0);
if (((Agent)Player).Alive)
{
Player.Locomotion.GrabbedByPouncer.StandUp();
}
FixWarpFX();
Player.FPSCamera.PouncerScreenFX.SetCovered(false);
}
else if (Player.FPSCamera.PouncerScreenFX.covered)
{
Player.FPSCamera.PouncerScreenFX.SetCovered(false);
}
Captor = null;
_warpTime = 0f;
}
else if (!isInArenaDim)
{
LastNode = ((Agent)Player).CourseNode;
LastDimension = ((Agent)Player).DimensionIndex;
LastPosition = ((Agent)Player).Position;
}
}
public void OnConsumed(EnemyAgent pouncer, PouncerDataContainer data)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references)
bool flag = default(bool);
BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(34, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SnatcherHandler OnConsumed, Enemy ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Object)pouncer).GetInstanceID());
}
Logger.Debug(val);
Captor = pouncer;
HeldStateData heldStateData = data.HeldStateData;
_warpTime = Clock.Time + data.ConsumeDuration + heldStateData.HeldStartAnimationDuration + heldStateData.MaxHeldDuration + heldStateData.SpitOutStateDuration;
}
public void OnDead(EnemyAgent pouncer)
{
if (!((Object)(object)Captor == (Object)null) && ((Object)Captor).GetInstanceID() == ((Object)pouncer).GetInstanceID())
{
Logger.Debug("SnatcherHandler OnDead");
Captor = null;
_warpTime = Clock.Time + 0.5f;
}
}
private void FixWarpFX()
{
Dimension dimension = GoodNode.m_dimension;
ExteriorCamera.GlobalSwitch = dimension.DimensionData.IsOutside;
if (Object.op_Implicit((Object)(object)dimension.DimensionRootTemp.SkyOcclusionVolume))
{
dimension.DimensionRootTemp.SkyOcclusionVolume.Upload();
}
if (dimension.DimensionData.IsOutside)
{
Lighting.ReflectionsDirty = true;
}
if (dimension.IsMainDimension)
{
Dimension.SetRealitySoundEnvironment();
}
Player.UpdateSoundScape();
}
}
internal static class SnatcherNativePatches
{
private unsafe delegate bool d_TryGetClosestAlivePlayerAgent(IntPtr node, out IntPtr playerAgent, Il2CppMethodInfo* methodInfo);
private static INativeDetour _detour;
private static d_TryGetClosestAlivePlayerAgent orig_TryGetClosestAlivePlayerAgent;
internal static void Init()
{
ApplyNativePatch();
}
private unsafe static void ApplyNativePatch()
{
_detour = INativeDetour.CreateAndApply<d_TryGetClosestAlivePlayerAgent>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<PlayerManager>("TryGetClosestAlivePlayerAgent", typeof(bool).FullName, false, new string[2]
{
typeof(AIG_CourseNode).FullName,
typeof(PlayerAgent).MakeByRefType().FullName
}), (d_TryGetClosestAlivePlayerAgent)TryGetClosestAlivePlayerAgentPatch, ref orig_TryGetClosestAlivePlayerAgent);
}
private unsafe static bool TryGetClosestAlivePlayerAgentPatch(IntPtr node, out IntPtr playerAgent, Il2CppMethodInfo* methodInfo)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
AIG_CourseNode val = new AIG_CourseNode(node);
PlayerAgent val2 = null;
PlayerAgent val3 = null;
int num = int.MaxValue;
for (int i = 0; i < PlayerManager.PlayerAgentsInLevel.Count; i++)
{
PlayerAgent val4 = PlayerManager.PlayerAgentsInLevel[i];
if (!((Object)(object)val4 != (Object)null) || !((Agent)val4).Alive)
{
continue;
}
Dimension dimension = ((Agent)val4).Dimension;
if (dimension != null && dimension.IsArenaDimension)
{
continue;
}
val3 = val4;
if (i < ((Il2CppArrayBase<PlayerCoverageData>)(object)val.m_playerCoverage.m_coverageDatas).Length)
{
PlayerCoverageData val5 = ((Il2CppArrayBase<PlayerCoverageData>)(object)val.m_playerCoverage.m_coverageDatas)[i];
if (val5.IsValidNodeDistance && num > val5.m_nodeDistance)
{
num = val5.m_nodeDistance;
val2 = val4;
}
}
}
if ((Object)(object)val2 == (Object)null)
{
val2 = val3;
}
playerAgent = ((val2 != null) ? ((Il2CppObjectBase)val2).Pointer : IntPtr.Zero);
return playerAgent != IntPtr.Zero;
}
}
[HarmonyPatch]
internal static class SnatcherPatches
{
private static SnatcherHandler? _handler;
private static bool _prepared;
[HarmonyPrepare]
private static void Prepare()
{
if (!_prepared)
{
LevelAPI.OnEnterLevel += OnEnterLevel;
_prepared = true;
}
}
private static void OnEnterLevel()
{
_handler = ((Component)PlayerManager.GetLocalPlayerAgent()).gameObject.AddOrGetComponent<SnatcherHandler>();
if (!((Behaviour)_handler).enabled)
{
_handler = null;
}
}
[HarmonyPatch(typeof(SurvivalWave), "OnSpawn")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Post_Wave_OnSpawn(SurvivalWave __instance)
{
AIG_CourseNode courseNode = __instance.m_courseNode;
if (courseNode != null && courseNode.m_dimension.IsArenaDimension)
{
__instance.m_courseNode = _handler?.GoodNode ?? __instance.m_courseNode;
}
}
[HarmonyPatch(typeof(EnemySync), "OnSpawn")]
[HarmonyPostfix]
[HarmonyPriority(600)]
[HarmonyWrapSafe]
private static void Post_Enemy_OnSpawn(EnemySync __instance)
{
EnemyAgent enemy = __instance.m_agent;
if (enemy.IsSetup && enemy.IsArenaDimensionEnemy)
{
enemy.AddOnDeadOnce(delegate
{
_handler?.OnDead(enemy);
});
}
}
[HarmonyPatch(typeof(PouncerBehaviour), "OnConsumeRequestReceived")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Post_Consume(PouncerBehaviour __instance, pEB_PouncerTargetInfoPacket data)
{
PlayerAgent val = default(PlayerAgent);
if (PlayerManager.TryGetPlayerAgent(ref data.PlayerSlot, ref val) && ((Agent)val).IsLocallyOwned)
{
_handler?.OnConsumed(((EnemyBehaviour)__instance).m_ai.m_enemyAgent, __instance.Data);
}
}
[HarmonyPatch(typeof(PouncerBehaviour), "RequestConsume")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Post_Consume(PouncerBehaviour __instance, int playerSlotIndex)
{
PlayerAgent val = default(PlayerAgent);
if (SNet.IsMaster && PlayerManager.TryGetPlayerAgent(ref playerSlotIndex, ref val) && ((Agent)val).IsLocallyOwned)
{
_handler?.OnConsumed(((EnemyBehaviour)__instance).m_ai.m_enemyAgent, __instance.Data);
}
}
[HarmonyPatch(typeof(PouncerScreenFX), "SetCovered", new Type[] { typeof(bool) })]
[HarmonyPrefix]
[HarmonyWrapSafe]
private static void Pre_CoverScreen()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)GameStateManager.CurrentStateName == 10)
{
FocusStateManager.ChangeState((eFocusState)4, true);
}
}
}
}
namespace SnatcherBugFix.Utils
{
internal static class EnemyAgentExtensions
{
public static void AddOnDeadOnce(this EnemyAgent agent, Action onDead)
{
Action onDead2 = onDead;
bool called = false;
agent.OnDeadCallback += Action.op_Implicit((Action)delegate
{
if (!called)
{
onDead2?.Invoke();
called = true;
}
});
}
}
internal static class GameObjectExtensions
{
public static bool TryAndGetComponent<T>(this GameObject go, out T component)
{
component = go.GetComponent<T>();
return component != null;
}
public static T AddOrGetComponent<T>(this GameObject go) where T : Component
{
if (!go.TryAndGetComponent<T>(out var component))
{
return go.AddComponent<T>();
}
return component;
}
}
}