@@ -937,6 +937,58 @@ func TestSharedWorldRegistryJoinReclaimRemovesOwnedGroundItems(t *testing.T) {
937937 }
938938}
939939
940+ func TestSharedWorldRegistryJoinReclaimRemovesOwnedGroundGold(t *testing.T) {
941+ registry := newSharedWorldRegistry()
942+ owner := peerVisibilityCharacter("ReclaimedGoldOwner", 0x010301b7, 0x020401b7, 1200, 2200, 0, 101, 201)
943+ peer := peerVisibilityCharacter("ReclaimedGoldPeer", 0x010301b8, 0x020401b8, 1220, 2220, 0, 102, 202)
944+ ownerID, _ := registry.Join(owner, newPendingServerFrames(), nil)
945+ peerPending := newPendingServerFrames()
946+ peerID, _ := registry.Join(peer, peerPending, nil)
947+ if ownerID == 0 || peerID == 0 {
948+ t.Fatalf("expected owner and peer to join shared world, got owner=%d peer=%d", ownerID, peerID)
949+ }
950+ peerPending.flush()
951+
952+ const groundVID uint32 = 0x0700002C
953+ if !registry.RegisterGroundGold(ownerID, "reclaimed-gold-owner", owner, groundVID, 250) {
954+ t.Fatal("expected owner ground gold registration to succeed")
955+ }
956+ peerPending.flush()
957+ if _, ok := registry.sessionDirectory.Remove(ownerID); !ok {
958+ t.Fatal("expected owner session entry to be removable for stale reclaim setup")
959+ }
960+
961+ freshOwnerPending := newPendingServerFrames()
962+ freshOwnerID, peers := registry.Join(owner, freshOwnerPending, nil)
963+ if freshOwnerID == 0 || freshOwnerID == ownerID {
964+ t.Fatalf("expected stale owner to be reclaimed with a fresh entity id, got old=%d fresh=%d", ownerID, freshOwnerID)
965+ }
966+ if len(peers) != 1 || peers[0].Name != peer.Name {
967+ t.Fatalf("expected fresh owner join to see existing peer, got %#v", peers)
968+ }
969+ if registry.GroundItemExists(groundVID) {
970+ t.Fatal("expected stale owner's owned ground gold to be removed during reclaim")
971+ }
972+ peerQueued := peerPending.flush()
973+ if len(peerQueued) != 5 {
974+ t.Fatalf("expected peer to receive owner delete, ground-gold delete, and 3-frame reentry burst, got %d frames", len(peerQueued))
975+ }
976+ ownerDel, err := worldproto.DecodeCharacterDeleteNotice(decodeSingleFrame(t, peerQueued[0]))
977+ if err != nil {
978+ t.Fatalf("decode reclaimed owner delete: %v", err)
979+ }
980+ if ownerDel.VID != owner.VID {
981+ t.Fatalf("unexpected reclaimed owner delete: %+v", ownerDel)
982+ }
983+ groundDel, err := itemproto.DecodeGroundDel(decodeSingleFrame(t, peerQueued[1]))
984+ if err != nil {
985+ t.Fatalf("decode reclaimed owner ground-gold delete: %v", err)
986+ }
987+ if groundDel.VID != groundVID {
988+ t.Fatalf("unexpected reclaimed owner ground-gold delete: %+v", groundDel)
989+ }
990+ }
991+
940992func TestSharedWorldRegistryRegisterGroundGoldRejectsExistingVID(t *testing.T) {
941993 registry := newSharedWorldRegistry()
942994 owner := peerVisibilityCharacter("GoldDropOwner", 0x01030194, 0x02040194, 1200, 2200, 0, 101, 201)
0 commit comments