refactor(battlenode): rename mode-id field off BattleType, add BattleModes (§D)

Behavior-preserving; 271 BattleNode/Matching/Services tests green, full solution builds.

"BattleType" meant two things: the Sessions.BattleType enum (Pvp/Bot) and an int
"mode id" field. Renamed the int field on MatchContext AND the BattleStartBody wire
DTO to BattleModeId (wire key stays "battleType" via JsonPropertyName), so BattleType
now means only the enum project-wide.

New Bridge/BattleModes.cs (TakeTwo = 11) replaces every 11 literal — both prod
MatchContextBuilder sites and the test fixtures/assertions. The arbitrary-passthrough
42 and bot 0 stay literal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-05 07:44:02 -04:00
parent d119d2c277
commit 578d0a75ef
24 changed files with 57 additions and 37 deletions

View File

@@ -0,0 +1,14 @@
namespace SVSim.BattleNode.Bridge;
/// <summary>
/// Known values for <see cref="MatchContext.BattleModeId"/> — the prod do_matching battle-mode id,
/// forwarded verbatim onto the wire (<c>battleType</c> field on BattleStart). Names the otherwise
/// magic <c>11</c>. Distinct from the <see cref="Sessions.BattleType"/> enum (Pvp/Bot), which is the
/// session topology, not the game mode.
/// </summary>
public static class BattleModes
{
/// <summary>Take Two (TK2) — the two-pick draft mode the v1 captures were taken from. Prod
/// rank-battle frames carry the same value (see <c>MatchContextBuilder</c>).</summary>
public const int TakeTwo = 11;
}

View File

@@ -25,5 +25,8 @@ public sealed record MatchContext(
int FieldId,
int IsOfficial, // 0 or 1
// Battle-mode hint, currently TK2 == 11. Future modes populate their own value.
int BattleType);
// Battle-mode hint (the prod do_matching mode id). Named BattleModeId, NOT BattleType, to
// avoid colliding with the <see cref="Sessions.BattleType"/> enum (Pvp/Bot) — a different axis.
// Known values live in <see cref="BattleModes"/> (currently just TK2 == 11). Future modes add
// their own constant.
int BattleModeId);

View File

@@ -55,7 +55,7 @@ public static class ServerBattleFrames
EnvelopeForPush(NetworkBattleUri.BattleStart,
new BattleStartBody(
TurnState: turnState, // First = this side goes first, Second = second. Caller decides.
BattleType: selfCtx.BattleType,
BattleModeId: selfCtx.BattleModeId,
SelfInfo: new BattleStartSelfInfo(
Rank: BattleFrameDefaults.PlayerRank,
BattlePoint: BattleFrameDefaults.PlayerBattlePoint,

View File

@@ -5,7 +5,9 @@ namespace SVSim.BattleNode.Protocol.Bodies;
public sealed record BattleStartBody(
[property: JsonPropertyName("turnState")]
[property: JsonConverter(typeof(JsonNumberEnumConverter<TurnState>))] TurnState TurnState,
[property: JsonPropertyName("battleType")] int BattleType,
// Wire key stays "battleType" (the client's contract); the CLR name is BattleModeId so the
// project keeps one meaning of "BattleType" — the Sessions.BattleType enum (Pvp/Bot).
[property: JsonPropertyName("battleType")] int BattleModeId,
[property: JsonPropertyName("selfInfo")] BattleStartSelfInfo SelfInfo,
[property: JsonPropertyName("oppoInfo")] BattleStartOppoInfo OppoInfo,
[property: JsonPropertyName("resultCode")] int ResultCode = (int)ReceiveNodeResultCode.Success) : IMsgBody;

View File

@@ -23,7 +23,7 @@ public sealed class NoOpBotParticipant : IBattleParticipant
ClassId: "0", CharaId: "0", CardMasterName: BotCardMasterName,
CountryCode: "", UserName: "Bot", SleeveId: "0",
EmblemId: "0", DegreeId: "0", FieldId: 0, IsOfficial: 0,
BattleType: 0);
BattleModeId: 0);
// Required by IBattleParticipant, but a silent bot never raises it — suppress the
// "event is never used" warning rather than keeping a dead null-emitting method.