MosswartMassacre/MosswartMassacre/Telemetry.cs

110 lines
4.3 KiB
C#

// Telemetry.cs ───────────────────────────────────────────────────────────────
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Decal.Adapter;
using Newtonsoft.Json;
namespace MosswartMassacre
{
public static class Telemetry
{
/* ───────────── configuration ───────────── */
private const string Endpoint = "https://mosswart.snakedesert.se/position/"; // <- trailing slash!
private const string SharedSecret = "your_shared_secret"; // <- keep in sync
private const int IntervalSec = 5; // seconds between posts
/* ───────────── runtime state ───────────── */
private static readonly HttpClient _http = new HttpClient();
private static string _sessionId;
private static CancellationTokenSource _cts;
private static bool _enabled;
/* ───────────── public API ───────────── */
public static void Start()
{
if (_enabled) return;
_enabled = true;
_sessionId = $"{CoreManager.Current.CharacterFilter.Name}-{DateTime.UtcNow:yyyyMMdd-HHmmss}";
_cts = new CancellationTokenSource();
PluginCore.WriteToChat("[Telemetry] HTTP streaming ENABLED");
_ = Task.Run(() => LoopAsync(_cts.Token)); // fire-and-forget
}
public static void Stop()
{
if (!_enabled) return;
_cts.Cancel();
_enabled = false;
PluginCore.WriteToChat("[Telemetry] HTTP streaming DISABLED");
}
/* ───────────── async loop ───────────── */
private static async Task LoopAsync(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
await SendSnapshotAsync(token);
}
catch (Exception ex)
{
PluginCore.WriteToChat($"[Telemetry] send failed: {ex.Message}");
}
try
{
await Task.Delay(TimeSpan.FromSeconds(IntervalSec), token);
}
catch (TaskCanceledException) { } // expected on Stop()
}
}
/* ───────────── single POST ───────────── */
private static async Task SendSnapshotAsync(CancellationToken token)
{
var coords = Coordinates.Me;
var payload = new
{
character_name = CoreManager.Current.CharacterFilter.Name,
char_tag = PluginCore.CharTag,
session_id = _sessionId,
timestamp = DateTime.UtcNow.ToString("o"),
ew = coords.EW,
ns = coords.NS,
z = coords.Z,
kills = PluginCore.totalKills,
onlinetime = (DateTime.Now - PluginCore.statsStartTime).ToString(@"dd\.hh\:mm\:ss"),
kills_per_hour = PluginCore.killsPerHour.ToString("F0"),
deaths = PluginCore.sessionDeaths.ToString(),
total_deaths = PluginCore.totalDeaths.ToString(),
rares_found = PluginCore.rareCount,
prismatic_taper_count = PluginCore.cachedPrismaticCount.ToString(),
vt_state = VtankControl.VtGetMetaState(),
};
string json = JsonConvert.SerializeObject(payload);
var req = new HttpRequestMessage(HttpMethod.Post, Endpoint)
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
req.Headers.Add("X-Plugin-Secret", SharedSecret);
using var resp = await _http.SendAsync(req, token);
if (!resp.IsSuccessStatusCode) // stay quiet on success
{
PluginCore.WriteToChat($"[Telemetry] server replied {resp.StatusCode}");
}
}
}
}