diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java index daf0b90aa..779420c16 100644 --- a/src/main/java/fr/themode/demo/PlayerInit.java +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -8,6 +8,7 @@ import net.minestom.server.benchmark.ThreadResult; import net.minestom.server.entity.*; import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.fakeplayer.FakePlayer; +import net.minestom.server.entity.fakeplayer.FakePlayerController; import net.minestom.server.event.entity.EntityAttackEvent; import net.minestom.server.event.item.ItemDropEvent; import net.minestom.server.event.item.ItemUpdateStateEvent; @@ -154,6 +155,8 @@ public class PlayerInit { //chickenCreature.setInstance(player.getInstance()); FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test"); + FakePlayerController controller = fakePlayer.getController(); + controller.sendChatMessage("I am a bot!"); }); diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 8a5e3b895..e5ddb79cf 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -126,6 +126,9 @@ public class Player extends LivingEntity { setRespawnPoint(new Position(0, 0, 0)); + // FakePlayer init its connection there + playerConnectionInit(); + init(); // Some client update @@ -178,6 +181,7 @@ public class Player extends LivingEntity { spawnPositionPacket.z = 0; playerConnection.sendPacket(spawnPositionPacket); + // Add player to list String property = "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19"; PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER); PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(getUuid(), username, getGameMode(), 10); @@ -186,18 +190,22 @@ public class Player extends LivingEntity { playerInfoPacket.playerInfos.add(addPlayer); playerConnection.sendPacket(playerInfoPacket); + // Init player for (Consumer playerInitialization : MinecraftServer.getConnectionManager().getPlayerInitializations()) { playerInitialization.accept(this); } + // Commands start { CommandManager commandManager = MinecraftServer.getCommandManager(); DeclareCommandsPacket declareCommandsPacket = commandManager.createDeclareCommandsPacket(this); playerConnection.sendPacket(declareCommandsPacket); } + // Commands end + // Recipes start { RecipeManager recipeManager = MinecraftServer.getRecipeManager(); DeclareRecipesPacket declareRecipesPacket = recipeManager.getDeclareRecipesPacket(); @@ -221,6 +229,10 @@ public class Player extends LivingEntity { playerConnection.sendPacket(unlockRecipesPacket); } } + // Recipes end + } + + protected void playerConnectionInit() { } @Override 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 4b1b71a3e..57f414426 100644 --- a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java +++ b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayer.java @@ -11,9 +11,12 @@ public class FakePlayer extends Player { public FakePlayer(UUID uuid, String username) { super(uuid, username, new FakePlayerConnection()); + } + + @Override + protected void playerConnectionInit() { FakePlayerConnection playerConnection = (FakePlayerConnection) getPlayerConnection(); playerConnection.setFakePlayer(this); - this.fakePlayerController = new FakePlayerController(this); } 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 da947c6e5..cad1b8cd5 100644 --- a/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java +++ b/src/main/java/net/minestom/server/entity/fakeplayer/FakePlayerController.java @@ -1,16 +1,100 @@ package net.minestom.server.entity.fakeplayer; -import net.minestom.server.network.player.PlayerConnection; +import net.minestom.server.entity.Entity; +import net.minestom.server.inventory.Inventory; +import net.minestom.server.inventory.InventoryModifier; +import net.minestom.server.inventory.PlayerInventory; +import net.minestom.server.item.ItemStack; +import net.minestom.server.network.packet.client.ClientPlayPacket; +import net.minestom.server.network.packet.client.play.*; +import net.minestom.server.network.packet.server.ServerPacket; +import net.minestom.server.network.packet.server.play.KeepAlivePacket; +import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket; +import net.minestom.server.utils.inventory.PlayerInventoryUtils; +/** + * This class act as a client controller for {@link FakePlayer} + */ public class FakePlayerController { private FakePlayer fakePlayer; - private PlayerConnection playerConnection; public FakePlayerController(FakePlayer fakePlayer) { this.fakePlayer = fakePlayer; - this.playerConnection = fakePlayer.getPlayerConnection(); + } - fakePlayer.setHeldItemSlot((short) 1); + /** + * Make the player write a message + * + * @param message the message to write + */ + public void sendChatMessage(String message) { + ClientChatMessagePacket chatMessagePacket = new ClientChatMessagePacket(); + chatMessagePacket.message = message; + addToQueue(chatMessagePacket); + } + + public void clickWindow(boolean playerInventory, short slot, byte button, short action, int mode) { + Inventory inventory = playerInventory ? null : fakePlayer.getOpenInventory(); + InventoryModifier inventoryModifier = inventory == null ? fakePlayer.getInventory() : inventory; + playerInventory = inventoryModifier instanceof PlayerInventory; + + slot = playerInventory ? (short) PlayerInventoryUtils.convertToPacketSlot(slot) : slot; + + ItemStack itemStack = inventoryModifier.getItemStack(slot); + + ClientClickWindowPacket clickWindowPacket = new ClientClickWindowPacket(); + clickWindowPacket.windowId = playerInventory ? 0 : inventory.getWindowId(); + clickWindowPacket.slot = slot; + clickWindowPacket.button = button; + clickWindowPacket.actionNumber = action; + clickWindowPacket.mode = mode; + clickWindowPacket.item = itemStack; + addToQueue(clickWindowPacket); + } + + public void closeWindow() { + Inventory openInventory = fakePlayer.getOpenInventory(); + + ClientCloseWindow closeWindow = new ClientCloseWindow(); + closeWindow.windowId = openInventory == null ? 0 : openInventory.getWindowId(); + addToQueue(closeWindow); + } + + public void sendPluginMessage(String channel, byte[] message) { + ClientPluginMessagePacket pluginMessagePacket = new ClientPluginMessagePacket(); + pluginMessagePacket.channel = channel; + pluginMessagePacket.data = message; + addToQueue(pluginMessagePacket); + } + + public void attackEntity(Entity entity) { + ClientInteractEntityPacket interactEntityPacket = new ClientInteractEntityPacket(); + interactEntityPacket.targetId = entity.getEntityId(); + interactEntityPacket.type = ClientInteractEntityPacket.Type.ATTACK; + addToQueue(interactEntityPacket); + } + + /** + * Make the player receives a packet + * WARNING: pretty much unsafe, used internally to redirect packets here, + * you should instead use {@link net.minestom.server.network.player.PlayerConnection#sendPacket(ServerPacket)} + * + * @param serverPacket the packet to consume + */ + public void consumePacket(ServerPacket serverPacket) { + if (serverPacket instanceof PlayerPositionAndLookPacket) { + ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket(); + teleportConfirmPacket.teleportId = ((PlayerPositionAndLookPacket) serverPacket).teleportId; + addToQueue(teleportConfirmPacket); + } else if (serverPacket instanceof KeepAlivePacket) { + ClientKeepAlivePacket keepAlivePacket = new ClientKeepAlivePacket(); + keepAlivePacket.id = ((KeepAlivePacket) serverPacket).id; + addToQueue(keepAlivePacket); + } + } + + private void addToQueue(ClientPlayPacket clientPlayPacket) { + this.fakePlayer.addPacketToQueue(clientPlayPacket); } } diff --git a/src/main/java/net/minestom/server/listener/PluginMessageListener.java b/src/main/java/net/minestom/server/listener/PluginMessageListener.java index 5351a1473..b76a4d75d 100644 --- a/src/main/java/net/minestom/server/listener/PluginMessageListener.java +++ b/src/main/java/net/minestom/server/listener/PluginMessageListener.java @@ -7,7 +7,7 @@ import net.minestom.server.network.packet.client.play.ClientPluginMessagePacket; public class PluginMessageListener { public static void listener(ClientPluginMessagePacket packet, Player player) { - PlayerPluginMessageEvent pluginMessageEvent = new PlayerPluginMessageEvent(packet.identifier, packet.data); + PlayerPluginMessageEvent pluginMessageEvent = new PlayerPluginMessageEvent(packet.channel, packet.data); player.callEvent(PlayerPluginMessageEvent.class, pluginMessageEvent); } diff --git a/src/main/java/net/minestom/server/listener/WindowListener.java b/src/main/java/net/minestom/server/listener/WindowListener.java index 27382ef45..8bc0331cd 100644 --- a/src/main/java/net/minestom/server/listener/WindowListener.java +++ b/src/main/java/net/minestom/server/listener/WindowListener.java @@ -14,12 +14,17 @@ import net.minestom.server.network.packet.server.play.WindowConfirmationPacket; public class WindowListener { public static void clickWindowListener(ClientClickWindowPacket packet, Player player) { - InventoryClickHandler clickHandler = player.getOpenInventory(); - if (clickHandler == null) { - clickHandler = player.getInventory(); + Inventory inventory; + byte windowId = packet.windowId; + if (windowId == 0) { + inventory = null; + } else { + inventory = player.getOpenInventory(); } - byte windowId = packet.windowId; + InventoryClickHandler clickHandler = inventory == null ? + player.getInventory() : player.getOpenInventory(); + short slot = packet.slot; byte button = packet.button; short actionNumber = packet.actionNumber; @@ -74,7 +79,7 @@ public class WindowListener { break; } - refreshCursorItem(player, player.getOpenInventory()); + refreshCursorItem(player, inventory); WindowConfirmationPacket windowConfirmationPacket = new WindowConfirmationPacket(); windowConfirmationPacket.windowId = windowId; diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientPluginMessagePacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientPluginMessagePacket.java index df923aaf6..11fb15e72 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientPluginMessagePacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientPluginMessagePacket.java @@ -5,12 +5,12 @@ import net.minestom.server.network.packet.client.ClientPlayPacket; public class ClientPluginMessagePacket extends ClientPlayPacket { - public String identifier; + public String channel; public byte[] data; @Override public void read(PacketReader reader) { - this.identifier = reader.readSizedString(); + this.channel = reader.readSizedString(); this.data = reader.getRemainingBytes(); } } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/KeepAlivePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/KeepAlivePacket.java index b82df3a99..941eef6be 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/KeepAlivePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/KeepAlivePacket.java @@ -6,7 +6,7 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier; public class KeepAlivePacket implements ServerPacket { - private long id; + public long id; public KeepAlivePacket(long id) { this.id = id; diff --git a/src/main/java/net/minestom/server/network/player/FakePlayerConnection.java b/src/main/java/net/minestom/server/network/player/FakePlayerConnection.java index a39aaa594..1eba9f741 100644 --- a/src/main/java/net/minestom/server/network/player/FakePlayerConnection.java +++ b/src/main/java/net/minestom/server/network/player/FakePlayerConnection.java @@ -23,7 +23,7 @@ public class FakePlayerConnection extends PlayerConnection { @Override public void sendPacket(ServerPacket serverPacket) { - + this.fakePlayer.getController().consumePacket(serverPacket); } @Override