feat(D.2b): ViewContents wiring is a full REPLACE (consumes the GameEventWiring TODO)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-22 14:28:08 +02:00
parent 48bf752cf1
commit ad9d2651c1
2 changed files with 37 additions and 9 deletions

View file

@ -556,6 +556,35 @@ public sealed class GameEventWiringTests
Assert.Equal(0x500000C9u, items.Get(0x50000A02u)!.ContainerId);
}
[Fact]
public void WireAll_ViewContents_IsFullReplace_DropsRemovedItems()
{
var (d, items, _, _, _) = MakeAll();
// First view of container 0xC9: two items.
DispatchViewContents(d, 0x500000C9u, new uint[] { 0x50000A01u, 0x50000A02u });
Assert.Equal(2, items.GetContents(0x500000C9u).Count);
// Second view: only one item — the other was removed server-side. Additive merge would keep both.
DispatchViewContents(d, 0x500000C9u, new uint[] { 0x50000A02u });
Assert.Equal(new[] { 0x50000A02u }, items.GetContents(0x500000C9u));
Assert.Equal(0u, items.Get(0x50000A01u)!.ContainerId);
}
private static void DispatchViewContents(GameEventDispatcher d, uint containerGuid, uint[] itemGuids)
{
byte[] payload = new byte[8 + itemGuids.Length * 8];
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(0), containerGuid);
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(4), (uint)itemGuids.Length);
for (int i = 0; i < itemGuids.Length; i++)
{
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(8 + i * 8), itemGuids[i]);
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(12 + i * 8), 0u); // containerType
}
var env = GameEventEnvelope.TryParse(WrapEnvelope(GameEventType.ViewContents, payload));
d.Dispatch(env!.Value);
}
[Fact]
public void WireAll_InventoryPutObjectIn3D_UnparentsFromContainer()
{