feat(battle-node): BattleResult enum for BattleFinish.result wire codes

This commit is contained in:
gamer147
2026-06-01 11:41:16 -04:00
parent eaf6d7160b
commit 677b1f1392
5 changed files with 39 additions and 7 deletions

View File

@@ -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;
}

View File

@@ -0,0 +1,19 @@
namespace SVSim.BattleNode.Protocol;
/// <summary>
/// Wire value of <c>result</c> on a BattleFinish frame. The client's
/// <c>BattleFinishResponsProcessing</c> switch maps these as:
/// 0 → LOSE, 1 → WIN, 2 → CONSISTENCY (desync / action-list mismatch).
/// </summary>
/// <remarks>
/// This is NOT the same as the client's in-memory <c>BATTLE_RESULT_TYPE</c> 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
/// <c>JsonNumberEnumConverter</c> on <see cref="Bodies.BattleFinishBody.Result"/>.
/// </remarks>
public enum BattleResult
{
Lose = 0,
Win = 1,
Consistency = 2,
}

View File

@@ -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>))]
BattleResult Result,
[property: JsonPropertyName("resultCode")] int ResultCode = 1) : IMsgBody;

View File

@@ -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<long> ExtractIdxList(MsgEnvelope env)
{

View File

@@ -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<int>(), 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<int>(), Is.EqualTo(0));
Assert.That(consistency["result"]!.GetValue<int>(), Is.EqualTo(2));
}
[Test]
public void AlivePushBody_SerializesScsAndOcs_AndDoesNotIncludeResultCode()
{