The wire-stack audit checked the transport layer by hand and found it clean: PacketHeader's seven fields match ACE's Pack order exactly, the optional-header sections are parsed in ACE's order, and PacketHeaderFlags is a twenty-three of twenty-three value match including the sparse gaps between 0x04 and 0x100 and between 0x00800000 and 0x01000000. Clean is worth freezing. These bits are not design choices; each one gates an optional-header section, so a single wrong value shifts every following section's offset and takes the packet checksum with it. The failure would not look like a wrong flag, it would look like a corrupt connection. The enum is small enough to pin exhaustively, so this transcribes ACE's declaration and asserts both directions: every ACE flag exists here with ACE's value, and we declare nothing ACE does not. Core.Net tests go 630 to 654. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
90 lines
3.4 KiB
C#
90 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using AcDream.Core.Net.Packets;
|
|
using Xunit;
|
|
|
|
namespace AcDream.Core.Net.Tests.Packets;
|
|
|
|
/// <summary>
|
|
/// Value-conformance for the transport flag word against ACE's
|
|
/// <c>Source/ACE.Server/Network/PacketHeaderFlags.cs</c>, read 2026-07-29
|
|
/// during the wire-stack audit.
|
|
///
|
|
/// <para>These are wire-format facts, not choices: a flag bit is the gate for
|
|
/// an optional-header section, so a single wrong value silently shifts every
|
|
/// subsequent section's offset and corrupts the packet checksum. The enum is
|
|
/// small enough to pin exhaustively, and doing so makes any future edit a
|
|
/// deliberate act rather than a typo.</para>
|
|
///
|
|
/// <para>The audit found acdream's enum a 23-of-23 match with ACE's, including
|
|
/// the sparse gaps (nothing between 0x04 and 0x100, nothing between 0x00800000
|
|
/// and 0x01000000). This test freezes that result.</para>
|
|
/// </summary>
|
|
public class PacketHeaderFlagsConformanceTests
|
|
{
|
|
/// <summary>
|
|
/// Transcribed from ACE's PacketHeaderFlags enum, in declaration order.
|
|
/// The trailing comments are ACE's own.
|
|
/// </summary>
|
|
private static readonly (string Name, uint Value)[] AceFlags =
|
|
{
|
|
("None", 0x00000000u),
|
|
("Retransmission", 0x00000001u),
|
|
("EncryptedChecksum", 0x00000002u), // can't be paired with 0x1
|
|
("BlobFragments", 0x00000004u),
|
|
("ServerSwitch", 0x00000100u),
|
|
("LogonServerAddr", 0x00000200u),
|
|
("EmptyHeader1", 0x00000400u),
|
|
("Referral", 0x00000800u),
|
|
("RequestRetransmit", 0x00001000u), // Nak
|
|
("RejectRetransmit", 0x00002000u), // Empty Ack
|
|
("AckSequence", 0x00004000u), // Pak
|
|
("Disconnect", 0x00008000u), // Empty Header 2
|
|
("LoginRequest", 0x00010000u),
|
|
("WorldLoginRequest", 0x00020000u),
|
|
("ConnectRequest", 0x00040000u),
|
|
("ConnectResponse", 0x00080000u),
|
|
("NetError", 0x00100000u),
|
|
("NetErrorDisconnect", 0x00200000u),
|
|
("CICMDCommand", 0x00400000u),
|
|
("TimeSync", 0x01000000u),
|
|
("EchoRequest", 0x02000000u),
|
|
("EchoResponse", 0x04000000u),
|
|
("Flow", 0x08000000u),
|
|
};
|
|
|
|
public static TheoryData<string, uint> Flags()
|
|
{
|
|
var data = new TheoryData<string, uint>();
|
|
foreach ((string name, uint value) in AceFlags)
|
|
data.Add(name, value);
|
|
return data;
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(Flags))]
|
|
public void Flag_MatchesAceValue(string name, uint aceValue)
|
|
{
|
|
Assert.True(
|
|
Enum.IsDefined(typeof(PacketHeaderFlags), aceValue) || aceValue == 0,
|
|
$"ACE declares {name} = 0x{aceValue:X8}; acdream has no such value.");
|
|
|
|
object parsed = Enum.Parse(typeof(PacketHeaderFlags), name);
|
|
Assert.Equal(aceValue, (uint)(PacketHeaderFlags)parsed);
|
|
}
|
|
|
|
[Fact]
|
|
public void EnumHasNoMembersAceDoesNotDeclare()
|
|
{
|
|
HashSet<string> ace = AceFlags.Select(f => f.Name).ToHashSet(StringComparer.Ordinal);
|
|
string[] ours = Enum.GetNames(typeof(PacketHeaderFlags));
|
|
|
|
string[] extra = ours.Where(n => !ace.Contains(n)).ToArray();
|
|
|
|
Assert.True(
|
|
extra.Length == 0,
|
|
$"acdream declares flags ACE does not: {string.Join(", ", extra)}");
|
|
Assert.Equal(AceFlags.Length, ours.Length);
|
|
}
|
|
}
|