From 76b7e59489a123340bef6760c8aa3eed0bbe84b7 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 26 May 2026 17:42:55 -0400 Subject: [PATCH] loader: emit traffic body as nested JSON, not escaped string Body field in traffic.ndjson / battle-traffic.ndjson is now a real nested JSON object instead of an escaped JSON string. Parse-on-write is wrapped in ParseBodyOrKeep with a string-fallback so a future non-JSON caller doesn't crash the line write. Co-Authored-By: Claude Opus 4.7 --- SVSimLoader/CaptureWriter.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/SVSimLoader/CaptureWriter.cs b/SVSimLoader/CaptureWriter.cs index bcc552f..900b437 100644 --- a/SVSimLoader/CaptureWriter.cs +++ b/SVSimLoader/CaptureWriter.cs @@ -91,7 +91,7 @@ internal static class CaptureWriter { "direction", direction }, { "url", url }, { "encrypted", encrypted }, - { "body", body }, + { "body", ParseBodyOrKeep(body) }, }); } @@ -102,7 +102,7 @@ internal static class CaptureWriter { "ts", DateTime.UtcNow.ToString("o") }, { "direction", direction }, { "uri", uri }, - { "body", body }, + { "body", ParseBodyOrKeep(body) }, }); } @@ -278,6 +278,17 @@ internal static class CaptureWriter if (classes.Count > 0) dump["classes"] = classes; } + // Parse body JSON so it serializes nested in the NDJSON line rather than as an + // escaped string. Falls back to the original string on parse failure — no current + // caller produces non-JSON, but a future caller passing raw text shouldn't crash + // the line write. + private static object ParseBodyOrKeep(string body) + { + if (string.IsNullOrEmpty(body)) return body; + try { return JsonMapper.ToObject(body); } + catch { return body; } + } + private static void AppendNdjson(string path, Dictionary entry) { string line = JsonMapper.ToJson(entry);