Consolidation

This commit is contained in:
gamer147
2026-05-25 16:34:24 -04:00
parent 9b051c444c
commit 8e913578ff
14 changed files with 566 additions and 280 deletions

View File

@@ -79,7 +79,7 @@ public class LoadController : SVSimController
// .AsNoTracking() — the local `viewer` instance is detached, and the service's writes
// (on a separate tracked instance) won't appear on this snapshot. Without the re-fetch,
// the response payload would be one /load/index behind on newly-granted cosmetics.
await _acquisition.GrantAsync(viewer.Id, newCardIds: null);
await _acquisition.BackfillCosmeticsAsync(viewer.Id);
viewer = await _viewerRepository.GetViewerByShortUdid(shortUdid);
if (viewer is null)
{

View File

@@ -196,7 +196,7 @@ public class PackController : SVSimController
// Draw + persist. DAILY single overrides packNumber to 1 (it's a one-card open).
int drawCount = child.IsDailySingle ? 1 : packNumber;
var draw = _opener.Draw(pack, _pools, drawCount, request.ExcludeCardIds, _rng);
var grant = await _acquisition.GrantAsync(viewerId, draw.Cards.Select(c => c.CardId));
var grant = await _acquisition.GrantManyAsync(viewerId, draw.Cards.Select(c => c.CardId));
// Build reward_list. The service produces the type=5 (Card) entries with post-state counts
// plus any cosmetic grants. Currency entry (type=2 Crystals or type=9 Rupy) stays in the

View File

@@ -2,6 +2,7 @@ using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SVSim.Database;
using SVSim.Database.Repositories.Globals;
using SVSim.Database.Repositories.Viewer;
@@ -26,17 +27,20 @@ public class PuzzleController : SVSimController
private readonly IPuzzleClearRepository _clears;
private readonly PuzzleMissionEvaluator _evaluator;
private readonly RewardGrantService _rewards;
private readonly ILogger<PuzzleController> _logger;
public PuzzleController(
IPuzzleCatalogRepository catalog,
IPuzzleClearRepository clears,
PuzzleMissionEvaluator evaluator,
RewardGrantService rewards)
RewardGrantService rewards,
ILogger<PuzzleController> logger)
{
_catalog = catalog;
_clears = clears;
_evaluator = evaluator;
_rewards = rewards;
_logger = logger;
}
/// <summary>/basic_puzzle/info — full catalog of groups + per-viewer clear flags.</summary>
@@ -175,6 +179,7 @@ public class PuzzleController : SVSimController
// to avoid the cartesian-explode pitfall (CLAUDE.md "EF split query").
var ctx = HttpContext.RequestServices.GetRequiredService<SVSimDbContext>();
var viewer = await ctx.Viewers
.Include(v => v.Cards).ThenInclude(c => c.Card)
.Include(v => v.Sleeves)
.Include(v => v.Emblems)
.Include(v => v.LeaderSkins)
@@ -186,11 +191,22 @@ public class PuzzleController : SVSimController
foreach (var status in fresh)
{
var granted = _rewards.Apply(
viewer,
(SVSim.Database.Enums.UserGoodsType)status.Mission.RewardType,
status.Mission.RewardDetailId,
status.Mission.RewardNumber);
IReadOnlyList<GrantedReward> granted;
try
{
granted = await _rewards.ApplyAsync(
viewer,
(SVSim.Database.Enums.UserGoodsType)status.Mission.RewardType,
status.Mission.RewardDetailId,
status.Mission.RewardNumber);
}
catch (NotSupportedException ex)
{
_logger.LogWarning(ex,
"PuzzleController: skipping unsupported reward_type={Type} detail={Detail} num={Num} for mission={MissionId}",
status.Mission.RewardType, status.Mission.RewardDetailId, status.Mission.RewardNumber, status.Mission.Id);
continue;
}
response.AchievedInfo.AchievedMissionList.Add(new PuzzleAchievedMissionEntry
{
@@ -202,12 +218,15 @@ public class PuzzleController : SVSimController
MissionRewardDetailId = status.Mission.RewardDetailId,
MissionRewardNumber = status.Mission.RewardNumber,
});
response.RewardList.Add(new TreasureRewardResponse
foreach (var g in granted)
{
RewardType = granted.RewardType,
RewardId = granted.RewardId,
RewardNum = granted.RewardNum,
});
response.RewardList.Add(new TreasureRewardResponse
{
RewardType = g.RewardType,
RewardId = g.RewardId,
RewardNum = g.RewardNum,
});
}
}
await ctx.SaveChangesAsync();