Decompiled source of ExtractionAutoRevive v0.1.1

ExtractionAutoRevive.dll

Decompiled 5 hours ago
using System;
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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("test")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("test")]
[assembly: AssemblyTitle("test")]
[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 ExtractionAutoRevive
{
	[BepInPlugin("jp.repo.extractionautorevive", "ExtractionAutoRevive", "1.0.0")]
	public sealed class ExtractionAutoRevivePlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			LogInfo("Awake enter");
			try
			{
				_harmony = new Harmony("jp.repo.extractionautorevive");
				_harmony.PatchAll(typeof(ExtractionPointStateSetPatch));
				LogInfo("Harmony PatchAll done");
			}
			catch (Exception ex)
			{
				LogError("Harmony PatchAll failed\n" + ex);
			}
			LogInfo("Awake exit");
		}

		internal static void LogInfo(string msg)
		{
			Debug.Log((object)("[ExtractionAutoRevive] " + msg));
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)msg);
			}
		}

		internal static void LogWarn(string msg)
		{
			Debug.LogWarning((object)("[ExtractionAutoRevive] " + msg));
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)msg);
			}
		}

		internal static void LogError(string msg)
		{
			Debug.LogError((object)("[ExtractionAutoRevive] " + msg));
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)msg);
			}
		}

		internal static bool IsHostOrSingle()
		{
			try
			{
				bool result = SemiFunc.IsMasterClientOrSingleplayer();
				LogInfo("HostGuard SemiFunc.IsMasterClientOrSingleplayer=" + result);
				return result;
			}
			catch (Exception ex)
			{
				LogWarn("HostGuard check failed\n" + ex);
				return false;
			}
		}

		internal static bool IsInLevel()
		{
			try
			{
				bool result = SemiFunc.RunIsLevel();
				LogInfo("StageGuard SemiFunc.RunIsLevel=" + result);
				return result;
			}
			catch (Exception ex)
			{
				LogWarn("StageGuard check failed\n" + ex);
				return false;
			}
		}

		internal static void ForceReviveAllDeadPlayers(string reason)
		{
			LogInfo("ForceReviveAllDeadPlayers enter reason=" + reason);
			GameDirector instance;
			try
			{
				instance = GameDirector.instance;
			}
			catch (Exception ex)
			{
				LogError("GameDirector.instance get failed\n" + ex);
				LogInfo("ForceReviveAllDeadPlayers exit");
				return;
			}
			if ((Object)(object)instance == (Object)null)
			{
				LogWarn("GameDirector.instance is null");
				LogInfo("ForceReviveAllDeadPlayers exit");
				return;
			}
			List<PlayerAvatar> playerList = instance.PlayerList;
			if (playerList == null)
			{
				LogWarn("GameDirector.instance.PlayerList is null");
				LogInfo("ForceReviveAllDeadPlayers exit");
				return;
			}
			int count;
			try
			{
				count = playerList.Count;
			}
			catch (Exception ex2)
			{
				LogError("PlayerList.Count get failed\n" + ex2);
				LogInfo("ForceReviveAllDeadPlayers exit");
				return;
			}
			LogInfo("PlayerList.Count=" + count);
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			for (int i = 0; i < count; i++)
			{
				PlayerAvatar val;
				try
				{
					val = playerList[i];
				}
				catch (Exception ex3)
				{
					LogWarn("PlayerList index access failed index=" + i + "\n" + ex3);
					continue;
				}
				num++;
				if ((Object)(object)val == (Object)null)
				{
					LogWarn("Player null index=" + i);
					continue;
				}
				string text;
				try
				{
					text = ((Object)val).name;
				}
				catch
				{
					text = "<name-error>";
				}
				bool flag = false;
				try
				{
					flag = val.deadSet;
				}
				catch (Exception ex4)
				{
					LogWarn("Read player.deadSet failed name=" + text + "\n" + ex4);
				}
				float num5 = float.NaN;
				bool flag2 = false;
				try
				{
					if ((Object)(object)val.playerHealth != (Object)null)
					{
						flag2 = true;
						num5 = val.playerHealth.health;
					}
				}
				catch (Exception ex5)
				{
					LogWarn("Read player.playerHealth.health failed name=" + text + "\n" + ex5);
				}
				bool flag3 = flag2 && num5 <= 0f;
				bool flag4 = flag || flag3;
				LogInfo("Eval index=" + (i + 1) + "/" + count + " name=" + text + " deadSet=" + flag + " hasHealth=" + flag2 + " hp=" + (flag2 ? num5.ToString() : "<null>") + " shouldRevive=" + flag4);
				if (!flag4)
				{
					LogInfo("Skip revive (alive) name=" + text);
					continue;
				}
				num2++;
				PlayerDeathHead val2 = null;
				try
				{
					val2 = val.playerDeathHead;
				}
				catch (Exception ex6)
				{
					LogWarn("Read player.playerDeathHead failed name=" + text + "\n" + ex6);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					try
					{
						val2.inExtractionPoint = true;
						LogInfo("Set head.inExtractionPoint=true name=" + text);
					}
					catch (Exception ex7)
					{
						LogWarn("Set head.inExtractionPoint failed name=" + text + "\n" + ex7);
					}
					try
					{
						val2.inTruck = true;
						LogInfo("Set head.inTruck=true name=" + text);
					}
					catch (Exception ex8)
					{
						LogWarn("Set head.inTruck failed name=" + text + "\n" + ex8);
					}
				}
				else
				{
					LogInfo("DeathHead null name=" + text);
				}
				num3++;
				try
				{
					val.Revive(true);
					num4++;
					LogInfo("Revive(true) called name=" + text);
				}
				catch (Exception ex9)
				{
					LogError("Revive(true) failed name=" + text + "\n" + ex9);
				}
			}
			LogInfo("Summary checked=" + num + " deadDetected=" + num2 + " reviveTried=" + num3 + " reviveSucceeded=" + num4);
			LogInfo("ForceReviveAllDeadPlayers exit");
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "StateSet")]
	internal static class ExtractionPointStateSetPatch
	{
		private static void Postfix(ExtractionPoint __instance, State newState)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Invalid comparison between Unknown and I4
			ExtractionAutoRevivePlugin.LogInfo("Patch StateSet enter epNull=" + ((Object)(object)__instance == (Object)null) + " newState=" + ((object)(State)(ref newState)).ToString());
			if (!ExtractionAutoRevivePlugin.IsHostOrSingle())
			{
				ExtractionAutoRevivePlugin.LogInfo("Patch skip reason=notHostOrSingle");
				ExtractionAutoRevivePlugin.LogInfo("Patch StateSet exit");
			}
			else if (!ExtractionAutoRevivePlugin.IsInLevel())
			{
				ExtractionAutoRevivePlugin.LogInfo("Patch skip reason=notInLevel");
				ExtractionAutoRevivePlugin.LogInfo("Patch StateSet exit");
			}
			else if ((int)newState == 3)
			{
				ExtractionAutoRevivePlugin.LogInfo("Patch ignore state=Success");
				ExtractionAutoRevivePlugin.LogInfo("Patch StateSet exit");
			}
			else if ((int)newState != 7)
			{
				ExtractionAutoRevivePlugin.LogInfo("Patch skip state=" + ((object)(State)(ref newState)).ToString());
				ExtractionAutoRevivePlugin.LogInfo("Patch StateSet exit");
			}
			else
			{
				ExtractionAutoRevivePlugin.LogInfo("Patch trigger state=Complete");
				ExtractionAutoRevivePlugin.ForceReviveAllDeadPlayers("ExtractionPoint.State.Complete");
				ExtractionAutoRevivePlugin.LogInfo("Patch StateSet exit");
			}
		}
	}
}