using System.Globalization;
using OpenAC.MosswartMassacre.Backend;
using OpenAC.MosswartMassacre.Infrastructure;
namespace OpenAC.MosswartMassacre.Streams;
///
/// The telemetry frame: sent right after the socket registers and then
/// every five seconds, as the original's socket loop did.
///
///
/// Several fields are strings on the wire (kill rate, deaths, taper count) and
/// mem_mb carries bytes; the backend reads them that way.
///
internal sealed class TelemetryStream : IMmFeature, IBackendConnectionListener
{
public static readonly TimeSpan Interval = TimeSpan.FromSeconds(5);
private readonly MmContext _context;
private readonly SessionStats _stats;
private readonly ProcessTelemetry _process = new();
private IDisposable? _timer;
public TelemetryStream(MmContext context, SessionStats stats)
{
_context = context;
_stats = stats;
}
public void OnBackendConnected()
{
if (!_context.IsLoggedIn)
return;
SendNow();
_timer?.Dispose();
_timer = _context.Scheduler.Every(Interval, SendNow);
}
public void OnLogin()
{
}
public void OnLogoff()
{
_timer?.Dispose();
_timer = null;
}
public void Dispose() => OnLogoff();
internal void SendNow()
{
if (!_context.IsLoggedIn)
return;
_context.Send(Build());
}
internal object Build()
{
MmCoordinates coords = MmCoordinates.From(_context.Automation.Navigation.Snapshot.Position);
var kills = _stats.Kills;
return new
{
type = "telemetry",
character_name = _context.CharacterName,
char_tag = _context.Settings.Current.CharTag ?? "",
session_id = _context.TelemetrySessionId,
timestamp = Wire.Timestamp(_context.Clock),
ew = coords.EW,
ns = coords.NS,
z = coords.Z,
kills = kills.TotalKills,
kills_per_hour = FrameworkNumberConverter.FrameworkFixed(kills.KillsPerHour, "F0", CultureInfo.CurrentCulture),
onlinetime = (_context.Clock.Now - kills.StatsStartTime).ToString(@"dd\.hh\:mm\:ss", CultureInfo.InvariantCulture),
deaths = kills.SessionDeaths.ToString(CultureInfo.CurrentCulture),
total_deaths = kills.TotalDeaths.ToString(CultureInfo.CurrentCulture),
prismatic_taper_count = _context.PrismaticTaperCount().ToString(CultureInfo.CurrentCulture),
vt_state = _context.MetaState() ?? string.Empty,
mem_mb = _process.MemoryBytes,
cpu_pct = _process.SampleCpuUsage(),
mem_handles = _process.HandleCount,
};
}
}