feat: working (scuffed) reentry after reconfiguration

(cherry picked from commit 3ad490356a)
This commit is contained in:
mworzala 2023-11-27 23:55:28 +02:00 committed by Matt Worzala
parent b9c2d42696
commit d4754c1f1d
7 changed files with 41 additions and 15 deletions

View File

@ -288,11 +288,8 @@ final class ServerProcessImpl implements ServerProcess {
scheduler().processTick(); scheduler().processTick();
// Waiting players update (newly connected clients waiting to get into the server) // Connection tick (let waiting clients in, send keep alives, handle configuration players packets)
connection().updateWaitingPlayers(); connection().tick(msTime);
// Keep Alive Handling
connection().handleKeepAlive(msTime);
// Server tick (chunks/entities) // Server tick (chunks/entities)
serverTick(msTime); serverTick(msTime);

View File

@ -160,7 +160,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
protected UUID uuid; protected UUID uuid;
private boolean isActive; // False if entity has only been instanced without being added somewhere private boolean isActive; // False if entity has only been instanced without being added somewhere
private boolean removed; protected boolean removed;
private final Set<Entity> passengers = new CopyOnWriteArraySet<>(); private final Set<Entity> passengers = new CopyOnWriteArraySet<>();
protected EntityType entityType; // UNSAFE to change, modify at your own risk protected EntityType entityType; // UNSAFE to change, modify at your own risk

View File

@ -261,10 +261,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public CompletableFuture<Void> UNSAFE_init(@NotNull Instance spawnInstance) { public CompletableFuture<Void> UNSAFE_init(@NotNull Instance spawnInstance) {
this.removed = false;
this.dimensionType = spawnInstance.getDimensionType(); this.dimensionType = spawnInstance.getDimensionType();
System.out.println("INIT PLAYER");
final JoinGamePacket joinGamePacket = new JoinGamePacket( final JoinGamePacket joinGamePacket = new JoinGamePacket(
getEntityId(), false, List.of(), 0, getEntityId(), false, List.of(), 0,
MinecraftServer.getChunkViewDistance(), MinecraftServer.getChunkViewDistance(), 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 the player is currently in the play state, we need to put them back in configuration.
if (playerConnection.getClientState() == ConnectionState.PLAY) { if (playerConnection.getClientState() == ConnectionState.PLAY) {
remove(false); remove(false);
System.out.println("SEND REENTER");
MinecraftServer.getConnectionManager().transitionPlayToConfig(this);
sendPacket(new StartConfigurationPacket()); sendPacket(new StartConfigurationPacket());
} else { } else {
// Sanity check that they are already in configuration. // 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) { public void update(long time) {
// Process received packets // Process received packets
interpretPacketQueue(); interpretPacketQueue();
if (isRemoved()) return;
super.update(time); // Super update (item pickup/fire management) super.update(time); // Super update (item pickup/fire management)

View File

@ -4,9 +4,20 @@ import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.client.play.ClientConfigurationAckPacket; import net.minestom.server.network.packet.client.play.ClientConfigurationAckPacket;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ForkJoinPool;
public class PlayConfigListener { public class PlayConfigListener {
public static void configAckListener(@NotNull ClientConfigurationAckPacket packet, @NotNull Player player) { 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();
});
} }
} }

View File

@ -9,6 +9,7 @@ public final class KeepAliveListener {
private static final Component KICK_MESSAGE = Component.text("Bad Keep Alive packet", NamedTextColor.RED); private static final Component KICK_MESSAGE = Component.text("Bad Keep Alive packet", NamedTextColor.RED);
public static void listener(ClientKeepAlivePacket packet, Player player) { public static void listener(ClientKeepAlivePacket packet, Player player) {
System.out.println("KEEP ALIVE LISTENER");
final long packetId = packet.id(); final long packetId = packet.id();
if (packetId != player.getLastKeepAlive()) { if (packetId != player.getLastKeepAlive()) {
player.kick(KICK_MESSAGE); player.kick(KICK_MESSAGE);

View File

@ -39,6 +39,7 @@ public final class ConnectionManager {
} }
private final MessagePassingQueue<PendingPlayer> waitingPlayers = new MpscUnboundedArrayQueue<>(64); private final MessagePassingQueue<PendingPlayer> waitingPlayers = new MpscUnboundedArrayQueue<>(64);
private final Set<Player> configurationPlayers = new CopyOnWriteArraySet<>();
private final Set<Player> players = new CopyOnWriteArraySet<>(); private final Set<Player> players = new CopyOnWriteArraySet<>();
private final Set<Player> unmodifiablePlayers = Collections.unmodifiableSet(players); private final Set<Player> unmodifiablePlayers = Collections.unmodifiableSet(players);
@ -189,7 +190,7 @@ public final class ConnectionManager {
@ApiStatus.Internal @ApiStatus.Internal
public void transitionLoginToConfig(@NotNull Player player) { public void transitionLoginToConfig(@NotNull Player player) {
configurationPlayers.add(player);
} }
@ApiStatus.Internal @ApiStatus.Internal
@ -199,7 +200,7 @@ public final class ConnectionManager {
@ApiStatus.Internal @ApiStatus.Internal
public void transitionPlayToConfig(@NotNull Player player) { 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) // Send login success packet (and switch to configuration phase)
LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername(), 0); LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername(), 0);
playerConnection.sendPacket(loginSuccessPacket); playerConnection.sendPacket(loginSuccessPacket);
configurationPlayers.add(player);
}); });
} }
@ -283,13 +285,23 @@ public final class ConnectionManager {
this.connectionPlayerMap.clear(); 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. * Connects waiting players.
*/ */
public void updateWaitingPlayers() { private void updateWaitingPlayers() {
this.waitingPlayers.drain(pp -> { this.waitingPlayers.drain(pp -> {
configurationPlayers.remove(pp.player);
System.out.println("DRAIN PP " + pp);
// Spawn the player at Player#getRespawnPoint // Spawn the player at Player#getRespawnPoint
CompletableFuture<Void> spawnFuture = pp.player.UNSAFE_init(pp.instance); CompletableFuture<Void> 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 * @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); final KeepAlivePacket keepAlivePacket = new KeepAlivePacket(tickStart);
for (Player player : getOnlinePlayers()) { for (Player player : getOnlinePlayers()) {
final long lastKeepAlive = tickStart - player.getLastKeepAlive(); final long lastKeepAlive = tickStart - player.getLastKeepAlive();

View File

@ -53,8 +53,10 @@ public class PacketProcessor {
} }
public ClientPacket process(@NotNull PlayerConnection connection, int packetId, ByteBuffer body) { 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 ClientPacket packet = create(connection.getClientState(), packetId, body);
final ConnectionState state = connection.getClientState(); final ConnectionState state = connection.getClientState();
System.out.println("READ2: " + state + " " + packet.getClass().getSimpleName());
switch (state) { switch (state) {
case HANDSHAKE, STATUS, LOGIN, CONFIGURATION -> packetListenerManager.processClientPacket(connection.getClientState(), packet, connection); case HANDSHAKE, STATUS, LOGIN, CONFIGURATION -> packetListenerManager.processClientPacket(connection.getClientState(), packet, connection);
case PLAY -> { case PLAY -> {