From 7013651a904bd748a2fc3ded87f2907f5e388436 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 21 Jun 2026 18:55:56 +0200 Subject: [PATCH] =?UTF-8?q?fix(net):=20D.2b-B=20B-Wire=20=E2=80=94=20Parse?= =?UTF-8?q?InventoryServerSaveFailed=20reads=20weenieError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0x00A0 InventoryServerSaveFailed carries (itemGuid, weenieError) per ACE GameEventInventoryServerSaveFailed.cs and holtburger events.rs:147. The old parser returned only the itemGuid as uint?, silently dropping the error code. Replaced with a typed InventoryServerSaveFailed record that reads both u32s (8-byte guard). Parser was unwired (no callers in GameEvents.cs or GameEventWiring.cs) so the signature change is safe. 1 new test in GameEventsInventoryTests. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/AcDream.Core.Net/Messages/GameEvents.cs | 14 ++++++++++---- .../Messages/GameEventsInventoryTests.cs | 13 +++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/AcDream.Core.Net/Messages/GameEvents.cs b/src/AcDream.Core.Net/Messages/GameEvents.cs index edb98809..71c7a4f5 100644 --- a/src/AcDream.Core.Net/Messages/GameEvents.cs +++ b/src/AcDream.Core.Net/Messages/GameEvents.cs @@ -402,11 +402,17 @@ public static class GameEvents return BinaryPrimitives.ReadUInt32LittleEndian(payload); } - /// 0x00A0 InventoryServerSaveFailed: revert a speculative local inventory op. - public static uint? ParseInventoryServerSaveFailed(ReadOnlySpan payload) + /// 0x00A0 InventoryServerSaveFailed: revert a speculative local inventory op. + /// (itemGuid, weenieError) — ACE GameEventInventoryServerSaveFailed.cs; holtburger + /// events.rs:147 reads both fields. + public readonly record struct InventoryServerSaveFailed(uint ItemGuid, uint WeenieError); + + public static InventoryServerSaveFailed? ParseInventoryServerSaveFailed(ReadOnlySpan payload) { - if (payload.Length < 4) return null; - return BinaryPrimitives.ReadUInt32LittleEndian(payload); + if (payload.Length < 8) return null; + return new InventoryServerSaveFailed( + BinaryPrimitives.ReadUInt32LittleEndian(payload), + BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(4))); } /// 0x0052 CloseGroundContainer: server closed a ground container view. diff --git a/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs b/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs index c77f646b..0517a1ff 100644 --- a/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs +++ b/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs @@ -59,4 +59,17 @@ public sealed class GameEventsInventoryTests Assert.Equal(3u, p.Value.Placement); Assert.Equal(1u, p.Value.ContainerType); } + + [Fact] + public void ParseInventoryServerSaveFailed_readsGuidAndError() + { + var b = new byte[8]; + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(0), 0x50000A01u); // itemGuid + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(4), 0x0Au); // weenieError + + var p = GameEvents.ParseInventoryServerSaveFailed(b); + Assert.NotNull(p); + Assert.Equal(0x50000A01u, p!.Value.ItemGuid); + Assert.Equal(0x0Au, p.Value.WeenieError); + } }