feat(http): ArenaTwoPickBattleController (do_matching stub + finish)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
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;
|
||||
public ArenaTwoPickBattleController(IArenaTwoPickService svc) => _svc = svc;
|
||||
|
||||
[HttpPost("do_matching")]
|
||||
public IActionResult DoMatching([FromBody] DoMatchingRequest req)
|
||||
{
|
||||
if (!TryGetViewerId(out _)) return Unauthorized();
|
||||
return Ok(new DoMatchingResponseDto());
|
||||
}
|
||||
|
||||
[HttpPost("finish")]
|
||||
public async Task<IActionResult> 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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MessagePack;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class BattleFinishRequest
|
||||
{
|
||||
[JsonPropertyName("class_id")] [Key("class_id")] public int ClassId { get; set; }
|
||||
[JsonPropertyName("total_turn")] [Key("total_turn")] public int TotalTurn { get; set; }
|
||||
[JsonPropertyName("evolve_count")] [Key("evolve_count")] public int EvolveCount { get; set; }
|
||||
[JsonPropertyName("enemy_evolve_count")] [Key("enemy_evolve_count")] public int EnemyEvolveCount { get; set; }
|
||||
[JsonPropertyName("battle_result")] [Key("battle_result")] public int BattleResult { get; set; }
|
||||
[JsonPropertyName("is_retire")] [Key("is_retire")] public int IsRetire { get; set; }
|
||||
[JsonPropertyName("SDTRB")] [Key("SDTRB")] public int Sdtrb { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MessagePack;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class DoMatchingRequest
|
||||
{
|
||||
[JsonPropertyName("card_master_hash")] [Key("card_master_hash")] public string? CardMasterHash { get; set; }
|
||||
[JsonPropertyName("deck_no")] [Key("deck_no")] public long DeckNo { get; set; }
|
||||
[JsonPropertyName("need_init")] [Key("need_init")] public int NeedInit { get; set; }
|
||||
[JsonPropertyName("log")] [Key("log")] public int Log { get; set; }
|
||||
[JsonPropertyName("excluded_field_id_list")] [Key("excluded_field_id_list")] public List<long> ExcludedFieldIdList { get; set; } = new();
|
||||
[JsonPropertyName("use_stage_select")] [Key("use_stage_select")] public int UseStageSelect { get; set; }
|
||||
[JsonPropertyName("is_default_skin")] [Key("is_default_skin")] public int IsDefaultSkin { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MessagePack;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Common.ArenaTwoPick;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class BattleFinishResponseDto
|
||||
{
|
||||
[JsonPropertyName("class_experience")] [Key("class_experience")]
|
||||
public int ClassExperience { get; set; }
|
||||
|
||||
[JsonPropertyName("get_class_experience")] [JsonConverter(typeof(StringifiedIntConverter))] [Key("get_class_experience")]
|
||||
public int GetClassExperience { get; set; }
|
||||
|
||||
[JsonPropertyName("class_level")] [JsonConverter(typeof(StringifiedIntConverter))] [Key("class_level")]
|
||||
public int ClassLevel { get; set; }
|
||||
|
||||
[JsonPropertyName("battle_result")] [Key("battle_result")]
|
||||
public int BattleResult { get; set; }
|
||||
|
||||
[JsonPropertyName("spot_point_info")] [Key("spot_point_info")]
|
||||
public SpotPointInfoDto SpotPointInfo { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("achieved_info")] [Key("achieved_info")]
|
||||
public ArenaTwoPickAchievedInfoDto AchievedInfo { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("result_decision")] [Key("result_decision")]
|
||||
public int ResultDecision { get; set; } = 1;
|
||||
|
||||
[JsonPropertyName("reward_list")] [Key("reward_list")]
|
||||
public List<RewardEntryDto> RewardList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("gathering_notification")] [Key("gathering_notification")]
|
||||
public GatheringNotificationDto GatheringNotification { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("battle_dialog_list")] [Key("battle_dialog_list")]
|
||||
public List<object> BattleDialogList { get; set; } = new();
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SpotPointInfoDto
|
||||
{
|
||||
[JsonPropertyName("before_spot_point")] [Key("before_spot_point")] public int BeforeSpotPoint { get; set; }
|
||||
[JsonPropertyName("add_spot_point")] [JsonConverter(typeof(StringifiedIntConverter))] [Key("add_spot_point")] public int AddSpotPoint { get; set; }
|
||||
[JsonPropertyName("after_spot_point")] [Key("after_spot_point")] public int AfterSpotPoint { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class GatheringNotificationDto
|
||||
{
|
||||
[JsonPropertyName("matching_established_message")] [Key("matching_established_message")]
|
||||
public string MatchingEstablishedMessage { get; set; } = "";
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class ArenaTwoPickAchievedInfoDto
|
||||
{
|
||||
[JsonPropertyName("achieved_achievement_list")] [Key("achieved_achievement_list")]
|
||||
public List<object> AchievedAchievementList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("achieved_mission_list")] [Key("achieved_mission_list")]
|
||||
public List<object> AchievedMissionList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("achieved_mission_reward_list")] [Key("achieved_mission_reward_list")]
|
||||
public List<object> AchievedMissionRewardList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("grand_master_reward_list")] [Key("grand_master_reward_list")]
|
||||
public List<object> GrandMasterRewardList { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("mission_start_data")] [Key("mission_start_data")]
|
||||
public List<object> MissionStartData { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MessagePack;
|
||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ArenaTwoPick;
|
||||
|
||||
[MessagePackObject]
|
||||
public class DoMatchingResponseDto
|
||||
{
|
||||
[JsonPropertyName("timeout_period")] [JsonConverter(typeof(StringifiedIntConverter))] [Key("timeout_period")]
|
||||
public int TimeoutPeriod { get; set; } = 50;
|
||||
|
||||
[JsonPropertyName("retry_period")] [JsonConverter(typeof(StringifiedIntConverter))] [Key("retry_period")]
|
||||
public int RetryPeriod { get; set; } = 3;
|
||||
|
||||
[JsonPropertyName("node_server_url")] [Key("node_server_url")]
|
||||
public string NodeServerUrl { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("room_param")] [Key("room_param")]
|
||||
public string RoomParam { get; set; } = "";
|
||||
|
||||
[JsonPropertyName("matching_state")] [Key("matching_state")]
|
||||
public int MatchingState { get; set; } = 3002;
|
||||
|
||||
[JsonPropertyName("mission_parameter")] [Key("mission_parameter")]
|
||||
public Dictionary<string, string> MissionParameter { get; set; } = new()
|
||||
{
|
||||
["follower_play_count_for_mission"] = "{me.game_play_cards_other_self.unit.count}",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using SVSim.UnitTests.Infrastructure;
|
||||
|
||||
namespace SVSim.UnitTests.Controllers;
|
||||
|
||||
public class ArenaTwoPickBattleControllerTests
|
||||
{
|
||||
[Test]
|
||||
public async Task DoMatching_returns_perpetual_searching_with_empty_node_url()
|
||||
{
|
||||
using var factory = new SVSimTestFactory();
|
||||
var viewerId = await factory.SeedViewerAsync();
|
||||
using var client = factory.CreateAuthenticatedClient(viewerId);
|
||||
var req = new { deck_no = 1L, need_init = 1, log = 1, excluded_field_id_list = new long[] { }, use_stage_select = 1, is_default_skin = 0 };
|
||||
var resp = await client.PostAsync("/arena_two_pick_battle/do_matching", JsonContent.Create(req));
|
||||
|
||||
Assert.That(resp.StatusCode, Is.EqualTo(HttpStatusCode.OK));
|
||||
var body = await resp.Content.ReadAsStringAsync();
|
||||
StringAssert.Contains("\"matching_state\":3002", body);
|
||||
StringAssert.Contains("\"node_server_url\":\"\"", body);
|
||||
StringAssert.DoesNotContain("\"battle_id\"", body);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user