Stop filtering remove-entity packets in TechHider

Stripping ids of hidden entities left ghost entities on clients once
the entity became visible and was later removed. Removing an unknown
entity id is harmless, so the packet is passed through.
This commit is contained in:
2026-10-27 10:10:09 +01:00
parent b47cff2805
commit 865d28645a
@@ -182,6 +182,9 @@ public class TechHider {
ClientboundSetChunkCacheCenterPacket.class, // 7.1.93 Set Center Chunk
ClientboundForgetLevelChunkPacket.class, // 7.1.38 Unload Chunk
ClientboundUpdateTagsPacket.class, // 7.1.133 Update Tags (play)
// 7.1.76 Remove Entities: must not be filtered, otherwise Player#hideEntity leaves ghosts on the client.
// Entities that are already gone from the world pass the entity checks anyway, so no additional information is leaked.
ClientboundRemoveEntitiesPacket.class,
ClientboundPlayerInfoRemovePacket.class, // 7.1.68 Player Info Remove
ClientboundPlayerInfoUpdatePacket.class, // 7.1.69 Player Info Update
ClientboundMoveVehiclePacket.class, // 7.1.56 Move Vehicle (vehicle the player is in)
@@ -242,8 +245,6 @@ public class TechHider {
// 7.1.82 Set Head Rotation: entity id and rotation.
processors.put(ClientboundRotateHeadPacket.class, (access, packet) -> this.processRotateHeadPacket(access, (ClientboundRotateHeadPacket) packet));
// 7.1.76 Remove Entities: entity id visibility side channel.
processors.put(ClientboundRemoveEntitiesPacket.class, (access, packet) -> this.processRemoveEntitiesPacket(access, (ClientboundRemoveEntitiesPacket) packet));
// 7.1.99 Link Entities: entity relationship signal.
processors.put(ClientboundSetEntityLinkPacket.class, (access, packet) -> this.processSetEntityLinkPacket(access, (ClientboundSetEntityLinkPacket) packet));
@@ -402,14 +403,6 @@ public class TechHider {
}
}
private Packet<?> processRemoveEntitiesPacket(ForPlayer access, ClientboundRemoveEntitiesPacket packet) {
IntList entityIdsToRemove = packet.getEntityIds();
IntList filteredEntitiesToRemove = entityIdsToRemove.intStream().filter((id) -> access.canAccessEntity(id)).collect(IntArrayList::new, IntList::add, IntList::addAll);
return new ClientboundRemoveEntitiesPacket(filteredEntitiesToRemove);
}
public Packet<?> processSetEntityLinkPacket(ForPlayer access, ClientboundSetEntityLinkPacket packet) {
int fromEntityId = packet.getSourceId();
int toEntityId = packet.getDestId();