diff --git a/SVSim.BattleNode/Sessions/BattleSession.cs b/SVSim.BattleNode/Sessions/BattleSession.cs index e6d209b..c849257 100644 --- a/SVSim.BattleNode/Sessions/BattleSession.cs +++ b/SVSim.BattleNode/Sessions/BattleSession.cs @@ -50,7 +50,7 @@ public sealed class BattleSession [NetworkBattleUri.TurnStart] = new TurnStartHandler(), [NetworkBattleUri.Judge] = new JudgeHandler(), [NetworkBattleUri.PlayActions] = new PlayActionsHandler(), - [NetworkBattleUri.Echo] = forwardWhenReady, + [NetworkBattleUri.Echo] = new EchoHandler(), [NetworkBattleUri.TurnEndActions] = forwardWhenReady, [NetworkBattleUri.JudgeResult] = forwardWhenReady, }; diff --git a/SVSim.BattleNode/Sessions/Dispatch/Handlers/EchoHandler.cs b/SVSim.BattleNode/Sessions/Dispatch/Handlers/EchoHandler.cs new file mode 100644 index 0000000..27dfbb5 --- /dev/null +++ b/SVSim.BattleNode/Sessions/Dispatch/Handlers/EchoHandler.cs @@ -0,0 +1,8 @@ +namespace SVSim.BattleNode.Sessions.Dispatch.Handlers; + +/// Echo is the receiver's per-frame ack; the client has no inbound Echo handler, so the +/// node consumes it (bullet-2 audit). Relaying would risk an echo->echo storm. +internal sealed class EchoHandler : IFrameHandler +{ + public IReadOnlyList Handle(FrameDispatchContext ctx) => Array.Empty(); +} diff --git a/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs b/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs index 537eb82..03e07a2 100644 --- a/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs +++ b/SVSim.UnitTests/BattleNode/Sessions/BattleSessionDispatchTests.cs @@ -478,7 +478,7 @@ public class BattleSessionDispatchTests } [Test] - public void Pvp_Echo_from_A_in_BothAfterReady_forwards_to_B() + public void Pvp_Echo_from_A_in_BothAfterReady_is_consumed_not_relayed() { var (s, a, b) = NewPvpSession(); DriveToAfterReady(s, a); @@ -486,8 +486,7 @@ public class BattleSessionDispatchTests var routes = s.ComputeFrames(a, NewEnvelope(NetworkBattleUri.Echo)); - Assert.That(routes.Count, Is.EqualTo(1)); - Assert.That(routes[0].Target, Is.SameAs(b)); + Assert.That(routes, Is.Empty, "Echo has no inbound handler on the client; relaying risks an echo storm."); } [Test]