using Microsoft.AspNetCore.Mvc; using SVSim.BattleNode.Bridge; using SVSim.EmulatedEntrypoint.Matching; using SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick; using SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ArenaTwoPick; using SVSim.EmulatedEntrypoint.Services; namespace SVSim.EmulatedEntrypoint.Controllers; [Route("arena_two_pick_battle")] public class ArenaTwoPickBattleController : SVSimController { private readonly IArenaTwoPickService _svc; private readonly IMatchContextBuilder _matchContextBuilder; private readonly IMatchingResolver _resolver; public ArenaTwoPickBattleController( IArenaTwoPickService svc, IMatchContextBuilder matchContextBuilder, IMatchingResolver resolver) { _svc = svc; _matchContextBuilder = matchContextBuilder; _resolver = resolver; } [HttpPost("do_matching")] public async Task DoMatching( [FromBody] DoMatchingRequest req, [FromQuery(Name = "scripted")] string? scripted = null, CancellationToken ct = default) { if (!TryGetViewerId(out var vid)) return Unauthorized(); // Accept "1" or "true" (case-insensitive) as per-request opt-in for the Scripted // path. ASP.NET's default bool binder rejects "1", so parse permissively here. // BattleNodeOptions.SoloDefaultsToScripted is the process-wide equivalent and is // applied inside the resolver. var scriptedOptIn = scripted is not null && (scripted == "1" || string.Equals(scripted, "true", StringComparison.OrdinalIgnoreCase)); try { var ctx = await _matchContextBuilder.BuildForTwoPickAsync(vid); var r = await _resolver.ResolveAsync("arena_two_pick_battle", new BattlePlayer(vid, ctx), scriptedOptIn, ct); return Ok(new DoMatchingResponseDto { MatchingState = r.MatchingState, BattleId = r.BattleId, NodeServerUrl = r.NodeServerUrl, }); } catch (ArenaTwoPickException ex) { return BadRequest(new { error_code = ex.ErrorCode }); } } [HttpPost("finish")] public async Task Finish([FromBody] BattleFinishRequest req) { if (!TryGetViewerId(out var vid)) return Unauthorized(); try { var result = await _svc.RecordBattleResultAsync(vid, req.BattleResult == 1); return Ok(new BattleFinishResponseDto { BattleResult = result.BattleResult, GetClassExperience = result.GetClassExperience, ClassExperience = result.ClassExperience, ClassLevel = result.ClassLevel, SpotPointInfo = new SpotPointInfoDto { BeforeSpotPoint = result.BeforeSpotPoint, AddSpotPoint = result.AddSpotPoint, AfterSpotPoint = result.AfterSpotPoint, }, }); } catch (ArenaTwoPickException ex) { return BadRequest(new { error_code = ex.ErrorCode }); } } }