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; [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("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPOJP.ExtractionAutoRevive { [BepInPlugin("REPOJP.ExtractionAutoRevive", "ExtractionAutoRevive", "4.0.1")] public sealed class ExtractionAutoRevivePlugin : BaseUnityPlugin { private sealed class PendingReviveEntry { public PlayerDeathHead DeathHead; public PlayerAvatar PlayerAvatar; public int Key; public float QueuedAt; public float GroundedStartedAt = -1f; public string LevelName; public string PlayerLabel; public string Source; } [CompilerGenerated] private sealed class d__39 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ExtractionAutoRevivePlugin <>4__this; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__39(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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; } <>4__this.ProcessPendingRevives(); if (<>4__this._pendingRevives.Count > 0) { 5__1 = 0.05f; if (<>4__this._configPendingCheckIntervalSeconds != null) { 5__1 = Mathf.Clamp(<>4__this._configPendingCheckIntervalSeconds.Value, 0.02f, 1f); } <>2__current = (object)new WaitForSecondsRealtime(5__1); <>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(); } } public const string PluginGuid = "REPOJP.ExtractionAutoRevive"; public const string PluginName = "ExtractionAutoRevive"; public const string PluginVersion = "4.0.1"; internal static ExtractionAutoRevivePlugin Instance; internal static ManualLogSource LogSource; private Harmony _harmony; private static int _extractionCompleteContextDepth; private Coroutine _pendingMonitorCoroutine; private readonly Dictionary _pendingRevives = new Dictionary(); private ConfigEntry _configEnableMod; private ConfigEntry _configEnableLog; private ConfigEntry _configEnableVerboseLog; private ConfigEntry _configReviveOnShopExtraction; private ConfigEntry _configRequiredGroundedSeconds; private ConfigEntry _configGroundCheckDistance; private ConfigEntry _configPendingCheckIntervalSeconds; private ConfigEntry _configMaxPendingSeconds; private static readonly FieldInfo FieldPlayerAvatarDeathHead = AccessTools.Field(typeof(PlayerAvatar), "playerDeathHead"); private static readonly FieldInfo FieldPlayerAvatarDeadSet = AccessTools.Field(typeof(PlayerAvatar), "deadSet"); private static readonly FieldInfo FieldPlayerAvatarIsDisabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled"); private static readonly FieldInfo FieldPlayerDeathHeadTriggered = AccessTools.Field(typeof(PlayerDeathHead), "triggered"); private static readonly FieldInfo FieldPlayerDeathHeadPhysGrabObject = AccessTools.Field(typeof(PlayerDeathHead), "physGrabObject"); private void Awake() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown try { ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ExtractionAutoRevive] Persist setup failed\n" + ex)); } try { Instance = this; LogSource = ((BaseUnityPlugin)this).Logger; SetupConfig(); _harmony = new Harmony("REPOJP.ExtractionAutoRevive"); _harmony.PatchAll(typeof(ExtractionAutoRevivePlugin).Assembly); WriteLog("Loaded v4.0.1"); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ExtractionAutoRevive] Awake failed\n" + ex2)); } } private void OnDestroy() { ClearPendingRevives("plugin destroy"); StopPendingMonitor(); try { if (_harmony != null) { _harmony.UnpatchSelf(); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ExtractionAutoRevive] Unpatch failed\n" + ex)); } if (Instance == this) { Instance = null; } } private void SetupConfig() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown _configEnableMod = ((BaseUnityPlugin)this).Config.Bind("General", "EnableMod", true, "Enable this mod. このMODを有効化"); _configReviveOnShopExtraction = ((BaseUnityPlugin)this).Config.Bind("General", "ReviveOnShopExtraction", false, "Also revive dead players when the shop extraction tube completes purchases. ショップ購入チューブ完了時も蘇生"); _configEnableLog = ((BaseUnityPlugin)this).Config.Bind("Log", "EnableLog", true, "Enable standard logs. 標準ログ有効化"); _configEnableVerboseLog = ((BaseUnityPlugin)this).Config.Bind("Log", "EnableVerboseLog", false, "Enable verbose logs. 詳細ログ有効化"); _configRequiredGroundedSeconds = ((BaseUnityPlugin)this).Config.Bind("GroundCheck", "RequiredGroundedSeconds", 0f, new ConfigDescription("Required seconds that the death head must stay on the ground before revive. 蘇生前にデスヘッドが地面接触している必要秒数", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), Array.Empty())); _configGroundCheckDistance = ((BaseUnityPlugin)this).Config.Bind("GroundCheck", "GroundCheckDistance", 0.35f, new ConfigDescription("Ground ray distance from the death head collider bounds. デスヘッドCollider境界からの地面判定距離", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 3f), Array.Empty())); _configPendingCheckIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind("GroundCheck", "PendingCheckIntervalSeconds", 0.05f, new ConfigDescription("Pending revive monitor interval. 遅延蘇生監視間隔", (AcceptableValueBase)(object)new AcceptableValueRange(0.02f, 1f), Array.Empty())); _configMaxPendingSeconds = ((BaseUnityPlugin)this).Config.Bind("GroundCheck", "MaxPendingSeconds", 0f, new ConfigDescription("Maximum seconds to wait for a death head to touch the ground. 0 means unlimited. デスヘッド地面接触待機最大秒数。0は無制限", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 600f), Array.Empty())); } private void WriteLog(string message) { if (_configEnableLog != null && _configEnableLog.Value && LogSource != null) { LogSource.LogInfo((object)("[ExtractionAutoRevive] " + message)); } } private void WriteVerbose(string message) { if (_configEnableVerboseLog != null && _configEnableVerboseLog.Value && LogSource != null) { LogSource.LogInfo((object)("[ExtractionAutoRevive] " + message)); } } private void WriteWarning(string message) { if (LogSource != null) { LogSource.LogWarning((object)("[ExtractionAutoRevive] " + message)); } } private bool IsModEnabled() { return _configEnableMod != null && _configEnableMod.Value; } private bool ShouldHandleShopExtraction() { return _configReviveOnShopExtraction != null && _configReviveOnShopExtraction.Value; } private bool CanRunHostLogic() { try { return SemiFunc.IsMasterClientOrSingleplayer(); } catch { return false; } } internal static void EnterExtractionCompleteContext(string source) { ExtractionAutoRevivePlugin instance = Instance; if (!((Object)(object)instance == (Object)null) && instance.IsModEnabled() && instance.CanRunHostLogic() && (!string.Equals(source, "shop", StringComparison.Ordinal) || instance.ShouldHandleShopExtraction())) { _extractionCompleteContextDepth++; instance.WriteVerbose("Enter extraction context source=" + source + " depth=" + _extractionCompleteContextDepth); } } internal static void ExitExtractionCompleteContext(string source, Exception exception) { ExtractionAutoRevivePlugin instance = Instance; bool flag = _extractionCompleteContextDepth > 0; if (_extractionCompleteContextDepth > 0) { _extractionCompleteContextDepth--; } if (!((Object)(object)instance == (Object)null) && flag) { instance.WriteVerbose("Exit extraction context source=" + source + " depth=" + _extractionCompleteContextDepth); if (exception != null) { instance.WriteWarning("Skip queue because extraction method failed source=" + source + "\n" + exception); } else if (instance.IsModEnabled() && instance.CanRunHostLogic()) { instance.QueueAllDeadPlayers(source); } } } internal static bool IsExtractionCompleteContextActive() { return _extractionCompleteContextDepth > 0; } private void QueueAllDeadPlayers(string source) { if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { WriteWarning("Skip queue reason=GameDirector PlayerList null source=" + source); return; } int num = 0; int num2 = 0; foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if ((Object)(object)player == (Object)null) { num2++; continue; } PlayerDeathHead playerDeathHead = GetPlayerDeathHead(player); if ((Object)(object)playerDeathHead == (Object)null) { num2++; WriteVerbose("Skip queue player=" + GetPlayerLabel(player) + " reason=deathHead null source=" + source); } else if (!IsPlayerDead(player, playerDeathHead)) { num2++; WriteVerbose("Skip queue player=" + GetPlayerLabel(player) + " reason=alive source=" + source); } else if (!IsDeathHeadTriggered(playerDeathHead)) { num2++; WriteVerbose("Skip queue player=" + GetPlayerLabel(player) + " reason=headNotTriggered source=" + source); } else { EnqueuePendingRevive(playerDeathHead, player, source); num++; } } WriteLog("Extraction complete source=" + source + " queued=" + num + " skipped=" + num2); StartPendingMonitorIfNeeded(); } private void EnqueuePendingRevive(PlayerDeathHead deathHead, PlayerAvatar playerAvatar, string source) { 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 var value)) { value.DeathHead = deathHead; value.PlayerAvatar = playerAvatar; value.PlayerLabel = GetPlayerLabel(playerAvatar); value.LevelName = GetCurrentLevelName(); value.Source = source; WriteVerbose("Refresh pending revive player=" + value.PlayerLabel + " key=" + num + " source=" + source); } else { PendingReviveEntry pendingReviveEntry = new PendingReviveEntry { DeathHead = deathHead, PlayerAvatar = playerAvatar, Key = num, QueuedAt = Time.unscaledTime, GroundedStartedAt = -1f, LevelName = GetCurrentLevelName(), PlayerLabel = GetPlayerLabel(playerAvatar), Source = source }; _pendingRevives[num] = pendingReviveEntry; WriteLog("Queue ground-wait revive player=" + pendingReviveEntry.PlayerLabel + " key=" + num + " source=" + source); } } } private void StartPendingMonitorIfNeeded() { if (_pendingRevives.Count > 0 && _pendingMonitorCoroutine == null) { _pendingMonitorCoroutine = ((MonoBehaviour)this).StartCoroutine(MonitorPendingRevives()); WriteVerbose("Pending monitor started"); } } private void StopPendingMonitor() { if (_pendingMonitorCoroutine != null) { try { ((MonoBehaviour)this).StopCoroutine(_pendingMonitorCoroutine); } catch { } _pendingMonitorCoroutine = null; } } [IteratorStateMachine(typeof(d__39))] private IEnumerator MonitorPendingRevives() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__39(0) { <>4__this = this }; } private void ProcessPendingRevives() { if (_pendingRevives.Count <= 0) { return; } List list = new List(_pendingRevives.Keys); foreach (int item in list) { if (!_pendingRevives.TryGetValue(item, out var value)) { continue; } if (value == null || (Object)(object)value.PlayerAvatar == (Object)null || (Object)(object)value.DeathHead == (Object)null) { RemovePendingRevive(item, "invalid reference"); continue; } if (HasQueuedLevelChanged(value)) { RemovePendingRevive(item, "level changed"); continue; } if (!IsPlayerDead(value.PlayerAvatar, value.DeathHead)) { RemovePendingRevive(item, "already alive"); continue; } if (!IsDeathHeadTriggered(value.DeathHead)) { RemovePendingRevive(item, "head no longer triggered"); continue; } if (HasPendingTimedOut(value)) { RemovePendingRevive(item, "pending timeout"); continue; } if (!IsDeathHeadGrounded(value.DeathHead)) { value.GroundedStartedAt = -1f; WriteVerbose("Pending wait player=" + value.PlayerLabel + " reason=not grounded"); continue; } if (value.GroundedStartedAt < 0f) { value.GroundedStartedAt = Time.unscaledTime; WriteVerbose("Pending grounded start player=" + value.PlayerLabel); } float num = 0f; if (_configRequiredGroundedSeconds != null) { num = Mathf.Clamp(_configRequiredGroundedSeconds.Value, 0f, 10f); } float num2 = Time.unscaledTime - value.GroundedStartedAt; if (num2 < num) { WriteVerbose("Pending grounded wait player=" + value.PlayerLabel + " elapsed=" + num2.ToString("F2")); } else if (ReviveNow(value.PlayerAvatar, value.DeathHead, "source=" + value.Source + " grounded=" + num2.ToString("F2") + "s")) { RemovePendingRevive(item, "revived"); } else { RemovePendingRevive(item, "revive failed"); } } } private bool HasPendingTimedOut(PendingReviveEntry entry) { if (entry == null) { return true; } float num = 0f; if (_configMaxPendingSeconds != null) { num = Mathf.Clamp(_configMaxPendingSeconds.Value, 0f, 600f); } if (num <= 0f) { return false; } return Time.unscaledTime - entry.QueuedAt >= num; } private void RemovePendingRevive(int key, string reason) { if (_pendingRevives.TryGetValue(key, out var 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 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 flag = (Object)(object)((Component)playerAvatar).gameObject != (Object)null && ((Component)playerAvatar).gameObject.activeSelf; bool flag2 = (Object)(object)deathHead != (Object)null && IsDeathHeadTriggered(deathHead); if (boolField) { return true; } if (boolField2) { return true; } if (!flag) { return true; } if (flag2) { return true; } return false; } private bool ReviveNow(PlayerAvatar playerAvatar, PlayerDeathHead deathHead, string reason) { if ((Object)(object)playerAvatar == (Object)null || (Object)(object)deathHead == (Object)null) { return false; } if (!IsPlayerDead(playerAvatar, deathHead)) { WriteVerbose("Skip revive player=" + GetPlayerLabel(playerAvatar) + " reason=alreadyAlive finalReason=" + reason); return true; } try { playerAvatar.Revive(false); WriteLog("Revive player=" + GetPlayerLabel(playerAvatar) + " " + reason); return true; } catch (Exception ex) { WriteWarning("Revive failed player=" + GetPlayerLabel(playerAvatar) + " " + reason + "\n" + ex); return false; } } private bool IsDeathHeadGrounded(PlayerDeathHead deathHead) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)deathHead == (Object)null) { return false; } PhysGrabObject playerDeathHeadPhysGrabObject = GetPlayerDeathHeadPhysGrabObject(deathHead); if ((Object)(object)playerDeathHeadPhysGrabObject == (Object)null) { return false; } float num = 0.35f; if (_configGroundCheckDistance != null) { num = Mathf.Clamp(_configGroundCheckDistance.Value, 0.05f, 3f); } try { Vector3 centerPoint = playerDeathHeadPhysGrabObject.centerPoint; if (SemiFunc.OnGroundCheck(centerPoint, num, playerDeathHeadPhysGrabObject)) { return true; } } catch { } try { if ((Object)(object)playerDeathHeadPhysGrabObject.rb != (Object)null) { Vector3 worldCenterOfMass = playerDeathHeadPhysGrabObject.rb.worldCenterOfMass; if (SemiFunc.OnGroundCheck(worldCenterOfMass, num, playerDeathHeadPhysGrabObject)) { return true; } } } catch { } try { Collider[] componentsInChildren = ((Component)deathHead).GetComponentsInChildren(); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger) { Bounds bounds = val.bounds; Vector3 center = ((Bounds)(ref bounds)).center; float num2 = ((Bounds)(ref bounds)).extents.y + num; if (SemiFunc.OnGroundCheck(center, num2, playerDeathHeadPhysGrabObject)) { return true; } } } } catch { } return false; } private int GetPendingKey(PlayerAvatar playerAvatar, PlayerDeathHead deathHead) { try { if ((Object)(object)playerAvatar != (Object)null && (Object)(object)playerAvatar.photonView != (Object)null && playerAvatar.photonView.ViewID > 0) { return playerAvatar.photonView.ViewID; } } catch { } try { PhotonView val = null; if ((Object)(object)deathHead != (Object)null) { val = ((Component)deathHead).GetComponent(); } if ((Object)(object)val != (Object)null && val.ViewID > 0) { return val.ViewID; } } catch { } 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"; } try { if (!string.IsNullOrEmpty(((Object)playerAvatar).name)) { return ((Object)playerAvatar).name; } } catch { } return "PlayerAvatar"; } private static PlayerDeathHead GetPlayerDeathHead(PlayerAvatar playerAvatar) { if ((Object)(object)playerAvatar == (Object)null) { return null; } if (FieldPlayerAvatarDeathHead != null) { try { object? value = FieldPlayerAvatarDeathHead.GetValue(playerAvatar); return (PlayerDeathHead)((value is PlayerDeathHead) ? value : null); } catch { } } try { return ((Component)playerAvatar).GetComponentInChildren(true); } catch { return null; } } private static bool IsDeathHeadTriggered(PlayerDeathHead deathHead) { return GetBoolField(FieldPlayerDeathHeadTriggered, deathHead, defaultValue: false); } 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; } try { val = ((Component)deathHead).GetComponent(); } catch { val = null; } return val; } private bool HasQueuedLevelChanged(PendingReviveEntry entry) { if (entry == null) { return true; } string currentLevelName = GetCurrentLevelName(); if (!string.IsNullOrEmpty(entry.LevelName) && !string.IsNullOrEmpty(currentLevelName) && !string.Equals(entry.LevelName, currentLevelName, StringComparison.Ordinal)) { return true; } return false; } private string GetCurrentLevelName() { try { if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null) { return ((Object)RunManager.instance.levelCurrent).name ?? string.Empty; } } catch { } return string.Empty; } 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; } } [HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInHaulList")] internal static class ExtractionPoint_DestroyAllPhysObjectsInHaulList_Patch { private static void Prefix() { ExtractionAutoRevivePlugin.EnterExtractionCompleteContext("haul"); } private static Exception Finalizer(Exception __exception) { ExtractionAutoRevivePlugin.ExitExtractionCompleteContext("haul", __exception); return __exception; } } [HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInShoppingList")] internal static class ExtractionPoint_DestroyAllPhysObjectsInShoppingList_Patch { private static void Prefix() { ExtractionAutoRevivePlugin.EnterExtractionCompleteContext("shop"); } private static Exception Finalizer(Exception __exception) { ExtractionAutoRevivePlugin.ExitExtractionCompleteContext("shop", __exception); return __exception; } } [HarmonyPatch(typeof(PlayerDeathHead), "Revive")] internal static class PlayerDeathHead_Revive_Patch { private static bool Prefix() { if (ExtractionAutoRevivePlugin.IsExtractionCompleteContextActive()) { return false; } return true; } } [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"); } } } }