From d4754c1f1d9f9c8828b768cdcb13eae9c99704c7 Mon Sep 17 00:00:00 2001 From: mworzala Date: Mon, 27 Nov 2023 23:55:28 +0200 Subject: [PATCH] feat: working (scuffed) reentry after reconfiguration (cherry picked from commit 3ad490356a39bd072d69a40a61f5b6c5c651afac) --- .../minestom/server/ServerProcessImpl.java | 7 ++---- .../net/minestom/server/entity/Entity.java | 2 +- .../net/minestom/server/entity/Player.java | 6 +++-- .../server/listener/PlayConfigListener.java | 13 +++++++++- .../listener/common/KeepAliveListener.java | 1 + .../server/network/ConnectionManager.java | 25 ++++++++++++++----- .../server/network/PacketProcessor.java | 2 ++ 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/minestom/server/ServerProcessImpl.java b/src/main/java/net/minestom/server/ServerProcessImpl.java index 56b6acea6..176881ccf 100644 --- a/src/main/java/net/minestom/server/ServerProcessImpl.java +++ b/src/main/java/net/minestom/server/ServerProcessImpl.java @@ -288,11 +288,8 @@ final class ServerProcessImpl implements ServerProcess { scheduler().processTick(); - // Waiting players update (newly connected clients waiting to get into the server) - connection().updateWaitingPlayers(); - - // Keep Alive Handling - connection().handleKeepAlive(msTime); + // Connection tick (let waiting clients in, send keep alives, handle configuration players packets) + connection().tick(msTime); // Server tick (chunks/entities) serverTick(msTime); diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index cc51aadc8..45f355877 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -160,7 +160,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev protected UUID uuid; private boolean isActive; // False if entity has only been instanced without being added somewhere - private boolean removed; + protected boolean removed; private final Set passengers = new CopyOnWriteArraySet<>(); protected EntityType entityType; // UNSAFE to change, modify at your own risk diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 4bfb15e13..122764a53 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -261,10 +261,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable, */ @ApiStatus.Internal public CompletableFuture UNSAFE_init(@NotNull Instance spawnInstance) { + this.removed = false; this.dimensionType = spawnInstance.getDimensionType(); - System.out.println("INIT PLAYER"); - final JoinGamePacket joinGamePacket = new JoinGamePacket( getEntityId(), false, List.of(), 0, MinecraftServer.getChunkViewDistance(), MinecraftServer.getChunkViewDistance(), @@ -387,6 +386,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable, // If the player is currently in the play state, we need to put them back in configuration. if (playerConnection.getClientState() == ConnectionState.PLAY) { remove(false); + System.out.println("SEND REENTER"); + MinecraftServer.getConnectionManager().transitionPlayToConfig(this); sendPacket(new StartConfigurationPacket()); } else { // Sanity check that they are already in configuration. @@ -422,6 +423,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, public void update(long time) { // Process received packets interpretPacketQueue(); + if (isRemoved()) return; super.update(time); // Super update (item pickup/fire management) diff --git a/src/main/java/net/minestom/server/listener/PlayConfigListener.java b/src/main/java/net/minestom/server/listener/PlayConfigListener.java index f18688e85..257711c5c 100644 --- a/src/main/java/net/minestom/server/listener/PlayConfigListener.java +++ b/src/main/java/net/minestom/server/listener/PlayConfigListener.java @@ -4,9 +4,20 @@ import net.minestom.server.entity.Player; import net.minestom.server.network.packet.client.play.ClientConfigurationAckPacket; import org.jetbrains.annotations.NotNull; +import java.util.concurrent.ForkJoinPool; + public class PlayConfigListener { public static void configAckListener(@NotNull ClientConfigurationAckPacket packet, @NotNull Player player) { - player.startConfigurationPhase(); +// player.startConfigurationPhase(); + System.out.println("PLAYER HAS REENTERED CONFIGURATION PHASE!!!!!" + player.getUsername()); + ForkJoinPool.commonPool().execute(() -> { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + player.startConfigurationPhase(); + }); } } diff --git a/src/main/java/net/minestom/server/listener/common/KeepAliveListener.java b/src/main/java/net/minestom/server/listener/common/KeepAliveListener.java index 3173e8a95..3a1627ecd 100644 --- a/src/main/java/net/minestom/server/listener/common/KeepAliveListener.java +++ b/src/main/java/net/minestom/server/listener/common/KeepAliveListener.java @@ -9,6 +9,7 @@ public final class KeepAliveListener { private static final Component KICK_MESSAGE = Component.text("Bad Keep Alive packet", NamedTextColor.RED); public static void listener(ClientKeepAlivePacket packet, Player player) { + System.out.println("KEEP ALIVE LISTENER"); final long packetId = packet.id(); if (packetId != player.getLastKeepAlive()) { player.kick(KICK_MESSAGE); diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index 62a933974..bd8ac6571 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -39,6 +39,7 @@ public final class ConnectionManager { } private final MessagePassingQueue waitingPlayers = new MpscUnboundedArrayQueue<>(64); + private final Set configurationPlayers = new CopyOnWriteArraySet<>(); private final Set players = new CopyOnWriteArraySet<>(); private final Set unmodifiablePlayers = Collections.unmodifiableSet(players); @@ -189,7 +190,7 @@ public final class ConnectionManager { @ApiStatus.Internal public void transitionLoginToConfig(@NotNull Player player) { - + configurationPlayers.add(player); } @ApiStatus.Internal @@ -199,7 +200,7 @@ public final class ConnectionManager { @ApiStatus.Internal public void transitionPlayToConfig(@NotNull Player player) { - + configurationPlayers.add(player); } /** @@ -267,6 +268,7 @@ public final class ConnectionManager { // Send login success packet (and switch to configuration phase) LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername(), 0); playerConnection.sendPacket(loginSuccessPacket); + configurationPlayers.add(player); }); } @@ -283,13 +285,23 @@ public final class ConnectionManager { this.connectionPlayerMap.clear(); } + public void tick(long tickStart) { + updateWaitingPlayers(); + handleKeepAlive(tickStart); + + // Interpret packets for configuration players + for (var player : configurationPlayers) { +// System.out.println("CONFIG INTERPRET: " + player.getUsername()); + player.interpretPacketQueue(); + } + } + /** * Connects waiting players. */ - public void updateWaitingPlayers() { + private void updateWaitingPlayers() { this.waitingPlayers.drain(pp -> { - - System.out.println("DRAIN PP " + pp); + configurationPlayers.remove(pp.player); // Spawn the player at Player#getRespawnPoint CompletableFuture spawnFuture = pp.player.UNSAFE_init(pp.instance); @@ -304,7 +316,8 @@ public final class ConnectionManager { * * @param tickStart the time of the update in milliseconds, forwarded to the packet */ - public void handleKeepAlive(long tickStart) { + private void handleKeepAlive(long tickStart) { + //todo need to send keep alives for config players also!! final KeepAlivePacket keepAlivePacket = new KeepAlivePacket(tickStart); for (Player player : getOnlinePlayers()) { final long lastKeepAlive = tickStart - player.getLastKeepAlive(); diff --git a/src/main/java/net/minestom/server/network/PacketProcessor.java b/src/main/java/net/minestom/server/network/PacketProcessor.java index f928faff6..f37c0e7f4 100644 --- a/src/main/java/net/minestom/server/network/PacketProcessor.java +++ b/src/main/java/net/minestom/server/network/PacketProcessor.java @@ -53,8 +53,10 @@ public class PacketProcessor { } public ClientPacket process(@NotNull PlayerConnection connection, int packetId, ByteBuffer body) { + System.out.println("READ: " + connection.getClientState() + " " + packetId); final ClientPacket packet = create(connection.getClientState(), packetId, body); final ConnectionState state = connection.getClientState(); + System.out.println("READ2: " + state + " " + packet.getClass().getSimpleName()); switch (state) { case HANDSHAKE, STATUS, LOGIN, CONFIGURATION -> packetListenerManager.processClientPacket(connection.getClientState(), packet, connection); case PLAY -> {