UI/Scoreboard.razor

A Razor UI component for the game's scoreboard. It renders a header with the map title and a list of ScoreboardRow components for each network connection sorted by kills then name, fetches the current map package title asynchronously, and toggles visibility based on the Score input and spawn menu state.

NetworkingExternal Download
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent

<root>
    <div class="body">
        <div class="title">
            <label class="big">sandbox</label>

            @if ( !string.IsNullOrEmpty( _mapTitle ) )
            {
                <label class="small">Playing on @(_mapTitle)</label>
            }
        </div>

        <div class="table">
            <div class="col">
                <div class="header row">
                    <div class="avatar-spacer"></div>
                    <div class="name"></div>
                    <div class="stat">Kills</div>
                    <div class="stat">Deaths</div>
                    <div class="stat">Ping</div>
                    <div class="mute-spacer"></div>
                </div>

                @foreach ( var connection in Connection.All.OrderByDescending( x => PlayerData.For( x )?.Kills ?? 0 ).ThenBy( x => x.DisplayName ) )
                {
                    <ScoreboardRow Connection="@connection" />
                }
            </div>
        </div>
    </div>
</root>

@code
{
    string _mapTitle = null;

    protected override void OnTreeFirstBuilt()
    {
        base.OnTreeFirstBuilt();
        FetchMap();
    }

    async void FetchMap()
    {
        var ident = Networking.MapName;

        var pkg = await Package.FetchAsync( ident, false );
        if ( pkg is not null )
        {
            _mapTitle = pkg.Title;
        }
    }

    protected override void OnUpdate()
    {
	    var host = Game.ActiveScene.Get<SpawnMenuHost>();
	    if ( host?.Panel?.HasClass( "open" ) ?? false )
	    {
		    Input.Clear( "Score" );
	    }

	    SetClass( "visible", Input.Down( "Score" ) );
    }

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