Files
SVSimServer/SVSim.EmulatedEntrypoint/Models/Dtos/RankBattle/RankBattleFinishRequestDto.cs
gamer147 bf783639c1 fix(rank-battle): inherit BaseRequest so auth fields survive translation roundtrip
The translation middleware decrypts + msgpack-decodes the request body
into the action's first-parameter type, then re-serializes that DTO to
JSON for the auth handler to read. Phase 3's DoMatchingRequestDto and
RankBattleFinishRequestDto didn't inherit BaseRequest, so viewer_id /
steam_id / steam_session_ticket were dropped during the msgpack → DTO
→ JSON pivot — the auth handler then saw a body with no auth fields
and 401'd every request.

Fixed by making both DTOs extend BaseRequest, mirroring the Phase 2 TK2
DoMatchingRequest pattern.

Also added [FromBody] BaseRequest parameters to the previously body-less
actions (AiStart × 2, ForceFinish, AddClientLog, GetLatestMasterPoint).
The translation middleware explicitly requires at least one parameter
to bind the decrypted msgpack body (see L130-136 of the middleware);
without it the request would throw InvalidOperationException at runtime.

Tests updated to post viewer_id / steam_id / steam_session_ticket
placeholder values in the request body, matching the existing TK2 test
pattern.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 09:29:48 -04:00

51 lines
1.5 KiB
C#

using System.Text.Json.Serialization;
using MessagePack;
using SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.RankBattle;
/// <summary>
/// Standard BattleFinishParam shape — see docs/api-spec/common/types.ts.md and
/// docs/api-spec/endpoints/post-login/rank-battle/finish.md. Future: promote to
/// a shared common DTO when a second finish endpoint reuses this.
///
/// Inherits viewer_id / steam_id / steam_session_ticket from <see cref="BaseRequest"/>
/// so the auth fields survive the translation-middleware round-trip.
/// </summary>
[MessagePackObject]
public sealed class RankBattleFinishRequestDto : BaseRequest
{
[JsonPropertyName("battle_result")]
[Key("battle_result")]
public int BattleResult { get; set; }
[JsonPropertyName("is_retire")]
[Key("is_retire")]
public int IsRetire { get; set; }
[JsonPropertyName("recovery_data")]
[Key("recovery_data")]
public string? RecoveryData { get; set; }
[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; }
// RankBattleFinishTask extends BattleFinishParam with SDTRB.
[JsonPropertyName("sdtrb")]
[Key("sdtrb")]
public int Sdtrb { get; set; }
}