Decompiled source of PlayerRespawnSystem v2.0.5

PlayerRespawnSystem.dll

Decompiled 3 months 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: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerRespawnSystem")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0ce7bfe1fd69d2a2f0adc383d27fb84a060e4177")]
[assembly: AssemblyProduct("PlayerRespawnSystem")]
[assembly: AssemblyTitle("PlayerRespawnSystem")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Mordrog;

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 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 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_003c: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: 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 = GameObject.Find("ArenaWalls").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);
	}

	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);
	}
}
internal class UsersRespawnTimers : NetworkBehaviour
{
	public delegate void UserTimerRespawnTimerEnd(NetworkUser user);

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

	public IReadOnlyDictionary<NetworkUserId, UserTimer> readOnlyInstances => usersRespawnTimers;

	public event UserTimerRespawnTimerEnd OnUserTimerRespawnTimerEnd;

	public void OnDestroy()
	{
		ClearAllUsersRespawnTimers();
	}

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

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

	public void StopAllCurrentRespawnTimers()
	{
		foreach (UserTimer value in usersRespawnTimers.Values)
		{
			value.Stop();
		}
	}

	public void ResumeAllCurrentRespawnTimers()
	{
		foreach (UserTimer value in usersRespawnTimers.Values)
		{
			value.Resume();
		}
	}

	public void ResetAllCurrentRespawnTimers()
	{
		foreach (UserTimer value in usersRespawnTimers.Values)
		{
			value.Reset();
		}
	}

	public void ClearAllUsersRespawnTimers()
	{
		//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>(usersRespawnTimers.Keys))
		{
			RemoveUserRespawnTimer(item);
		}
	}

	public void AddUserRespawnTimer(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 (!usersRespawnTimers.ContainsKey(userId))
		{
			usersRespawnTimers[userId] = ((Component)this).gameObject.AddComponent<UserTimer>();
			usersRespawnTimers[userId].UserId = userId;
			usersRespawnTimers[userId].OnTimerEndInFiveSeconds += UsersRespawnTimers_OnRespawnInFiveSeconds;
			usersRespawnTimers[userId].OnTimerEnd += UsersRespawnTimers_OnTimerEnd;
		}
	}

	public void RemoveUserRespawnTimer(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 (usersRespawnTimers.TryGetValue(userId, out var value))
		{
			value.OnTimerEndInFiveSeconds -= UsersRespawnTimers_OnRespawnInFiveSeconds;
			value.OnTimerEnd -= UsersRespawnTimers_OnTimerEnd;
			Object.DestroyImmediate((Object)(object)usersRespawnTimers[userId]);
			usersRespawnTimers.Remove(userId);
		}
	}

	private void UsersRespawnTimers_OnRespawnInFiveSeconds(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))
		{
			ChatHelper.UserWillRespawnAfter(user.userName, 5u);
		}
	}

	private void UsersRespawnTimers_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.OnUserTimerRespawnTimerEnd?.Invoke(user);
		}
	}
}
internal class UserTimer : NetworkBehaviour
{
	public delegate void TimerEndInFiveSeconds(NetworkUserId userId);

	public delegate void TimerEnd(NetworkUserId userId);

	private bool spawnInFiveSecondsFired;

	public float TimeRemaining { get; private set; }

	public NetworkUserId UserId { get; set; }

	public bool IsRunning { get; private set; }

	public event TimerEndInFiveSeconds OnTimerEndInFiveSeconds;

	public event TimerEnd OnTimerEnd;

	public void StartTimer(float time)
	{
		TimeRemaining = time;
		spawnInFiveSecondsFired = 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 && !spawnInFiveSecondsFired)
			{
				spawnInFiveSecondsFired = true;
				this.OnTimerEndInFiveSeconds?.Invoke(UserId);
			}
		}
		else
		{
			Reset();
			this.OnTimerEnd?.Invoke(UserId);
		}
	}
}
internal class UsersArtifactTrialRespawn : NetworkBehaviour
{
	public UsersRespawnController respawnController;

	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
		CombatState.OnEnter += new hook_OnEnter(ArtifactTrialMissionController_CombatState_OnEnter);
		CombatState.OnExit += new hook_OnExit(CombatState_OnExit);
	}

	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
		CombatState.OnEnter -= new hook_OnEnter(ArtifactTrialMissionController_CombatState_OnEnter);
		CombatState.OnExit -= new hook_OnExit(CombatState_OnExit);
	}

	private void ArtifactTrialMissionController_CombatState_OnEnter(orig_OnEnter orig, EntityState self)
	{
		orig.Invoke(self);
		respawnController.RespawnType = RespawnType.Artifact;
		if (PluginConfig.RespawnOnArtifactTrialStart.Value)
		{
			respawnController.RespawnAllUsers();
		}
		if (PluginConfig.BlockTimedRespawnOnArtifactTrial.Value)
		{
			respawnController.BlockTimedRespawn();
		}
	}

	private void CombatState_OnExit(orig_OnExit orig, EntityState self)
	{
		orig.Invoke(self);
		if (PluginConfig.BlockTimedRespawnOnArtifactTrial.Value)
		{
			respawnController.UnblockTimedRespawn();
		}
		if (PluginConfig.RespawnOnArtifactTrialEnd.Value)
		{
			respawnController.RespawnAllUsers();
		}
	}
}
internal class UsersMithrixRespawn : NetworkBehaviour
{
	public UsersRespawnController respawnController;

	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
		Phase1.OnEnter += new hook_OnEnter(BrotherEncounter_Phase1_OnEnter);
		EncounterFinished.OnEnter += new hook_OnEnter(BrotherEncounter_EncounterFinished_OnEnter);
	}

	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
		Phase1.OnEnter -= new hook_OnEnter(BrotherEncounter_Phase1_OnEnter);
		EncounterFinished.OnEnter -= new hook_OnEnter(BrotherEncounter_EncounterFinished_OnEnter);
	}

	private void BrotherEncounter_Phase1_OnEnter(orig_OnEnter orig, Phase1 self)
	{
		orig.Invoke(self);
		respawnController.RespawnType = RespawnType.Mithrix;
		if (PluginConfig.RespawnOnMithrixStart.Value)
		{
			respawnController.RespawnAllUsers();
		}
		if (PluginConfig.BlockTimedRespawnOnMithrixFight.Value)
		{
			respawnController.BlockTimedRespawn();
		}
	}

	private void BrotherEncounter_EncounterFinished_OnEnter(orig_OnEnter orig, EncounterFinished self)
	{
		orig.Invoke(self);
		if (PluginConfig.BlockTimedRespawnOnMithrixFight.Value)
		{
			respawnController.UnblockTimedRespawn();
		}
		if (PluginConfig.RespawnOnMithrixEnd.Value)
		{
			respawnController.RespawnAllUsers();
		}
	}
}
internal class UsersTeleporterRespawn : NetworkBehaviour
{
	public UsersRespawnController respawnController;

	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
		ChargingState.OnEnter += new hook_OnEnter(TeleporterInteraction_ChargingState_OnEnter);
		ChargedState.OnEnter += new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter);
	}

	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
		ChargingState.OnEnter -= new hook_OnEnter(TeleporterInteraction_ChargingState_OnEnter);
		ChargedState.OnEnter -= new hook_OnEnter(TeleporterInteraction_ChargedState_OnEnter);
	}

	private void TeleporterInteraction_ChargingState_OnEnter(orig_OnEnter orig, BaseState self)
	{
		orig.Invoke(self);
		respawnController.RespawnType = RespawnType.Teleporter;
		if (PluginConfig.RespawnOnTPStart.Value)
		{
			respawnController.RespawnAllUsers();
		}
		if (PluginConfig.BlockTimedRespawnOnTPEvent.Value)
		{
			respawnController.BlockTimedRespawn();
			ChatHelper.RespawnBlockedOnTPEvent();
		}
	}

	private void TeleporterInteraction_ChargedState_OnEnter(orig_OnEnter orig, BaseState self)
	{
		orig.Invoke(self);
		if (PluginConfig.BlockTimedRespawnOnTPEvent.Value)
		{
			respawnController.UnblockTimedRespawn();
		}
		if (PluginConfig.RespawnOnTPEnd.Value)
		{
			respawnController.RespawnAllUsers();
		}
	}
}
internal class UsersTimedRespawn : NetworkBehaviour
{
	public UsersRespawnController respawnController;

	private UsersRespawnTimers usersRespawnTimers;

	public IReadOnlyDictionary<NetworkUserId, UserTimer> readOnlyInstances => usersRespawnTimers.readOnlyInstances;

	private void Awake()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//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
		usersRespawnTimers = ((Component)this).gameObject.AddComponent<UsersRespawnTimers>();
		usersRespawnTimers.OnUserTimerRespawnTimerEnd += 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);
	}

	public void OnDestroy()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//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
		usersRespawnTimers.OnUserTimerRespawnTimerEnd -= 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);
	}

	private void UsersRespawnTimers_OnUserTimerRespawnTimerEnd(NetworkUser user)
	{
		respawnController.RespawnUser(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);
		usersRespawnTimers.AddUserRespawnTimer(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);
		usersRespawnTimers.RemoveUserRespawnTimer(user.id);
	}

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

	private void Run_OnDestroy(orig_OnDestroy orig, Run self)
	{
		orig.Invoke(self);
		usersRespawnTimers.ClearAllUsersRespawnTimers();
	}

	public void StartTimedRespawn(NetworkUser user)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)user))
		{
			uint respawnTime = RespawnTimeCalculation.GetRespawnTime();
			usersRespawnTimers.StartRespawnTimer(user.id, respawnTime);
			ChatHelper.UserWillRespawnAfter(user.userName, respawnTime);
		}
	}

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

	public void StopAllRespawnTimers()
	{
		usersRespawnTimers.StopAllCurrentRespawnTimers();
	}

	public void ResumeAllRespawnTimers()
	{
		usersRespawnTimers.ResumeAllCurrentRespawnTimers();
	}

	public void ResetAllRespawnTimers()
	{
		usersRespawnTimers.ResetAllCurrentRespawnTimers();
	}
}
internal class DeathTimerController : NetworkBehaviour
{
	private DeathTimerPanel deathTimerPanel;

	public readonly int UpdateTimersEveryXFrames = 5;

	private int frameCount;

	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<DeathTimerPanel>();
	}

	private void Run_OnDestroy(orig_OnDestroy orig, Run self)
	{
		orig.Invoke(self);
		deathTimerPanel = null;
	}

	public void FixedUpdate()
	{
		if (NetworkServer.active && ((NetworkBehaviour)this).hasAuthority)
		{
			frameCount++;
			if (frameCount >= UpdateTimersEveryXFrames)
			{
				CmdUpdateAllDeathTimers();
				frameCount = 0;
			}
		}
	}

	[Command]
	public void CmdUpdateAllDeathTimers()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)UsersRespawnController.instance))
		{
			return;
		}
		foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
		{
			if (UsersRespawnController.instance.usersTimedRespawn.readOnlyInstances.TryGetValue(readOnlyInstances.id, out var value))
			{
				float timeRemaining = value.TimeRemaining;
				bool canTimedRespawn = UsersRespawnController.instance.CheckIfCanTimedRespawn((readOnlyInstances != null) ? readOnlyInstances.master : null);
				bool canRespawnAfter = UsersRespawnController.instance.CheckIfCanRespawn((readOnlyInstances != null) ? readOnlyInstances.master : null) && UsersRespawnController.instance.IsTimedRespawnBlocked;
				RespawnType respawnType = UsersRespawnController.instance.RespawnType;
				TargetUpdateDeathTimer(((NetworkBehaviour)readOnlyInstances).connectionToClient, timeRemaining, canTimedRespawn, canRespawnAfter, respawnType);
			}
		}
	}

	[TargetRpc]
	public void TargetUpdateDeathTimer(NetworkConnection target, float respawnTime, bool canTimedRespawn, bool canRespawnAfter, RespawnType respawnType)
	{
		if (!Object.op_Implicit((Object)(object)deathTimerPanel) || !PluginConfig.UseDeathTimerUI.Value)
		{
			return;
		}
		if (canTimedRespawn)
		{
			deathTimerPanel.show = true;
			((TMP_Text)deathTimerPanel.textContext2).text = $"in <color=red>{Mathf.CeilToInt(respawnTime)}</color> seconds";
		}
		else if (canRespawnAfter)
		{
			switch (respawnType)
			{
			case RespawnType.Default:
				deathTimerPanel.show = false;
				break;
			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;
			}
		}
		else
		{
			deathTimerPanel.show = false;
		}
	}
}
internal class DeathTimerPanel : 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));
		}
	}
}
public enum RespawnType : byte
{
	Default,
	Teleporter,
	Mithrix,
	Artifact
}
internal class UsersRespawnController : NetworkBehaviour
{
	public UsersTimedRespawn usersTimedRespawn;

	private UsersTeleporterRespawn usersTeleporterRespawn;

	private UsersMithrixRespawn usersMithrixRespawn;

	private UsersArtifactTrialRespawn usersArtifactTrialRespawn;

	private Queue<CharacterBody> respawnCharacterMaster = new Queue<CharacterBody>();

	public bool IsAdvancingStage { get; private set; }

	public bool IsTimedRespawnBlocked { get; private set; }

	public RespawnType RespawnType { get; set; }

	public static UsersRespawnController instance { get; private set; }

	public void Awake()
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Expected O, but got Unknown
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Expected O, but got Unknown
		usersTimedRespawn = ((Component)this).gameObject.AddComponent<UsersTimedRespawn>();
		usersTeleporterRespawn = ((Component)this).gameObject.AddComponent<UsersTeleporterRespawn>();
		usersMithrixRespawn = ((Component)this).gameObject.AddComponent<UsersMithrixRespawn>();
		usersArtifactTrialRespawn = ((Component)this).gameObject.AddComponent<UsersArtifactTrialRespawn>();
		usersTimedRespawn.respawnController = (usersTeleporterRespawn.respawnController = (usersMithrixRespawn.respawnController = (usersArtifactTrialRespawn.respawnController = this)));
		PlayerCharacterMasterController.OnBodyDeath += new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
		SceneExitController.SetState += new hook_SetState(SceneExitController_SetState);
		Stage.OnEnable += new hook_OnEnable(Stage_OnEnable);
		Stage.BeginAdvanceStage += new hook_BeginAdvanceStage(Stage_BeginAdvanceStage);
		Stage.RespawnCharacter += new hook_RespawnCharacter(Stage_RespawnCharacter);
		Stage.GetPlayerSpawnTransform += new hook_GetPlayerSpawnTransform(Stage_GetPlayerSpawnTransform);
		CharacterMaster.Respawn += new hook_Respawn(CharacterMaster_Respawn);
		Run.OnServerSceneChanged += new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
		Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy);
	}

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

	protected void OnDisable()
	{
		instance = SingletonHelper.Unassign<UsersRespawnController>(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
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		PlayerCharacterMasterController.OnBodyDeath -= new hook_OnBodyDeath(PlayerCharacterMasterController_OnBodyDeath);
		SceneExitController.SetState -= new hook_SetState(SceneExitController_SetState);
		Stage.OnEnable -= new hook_OnEnable(Stage_OnEnable);
		Stage.BeginAdvanceStage -= new hook_BeginAdvanceStage(Stage_BeginAdvanceStage);
		Stage.RespawnCharacter -= new hook_RespawnCharacter(Stage_RespawnCharacter);
		Stage.GetPlayerSpawnTransform -= new hook_GetPlayerSpawnTransform(Stage_GetPlayerSpawnTransform);
		CharacterMaster.Respawn -= new hook_Respawn(CharacterMaster_Respawn);
		Run.OnServerSceneChanged -= new hook_OnServerSceneChanged(Run_OnServerSceneChanged);
		Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy);
		Object.Destroy((Object)(object)usersTimedRespawn);
		Object.Destroy((Object)(object)usersTeleporterRespawn);
		Object.Destroy((Object)(object)usersMithrixRespawn);
		Object.Destroy((Object)(object)usersArtifactTrialRespawn);
	}

	private void PlayerCharacterMasterController_OnBodyDeath(orig_OnBodyDeath orig, PlayerCharacterMasterController self)
	{
		orig.Invoke(self);
		Stage.instance.usePod = false;
		NetworkUser user = UsersHelper.GetUser(self.master);
		if (!Object.op_Implicit((Object)(object)user))
		{
			return;
		}
		if (CheckIfCanTimedRespawn(self.master))
		{
			usersTimedRespawn.StartTimedRespawn(user);
		}
		else
		{
			if (!IsTimedRespawnBlocked)
			{
				return;
			}
			switch (RespawnType)
			{
			case RespawnType.Teleporter:
				if (PluginConfig.RespawnOnTPEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterTPEvent(user.userName);
				}
				break;
			case RespawnType.Mithrix:
				if (PluginConfig.RespawnOnMithrixEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterMithrixFight(user.userName);
				}
				break;
			case RespawnType.Artifact:
				if (PluginConfig.RespawnOnArtifactTrialEnd.Value)
				{
					ChatHelper.UserWillRespawnAfterArtifactTrial(user.userName);
				}
				break;
			}
		}
	}

	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)
		{
			IsAdvancingStage = true;
		}
	}

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

	private void Stage_BeginAdvanceStage(orig_BeginAdvanceStage orig, Stage self, SceneDef destinationStage)
	{
		orig.Invoke(self, destinationStage);
		UnblockTimedRespawn();
		RespawnType = RespawnType.Default;
		usersTimedRespawn.ResetAllRespawnTimers();
	}

	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))
			{
				respawnCharacterMaster.Enqueue(component);
			}
		}
		orig.Invoke(self, characterMaster);
	}

	private Transform Stage_GetPlayerSpawnTransform(orig_GetPlayerSpawnTransform orig, Stage self)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		if (respawnCharacterMaster.Count == 0)
		{
			return orig.Invoke(self);
		}
		CharacterBody body = respawnCharacterMaster.Dequeue();
		switch (RespawnType)
		{
		case RespawnType.Teleporter:
		{
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionAroundTeleporter(body, 0.5f, 3f);
			if (transform.position != Vector3.zero)
			{
				return transform;
			}
			Debug.Log((object)$"UsersRespawnController::Stage_GetPlayerSpawnTransform hook: Failed to find better respawn position for '{RespawnType}' respawn type");
			break;
		}
		case RespawnType.Mithrix:
		{
			Transform transform = new GameObject().transform;
			transform.position = RespawnPosition.GetSpawnPositionAroundMoonBoss(body, 100f, 105f);
			if (transform.position != Vector3.zero)
			{
				return transform;
			}
			Debug.Log((object)$"UsersRespawnController::Stage_GetPlayerSpawnTransform hook: Failed to find better respawn position for '{RespawnType}' respawn type");
			break;
		}
		}
		return orig.Invoke(self);
	}

	private CharacterBody CharacterMaster_Respawn(orig_Respawn orig, CharacterMaster self, Vector3 footPosition, Quaternion rotation, bool wasRevivedMidStage)
	{
		//IL_0013: 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)
		usersTimedRespawn.ResetTimedRespawn(UsersHelper.GetUser(self));
		return orig.Invoke(self, footPosition, rotation, wasRevivedMidStage);
	}

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

	private void Run_OnDestroy(orig_OnDestroy orig, Run self)
	{
		orig.Invoke(self);
		respawnCharacterMaster.Clear();
		UnblockTimedRespawn();
		RespawnType = RespawnType.Default;
	}

	public void BlockTimedRespawn()
	{
		IsTimedRespawnBlocked = true;
		usersTimedRespawn.StopAllRespawnTimers();
	}

	public void UnblockTimedRespawn()
	{
		IsTimedRespawnBlocked = false;
		usersTimedRespawn.ResumeAllRespawnTimers();
	}

	public void RespawnUser(NetworkUser user)
	{
		if (Object.op_Implicit((Object)(object)((user != null) ? user.master : null)) && CheckIfCanRespawn(user.master))
		{
			Stage.instance.RespawnCharacter(user.master);
		}
	}

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

	public bool CheckIfCanRespawn(CharacterMaster master)
	{
		if (Object.op_Implicit((Object)(object)master) && master.IsDeadAndOutOfLivesServer())
		{
			return !IsAdvancingStage;
		}
		return false;
	}

	public bool CheckIfCanTimedRespawn(CharacterMaster master)
	{
		if (CheckIfCanRespawn(master) && !CheckIfCurrentStageIsIgnoredForTimedRespawn() && !IsTimedRespawnBlocked)
		{
			return PluginConfig.UseTimedRespawn.Value;
		}
		return false;
	}

	public bool CheckIfCurrentStageIsIgnoredForTimedRespawn()
	{
		return PluginConfig.IgnoredMapsForTimedRespawn.Value.Contains(SceneCatalog.GetSceneDefForCurrentScene().baseSceneName);
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[R2APISubmoduleDependency(new string[] { "PrefabAPI" })]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.Mordrog.PlayerRespawnSystem", "PlayerRespawnSystem", "2.0.4")]
public class PlayerRespawnSystemPlugin : BaseUnityPlugin
{
	public const string ModVer = "2.0.4";

	public const string ModName = "PlayerRespawnSystem";

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

	private UsersRespawnController usersRespawnController;

	private static GameObject DeathTimerControllerPrefab;

	private GameObject deathTimerController;

	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>();
		DeathTimerControllerPrefab = PrefabAPI.InstantiateClone(val, "DeathTimerController");
		Object.Destroy((Object)val);
		DeathTimerControllerPrefab.AddComponent<DeathTimerController>();
		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)deathTimerController))
		{
			deathTimerController = Object.Instantiate<GameObject>(DeathTimerControllerPrefab);
			deathTimerController.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)))
		{
			deathTimerController.SetActive(true);
			usersRespawnController = ((Component)this).gameObject.AddComponent<UsersRespawnController>();
			if (NetworkServer.active)
			{
				NetworkServer.Spawn(deathTimerController);
			}
		}
	}

	private void Run_OnDestroy(orig_OnDestroy 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)))
		{
			if (Object.op_Implicit((Object)(object)deathTimerController))
			{
				deathTimerController.SetActive(false);
			}
			Object.Destroy((Object)(object)usersRespawnController);
			if (NetworkServer.active && Object.op_Implicit((Object)(object)deathTimerController))
			{
				NetworkServer.UnSpawn(deathTimerController);
			}
		}
	}

	private void InitConfig()
	{
		PluginConfig.IgnoredMapsForTimedRespawn = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "IgnoredMapsForTimedRespawn", "bazaar,arena,goldshores,moon,moon2,artifactworld,mysteryspace,limbo,voidraid", "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).");
	}
}
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;
}