134 lines
4.4 KiB
C#
134 lines
4.4 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using SVSim.Database.Enums;
|
|
using SVSim.Database.Models;
|
|
using SVSim.Database.Repositories.Viewer;
|
|
using SVSim.EmulatedEntrypoint.Constants;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Common;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.Practice;
|
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Responses.Practice;
|
|
|
|
namespace SVSim.EmulatedEntrypoint.Controllers;
|
|
|
|
public class PracticeController : SVSimController
|
|
{
|
|
// Hand-curated AI opponents (audit B14 pattern). Replace with master data when the
|
|
// practice subsystem is built out.
|
|
private static readonly List<PracticeOpponent> StubOpponents = new()
|
|
{
|
|
new PracticeOpponent
|
|
{
|
|
PracticeId = 1,
|
|
TextId = "Practice_001",
|
|
ClassId = 1,
|
|
CharaId = 1,
|
|
DegreeId = 0,
|
|
AiDeckLevel = 1,
|
|
AiLogicLevel = 1,
|
|
AiMaxLife = 20,
|
|
Battle3dFieldId = "1",
|
|
IsCampaignPractice = false
|
|
},
|
|
new PracticeOpponent
|
|
{
|
|
PracticeId = 2,
|
|
TextId = "Practice_002",
|
|
ClassId = 2,
|
|
CharaId = 2,
|
|
DegreeId = 0,
|
|
AiDeckLevel = 2,
|
|
AiLogicLevel = 2,
|
|
AiMaxLife = 20,
|
|
Battle3dFieldId = "1",
|
|
IsCampaignPractice = false
|
|
},
|
|
new PracticeOpponent
|
|
{
|
|
PracticeId = 3,
|
|
TextId = "Practice_003",
|
|
ClassId = 3,
|
|
CharaId = 3,
|
|
DegreeId = 0,
|
|
AiDeckLevel = 3,
|
|
AiLogicLevel = 3,
|
|
AiMaxLife = 25,
|
|
Battle3dFieldId = "1",
|
|
IsCampaignPractice = false
|
|
}
|
|
};
|
|
|
|
private readonly IViewerRepository _viewerRepository;
|
|
|
|
public PracticeController(IViewerRepository viewerRepository)
|
|
{
|
|
_viewerRepository = viewerRepository;
|
|
}
|
|
|
|
/// <summary>
|
|
/// /practice/info — returns the AI opponent catalog. Response data is a JSON array
|
|
/// directly (not wrapped in an object), per spec.
|
|
/// </summary>
|
|
[HttpPost("info")]
|
|
public Task<List<PracticeOpponent>> Info(BaseRequest request)
|
|
{
|
|
return Task.FromResult(StubOpponents);
|
|
}
|
|
|
|
/// <summary>
|
|
/// /practice/deck_list — returns viewer's decks scoped by format (always Format.All
|
|
/// per spec, server can ignore the request field).
|
|
/// </summary>
|
|
[HttpPost("deck_list")]
|
|
public async Task<ActionResult<PracticeDeckListResponse>> DeckList(DeckFormatRequest request)
|
|
{
|
|
var shortUdidClaim = User.Claims.FirstOrDefault(c => c.Type == ShadowverseClaimTypes.ShortUdidClaim)?.Value;
|
|
if (shortUdidClaim is null || !long.TryParse(shortUdidClaim, out long shortUdid))
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
Viewer? viewer = await _viewerRepository.GetViewerByShortUdid(shortUdid);
|
|
if (viewer is null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
return new PracticeDeckListResponse
|
|
{
|
|
MaintenanceCardList = new List<long>(),
|
|
UserDeckRotation = viewer.Decks.Where(d => d.Format == Format.Rotation)
|
|
.Select(d => new UserDeck(d)).ToList(),
|
|
UserDeckUnlimited = viewer.Decks.Where(d => d.Format == Format.Unlimited)
|
|
.Select(d => new UserDeck(d)).ToList()
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// /practice/start — server is essentially a no-op for practice. Spec: empty body
|
|
/// response is fine; client tolerates missing mission_parameter.
|
|
/// </summary>
|
|
[HttpPost("start")]
|
|
public Task<PracticeStartResponse> Start(BaseRequest request)
|
|
{
|
|
return Task.FromResult(new PracticeStartResponse());
|
|
}
|
|
|
|
/// <summary>
|
|
/// /practice/finish — accept the recovery_data blob without validation; return zero
|
|
/// XP / no rewards. Class XP bookkeeping is deferred until a per-class XP store exists.
|
|
/// </summary>
|
|
[HttpPost("finish")]
|
|
public Task<PracticeFinishResponse> Finish(PracticeFinishRequest request)
|
|
{
|
|
return Task.FromResult(new PracticeFinishResponse
|
|
{
|
|
GetClassExperience = 0,
|
|
ClassExperience = 0,
|
|
ClassLevel = 1,
|
|
AchievedInfo = new Dictionary<string, object>(),
|
|
RewardList = new List<Models.Dtos.Common.Reward>()
|
|
});
|
|
}
|
|
}
|