diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 470ed7d78..25dd21662 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -87,7 +87,6 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.ItemFrameEntity; import org.geysermc.geyser.entity.type.Tickable; -import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.erosion.AbstractGeyserboundPacketHandler; import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler; @@ -888,18 +887,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public void packetReceived(Session session, Packet packet) { if (protocol.getState() == ProtocolState.CONFIGURATION) { if (packet instanceof ClientboundFinishConfigurationPacket) { - GeyserSession.this.ensureInEventLoop(() -> { - // Clear the player list, as on Java the player list is cleared after transitioning from config to play phase - PlayerListPacket playerListPacket = new PlayerListPacket(); - playerListPacket.setAction(PlayerListPacket.Action.REMOVE); - for (PlayerEntity otherEntity : GeyserSession.this.getEntityCache().getAllPlayerEntities()) { - playerListPacket.getEntries().add(new PlayerListPacket.Entry(otherEntity.getTabListUuid())); - GeyserSession.this.getEntityCache().removePlayerEntity(otherEntity.getUuid()); - } - GeyserSession.this.sendUpstreamPacket(playerListPacket); - - GeyserSession.this.sendDownstreamPacket(new ServerboundFinishConfigurationPacket()); - }); + // Prevent + GeyserSession.this.ensureInEventLoop(() -> GeyserSession.this.sendDownstreamPacket(new ServerboundFinishConfigurationPacket())); return; } } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java index 6524e1ddc..24f683242 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/EntityCache.java @@ -32,6 +32,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Getter; +import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.entity.type.Tickable; import org.geysermc.geyser.entity.type.player.PlayerEntity; @@ -141,6 +142,16 @@ public class EntityCache { return playerEntities.values(); } + public void removeAllPlayerEntities() { + PlayerListPacket playerListPacket = new PlayerListPacket(); + playerListPacket.setAction(PlayerListPacket.Action.REMOVE); + for (PlayerEntity otherEntity : playerEntities.values()) { + playerListPacket.getEntries().add(new PlayerListPacket.Entry(otherEntity.getTabListUuid())); + } + session.sendUpstreamPacket(playerListPacket); + playerEntities.clear(); + } + public void addBossBar(UUID uuid, BossBar bossBar) { bossBars.put(uuid, bossBar); bossBar.addBossBar(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaFinishConfigurationPacketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaFinishConfigurationPacketTranslator.java new file mode 100644 index 000000000..80923761f --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaFinishConfigurationPacketTranslator.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.translator.protocol.java; + +import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.translator.protocol.PacketTranslator; +import org.geysermc.geyser.translator.protocol.Translator; +import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundFinishConfigurationPacket; + +@Translator(packet = ClientboundFinishConfigurationPacket.class) +public class JavaFinishConfigurationPacketTranslator extends PacketTranslator { + + @Override + public void translate(GeyserSession session, ClientboundFinishConfigurationPacket packet) { + // Clear the player list, as on Java the player list is cleared after transitioning from config to play phase + session.getEntityCache().removeAllPlayerEntities(); + } +}