feat(pack): /pack/open supports type_detail=10 FREE_PACKS with per-campaign daily quota
This commit is contained in:
@@ -305,14 +305,15 @@ public class PackController : SVSimController
|
||||
// 4 TICKET / 5 TICKET_MULTI -> consume child.ItemId from OwnedItemEntry
|
||||
// Skin-overload types (8/9/13) and free-pack overlays (10/11/12) need extra
|
||||
// selection / banner plumbing — kept 501 until the relevant flows land.
|
||||
if (!isTutorialPath && child.TypeDetail is not (1 or 2 or 3 or 4 or 5 or 6 or 7))
|
||||
if (!isTutorialPath && child.TypeDetail is not (1 or 2 or 3 or 4 or 5 or 6 or 7 or 10))
|
||||
return StatusCode(StatusCodes.Status501NotImplemented, new { error = "currency_path_not_implemented" });
|
||||
|
||||
// Load viewer via InventoryService transaction with extra includes for pack-open needs.
|
||||
await using var tx = await _inv.BeginAsync(viewerId, HttpContext.RequestAborted, cfg => cfg
|
||||
.WithInclude(v => v.PackOpenCounts)
|
||||
.WithInclude(v => v.GachaPointBalances)
|
||||
.WithInclude(v => v.MissionData));
|
||||
.WithInclude(v => v.MissionData)
|
||||
.WithInclude(v => v.FreePackClaims));
|
||||
var viewer = tx.Viewer;
|
||||
|
||||
// Tutorial alias is only valid pre-END. After state>=100 the viewer has already
|
||||
@@ -371,6 +372,42 @@ public class PackController : SVSimController
|
||||
if (!debit.Success) return BadRequest(new { error = "insufficient_tickets" });
|
||||
break;
|
||||
}
|
||||
case 10: // FREE_PACKS — no currency, no ticket; gated by daily quota per campaign
|
||||
{
|
||||
if (child.FreeGachaCampaignId is not int campaignId)
|
||||
return StatusCode(StatusCodes.Status501NotImplemented, new { error = "free_pack_missing_campaign_id" });
|
||||
|
||||
int dailyCap = child.DailyFreeGachaCount > 0 ? child.DailyFreeGachaCount : 1;
|
||||
var today = DateTime.UtcNow.Date;
|
||||
var existing = viewer.FreePackClaims.FirstOrDefault(c => c.FreeGachaCampaignId == campaignId);
|
||||
if (existing is not null && existing.LastClaimedAt.Date == today && existing.ClaimCount >= dailyCap)
|
||||
return BadRequest(new { error = "free_pack_already_claimed_today" });
|
||||
|
||||
// pack_number is forced to 1 — free-pack metadata never authorizes multi-opens.
|
||||
// The capture shows pack_number=1 even when daily_free_gacha_count=1 == daily quota.
|
||||
packNumber = 1;
|
||||
|
||||
if (existing is null)
|
||||
{
|
||||
viewer.FreePackClaims.Add(new ViewerFreePackClaim
|
||||
{
|
||||
FreeGachaCampaignId = campaignId,
|
||||
ClaimCount = 1,
|
||||
LastClaimedAt = DateTime.UtcNow,
|
||||
});
|
||||
}
|
||||
else if (existing.LastClaimedAt.Date != today)
|
||||
{
|
||||
existing.ClaimCount = 1;
|
||||
existing.LastClaimedAt = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.ClaimCount++;
|
||||
existing.LastClaimedAt = DateTime.UtcNow;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user