fix(B.5): handle PickupEvent 0xF74A so picked-up items despawn locally
ACE sends GameMessagePickupEvent (opcode 0xF74A) instead of GameMessageDeleteObject (0xF747) for items removed via player pickup (Player_Tracking.RemoveTrackedObject with fromPickup=true). Without this handler, BuildPickUp succeeded server-side (item moved into the player's container, retail observers saw it disappear), but our local client kept rendering it on the ground because the despawn message went to the unhandled-opcode bucket. PickupEvent's wire body adds an objectPositionSequence field on top of DeleteObject's layout, so the parser is its own type. The downstream view-removal semantics are identical to DeleteObject, so the dispatcher routes both opcodes into the same EntityDeleted event via a small adapter.
This commit is contained in:
parent
5c24f6cafe
commit
f7636a9e78
3 changed files with 102 additions and 0 deletions
41
tests/AcDream.Core.Net.Tests/Messages/PickupEventTests.cs
Normal file
41
tests/AcDream.Core.Net.Tests/Messages/PickupEventTests.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System.Buffers.Binary;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Net.Tests.Messages;
|
||||
|
||||
public sealed class PickupEventTests
|
||||
{
|
||||
[Fact]
|
||||
public void RejectsWrongOpcode()
|
||||
{
|
||||
Span<byte> body = stackalloc byte[12];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(body, 0xDEADBEEFu);
|
||||
|
||||
Assert.Null(PickupEvent.TryParse(body));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RejectsTruncated()
|
||||
{
|
||||
Assert.Null(PickupEvent.TryParse(ReadOnlySpan<byte>.Empty));
|
||||
Assert.Null(PickupEvent.TryParse(new byte[11]));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesGuidAndSequences()
|
||||
{
|
||||
Span<byte> body = stackalloc byte[12];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(body, PickupEvent.Opcode);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(body.Slice(4), 0x80000727u);
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(body.Slice(8), 0x1234);
|
||||
BinaryPrimitives.WriteUInt16LittleEndian(body.Slice(10), 0x5678);
|
||||
|
||||
var parsed = PickupEvent.TryParse(body);
|
||||
|
||||
Assert.NotNull(parsed);
|
||||
Assert.Equal(0x80000727u, parsed!.Value.Guid);
|
||||
Assert.Equal((ushort)0x1234, parsed.Value.InstanceSequence);
|
||||
Assert.Equal((ushort)0x5678, parsed.Value.PositionSequence);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue