UI/Scoreboard.razor
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent

<root>
    <div class="table">
        <div class="title">
            <label>@Networking.ServerName</label>
            <label class="small">@(Connection.All.Count) / @Networking.MaxPlayers</label>
        </div>

        @* Show timer when changing map *@
        @if ( GameManager.Current.CurrentGameStage == GameManager.GameStage.Results )
        {
            <div class="header row center">
                <div class="name">Changing map in @TimeRemaining</div>
            </div>
        }

        <div class="header row">
            <div class="name"></div>
            <div class="stat">#scoreboard.kills</div>
            <div class="stat">#scoreboard.deaths</div>
            <div class="stat">#scoreboard.ping</div>
        </div>

        <div class="col">
            @foreach ( var entry in Scene.GetAll<PlayerData>().OrderByDescending( x => x.Kills ).ThenBy( x => x.DisplayName ) )
            {
                string specialClass = "";
                if ( entry.IsMe ) specialClass = "me";

                <div class="row player @specialClass">
                    @if ( !entry.IsBot )
                    {
                        <img class="avatar" src="avatar:@entry.Connection.SteamId" />
                    }
                    <div class="name">@entry.DisplayName</div>
                    <div class="stat">@entry.Kills</div>
                    <div class="stat">@entry.Deaths</div>
                    <div class="stat">@(entry.Ping.CeilToInt())</div>
                </div>
            }
        </div>
    </div>
</root>

@code
{
    string TimeRemaining => TimeSpan.FromSeconds( (GameSettings.WarmupTime + GameSettings.RoundTime + GameSettings.ResultTime) - Time.Now )
                            .ToString( @"mm\:ss" );

    bool IsVisible => HasClass( "visible" );
	bool IsInteractable => HasClass( "interact" );

	protected override void OnUpdate()
	{
        SetClass( "visible", Input.Down( "score" ) || GameManager.Current.CurrentGameStage == GameManager.GameStage.Results );
	}

    /// <summary>
    /// update every second
    /// </summary>
    protected override int BuildHash() => System.HashCode.Combine( RealTime.Now.CeilToInt() );
}