From 22a482526530ff7c79238f9be41aff8b0984d418 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sun, 31 May 2026 22:07:31 -0400 Subject: [PATCH] feat(battle-node): Gungnir alive-body builders (scs/ocs ONLINE placeholders) --- SVSim.BattleNode/Reliability/Gungnir.cs | 23 +++++++++++++++ .../BattleNode/Reliability/GungnirTests.cs | 28 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 SVSim.BattleNode/Reliability/Gungnir.cs create mode 100644 SVSim.UnitTests/BattleNode/Reliability/GungnirTests.cs diff --git a/SVSim.BattleNode/Reliability/Gungnir.cs b/SVSim.BattleNode/Reliability/Gungnir.cs new file mode 100644 index 0000000..c1644e7 --- /dev/null +++ b/SVSim.BattleNode/Reliability/Gungnir.cs @@ -0,0 +1,23 @@ +namespace SVSim.BattleNode.Reliability; + +/// +/// Body builders for the alive channel. The timer/loop that drives 5s emits lives on +/// BattleSession; this class is just the pure body-shape factory. +/// v1 always reports scs/ocs=ONLINE — real disconnect detection is deferred. +/// +public static class Gungnir +{ + public static readonly TimeSpan EmitInterval = TimeSpan.FromSeconds(5); + + public static Dictionary BuildAliveEmitBody(InboundTracker tracker) => new() + { + ["currentSeq"] = tracker.HighWaterMark, + // actionSeq omitted in v1 — no turn-transition flag yet. + }; + + public static Dictionary BuildAlivePushBody() => new() + { + ["scs"] = "ONLINE", + ["ocs"] = "ONLINE", + }; +} diff --git a/SVSim.UnitTests/BattleNode/Reliability/GungnirTests.cs b/SVSim.UnitTests/BattleNode/Reliability/GungnirTests.cs new file mode 100644 index 0000000..40ea1b5 --- /dev/null +++ b/SVSim.UnitTests/BattleNode/Reliability/GungnirTests.cs @@ -0,0 +1,28 @@ +using NUnit.Framework; +using SVSim.BattleNode.Reliability; + +namespace SVSim.UnitTests.BattleNode.Reliability; + +[TestFixture] +public class GungnirTests +{ + [Test] + public void BuildAlivePush_AlwaysReturnsScsOnlineOcsOnline() + { + var body = Gungnir.BuildAlivePushBody(); + Assert.That(body["scs"], Is.EqualTo("ONLINE")); + Assert.That(body["ocs"], Is.EqualTo("ONLINE")); + } + + [Test] + public void BuildAliveEmit_CarriesCurrentSeqFromTracker() + { + var tracker = new InboundTracker(); + tracker.Observe(7); + + var body = Gungnir.BuildAliveEmitBody(tracker); + + Assert.That(body["currentSeq"], Is.EqualTo(7L)); + Assert.That(body.ContainsKey("actionSeq"), Is.False); // omitted in v1 + } +}