PlayerSession.cs
using Sandbox;
using Sandbox.Services.Players;
using System;
using System.Linq;

public sealed class PlayerSession : Component
{
	public static PlayerSession CurrentSession { get; private set; }
	[Sync] public string AvatarUrl { get; set; }
	[Sync] public string DisplayName { get; set; }
	[Sync] public int Kills { get; set; }
	[Sync] public int KillStreak { get; set; }
	[Sync] public int Deaths { get; set; }
	[Sync] public bool IsVR { get; set; }

	/// <summary>Index into the current map vote options, or -1 if the player has not voted.</summary>
	[Sync] public int MapVote { get; set; } = -1;

	/// <summary>Standing eye height in game units (inches), from VR calibration or the desktop default.</summary>
	[Sync] public float StandingEyeHeight { get; set; } = 64f;

	/// <summary>True after the owner finishes join setup (desktop skip, or VR Continue).</summary>
	[Sync, Change( nameof( OnReadyToSpawnChanged ) )]
	public bool IsReadyToSpawn { get; set; }

	/// <summary>True after the owner has pressed Calibrate at least once this session.</summary>
	[Sync] public bool HasCalibratedHeight { get; set; }

	/// <summary>True when a spawn transform was reserved during VR calibration.</summary>
	[Sync] public bool HasReservedSpawn { get; set; }

	/// <summary>World position reserved at calibration; reused when the real pawn spawns.</summary>
	[Sync] public Vector3 ReservedSpawnPosition { get; set; }

	/// <summary>World rotation reserved at calibration; reused when the real pawn spawns.</summary>
	[Sync] public Rotation ReservedSpawnRotation { get; set; } = Rotation.Identity;

	public Guid LastKiller {  get; set; }

	private float _lastKillTime;
	private int _multiKillCount;
	private GameObject _calibrationRigGo;
	private VrCalibrationRig _calibrationRig;
	private bool _wantsCalibrationRig;

	private const float MinEyeHeight = 40f;
	private const float MaxEyeHeight = 80f;
	private const string VrRootPrefabPath = "player/vrroot.prefab";

	public int RegisterMultiKill( float windowSeconds )
	{
		var now = Time.Now;

		if ( _lastKillTime > 0f && (now - _lastKillTime) <= windowSeconds )
			_multiKillCount++;
		else
			_multiKillCount = 1;

		_lastKillTime = now;
		return _multiKillCount;
	}

	public void ResetKillStreaks()
	{
		KillStreak = 0;
		_multiKillCount = 0;
		_lastKillTime = 0f;
	}

	/// <summary>Samples the VR headset height and stores it as standing eye height.</summary>
	public float CalibrateStandingEyeHeight()
	{
		if ( IsProxy || !Game.IsRunningInVR )
			return StandingEyeHeight;

		var height = _calibrationRig.IsValid()
			? _calibrationRig.MeasureEyeHeight()
			: Input.VR.Head.Position.z;

		StandingEyeHeight = Math.Clamp( height, MinEyeHeight, MaxEyeHeight );
		HasCalibratedHeight = true;
		return StandingEyeHeight;
	}

	/// <summary>Marks the session ready to spawn after a successful calibration.</summary>
	public bool ConfirmCalibration()
	{
		if ( IsProxy || !HasCalibratedHeight )
			return false;

		DestroyCalibrationRig();
		IsReadyToSpawn = true;
		return true;
	}

	public static string FormatHeightFeet( float inches )
	{
		var totalInches = (int)MathF.Round( inches );
		var feet = totalInches / 12;
		var remainingInches = totalInches % 12;
		return $"{feet}'{remainingInches}\"";
	}

	public static string FormatHeightCentimeters( float inches )
	{
		var cm = MathF.Round( inches * 2.54f );
		return $"{cm:0} cm";
	}

	protected override void OnStart()
	{
		NetworkManager.Instance.PlayerSessions.Add( this );
		if ( !IsProxy )
		{
			AvatarUrl = Profile.Local.Avatar;
			DisplayName = Profile.Local.Name;
			CurrentSession = this;
			IsVR = Game.IsRunningInVR;

			if ( !Game.IsRunningInVR || NetworkManager.Instance.SkipHeightCalibration )
			{
				StandingEyeHeight = 64f;
				IsReadyToSpawn = true;
			}
			else
			{
				_wantsCalibrationRig = true;
				Log.Info( "PlayerSession: VR client waiting to create calibration rig." );
			}
		}
	}

	protected override void OnUpdate()
	{
		if ( !_wantsCalibrationRig || IsReadyToSpawn || _calibrationRigGo.IsValid() )
			return;

		if ( NetworkManager.Instance is null || !NetworkManager.Instance.IsMapReady )
			return;

		CreateCalibrationRig();
	}

	protected override void OnDestroy()
	{
		DestroyCalibrationRig();

		if ( CurrentSession == this )
			CurrentSession = null;

		NetworkManager.Instance?.PlayerSessions.Remove( this );
	}

	private void OnReadyToSpawnChanged( bool oldValue, bool newValue )
	{
		if ( !newValue || !Networking.IsHost )
			return;

		NetworkManager.Instance?.TrySpawnPlayer( Network.Owner );
	}

	private void CreateCalibrationRig()
	{
		if ( _calibrationRigGo.IsValid() )
			return;

		var spawnTransform = PickSpawnTransform();
		ReservedSpawnPosition = spawnTransform.Position;
		ReservedSpawnRotation = spawnTransform.Rotation;
		HasReservedSpawn = true;

		_calibrationRigGo = new GameObject( "VrCalibrationRig" )
		{
			NetworkMode = NetworkMode.Never,
			WorldTransform = spawnTransform
		};

		_calibrationRig = _calibrationRigGo.AddComponent<VrCalibrationRig>();
		_calibrationRig.Session = this;

		var vrRoot = CloneVrRoot( _calibrationRigGo );
		if ( !vrRoot.IsValid() )
		{
			Log.Warning( "PlayerSession: failed to clone VR root for calibration; will retry." );
			_calibrationRigGo.Destroy();
			_calibrationRigGo = null;
			_calibrationRig = null;
			return;
		}

		var vrController = vrRoot.Components.Get<VrCharacterController>( FindMode.EverythingInSelfAndDescendants );
		if ( vrController.IsValid() )
			vrController.MovementEnabled = false;

		_calibrationRig.EnsurePanel();
		_wantsCalibrationRig = false;
		Log.Info( $"PlayerSession: calibration rig created at {spawnTransform.Position}." );
	}

	private static GameObject CloneVrRoot( GameObject parent )
	{
		var fromPlayerPrefab = NetworkManager.Instance?.PlayerPrefab?
			.Components.Get<PlayerCharacterController>()?.VRRootPrefab;

		if ( fromPlayerPrefab.IsValid() )
			return fromPlayerPrefab.Clone( transform: global::Transform.Zero, parent: parent );

		try
		{
			return GameObject.Clone( VrRootPrefabPath, global::Transform.Zero, parent );
		}
		catch ( Exception e )
		{
			Log.Warning( $"PlayerSession: GameObject.Clone(\"{VrRootPrefabPath}\") failed: {e.Message}" );
			return null;
		}
	}

	private void DestroyCalibrationRig()
	{
		_wantsCalibrationRig = false;

		if ( _calibrationRigGo.IsValid() )
			_calibrationRigGo.Destroy();

		_calibrationRigGo = null;
		_calibrationRig = null;
	}

	private static Transform PickSpawnTransform()
	{
		var spawnPoints = Game.ActiveScene.GetAllComponents<SpawnPoint>().ToArray();
		if ( spawnPoints.Length == 0 )
			return global::Transform.Zero;

		return spawnPoints[Game.Random.Int( 0, spawnPoints.Length - 1 )].Transform.World;
	}

	public void ClearStats()
	{
		Kills = 0;
		KillStreak = 0;
		Deaths = 0;
		LastKiller = Guid.Empty;
		ResetKillStreaks();
	}
}