feat(replay): wire finish hook for rank-battle family
Finish now consumes the stashed BattleContext, records a ViewerBattleHistory row (idempotent + retention-capped), and calls IPlayedTogetherWriter for human PvP (skipped for AI). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using SVSim.BattleNode.Bridge;
|
||||
using SVSim.BattleNode.Sessions;
|
||||
using SVSim.Database.Enums;
|
||||
using SVSim.Database.Services.Friend;
|
||||
using SVSim.Database.Services.Replay;
|
||||
using SVSim.EmulatedEntrypoint.Constants;
|
||||
using SVSim.EmulatedEntrypoint.Extensions;
|
||||
@@ -30,6 +31,8 @@ public sealed class RankBattleController : ControllerBase
|
||||
private readonly IMatchContextBuilder _ctxBuilder;
|
||||
private readonly IBotRoster _botRoster;
|
||||
private readonly IBattleContextStore _battleContextStore;
|
||||
private readonly IBattleHistoryWriter _historyWriter;
|
||||
private readonly IPlayedTogetherWriter _playedTogetherWriter;
|
||||
private readonly ILogger<RankBattleController> _log;
|
||||
|
||||
public RankBattleController(
|
||||
@@ -38,6 +41,8 @@ public sealed class RankBattleController : ControllerBase
|
||||
IMatchContextBuilder ctxBuilder,
|
||||
IBotRoster botRoster,
|
||||
IBattleContextStore battleContextStore,
|
||||
IBattleHistoryWriter historyWriter,
|
||||
IPlayedTogetherWriter playedTogetherWriter,
|
||||
ILogger<RankBattleController> log)
|
||||
{
|
||||
_resolver = resolver;
|
||||
@@ -45,6 +50,8 @@ public sealed class RankBattleController : ControllerBase
|
||||
_ctxBuilder = ctxBuilder;
|
||||
_botRoster = botRoster;
|
||||
_battleContextStore = battleContextStore;
|
||||
_historyWriter = historyWriter;
|
||||
_playedTogetherWriter = playedTogetherWriter;
|
||||
_log = log;
|
||||
}
|
||||
|
||||
@@ -84,9 +91,29 @@ public sealed class RankBattleController : ControllerBase
|
||||
[HttpPost("/unlimited_rank_battle/finish")]
|
||||
[HttpPost("/ai_rotation_rank_battle/finish")]
|
||||
[HttpPost("/ai_unlimited_rank_battle/finish")]
|
||||
public IActionResult Finish([FromBody] RankBattleFinishRequestDto req)
|
||||
public async Task<IActionResult> Finish([FromBody] RankBattleFinishRequestDto req, CancellationToken ct)
|
||||
{
|
||||
if (!TryGetViewerId(out var _)) return Unauthorized();
|
||||
if (!TryGetViewerId(out var vid)) return Unauthorized();
|
||||
|
||||
var ctx = _battleContextStore.TakeFor(vid);
|
||||
bool isWin = req.BattleResult == 1;
|
||||
|
||||
await _historyWriter.RecordAsync(vid, ctx, isWin, ct);
|
||||
|
||||
// Played-together only fires for human PvP. AI bots have OpponentViewerId=0.
|
||||
if (ctx is { OpponentViewerId: > 0 })
|
||||
{
|
||||
await _playedTogetherWriter.RecordAsync(
|
||||
vid,
|
||||
ctx.OpponentViewerId,
|
||||
new BattleParticipationContext(
|
||||
PlayedMode: 0,
|
||||
BattleType: ctx.BattleType,
|
||||
DeckFormat: ctx.DeckFormat,
|
||||
TwoPickType: ctx.TwoPickType),
|
||||
ct);
|
||||
}
|
||||
|
||||
return Ok(new RankBattleFinishResponseDto
|
||||
{
|
||||
BattleResult = req.BattleResult,
|
||||
|
||||
Reference in New Issue
Block a user