feat(rank): AI-start SelfInfo carries viewer rank progress

/ai_*_rank_battle/start now reads ViewerRankProgress for the target format
and populates SelfInfo.rank / battlePoint / isMasterRank / masterPoint so
the pre-battle screen matches the viewer's real state. Read-only path uses
IRankProgressService.GetAsync (added in this commit).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-07-04 10:25:29 -04:00
parent 7ff8a7bd92
commit 4ce1cd172a
2 changed files with 46 additions and 4 deletions

View File

@@ -284,6 +284,13 @@ public sealed class RankBattleController : ControllerBase
var bot = await _botRoster.PickAsync(selfCtx, pending.BattleId, ct);
var seed = Random.Shared.Next();
// Read the viewer's rank progression for this format so the pre-battle screen
// shows the current tier/point rather than "Beginner 0 with 0 pts."
var selfViewer = await _viewers.LoadForRankProgressAsync(vid, ct);
var selfRank = selfViewer is null
? new RankProgressResult(1, 0, 0, 0, 0, false, false)
: await _rankProgress.GetAsync(selfViewer, format, ct);
// Stash battle context for the upcoming /finish so the replay-history hook can
// compose a ViewerBattleHistory row. See docs/superpowers/specs/2026-06-10-replay-info-design.md.
if (long.TryParse(pending.BattleId, out var battleIdLong))
@@ -327,12 +334,12 @@ public sealed class RankBattleController : ControllerBase
IsOfficial = selfCtx.IsOfficial,
OppoId = bot.AiId,
Seed = seed,
Rank = 0,
BattlePoint = 0,
Rank = selfRank.Rank,
BattlePoint = selfRank.AfterBattlePoint,
ClassId = (int)selfCtx.ClassId,
CharaId = int.TryParse(selfCtx.CharaId, out var chId) ? chId : -1,
IsMasterRank = 0,
MasterPoint = 0,
IsMasterRank = selfRank.IsMasterRank ? 1 : 0,
MasterPoint = selfRank.AfterMasterPoint,
},
OppoInfo = new AiBattlePlayerInfo
{