From fee84cca24c6aa749aa79f2aab829e19fcf1a3dc Mon Sep 17 00:00:00 2001 From: gamer147 Date: Tue, 2 Jun 2026 01:29:11 -0400 Subject: [PATCH] feat(battle-node): wire WS handler's case BattleType.Bot to real (Real, NoOp) session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the Phase-2 log-and-return stub with a real session construction. P2 is always null for Bot (bridge contract), so no WaitingRoom flow needed — single real WS, Phase-1 WhenAll-everything RunAsync semantics work because NoOp.RunAsync completes immediately. Integration test follows in the next task. Co-Authored-By: Claude Opus 4.7 --- .../Hosting/BattleNodeWebSocketHandler.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/SVSim.BattleNode/Hosting/BattleNodeWebSocketHandler.cs b/SVSim.BattleNode/Hosting/BattleNodeWebSocketHandler.cs index b89611c..770dbe2 100644 --- a/SVSim.BattleNode/Hosting/BattleNodeWebSocketHandler.cs +++ b/SVSim.BattleNode/Hosting/BattleNodeWebSocketHandler.cs @@ -193,9 +193,19 @@ public sealed class BattleNodeWebSocketHandler } case BattleType.Bot: - // Phase 3 deliverable. - _log.LogWarning("BattleType.Bot not yet supported (Phase 3); BattleId={Bid}", battleId); - return; + { + // Phase 3: real (Real, NoOp) session. Bot's pending always has P2 == null + // (per IMatchingBridge contract validation), so isP1 must be true here. The + // earlier isP1/isP2 check has already rejected viewer mismatches. + _store.RemovePending(battleId); + var botReal = new RealParticipant(ws, viewerId, pending.P1.Context, + _loggerFactory.CreateLogger()); + var noopBot = new NoOpBotParticipant(); + var botSession = new BattleSession(battleId, BattleType.Bot, botReal, noopBot, + _loggerFactory.CreateLogger()); + await botSession.RunAsync(ctx.RequestAborted); + break; + } default: _log.LogError("Unknown BattleType={Type} for BattleId={Bid}; closing WS", pending.Type, battleId);