feat: working (scuffed) reentry after reconfiguration

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

View File

@ -257,11 +257,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);

View File

@ -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<Entity> passengers = new CopyOnWriteArraySet<>();
protected EntityType entityType; // UNSAFE to change, modify at your own risk

View File

@ -262,10 +262,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
*/
@ApiStatus.Internal
public CompletableFuture<Void> 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(),
@ -388,6 +387,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.
@ -423,6 +424,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)

View File

@ -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();
});
}
}

View File

@ -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);

View File

@ -39,6 +39,7 @@ public final class ConnectionManager {
}
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> 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<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
*/
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();

View File

@ -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 -> {