diff --git a/demo/src/main/java/net/minestom/demo/PlayerInit.java b/demo/src/main/java/net/minestom/demo/PlayerInit.java index ee475a6d09c..68c54e190ac 100644 --- a/demo/src/main/java/net/minestom/demo/PlayerInit.java +++ b/demo/src/main/java/net/minestom/demo/PlayerInit.java @@ -14,6 +14,7 @@ import net.minestom.server.entity.ItemEntity; import net.minestom.server.entity.Player; import net.minestom.server.entity.damage.Damage; +import net.minestom.server.entity.fakeplayer.FakePlayer; import net.minestom.server.event.Event; import net.minestom.server.event.EventNode; import net.minestom.server.event.entity.EntityAttackEvent; @@ -34,7 +35,6 @@ import net.minestom.server.monitoring.BenchmarkManager; import net.minestom.server.monitoring.TickMonitor; import net.minestom.server.utils.MathUtils; -import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.world.DimensionType; @@ -84,17 +84,15 @@ public class PlayerInit { itemEntity.setInstance(player.getInstance(), playerPos.withY(y -> y + 1.5)); Vec velocity = playerPos.direction().mul(6); itemEntity.setVelocity(velocity); + + FakePlayer.initPlayer(UUID.randomUUID(), "fake123", fp -> { + System.out.println("fp = " + fp); + }); }) .addListener(PlayerDisconnectEvent.class, event -> System.out.println("DISCONNECTION " + event.getPlayer().getUsername())) .addListener(AsyncPlayerConfigurationEvent.class, event -> { final Player player = event.getPlayer(); - try { - Thread.sleep(60 * 1000); - } catch (Exception e) { - throw new RuntimeException(e); - } - var instances = MinecraftServer.getInstanceManager().getInstances(); Instance instance = instances.stream().skip(new Random().nextInt(instances.size())).findFirst().orElse(null); event.setSpawningInstance(instance); @@ -175,10 +173,10 @@ public class PlayerInit { instanceContainer.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.STONE)); instanceContainer.setChunkSupplier(LightingChunk::new); - var i2 = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, null, NamespaceID.from("minestom:demo")); - instanceManager.registerInstance(i2); - i2.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.GRASS_BLOCK)); - i2.setChunkSupplier(LightingChunk::new); +// var i2 = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD, null, NamespaceID.from("minestom:demo")); +// instanceManager.registerInstance(i2); +// i2.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.GRASS_BLOCK)); +// i2.setChunkSupplier(LightingChunk::new); // System.out.println("start"); // var chunks = new ArrayList>(); diff --git a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java index f5447af85ca..d7487a4f4e3 100644 --- a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java +++ b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java @@ -6,11 +6,13 @@ import net.minestom.server.entity.Player; import net.minestom.server.entity.pathfinding.NavigableEntity; import net.minestom.server.entity.pathfinding.Navigator; -import net.minestom.server.event.Event; import net.minestom.server.event.EventListener; import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.instance.Instance; +import net.minestom.server.listener.manager.PacketListenerManager; import net.minestom.server.network.ConnectionManager; +import net.minestom.server.network.ConnectionState; +import net.minestom.server.network.packet.client.login.ClientLoginAcknowledgedPacket; import net.minestom.server.network.player.FakePlayerConnection; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.utils.time.TimeUnit; @@ -32,6 +34,7 @@ public class FakePlayer extends Player implements NavigableEntity { private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager(); + private static final PacketListenerManager PACKET_LISTENER_MANAGER = MinecraftServer.getPacketListenerManager(); private final FakePlayerOption option; private final FakePlayerController fakePlayerController; @@ -58,6 +61,7 @@ protected FakePlayer(@NotNull UUID uuid, @NotNull String username, if (spawnCallback != null) { spawnListener = EventListener.builder(PlayerSpawnEvent.class) + .expireWhen(ignored -> this.isRemoved()) .handler(event -> { if (event.getPlayer().equals(this)) if (event.isFirstSpawn()) { @@ -68,7 +72,11 @@ protected FakePlayer(@NotNull UUID uuid, @NotNull String username, MinecraftServer.getGlobalEventHandler().addListener(spawnListener); } - CONNECTION_MANAGER.transitionLoginToConfig(this); + playerConnection.setConnectionState(ConnectionState.LOGIN); + CONNECTION_MANAGER.transitionLoginToConfig(this).thenRun(() -> { + // Need to immediately reply with login acknowledged for the player to enter config. + PACKET_LISTENER_MANAGER.processClientPacket(new ClientLoginAcknowledgedPacket(), getPlayerConnection()); + }); } /** diff --git a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java index 5022e7833b0..a05d589aaa8 100644 --- a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java +++ b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java @@ -11,10 +11,12 @@ import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.network.packet.client.common.ClientKeepAlivePacket; import net.minestom.server.network.packet.client.common.ClientPluginMessagePacket; +import net.minestom.server.network.packet.client.configuration.ClientFinishConfigurationPacket; import net.minestom.server.network.packet.client.play.*; import net.minestom.server.network.packet.server.SendablePacket; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.common.KeepAlivePacket; +import net.minestom.server.network.packet.server.configuration.FinishConfigurationPacket; import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.utils.MathUtils; @@ -196,6 +198,8 @@ public void consumePacket(ServerPacket serverPacket) { addToQueue(new ClientTeleportConfirmPacket(playerPositionAndLookPacket.teleportId())); } else if (serverPacket instanceof KeepAlivePacket keepAlivePacket) { addToQueue(new ClientKeepAlivePacket(keepAlivePacket.id())); + } else if (serverPacket instanceof FinishConfigurationPacket) { + addToQueue(new ClientFinishConfigurationPacket()); } } @@ -206,7 +210,6 @@ public void consumePacket(ServerPacket serverPacket) { * @param clientPlayPacket The packet to add in the queue. */ private void addToQueue(ClientPacket clientPlayPacket) { - //todo fix me -// this.fakePlayer.addPacketToQueue(clientPlayPacket); + this.fakePlayer.addPacketToQueue(clientPlayPacket); } } diff --git a/src/main/java/net/minestom/server/listener/preplay/LoginListener.java b/src/main/java/net/minestom/server/listener/preplay/LoginListener.java index 2b12707b496..c14c02beb3e 100644 --- a/src/main/java/net/minestom/server/listener/preplay/LoginListener.java +++ b/src/main/java/net/minestom/server/listener/preplay/LoginListener.java @@ -214,22 +214,6 @@ public static void loginPluginResponseListener(@NotNull ClientLoginPluginRespons public static void loginAckListener(@NotNull ClientLoginAcknowledgedPacket ignored, @NotNull PlayerConnection connection) { final Player player = Objects.requireNonNull(connection.getPlayer()); CONNECTION_MANAGER.doConfiguration(player, true); -// // Registry data -// var registry = new HashMap(); -// registry.put("minecraft:chat_type", Messenger.chatRegistry()); -// registry.put("minecraft:dimension_type", MinecraftServer.getDimensionTypeManager().toNBT()); -// registry.put("minecraft:worldgen/biome", MinecraftServer.getBiomeManager().toNBT()); -// registry.put("minecraft:damage_type", DamageType.getNBT()); -// connection.sendPacket(new RegistryDataPacket(NBT.Compound(registry))); -// -// // Tags -// connection.sendPacket(TagsPacket.DEFAULT_TAGS); -// -// // Server Brand -// connection.sendPacket(PluginMessagePacket.getBrandPacket()); -// -// // Enter configuration phase (for the first time) -// CONNECTION_MANAGER.transitionConfigToPlay(player, true); } } diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java index 5dae96d88be..e7b76b96c9d 100644 --- a/src/main/java/net/minestom/server/network/ConnectionManager.java +++ b/src/main/java/net/minestom/server/network/ConnectionManager.java @@ -208,13 +208,14 @@ public void setPlayerProvider(@Nullable PlayerProvider playerProvider) { public @NotNull Player createPlayer(@NotNull PlayerConnection connection, @NotNull UUID uuid, @NotNull String username) { final Player player = playerProvider.createPlayer(uuid, username, connection); this.connectionPlayerMap.put(connection, player); - transitionLoginToConfig(player); + var future = transitionLoginToConfig(player); + if (DebugUtils.INSIDE_TEST) future.join(); return player; } @ApiStatus.Internal - public void transitionLoginToConfig(@NotNull Player player) { - CompletableFuture configFuture = AsyncUtils.runAsync(() -> { + public @NotNull CompletableFuture transitionLoginToConfig(@NotNull Player player) { + return AsyncUtils.runAsync(() -> { final PlayerConnection playerConnection = player.getPlayerConnection(); // Compression @@ -245,7 +246,6 @@ public void transitionLoginToConfig(@NotNull Player player) { LoginSuccessPacket loginSuccessPacket = new LoginSuccessPacket(player.getUuid(), player.getUsername(), 0); playerConnection.sendPacket(loginSuccessPacket); }); - if (DebugUtils.INSIDE_TEST) configFuture.join(); } @ApiStatus.Internal