Decompiled source of PlayerRespawnSystem v2.1.2

PlayerRespawnSystem.dll

Decompiled a month 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 BepInEx;
using BepInEx.Configuration;
using EntityStates;
using EntityStates.Missions.BrotherEncounter;
using On.EntityStates.Missions.BrotherEncounter;
using On.RoR2;
using On.RoR2.UI;
using R2API;
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+ec4c191fd338d186da88c2c14b60fdefb29d6857")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.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 : NetworkBehaviour
{
	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))
			{
				Debug.Log((object)$"PlayerRespawnSystem: 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_0062: 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))
			{
				Debug.Log((object)$"PlayerRespawnSystem: Getting respawn position for {respawnController2.GetRespawnType()} respawn");
				if (respawnController2.GetRespawnTransform(val2, out var outRespawnTransform))
				{
					Debug.Log((object)$"PlayerRespawnSystem: Found respawn position at {outRespawnTransform.position}");
					return outRespawnTransform;
				}
				Debug.Log((object)"PlayerRespawnSystem: Failed to find respawn position, using default");
			}
		}
		return orig.Invoke(self);
	}

	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 PlayerRespawnSystem : NetworkBehaviour
{
	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_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Expected O, but got Unknown
		playerRespawner = ((Component)this).gameObject.AddComponent<PlayerRespawner>();
		foreach (var (respawnType2, type2) in RespawnController.GetRespawnControllerTypes())
		{
			if (RespawnController.IsEnabled(type2))
			{
				Debug.Log((object)$"PlayerRespawnSystem: 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;
	}

	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)
	{
	}
}
[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, EntityState 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, EntityState 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;
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
[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
		MeridianEventStart.OnEnter += new hook_OnEnter(MeridianEventStart_OnEnter);
		MeridianEventCleared.OnEnter += new hook_OnEnter(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
		MeridianEventStart.OnEnter -= new hook_OnEnter(MeridianEventStart_OnEnter);
		MeridianEventCleared.OnEnter -= new hook_OnEnter(MeridianEventCleared_OnEnter);
		Run.AdvanceStage -= new hook_AdvanceStage(Run_AdvanceStage);
	}

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

	private void MeridianEventCleared_OnEnter(orig_OnEnter orig, MeridianEventCleared 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;
		}
		Debug.Log((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
		outRespawnTransform = null;
		return false;
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
[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;
		}
		Debug.Log((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
		outRespawnTransform = null;
		return false;
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
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 : NetworkBehaviour, IRespawnController
{
	private bool isActive;

	protected PlayerRespawner playerRespawner;

	public bool IsActive
	{
		get
		{
			return isActive;
		}
		protected set
		{
			if (isActive != value)
			{
				Debug.Log((object)("PlayerRespawnSystem: " + (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;
	}

	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 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_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: 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_00ae: 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)
		{
			Debug.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)
			{
				Debug.LogWarning((object)"Failed to get VoidRaidGauntletController::initialDonut field");
				return Vector3.zero;
			}
		}
		else
		{
			if (!(field3.GetValue(VoidRaidGauntletController.instance) is DonutInfo[] array))
			{
				Debug.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_0036: 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_003e: 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;
		LayerIndex world = LayerIndex.world;
		if (Physics.SphereCast(val2, maxRadiusAroundPosition, ref val, num, LayerMask.op_Implicit(((LayerIndex)(ref 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, BaseState 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, BaseState 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;
		}
		Debug.Log((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
		outRespawnTransform = null;
		return false;
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
[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)
			{
				Debug.Log((object)$"PlayerRespawnSystem: Timed respawn using {value.GetRespawnType()} respawn position");
				return value.GetRespawnTransform(body, out outRespawnTransform);
			}
		}
		Debug.Log((object)"PlayerRespawnSystem: Timed respawn using default respawn position");
		return base.GetRespawnTransform(body, out outRespawnTransform);
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
[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;
		}
		Debug.Log((object)$"GetRespawnTransform: Failed to find better respawn position for '{GetRespawnType()}' respawn type");
		outRespawnTransform = null;
		return false;
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		bool flag2 = default(bool);
		return flag2 || flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
	}
}
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 MultiUserTimers : NetworkBehaviour
{
	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);
		}
	}

	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 UserTimer : NetworkBehaviour
{
	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);
		}
	}

	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)
	{
	}
}
[BepInPlugin("com.Mordrog.PlayerRespawnSystem", "PlayerRespawnSystem", "2.1.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class PlayerRespawnSystemPlugin : BaseUnityPlugin
{
	public const string ModVer = "2.1.2";

	public const string ModName = "PlayerRespawnSystem";

	public const string ModGuid = "com.Mordrog.PlayerRespawnSystem";

	private PlayerRespawnSystem playerRespawnSystem;

	private static GameObject uiDeathTimerControllerPrefab;

	private GameObject uiDeathTimerController;

	public PlayerRespawnSystemPlugin()
	{
		InitConfig();
	}

	public void Awake()
	{
		//IL_0005: 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)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0026: Expected O, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Expected O, but got Unknown
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		GameObject val = new GameObject("temp");
		val.AddComponent<NetworkIdentity>();
		uiDeathTimerControllerPrefab = PrefabAPI.InstantiateClone(val, "UIDeathTimerController");
		Object.Destroy((Object)val);
		uiDeathTimerControllerPrefab.AddComponent<UIDeathTimerController>();
		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);
		if (!Object.op_Implicit((Object)(object)uiDeathTimerController))
		{
			uiDeathTimerController = Object.Instantiate<GameObject>(uiDeathTimerControllerPrefab);
			uiDeathTimerController.transform.SetParent(((Component)self).transform, false);
		}
	}

	private void Run_Awake(orig_Awake orig, Run self)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		orig.Invoke(self);
		if (!PluginConfig.IgnoredGameModes.Value.Contains(GameModeCatalog.GetGameModeName(self.gameModeIndex)))
		{
			uiDeathTimerController.SetActive(true);
			playerRespawnSystem = ((Component)this).gameObject.AddComponent<PlayerRespawnSystem>();
			if (NetworkServer.active)
			{
				NetworkServer.Spawn(uiDeathTimerController);
			}
		}
	}

	private void Run_OnDestroy(orig_OnDestroy orig, Run self)
	{
		orig.Invoke(self);
		if (Object.op_Implicit((Object)(object)uiDeathTimerController))
		{
			uiDeathTimerController.SetActive(false);
		}
		if (Object.op_Implicit((Object)(object)playerRespawnSystem))
		{
			Object.Destroy((Object)(object)playerRespawnSystem);
		}
		if (NetworkServer.active && Object.op_Implicit((Object)(object)uiDeathTimerController))
		{
			NetworkServer.UnSpawn(uiDeathTimerController);
		}
	}

	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;
}