diff --git a/src/AcDream.Core.Net/Messages/GameEvents.cs b/src/AcDream.Core.Net/Messages/GameEvents.cs index bd28a283..edb98809 100644 --- a/src/AcDream.Core.Net/Messages/GameEvents.cs +++ b/src/AcDream.Core.Net/Messages/GameEvents.cs @@ -343,19 +343,24 @@ public static class GameEvents BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(8))); } - /// 0x0022 InventoryPutObjInContainer: server puts item into container slot. + /// 0x0022 InventoryPutObjInContainer: server puts item into container slot. + /// 4 fields (ACE GameEventItemServerSaysContainId.cs): itemGuid, containerGuid, + /// placement, containerType. ContainerType (0=item,1=container,2=foci) confirmed + /// vs holtburger events.rs fixture (slot=3 type=1). public readonly record struct InventoryPutObjInContainer( uint ItemGuid, uint ContainerGuid, - uint Placement); + uint Placement, + uint ContainerType); public static InventoryPutObjInContainer? ParsePutObjInContainer(ReadOnlySpan payload) { - if (payload.Length < 12) return null; + if (payload.Length < 16) return null; return new InventoryPutObjInContainer( BinaryPrimitives.ReadUInt32LittleEndian(payload), BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(4)), - BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(8))); + BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(8)), + BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(12))); } /// 0x0196 ViewContents: full contents list of a container you opened. diff --git a/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs b/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs index 5a49b53a..c77f646b 100644 --- a/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs +++ b/tests/AcDream.Core.Net.Tests/Messages/GameEventsInventoryTests.cs @@ -42,4 +42,21 @@ public sealed class GameEventsInventoryTests [Fact] public void ParseViewContents_truncated_returnsNull() => Assert.Null(GameEvents.ParseViewContents(new byte[4])); + + [Fact] + public void ParsePutObjInContainer_readsAllFourFields() + { + var b = new byte[16]; + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(0), 0x50000A01u); // itemGuid + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(4), 0x500000C9u); // containerGuid + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(8), 3u); // placement + BinaryPrimitives.WriteUInt32LittleEndian(b.AsSpan(12), 1u); // containerType + + var p = GameEvents.ParsePutObjInContainer(b); + Assert.NotNull(p); + Assert.Equal(0x50000A01u, p!.Value.ItemGuid); + Assert.Equal(0x500000C9u, p.Value.ContainerGuid); + Assert.Equal(3u, p.Value.Placement); + Assert.Equal(1u, p.Value.ContainerType); + } }