Decompiled source of PlayerRespawnSystem v2.1.5

PlayerRespawnSystem.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates.Missions.BrotherEncounter;
using Microsoft.CodeAnalysis;
using On.EntityStates.Missions.BrotherEncounter;
using On.RoR2;
using On.RoR2.UI;
using R2API.Utils;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerRespawnSystem")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyProduct("PlayerRespawnSystem")]
[assembly: AssemblyTitle("PlayerRespawnSystem")]
[assembly: AssemblyInformationalVersion("1.0.0+9a974579cea7fe6054042d510b7462900fc5099d")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[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]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PlayerRespawnSystem
{
	public static class ChatHelper
	{
		private const string GrayColor = "7e91af";

		private const string RedColor = "ff0000";

		private const string YellowColor = "ffff00";

		private const string GreenColor = "32cd32";

		private const string SilverColor = "c0c0c0";

		public static void TimedRespawnBlockedOnStage()
		{
			//IL_0006: 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)
			//IL_0017: Expected O, but got Unknown
			string baseToken = "<color=#7e91af>Timed respawns are blocked on this stage.</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void RespawnBlockedOnTPEvent()
		{
			//IL_0006: 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)
			//IL_0017: Expected O, but got Unknown
			string baseToken = "<color=#7e91af>Respawns are blocked on teleporter event.</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfterTPEvent(string userName)
		{
			//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_0022: Expected O, but got Unknown
			string baseToken = "<color=#32cd32>" + userName + "</color> <color=#7e91af>will respawn after teleporter event</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfterMithrixFight(string userName)
		{
			//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_0022: Expected O, but got Unknown
			string baseToken = "<color=#32cd32>" + userName + "</color> <color=#7e91af>will respawn after mithrix fight</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfterArtifactTrial(string userName)
		{
			//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_0022: Expected O, but got Unknown
			string baseToken = "<color=#32cd32>" + userName + "</color> <color=#7e91af>will respawn after artifact trial</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfterVoidlingFight(string userName)
		{
			//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_0022: Expected O, but got Unknown
			string baseToken = "<color=#32cd32>" + userName + "</color> <color=#7e91af>will respawn after voidling fight</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfterFalseSonFight(string userName)
		{
			//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_0022: Expected O, but got Unknown
			string baseToken = "<color=#32cd32>" + userName + "</color> <color=#7e91af>will respawn after false son fight</color>";
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}

		public static void UserWillRespawnAfter(string userName, uint respawnTime)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			string baseToken = string.Format("<color=#{0}>{1}</color> <color=#{2}>will respawn in {3} seconds</color>", "32cd32", userName, "7e91af", respawnTime);
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = baseToken
			});
		}
	}
	public static class UsersHelper
	{
		public static NetworkUser GetUser(NetworkUserId userId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser u)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				NetworkUserId id = u.id;
				return ((NetworkUserId)(ref id)).Equals(userId);
			});
		}

		public static NetworkUser GetUser(CharacterMaster master)
		{
			return ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)((NetworkUser u) => (Object)(object)u.master == (Object)(object)master));
		}
	}
	internal class PlayerRespawner : MonoBehaviour
	{
		private Queue<Tuple<RespawnController, CharacterBody>> respawnQueue = new Queue<Tuple<RespawnController, CharacterBody>>();

		public bool IsAdvancingStage { get; set; }

		public void RespawnUser(RespawnController respawnController, NetworkUser user)
		{
			if (CheckIfControllerCanRespawn(respawnController, user) && Object.op_Implicit((Object)(object)user.master.bodyPrefab))
			{
				CharacterBody component = user.master.bodyPrefab.GetComponent<CharacterBody>();
				if (Object.op_Implicit((Object)(object)component))
				{
					PlayerRespawnSystemPlugin.Log.LogDebug((object)$"Issuing {respawnController.GetRespawnType()} respawn");
					respawnQueue.Enqueue(new Tuple<RespawnController, CharacterBody>(respawnController, component));
					Stage.instance.RespawnCharacter(user.master);
				}
			}
		}

		public void RespawnAllUsers(RespawnController respawnController)
		{
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				RespawnUser(respawnController, readOnlyInstances);
			}
		}

		public bool CheckIfControllerCanRespawn(RespawnController respawnController, NetworkUser user)
		{
			if (Object.op_Implicit((Object)(object)respawnController) && respawnController.IsActive)
			{
				return CheckIfUserCanBeRespawned(user);
			}
			return false;
		}

		public bool CheckIfUserCanBeRespawned(NetworkUser user)
		{
			if (Object.op_Implicit((Object)(object)user) && Object.op_Implicit((Object)(object)user.master) && user.master.IsDeadAndOutOfLivesServer())
			{
				return !IsAdvancingStage;
			}
			return false;
		}

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Stage.RespawnCharacter += new hook_RespawnCharacter(Stage_RespawnCharacter);
			Stage.GetPlayerSpawnTransform += new hook_GetPlayerSpawnTransform(Stage_GetPlayerSpawnTransform);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Stage.RespawnCharacter -= new hook_RespawnCharacter(Stage_RespawnCharacter);
			Stage.GetPlayerSpawnTransform -= new hook_GetPlayerSpawnTransform(Stage_GetPlayerSpawnTransform);
		}

		private void Stage_RespawnCharacter(orig_RespawnCharacter orig, Stage self, CharacterMaster characterMaster)
		{
			if (Object.op_Implicit((Object)(object)characterMaster.bodyPrefab))
			{
				CharacterBody component = characterMaster.bodyPrefab.GetComponent<CharacterBody>();
				if (Object.op_Implicit((Object)(object)component) && (respawnQueue.Count == 0 || (Object)(object)respawnQueue.Last().Item2 != (Object)(object)component))
				{
					respawnQueue.Enqueue(new Tuple<RespawnController, CharacterBody>(null, component));
				}
			}
			orig.Invoke(self, characterMaster);
		}

		private Transform Stage_GetPlayerSpawnTransform(orig_GetPlayerSpawnTransform orig, Stage self)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (respawnQueue.Count > 0)
			{
				var (respawnController2, val2) = respawnQueue.Dequeue();
				if (Object.op_Implicit((Object)(object)respawnController2) && Object.op_Implicit((Object)(object)val2))
				{
					PlayerRespawnSystemPlugin.Log.LogDebug((object)$"Getting respawn position for {respawnController2.GetRespawnType()} respawn");
					if (respawnController2.GetRespawnTransform(val2, out var outRespawnTransform))
					{
						PlayerRespawnSystemPlugin.Log.LogDebug((object)$"Found respawn position at {outRespawnTransform.position}");
						return outRespawnTransform;
					}
					PlayerRespawnSystemPlugin.Log.LogDebug((object)"Failed to find respawn position, using default");
				}
			}
			return orig.Invoke(self);
		}
	}
	internal class PlayerRespawnSystem : MonoBehaviour
	{
		private Dictionary<RespawnType, RespawnController> respawnControllers = new Dictionary<RespawnType, RespawnController>();

		private PlayerRespawner playerRespawner;

		public static PlayerRespawnSystem instance { get; private set; }

		public IReadOnlyDictionary<RespawnType, RespawnController> RespawnControllers => respawnControllers;

		public bool CheckIfUserCanBeRespawned(NetworkUser user)
		{
			return playerRespawner.CheckIfUserCanBeRespawned(user);
		}

		public void BlockTimedRespawn()
		{
			if (respawnControllers.ContainsKey(RespawnType.Timed))
			{
				(respawnControllers[RespawnType.Timed] as TimedRespawnController).StopAllRespawnTimers();
			}
		}

		public void UnblockTimedRespawn()
		{
			if (respawnControllers.ContainsKey(RespawnType.Timed))
			{
				(respawnControllers[RespawnType.Timed] as TimedRespawnController).ResumeAllRespawnTimers();
			}
		}

		protected void OnEnable()
		{
			instance = SingletonHelper.Assign<PlayerRespawnSystem>(instance, this);
		}

		protected void OnDisable()
		{
			instance = SingletonHelper.Unassign<PlayerRespawnSystem>(instance, this);
		}

		public void Awake()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			playerRespawner = ((Component)this).gameObject.AddComponent<PlayerRespawner>();
			foreach (var (respawnType2, type2) in RespawnController.GetRespawnControllerTypes())
			{
				if (RespawnController.IsEnabled(type2))
				{
					PlayerRespawnSystemPlugin.Log.LogDebug((object)$"Enabling {respawnType2} respawn controller");
					respawnControllers[respawnType2] = (RespawnController)(object)((Component)this).gameObject.AddComponent(type2);
					respawnControllers[respawnType2].Init(playerRespawner);
					respawnControllers[respawnType2].OnRequestTimedRespawnBlock += BlockTimedRespawn;
					respawnControllers[respawnType2].OnRequestTimedRespawnUnblock += UnblockTimedRespawn;
				}
			}
			Stage.OnEnable += new hook_OnEnable(Stage_OnEnable);
			PlayerCharacterMasterController.OnBodyDeath += new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
			SceneExitController.SetState += new hook_SetState(SceneExitController_SetState);
			Run.OnServerSceneChanged += new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
		}

		public void OnDestroy()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			foreach (var (key, _) in respawnControllers)
			{
				respawnControllers[key].OnRequestTimedRespawnBlock -= BlockTimedRespawn;
				respawnControllers[key].OnRequestTimedRespawnUnblock -= UnblockTimedRespawn;
				Object.Destroy((Object)(object)respawnControllers[key]);
			}
			respawnControllers.Clear();
			Object.Destroy((Object)(object)playerRespawner);
			Stage.OnEnable -= new hook_OnEnable(Stage_OnEnable);
			PlayerCharacterMasterController.OnBodyDeath -= new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
			SceneExitController.SetState -= new hook_SetState(SceneExitController_SetState);
			Run.OnServerSceneChanged -= new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
		}

		private void Stage_OnEnable(orig_OnEnable orig, Stage self)
		{
			orig.Invoke(self);
			if (!PluginConfig.UsePodsOnStartOfMatch.Value)
			{
				Stage.instance.usePod = false;
			}
		}

		private void PlayerCharacterMasterController_OnBodyDeath(orig_OnBodyDeath orig, PlayerCharacterMasterController self)
		{
			orig.Invoke(self);
			if (!respawnControllers.ContainsKey(RespawnType.Timed))
			{
				return;
			}
			NetworkUser user = UsersHelper.GetUser(self.master);
			if (Object.op_Implicit((Object)(object)user) && !respawnControllers[RespawnType.Timed].IsActive)
			{
				if (IsRespawnControllerEnabledAndActive(RespawnType.Teleporter) && PluginConfig.RespawnOnTPEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterTPEvent(user.userName);
				}
				if (IsRespawnControllerEnabledAndActive(RespawnType.Mithrix) && PluginConfig.RespawnOnMithrixEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterMithrixFight(user.userName);
				}
				if (IsRespawnControllerEnabledAndActive(RespawnType.Voidling) && PluginConfig.RespawnOnVoidlingEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterVoidlingFight(user.userName);
				}
				if (IsRespawnControllerEnabledAndActive(RespawnType.FalseSon) && PluginConfig.RespawnOnFalseSonEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterFalseSonFight(user.userName);
				}
			}
		}

		private void SceneExitController_SetState(orig_SetState orig, SceneExitController self, ExitState newState)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			orig.Invoke(self, newState);
			if ((int)newState == 2)
			{
				playerRespawner.IsAdvancingStage = true;
			}
		}

		private void Run_OnServerSceneChanged(orig_OnServerSceneChanged orig, Run self, string sceneName)
		{
			orig.Invoke(self, sceneName);
			playerRespawner.IsAdvancingStage = false;
		}

		private bool IsRespawnControllerEnabledAndActive(RespawnType respawnType)
		{
			if (respawnControllers.ContainsKey(respawnType))
			{
				return respawnControllers[respawnType].IsActive;
			}
			return false;
		}
	}
	[AssociatedRespawnType(RespawnType.Artifact)]
	internal class ArtifactTrialRespawnController : RespawnController
	{
		public new static bool IsEnabled => true;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			CombatState.OnEnter += new hook_OnEnter(ArtifactTrialMissionController_CombatState_OnEnter);
			CombatState.OnExit += new hook_OnExit(CombatState_OnExit);
			Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			CombatState.OnEnter -= new hook_OnEnter(ArtifactTrialMissionController_CombatState_OnEnter);
			CombatState.OnExit -= new hook_OnExit(CombatState_OnExit);
			Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
		}

		private void ArtifactTrialMissionController_CombatState_OnEnter(orig_OnEnter orig, CombatState self)
		{
			orig.Invoke(self);
			base.IsActive = true;
			if (PluginConfig.RespawnOnArtifactTrialStart.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			if (PluginConfig.BlockTimedRespawnOnArtifactTrial.Value)
			{
				RequestTimedRespawnBlock();
			}
		}

		private void CombatState_OnExit(orig_OnExit orig, CombatState self)
		{
			orig.Invoke(self);
			if (PluginConfig.BlockTimedRespawnOnArtifactTrial.Value)
			{
				RequestTimedRespawnUnblock();
			}
			if (PluginConfig.RespawnOnArtifactTrialEnd.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			base.IsActive = false;
		}

		private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene)
		{
			orig.Invoke(self, nextScene);
			base.IsActive = false;
		}
	}
	[AssociatedRespawnType(RespawnType.FalseSon)]
	internal class FalseSonRespawnController : RespawnController
	{
		public new static bool IsEnabled => true;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			MeridianEventTriggerInteraction.Start += new hook_Start(MeridianEventStart_OnEnter);
			MeridianEventTriggerInteraction.TriggerEventClear += new hook_TriggerEventClear(MeridianEventCleared_OnEnter);
			Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			MeridianEventTriggerInteraction.Start -= new hook_Start(MeridianEventStart_OnEnter);
			MeridianEventTriggerInteraction.TriggerEventClear -= new hook_TriggerEventClear(MeridianEventCleared_OnEnter);
			Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
		}

		private void MeridianEventStart_OnEnter(orig_Start orig, MeridianEventTriggerInteraction self)
		{
			orig.Invoke(self);
			base.IsActive = true;
			if (PluginConfig.RespawnOnFalseSonStart.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			if (PluginConfig.BlockTimedRespawnOnFalseSonFight.Value)
			{
				RequestTimedRespawnBlock();
			}
		}

		private void MeridianEventCleared_OnEnter(orig_TriggerEventClear orig, MeridianEventTriggerInteraction self)
		{
			orig.Invoke(self);
			if (PluginConfig.BlockTimedRespawnOnFalseSonFight.Value)
			{
				RequestTimedRespawnUnblock();
			}
			if (PluginConfig.RespawnOnFalseSonEnd.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			base.IsActive = false;
		}

		private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene)
		{
			orig.Invoke(self, nextScene);
			base.IsActive = false;
		}

		public override bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionForStormBoss();
			if (transform.position != Vector3.zero)
			{
				outRespawnTransform = transform;
				return true;
			}
			PlayerRespawnSystemPlugin.Log.LogDebug((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
			outRespawnTransform = null;
			return false;
		}
	}
	[AssociatedRespawnType(RespawnType.Mithrix)]
	internal class MithrixRespawnController : RespawnController
	{
		public new static bool IsEnabled => true;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			Phase1.OnEnter += new hook_OnEnter(BrotherEncounter_Phase1_OnEnter);
			EncounterFinished.OnEnter += new hook_OnEnter(BrotherEncounter_EncounterFinished_OnEnter);
			Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			Phase1.OnEnter -= new hook_OnEnter(BrotherEncounter_Phase1_OnEnter);
			EncounterFinished.OnEnter -= new hook_OnEnter(BrotherEncounter_EncounterFinished_OnEnter);
			Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
		}

		private void BrotherEncounter_Phase1_OnEnter(orig_OnEnter orig, Phase1 self)
		{
			orig.Invoke(self);
			base.IsActive = true;
			if (PluginConfig.RespawnOnMithrixStart.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			if (PluginConfig.BlockTimedRespawnOnMithrixFight.Value)
			{
				RequestTimedRespawnBlock();
			}
		}

		private void BrotherEncounter_EncounterFinished_OnEnter(orig_OnEnter orig, EncounterFinished self)
		{
			orig.Invoke(self);
			if (PluginConfig.BlockTimedRespawnOnMithrixFight.Value)
			{
				RequestTimedRespawnUnblock();
			}
			if (PluginConfig.RespawnOnMithrixEnd.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			base.IsActive = false;
		}

		private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene)
		{
			orig.Invoke(self, nextScene);
			base.IsActive = false;
		}

		public override bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionAroundMoonBoss(body, 100f, 105f);
			if (transform.position != Vector3.zero)
			{
				outRespawnTransform = transform;
				return true;
			}
			PlayerRespawnSystemPlugin.Log.LogDebug((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
			outRespawnTransform = null;
			return false;
		}
	}
	public enum RespawnType : byte
	{
		Timed,
		Teleporter,
		Mithrix,
		Artifact,
		Voidling,
		FalseSon
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	public class AssociatedRespawnType : Attribute
	{
		public RespawnType RespawnType { get; }

		public AssociatedRespawnType(RespawnType respawnType)
		{
			RespawnType = respawnType;
		}
	}
	internal interface IRespawnController
	{
		public delegate void RequestTimedRespawnBlock();

		public delegate void RequestTimedRespawnUnblock();

		event RequestTimedRespawnBlock OnRequestTimedRespawnBlock;

		event RequestTimedRespawnBlock OnRequestTimedRespawnUnblock;
	}
	internal abstract class RespawnController : MonoBehaviour, IRespawnController
	{
		private bool isActive;

		protected PlayerRespawner playerRespawner;

		public bool IsActive
		{
			get
			{
				return isActive;
			}
			protected set
			{
				if (isActive != value)
				{
					PlayerRespawnSystemPlugin.Log.LogDebug((object)((value ? "Activating" : "Deactivating") + $" {GetRespawnType()} respawn controller"));
					isActive = value;
				}
			}
		}

		public event IRespawnController.RequestTimedRespawnBlock OnRequestTimedRespawnBlock;

		public event IRespawnController.RequestTimedRespawnBlock OnRequestTimedRespawnUnblock;

		public void Init(PlayerRespawner playerRespawner)
		{
			this.playerRespawner = playerRespawner;
		}

		public RespawnType GetRespawnType()
		{
			return ((object)this).GetType().GetCustomAttribute<AssociatedRespawnType>().RespawnType;
		}

		public virtual bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			outRespawnTransform = null;
			return false;
		}

		protected void RequestTimedRespawnBlock()
		{
			this.OnRequestTimedRespawnBlock?.Invoke();
		}

		protected void RequestTimedRespawnUnblock()
		{
			this.OnRequestTimedRespawnUnblock?.Invoke();
		}

		public static bool IsEnabled(Type type)
		{
			return (bool)type.GetProperty("IsEnabled", BindingFlags.Static | BindingFlags.Public).GetValue(null);
		}

		public static Dictionary<RespawnType, Type> GetRespawnControllerTypes()
		{
			Dictionary<RespawnType, Type> dictionary = new Dictionary<RespawnType, Type>();
			foreach (Type item in from t in Assembly.GetExecutingAssembly().GetTypes()
				where t.GetCustomAttribute<AssociatedRespawnType>() != null
				select t)
			{
				RespawnType respawnType = item.GetCustomAttribute<AssociatedRespawnType>().RespawnType;
				dictionary[respawnType] = item;
			}
			return dictionary;
		}
	}
	internal static class RespawnPosition
	{
		public static Vector3 GetSpawnPositionAroundTeleporter(CharacterBody body, float minSpawnRadius, float maxSpawnRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_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)
			Vector3 zero = Vector3.zero;
			int num = 0;
			do
			{
				if (num++ > 1000)
				{
					return Vector3.zero;
				}
				zero = ((Component)TeleporterInteraction.instance).transform.position;
				zero += GetRandomPositionInCircle(minSpawnRadius, maxSpawnRadius);
			}
			while (!TryUpdateToProperPositionOnStage(ref zero, body.radius));
			return new Vector3(zero.x, zero.y + Util.GetBodyPrefabFootOffset(((Component)body).gameObject), zero.z);
		}

		public static Vector3 GetSpawnPositionAroundMoonBoss(CharacterBody body, float minSpawnRadius, float maxSpawnRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = Vector3.zero;
			int num = 0;
			do
			{
				if (num++ > 1000)
				{
					return Vector3.zero;
				}
				GameObject val = GameObject.Find("ArenaWalls");
				if (Object.op_Implicit((Object)(object)val))
				{
					position = val.transform.position;
					position += GetRandomPositionInCircle(minSpawnRadius, maxSpawnRadius);
				}
			}
			while (!TryUpdateToProperPositionOnStage(ref position, body.radius));
			return new Vector3(position.x, position.y + Util.GetBodyPrefabFootOffset(((Component)body).gameObject), position.z);
		}

		public static Vector3 GetSpawnPositionForVoidBoss()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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)
			FieldInfo field = typeof(VoidRaidGauntletController).GetField("gauntletIndex", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
			FieldInfo field2 = typeof(VoidRaidGauntletController).GetField("initialDonut", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
			FieldInfo field3 = typeof(VoidRaidGauntletController).GetField("followingDonuts", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
			if (field == null || field2 == null || field3 == null)
			{
				PlayerRespawnSystemPlugin.Log.LogWarning((object)"Failed to find VoidRaidGauntletController field");
				return Vector3.zero;
			}
			int num = (int)field.GetValue(VoidRaidGauntletController.instance);
			DonutInfo val;
			if (num <= 0)
			{
				object? value = field2.GetValue(VoidRaidGauntletController.instance);
				val = (DonutInfo)((value is DonutInfo) ? value : null);
				if (val == null)
				{
					PlayerRespawnSystemPlugin.Log.LogWarning((object)"Failed to get VoidRaidGauntletController::initialDonut field");
					return Vector3.zero;
				}
			}
			else
			{
				if (!(field3.GetValue(VoidRaidGauntletController.instance) is DonutInfo[] array))
				{
					PlayerRespawnSystemPlugin.Log.LogWarning((object)"Failed to get VoidRaidGauntletController::followingDonuts field");
					return Vector3.zero;
				}
				val = array[num - 1];
			}
			return val.returnPoint.position;
		}

		public static Vector3 GetSpawnPositionForStormBoss()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return MeridianEventTriggerInteraction.instance.sceneBoundsNew.transform.position;
		}

		private static Vector3 GetRandomPositionInCircle(float minRadius, float maxRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector3 val = Vector2.op_Implicit(((Vector2)(ref insideUnitCircle)).normalized * Random.Range(minRadius, maxRadius));
			val.z = val.y;
			val.y = 0f;
			return val;
		}

		private static bool TryUpdateToProperPositionOnStage(ref Vector3 position, float maxRadiusAroundPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			Ray val2 = new Ray(position + Vector3.up * 2f, Vector3.down);
			float num = 4f;
			if (Physics.SphereCast(val2, maxRadiusAroundPosition, ref val, num, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask)))
			{
				position.y += 2f - ((RaycastHit)(ref val)).distance;
				return true;
			}
			return false;
		}
	}
	public enum RespawnTimeType
	{
		StageTimeBased,
		GameTimeBased
	}
	internal static class RespawnTimeCalculation
	{
		public static uint GetRespawnTime()
		{
			uint num = PluginConfig.StartingRespawnTime.Value;
			switch (PluginConfig.RespawnTimeType.Value)
			{
			case RespawnTimeType.StageTimeBased:
				num += RespawnTimeBasedOnPassedStageTime();
				break;
			case RespawnTimeType.GameTimeBased:
				num += RespawnTimeBasedOnPassedGameTime();
				break;
			}
			return (uint)Mathf.Min((float)num, (float)PluginConfig.MaxRespawnTime.Value);
		}

		private static uint RespawnTimeBasedOnPassedStageTime()
		{
			return (GameSecondsPassed() - StageEntrySeconds()) / PluginConfig.UpdateCurrentRespawnTimeEveryXSeconds.Value * PluginConfig.UpdateCurrentRepsawnTimeByXSeconds.Value;
		}

		private static uint RespawnTimeBasedOnPassedGameTime()
		{
			return GameSecondsPassed() / PluginConfig.UpdateCurrentRespawnTimeEveryXSeconds.Value * PluginConfig.UpdateCurrentRepsawnTimeByXSeconds.Value;
		}

		private static uint StageEntrySeconds()
		{
			return (uint)(Object.op_Implicit((Object)(object)Stage.instance) ? Stage.instance.Network_entryStopwatchValue : 0f);
		}

		private static uint GameSecondsPassed()
		{
			return (uint)(Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.GetRunStopwatch() : 0f);
		}
	}
	[AssociatedRespawnType(RespawnType.Teleporter)]
	internal class TeleporterRespawnController : RespawnController
	{
		public new static bool IsEnabled => true;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ChargingState.OnEnter += new hook_OnEnter(TeleporterInteraction_ChargingState_OnEnter);
			ChargedState.OnEnter += new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter);
			Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ChargingState.OnEnter -= new hook_OnEnter(TeleporterInteraction_ChargingState_OnEnter);
			ChargedState.OnEnter -= new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter);
			Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
		}

		private void TeleporterInteraction_ChargingState_OnEnter(orig_OnEnter orig, ChargingState self)
		{
			orig.Invoke(self);
			base.IsActive = true;
			if (PluginConfig.RespawnOnTPStart.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			if (PluginConfig.BlockTimedRespawnOnTPEvent.Value)
			{
				RequestTimedRespawnBlock();
				if (PluginConfig.UseTimedRespawn.Value)
				{
					ChatHelper.RespawnBlockedOnTPEvent();
				}
			}
		}

		private void TeleporterInteraction_ChargedState_OnEnter(orig_OnEnter orig, ChargedState self)
		{
			orig.Invoke(self);
			if (PluginConfig.BlockTimedRespawnOnTPEvent.Value)
			{
				RequestTimedRespawnUnblock();
			}
			if (PluginConfig.RespawnOnTPEnd.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			base.IsActive = false;
		}

		private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene)
		{
			orig.Invoke(self, nextScene);
			base.IsActive = false;
		}

		public override bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionAroundTeleporter(body, 0.5f, 3f);
			if (transform.position != Vector3.zero)
			{
				outRespawnTransform = transform;
				return true;
			}
			PlayerRespawnSystemPlugin.Log.LogDebug((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
			outRespawnTransform = null;
			return false;
		}
	}
	[AssociatedRespawnType(RespawnType.Timed)]
	internal class TimedRespawnController : RespawnController
	{
		private MultiUserTimers userRespawnTimers;

		public new static bool IsEnabled => PluginConfig.UseTimedRespawn.Value;

		public IReadOnlyDictionary<NetworkUserId, UserTimer> UserRespawnTimers => userRespawnTimers.UserTimers;

		public void StartRespawnTimer(NetworkUser user)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (base.IsActive && Object.op_Implicit((Object)(object)user) && playerRespawner.CheckIfControllerCanRespawn(this, user))
			{
				uint respawnTime = RespawnTimeCalculation.GetRespawnTime();
				userRespawnTimers.StartTimer(user.id, respawnTime);
				ChatHelper.UserWillRespawnAfter(user.userName, respawnTime);
			}
		}

		public void ResetRespawnTimer(NetworkUser user)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)user))
			{
				userRespawnTimers.ResetTimer(user.id);
			}
		}

		public void StopAllRespawnTimers()
		{
			userRespawnTimers.StopTimers();
			base.IsActive = false;
		}

		public void ResumeAllRespawnTimers(bool forceResume = false)
		{
			if (forceResume || !CheckIfCurrentStageIsIgnoredForTimedRespawn())
			{
				userRespawnTimers.ResumeTimers();
				base.IsActive = true;
			}
		}

		public void ResetAllRespawnTimers()
		{
			userRespawnTimers.ResetTimers();
		}

		public void Awake()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			base.IsActive = true;
			userRespawnTimers = ((Component)this).gameObject.AddComponent<MultiUserTimers>();
			userRespawnTimers.OnUserTimerEndInFiveSeconds += UserRespawnTimers_OnUserTimerEndInFiveSeconds;
			userRespawnTimers.OnUserTimerEnd += UsersRespawnTimers_OnUserTimerRespawnTimerEnd;
			Run.OnUserAdded += new hook_OnUserAdded(Run_OnUserAdded);
			Run.OnUserRemoved += new hook_OnUserRemoved(Run_OnUserRemoved);
			Run.BeginGameOver += new hook_BeginGameOver(Run_BeginGameOver);
			Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
			PlayerCharacterMasterController.OnBodyDeath += new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
			CharacterMaster.Respawn += new hook_Respawn(CharacterMaster_Respawn);
			Run.OnServerSceneChanged += new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
			Stage.BeginAdvanceStage += new hook_BeginAdvanceStage(Stage_BeginAdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			userRespawnTimers.OnUserTimerEndInFiveSeconds -= UserRespawnTimers_OnUserTimerEndInFiveSeconds;
			userRespawnTimers.OnUserTimerEnd -= UsersRespawnTimers_OnUserTimerRespawnTimerEnd;
			Object.Destroy((Object)(object)userRespawnTimers);
			Run.OnUserAdded -= new hook_OnUserAdded(Run_OnUserAdded);
			Run.OnUserRemoved -= new hook_OnUserRemoved(Run_OnUserRemoved);
			Run.BeginGameOver -= new hook_BeginGameOver(Run_BeginGameOver);
			Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy);
			PlayerCharacterMasterController.OnBodyDeath -= new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
			CharacterMaster.Respawn -= new hook_Respawn(CharacterMaster_Respawn);
			Run.OnServerSceneChanged -= new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
			Stage.BeginAdvanceStage -= new hook_BeginAdvanceStage(Stage_BeginAdvanceStage);
		}

		private void UserRespawnTimers_OnUserTimerEndInFiveSeconds(NetworkUser user)
		{
			ChatHelper.UserWillRespawnAfter(user.userName, 5u);
		}

		private void UsersRespawnTimers_OnUserTimerRespawnTimerEnd(NetworkUser user)
		{
			playerRespawner.RespawnUser(this, user);
		}

		private void Run_OnUserAdded(orig_OnUserAdded orig, Run self, NetworkUser user)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, user);
			userRespawnTimers.AddTimer(user.id);
		}

		private void Run_OnUserRemoved(orig_OnUserRemoved orig, Run self, NetworkUser user)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, user);
			userRespawnTimers.RemoveTimer(user.id);
		}

		private void Run_BeginGameOver(orig_BeginGameOver orig, Run self, GameEndingDef gameEndingDef)
		{
			orig.Invoke(self, gameEndingDef);
			userRespawnTimers.ClearTimers();
		}

		private void Run_OnDestroy(orig_OnDestroy orig, Run self)
		{
			orig.Invoke(self);
			userRespawnTimers.ClearTimers();
		}

		private void PlayerCharacterMasterController_OnBodyDeath(orig_OnBodyDeath orig, PlayerCharacterMasterController self)
		{
			orig.Invoke(self);
			NetworkUser user = UsersHelper.GetUser(self.master);
			if (Object.op_Implicit((Object)(object)user))
			{
				StartRespawnTimer(user);
			}
		}

		private CharacterBody CharacterMaster_Respawn(orig_Respawn orig, CharacterMaster self, Vector3 footPosition, Quaternion rotation, bool wasRevivedMidStage)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser user = UsersHelper.GetUser(self);
			if (Object.op_Implicit((Object)(object)user))
			{
				ResetRespawnTimer(user);
			}
			return orig.Invoke(self, footPosition, rotation, wasRevivedMidStage);
		}

		private void Run_OnServerSceneChanged(orig_OnServerSceneChanged orig, Run self, string sceneName)
		{
			orig.Invoke(self, sceneName);
			ResetAllRespawnTimers();
			ResumeAllRespawnTimers();
			if (CheckIfCurrentStageIsIgnoredForTimedRespawn())
			{
				StopAllRespawnTimers();
				ChatHelper.TimedRespawnBlockedOnStage();
			}
		}

		private void Stage_BeginAdvanceStage(orig_BeginAdvanceStage orig, Stage self, SceneDef destinationStage)
		{
			orig.Invoke(self, destinationStage);
			ResetAllRespawnTimers();
			ResumeAllRespawnTimers();
		}

		private bool CheckIfCurrentStageIsIgnoredForTimedRespawn()
		{
			return PluginConfig.IgnoredMapsForTimedRespawn.Value.Contains(SceneCatalog.GetSceneDefForCurrentScene().baseSceneName);
		}

		public override bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			foreach (RespawnType value2 in Enum.GetValues(typeof(RespawnType)))
			{
				if (value2 != 0 && PlayerRespawnSystem.instance.RespawnControllers.TryGetValue(value2, out var value) && value.IsActive)
				{
					PlayerRespawnSystemPlugin.Log.LogDebug((object)$"Timed respawn using {value.GetRespawnType()} respawn position");
					return value.GetRespawnTransform(body, out outRespawnTransform);
				}
			}
			PlayerRespawnSystemPlugin.Log.LogDebug((object)"Timed respawn using default respawn position");
			return base.GetRespawnTransform(body, out outRespawnTransform);
		}
	}
	[AssociatedRespawnType(RespawnType.Voidling)]
	internal class VoidlingRespawnController : RespawnController
	{
		public new static bool IsEnabled => true;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ScriptedCombatEncounter.BeginEncounter += new hook_BeginEncounter(ScriptedCombatEncounter_BeginEncounter);
			VoidRaidGauntletController.SpawnOutroPortal += new hook_SpawnOutroPortal(VoidRaidGauntletController_SpawnOutroPortal);
			Run.AdvanceStage += new hook_AdvanceStage(Run_AdvanceStage);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ScriptedCombatEncounter.BeginEncounter -= new hook_BeginEncounter(ScriptedCombatEncounter_BeginEncounter);
			VoidRaidGauntletController.SpawnOutroPortal -= new hook_SpawnOutroPortal(VoidRaidGauntletController_SpawnOutroPortal);
			Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
		}

		private void ScriptedCombatEncounter_BeginEncounter(orig_BeginEncounter orig, ScriptedCombatEncounter self)
		{
			orig.Invoke(self);
			if (!base.IsActive && !(SceneCatalog.GetSceneDefForCurrentScene().baseSceneName.ToLower() != "voidraid"))
			{
				base.IsActive = true;
				if (PluginConfig.RespawnOnVoidlingStart.Value)
				{
					playerRespawner.RespawnAllUsers(this);
				}
				if (PluginConfig.BlockTimedRespawnOnVoidlingFight.Value)
				{
					RequestTimedRespawnBlock();
				}
			}
		}

		private void VoidRaidGauntletController_SpawnOutroPortal(orig_SpawnOutroPortal orig, VoidRaidGauntletController self)
		{
			orig.Invoke(self);
			if (PluginConfig.BlockTimedRespawnOnVoidlingFight.Value)
			{
				RequestTimedRespawnUnblock();
			}
			if (PluginConfig.RespawnOnVoidlingEnd.Value)
			{
				playerRespawner.RespawnAllUsers(this);
			}
			base.IsActive = false;
		}

		private void Run_AdvanceStage(orig_AdvanceStage orig, Run self, SceneDef nextScene)
		{
			orig.Invoke(self, nextScene);
			base.IsActive = false;
		}

		public override bool GetRespawnTransform(CharacterBody body, out Transform outRespawnTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionForVoidBoss();
			if (transform.position != Vector3.zero)
			{
				outRespawnTransform = transform;
				return true;
			}
			PlayerRespawnSystemPlugin.Log.LogDebug((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
			outRespawnTransform = null;
			return false;
		}
	}
	internal class PlayerUIRpcProxy : NetworkBehaviour
	{
		private static int kTargetRpcTargetUpdateDeathTimer;

		[TargetRpc]
		public void TargetUpdateDeathTimer(NetworkConnection target, float respawnTime, bool canRespawn, bool canTimedRespawn, RespawnType activeRespawnType)
		{
			UIDeathTimerClient instance = UIDeathTimerClient.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				PlayerRespawnSystemPlugin.Log.LogWarning((object)"[ClientRPC] Could not find singleton panel, exiting");
			}
			else
			{
				instance.UpdateDeathTimer(respawnTime, canRespawn, canTimedRespawn, activeRespawnType);
			}
		}

		private void UNetVersion()
		{
		}

		protected static void InvokeRpcTargetUpdateDeathTimer(NetworkBehaviour obj, NetworkReader reader)
		{
			if (!NetworkClient.active)
			{
				Debug.LogError((object)"TargetRPC TargetUpdateDeathTimer called on server.");
			}
			else
			{
				((PlayerUIRpcProxy)(object)obj).TargetUpdateDeathTimer(ClientScene.readyConnection, reader.ReadSingle(), reader.ReadBoolean(), reader.ReadBoolean(), (RespawnType)reader.ReadInt32());
			}
		}

		public void CallTargetUpdateDeathTimer(NetworkConnection target, float respawnTime, bool canRespawn, bool canTimedRespawn, RespawnType activeRespawnType)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogError((object)"TargetRPC Function TargetUpdateDeathTimer called on client.");
				return;
			}
			if (target is ULocalConnectionToServer)
			{
				Debug.LogError((object)"TargetRPC Function TargetUpdateDeathTimer called on connection to server");
				return;
			}
			NetworkWriter val = new NetworkWriter();
			val.Write((short)0);
			val.Write((short)2);
			val.WritePackedUInt32((uint)kTargetRpcTargetUpdateDeathTimer);
			val.Write(((Component)this).GetComponent<NetworkIdentity>().netId);
			val.Write(respawnTime);
			val.Write(canRespawn);
			val.Write(canTimedRespawn);
			val.Write((int)activeRespawnType);
			((NetworkBehaviour)this).SendTargetRPCInternal(target, val, 0, "TargetUpdateDeathTimer");
		}

		static PlayerUIRpcProxy()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			kTargetRpcTargetUpdateDeathTimer = 444689005;
			NetworkBehaviour.RegisterRpcDelegate(typeof(PlayerUIRpcProxy), kTargetRpcTargetUpdateDeathTimer, new CmdDelegate(InvokeRpcTargetUpdateDeathTimer));
			NetworkCRC.RegisterBehaviour("PlayerUIRpcProxy", 0);
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			bool result = default(bool);
			return result;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
		}
	}
	internal class UIDeathTimerClient : MonoBehaviour
	{
		private UIDeathTimerPanel deathTimerPanel;

		public static UIDeathTimerClient instance { get; private set; }

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			HUD.Awake += new hook_Awake(HUD_Awake);
			Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
			instance = SingletonHelper.Assign<UIDeathTimerClient>(instance, this);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			HUD.Awake -= new hook_Awake(HUD_Awake);
			Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy);
			instance = SingletonHelper.Unassign<UIDeathTimerClient>(instance, this);
		}

		private void HUD_Awake(orig_Awake orig, HUD self)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			orig.Invoke(self);
			GameObject val = new GameObject("death_timer_box");
			val.transform.SetParent(self.mainContainer.transform, false);
			val.transform.SetAsFirstSibling();
			deathTimerPanel = val.AddComponent<UIDeathTimerPanel>();
		}

		private void Run_OnDestroy(orig_OnDestroy orig, Run self)
		{
			orig.Invoke(self);
			Object.Destroy((Object)(object)deathTimerPanel);
		}

		public void UpdateDeathTimer(float respawnTime, bool canRespawn, bool canTimedRespawn, RespawnType activeRespawnType)
		{
			if (!Object.op_Implicit((Object)(object)deathTimerPanel) || !PluginConfig.UseDeathTimerUI.Value)
			{
				PlayerRespawnSystemPlugin.Log.LogWarning((object)"[Client] deathTimerPanel cannot be updated");
			}
			else if (canRespawn)
			{
				if (canTimedRespawn)
				{
					((TMP_Text)deathTimerPanel.textContext2).text = $"in <color=red>{Mathf.CeilToInt(respawnTime)}</color> seconds";
					deathTimerPanel.show = true;
					return;
				}
				switch (activeRespawnType)
				{
				case RespawnType.Teleporter:
					if (PluginConfig.RespawnOnTPEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>teleporter</color> event";
						deathTimerPanel.show = true;
					}
					break;
				case RespawnType.Mithrix:
					if (PluginConfig.RespawnOnMithrixEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>Mithrix</color> fight";
						deathTimerPanel.show = true;
					}
					break;
				case RespawnType.Artifact:
					if (PluginConfig.RespawnOnArtifactTrialEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>artifact trial</color> ends";
						deathTimerPanel.show = true;
					}
					break;
				default:
					deathTimerPanel.show = false;
					break;
				}
			}
			else
			{
				deathTimerPanel.show = false;
			}
		}
	}
	internal class UIDeathTimerController : NetworkBehaviour
	{
		private UIDeathTimerPanel deathTimerPanel;

		public readonly float UpdateUIEveryXSeconds = 0.5f;

		private float deltaCount;

		private static int kCmdCmdUpdateAllDeathTimers;

		private static int kTargetRpcTargetUpdateDeathTimer;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			HUD.Awake += new hook_Awake(HUD_Awake);
			Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			HUD.Awake -= new hook_Awake(HUD_Awake);
			Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy);
		}

		private void HUD_Awake(orig_Awake orig, HUD self)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			orig.Invoke(self);
			GameObject val = new GameObject("death_timer_box");
			val.transform.SetParent(self.mainContainer.transform);
			val.transform.SetAsFirstSibling();
			deathTimerPanel = val.AddComponent<UIDeathTimerPanel>();
		}

		private void Run_OnDestroy(orig_OnDestroy orig, Run self)
		{
			orig.Invoke(self);
			Object.Destroy((Object)(object)deathTimerPanel);
		}

		public void Update()
		{
			if (NetworkServer.active && ((NetworkBehaviour)this).hasAuthority)
			{
				deltaCount += Time.deltaTime;
				if (deltaCount >= UpdateUIEveryXSeconds)
				{
					CallCmdUpdateAllDeathTimers();
					deltaCount = 0f;
				}
			}
		}

		[Command]
		public void CmdUpdateAllDeathTimers()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)PlayerRespawnSystem.instance) || !PlayerRespawnSystem.instance.RespawnControllers.ContainsKey(RespawnType.Timed))
			{
				return;
			}
			RespawnType activeRespawnType = RespawnType.Timed;
			TimedRespawnController timedRespawnController = null;
			foreach (var (respawnType2, respawnController2) in PlayerRespawnSystem.instance.RespawnControllers)
			{
				if (respawnController2 is TimedRespawnController)
				{
					timedRespawnController = respawnController2 as TimedRespawnController;
				}
				else if (respawnController2.IsActive)
				{
					activeRespawnType = respawnType2;
				}
			}
			if (!Object.op_Implicit((Object)(object)timedRespawnController))
			{
				return;
			}
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if (timedRespawnController.UserRespawnTimers.TryGetValue(readOnlyInstances.id, out var value))
				{
					float timeRemaining = value.TimeRemaining;
					bool flag = PlayerRespawnSystem.instance.CheckIfUserCanBeRespawned(readOnlyInstances);
					bool canTimedRespawn = flag && timedRespawnController.IsActive;
					CallTargetUpdateDeathTimer(((NetworkBehaviour)readOnlyInstances).connectionToClient, timeRemaining, flag, canTimedRespawn, activeRespawnType);
				}
			}
		}

		[TargetRpc]
		public void TargetUpdateDeathTimer(NetworkConnection target, float respawnTime, bool canRespawn, bool canTimedRespawn, RespawnType activeRespawnType)
		{
			if (!Object.op_Implicit((Object)(object)deathTimerPanel) || !PluginConfig.UseDeathTimerUI.Value)
			{
				return;
			}
			if (canRespawn)
			{
				if (canTimedRespawn)
				{
					((TMP_Text)deathTimerPanel.textContext2).text = $"in <color=red>{Mathf.CeilToInt(respawnTime)}</color> seconds";
					deathTimerPanel.show = true;
					return;
				}
				switch (activeRespawnType)
				{
				case RespawnType.Teleporter:
					if (PluginConfig.RespawnOnTPEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>teleporter</color> event";
						deathTimerPanel.show = true;
					}
					break;
				case RespawnType.Mithrix:
					if (PluginConfig.RespawnOnMithrixEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>Mithrix</color> fight";
						deathTimerPanel.show = true;
					}
					break;
				case RespawnType.Artifact:
					if (PluginConfig.RespawnOnArtifactTrialEnd.Value)
					{
						((TMP_Text)deathTimerPanel.textContext2).text = "after <color=red>artifact trial</color> ends";
						deathTimerPanel.show = true;
					}
					break;
				default:
					deathTimerPanel.show = false;
					break;
				}
			}
			else
			{
				deathTimerPanel.show = false;
			}
		}

		private void UNetVersion()
		{
		}

		protected static void InvokeCmdCmdUpdateAllDeathTimers(NetworkBehaviour obj, NetworkReader reader)
		{
			if (!NetworkServer.active)
			{
				Debug.LogError((object)"Command CmdUpdateAllDeathTimers called on client.");
			}
			else
			{
				((UIDeathTimerController)(object)obj).CmdUpdateAllDeathTimers();
			}
		}

		public void CallCmdUpdateAllDeathTimers()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				Debug.LogError((object)"Command function CmdUpdateAllDeathTimers called on server.");
				return;
			}
			if (((NetworkBehaviour)this).isServer)
			{
				CmdUpdateAllDeathTimers();
				return;
			}
			NetworkWriter val = new NetworkWriter();
			val.Write((short)0);
			val.Write((short)5);
			val.WritePackedUInt32((uint)kCmdCmdUpdateAllDeathTimers);
			val.Write(((Component)this).GetComponent<NetworkIdentity>().netId);
			((NetworkBehaviour)this).SendCommandInternal(val, 0, "CmdUpdateAllDeathTimers");
		}

		protected static void InvokeRpcTargetUpdateDeathTimer(NetworkBehaviour obj, NetworkReader reader)
		{
			if (!NetworkClient.active)
			{
				Debug.LogError((object)"TargetRPC TargetUpdateDeathTimer called on server.");
			}
			else
			{
				((UIDeathTimerController)(object)obj).TargetUpdateDeathTimer(ClientScene.readyConnection, reader.ReadSingle(), reader.ReadBoolean(), reader.ReadBoolean(), (RespawnType)reader.ReadInt32());
			}
		}

		public void CallTargetUpdateDeathTimer(NetworkConnection target, float respawnTime, bool canRespawn, bool canTimedRespawn, RespawnType activeRespawnType)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				Debug.LogError((object)"TargetRPC Function TargetUpdateDeathTimer called on client.");
				return;
			}
			if (target is ULocalConnectionToServer)
			{
				Debug.LogError((object)"TargetRPC Function TargetUpdateDeathTimer called on connection to server");
				return;
			}
			NetworkWriter val = new NetworkWriter();
			val.Write((short)0);
			val.Write((short)2);
			val.WritePackedUInt32((uint)kTargetRpcTargetUpdateDeathTimer);
			val.Write(((Component)this).GetComponent<NetworkIdentity>().netId);
			val.Write(respawnTime);
			val.Write(canRespawn);
			val.Write(canTimedRespawn);
			val.Write((int)activeRespawnType);
			((NetworkBehaviour)this).SendTargetRPCInternal(target, val, 0, "TargetUpdateDeathTimer");
		}

		static UIDeathTimerController()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			kCmdCmdUpdateAllDeathTimers = -1371328405;
			NetworkBehaviour.RegisterCommandDelegate(typeof(UIDeathTimerController), kCmdCmdUpdateAllDeathTimers, new CmdDelegate(InvokeCmdCmdUpdateAllDeathTimers));
			kTargetRpcTargetUpdateDeathTimer = -1544614294;
			NetworkBehaviour.RegisterRpcDelegate(typeof(UIDeathTimerController), kTargetRpcTargetUpdateDeathTimer, new CmdDelegate(InvokeRpcTargetUpdateDeathTimer));
			NetworkCRC.RegisterBehaviour("UIDeathTimerController", 0);
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			bool result = default(bool);
			return result;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
		}
	}
	internal class UIDeathTimerPanel : MonoBehaviour
	{
		public RectTransform rectTransform;

		public RectTransform colorRectTransform;

		public HGTextMeshProUGUI textContext1;

		public HGTextMeshProUGUI textContext2;

		public bool show;

		private float fontSize = 30f;

		private float showSpeed = 0.05f;

		private float hideSpeed = 0.1f;

		public void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00af: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			rectTransform = ((Component)this).gameObject.AddComponent<RectTransform>();
			rectTransform.anchorMin = Vector2.one / 2f;
			rectTransform.anchorMax = Vector2.one / 2f;
			rectTransform.pivot = Vector2.one / 2f;
			((Transform)rectTransform).localPosition = Vector3.zero;
			((Transform)rectTransform).position = Vector3.zero;
			rectTransform.sizeDelta = new Vector2(300f, 60f);
			((Transform)rectTransform).localScale = Vector3.one;
			GameObject val = new GameObject();
			val.transform.SetParent(((Component)this).transform);
			colorRectTransform = val.AddComponent<RectTransform>();
			Image obj = val.AddComponent<Image>();
			((Transform)((Graphic)obj).rectTransform).localPosition = Vector3.zero;
			((Graphic)obj).rectTransform.anchorMin = Vector2.zero;
			((Graphic)obj).rectTransform.anchorMax = Vector2.one;
			((Graphic)obj).rectTransform.pivot = Vector2.one / 2f;
			((Graphic)obj).color = new Color(0f, 0f, 0f, 0.5f);
			GameObject val2 = new GameObject();
			val2.transform.SetParent(((Component)this).transform);
			textContext1 = val2.AddComponent<HGTextMeshProUGUI>();
			((Transform)((TMP_Text)textContext1).rectTransform).localPosition = Vector3.zero;
			((TMP_Text)textContext1).rectTransform.anchorMin = Vector2.zero;
			((TMP_Text)textContext1).rectTransform.anchorMax = Vector2.one;
			((TMP_Text)textContext1).rectTransform.pivot = Vector2.one / 2f;
			((TMP_Text)textContext1).enableAutoSizing = false;
			((TMP_Text)textContext1).fontSizeMax = fontSize;
			((Graphic)textContext1).color = Color.white;
			((TMP_Text)textContext1).alignment = (TextAlignmentOptions)258;
			((TMP_Text)textContext1).text = "You will respawn";
			GameObject val3 = new GameObject();
			val3.transform.SetParent(((Component)this).transform);
			textContext2 = val3.AddComponent<HGTextMeshProUGUI>();
			((Transform)((TMP_Text)textContext2).rectTransform).localPosition = Vector3.zero;
			((TMP_Text)textContext2).rectTransform.anchorMin = Vector2.zero;
			((TMP_Text)textContext2).rectTransform.anchorMax = Vector2.one;
			((TMP_Text)textContext2).rectTransform.pivot = Vector2.one / 2f;
			((TMP_Text)textContext2).enableAutoSizing = false;
			((TMP_Text)textContext2).fontSizeMax = fontSize;
			((Graphic)textContext2).color = Color.white;
			((TMP_Text)textContext2).alignment = (TextAlignmentOptions)4098;
			((TMP_Text)textContext2).text = "in x seconds";
		}

		public void OnEnable()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchoredPosition = new Vector2(0f, 100f);
		}

		public void FixedUpdate()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			if (show && ((TMP_Text)textContext1).fontSize != fontSize && ((TMP_Text)textContext2).fontSize != fontSize && ((Transform)colorRectTransform).localScale != Vector3.one)
			{
				((TMP_Text)textContext1).fontSize = Mathf.Lerp(((TMP_Text)textContext1).fontSize, fontSize, showSpeed);
				((TMP_Text)textContext2).fontSize = Mathf.Lerp(((TMP_Text)textContext2).fontSize, fontSize, showSpeed);
				((Transform)colorRectTransform).localScale = Vector2.op_Implicit(Vector2.Lerp(Vector2.op_Implicit(((Transform)colorRectTransform).localScale), Vector2.op_Implicit(Vector3.one), showSpeed));
			}
			else if (!show && ((TMP_Text)textContext1).fontSize != 0f && ((TMP_Text)textContext2).fontSize != 0f && ((Transform)colorRectTransform).localScale != Vector3.up)
			{
				((TMP_Text)textContext1).fontSize = Mathf.Lerp(((TMP_Text)textContext1).fontSize, 0f, hideSpeed);
				((TMP_Text)textContext2).fontSize = Mathf.Lerp(((TMP_Text)textContext2).fontSize, 0f, hideSpeed);
				((Transform)colorRectTransform).localScale = Vector2.op_Implicit(Vector2.Lerp(Vector2.op_Implicit(((Transform)colorRectTransform).localScale), Vector2.op_Implicit(Vector3.up), hideSpeed));
			}
		}
	}
	internal class UIDeathTimerServer : NetworkBehaviour
	{
		public readonly float UpdateUIEveryXSeconds = 0.5f;

		[ServerCallback]
		public void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (NetworkServer.active)
			{
				Run.Start += new hook_Start(Run_OnStart);
				Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
			}
		}

		[ServerCallback]
		public void OnDestroy()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (NetworkServer.active)
			{
				Run.Start -= new hook_Start(Run_OnStart);
				Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy);
			}
		}

		public void Run_OnStart(orig_Start orig, Run self)
		{
			orig.Invoke(self);
			((MonoBehaviour)this).InvokeRepeating("UpdateAllDeathTimers", 2f, UpdateUIEveryXSeconds);
		}

		private void Run_OnDestroy(orig_OnDestroy orig, Run self)
		{
			orig.Invoke(self);
			((MonoBehaviour)this).CancelInvoke("UpdateAllDeathTimers");
		}

		public void UpdateAllDeathTimers()
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)PlayerRespawnSystem.instance) || !PlayerRespawnSystem.instance.RespawnControllers.ContainsKey(RespawnType.Timed))
			{
				return;
			}
			RespawnType activeRespawnType = RespawnType.Timed;
			TimedRespawnController timedRespawnController = null;
			foreach (var (respawnType2, respawnController2) in PlayerRespawnSystem.instance.RespawnControllers)
			{
				if (respawnController2 is TimedRespawnController)
				{
					timedRespawnController = respawnController2 as TimedRespawnController;
				}
				else if (respawnController2.IsActive)
				{
					activeRespawnType = respawnType2;
				}
			}
			if (!Object.op_Implicit((Object)(object)timedRespawnController))
			{
				return;
			}
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				NetworkConnection connectionToClient = ((NetworkBehaviour)readOnlyInstances).connectionToClient;
				if (connectionToClient != null && connectionToClient.isReady && timedRespawnController.UserRespawnTimers.TryGetValue(readOnlyInstances.id, out var value))
				{
					float timeRemaining = value.TimeRemaining;
					bool flag = PlayerRespawnSystem.instance.CheckIfUserCanBeRespawned(readOnlyInstances);
					bool canTimedRespawn = flag && timedRespawnController.IsActive;
					((Component)readOnlyInstances).GetComponent<PlayerUIRpcProxy>().CallTargetUpdateDeathTimer(connectionToClient, timeRemaining, flag, canTimedRespawn, activeRespawnType);
				}
			}
		}

		private void UNetVersion()
		{
		}

		public override bool OnSerialize(NetworkWriter writer, bool forceAll)
		{
			bool result = default(bool);
			return result;
		}

		public override void OnDeserialize(NetworkReader reader, bool initialState)
		{
		}
	}
	internal class MultiUserTimers : MonoBehaviour
	{
		public delegate void UserTimerEndInFiveSeconds(NetworkUser user);

		public delegate void UserTimerEnd(NetworkUser user);

		private Dictionary<NetworkUserId, UserTimer> userTimers = new Dictionary<NetworkUserId, UserTimer>();

		public IReadOnlyDictionary<NetworkUserId, UserTimer> UserTimers => userTimers;

		public event UserTimerEndInFiveSeconds OnUserTimerEndInFiveSeconds;

		public event UserTimerEnd OnUserTimerEnd;

		public void OnDestroy()
		{
			ClearTimers();
		}

		public void StartTimer(NetworkUserId userId, uint time)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (userTimers.TryGetValue(userId, out var value))
			{
				value.StartTimer(time);
			}
		}

		public void ResetTimer(NetworkUserId userId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (userTimers.TryGetValue(userId, out var value))
			{
				value.Reset();
			}
		}

		public void StopTimers()
		{
			foreach (UserTimer value in userTimers.Values)
			{
				value.Stop();
			}
		}

		public void ResumeTimers()
		{
			foreach (UserTimer value in userTimers.Values)
			{
				value.Resume();
			}
		}

		public void ResetTimers()
		{
			foreach (UserTimer value in userTimers.Values)
			{
				value.Reset();
			}
		}

		public void ClearTimers()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			foreach (NetworkUserId item in new List<NetworkUserId>(userTimers.Keys))
			{
				RemoveTimer(item);
			}
		}

		public void AddTimer(NetworkUserId userId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!userTimers.ContainsKey(userId))
			{
				userTimers[userId] = ((Component)this).gameObject.AddComponent<UserTimer>();
				userTimers[userId].UserId = userId;
				userTimers[userId].OnTimerEndInFiveSeconds += UserTimer_OnTimerEndInFiveSeconds;
				userTimers[userId].OnTimerEnd += UserTimer_OnTimerEnd;
			}
		}

		public void RemoveTimer(NetworkUserId userId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (userTimers.TryGetValue(userId, out var value))
			{
				value.OnTimerEndInFiveSeconds -= UserTimer_OnTimerEndInFiveSeconds;
				value.OnTimerEnd -= UserTimer_OnTimerEnd;
				Object.DestroyImmediate((Object)(object)userTimers[userId]);
				userTimers.Remove(userId);
			}
		}

		private void UserTimer_OnTimerEndInFiveSeconds(NetworkUserId userId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser user = UsersHelper.GetUser(userId);
			if (Object.op_Implicit((Object)(object)user))
			{
				this.OnUserTimerEndInFiveSeconds?.Invoke(user);
			}
		}

		private void UserTimer_OnTimerEnd(NetworkUserId userId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser user = UsersHelper.GetUser(userId);
			if (Object.op_Implicit((Object)(object)user))
			{
				this.OnUserTimerEnd?.Invoke(user);
			}
		}
	}
	internal class UserTimer : MonoBehaviour
	{
		public delegate void TimerEndInFiveSeconds(NetworkUserId userId);

		public delegate void TimerEnd(NetworkUserId userId);

		private bool hasTimerEndInFiveSecondsFired;

		public NetworkUserId UserId { get; set; }

		public float TimeRemaining { get; private set; }

		public bool IsRunning { get; private set; }

		public event TimerEndInFiveSeconds OnTimerEndInFiveSeconds;

		public event TimerEnd OnTimerEnd;

		public UserTimer(NetworkUserId userId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			UserId = userId;
		}

		public void StartTimer(float time)
		{
			TimeRemaining = time;
			hasTimerEndInFiveSecondsFired = false;
			IsRunning = true;
		}

		public void Reset()
		{
			IsRunning = false;
			TimeRemaining = 0f;
		}

		public void Stop()
		{
			if (TimeRemaining > 0f)
			{
				IsRunning = false;
			}
		}

		public void Resume()
		{
			if (TimeRemaining > 0f)
			{
				IsRunning = true;
			}
		}

		public void Update()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsRunning)
			{
				return;
			}
			if (TimeRemaining > 0f)
			{
				TimeRemaining -= Time.deltaTime;
				if (TimeRemaining <= 5f && !hasTimerEndInFiveSecondsFired)
				{
					hasTimerEndInFiveSecondsFired = true;
					this.OnTimerEndInFiveSeconds?.Invoke(UserId);
				}
			}
			else
			{
				Reset();
				this.OnTimerEnd?.Invoke(UserId);
			}
		}
	}
	[BepInPlugin("com.eviegc.PlayerRespawnSystem", "PlayerRespawnSystem", "2.1.5")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PlayerRespawnSystemPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private PlayerRespawnSystem playerRespawnSystem;

		private GameObject uiDeathTimerServer;

		private GameObject uiDeathTimerClient;

		public PlayerRespawnSystemPlugin()
		{
			InitConfig();
		}

		public void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			NetworkUser.OnEnable += new hook_OnEnable(NetworkUser_OnEnable);
			Run.Awake += new hook_Awake(Run_Awake);
			Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
		}

		private void NetworkUser_OnEnable(orig_OnEnable orig, NetworkUser self)
		{
			orig.Invoke(self);
			((BaseUnityPlugin)this).Logger.LogDebug((object)"[Client] Adding PlayerUIRpcProxy component to NetworkUser");
			if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<PlayerUIRpcProxy>()))
			{
				((Component)self).gameObject.AddComponent<PlayerUIRpcProxy>();
			}
		}

		private void Run_Awake(orig_Awake orig, Run self)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			orig.Invoke(self);
			if (!PluginConfig.IgnoredGameModes.Value.Contains(GameModeCatalog.GetGameModeName(self.gameModeIndex)))
			{
				if (NetworkClient.active)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)"[Client] Creating UIDeathTimerClient");
					uiDeathTimerClient = new GameObject("death_timer_client");
					uiDeathTimerClient.transform.SetParent(((Component)self).transform, false);
					uiDeathTimerClient.AddComponent<UIDeathTimerClient>();
				}
				if (NetworkServer.active)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)"[Server] Creating PlayerRespawnSystem");
					playerRespawnSystem = ((Component)this).gameObject.AddComponent<PlayerRespawnSystem>();
					((BaseUnityPlugin)this).Logger.LogDebug((object)"[Server] Creating UIDeathTimerServer");
					uiDeathTimerServer = new GameObject("death_timer_server");
					uiDeathTimerServer.transform.SetParent(((Component)self).transform, false);
					uiDeathTimerServer.AddComponent<UIDeathTimerServer>();
					uiDeathTimerServer.SetActive(true);
				}
			}
		}

		private void Run_OnDestroy(orig_OnDestroy orig, Run self)
		{
			orig.Invoke(self);
			if (Object.op_Implicit((Object)(object)uiDeathTimerServer))
			{
				Object.Destroy((Object)(object)uiDeathTimerServer);
			}
			if (Object.op_Implicit((Object)(object)uiDeathTimerClient))
			{
				Object.Destroy((Object)(object)uiDeathTimerClient);
			}
			if (Object.op_Implicit((Object)(object)playerRespawnSystem))
			{
				Object.Destroy((Object)(object)playerRespawnSystem);
			}
		}

		private void InitConfig()
		{
			PluginConfig.IgnoredMapsForTimedRespawn = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "IgnoredMapsForTimedRespawn", "bazaar,arena,goldshores,moon,moon2,artifactworld,mysteryspace,limbo,voidraid,meridian", "Maps on which respawning is ignored.");
			PluginConfig.IgnoredGameModes = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "IgnoredGameModes", "InfiniteTowerRun", "Gamemode in which respawning should not work.");
			PluginConfig.RespawnTimeType = ((BaseUnityPlugin)this).Config.Bind<RespawnTimeType>("Settings", "RespawnTimeType", RespawnTimeType.StageTimeBased, "Type of time to consider when calculating respawn time.");
			PluginConfig.StartingRespawnTime = ((BaseUnityPlugin)this).Config.Bind<uint>("Settings", "StartingRespawnTime", 30u, "Starting respawn time.");
			PluginConfig.MaxRespawnTime = ((BaseUnityPlugin)this).Config.Bind<uint>("Settings", "MaxRespawnTime", 180u, "Max respawn time.");
			PluginConfig.UpdateCurrentRepsawnTimeByXSeconds = ((BaseUnityPlugin)this).Config.Bind<uint>("Settings", "UpdateCurrentRepsawnTimeByXSeconds", 5u, "Value by which current respawn time is updated every UpdateCurrentRespawnTimeEveryXSeconds.");
			PluginConfig.UpdateCurrentRespawnTimeEveryXSeconds = ((BaseUnityPlugin)this).Config.Bind<uint>("Settings", "UpdateCurrentRespawnTimeEveryXSeconds", 10u, "Time interval between updates of the UpdateCurrentRepsawnTimeByXSeconds.");
			PluginConfig.UsePodsOnStartOfMatch = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "UsePodsOnStartOfMatch", false, "Should players spawn from pods on start of match.");
			PluginConfig.UseDeathTimerUI = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "UseDeathTimerUI", true, "Should UI death timer show up for you on death.");
			PluginConfig.UseTimedRespawn = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "UseTimedRespawn", true, "Should players be respawned on timed based system.");
			PluginConfig.BlockTimedRespawnOnTPEvent = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "BlockTimedRespawnOnTPEvent", true, "Should players be blocked from respawning after teleporter event is started.");
			PluginConfig.RespawnOnTPStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnTPStart", true, "Should players be respawned on start of teleporter event (regardless of BlockSpawningOnTPEvent).");
			PluginConfig.RespawnOnTPEnd = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnTPEnd", true, "Should players be respawned on end of teleporter event (regardless of BlockSpawningOnTPEvent).");
			PluginConfig.BlockTimedRespawnOnMithrixFight = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "BlockTimedRespawnOnMithrixFight", true, "Should players be blocked from respawning after Mithrix fight is started.");
			PluginConfig.RespawnOnMithrixStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnMithrixStart", true, "Should players be respawned on start of Mithrix fight (regardless of BlockRespawningOnMithrixFight or map being ignored).");
			PluginConfig.RespawnOnMithrixEnd = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnMithrixEnd", false, "Should players be respawned on end of Mithrix fight (regardless of BlockRespawningOnMithrixFight or map being ignored).");
			PluginConfig.BlockTimedRespawnOnArtifactTrial = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "BlockTimedRespawnOnArtifactTrial", true, "Should players be blocked from respawning after Artifact trial is started.");
			PluginConfig.RespawnOnArtifactTrialStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnArtifactTrialStart", true, "Should players be respawned on start of Artifact trial (regardless of BlockTimedRespawningOnArtifactTrial or map being ignored).");
			PluginConfig.RespawnOnArtifactTrialEnd = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnArtifactTrialEnd", true, "Should players be respawned on end of Artifact trial (regardless of BlockTimedRespawningOnArtifactTrial or map being ignored).");
			PluginConfig.BlockTimedRespawnOnVoidlingFight = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "BlockTimedRespawnOnVoidlingFight", true, "Should players be blocked from respawning after Voidling fight is started.");
			PluginConfig.RespawnOnVoidlingStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnVoidlingStart", true, "Should players be respawned on start of Voidling fight (regardless of BlockTimedRespawnOnVoidlingFight or map being ignored).");
			PluginConfig.RespawnOnVoidlingEnd = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnVoidlingEnd", true, "Should players be respawned on end of Voidling fight (regardless of BlockTimedRespawnOnVoidlingFight or map being ignored).");
			PluginConfig.BlockTimedRespawnOnFalseSonFight = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "BlockTimedRespawnOnFalseSonFight", true, "Should players be blocked from respawning after False Son fight is started.");
			PluginConfig.RespawnOnFalseSonStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnFalseSonStart", false, "Should players be respawned on start of False Son fight (regardless of BlockTimedRespawnOnFalseSonFight or map being ignored).");
			PluginConfig.RespawnOnFalseSonEnd = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "RespawnOnFalseSonEnd", true, "Should players be respawned on end of False Son fight (regardless of BlockTimedRespawnOnFalseSonFight or map being ignored).");
		}
	}
	public static class PluginConfig
	{
		public static ConfigEntry<string> IgnoredMapsForTimedRespawn;

		public static ConfigEntry<string> IgnoredGameModes;

		public static ConfigEntry<RespawnTimeType> RespawnTimeType;

		public static ConfigEntry<uint> StartingRespawnTime;

		public static ConfigEntry<uint> MaxRespawnTime;

		public static ConfigEntry<uint> UpdateCurrentRespawnTimeEveryXSeconds;

		public static ConfigEntry<uint> UpdateCurrentRepsawnTimeByXSeconds;

		public static ConfigEntry<bool> UsePodsOnStartOfMatch;

		public static ConfigEntry<bool> UseDeathTimerUI;

		public static ConfigEntry<bool> UseTimedRespawn;

		public static ConfigEntry<bool> BlockTimedRespawnOnTPEvent;

		public static ConfigEntry<bool> RespawnOnTPStart;

		public static ConfigEntry<bool> RespawnOnTPEnd;

		public static ConfigEntry<bool> BlockTimedRespawnOnMithrixFight;

		public static ConfigEntry<bool> RespawnOnMithrixStart;

		public static ConfigEntry<bool> RespawnOnMithrixEnd;

		public static ConfigEntry<bool> BlockTimedRespawnOnArtifactTrial;

		public static ConfigEntry<bool> RespawnOnArtifactTrialStart;

		public static ConfigEntry<bool> RespawnOnArtifactTrialEnd;

		public static ConfigEntry<bool> BlockTimedRespawnOnVoidlingFight;

		public static ConfigEntry<bool> RespawnOnVoidlingStart;

		public static ConfigEntry<bool> RespawnOnVoidlingEnd;

		public static ConfigEntry<bool> BlockTimedRespawnOnFalseSonFight;

		public static ConfigEntry<bool> RespawnOnFalseSonStart;

		public static ConfigEntry<bool> RespawnOnFalseSonEnd;
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.eviegc.PlayerRespawnSystem";

		public const string PLUGIN_NAME = "PlayerRespawnSystem";

		public const string PLUGIN_VERSION = "2.1.5";
	}
}