From 83eead729ef90f8e27063bda1c75410a9759b497 Mon Sep 17 00:00:00 2001 From: Chubbyduck1 Date: Tue, 7 Jul 2026 12:40:42 -0400 Subject: [PATCH 1/2] fix: ViewerEngineListener not handling UserDisconnectEvent --- .../entitylib/ve/ViewerEngineListener.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java b/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java index ac4d89a..1ee1f13 100644 --- a/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java +++ b/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java @@ -2,6 +2,7 @@ import com.github.retrooper.packetevents.event.PacketListenerAbstract; import com.github.retrooper.packetevents.event.PacketSendEvent; +import com.github.retrooper.packetevents.event.UserDisconnectEvent; import com.github.retrooper.packetevents.protocol.packettype.PacketType; import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; import com.github.retrooper.packetevents.protocol.player.User; @@ -11,6 +12,7 @@ import me.tofaa.entitylib.utils.Check; import me.tofaa.entitylib.wrapper.WrapperEntity; +import java.util.UUID; import java.util.function.Consumer; final class ViewerEngineListener extends PacketListenerAbstract { @@ -81,6 +83,22 @@ else if (type == PacketType.Play.Server.CHUNK_DATA) { } } + @Override + public void onUserDisconnect(final UserDisconnectEvent event) { + final UUID uniqueId = event.getUser().getUUID(); + + // Note from Chubbyduck1: While this says it's non-null, it can actually be null in this case. Not sure why. When run without this, it would spam NPEs for me. + if (uniqueId == null) { + return; + } + + engine.getTracked0().forEach(entity -> { + if (entity.hasViewer(uniqueId)) { + entity.removeViewer(uniqueId); + } + }); + } + private void genericSpawnCheck(int entityId, User user) { WrapperEntity entity = EntityLib.getApi().getEntity(entityId); if (entity == null) return; From 0d0c44afd87fac7749c5b139b170047a446f6478 Mon Sep 17 00:00:00 2001 From: Chubbyduck1 Date: Tue, 7 Jul 2026 12:53:39 -0400 Subject: [PATCH 2/2] fix: Disconnect sending packets, and running off executor --- .../entitylib/ve/ViewerEngineListener.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java b/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java index 1ee1f13..aadfe24 100644 --- a/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java +++ b/api/src/main/java/me/tofaa/entitylib/ve/ViewerEngineListener.java @@ -85,17 +85,19 @@ else if (type == PacketType.Play.Server.CHUNK_DATA) { @Override public void onUserDisconnect(final UserDisconnectEvent event) { - final UUID uniqueId = event.getUser().getUUID(); - - // Note from Chubbyduck1: While this says it's non-null, it can actually be null in this case. Not sure why. When run without this, it would spam NPEs for me. - if (uniqueId == null) { - return; - } + engine.getExecutor().execute(() -> { + final UUID uniqueId = event.getUser().getUUID(); - engine.getTracked0().forEach(entity -> { - if (entity.hasViewer(uniqueId)) { - entity.removeViewer(uniqueId); + // Note from Chubbyduck1: While this says it's non-null, it can actually be null in this case. Not sure why. When run without this, it would spam NPEs for me. + if (uniqueId == null) { + return; } + + engine.getTracked0().forEach(entity -> { + if (entity.hasViewer(uniqueId)) { + entity.removeViewerSilently(uniqueId); + } + }); }); }