perf(net): frame recurring sends in place

Write normal game-message and ACK packet framing directly into bounded stack spans, hash fragments without materialization, and send the populated slice to the socket. Preserve exact wire bytes and ISAAC failure ordering with differential and zero-allocation tests.
This commit is contained in:
Erik 2026-07-25 06:02:52 +02:00
parent e928c5dd02
commit 41c1a59392
7 changed files with 485 additions and 31 deletions

View file

@ -2152,17 +2152,28 @@ public sealed class WorldSession : IDisposable
private void SendGameMessage(byte[] gameMessageBody, GameMessageGroup queue)
{
var fragment = GameMessageFragment.BuildSingleFragment(
_fragmentSequence++, queue, gameMessageBody);
byte[] packetBody = GameMessageFragment.Serialize(fragment);
Span<byte> datagram = stackalloc byte[
PacketHeader.Size
+ MessageFragmentHeader.MaxFragmentSize];
int fragmentLength =
GameMessageFragment.WriteSingleFragment(
datagram.Slice(PacketHeader.Size),
_fragmentSequence++,
queue,
gameMessageBody);
var header = new PacketHeader
{
Sequence = _clientPacketSequence++,
Flags = PacketHeaderFlags.BlobFragments | PacketHeaderFlags.EncryptedChecksum,
Id = _sessionClientId,
};
byte[] datagram = PacketCodec.Encode(header, packetBody, _outboundIsaac);
_net.Send(datagram);
int datagramLength = PacketCodec.FinalizeInPlace(
header,
datagram,
fragmentLength,
optionalLength: 0,
_outboundIsaac);
_net.Send(datagram.Slice(0, datagramLength));
}
/// <summary>
@ -2191,8 +2202,11 @@ public sealed class WorldSession : IDisposable
private void SendAck(uint serverPacketSequence)
{
// 4-byte body: little-endian u32 of the server sequence we're acking.
Span<byte> body = stackalloc byte[4];
BinaryPrimitives.WriteUInt32LittleEndian(body, serverPacketSequence);
Span<byte> datagram = stackalloc byte[
PacketHeader.Size + sizeof(uint)];
BinaryPrimitives.WriteUInt32LittleEndian(
datagram.Slice(PacketHeader.Size),
serverPacketSequence);
// Holtburger uses current_client_sequence (= packet_sequence - 1) for
// ack headers. We mirror that — acks borrow the most recently issued
@ -2208,8 +2222,13 @@ public sealed class WorldSession : IDisposable
Id = _sessionClientId,
};
byte[] datagram = PacketCodec.Encode(header, body, outboundIsaac: null);
_net.Send(datagram);
int datagramLength = PacketCodec.FinalizeInPlace(
header,
datagram,
bodyLength: sizeof(uint),
optionalLength: sizeof(uint),
outboundIsaac: null);
_net.Send(datagram.Slice(0, datagramLength));
}
private void Transition(State next)