141 lines
5.1 KiB
C#
141 lines
5.1 KiB
C#
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace FloodSWE.Networking
|
|
{
|
|
/// <summary>
|
|
/// Binds SweServerRuntime diagnostics to user-provided TMP text fields.
|
|
/// </summary>
|
|
public sealed class SweServerDiagnosticsHud : MonoBehaviour
|
|
{
|
|
[Header("References")]
|
|
[SerializeField] private SweServerRuntime serverRuntime;
|
|
[SerializeField] private TMP_Text simulationText;
|
|
[SerializeField] private TMP_Text connectionText;
|
|
[SerializeField] private TMP_Text commandText;
|
|
[SerializeField] private TMP_Text forcingText;
|
|
[SerializeField] private TMP_Text tileLoadText;
|
|
|
|
[Header("Behavior")]
|
|
[SerializeField] private bool autoFindRuntime = true;
|
|
[SerializeField] private float refreshIntervalSeconds = 0.15f;
|
|
|
|
[Header("Labels")]
|
|
[SerializeField] private string connectedLabel = "Connected";
|
|
[SerializeField] private string staleLabel = "Stale";
|
|
[SerializeField] private string disconnectedLabel = "Disconnected";
|
|
[SerializeField] private string unknownAgeLabel = "n/a";
|
|
[SerializeField] private string numberFormat = "0.00";
|
|
|
|
[Header("Colors")]
|
|
[SerializeField] private Color connectedColor = new Color(0.4f, 1.0f, 0.4f);
|
|
[SerializeField] private Color staleColor = new Color(1.0f, 0.9f, 0.3f);
|
|
[SerializeField] private Color disconnectedColor = new Color(1.0f, 0.5f, 0.5f);
|
|
|
|
private float nextRefreshTime;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (serverRuntime == null && autoFindRuntime)
|
|
{
|
|
serverRuntime = FindFirstObjectByType<SweServerRuntime>();
|
|
}
|
|
|
|
Refresh(true);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Time.unscaledTime < nextRefreshTime)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Refresh(false);
|
|
}
|
|
|
|
private void Refresh(bool immediate)
|
|
{
|
|
nextRefreshTime = Time.unscaledTime + Mathf.Max(0.02f, refreshIntervalSeconds);
|
|
if (serverRuntime == null)
|
|
{
|
|
SetText(simulationText, "Sim Speed: n/a");
|
|
SetText(connectionText, "Connection: runtime missing");
|
|
SetText(commandText, "Last Command: n/a");
|
|
SetText(forcingText, "Forcing: n/a");
|
|
SetText(tileLoadText, "Tile Load: runtime missing");
|
|
if (connectionText != null)
|
|
{
|
|
connectionText.color = disconnectedColor;
|
|
}
|
|
return;
|
|
}
|
|
|
|
string simLine = $"Sim Speed: {serverRuntime.SimulatedSecondsPerSecond.ToString(numberFormat)} sim-s/s";
|
|
if (!serverRuntime.HasSimulationThroughput)
|
|
{
|
|
simLine = "Sim Speed: warming up";
|
|
}
|
|
SetText(simulationText, simLine);
|
|
|
|
string state;
|
|
Color stateColor;
|
|
if (!serverRuntime.HasConnectedClients)
|
|
{
|
|
state = disconnectedLabel;
|
|
stateColor = disconnectedColor;
|
|
}
|
|
else if (serverRuntime.HasRecentClientSignal)
|
|
{
|
|
state = connectedLabel;
|
|
stateColor = connectedColor;
|
|
}
|
|
else
|
|
{
|
|
state = staleLabel;
|
|
stateColor = staleColor;
|
|
}
|
|
|
|
string connectionLine =
|
|
$"Connection: {state} | clients={serverRuntime.ConnectedClientCount} | endpoint={serverRuntime.QuestEndpointLabel}";
|
|
SetText(connectionText, connectionLine);
|
|
if (connectionText != null)
|
|
{
|
|
connectionText.color = stateColor;
|
|
}
|
|
|
|
string age = float.IsInfinity(serverRuntime.LastCommandAgeSeconds)
|
|
? unknownAgeLabel
|
|
: $"{serverRuntime.LastCommandAgeSeconds.ToString(numberFormat)}s";
|
|
string commandLine =
|
|
$"Last Command: {serverRuntime.LastCommandName} from {serverRuntime.LastCommandSender} ({age}) | " +
|
|
$"ctrl={serverRuntime.DecodedControlPackets}/{serverRuntime.ReceivedControlPackets} invalid={serverRuntime.InvalidControlPackets} ack={serverRuntime.AckPacketsSent}";
|
|
SetText(commandText, commandLine);
|
|
|
|
string forcingLine =
|
|
$"Forcing: {serverRuntime.LastForcingStatus} | cells={serverRuntime.LastForcedCellCount} | tile={serverRuntime.ActiveTileLabel}";
|
|
SetText(forcingText, forcingLine);
|
|
|
|
string tileLine =
|
|
$"Tile Load: {serverRuntime.TileLoadSummary} | framePayload={serverRuntime.LastFramePayloadBytes}B " +
|
|
$"frames={serverRuntime.TransmittedFramePackets} dropped={serverRuntime.DroppedFramePackets}";
|
|
SetText(tileLoadText, tileLine);
|
|
|
|
if (immediate)
|
|
{
|
|
nextRefreshTime = Time.unscaledTime;
|
|
}
|
|
}
|
|
|
|
private static void SetText(TMP_Text target, string value)
|
|
{
|
|
if (target == null || target.text == value)
|
|
{
|
|
return;
|
|
}
|
|
|
|
target.text = value;
|
|
}
|
|
}
|
|
}
|