Review fixes: telemetry session id per login; Framework number text

F1: the telemetry session id is new at every login. The original made one per
load of its assembly and its loader reloaded it at every login; the backend
counts new kills per (session id, character), so reusing one id across a
relog under-counted kills until the reset counter passed the old total.

F5/F6: .NET Framework never wrote a negative zero, and its fixed-point
formats (F7, F2, F0) rounded at fifteen significant digits, half away from
zero. Spawn and portal coordinates, kills_per_hour and the !report line now
format that way; the round-trip converter maps -0 to 0.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-25 13:04:28 +02:00
parent 9b5371c2e4
commit 71f14473c6
10 changed files with 157 additions and 10 deletions

View file

@ -43,6 +43,25 @@ public sealed class WireNumberTests
public void Floats_use_the_frameworks_round_trip_digits(float value, string expected) =>
Assert.Equal("{\"v\":" + expected + "}", Wire.Serialize(new { v = value }));
[Fact]
public void Negative_zero_is_written_as_zero_as_the_framework_did()
{
Assert.Equal("{\"v\":0.0}", Wire.Serialize(new { v = Math.Round(-0.001, 2) }));
Assert.Equal("{\"v\":0.0}", Wire.Serialize(new { v = -0f }));
}
[Theory]
// Rounded half away from zero at fifteen significant digits, as the
// Framework did; the modern exact-binary rounding differs on these.
[InlineData(0.125, "F2", "0.13")]
[InlineData(2.675, "F2", "2.68")]
[InlineData(-0.001, "F2", "0.00")]
[InlineData(-0.0, "F7", "0.0000000")]
[InlineData(12.5, "F0", "13")]
[InlineData(33.650001525878906, "F7", "33.6500015")]
public void Fixed_formats_round_as_the_framework_did(double value, string format, string expected) =>
Assert.Equal(expected, FrameworkNumberConverter.FrameworkFixed(value, format, System.Globalization.CultureInfo.InvariantCulture));
[Fact]
public void Nulls_and_non_finite_values_keep_newtonsofts_handling()
{

View file

@ -42,6 +42,21 @@ public sealed class PluginLifecycleTests
Assert.Equal("Horan", harness.Context.Settings.CharacterName);
}
[Fact]
public void Each_login_gets_a_new_telemetry_session_id()
{
// The backend counts new kills per (session id, character); the kill
// counter restarts at every login, so the id must too.
using var harness = new PluginHarness("Mossy");
harness.Login();
string first = harness.Context.TelemetrySessionId;
harness.Plugin.OnLogin();
Assert.NotEqual(first, harness.Context.TelemetrySessionId);
Assert.Equal(32, harness.Context.TelemetrySessionId.Length);
}
[Fact]
public void Mm_without_a_subcommand_prints_usage_and_unknown_is_reported()
{

View file

@ -142,7 +142,7 @@ public sealed class StreamGoldenTests
Assert.Equal(expectedOrder, frame.Properties().Select(p => p.Name));
string head = "{\"type\":\"telemetry\",\"character_name\":\"Mossy\",\"char_tag\":\"tank\",\"session_id\":\""
+ MmContext.ProcessSessionId + "\",\"timestamp\":\"2026-09-25T10:00:15.1230000Z\","
+ harness.Context.TelemetrySessionId + "\",\"timestamp\":\"2026-09-25T10:00:15.1230000Z\","
+ "\"ew\":" + D(33.65f) + ",\"ns\":" + D(42.55f) + ",\"z\":42.5,\"kills\":0,"
+ "\"kills_per_hour\":\"0\",\"onlinetime\":\"00.01:30:00\",\"deaths\":\"0\",\"total_deaths\":\"7\","
+ "\"prismatic_taper_count\":\"1234\",\"vt_state\":\"Combat\",\"mem_mb\":";