using SVSim.BattleNode.Bridge; namespace SVSim.EmulatedEntrypoint.Matching; /// /// Single source of truth for how a /do_matching request is resolved into a wire /// matching_state + battle_id + node_server_url across every battle family. /// /// Lives here (and not on each controller) because the resolution rules are the same /// regardless of which URL family carried the request: /// /// /// Consult and translate the /// resulting into a wire matching_state per the /// 3002 / 3004 / 3007 / 3011 vocabulary. /// /// /// Family-specific details (DTO shapes, family-specific request fields like /// card_master_id, error-mapping like rank-battle's 3001 on a missing deck) stay /// on the controllers. The resolver only owns the cross-cutting "did the flag win, did /// pair-up resolve, what's the state code" decision. /// /// public interface IMatchingResolver { /// /// The matching-mode key the resolver passes through to /// — one of the /// registry's mode names (e.g. "arena_two_pick_battle", /// "rotation_rank_battle", "unlimited_rank_battle"). /// /// Caller's (viewer-id + built MatchContext). Task ResolveAsync( string mode, BattlePlayer player, CancellationToken ct); } /// /// Wire-level outcome of a /do_matching resolution. Always carries a non-null /// — empty string while parked (3002), real URL on resolution — /// because the client's DoMatchingBase.SettingDoMatchingData() calls /// .ToString() on the wire field without a Keys.Contains guard. /// public sealed record MatchingResolution(int MatchingState, string? BattleId, string NodeServerUrl);