From 677b1f1392a10db5472ba1c771c9bddcada0e0d5 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Mon, 1 Jun 2026 11:41:16 -0400 Subject: [PATCH] feat(battle-node): BattleResult enum for BattleFinish.result wire codes --- .../Lifecycle/ScriptedProfiles.cs | 3 --- SVSim.BattleNode/Protocol/BattleResult.cs | 19 +++++++++++++++++++ .../Protocol/Bodies/BattleFinishBody.cs | 4 +++- SVSim.BattleNode/Sessions/BattleSession.cs | 2 +- .../Protocol/Bodies/SmallBodiesTests.cs | 18 ++++++++++++++++-- 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 SVSim.BattleNode/Protocol/BattleResult.cs diff --git a/SVSim.BattleNode/Lifecycle/ScriptedProfiles.cs b/SVSim.BattleNode/Lifecycle/ScriptedProfiles.cs index 63c24b5..081bb4b 100644 --- a/SVSim.BattleNode/Lifecycle/ScriptedProfiles.cs +++ b/SVSim.BattleNode/Lifecycle/ScriptedProfiles.cs @@ -66,7 +66,4 @@ internal static class ScriptedProfiles // display state. v1 doesn't simulate the opponent — once this lands, // the client sits there indefinitely. public const int OpponentTurnStartSpin = 100; - - // BattleFinish result code for v1 no-contest finishes (player wins). - public const int BattleResultPlayerWins = 1; } diff --git a/SVSim.BattleNode/Protocol/BattleResult.cs b/SVSim.BattleNode/Protocol/BattleResult.cs new file mode 100644 index 0000000..1e0bc11 --- /dev/null +++ b/SVSim.BattleNode/Protocol/BattleResult.cs @@ -0,0 +1,19 @@ +namespace SVSim.BattleNode.Protocol; + +/// +/// Wire value of result on a BattleFinish frame. The client's +/// BattleFinishResponsProcessing switch maps these as: +/// 0 → LOSE, 1 → WIN, 2 → CONSISTENCY (desync / action-list mismatch). +/// +/// +/// This is NOT the same as the client's in-memory BATTLE_RESULT_TYPE enum +/// (NONE=0, WIN=1, LOSE=2, CONSISTENCY=3) — the wire codes shift LOSE down to 0. +/// Always serialize as the int value, not the name; see the +/// JsonNumberEnumConverter on . +/// +public enum BattleResult +{ + Lose = 0, + Win = 1, + Consistency = 2, +} diff --git a/SVSim.BattleNode/Protocol/Bodies/BattleFinishBody.cs b/SVSim.BattleNode/Protocol/Bodies/BattleFinishBody.cs index 3ac3c47..42595ec 100644 --- a/SVSim.BattleNode/Protocol/Bodies/BattleFinishBody.cs +++ b/SVSim.BattleNode/Protocol/Bodies/BattleFinishBody.cs @@ -3,5 +3,7 @@ using System.Text.Json.Serialization; namespace SVSim.BattleNode.Protocol.Bodies; public sealed record BattleFinishBody( - [property: JsonPropertyName("result")] int Result, + [property: JsonPropertyName("result")] + [property: JsonConverter(typeof(JsonNumberEnumConverter))] + BattleResult Result, [property: JsonPropertyName("resultCode")] int ResultCode = 1) : IMsgBody; diff --git a/SVSim.BattleNode/Sessions/BattleSession.cs b/SVSim.BattleNode/Sessions/BattleSession.cs index dc7ad39..aff41dc 100644 --- a/SVSim.BattleNode/Sessions/BattleSession.cs +++ b/SVSim.BattleNode/Sessions/BattleSession.cs @@ -289,7 +289,7 @@ public sealed class BattleSession Cat: EmitCategory.Battle, PubSeq: null, PlaySeq: null, - Body: new BattleFinishBody(Result: ScriptedProfiles.BattleResultPlayerWins)); + Body: new BattleFinishBody(Result: BattleResult.Win)); private static IReadOnlyList ExtractIdxList(MsgEnvelope env) { diff --git a/SVSim.UnitTests/BattleNode/Protocol/Bodies/SmallBodiesTests.cs b/SVSim.UnitTests/BattleNode/Protocol/Bodies/SmallBodiesTests.cs index a76f1eb..e51c8ed 100644 --- a/SVSim.UnitTests/BattleNode/Protocol/Bodies/SmallBodiesTests.cs +++ b/SVSim.UnitTests/BattleNode/Protocol/Bodies/SmallBodiesTests.cs @@ -1,6 +1,7 @@ using System.Text.Json; using System.Text.Json.Nodes; using NUnit.Framework; +using SVSim.BattleNode.Protocol; using SVSim.BattleNode.Protocol.Bodies; namespace SVSim.UnitTests.BattleNode.Protocol.Bodies; @@ -31,9 +32,11 @@ public class SmallBodiesTests } [Test] - public void BattleFinishBody_SerializesResultAndResultCode() + public void BattleFinishBody_SerializesResultAndResultCode_AsNumericWireValues() { - var body = new BattleFinishBody(Result: 1); + // The wire field is the int code (Win=1); BattleResult uses JsonNumberEnumConverter + // to override the default JsonStringEnumConverter (which would emit "Win" instead). + var body = new BattleFinishBody(Result: BattleResult.Win); var node = (JsonObject)JsonSerializer.SerializeToNode(body)!; @@ -41,6 +44,17 @@ public class SmallBodiesTests Assert.That(node["resultCode"]!.GetValue(), Is.EqualTo(1)); } + [Test] + public void BattleFinishBody_LoseAndConsistency_SerializeAsZeroAndTwo() + { + // Lock the wire values per BattleFinishResponsProcessing's switch (0=LOSE, 2=CONSISTENCY). + var lose = (JsonObject)JsonSerializer.SerializeToNode(new BattleFinishBody(BattleResult.Lose))!; + var consistency = (JsonObject)JsonSerializer.SerializeToNode(new BattleFinishBody(BattleResult.Consistency))!; + + Assert.That(lose["result"]!.GetValue(), Is.EqualTo(0)); + Assert.That(consistency["result"]!.GetValue(), Is.EqualTo(2)); + } + [Test] public void AlivePushBody_SerializesScsAndOcs_AndDoesNotIncludeResultCode() {