Clear entity data on world change in world tracker

This commit is contained in:
Nassim Jahnke 2021-09-14 17:35:27 +02:00
parent 32a84f24ef
commit c264e639d6
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
3 changed files with 55 additions and 9 deletions

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -362,7 +362,14 @@ public abstract class EntityRewriter<T extends Protocol> extends RewriterBase<T>
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<T extends Protocol> extends RewriterBase<T>
} 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);
};
}