diff --git a/src/main/java/fr/themode/minestom/Main.java b/src/main/java/fr/themode/minestom/Main.java index 9b2bad581..7520176e7 100644 --- a/src/main/java/fr/themode/minestom/Main.java +++ b/src/main/java/fr/themode/minestom/Main.java @@ -6,9 +6,13 @@ import fr.adamaq01.ozao.net.server.Server; import fr.adamaq01.ozao.net.server.ServerHandler; import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer; import fr.themode.minestom.entity.EntityManager; +import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.ConnectionManager; import fr.themode.minestom.net.PacketProcessor; +import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket; import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; +import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket; +import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.net.protocol.MinecraftProtocol; import java.lang.reflect.InvocationTargetException; @@ -21,6 +25,7 @@ public class Main { // Others private static ConnectionManager connectionManager; private static PacketProcessor packetProcessor; + private static Server server; public static void main(String[] args) { entityManager = new EntityManager(); @@ -28,7 +33,7 @@ public class Main { connectionManager = new ConnectionManager(); packetProcessor = new PacketProcessor(connectionManager); - Server server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() { + server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() { @Override public void onConnect(Server server, Connection connection) { System.out.println("A connection"); @@ -37,6 +42,25 @@ public class Main { @Override public void onDisconnect(Server server, Connection connection) { System.out.println("A DISCONNECTION"); + if (packetProcessor.hasPlayerConnection(connection)) { + if (connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)) != null) { + Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(connection)); + player.remove(); + connectionManager.removePlayer(packetProcessor.getPlayerConnection(connection)); + + PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.REMOVE_PLAYER); + playerInfoPacket.playerInfos.add(new PlayerInfoPacket.RemovePlayer(player.getUuid())); + DestroyEntitiesPacket destroyEntitiesPacket = new DestroyEntitiesPacket(); + destroyEntitiesPacket.entityIds = new int[] {player.getEntityId()}; + for (Player onlinePlayer : connectionManager.getOnlinePlayers()) { + if (!onlinePlayer.equals(player)) { + onlinePlayer.getPlayerConnection().sendPacket(destroyEntitiesPacket); + onlinePlayer.getPlayerConnection().sendPacket(playerInfoPacket); + } + } + } + packetProcessor.removePlayerConnection(connection); + } } @Override @@ -83,6 +107,10 @@ public class Main { } } + public static Server getServer() { + return server; + } + public static EntityManager getEntityManager() { return entityManager; } diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index 92881fe3f..d2a2e0a38 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -9,7 +9,7 @@ public class Entity { private static volatile int lastEntityId; protected double x, y, z; private int id; - private UUID uuid; + protected UUID uuid; private boolean isActive; // False if entity has only been instanced without being added somewhere private boolean shouldRemove; @@ -79,5 +79,4 @@ public class Entity { protected boolean shouldRemove() { return shouldRemove; } - } diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index b82f118eb..a20fe499d 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -32,4 +32,5 @@ public class EntityManager { protected void addLivingEntity(LivingEntity livingEntity) { this.livingEntities.add(livingEntity); } + } diff --git a/src/main/java/fr/themode/minestom/entity/Player.java b/src/main/java/fr/themode/minestom/entity/Player.java index 6c462806e..0a865a0bb 100644 --- a/src/main/java/fr/themode/minestom/entity/Player.java +++ b/src/main/java/fr/themode/minestom/entity/Player.java @@ -1,7 +1,13 @@ package fr.themode.minestom.entity; +import fr.themode.minestom.Main; +import fr.themode.minestom.net.packet.server.play.EntityLookAndRelativeMovePacket; +import fr.themode.minestom.net.packet.server.play.EntityTeleportPacket; +import fr.themode.minestom.net.packet.server.play.PlayerPositionAndLookPacket; import fr.themode.minestom.net.player.PlayerConnection; +import java.util.UUID; + public class Player extends LivingEntity { private boolean isSneaking; @@ -9,16 +15,35 @@ public class Player extends LivingEntity { private long lastKeepAlive; + private String username; private PlayerConnection playerConnection; // TODO set proper UUID - public Player(PlayerConnection playerConnection) { + public Player(UUID uuid, String username, PlayerConnection playerConnection) { + this.uuid = uuid; + this.username = username; this.playerConnection = playerConnection; } @Override public void update() { // System.out.println("Je suis l'update"); + EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); + entityTeleportPacket.entityId = getEntityId(); + entityTeleportPacket.x = x; + entityTeleportPacket.y = y; + entityTeleportPacket.z = z; + entityTeleportPacket.yaw = yaw; + entityTeleportPacket.pitch = pitch; + entityTeleportPacket.onGround = true; + for (Player onlinePlayer : Main.getConnectionManager().getOnlinePlayers()) { + if (!onlinePlayer.equals(this)) + onlinePlayer.getPlayerConnection().sendPacket(entityTeleportPacket); + } + } + + public String getUsername() { + return username; } public PlayerConnection getPlayerConnection() { @@ -55,4 +80,9 @@ public class Player extends LivingEntity { public long getLastKeepAlive() { return lastKeepAlive; } + + public enum Hand { + MAIN, + OFF + } } diff --git a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java b/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java index 37c512844..e3e76e5d4 100644 --- a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java +++ b/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java @@ -19,7 +19,7 @@ public class ChickenCreature extends EntityCreature { EntityRelativeMovePacket entityRelativeMovePacket = new EntityRelativeMovePacket(); entityRelativeMovePacket.entityId = getEntityId(); entityRelativeMovePacket.deltaZ = (short) ((newPos * 32 - getZ() * 32) * 128); - entityRelativeMovePacket.onGround = true; + entityRelativeMovePacket.onGround = false; getViewers().forEach(player -> player.getPlayerConnection().sendPacket(entityRelativeMovePacket)); setZ(newPos); } diff --git a/src/main/java/fr/themode/minestom/net/ConnectionManager.java b/src/main/java/fr/themode/minestom/net/ConnectionManager.java index fb5526a75..feed6198e 100644 --- a/src/main/java/fr/themode/minestom/net/ConnectionManager.java +++ b/src/main/java/fr/themode/minestom/net/ConnectionManager.java @@ -3,10 +3,7 @@ package fr.themode.minestom.net; import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.player.PlayerConnection; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class ConnectionManager { @@ -21,7 +18,11 @@ public class ConnectionManager { } // Is only used at LoginStartPacket#process - public void createPlayer(PlayerConnection connection) { - this.connectionPlayerMap.put(connection, new Player(connection)); + public void createPlayer(UUID uuid, String username, PlayerConnection connection) { + this.connectionPlayerMap.put(connection, new Player(uuid, username, connection)); + } + + public void removePlayer(PlayerConnection connection) { + this.connectionPlayerMap.remove(connection); } } diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index 416cf9361..5cb742c97 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -85,4 +85,8 @@ public class PacketProcessor { public boolean hasPlayerConnection(Connection connection) { return connectionPlayerConnectionMap.containsKey(connection); } + + public void removePlayerConnection(Connection connection) { + connectionPlayerConnectionMap.remove(connection); + } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java index 3c6749774..d4df63f13 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPlayPacketsHandler.java @@ -16,5 +16,7 @@ public class ClientPlayPacketsHandler extends ClientPacketsHandler { register(0x14, ClientPlayerPacket.class); register(0x2A, ClientAnimationPacket.class); register(0x1B, ClientEntityActionPacket.class); + register(0x0E, ClientUseEntityPacket.class); + register(0x03, ClientChatMessagePacket.class); } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java index 2681f0495..f9b426ff8 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java @@ -10,24 +10,36 @@ import fr.themode.minestom.net.ConnectionState; import fr.themode.minestom.net.packet.client.ClientPreplayPacket; import fr.themode.minestom.net.packet.server.login.JoinGamePacket; import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket; +import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket; import fr.themode.minestom.net.packet.server.play.PlayerPositionAndLookPacket; +import fr.themode.minestom.net.packet.server.play.SpawnPlayerPacket; import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket; import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.utils.Utils; import fr.themode.minestom.world.*; +import java.util.HashMap; +import java.util.UUID; + public class LoginStartPacket implements ClientPreplayPacket { private String username; @Override public void process(PlayerConnection connection, ConnectionManager connectionManager) { + HashMap uuids = new HashMap<>(); + uuids.put("TheMode911", UUID.fromString("ab70ecb4-2346-4c14-a52d-7a091507c24e")); + uuids.put("Adamaq01", UUID.fromString("58ffa9d8-aee1-4587-8b79-41b754f6f238")); + HashMap properties = new HashMap<>(); + properties.put("TheMode911", "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19"); + properties.put("Adamaq01", "eyJ0aW1lc3RhbXAiOjE1NjU0NzgyODU4MTksInByb2ZpbGVJZCI6IjU4ZmZhOWQ4YWVlMTQ1ODc4Yjc5NDFiNzU0ZjZmMjM4IiwicHJvZmlsZU5hbWUiOiJBZGFtYXEwMSIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lMTNiNmMyMjNlMTFiYjM1Nzc5OTdkZWY3YzA2ZDUwZmM4NzMxYjBkZWQyOTRlZDQ2ZmM4ZDczNDI1NGM5ZTkifSwiQ0FQRSI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IwY2MwODg0MDcwMDQ0NzMyMmQ5NTNhMDJiOTY1ZjFkNjVhMTNhNjAzYmY2NGIxN2M4MDNjMjE0NDZmZTE2MzUifX19"); + // TODO send encryption request OR directly login success - LoginSuccessPacket successPacket = new LoginSuccessPacket(username); + LoginSuccessPacket successPacket = new LoginSuccessPacket(uuids.get(username), username); connection.sendPacket(successPacket); connection.setConnectionState(ConnectionState.PLAY); - connectionManager.createPlayer(connection); + connectionManager.createPlayer(uuids.get(username), username, connection); Player player = connectionManager.getPlayer(connection); player.addToWorld(); @@ -36,10 +48,9 @@ public class LoginStartPacket implements ClientPreplayPacket { joinGamePacket.entityId = player.getEntityId(); joinGamePacket.gameMode = GameMode.CREATIVE; joinGamePacket.dimension = Dimension.OVERWORLD; - joinGamePacket.maxPlayers = 0; + joinGamePacket.maxPlayers = 10; joinGamePacket.levelType = "default"; joinGamePacket.reducedDebugInfo = false; - connection.sendPacket(joinGamePacket); // TODO minecraft:brand plugin message @@ -53,13 +64,14 @@ public class LoginStartPacket implements ClientPreplayPacket { for (int z = 0; z < 16; z++) customChunk.setBlock(x, 4, z, new CustomBlock(1)); // Stone - for (int x = -5; x < 5; x++) { - for (int z = -5; z < 5; z++) { + for (int x = -2; x < 2; x++) { + for (int z = -2; z < 2; z++) { Packet packet = ChunkPacketCreator.create(x, z, customChunk, 0, 15); connection.getConnection().sendPacket(packet); } } + SpawnPositionPacket spawnPositionPacket = new SpawnPositionPacket(); spawnPositionPacket.x = 0; spawnPositionPacket.y = 18; @@ -67,23 +79,59 @@ public class LoginStartPacket implements ClientPreplayPacket { connection.sendPacket(spawnPositionPacket); PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket(); - playerPositionAndLookPacket.x = 50; + playerPositionAndLookPacket.x = 0; playerPositionAndLookPacket.y = 5; - playerPositionAndLookPacket.z = 50; + playerPositionAndLookPacket.z = 0; playerPositionAndLookPacket.yaw = 0; playerPositionAndLookPacket.pitch = 0; playerPositionAndLookPacket.flags = 0; playerPositionAndLookPacket.teleportId = 42; connection.sendPacket(playerPositionAndLookPacket); - for (int x = -20; x < 20; x++) - for (int z = -20; z < 20; z++) { + PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER); + PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(uuids.get(username), username, GameMode.CREATIVE, 10); + PlayerInfoPacket.AddPlayer.Property property = new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(username)); + addPlayer.properties.add(property); + playerInfoPacket.playerInfos.add(addPlayer); + connection.sendPacket(playerInfoPacket); + + for (int x = -2; x < 2; x++) + for (int z = -2; z < 2; z++) { // TODO test entity ChickenCreature chickenCreature = new ChickenCreature(); - chickenCreature.setPosition(50 + (double) x * 1, 5, 50 + (double) z * 1); + chickenCreature.setPosition(0 + (double) x * 1, 5, 0 + (double) z * 1); connectionManager.getOnlinePlayers().forEach(p -> chickenCreature.addViewer(p)); chickenCreature.addToWorld(); } + + + SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket(); + spawnPlayerPacket.entityId = player.getEntityId(); + spawnPlayerPacket.playerUuid = uuids.get(username); + spawnPlayerPacket.x = 0; + spawnPlayerPacket.y = 5; + spawnPlayerPacket.z = 0; + for (Player onlinePlayer : connectionManager.getOnlinePlayers()) { + if (onlinePlayer.getUsername().equals(username)) continue; + onlinePlayer.getPlayerConnection().sendPacket(playerInfoPacket); + onlinePlayer.getPlayerConnection().sendPacket(spawnPlayerPacket); + + SpawnPlayerPacket spawnPacket = new SpawnPlayerPacket(); + spawnPacket.entityId = onlinePlayer.getEntityId(); + spawnPacket.playerUuid = uuids.get(onlinePlayer.getUsername()); + spawnPacket.x = onlinePlayer.getX(); + spawnPacket.y = onlinePlayer.getY(); + spawnPacket.z = onlinePlayer.getZ(); + + PlayerInfoPacket pInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER); + PlayerInfoPacket.AddPlayer addP = new PlayerInfoPacket.AddPlayer(uuids.get(onlinePlayer.getUsername()), onlinePlayer.getUsername(), GameMode.CREATIVE, 10); + PlayerInfoPacket.AddPlayer.Property p = new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(onlinePlayer.getUsername())); + addP.properties.add(p); + pInfoPacket.playerInfos.add(addP); + connection.sendPacket(pInfoPacket); + connection.sendPacket(spawnPacket); + } + System.out.println("HAHAHAHHAHHAH " + player.getUuid()); } @Override diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientAnimationPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientAnimationPacket.java index 4b2a91cfb..0ddc338c7 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientAnimationPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientAnimationPacket.java @@ -7,7 +7,7 @@ import fr.themode.minestom.utils.Utils; public class ClientAnimationPacket implements ClientPlayPacket { - public Hand hand; + public Player.Hand hand; @Override public void process(Player player) { @@ -15,11 +15,6 @@ public class ClientAnimationPacket implements ClientPlayPacket { @Override public void read(Buffer buffer) { - this.hand = Hand.values()[Utils.readVarInt(buffer)]; - } - - public enum Hand { - MAIN, - OFF + this.hand = Player.Hand.values()[Utils.readVarInt(buffer)]; } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientChatMessagePacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientChatMessagePacket.java new file mode 100644 index 000000000..cfc6c15a4 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientChatMessagePacket.java @@ -0,0 +1,24 @@ +package fr.themode.minestom.net.packet.client.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.Main; +import fr.themode.minestom.entity.Player; +import fr.themode.minestom.net.packet.client.ClientPlayPacket; +import fr.themode.minestom.net.packet.server.play.ChatMessagePacket; +import fr.themode.minestom.utils.Utils; + +public class ClientChatMessagePacket implements ClientPlayPacket { + + private String message; + + @Override + public void process(Player player) { + ChatMessagePacket chatMessagePacket = new ChatMessagePacket(String.format("{\"text\": \"<%s> %s\"}", player.getUsername(), message), ChatMessagePacket.Position.CHAT); + Main.getConnectionManager().getOnlinePlayers().forEach(player1 -> player1.getPlayerConnection().sendPacket(chatMessagePacket)); + } + + @Override + public void read(Buffer buffer) { + this.message = Utils.readString(buffer); + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientUseEntityPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientUseEntityPacket.java new file mode 100644 index 000000000..bb32b2714 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientUseEntityPacket.java @@ -0,0 +1,41 @@ +package fr.themode.minestom.net.packet.client.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.entity.Player; +import fr.themode.minestom.net.packet.client.ClientPlayPacket; +import fr.themode.minestom.utils.Utils; + +public class ClientUseEntityPacket implements ClientPlayPacket { + + private int target; + private Type type; + private float x; + private float y; + private float z; + private Player.Hand hand; + + @Override + public void process(Player player) { + + } + + @Override + public void read(Buffer buffer) { + this.target = Utils.readVarInt(buffer); + this.type = Type.values()[Utils.readVarInt(buffer)]; + if (this.type == Type.INTERACT_AT) { + this.x = buffer.getFloat(); + this.y = buffer.getFloat(); + this.z = buffer.getFloat(); + } + if (type == Type.INTERACT || type == Type.INTERACT_AT) + this.hand = Player.Hand.values()[Utils.readVarInt(buffer)]; + } + + public static enum Type { + + INTERACT, + ATTACK, + INTERACT_AT; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/login/LoginSuccessPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/login/LoginSuccessPacket.java index 96ea98d18..313c4a346 100644 --- a/src/main/java/fr/themode/minestom/net/packet/server/login/LoginSuccessPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/server/login/LoginSuccessPacket.java @@ -8,15 +8,22 @@ import java.util.UUID; public class LoginSuccessPacket implements ServerPacket { + public UUID uuid; public String username; public LoginSuccessPacket(String username) { + this.uuid = UUID.randomUUID(); + this.username = username; + } + + public LoginSuccessPacket(UUID uuid, String username) { + this.uuid = uuid; this.username = username; } @Override public void write(Buffer buffer) { - Utils.writeString(buffer, UUID.randomUUID().toString()); // TODO mojang auth + Utils.writeString(buffer, uuid.toString()); // TODO mojang auth Utils.writeString(buffer, username); } diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/ChatMessagePacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/ChatMessagePacket.java new file mode 100644 index 000000000..63fd6ea84 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/ChatMessagePacket.java @@ -0,0 +1,34 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class ChatMessagePacket implements ServerPacket { + + private String message; + private Position position; + + public ChatMessagePacket(String message, Position position) { + this.message = message; + this.position = position; + } + + @Override + public void write(Buffer buffer) { + Utils.writeString(buffer, this.message); + buffer.putByte((byte) this.position.ordinal()); + } + + @Override + public int getId() { + return 0x0E; + } + + public static enum Position { + + CHAT, + SYSTEM_MESSAGE, + GAME_INFO; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/DestroyEntitiesPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/DestroyEntitiesPacket.java new file mode 100644 index 000000000..600255f66 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/DestroyEntitiesPacket.java @@ -0,0 +1,24 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class DestroyEntitiesPacket implements ServerPacket { + + public int[] entityIds; + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, entityIds.length); + for (int i = 0; i < entityIds.length; i++) { + int entityId = entityIds[i]; + Utils.writeVarInt(buffer, entityId); + } + } + + @Override + public int getId() { + return 0x37; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/EntityMetaDataPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityMetaDataPacket.java new file mode 100644 index 000000000..691625614 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityMetaDataPacket.java @@ -0,0 +1,20 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class EntityMetaDataPacket implements ServerPacket { + + public int entityId; + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, entityId); + } + + @Override + public int getId() { + return 0x43; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/EntityTeleportPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityTeleportPacket.java new file mode 100644 index 000000000..2b8be252b --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/EntityTeleportPacket.java @@ -0,0 +1,29 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +public class EntityTeleportPacket implements ServerPacket { + + public int entityId; + public double x, y, z; + public float yaw, pitch; + public boolean onGround; + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, entityId); + buffer.putDouble(x); + buffer.putDouble(y); + buffer.putDouble(y); + buffer.getData().writeByte((int) (this.yaw * 256 / 360)); + buffer.getData().writeByte((int) (this.pitch * 256 / 360)); + buffer.putBoolean(onGround); + } + + @Override + public int getId() { + return 0x56; + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/PlayerInfoPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/PlayerInfoPacket.java new file mode 100644 index 000000000..3df552d75 --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/PlayerInfoPacket.java @@ -0,0 +1,177 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.entity.GameMode; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +import java.util.ArrayList; +import java.util.UUID; + +public class PlayerInfoPacket implements ServerPacket { + + public Action action; + public ArrayList playerInfos; + + public PlayerInfoPacket(Action action) { + this.action = action; + this.playerInfos = new ArrayList<>(); + } + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, this.action.ordinal()); + Utils.writeVarInt(buffer, this.playerInfos.size()); + for (PlayerInfo playerInfo : this.playerInfos) { + if (!playerInfo.getClass().equals(action.getClazz())) continue; + buffer.putLong(playerInfo.uuid.getMostSignificantBits()); + buffer.putLong(playerInfo.uuid.getLeastSignificantBits()); + playerInfo.write(buffer); + } + } + + @Override + public int getId() { + return 0x33; + } + + public static enum Action { + + ADD_PLAYER(AddPlayer.class), + UPDATE_GAMEMODE(UpdateGamemode.class), + UPDATE_LATENCY(UpdateLatency.class), + UPDATE_DISPLAY_NAME(UpdateDisplayName.class), + REMOVE_PLAYER(RemovePlayer.class); + + private Class clazz; + + Action(Class clazz) { + this.clazz = clazz; + } + + public Class getClazz() { + return clazz; + } + } + + public static abstract class PlayerInfo { + + public UUID uuid; + + public PlayerInfo(UUID uuid) { + this.uuid = uuid; + } + + public abstract void write(Buffer buffer); + } + + public static class AddPlayer extends PlayerInfo { + + public String name; + public ArrayList properties; + public GameMode gameMode; + public int ping; + public boolean hasDisplayName = false; + public String displayName; + + public AddPlayer(UUID uuid, String name, GameMode gameMode, int ping) { + super(uuid); + this.name = name; + this.properties = new ArrayList<>(); + this.gameMode = gameMode; + this.ping = ping; + } + + @Override + public void write(Buffer buffer) { + Utils.writeString(buffer, name); + Utils.writeVarInt(buffer, properties.size()); + for (Property property : properties) { + property.write(buffer); + } + Utils.writeVarInt(buffer, gameMode.getId()); + Utils.writeVarInt(buffer, ping); + buffer.putBoolean(hasDisplayName); + if (hasDisplayName) + Utils.writeString(buffer, displayName); + } + + public static class Property { + + public String name; + public String value; + public boolean signed = false; + public String signature; + + public Property(String name, String value) { + this.name = name; + this.value = value; + } + + public void write(Buffer buffer) { + Utils.writeString(buffer, name); + Utils.writeString(buffer, value); + buffer.putBoolean(signed); + if (signed) + Utils.writeString(buffer, signature); + } + } + } + + public static class UpdateGamemode extends PlayerInfo { + + public GameMode gameMode; + + public UpdateGamemode(UUID uuid, GameMode gameMode) { + super(uuid); + this.gameMode = gameMode; + } + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, gameMode.getId()); + } + } + + public static class UpdateLatency extends PlayerInfo { + + public int ping; + + public UpdateLatency(UUID uuid, int ping) { + super(uuid); + this.ping = ping; + } + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, ping); + } + } + + public static class UpdateDisplayName extends PlayerInfo { + + public String displayName; + + public UpdateDisplayName(UUID uuid, String displayName) { + super(uuid); + this.displayName = displayName; + } + + @Override + public void write(Buffer buffer) { + buffer.putBoolean(true); // ???? + Utils.writeString(buffer, displayName); + } + } + + public static class RemovePlayer extends PlayerInfo { + + public RemovePlayer(UUID uuid) { + super(uuid); + } + + @Override + public void write(Buffer buffer) { + } + } +} diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/SpawnPlayerPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/SpawnPlayerPacket.java new file mode 100644 index 000000000..064e2971c --- /dev/null +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/SpawnPlayerPacket.java @@ -0,0 +1,36 @@ +package fr.themode.minestom.net.packet.server.play; + +import fr.adamaq01.ozao.net.Buffer; +import fr.themode.minestom.net.packet.server.ServerPacket; +import fr.themode.minestom.utils.Utils; + +import java.util.UUID; + +public class SpawnPlayerPacket implements ServerPacket { + + public int entityId; + public UUID playerUuid; + public double x; + public double y; + public double z; + // public float yaw; + // public float pitch; + + @Override + public void write(Buffer buffer) { + Utils.writeVarInt(buffer, entityId); + buffer.putLong(playerUuid.getMostSignificantBits()); + buffer.putLong(playerUuid.getLeastSignificantBits()); + buffer.putDouble(x); + buffer.putDouble(y); + buffer.putDouble(z); + buffer.getData().writeByte(0); + buffer.getData().writeByte(0); + buffer.putByte((byte) 0xff); // TODO Metadata + } + + @Override + public int getId() { + return 0x05; + } +}