using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("REPOJP")]
[assembly: AssemblyTitle("REPOJP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.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;
}
}
[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 ExtractionAutoRevive
{
[BepInPlugin("com.repojp.extractionautorevive", "ExtractionAutoRevive", "1.2.0")]
public sealed class ExtractionAutoRevivePlugin : BaseUnityPlugin
{
private sealed class PendingReviveEntry
{
public PlayerDeathHead DeathHead;
public PlayerAvatar PlayerAvatar;
public int Key;
public float QueuedAt;
public float ElectrifiedEndedAt = -1f;
public float VelocityStableStartedAt = -1f;
public string PlayerLabel;
}
[CompilerGenerated]
private sealed class <MonitorPendingRevives>d__37 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ExtractionAutoRevivePlugin <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MonitorPendingRevives>d__37(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
while (<>4__this.pendingRevives.Count > 0)
{
if (!<>4__this.IsModEnabled())
{
<>4__this.ClearPendingRevives("mod disabled");
break;
}
if (!<>4__this.CanRunHostLogic())
{
<>4__this.ClearPendingRevives("host lost");
break;
}
if (<>4__this.ShouldClearPendingByRoundState())
{
<>4__this.ClearPendingRevives("round transition");
break;
}
<>4__this.ProcessPendingRevives();
if (<>4__this.pendingRevives.Count > 0)
{
<>2__current = (object)new WaitForSecondsRealtime(Mathf.Clamp(<>4__this.configPendingCheckIntervalSeconds.Value, 0.02f, 1f));
<>1__state = 1;
return true;
}
}
<>4__this.pendingMonitorCoroutine = null;
<>4__this.WriteVerbose("Pending monitor stopped");
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
internal static ExtractionAutoRevivePlugin Instance;
internal static ManualLogSource Log;
private Harmony harmony;
private static int customReviveContextDepth;
private Coroutine pendingMonitorCoroutine;
private readonly Dictionary<int, PendingReviveEntry> pendingRevives = new Dictionary<int, PendingReviveEntry>();
private ConfigEntry<bool> configEnableMod;
private ConfigEntry<bool> configEnableLog;
private ConfigEntry<bool> configEnableVerboseLog;
private ConfigEntry<float> configPitHeadExtraDelaySeconds;
private ConfigEntry<float> configPitHeadMaxVelocityToRevive;
private ConfigEntry<float> configPendingCheckIntervalSeconds;
private static readonly FieldInfo FieldPlayerAvatarDeadSet = AccessTools.Field(typeof(PlayerAvatar), "deadSet");
private static readonly FieldInfo FieldPlayerAvatarIsDisabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");
private static readonly FieldInfo FieldPlayerAvatarFinalHeal = AccessTools.Field(typeof(PlayerAvatar), "finalHeal");
private static readonly FieldInfo FieldPlayerDeathHeadTriggered = AccessTools.Field(typeof(PlayerDeathHead), "triggered");
private static readonly FieldInfo FieldPlayerDeathHeadInExtractionPoint = AccessTools.Field(typeof(PlayerDeathHead), "inExtractionPoint");
private static readonly FieldInfo FieldPlayerDeathHeadInTruck = AccessTools.Field(typeof(PlayerDeathHead), "inTruck");
private static readonly FieldInfo FieldPlayerDeathHeadPhysGrabObject = AccessTools.Field(typeof(PlayerDeathHead), "physGrabObject");
private static readonly FieldInfo FieldPhysGrabObjectDeathPitEffect = AccessTools.Field(typeof(PhysGrabObject), "deathPitEffect");
private static readonly FieldInfo FieldPhysGrabObjectDeathPitEffectDisableTimer = AccessTools.Field(typeof(PhysGrabObject), "deathPitEffectDisableTimer");
private static readonly FieldInfo FieldDeathPitSaveEffectTimeCurrent = AccessTools.Field(typeof(DeathPitSaveEffect), "timeCurrent");
private void Awake()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected O, but got Unknown
try
{
((Component)this).transform.parent = null;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[ExtractionAutoRevive] Persist setup failed ex={arg}");
}
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
SetupConfig();
SceneManager.activeSceneChanged += OnActiveSceneChanged;
harmony = new Harmony("com.repojp.extractionautorevive");
harmony.PatchAll();
WriteLog("Loaded");
}
private void OnDestroy()
{
ClearPendingRevives("plugin destroy");
SceneManager.activeSceneChanged -= OnActiveSceneChanged;
try
{
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch (Exception arg)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"[ExtractionAutoRevive] Unpatch failed ex={arg}");
}
if (Instance == this)
{
Instance = null;
}
}
private void SetupConfig()
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Expected O, but got Unknown
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
configEnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "MOD overall enable switch");
configEnableLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Log", "EnableLog", true, "Enable standard logs");
configEnableVerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Log", "EnableVerboseLog", false, "Enable verbose logs");
configPitHeadExtraDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("PitHead", "PitHeadExtraDelaySeconds", 0.35f, new ConfigDescription("Additional delay after death pit electricity ends", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
configPitHeadMaxVelocityToRevive = ((BaseUnityPlugin)this).Config.Bind<float>("PitHead", "PitHeadMaxVelocityToRevive", 1f, new ConfigDescription("Maximum rigidbody velocity magnitude allowed before revive", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
configPendingCheckIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("PitHead", "PendingCheckIntervalSeconds", 0.05f, new ConfigDescription("Pending pit head monitor interval", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 1f), Array.Empty<object>()));
}
private void OnActiveSceneChanged(Scene previousScene, Scene nextScene)
{
ClearPendingRevives("scene changed " + ((Scene)(ref previousScene)).name + " -> " + ((Scene)(ref nextScene)).name);
}
private void WriteLog(string message)
{
if (configEnableLog != null && configEnableLog.Value)
{
Log.LogInfo((object)("[ExtractionAutoRevive] " + message));
}
}
private void WriteVerbose(string message)
{
if (configEnableVerboseLog != null && configEnableVerboseLog.Value)
{
Log.LogInfo((object)("[ExtractionAutoRevive] " + message));
}
}
private void WriteWarning(string message)
{
Log.LogWarning((object)("[ExtractionAutoRevive] " + message));
}
internal static void EnterCustomReviveContext()
{
customReviveContextDepth++;
}
internal static void ExitCustomReviveContext()
{
if (customReviveContextDepth > 0)
{
customReviveContextDepth--;
}
}
internal static bool IsCustomReviveContextActive()
{
return customReviveContextDepth > 0;
}
internal bool IsModEnabled()
{
return configEnableMod != null && configEnableMod.Value;
}
internal void HandleDeathHeadRevive(PlayerDeathHead deathHead)
{
if (IsModEnabled() && !((Object)(object)deathHead == (Object)null))
{
PlayerAvatar playerAvatar = deathHead.playerAvatar;
DeathPitSaveEffect effect;
if ((Object)(object)playerAvatar == (Object)null)
{
WriteWarning("Skip custom revive reason=playerAvatar null");
}
else if (!IsPlayerDead(playerAvatar, deathHead))
{
WriteVerbose("Skip custom revive player=" + GetPlayerLabel(playerAvatar) + " reason=alreadyAlive");
}
else if (!GetBoolField(FieldPlayerDeathHeadTriggered, deathHead, defaultValue: false))
{
WriteVerbose("Skip custom revive player=" + GetPlayerLabel(playerAvatar) + " reason=headNotTriggered");
}
else if (IsPitHeadElectrified(deathHead, out effect))
{
EnqueuePendingRevive(deathHead, playerAvatar);
}
else
{
ReviveNow(playerAvatar, "immediate");
}
}
}
private void EnqueuePendingRevive(PlayerDeathHead deathHead, PlayerAvatar playerAvatar)
{
if (!((Object)(object)deathHead == (Object)null) && !((Object)(object)playerAvatar == (Object)null))
{
int num = GetPendingKey(playerAvatar, deathHead);
if (num == 0)
{
num = ((Object)playerAvatar).GetInstanceID();
}
if (pendingRevives.TryGetValue(num, out PendingReviveEntry value))
{
value.DeathHead = deathHead;
value.PlayerAvatar = playerAvatar;
value.PlayerLabel = GetPlayerLabel(playerAvatar);
WriteVerbose($"Refresh pending revive player={value.PlayerLabel} key={num}");
StartPendingMonitorIfNeeded();
}
else
{
PendingReviveEntry pendingReviveEntry = new PendingReviveEntry
{
DeathHead = deathHead,
PlayerAvatar = playerAvatar,
Key = num,
QueuedAt = Time.unscaledTime,
PlayerLabel = GetPlayerLabel(playerAvatar)
};
pendingRevives[num] = pendingReviveEntry;
WriteLog($"Queue delayed revive player={pendingReviveEntry.PlayerLabel} key={num}");
StartPendingMonitorIfNeeded();
}
}
}
private void StartPendingMonitorIfNeeded()
{
if (pendingRevives.Count > 0 && pendingMonitorCoroutine == null)
{
pendingMonitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPendingRevives());
WriteVerbose("Pending monitor started");
}
}
[IteratorStateMachine(typeof(<MonitorPendingRevives>d__37))]
private IEnumerator MonitorPendingRevives()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MonitorPendingRevives>d__37(0)
{
<>4__this = this
};
}
private void ProcessPendingRevives()
{
if (pendingRevives.Count <= 0)
{
return;
}
List<int> list = new List<int>(pendingRevives.Keys);
foreach (int item in list)
{
if (!pendingRevives.TryGetValue(item, out PendingReviveEntry value))
{
continue;
}
if (value == null || (Object)(object)value.PlayerAvatar == (Object)null || (Object)(object)value.DeathHead == (Object)null)
{
RemovePendingRevive(item, "invalid reference");
continue;
}
if (!IsPlayerDead(value.PlayerAvatar, value.DeathHead))
{
RemovePendingRevive(item, "already alive");
continue;
}
if (!GetBoolField(FieldPlayerDeathHeadTriggered, value.DeathHead, defaultValue: false))
{
RemovePendingRevive(item, "head no longer triggered");
continue;
}
if (ShouldLeaveToVanillaTruckRevive(value.DeathHead, value.PlayerAvatar))
{
RemovePendingRevive(item, "vanilla truck revive");
continue;
}
if (IsPitHeadElectrified(value.DeathHead, out DeathPitSaveEffect _))
{
value.ElectrifiedEndedAt = -1f;
value.VelocityStableStartedAt = -1f;
WriteVerbose("Pending wait player=" + value.PlayerLabel + " reason=electrified");
continue;
}
if (value.ElectrifiedEndedAt < 0f)
{
value.ElectrifiedEndedAt = Time.unscaledTime;
value.VelocityStableStartedAt = -1f;
WriteVerbose("Pending electricity ended player=" + value.PlayerLabel);
}
float num = Time.unscaledTime - value.ElectrifiedEndedAt;
if (num < configPitHeadExtraDelaySeconds.Value)
{
WriteVerbose($"Pending extra delay player={value.PlayerLabel} elapsed={num:F2}");
continue;
}
float headVelocityMagnitude = GetHeadVelocityMagnitude(value.DeathHead);
if (headVelocityMagnitude > configPitHeadMaxVelocityToRevive.Value)
{
value.VelocityStableStartedAt = -1f;
WriteVerbose($"Pending velocity wait player={value.PlayerLabel} velocity={headVelocityMagnitude:F2}");
continue;
}
if (value.VelocityStableStartedAt < 0f)
{
value.VelocityStableStartedAt = Time.unscaledTime;
WriteVerbose("Pending velocity stable start player=" + value.PlayerLabel);
}
ReviveNow(value.PlayerAvatar, "delayed");
RemovePendingRevive(item, "revived");
}
}
private void RemovePendingRevive(int key, string reason)
{
if (pendingRevives.TryGetValue(key, out PendingReviveEntry value))
{
WriteVerbose($"Pending remove player={value.PlayerLabel} key={key} reason={reason}");
pendingRevives.Remove(key);
}
}
internal void ClearPendingRevives(string reason)
{
if (pendingRevives.Count > 0)
{
WriteLog($"Clear pending revives count={pendingRevives.Count} reason={reason}");
pendingRevives.Clear();
}
}
private bool CanRunHostLogic()
{
try
{
return SemiFunc.IsMasterClientOrSingleplayer();
}
catch
{
return false;
}
}
private bool ShouldClearPendingByRoundState()
{
try
{
if ((Object)(object)RunManager.instance == (Object)null)
{
return false;
}
if (SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu() || (!SemiFunc.RunIsShop() && !SemiFunc.RunIsLevel()))
{
return true;
}
if ((Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.allExtractionPointsCompleted)
{
return true;
}
}
catch
{
return true;
}
return false;
}
private bool ShouldLeaveToVanillaTruckRevive(PlayerDeathHead deathHead, PlayerAvatar playerAvatar)
{
if ((Object)(object)deathHead == (Object)null || (Object)(object)playerAvatar == (Object)null)
{
return false;
}
if ((Object)(object)RoundDirector.instance == (Object)null)
{
return false;
}
if (!RoundDirector.instance.allExtractionPointsCompleted)
{
return false;
}
if (GetBoolField(FieldPlayerAvatarFinalHeal, playerAvatar, defaultValue: false))
{
return false;
}
if (!GetBoolField(FieldPlayerDeathHeadInTruck, deathHead, defaultValue: false))
{
return false;
}
return true;
}
private bool IsPlayerDead(PlayerAvatar playerAvatar, PlayerDeathHead deathHead)
{
if ((Object)(object)playerAvatar == (Object)null)
{
return false;
}
bool boolField = GetBoolField(FieldPlayerAvatarDeadSet, playerAvatar, defaultValue: false);
bool boolField2 = GetBoolField(FieldPlayerAvatarIsDisabled, playerAvatar, defaultValue: false);
bool activeSelf = ((Component)playerAvatar).gameObject.activeSelf;
bool flag = (Object)(object)deathHead != (Object)null && GetBoolField(FieldPlayerDeathHeadTriggered, deathHead, defaultValue: false);
if (boolField)
{
return true;
}
if (boolField2)
{
return true;
}
if (!activeSelf)
{
return true;
}
if (flag)
{
return true;
}
return false;
}
private void ReviveNow(PlayerAvatar playerAvatar, string reason)
{
if ((Object)(object)playerAvatar == (Object)null)
{
return;
}
if (!IsPlayerDead(playerAvatar, playerAvatar.playerDeathHead))
{
WriteVerbose("Skip revive player=" + GetPlayerLabel(playerAvatar) + " reason=alreadyAlive finalReason=" + reason);
return;
}
try
{
playerAvatar.Revive(true);
WriteLog("Revive(true) player=" + GetPlayerLabel(playerAvatar) + " reason=" + reason);
}
catch (Exception arg)
{
WriteWarning($"Revive(true) failed player={GetPlayerLabel(playerAvatar)} reason={reason} ex={arg}");
}
}
private bool IsPitHeadElectrified(PlayerDeathHead deathHead, out DeathPitSaveEffect effect)
{
effect = null;
if ((Object)(object)deathHead == (Object)null)
{
return false;
}
PhysGrabObject playerDeathHeadPhysGrabObject = GetPlayerDeathHeadPhysGrabObject(deathHead);
if ((Object)(object)playerDeathHeadPhysGrabObject == (Object)null)
{
return false;
}
float floatField = GetFloatField(FieldPhysGrabObjectDeathPitEffectDisableTimer, playerDeathHeadPhysGrabObject, 0f);
GameObject gameObjectField = GetGameObjectField(FieldPhysGrabObjectDeathPitEffect, playerDeathHeadPhysGrabObject);
if ((Object)(object)gameObjectField == (Object)null)
{
if (floatField > 0f)
{
return false;
}
return false;
}
effect = gameObjectField.GetComponent<DeathPitSaveEffect>();
if ((Object)(object)effect == (Object)null)
{
return false;
}
if ((Object)(object)effect.physGrabObject != (Object)null && (Object)(object)effect.physGrabObject != (Object)(object)playerDeathHeadPhysGrabObject)
{
return false;
}
float floatField2 = GetFloatField(FieldDeathPitSaveEffectTimeCurrent, effect, 0f);
if (floatField2 > 0f)
{
return true;
}
return false;
}
private float GetHeadVelocityMagnitude(PlayerDeathHead deathHead)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)deathHead == (Object)null)
{
return 0f;
}
PhysGrabObject playerDeathHeadPhysGrabObject = GetPlayerDeathHeadPhysGrabObject(deathHead);
if ((Object)(object)playerDeathHeadPhysGrabObject == (Object)null)
{
return 0f;
}
if ((Object)(object)playerDeathHeadPhysGrabObject.rb == (Object)null)
{
return 0f;
}
Vector3 velocity = playerDeathHeadPhysGrabObject.rb.velocity;
return ((Vector3)(ref velocity)).magnitude;
}
private int GetPendingKey(PlayerAvatar playerAvatar, PlayerDeathHead deathHead)
{
if ((Object)(object)playerAvatar != (Object)null && (Object)(object)playerAvatar.photonView != (Object)null && playerAvatar.photonView.ViewID > 0)
{
return playerAvatar.photonView.ViewID;
}
PhotonView val = null;
if ((Object)(object)deathHead != (Object)null)
{
val = ((Component)deathHead).GetComponent<PhotonView>();
}
if ((Object)(object)val != (Object)null && val.ViewID > 0)
{
return val.ViewID;
}
if ((Object)(object)playerAvatar != (Object)null)
{
return ((Object)playerAvatar).GetInstanceID();
}
return 0;
}
private string GetPlayerLabel(PlayerAvatar playerAvatar)
{
if ((Object)(object)playerAvatar == (Object)null)
{
return "null";
}
if (!string.IsNullOrEmpty(((Object)playerAvatar).name))
{
return ((Object)playerAvatar).name;
}
return "PlayerAvatar";
}
private PhysGrabObject GetPlayerDeathHeadPhysGrabObject(PlayerDeathHead deathHead)
{
if ((Object)(object)deathHead == (Object)null)
{
return null;
}
PhysGrabObject val = null;
if (FieldPlayerDeathHeadPhysGrabObject != null)
{
try
{
object? value = FieldPlayerDeathHeadPhysGrabObject.GetValue(deathHead);
val = (PhysGrabObject)((value is PhysGrabObject) ? value : null);
}
catch
{
}
}
if ((Object)(object)val != (Object)null)
{
return val;
}
return ((Component)deathHead).GetComponent<PhysGrabObject>();
}
private static bool GetBoolField(FieldInfo fieldInfo, object instance, bool defaultValue)
{
if (fieldInfo == null || instance == null)
{
return defaultValue;
}
try
{
object value = fieldInfo.GetValue(instance);
if (value is bool)
{
return (bool)value;
}
}
catch
{
}
return defaultValue;
}
private static float GetFloatField(FieldInfo fieldInfo, object instance, float defaultValue)
{
if (fieldInfo == null || instance == null)
{
return defaultValue;
}
try
{
object value = fieldInfo.GetValue(instance);
if (value is float)
{
return (float)value;
}
}
catch
{
}
return defaultValue;
}
private static GameObject GetGameObjectField(FieldInfo fieldInfo, object instance)
{
if (fieldInfo == null || instance == null)
{
return null;
}
try
{
object? value = fieldInfo.GetValue(instance);
return (GameObject)((value is GameObject) ? value : null);
}
catch
{
return null;
}
}
}
[HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInShoppingList")]
internal static class ExtractionPoint_DestroyAllPhysObjectsInShoppingList_Patch
{
private static void Prefix()
{
if (SemiFunc.IsMasterClientOrSingleplayer())
{
ExtractionAutoRevivePlugin.EnterCustomReviveContext();
}
}
private static Exception Finalizer(Exception __exception)
{
if (SemiFunc.IsMasterClientOrSingleplayer())
{
ExtractionAutoRevivePlugin.ExitCustomReviveContext();
}
return __exception;
}
}
[HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInHaulList")]
internal static class ExtractionPoint_DestroyAllPhysObjectsInHaulList_Patch
{
private static void Prefix()
{
if (SemiFunc.IsMasterClientOrSingleplayer())
{
ExtractionAutoRevivePlugin.EnterCustomReviveContext();
}
}
private static Exception Finalizer(Exception __exception)
{
if (SemiFunc.IsMasterClientOrSingleplayer())
{
ExtractionAutoRevivePlugin.ExitCustomReviveContext();
}
return __exception;
}
}
[HarmonyPatch(typeof(PlayerDeathHead), "Revive")]
internal static class PlayerDeathHead_Revive_Patch
{
private static bool Prefix(PlayerDeathHead __instance)
{
if (!ExtractionAutoRevivePlugin.IsCustomReviveContextActive())
{
return true;
}
if ((Object)(object)ExtractionAutoRevivePlugin.Instance == (Object)null)
{
return true;
}
if (!ExtractionAutoRevivePlugin.Instance.IsModEnabled())
{
return true;
}
try
{
ExtractionAutoRevivePlugin.Instance.HandleDeathHeadRevive(__instance);
}
catch (Exception arg)
{
ManualLogSource log = ExtractionAutoRevivePlugin.Log;
if (log != null)
{
log.LogWarning((object)$"[ExtractionAutoRevive] PlayerDeathHead.Revive patch failed ex={arg}");
}
}
return false;
}
}
[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
internal static class RunManager_ChangeLevel_Patch
{
private static void Prefix()
{
if ((Object)(object)ExtractionAutoRevivePlugin.Instance != (Object)null)
{
ExtractionAutoRevivePlugin.Instance.ClearPendingRevives("run manager change level");
}
}
}
[HarmonyPatch(typeof(RunManager), "RestartScene")]
internal static class RunManager_RestartScene_Patch
{
private static void Prefix()
{
if ((Object)(object)ExtractionAutoRevivePlugin.Instance != (Object)null)
{
ExtractionAutoRevivePlugin.Instance.ClearPendingRevives("run manager restart scene");
}
}
}
[HarmonyPatch(typeof(RoundDirector), "ExtractionCompletedAllRPC")]
internal static class RoundDirector_ExtractionCompletedAllRPC_Patch
{
private static void Postfix()
{
if ((Object)(object)ExtractionAutoRevivePlugin.Instance != (Object)null)
{
ExtractionAutoRevivePlugin.Instance.ClearPendingRevives("all extractions completed");
}
}
}
[HarmonyPatch(typeof(TruckHealer), "StateUpdate")]
internal static class TruckHealer_StateUpdate_Patch
{
private static void Prefix(State _newState)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (((int)_newState == 1 || (int)_newState == 2 || (int)_newState == 3) && (Object)(object)ExtractionAutoRevivePlugin.Instance != (Object)null)
{
ExtractionAutoRevivePlugin.Instance.ClearPendingRevives($"truck healer state={_newState}");
}
}
}
}