diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 2e1ab97ed..6526d9fe9 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -33,6 +33,7 @@ import net.minestom.server.potion.TimedPotion; import net.minestom.server.tag.Tag; import net.minestom.server.tag.TagHandler; import net.minestom.server.thread.ThreadProvider; +import net.minestom.server.utils.async.AsyncUtils; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.entity.EntityUtils; import net.minestom.server.utils.player.PlayerUtils; @@ -708,6 +709,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler public CompletableFuture setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) { Check.stateCondition(!instance.isRegistered(), "Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance"); + if (isRemoved()) return AsyncUtils.VOID_FUTURE; if (this.instance != null) { this.instance.UNSAFE_removeEntity(this); } @@ -1267,16 +1269,15 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler * WARNING: this does not trigger {@link EntityDeathEvent}. */ public void remove() { - if (isRemoved()) - return; - + if (isRemoved()) return; MinecraftServer.getUpdateManager().getThreadProvider().removeEntity(this); this.removed = true; this.shouldRemove = true; Entity.ENTITY_BY_ID.remove(id); Entity.ENTITY_BY_UUID.remove(uuid); - if (instance != null) + if (instance != null) { instance.UNSAFE_removeEntity(this); + } } /** diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index f8b38da7e..2177ea141 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -441,18 +441,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable, @Override public void remove() { - if (isRemoved()) - return; - + if (isRemoved()) return; EventDispatcher.call(new PlayerDisconnectEvent(this)); - super.remove(); this.packets.clear(); - if (getOpenInventory() != null) + if (getOpenInventory() != null) { getOpenInventory().removeViewer(this); - + } MinecraftServer.getBossBarManager().removeAllBossBars(this); - // Advancement tabs cache { Set advancementTabs = AdvancementTab.getTabs(this); @@ -462,15 +458,10 @@ public class Player extends LivingEntity implements CommandSender, Localizable, } } } - // Clear all viewable entities this.viewableEntities.forEach(entity -> entity.removeViewer(this)); // Clear all viewable chunks - this.viewableChunks.forEach(chunk -> { - if (chunk.isLoaded()) - chunk.removeViewer(this); - }); - playerConnection.disconnect(); + this.viewableChunks.forEach(chunk -> chunk.removeViewer(this)); } @Override diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index d6b8d1fef..2667e93af 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -268,7 +268,7 @@ public final class ConnectionManager { * @param connection the player connection * @see PlayerConnection#disconnect() to properly disconnect a player */ - public void removePlayer(@NotNull PlayerConnection connection) { + public synchronized void removePlayer(@NotNull PlayerConnection connection) { final Player player = this.connectionPlayerMap.get(connection); if (player == null) return; @@ -344,7 +344,7 @@ public final class ConnectionManager { /** * Shutdowns the connection manager by kicking all the currently connected players. */ - public void shutdown() { + public synchronized void shutdown() { DisconnectPacket disconnectPacket = new DisconnectPacket(shutdownText); for (Player player : getOnlinePlayers()) { final PlayerConnection playerConnection = player.getPlayerConnection(); diff --git a/src/main/java/net/minestom/server/network/player/NettyPlayerConnection.java b/src/main/java/net/minestom/server/network/player/NettyPlayerConnection.java index 0b780e9f9..e57294f1f 100644 --- a/src/main/java/net/minestom/server/network/player/NettyPlayerConnection.java +++ b/src/main/java/net/minestom/server/network/player/NettyPlayerConnection.java @@ -101,7 +101,7 @@ public class NettyPlayerConnection extends PlayerConnection { content = readBuffer; } else { // Decompress to content buffer - content = workerContext.contentBuffer.clear(); + content = workerContext.contentBuffer; try { final var inflater = workerContext.inflater; inflater.setInput(readBuffer); @@ -255,11 +255,7 @@ public class NettyPlayerConnection extends PlayerConnection { @Override public void disconnect() { - try { - this.worker.disconnect(this, channel); - } catch (IOException e) { - e.printStackTrace(); - } + this.worker.disconnect(this, channel); } public @NotNull SocketChannel getChannel() { diff --git a/src/main/java/net/minestom/server/network/player/PlayerConnection.java b/src/main/java/net/minestom/server/network/player/PlayerConnection.java index 28feb23b5..3acddf607 100644 --- a/src/main/java/net/minestom/server/network/player/PlayerConnection.java +++ b/src/main/java/net/minestom/server/network/player/PlayerConnection.java @@ -160,8 +160,7 @@ public abstract class PlayerConnection { * * @return the player, can be null if not initialized yet */ - @Nullable - public Player getPlayer() { + public @Nullable Player getPlayer() { return player; } diff --git a/src/main/java/net/minestom/server/network/socket/Worker.java b/src/main/java/net/minestom/server/network/socket/Worker.java index 9764d2b00..4d5762ebe 100644 --- a/src/main/java/net/minestom/server/network/socket/Worker.java +++ b/src/main/java/net/minestom/server/network/socket/Worker.java @@ -61,11 +61,7 @@ public final class Worker { connection.processPackets(workerContext, packetProcessor); } catch (IOException e) { // TODO print exception? (should ignore disconnection) - try { - disconnect(connection, channel); - } catch (IOException ioException) { - ioException.printStackTrace(); - } + connection.disconnect(); } finally { workerContext.clearBuffers(); } @@ -84,15 +80,18 @@ public final class Worker { this.selector.wakeup(); } - public void disconnect(NettyPlayerConnection connection, SocketChannel channel) throws IOException { - if (connectionMap.remove(channel) == null) return; - // Client close - channel.close(); - connection.refreshOnline(false); - Player player = connection.getPlayer(); - if (player != null) { - player.remove(); + public void disconnect(NettyPlayerConnection connection, SocketChannel channel) { + try { + channel.close(); + this.connectionMap.remove(channel); MinecraftServer.getConnectionManager().removePlayer(connection); + connection.refreshOnline(false); + Player player = connection.getPlayer(); + if (player != null) { + player.remove(); + } + } catch (IOException e) { + e.printStackTrace(); } }