From c264e639d6faf14cd76785f2126ac952c9771d12 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Tue, 14 Sep 2021 17:35:27 +0200 Subject: [PATCH] Clear entity data on world change in world tracker --- .../api/data/entity/EntityTracker.java | 23 ++++++++++++++-- .../data/entity/EntityTrackerBase.java | 26 ++++++++++++++----- .../viaversion/rewriter/EntityRewriter.java | 15 ++++++++++- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java index 986f3ded2..938007785 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/entity/EntityTracker.java @@ -67,6 +67,11 @@ public interface EntityTracker { */ void removeEntity(int id); + /** + * Clears stored entity types and data. + */ + void clearEntities(); + /** * Returns the stored entity data if an entity with the id is tracked, else null. * If no data has been initialized yet, it will be done and returned by this method. @@ -101,8 +106,8 @@ public interface EntityTracker { void setClientEntityId(int clientEntityId); /** - * Returns the current world section height. - * Always 16 for sub 1.17 worlds. + * Returns the current world section height (block height / 16). + * This is always 16 for sub 1.17 worlds. * * @return current world section height */ @@ -128,4 +133,18 @@ public interface EntityTracker { * @param currentMinY minimum y of the current world */ void setCurrentMinY(int currentMinY); + + /** + * Returns the name of the world the player is currently in. + * + * @return world name of the current world + */ + @Nullable String currentWorld(); + + /** + * Sets the name of the world the player is currently in. + * + * @param currentWorld name of the current world + */ + void setCurrentWorld(String currentWorld); } diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 8f6841c56..0a5741206 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -37,6 +37,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis private int clientEntityId = -1; private int currentWorldSectionHeight = 16; private int currentMinY; + private String currentWorld; public EntityTrackerBase(UserConnection connection, @Nullable EntityType playerType) { this(connection, playerType, false); @@ -81,6 +82,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis return entityData.get(id); } + //TODO Soft memory leak: Remove entities on respawn in protocols prior to 1.18 (1.16+ only when the worldname is different) @Override public void removeEntity(int id) { entityTypes.remove(id); @@ -89,6 +91,14 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis } } + @Override + public void clearEntities() { + entityTypes.clear(); + if (entityData != null) { + entityData.clear(); + } + } + @Override public int clientEntityId() { return clientEntityId; @@ -108,9 +118,6 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis this.clientEntityId = clientEntityId; } - /** - * @return amount of chunk sections of the current world (block height / 16) - */ @Override public int currentWorldSectionHeight() { return currentWorldSectionHeight; @@ -121,9 +128,6 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis this.currentWorldSectionHeight = currentWorldSectionHeight; } - /** - * @return absolute minimum y coordinate of the current world - */ @Override public int currentMinY() { return currentMinY; @@ -133,4 +137,14 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis public void setCurrentMinY(int currentMinY) { this.currentMinY = currentMinY; } + + @Override + public @Nullable String currentWorld() { + return currentWorld; + } + + @Override + public void setCurrentWorld(final String currentWorld) { + this.currentWorld = currentWorld; + } } diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java index 73bb648b9..2634a2073 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java @@ -362,7 +362,14 @@ public abstract class EntityRewriter extends RewriterBase return trackerAndRewriterHandler(null); } - protected PacketHandler worldDataTrackerHandler(int nbtIndex) { + /** + * Returns a packet handler storing height, min_y, and name of the current world. + * If the client changes to a new world, the stored entity data will be cleared. + * + * @param nbtIndex index of the current world's nbt + * @return packet handler + */ + public PacketHandler worldDataTrackerHandler(int nbtIndex) { return wrapper -> { EntityTracker tracker = tracker(wrapper.user()); @@ -381,6 +388,12 @@ public abstract class EntityRewriter extends RewriterBase } else { Via.getPlatform().getLogger().warning("Min Y missing in dimension data: " + registryData); } + + String world = wrapper.get(Type.STRING, 0); + if (tracker.currentWorld() != null && !tracker.currentWorld().equals(world)) { + tracker.clearEntities(); + } + tracker.setCurrentWorld(world); }; }